From 81b54a7dd97fbcbd4a84655139cd1570d1103516 Mon Sep 17 00:00:00 2001 From: Travis Nickles Date: Thu, 11 May 2017 06:41:18 -0700 Subject: [PATCH] Change plugin and unplug routines with ScpVBus --- DS4Windows/DS4Control/ControlSerivce.cs | 37 ++++++++++++--- DS4Windows/DS4Control/ScpUtil.cs | 63 +++++++++++++++++++++---- DS4Windows/DS4Forms/DS4Form.cs | 2 +- DS4Windows/DS4Forms/Options.cs | 3 +- 4 files changed, 86 insertions(+), 19 deletions(-) diff --git a/DS4Windows/DS4Control/ControlSerivce.cs b/DS4Windows/DS4Control/ControlSerivce.cs index b58704c..65aa332 100644 --- a/DS4Windows/DS4Control/ControlSerivce.cs +++ b/DS4Windows/DS4Control/ControlSerivce.cs @@ -135,8 +135,19 @@ namespace DS4Windows if (!getDInputOnly(i)) { - LogDebug("Plugging in X360 Controller #" + (x360Bus.FirstController + i)); - x360Bus.Plugin(i); + int xinputIndex = x360Bus.FirstController + i; + LogDebug("Plugging in X360 Controller #" + xinputIndex); + bool xinputResult = x360Bus.Plugin(i); + if (xinputResult) + { + LogDebug("X360 Controller # " + xinputIndex + " connected"); + useDInputOnly[i] = false; + } + else + { + LogDebug("X360 Controller # " + xinputIndex + " failed. Using DInput only mode"); + useDInputOnly[i] = true; + } } device.Report += this.On_Report; @@ -226,6 +237,7 @@ namespace DS4Windows CurrentState[i].Battery = PreviousState[i].Battery = 0; // Reset for the next connection's initial status change. x360Bus.Unplug(i); + useDInputOnly[i] = false; anyUnplugged = true; DS4Controllers[i] = null; touchPad[i] = null; @@ -319,8 +331,19 @@ namespace DS4Windows device.Report += this.On_Report; if (!getDInputOnly(Index)) { - LogDebug("Plugging in X360 Controller #" + (x360Bus.FirstController + Index)); - x360Bus.Plugin(Index); + int xinputIndex = x360Bus.FirstController + i; + LogDebug("Plugging in X360 Controller #" + xinputIndex); + bool xinputResult = x360Bus.Plugin(i); + if (xinputResult) + { + LogDebug("X360 Controller # " + xinputIndex + " connected"); + useDInputOnly[i] = false; + } + else + { + LogDebug("X360 Controller # " + xinputIndex + " failed. Using DInput only mode"); + useDInputOnly[i] = true; + } } TouchPadOn(Index, device); @@ -517,7 +540,6 @@ namespace DS4Windows return Properties.Resources.NoneText; } - private int XINPUT_UNPLUG_SETTLE_TIME = 250; // Inhibit races that occur with the asynchronous teardown of ScpVBus -> X360 driver instance. //Called when DS4 is disconnected or timed out protected virtual void On_DS4Removal(object sender, EventArgs e) { @@ -548,7 +570,9 @@ namespace DS4Windows string removed = Properties.Resources.ControllerWasRemoved.Replace("*Mac address*", (ind + 1).ToString()); if (device.getBattery() <= 20 && device.getConnectionType() == ConnectionType.BT && !device.isCharging()) + { removed += ". " + Properties.Resources.ChargeController; + } LogDebug(removed); Log.LogToTray(removed); @@ -558,6 +582,7 @@ namespace DS4Windows touchPad[ind] = null; lag[ind] = false; inWarnMonitor[ind] = false; + useDInputOnly[ind] = false; OnControllerRemoved(this, ind); //ControllerStatusChanged(this); } @@ -639,7 +664,7 @@ namespace DS4Windows // Update the GUI/whatever. DS4LightBar.updateLightBar(device, ind, cState, ExposedState[ind], touchPad[ind]); - if (!getDInputOnly(ind)) + if (!useDInputOnly[ind]) { x360Bus.Parse(cState, processingData[ind].Report, ind); // We push the translated Xinput state, and simultaneously we diff --git a/DS4Windows/DS4Control/ScpUtil.cs b/DS4Windows/DS4Control/ScpUtil.cs index 89b8642..1c9acfe 100644 --- a/DS4Windows/DS4Control/ScpUtil.cs +++ b/DS4Windows/DS4Control/ScpUtil.cs @@ -217,8 +217,10 @@ namespace DS4Windows static string exepath = Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName; public static string appdatapath; public static bool runHotPlug = false; + public const int XINPUT_UNPLUG_SETTLE_TIME = 250; // Inhibit races that occur with the asynchronous teardown of ScpVBus -> X360 driver instance. public static string[] tempprofilename = new string[5] { string.Empty, string.Empty, string.Empty, string.Empty, string.Empty }; public static bool[] tempprofileDistance = new bool[5] { false, false, false, false, false }; + public static bool[] useDInputOnly = new bool[5] { false, false, false, false, false }; public static X360Controls[] defaultButtonMapping = { X360Controls.None, X360Controls.LXNeg, X360Controls.LXPos, X360Controls.LYNeg, X360Controls.LYPos, X360Controls.RXNeg, X360Controls.RXPos, X360Controls.RYNeg, X360Controls.RYPos, @@ -480,6 +482,7 @@ namespace DS4Windows { return m_Config.dinputOnly[index]; } + public static bool[] StartTouchpadOff => m_Config.startTouchpadOff; public static bool[] UseTPforControls => m_Config.useTPforControls; public static bool getUseTPforControls(int index) @@ -826,14 +829,15 @@ namespace DS4Windows public static Dictionary getShiftCustomKeyTypes(int device) => m_Config.shiftCustomMapKeyTypes[device]; */ public static bool Load() => m_Config.Load(); - public static void LoadProfile(int device, bool launchprogram, ControlService control) + public static void LoadProfile(int device, bool launchprogram, ControlService control, bool xinputChange = true) { - m_Config.LoadProfile(device, launchprogram, control); + m_Config.LoadProfile(device, launchprogram, control, "", xinputChange); tempprofilename[device] = string.Empty; tempprofileDistance[device] = false; } - public static void LoadTempProfile(int device, string name, bool launchprogram, ControlService control) + public static void LoadTempProfile(int device, string name, bool launchprogram, + ControlService control, bool xinputChange = true) { m_Config.LoadProfile(device, launchprogram, control, appdatapath + @"\Profiles\" + name + ".xml"); tempprofilename[device] = name; @@ -1747,7 +1751,7 @@ namespace DS4Windows return "Unbound"; } - public Boolean LoadProfile(int device, bool launchprogram, ControlService control, string propath = "") + public Boolean LoadProfile(int device, bool launchprogram, ControlService control, string propath = "", bool xinputChange = true) { Boolean Loaded = true; Dictionary customMapKeyTypes = new Dictionary(); @@ -1767,6 +1771,7 @@ namespace DS4Windows profilepath = Global.appdatapath + @"\Profiles\" + profilePath[device] + ".xml"; else profilepath = propath; + if (File.Exists(profilepath)) { XmlNode Item; @@ -2022,14 +2027,52 @@ namespace DS4Windows try { Item = m_Xdoc.SelectSingleNode("/" + rootname + "/DinputOnly"); - Boolean.TryParse(Item.InnerText, out dinputOnly[device]); - if (device < 4) - { - if (dinputOnly[device] == true) control.x360Bus.Unplug(device); - else if (control.DS4Controllers[device] != null && control.DS4Controllers[device].IsAlive()) control.x360Bus.Plugin(device); - } + bool.TryParse(Item.InnerText, out dinputOnly[device]); } catch { missingSetting = true; } + + Global.useDInputOnly[device] = dinputOnly[device]; + + // Only change xinput devices under certain conditions. Avoid + // performing this upon program startup before loading devices. + if (xinputChange) + { + bool changed = false; + if (device < 4) + { + DS4Device tempDevice = control.DS4Controllers[device]; + if (dinputOnly[device] == true) + { + bool xinputResult = control.x360Bus.Unplug(device); + if (xinputResult) + { + int xinputIndex = control.x360Bus.FirstController + device; + Log.LogToGui("X360 Controller # " + xinputIndex + " unplugged", false); + Global.useDInputOnly[device] = false; + } + + changed = true; + } + else if (tempDevice != null && tempDevice.IsAlive()) + { + bool xinputResult = control.x360Bus.Plugin(device); + if (xinputResult) + { + int xinputIndex = control.x360Bus.FirstController + device; + Log.LogToGui("X360 Controller # " + xinputIndex + " connected", false); + Global.useDInputOnly[device] = true; + } + + changed = true; + } + } + + if (changed) + { + System.Threading.Thread.Sleep(Global.XINPUT_UNPLUG_SETTLE_TIME); + } + } + try { Item = m_Xdoc.SelectSingleNode("/" + rootname + "/StartTouchpadOff"); diff --git a/DS4Windows/DS4Forms/DS4Form.cs b/DS4Windows/DS4Forms/DS4Form.cs index b3dcb34..f026d5d 100644 --- a/DS4Windows/DS4Forms/DS4Form.cs +++ b/DS4Windows/DS4Forms/DS4Form.cs @@ -311,7 +311,7 @@ namespace DS4Windows //NewVersion(); for (int i = 0; i < 4; i++) { - LoadProfile(i, false, Program.rootHub); + LoadProfile(i, false, Program.rootHub, false); if (UseCustomLed[i]) lights[i].BackColor = CustomColor[i].ToColorA; else diff --git a/DS4Windows/DS4Forms/Options.cs b/DS4Windows/DS4Forms/Options.cs index 5bedab4..4c766f6 100644 --- a/DS4Windows/DS4Forms/Options.cs +++ b/DS4Windows/DS4Forms/Options.cs @@ -1673,7 +1673,7 @@ namespace DS4Windows private void Options_FormClosing(object sender, FormClosingEventArgs e) { for (int i = 0; i < 4; i++) - LoadProfile(i, false, Program.rootHub); //Refreshes all profiles in case other controllers are using the same profile + LoadProfile(i, false, Program.rootHub); // Refreshes all profiles in case other controllers are using the same profile if (olddinputcheck != cBDinput.Checked) { @@ -2202,7 +2202,6 @@ namespace DS4Windows StartTouchpadOff[device] = cbStartTouchpadOff.Checked; } - private void Items_MouseHover(object sender, EventArgs e) { string name = ((Control)sender).Name;