Last active
March 4, 2021 00:20
-
-
Save Ryochan7/736cbd9c488e6b6409fa4757b08f0aaf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/DS4Windows/DS4Control/ControlService.cs b/DS4Windows/DS4Control/ControlService.cs | |
| index a47dfb0b..1109b080 100644 | |
| --- a/DS4Windows/DS4Control/ControlService.cs | |
| +++ b/DS4Windows/DS4Control/ControlService.cs | |
| @@ -10,6 +10,7 @@ using System.Windows.Threading; | |
| using DS4WinWPF.DS4Control; | |
| using Microsoft.Win32; | |
| using Sensorit.Base; | |
| +using System.Linq; | |
| namespace DS4Windows | |
| { | |
| @@ -623,7 +624,7 @@ namespace DS4Windows | |
| return temp; | |
| } | |
| - private void EstablishOutFeedback(int index, OutContType contType, | |
| + public void EstablishOutFeedback(int index, OutContType contType, | |
| OutputDevice outDevice, DS4Device device) | |
| { | |
| int devIndex = index; | |
| @@ -638,7 +639,7 @@ namespace DS4Windows | |
| SetDevRumble(device, args.LargeMotor, args.SmallMotor, devIndex); | |
| }; | |
| tempXbox.cont.FeedbackReceived += p; | |
| - tempXbox.forceFeedbackCall = p; | |
| + tempXbox.forceFeedbackCall.Add(index, p); | |
| } | |
| else if (contType == OutContType.DS4) | |
| { | |
| @@ -717,13 +718,15 @@ namespace DS4Windows | |
| } | |
| } | |
| - public void RemoveOutFeedback(OutContType contType, OutputDevice outDevice) | |
| + public void RemoveOutFeedback(OutContType contType, OutputDevice outDevice, int inIdx) | |
| { | |
| if (contType == OutContType.X360) | |
| { | |
| Xbox360OutDevice tempXbox = outDevice as Xbox360OutDevice; | |
| - tempXbox.cont.FeedbackReceived -= tempXbox.forceFeedbackCall; | |
| - tempXbox.forceFeedbackCall = null; | |
| + tempXbox.cont.FeedbackReceived -= tempXbox.forceFeedbackCall[inIdx]; | |
| + tempXbox.forceFeedbackCall.Remove(inIdx); | |
| + //tempXbox.cont.FeedbackReceived -= tempXbox.forceFeedbackCall; | |
| + //tempXbox.forceFeedbackCall = null; | |
| } | |
| else if (contType == OutContType.DS4) | |
| { | |
| @@ -790,7 +793,17 @@ namespace DS4Windows | |
| // Enable ViGem feedback callback handler only if lightbar/rumble data output is enabled (if those are disabled then no point enabling ViGem callback handler call) | |
| if (Global.EnableOutputDataToDS4[index]) | |
| + { | |
| EstablishOutFeedback(index, OutContType.X360, tempXbox, device); | |
| + if (device.JointDeviceSlotNumber != -1) | |
| + { | |
| + DS4Device tempDS4Device = DS4Controllers[device.JointDeviceSlotNumber]; | |
| + if (tempDS4Device != null) | |
| + { | |
| + EstablishOutFeedback(device.JointDeviceSlotNumber, OutContType.X360, tempXbox, tempDS4Device); | |
| + } | |
| + } | |
| + } | |
| outputslotMan.DeferredPlugin(tempXbox, index, outputDevices, contType); | |
| //slotDevice.CurrentInputBound = OutSlotDevice.InputBound.Bound; | |
| @@ -810,8 +823,19 @@ namespace DS4Windows | |
| // Enable ViGem feedback callback handler only if lightbar/rumble data output is enabled (if those are disabled then no point enabling ViGem callback handler call) | |
| if (Global.EnableOutputDataToDS4[index]) | |
| + { | |
| EstablishOutFeedback(index, OutContType.X360, tempXbox, device); | |
| + if (device.JointDeviceSlotNumber != -1) | |
| + { | |
| + DS4Device tempDS4Device = DS4Controllers[device.JointDeviceSlotNumber]; | |
| + if (tempDS4Device != null) | |
| + { | |
| + EstablishOutFeedback(device.JointDeviceSlotNumber, OutContType.X360, tempXbox, tempDS4Device); | |
| + } | |
| + } | |
| + } | |
| + | |
| outputslotMan.EventDispatcher.BeginInvoke((Action)(() => | |
| { | |
| outputDevices[index] = tempXbox; | |
| @@ -838,8 +862,19 @@ namespace DS4Windows | |
| // Enable ViGem feedback callback handler only if DS4 lightbar/rumble data output is enabled (if those are disabled then no point enabling ViGem callback handler call) | |
| if (Global.EnableOutputDataToDS4[index]) | |
| + { | |
| EstablishOutFeedback(index, OutContType.DS4, tempDS4, device); | |
| - | |
| + | |
| + if (device.JointDeviceSlotNumber != -1) | |
| + { | |
| + DS4Device tempDS4Device = DS4Controllers[device.JointDeviceSlotNumber]; | |
| + if (tempDS4Device != null) | |
| + { | |
| + EstablishOutFeedback(device.JointDeviceSlotNumber, OutContType.DS4, tempDS4, tempDS4Device); | |
| + } | |
| + } | |
| + } | |
| + | |
| outputslotMan.DeferredPlugin(tempDS4, index, outputDevices, contType); | |
| //slotDevice.CurrentInputBound = OutSlotDevice.InputBound.Bound; | |
| @@ -858,8 +893,19 @@ namespace DS4Windows | |
| // Enable ViGem feedback callback handler only if lightbar/rumble data output is enabled (if those are disabled then no point enabling ViGem callback handler call) | |
| if (Global.EnableOutputDataToDS4[index]) | |
| + { | |
| EstablishOutFeedback(index, OutContType.DS4, tempDS4, device); | |
| + if (device.JointDeviceSlotNumber != -1) | |
| + { | |
| + DS4Device tempDS4Device = DS4Controllers[device.JointDeviceSlotNumber]; | |
| + if (tempDS4Device != null) | |
| + { | |
| + EstablishOutFeedback(device.JointDeviceSlotNumber, OutContType.DS4, tempDS4, tempDS4Device); | |
| + } | |
| + } | |
| + } | |
| + | |
| outputslotMan.EventDispatcher.BeginInvoke((Action)(() => | |
| { | |
| outputDevices[index] = tempDS4; | |
| @@ -912,7 +958,8 @@ namespace DS4Windows | |
| { | |
| slotDevice.CurrentInputBound = OutSlotDevice.InputBound.Unbound; | |
| dev.ResetState(); | |
| - RemoveOutFeedback(currentType, dev); | |
| + dev.RemoveFeedbacks(); | |
| + //RemoveOutFeedback(currentType, dev, index); | |
| } | |
| //dev.Disconnect(); | |
| //LogDebug(tempType + " Controller # " + (index + 1) + " unplugged"); | |
| @@ -974,6 +1021,7 @@ namespace DS4Windows | |
| //for (int i = 0, devCount = devices.Count(); i < devCount; i++) | |
| int i = 0; | |
| + InputDevices.JoyConDevice tempPrimaryJoyDev = null; | |
| for (var devEnum = devices.GetEnumerator(); devEnum.MoveNext() && loopControllers; i++) | |
| { | |
| DS4Device device = devEnum.Current; | |
| @@ -987,6 +1035,32 @@ namespace DS4Windows | |
| device.CurrentExclusiveStatus = DS4Device.ExclusiveStatus.HidGuardAffected; | |
| } | |
| + if (device.DeviceType == InputDevices.InputDeviceType.JoyConL || | |
| + device.DeviceType == InputDevices.InputDeviceType.JoyConR) | |
| + { | |
| + if (tempPrimaryJoyDev == null) | |
| + { | |
| + tempPrimaryJoyDev = device as InputDevices.JoyConDevice; | |
| + } | |
| + else | |
| + { | |
| + InputDevices.JoyConDevice currentJoyDev = device as InputDevices.JoyConDevice; | |
| + tempPrimaryJoyDev.PerformStateMerge = true; | |
| + tempPrimaryJoyDev.JointDevice = currentJoyDev; | |
| + currentJoyDev.PerformStateMerge = true; | |
| + currentJoyDev.JointDevice = tempPrimaryJoyDev; | |
| + currentJoyDev.PrimaryDevice = false; | |
| + | |
| + tempPrimaryJoyDev.JointState = currentJoyDev.JointState; | |
| + InputDevices.JoyConDevice parentJoy = tempPrimaryJoyDev; | |
| + | |
| + tempPrimaryJoyDev.Removal += (sender, args) => { currentJoyDev.JointDevice = null; }; | |
| + currentJoyDev.Removal += (sender, args) => { parentJoy.JointDevice = null; }; | |
| + | |
| + tempPrimaryJoyDev = null; | |
| + } | |
| + } | |
| + | |
| Task task = new Task(() => { Thread.Sleep(5); WarnExclusiveModeFailure(device); }); | |
| task.Start(); | |
| @@ -1030,7 +1104,28 @@ namespace DS4Windows | |
| if (!getDInputOnly(i) && device.isSynced()) | |
| { | |
| //useDInputOnly[i] = false; | |
| - PluginOutDev(i, device); | |
| + if (device.PrimaryDevice) | |
| + { | |
| + PluginOutDev(i, device); | |
| + } | |
| + else | |
| + { | |
| + int otherIdx = (device as InputDevices.JoyConDevice).JointDevice.DeviceSlotNumber; | |
| + OutputDevice tempOutDev = outputDevices[otherIdx]; | |
| + if (tempOutDev != null) | |
| + { | |
| + OutContType tempConType = activeOutDevType[otherIdx]; | |
| + EstablishOutFeedback(i, tempConType, tempOutDev, device); | |
| + outputDevices[i] = tempOutDev; | |
| + Global.activeOutDevType[i] = tempConType; | |
| + | |
| + //useDInputOnly[i] = false; | |
| + //Global.activeOutDevType[i] = OutContType.X360; | |
| + } | |
| + | |
| + //useDInputOnly[i] = true; | |
| + //Global.activeOutDevType[i] = OutContType.None; | |
| + } | |
| } | |
| else | |
| { | |
| @@ -1038,7 +1133,16 @@ namespace DS4Windows | |
| Global.activeOutDevType[i] = OutContType.None; | |
| } | |
| - TouchPadOn(i, device); | |
| + if (!device.PrimaryDevice && device.JointDeviceSlotNumber != DS4Device.DEFAULT_JOINT_SLOT_NUMBER) | |
| + { | |
| + int otherIdx = device.JointDeviceSlotNumber; | |
| + TouchPadOn(otherIdx, device); | |
| + } | |
| + else if (device.PrimaryDevice && (device.DeviceType == InputDevices.InputDeviceType.JoyConR)) | |
| + { | |
| + TouchPadOn(i, device); | |
| + } | |
| + | |
| CheckProfileOptions(i, device, true); | |
| } | |
| @@ -1048,7 +1152,7 @@ namespace DS4Windows | |
| this.On_Report(sender, e, tempIdx); | |
| }; | |
| - if (_udpServer != null && i < UdpServer.NUMBER_SLOTS) | |
| + if (_udpServer != null && i < UdpServer.NUMBER_SLOTS && device.PrimaryDevice) | |
| { | |
| DS4Device.ReportHandler<EventArgs> tempEvnt = (sender, args) => | |
| { | |
| @@ -1287,6 +1391,13 @@ namespace DS4Windows | |
| activeControllers = numControllers; | |
| //foreach (DS4Device device in devices) | |
| //for (int i = 0, devlen = devices.Count(); i < devlen; i++) | |
| + InputDevices.JoyConDevice tempPrimaryJoyDev = devices.Where(d => | |
| + (d.DeviceType == InputDevices.InputDeviceType.JoyConL || d.DeviceType == InputDevices.InputDeviceType.JoyConR) | |
| + && d.PrimaryDevice && d.JointDeviceSlotNumber == -1).FirstOrDefault() as InputDevices.JoyConDevice; | |
| + InputDevices.JoyConDevice tempSecondaryJoyDev = devices.Where(d => | |
| + (d.DeviceType == InputDevices.InputDeviceType.JoyConL || d.DeviceType == InputDevices.InputDeviceType.JoyConR) | |
| + && !d.PrimaryDevice && d.JointDeviceSlotNumber == -1).FirstOrDefault() as InputDevices.JoyConDevice; | |
| + | |
| for (var devEnum = devices.GetEnumerator(); devEnum.MoveNext() && loopControllers;) | |
| { | |
| DS4Device device = devEnum.Current; | |
| @@ -1326,6 +1437,45 @@ namespace DS4Windows | |
| device.CurrentExclusiveStatus = DS4Device.ExclusiveStatus.HidGuardAffected; | |
| } | |
| + if (device.DeviceType == InputDevices.InputDeviceType.JoyConL || | |
| + device.DeviceType == InputDevices.InputDeviceType.JoyConR) | |
| + { | |
| + if (tempPrimaryJoyDev == device && | |
| + tempSecondaryJoyDev != null) | |
| + { | |
| + InputDevices.JoyConDevice currentJoyDev = device as InputDevices.JoyConDevice; | |
| + tempSecondaryJoyDev.PerformStateMerge = true; | |
| + tempSecondaryJoyDev.JointDevice = currentJoyDev; | |
| + currentJoyDev.PerformStateMerge = true; | |
| + currentJoyDev.JointDevice = tempSecondaryJoyDev; | |
| + currentJoyDev.PrimaryDevice = true; | |
| + | |
| + tempSecondaryJoyDev.JointState = currentJoyDev.JointState; | |
| + InputDevices.JoyConDevice secondaryJoy = tempSecondaryJoyDev; | |
| + secondaryJoy.Removal += (sender, args) => { currentJoyDev.JointDevice = null; }; | |
| + currentJoyDev.Removal += (sender, args) => { secondaryJoy.JointDevice = null; }; | |
| + | |
| + tempSecondaryJoyDev = null; | |
| + tempPrimaryJoyDev = null; | |
| + } | |
| + else if (tempPrimaryJoyDev != null) | |
| + { | |
| + InputDevices.JoyConDevice currentJoyDev = device as InputDevices.JoyConDevice; | |
| + tempPrimaryJoyDev.PerformStateMerge = true; | |
| + tempPrimaryJoyDev.JointDevice = currentJoyDev; | |
| + currentJoyDev.PerformStateMerge = true; | |
| + currentJoyDev.JointDevice = tempPrimaryJoyDev; | |
| + currentJoyDev.PrimaryDevice = false; | |
| + | |
| + tempPrimaryJoyDev.JointState = currentJoyDev.JointState; | |
| + InputDevices.JoyConDevice parentJoy = tempPrimaryJoyDev; | |
| + tempPrimaryJoyDev.Removal += (sender, args) => { currentJoyDev.JointDevice = null; }; | |
| + currentJoyDev.Removal += (sender, args) => { parentJoy.JointDevice = null; }; | |
| + | |
| + tempPrimaryJoyDev = null; | |
| + } | |
| + } | |
| + | |
| Task task = new Task(() => { Thread.Sleep(5); WarnExclusiveModeFailure(device); }); | |
| task.Start(); | |
| DS4Controllers[Index] = device; | |
| @@ -1368,7 +1518,28 @@ namespace DS4Windows | |
| if (!getDInputOnly(Index) && device.isSynced()) | |
| { | |
| //useDInputOnly[Index] = false; | |
| - PluginOutDev(Index, device); | |
| + if (device.PrimaryDevice) | |
| + { | |
| + PluginOutDev(Index, device); | |
| + } | |
| + else | |
| + { | |
| + int otherIdx = (device as InputDevices.JoyConDevice).JointDevice.DeviceSlotNumber; | |
| + OutputDevice tempOutDev = outputDevices[otherIdx]; | |
| + if (tempOutDev != null) | |
| + { | |
| + OutContType tempConType = activeOutDevType[otherIdx]; | |
| + EstablishOutFeedback(Index, tempConType, tempOutDev, device); | |
| + outputDevices[Index] = tempOutDev; | |
| + Global.activeOutDevType[Index] = tempConType; | |
| + | |
| + //useDInputOnly[i] = false; | |
| + //Global.activeOutDevType[i] = OutContType.X360; | |
| + } | |
| + | |
| + //useDInputOnly[Index] = true; | |
| + //Global.activeOutDevType[Index] = OutContType.None; | |
| + } | |
| } | |
| else | |
| { | |
| @@ -1376,7 +1547,16 @@ namespace DS4Windows | |
| Global.activeOutDevType[Index] = OutContType.None; | |
| } | |
| - TouchPadOn(Index, device); | |
| + if (!device.PrimaryDevice && device.JointDeviceSlotNumber != DS4Device.DEFAULT_JOINT_SLOT_NUMBER) | |
| + { | |
| + int otherIdx = device.JointDeviceSlotNumber; | |
| + TouchPadOn(otherIdx, device); | |
| + } | |
| + else if (device.PrimaryDevice && (device.DeviceType == InputDevices.InputDeviceType.JoyConR)) | |
| + { | |
| + TouchPadOn(Index, device); | |
| + } | |
| + | |
| CheckProfileOptions(Index, device); | |
| } | |
| @@ -1386,7 +1566,7 @@ namespace DS4Windows | |
| this.On_Report(sender, e, tempIdx); | |
| }; | |
| - if (_udpServer != null && Index < UdpServer.NUMBER_SLOTS) | |
| + if (_udpServer != null && Index < UdpServer.NUMBER_SLOTS && device.PrimaryDevice) | |
| { | |
| DS4Device.ReportHandler<EventArgs> tempEvnt = (sender, args) => | |
| { | |
| @@ -1766,6 +1946,15 @@ namespace DS4Windows | |
| { | |
| UnplugOutDev(ind, device); | |
| } | |
| + else if (!device.PrimaryDevice) | |
| + { | |
| + OutputDevice outDev = outputDevices[ind]; | |
| + if (outDev != null) | |
| + { | |
| + outDev.RemoveFeedback(ind); | |
| + outputDevices[ind] = null; | |
| + } | |
| + } | |
| // Use Task to reset device synth state and commit it | |
| Task.Run(() => | |
| @@ -1873,8 +2062,18 @@ namespace DS4Windows | |
| } | |
| } | |
| - device.getCurrentState(CurrentState[ind]); | |
| - DS4State cState = CurrentState[ind]; | |
| + DS4State cState; | |
| + if (!device.PerformStateMerge) | |
| + { | |
| + cState = CurrentState[ind]; | |
| + device.getCurrentState(cState); | |
| + } | |
| + else | |
| + { | |
| + cState = (device as InputDevices.JoyConDevice).JointState; | |
| + device.MergeStateData(cState); | |
| + } | |
| + | |
| DS4State pState = device.getPreviousStateRef(); | |
| //device.getPreviousState(PreviousState[ind]); | |
| //DS4State pState = PreviousState[ind]; | |
| @@ -1912,6 +2111,12 @@ namespace DS4Windows | |
| // */ | |
| //} | |
| + if (!device.PrimaryDevice) | |
| + { | |
| + // Skip mapping routine if part of a joined device | |
| + return; | |
| + } | |
| + | |
| if (getEnableTouchToggle(ind)) | |
| CheckForTouchToggle(ind, cState, pState); | |
| diff --git a/DS4Windows/DS4Control/DS4OutDevice.cs b/DS4Windows/DS4Control/DS4OutDevice.cs | |
| index 8dab686a..9b1248a1 100644 | |
| --- a/DS4Windows/DS4Control/DS4OutDevice.cs | |
| +++ b/DS4Windows/DS4Control/DS4OutDevice.cs | |
| @@ -42,5 +42,18 @@ namespace DS4Windows | |
| cont = null; | |
| } | |
| public override string GetDeviceType() => devtype; | |
| + | |
| + public override void RemoveFeedbacks() | |
| + { | |
| + if (forceFeedbackCall != null) | |
| + { | |
| + cont.FeedbackReceived -= forceFeedbackCall; | |
| + forceFeedbackCall = null; | |
| + } | |
| + } | |
| + | |
| + public override void RemoveFeedback(int inIdx) | |
| + { | |
| + } | |
| } | |
| } | |
| diff --git a/DS4Windows/DS4Control/OutputDevice.cs b/DS4Windows/DS4Control/OutputDevice.cs | |
| index ada31e46..154f650e 100644 | |
| --- a/DS4Windows/DS4Control/OutputDevice.cs | |
| +++ b/DS4Windows/DS4Control/OutputDevice.cs | |
| @@ -11,5 +11,9 @@ namespace DS4Windows | |
| public abstract void Disconnect(); | |
| public abstract void ResetState(bool submit=true); | |
| public abstract string GetDeviceType(); | |
| + | |
| + public abstract void RemoveFeedbacks(); | |
| + | |
| + public abstract void RemoveFeedback(int inIdx); | |
| } | |
| } | |
| diff --git a/DS4Windows/DS4Control/ScpUtil.cs b/DS4Windows/DS4Control/ScpUtil.cs | |
| index 97380f13..695c0a56 100644 | |
| --- a/DS4Windows/DS4Control/ScpUtil.cs | |
| +++ b/DS4Windows/DS4Control/ScpUtil.cs | |
| @@ -5083,8 +5083,12 @@ namespace DS4Windows | |
| // performing this upon program startup before loading devices. | |
| if (xinputChange) | |
| { | |
| - CheckOldDevicestatus(device, control, oldContType, | |
| - out xinputPlug, out xinputStatus); | |
| + DS4Device tempDev = control.DS4Controllers[device]; | |
| + if (tempDev != null) | |
| + { | |
| + CheckOldDevicestatus(device, control, oldContType, | |
| + out xinputPlug, out xinputStatus); | |
| + } | |
| } | |
| try | |
| @@ -7062,25 +7066,27 @@ namespace DS4Windows | |
| { | |
| tempDev.setIdleTimeout(idleDisconnectTimeout[device]); | |
| tempDev.setBTPollRate(btPollRate[device]); | |
| - if (xinputStatus && xinputPlug) | |
| + if (xinputStatus && tempDev.PrimaryDevice) | |
| { | |
| - OutputDevice tempOutDev = control.outputDevices[device]; | |
| - if (tempOutDev != null) | |
| + if (xinputPlug) | |
| + { | |
| + OutputDevice tempOutDev = control.outputDevices[device]; | |
| + if (tempOutDev != null) | |
| + { | |
| + tempOutDev = null; | |
| + //Global.activeOutDevType[device] = OutContType.None; | |
| + control.UnplugOutDev(device, tempDev); | |
| + } | |
| + | |
| + OutContType tempContType = outputDevType[device]; | |
| + control.PluginOutDev(device, tempDev); | |
| + //Global.useDInputOnly[device] = false; | |
| + } | |
| + else | |
| { | |
| - tempOutDev = null; | |
| //Global.activeOutDevType[device] = OutContType.None; | |
| control.UnplugOutDev(device, tempDev); | |
| } | |
| - | |
| - OutContType tempContType = outputDevType[device]; | |
| - control.PluginOutDev(device, tempDev); | |
| - //Global.useDInputOnly[device] = false; | |
| - | |
| - } | |
| - else if (xinputStatus && !xinputPlug) | |
| - { | |
| - //Global.activeOutDevType[device] = OutContType.None; | |
| - control.UnplugOutDev(device, tempDev); | |
| } | |
| tempDev.RumbleAutostopTime = rumbleAutostopTime[device]; | |
| diff --git a/DS4Windows/DS4Control/Xbox360OutDevice.cs b/DS4Windows/DS4Control/Xbox360OutDevice.cs | |
| index 6c4df1fc..6f736e78 100644 | |
| --- a/DS4Windows/DS4Control/Xbox360OutDevice.cs | |
| +++ b/DS4Windows/DS4Control/Xbox360OutDevice.cs | |
| @@ -2,6 +2,7 @@ | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.Text; | |
| +using System.Threading; | |
| using System.Threading.Tasks; | |
| using Nefarius.ViGEm.Client; | |
| using Nefarius.ViGEm.Client.Targets; | |
| @@ -19,7 +20,10 @@ namespace DS4Windows | |
| public const string devType = "X360"; | |
| public IXbox360Controller cont; | |
| - public Xbox360FeedbackReceivedEventHandler forceFeedbackCall; | |
| + // Input index, Xbox360FeedbackReceivedEventHandler instance | |
| + public Dictionary<int, Xbox360FeedbackReceivedEventHandler> forceFeedbackCall = | |
| + new Dictionary<int, Xbox360FeedbackReceivedEventHandler>(); | |
| + private ReaderWriterLockSlim lockSlim = new ReaderWriterLockSlim(); | |
| public Xbox360OutDevice(ViGEmClient client) | |
| { | |
| @@ -32,6 +36,7 @@ namespace DS4Windows | |
| if (!connected) return; | |
| //cont.ResetReport(); | |
| + | |
| ushort tempButtons = 0; | |
| unchecked | |
| @@ -125,6 +130,7 @@ namespace DS4Windows | |
| } | |
| cont.SubmitReport(); | |
| + | |
| } | |
| private short AxisScale(Int32 Value, Boolean Flip) | |
| @@ -152,8 +158,13 @@ namespace DS4Windows | |
| { | |
| if (forceFeedbackCall != null) | |
| { | |
| - cont.FeedbackReceived -= forceFeedbackCall; | |
| - forceFeedbackCall = null; | |
| + foreach(KeyValuePair<int, Xbox360FeedbackReceivedEventHandler> pair in forceFeedbackCall) | |
| + { | |
| + cont.FeedbackReceived -= pair.Value; | |
| + } | |
| + | |
| + //forceFeedbackCall = null; | |
| + forceFeedbackCall.Clear(); | |
| } | |
| connected = false; | |
| @@ -170,5 +181,25 @@ namespace DS4Windows | |
| cont.SubmitReport(); | |
| } | |
| } | |
| + | |
| + public override void RemoveFeedbacks() | |
| + { | |
| + foreach (KeyValuePair<int, Xbox360FeedbackReceivedEventHandler> pair in forceFeedbackCall) | |
| + { | |
| + cont.FeedbackReceived -= pair.Value; | |
| + } | |
| + | |
| + //forceFeedbackCall = null; | |
| + forceFeedbackCall.Clear(); | |
| + } | |
| + | |
| + public override void RemoveFeedback(int inIdx) | |
| + { | |
| + if (forceFeedbackCall.TryGetValue(inIdx, out Xbox360FeedbackReceivedEventHandler handler)) | |
| + { | |
| + cont.FeedbackReceived -= handler; | |
| + forceFeedbackCall.Remove(inIdx); | |
| + } | |
| + } | |
| } | |
| } | |
| diff --git a/DS4Windows/DS4Forms/MainWindow.xaml b/DS4Windows/DS4Forms/MainWindow.xaml | |
| index 5c09b3e0..0064b2de 100644 | |
| --- a/DS4Windows/DS4Forms/MainWindow.xaml | |
| +++ b/DS4Windows/DS4Forms/MainWindow.xaml | |
| @@ -95,11 +95,11 @@ | |
| </DataTemplate> | |
| </GridViewColumn.CellTemplate> | |
| </GridViewColumn> | |
| - <GridViewColumn x:Name="LinkProfColumn" Header="Link Profile/ID" Width="100" > | |
| + <GridViewColumn x:Name="LinkProfColumn" Header="Link Profile/ID" Width="100"> | |
| <GridViewColumn.CellTemplate> | |
| <DataTemplate> | |
| <StackPanel Width="{Binding ElementName=LinkProfColumn, Path=Width}"> | |
| - <CheckBox IsChecked="{Binding LinkedProfile}" HorizontalAlignment="Center" /> | |
| + <CheckBox IsChecked="{Binding LinkedProfile}" HorizontalAlignment="Center" IsEnabled="{Binding PrimaryDevice}" /> | |
| </StackPanel> | |
| </DataTemplate> | |
| </GridViewColumn.CellTemplate> | |
| @@ -109,7 +109,7 @@ | |
| <DataTemplate> | |
| <StackPanel Width="{Binding Path=Width, ElementName=selectProfileColumn, Mode=OneWay}" HorizontalAlignment="Center"> | |
| <ComboBox x:Name="selectProfCombo" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource Mode=TemplatedParent}, Mode=OneWay}" | |
| - ItemsSource="{Binding ProfileListCol}" SelectedIndex="{Binding SelectedIndex}" Height="Auto" Tag="{Binding DevIndex, Mode=OneTime}" Margin="0" | |
| + ItemsSource="{Binding ProfileListCol}" SelectedIndex="{Binding SelectedIndex}" IsEnabled="{Binding PrimaryDevice}" Height="Auto" Tag="{Binding DevIndex, Mode=OneTime}" Margin="0" | |
| SelectionChanged="SelectProfCombo_SelectionChanged" KeyDown="SelectProfCombo_KeyDown"> | |
| <ComboBox.ItemTemplate> | |
| <DataTemplate> | |
| @@ -125,7 +125,7 @@ | |
| <GridViewColumn.CellTemplate> | |
| <DataTemplate> | |
| <StackPanel Width="{Binding ElementName=editColumn, Path=Width}"> | |
| - <xctk:SplitButton x:Name="ProfEditSBtn" Content="{lex:Loc Edit}" Height="20" MinWidth="60" | |
| + <xctk:SplitButton x:Name="ProfEditSBtn" Content="{lex:Loc Edit}" Height="20" MinWidth="60" IsEnabled="{Binding PrimaryDevice}" | |
| Tag="{Binding DevIndex, Mode=OneTime}" Click="ProfEditSBtn_Click" HorizontalAlignment="Center"> | |
| <xctk:SplitButton.DropDownContent> | |
| <Button x:Name="newProfBtn" Content="{lex:Loc NewProfile}" MinWidth="120" Tag="{Binding DevIndex, Mode=OneTime}" Click="NewProfBtn_Click" /> | |
| diff --git a/DS4Windows/DS4Forms/ViewModels/ControllerListViewModel.cs b/DS4Windows/DS4Forms/ViewModels/ControllerListViewModel.cs | |
| index c8e4163f..42807ed5 100644 | |
| --- a/DS4Windows/DS4Forms/ViewModels/ControllerListViewModel.cs | |
| +++ b/DS4Windows/DS4Forms/ViewModels/ControllerListViewModel.cs | |
| @@ -339,6 +339,11 @@ namespace DS4WinWPF.DS4Forms.ViewModels | |
| } | |
| } | |
| + public bool PrimaryDevice | |
| + { | |
| + get => device.PrimaryDevice; | |
| + } | |
| + | |
| public delegate void CustomColorHandler(CompositeDeviceModel sender); | |
| public event CustomColorHandler RequestColorPicker; | |
| diff --git a/DS4Windows/DS4Library/DS4Device.cs b/DS4Windows/DS4Library/DS4Device.cs | |
| index 484e7312..8d01dfe9 100644 | |
| --- a/DS4Windows/DS4Library/DS4Device.cs | |
| +++ b/DS4Windows/DS4Library/DS4Device.cs | |
| @@ -578,6 +578,27 @@ namespace DS4Windows | |
| protected event EventHandler DeviceSlotNumberChanged; | |
| protected byte deviceSlotMask = 0x00; | |
| + protected bool performStateMerge; | |
| + public bool PerformStateMerge | |
| + { | |
| + get => performStateMerge; set => performStateMerge = value; | |
| + } | |
| + | |
| + protected bool primaryDevice = true; | |
| + public bool PrimaryDevice | |
| + { | |
| + get => primaryDevice; | |
| + set => primaryDevice = value; | |
| + } | |
| + | |
| + public const int DEFAULT_JOINT_SLOT_NUMBER = -1; | |
| + protected int jointDeviceSlotNumber = DEFAULT_JOINT_SLOT_NUMBER; | |
| + public virtual int JointDeviceSlotNumber | |
| + { | |
| + get => jointDeviceSlotNumber; | |
| + set => jointDeviceSlotNumber = value; | |
| + } | |
| + | |
| public DS4Device(HidDevice hidDevice, string disName, VidPidFeatureSet featureSet = VidPidFeatureSet.DefaultDS4) | |
| { | |
| hDevice = hidDevice; | |
| @@ -2055,5 +2076,9 @@ namespace DS4Windows | |
| PrepareOutputFeaturesByte(); | |
| } | |
| } | |
| + | |
| + public virtual void MergeStateData(DS4State dState) | |
| + { | |
| + } | |
| } | |
| } | |
| diff --git a/DS4Windows/DS4Library/InputDevices/JoyConDevice.cs b/DS4Windows/DS4Library/InputDevices/JoyConDevice.cs | |
| index 92325d77..8563cde7 100644 | |
| --- a/DS4Windows/DS4Library/InputDevices/JoyConDevice.cs | |
| +++ b/DS4Windows/DS4Library/InputDevices/JoyConDevice.cs | |
| @@ -214,6 +214,42 @@ namespace DS4Windows.InputDevices | |
| public bool EnableHomeLED { get => enableHomeLED; set => enableHomeLED = value; } | |
| private JoyConControllerOptions nativeOptionsStore; | |
| + private DS4State jointState = new DS4State(); | |
| + public DS4State JointState | |
| + { | |
| + get => jointState; set => jointState = value; | |
| + } | |
| + | |
| + private ReaderWriterLockSlim lockSlim = new ReaderWriterLockSlim(); | |
| + private JoyConDevice jointDevice; | |
| + public JoyConDevice JointDevice | |
| + { | |
| + get => jointDevice; | |
| + set | |
| + { | |
| + jointDevice = value; | |
| + if (jointDevice == null) | |
| + { | |
| + } | |
| + else | |
| + { | |
| + } | |
| + } | |
| + } | |
| + | |
| + public override int JointDeviceSlotNumber | |
| + { | |
| + get | |
| + { | |
| + int result = -1; | |
| + if (jointDevice != null) | |
| + { | |
| + result = jointDevice.deviceSlotNumber; | |
| + } | |
| + | |
| + return result; | |
| + } | |
| + } | |
| public override event ReportHandler<EventArgs> Report = null; | |
| public override event EventHandler<EventArgs> Removal = null; | |
| @@ -1288,5 +1324,45 @@ namespace DS4Windows.InputDevices | |
| enableHomeLED = nativeOptionsStore.EnableHomeLED; | |
| } | |
| } | |
| + | |
| + public override void MergeStateData(DS4State dState) | |
| + { | |
| + using (WriteLocker locker = new WriteLocker(lockSlim)) | |
| + { | |
| + if (DeviceType == InputDeviceType.JoyConL) | |
| + { | |
| + dState.LX = cState.LX; | |
| + dState.LY = cState.LY; | |
| + dState.L1 = cState.L1; | |
| + dState.L2 = cState.L2; | |
| + dState.L3 = cState.L3; | |
| + dState.L2Btn = cState.L2Btn; | |
| + dState.DpadUp = cState.DpadUp; | |
| + dState.DpadDown = cState.DpadDown; | |
| + dState.DpadLeft = cState.DpadLeft; | |
| + dState.DpadRight = cState.DpadRight; | |
| + dState.Share = cState.Share; | |
| + if (primaryDevice) dState.Motion = cState.Motion; | |
| + //dState.Motion = cState.Motion; | |
| + } | |
| + else if (DeviceType == InputDeviceType.JoyConR) | |
| + { | |
| + dState.RX = cState.RX; | |
| + dState.RY = cState.RY; | |
| + dState.R1 = cState.R1; | |
| + dState.R2 = cState.R2; | |
| + dState.R3 = cState.R3; | |
| + dState.R2Btn = cState.R2Btn; | |
| + dState.Cross = cState.Cross; | |
| + dState.Circle = cState.Circle; | |
| + dState.Triangle = cState.Triangle; | |
| + dState.Square = cState.Square; | |
| + dState.PS = cState.PS; | |
| + dState.Options = cState.Options; | |
| + if (primaryDevice) dState.Motion = cState.Motion; | |
| + //dState.Motion = cState.Motion; | |
| + } | |
| + } | |
| + } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment