diff --git a/mi/Program.cs b/mi/Program.cs index e313921..8bcecc0 100755 --- a/mi/Program.cs +++ b/mi/Program.cs @@ -111,7 +111,15 @@ private static void ManageControllers(ScpBus scpBus) { var compatibleDevices = HidDevices.Enumerate(0x2717, 0x3144).ToList(); var existingDevices = Gamepads.Select(g => g.Device).ToList(); - var newDevices = compatibleDevices.Where(d => !existingDevices.Contains(d)); + var newDevices = compatibleDevices.Where(d => !existingDevices.Select(e => e.DevicePath).Contains(d.DevicePath)); + foreach (var gamepad in Gamepads.ToList()) + { + if (!gamepad.check_connected()) + { + gamepad.unplug(); + Gamepads.Remove(gamepad); + } + } foreach (var deviceInstance in newDevices) { var device = deviceInstance; @@ -157,19 +165,19 @@ private static void ManageControllers(ScpBus scpBus) device.ReadProduct(out product); - Gamepads.Add(new Xiaomi_gamepad(device, scpBus, Gamepads.Count + 1)); + var usedIndexes = Gamepads.Select(g => g.Index); + var index = 1; + while (usedIndexes.Contains(index)) + { + index++; + } + Gamepads.Add(new Xiaomi_gamepad(device, scpBus, index)); } if (Gamepads.Count != nrConnected) { InformUser($"{Gamepads.Count} controllers connected"); } - nrConnected = Gamepads.Count; - if (nrConnected == 4) - { - Thread.Sleep(10000); - continue; - } - Thread.Sleep(5000); + Thread.Sleep(1000); } } diff --git a/mi/Xiaomi_gamepad.cs b/mi/Xiaomi_gamepad.cs index deb10a1..572b383 100644 --- a/mi/Xiaomi_gamepad.cs +++ b/mi/Xiaomi_gamepad.cs @@ -8,28 +8,48 @@ namespace mi public class Xiaomi_gamepad { public HidDevice Device { get; set; } + public int Index; + private Thread rThread, iThread; + private ScpBus ScpBus; private byte[] Vibration = { 0x20, 0x00, 0x00 }; private Mutex rumble_mutex = new Mutex(); + private bool Running = true; //private byte[] enableAccelerometer = { 0x31, 0x01, 0x08 }; public Xiaomi_gamepad(HidDevice device, ScpBus scpBus, int index) { + Index = index; + ScpBus = scpBus; Device = device; Device.WriteFeatureData(Vibration); - Thread rThread = new Thread(() => rumble_thread(Device)); + rThread = new Thread(() => rumble_thread(Device)); // rThread.Priority = ThreadPriority.BelowNormal; rThread.Start(); - Thread iThread = new Thread(() => input_thread(Device, scpBus, index)); + iThread = new Thread(() => input_thread(Device, scpBus, index)); iThread.Priority = ThreadPriority.Highest; iThread.Start(); } + public bool check_connected() + { + return Device.WriteFeatureData(Vibration); + } + + public void unplug() + { + Running = false; + rThread.Join(); + iThread.Join(); + ScpBus.Unplug(Index); + Device.CloseDevice(); + } + private void rumble_thread(HidDevice Device) { byte[] local_vibration = { 0x20, 0x00, 0x00 }; - while (true) + while (Running) { rumble_mutex.WaitOne(); if (local_vibration[2] != Vibration[2] || Vibration[1] != local_vibration[1]) @@ -55,7 +75,7 @@ private void input_thread(HidDevice Device, ScpBus scpBus, int index) int timeout = 30; long last_changed = 0; long last_mi_button = 0; - while (true) + while (Running) { HidDeviceData data = Device.Read(timeout); var currentState = data.Data;