From a798359a9f3f1e3745700c1f909378af860b1bf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Exterck=C3=B6tter=20Tj=C3=A4der?= Date: Tue, 18 Apr 2017 22:25:43 -0300 Subject: [PATCH] Unplug device from ScpBus when it is no longer connected. --- mi/Program.cs | 26 ++++++++++++++++++-------- mi/Xiaomi_gamepad.cs | 28 ++++++++++++++++++++++++---- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/mi/Program.cs b/mi/Program.cs index ce5aeab..11a4c96 100755 --- a/mi/Program.cs +++ b/mi/Program.cs @@ -112,6 +112,14 @@ 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.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,21 @@ private static void ManageControllers(ScpBus scpBus) device.ReadProduct(out product); - Gamepads.Add(new Xiaomi_gamepad(device, scpBus, Gamepads.Count + 1)); + var index = 1; + try + { + index = Gamepads.Select(g => g.Index).Min(); + } + catch (InvalidOperationException) + { + } + 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;