Last active
March 24, 2018 01:38
-
-
Save Ryochan7/a8aaa5234d55259da83b395ab373efd1 to your computer and use it in GitHub Desktop.
Patch for DS4Windows implementing ViGEm and UDP
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 e8a164c..7ae2ade 100644 | |
--- a/DS4Windows/DS4Control/ControlService.cs | |
+++ b/DS4Windows/DS4Control/ControlService.cs | |
@@ -7,6 +7,9 @@ using System.Media; | |
using System.Threading.Tasks; | |
using static DS4Windows.Global; | |
using System.Threading; | |
+using Nefarius.ViGEm.Client; | |
+using Nefarius.ViGEm.Client.Targets; | |
+using Nefarius.ViGEm.Client.Targets.Xbox360; | |
using Registry = Microsoft.Win32.Registry; | |
namespace DS4Windows | |
@@ -14,6 +17,10 @@ namespace DS4Windows | |
public class ControlService | |
{ | |
public X360Device x360Bus = null; | |
+ public ViGEmClient vigemTestClient = null; | |
+ private const int inputResolution = 127 - (-128); | |
+ private const float reciprocalInputResolution = 1 / (float)inputResolution; | |
+ private const int outputResolution = 32767 - (-32768); | |
public const int DS4_CONTROLLER_COUNT = 4; | |
public DS4Device[] DS4Controllers = new DS4Device[DS4_CONTROLLER_COUNT]; | |
public Mouse[] touchPad = new Mouse[DS4_CONTROLLER_COUNT]; | |
@@ -28,6 +35,10 @@ namespace DS4Windows | |
bool[] buttonsdown = new bool[4] { false, false, false, false }; | |
bool[] held = new bool[DS4_CONTROLLER_COUNT]; | |
int[] oldmouse = new int[DS4_CONTROLLER_COUNT] { -1, -1, -1, -1 }; | |
+ public Xbox360Controller[] x360controls = new Xbox360Controller[4] { null, null, null, null }; | |
+ private Xbox360Report[] x360reports = new Xbox360Report[4] { new Xbox360Report(), new Xbox360Report(), | |
+ new Xbox360Report(), new Xbox360Report() | |
+ }; | |
Thread tempThread; | |
public List<string> affectedDevs = new List<string>() | |
{ | |
@@ -39,6 +50,7 @@ namespace DS4Windows | |
}; | |
public bool suspending; | |
//SoundPlayer sp = new SoundPlayer(); | |
+ private UdpServer _udpServer; | |
private class X360Data | |
{ | |
@@ -48,6 +60,75 @@ namespace DS4Windows | |
private X360Data[] processingData = new X360Data[4]; | |
+ void GetPadDetailForIdx(int padIdx, ref DualShockPadMeta meta) | |
+ { | |
+ //meta = new DualShockPadMeta(); | |
+ meta.PadId = (byte) padIdx; | |
+ meta.Model = DsModel.DS4; | |
+ | |
+ var d = DS4Controllers[padIdx]; | |
+ if (d == null) | |
+ { | |
+ meta.PadMacAddress = null; | |
+ meta.PadState = DsState.Disconnected; | |
+ meta.ConnectionType = DsConnection.None; | |
+ meta.Model = DsModel.None; | |
+ meta.BatteryStatus = 0; | |
+ meta.IsActive = false; | |
+ | |
+ //return meta; | |
+ } | |
+ | |
+ bool isValidSerial = false; | |
+ //if (d.isValidSerial()) | |
+ //{ | |
+ string stringMac = d.getMacAddress(); | |
+ if (!string.IsNullOrEmpty(stringMac)) | |
+ { | |
+ stringMac = string.Join("", stringMac.Split(':')); | |
+ //stringMac = stringMac.Replace(":", "").Trim(); | |
+ meta.PadMacAddress = System.Net.NetworkInformation.PhysicalAddress.Parse(stringMac); | |
+ isValidSerial = d.isValidSerial(); | |
+ } | |
+ //} | |
+ | |
+ if (!isValidSerial) | |
+ { | |
+ //meta.PadMacAddress = null; | |
+ meta.PadState = DsState.Disconnected; | |
+ } | |
+ else | |
+ { | |
+ if (d.isSynced() || d.IsAlive()) | |
+ meta.PadState = DsState.Connected; | |
+ else | |
+ meta.PadState = DsState.Reserved; | |
+ } | |
+ | |
+ meta.ConnectionType = (d.getConnectionType() == ConnectionType.USB) ? DsConnection.Usb : DsConnection.Bluetooth; | |
+ meta.IsActive = !d.isDS4Idle(); | |
+ | |
+ if (d.isCharging() && d.getBattery() >= 100) | |
+ meta.BatteryStatus = DsBattery.Charged; | |
+ else | |
+ { | |
+ if (d.getBattery() >= 95) | |
+ meta.BatteryStatus = DsBattery.Full; | |
+ else if (d.getBattery() >= 70) | |
+ meta.BatteryStatus = DsBattery.High; | |
+ else if (d.getBattery() >= 50) | |
+ meta.BatteryStatus = DsBattery.Medium; | |
+ else if (d.getBattery() >= 20) | |
+ meta.BatteryStatus = DsBattery.Low; | |
+ else if (d.getBattery() >= 5) | |
+ meta.BatteryStatus = DsBattery.Dying; | |
+ else | |
+ meta.BatteryStatus = DsBattery.None; | |
+ } | |
+ | |
+ //return meta; | |
+ } | |
+ | |
public ControlService() | |
{ | |
//sp.Stream = Properties.Resources.EE; | |
@@ -70,6 +151,8 @@ namespace DS4Windows | |
PreviousState[i] = new DS4State(); | |
ExposedState[i] = new DS4StateExposed(CurrentState[i]); | |
} | |
+ | |
+ _udpServer = new UdpServer(GetPadDetailForIdx); | |
} | |
private void WarnExclusiveModeFailure(DS4Device device) | |
@@ -122,14 +205,44 @@ namespace DS4Windows | |
return unplugResult; | |
} | |
+ private void startViGEm() | |
+ { | |
+ tempThread = new Thread(() => { try { vigemTestClient = new ViGEmClient(); } catch { } }); | |
+ tempThread.Priority = ThreadPriority.AboveNormal; | |
+ tempThread.IsBackground = true; | |
+ tempThread.Start(); | |
+ while (tempThread.IsAlive) | |
+ { | |
+ Thread.SpinWait(500); | |
+ } | |
+ } | |
+ | |
+ private void stopViGEm() | |
+ { | |
+ if (tempThread != null) | |
+ { | |
+ tempThread.Interrupt(); | |
+ tempThread.Join(); | |
+ tempThread = null; | |
+ } | |
+ | |
+ if (vigemTestClient != null) | |
+ { | |
+ vigemTestClient.Dispose(); | |
+ vigemTestClient = null; | |
+ } | |
+ } | |
+ | |
public bool Start(object tempui, bool showlog = true) | |
{ | |
- if (x360Bus.Open() && x360Bus.Start()) | |
+ startViGEm(); | |
+ if (vigemTestClient != null) | |
+ //if (x360Bus.Open() && x360Bus.Start()) | |
{ | |
if (showlog) | |
LogDebug(Properties.Resources.Starting); | |
- LogDebug("Connection to Scp Virtual Bus established"); | |
+ LogDebug("Connection to ViGEm established"); | |
DS4Devices.isExclusiveMode = getUseExclusiveMode(); | |
if (showlog) | |
@@ -176,11 +289,17 @@ namespace DS4Windows | |
if (!getDInputOnly(i) && device.isSynced()) | |
{ | |
- int xinputIndex = x360Bus.FirstController + i; | |
- LogDebug("Plugging in X360 Controller #" + xinputIndex); | |
- bool xinputResult = x360Bus.Plugin(i); | |
- LogDebug("X360 Controller # " + xinputIndex + " connected"); | |
+ //int xinputIndex = x360Bus.FirstController + i; | |
+ LogDebug("Plugging in X360 Controller #" + (i + 1)); | |
useDInputOnly[i] = false; | |
+ x360controls[i] = new Xbox360Controller(vigemTestClient); | |
+ x360controls[i].Connect(); | |
+ int devIndex = i; | |
+ x360controls[i].FeedbackReceived += (sender, args) => | |
+ { | |
+ setRumble(args.SmallMotor, args.LargeMotor, devIndex); | |
+ }; | |
+ LogDebug("X360 Controller # " + (i + 1) + " connected"); | |
} | |
device.Report += this.On_Report; | |
@@ -216,10 +335,28 @@ namespace DS4Windows | |
} | |
running = true; | |
+ | |
+ if (_udpServer != null) | |
+ { | |
+ var UDP_SERVER_PORT = 26760; | |
+ | |
+ try | |
+ { | |
+ _udpServer.Start(UDP_SERVER_PORT); | |
+ LogDebug("UDP server listening on port " + UDP_SERVER_PORT); | |
+ } | |
+ catch (System.Net.Sockets.SocketException ex) | |
+ { | |
+ var errMsg = String.Format("Couldn't start UDP server on port {0}, outside applications won't be able to access pad data ({1})", UDP_SERVER_PORT, ex.SocketErrorCode); | |
+ | |
+ LogDebug(errMsg, true); | |
+ Log.LogToTray(errMsg, true, true); | |
+ } | |
+ } | |
} | |
else | |
{ | |
- string logMessage = "Could not connect to Scp Virtual Bus Driver. Please check the status of the System device in Device Manager"; | |
+ string logMessage = "Could not connect to ViGEm. Please check the status of the System device in Device Manager"; | |
LogDebug(logMessage); | |
Log.LogToTray(logMessage); | |
} | |
@@ -238,9 +375,8 @@ namespace DS4Windows | |
if (showlog) | |
LogDebug(Properties.Resources.StoppingX360); | |
- LogDebug("Closing connection to Scp Virtual Bus"); | |
+ LogDebug("Closing connection to ViGEm"); | |
- bool anyUnplugged = false; | |
for (int i = 0, arlength = DS4Controllers.Length; i < arlength; i++) | |
{ | |
DS4Device tempDevice = DS4Controllers[i]; | |
@@ -272,9 +408,9 @@ namespace DS4Windows | |
} | |
CurrentState[i].Battery = PreviousState[i].Battery = 0; // Reset for the next connection's initial status change. | |
- x360Bus.Unplug(i); | |
+ x360controls[i]?.Disconnect(); | |
+ x360controls[i] = null; | |
useDInputOnly[i] = true; | |
- anyUnplugged = true; | |
DS4Controllers[i] = null; | |
touchPad[i] = null; | |
lag[i] = false; | |
@@ -282,18 +418,18 @@ namespace DS4Windows | |
} | |
} | |
- if (anyUnplugged) | |
- Thread.Sleep(XINPUT_UNPLUG_SETTLE_TIME); | |
- | |
- x360Bus.UnplugAll(); | |
- x360Bus.Stop(); | |
- | |
if (showlog) | |
LogDebug(Properties.Resources.StoppingDS4); | |
DS4Devices.stopControllers(); | |
+ | |
+ if (_udpServer != null) | |
+ _udpServer.Stop(); | |
+ | |
if (showlog) | |
LogDebug(Properties.Resources.StoppedDS4Windows); | |
+ | |
+ stopViGEm(); | |
} | |
runHotPlug = false; | |
@@ -358,11 +494,17 @@ namespace DS4Windows | |
device.Report += this.On_Report; | |
if (!getDInputOnly(Index) && device.isSynced()) | |
{ | |
- int xinputIndex = x360Bus.FirstController + Index; | |
- LogDebug("Plugging in X360 Controller #" + xinputIndex); | |
- bool xinputResult = x360Bus.Plugin(Index); | |
- LogDebug("X360 Controller # " + xinputIndex + " connected"); | |
+ //int xinputIndex = x360Bus.FirstController + Index; | |
+ LogDebug("Plugging in X360 Controller #" + (Index + 1)); | |
useDInputOnly[Index] = false; | |
+ x360controls[Index] = new Xbox360Controller(vigemTestClient); | |
+ x360controls[Index].Connect(); | |
+ int devIndex = Index; | |
+ x360controls[Index].FeedbackReceived += (sender, args) => | |
+ { | |
+ setRumble(args.SmallMotor, args.LargeMotor, devIndex); | |
+ }; | |
+ LogDebug("X360 Controller # " + (Index + 1) + " connected"); | |
} | |
TouchPadOn(Index, device); | |
@@ -392,6 +534,49 @@ namespace DS4Windows | |
return true; | |
} | |
+ private void testNewReport(ref Xbox360Report xboxreport, DS4State state) | |
+ { | |
+ Xbox360Buttons tempButtons = 0; | |
+ | |
+ if (state.Share) tempButtons |= Xbox360Buttons.Back; | |
+ if (state.L3) tempButtons |= Xbox360Buttons.LeftThumb; | |
+ if (state.R3) tempButtons |= Xbox360Buttons.RightThumb; | |
+ if (state.Options) tempButtons |= Xbox360Buttons.Start; | |
+ | |
+ if (state.DpadUp) tempButtons |= Xbox360Buttons.Up; | |
+ if (state.DpadRight) tempButtons |= Xbox360Buttons.Right; | |
+ if (state.DpadDown) tempButtons |= Xbox360Buttons.Down; | |
+ if (state.DpadLeft) tempButtons |= Xbox360Buttons.Left; | |
+ | |
+ if (state.L1) tempButtons |= Xbox360Buttons.LeftShoulder; | |
+ if (state.R1) tempButtons |= Xbox360Buttons.RightShoulder; | |
+ | |
+ if (state.Triangle) tempButtons |= Xbox360Buttons.Y; | |
+ if (state.Circle) tempButtons |= Xbox360Buttons.B; | |
+ if (state.Cross) tempButtons |= Xbox360Buttons.A; | |
+ if (state.Square) tempButtons |= Xbox360Buttons.X; | |
+ if (state.PS) tempButtons |= Xbox360Buttons.Guide; | |
+ xboxreport.SetButtons(tempButtons); | |
+ | |
+ xboxreport.LeftTrigger = state.L2; | |
+ xboxreport.RightTrigger = state.R2; | |
+ xboxreport.LeftThumbX = AxisScale(state.LX, false); | |
+ xboxreport.LeftThumbY = AxisScale(state.LY, true); | |
+ xboxreport.RightThumbX = AxisScale(state.RX, false); | |
+ xboxreport.RightThumbY = AxisScale(state.RY, true); | |
+ } | |
+ | |
+ private short AxisScale(Int32 Value, Boolean Flip) | |
+ { | |
+ Value -= 0x80; | |
+ | |
+ //float temp = (Value - (-128)) / (float)inputResolution; | |
+ float temp = (Value - (-128)) * reciprocalInputResolution; | |
+ if (Flip) temp = (temp - 0.5f) * -1.0f + 0.5f; | |
+ | |
+ return (short) (temp * outputResolution + (-32768)); | |
+ } | |
+ | |
private void CheckProfileOptions(int ind, DS4Device device, bool startUp=false) | |
{ | |
device.setIdleTimeout(getIdleDisconnectTimeout(ind)); | |
@@ -607,21 +792,25 @@ namespace DS4Windows | |
{ | |
if (!useDInputOnly[ind]) | |
{ | |
- bool unplugResult = x360Bus.Unplug(ind); | |
- int xinputIndex = x360Bus.FirstController + ind; | |
- LogDebug("X360 Controller # " + xinputIndex + " unplugged"); | |
+ x360controls[ind].Disconnect(); | |
+ x360controls[ind] = null; | |
useDInputOnly[ind] = true; | |
+ LogDebug("X360 Controller # " + (ind + 1) + " unplugged"); | |
} | |
} | |
else | |
{ | |
if (!getDInputOnly(ind)) | |
{ | |
- int xinputIndex = x360Bus.FirstController + ind; | |
- LogDebug("Plugging in X360 Controller #" + xinputIndex); | |
- bool xinputResult = x360Bus.Plugin(ind); | |
- LogDebug("X360 Controller # " + xinputIndex + " connected"); | |
+ LogDebug("Plugging in X360 Controller #" + (ind + 1)); | |
+ x360controls[ind] = new Xbox360Controller(vigemTestClient); | |
+ x360controls[ind].Connect(); | |
+ x360controls[ind].FeedbackReceived += (eventsender, args) => | |
+ { | |
+ setRumble(args.SmallMotor, args.LargeMotor, ind); | |
+ }; | |
useDInputOnly[ind] = false; | |
+ LogDebug("X360 Controller # " + (ind + 1) + " connected"); | |
} | |
} | |
} | |
@@ -655,9 +844,9 @@ namespace DS4Windows | |
CurrentState[ind].Battery = PreviousState[ind].Battery = 0; // Reset for the next connection's initial status change. | |
if (!useDInputOnly[ind]) | |
{ | |
- bool unplugResult = x360Bus.Unplug(ind); | |
- int xinputIndex = x360Bus.FirstController + ind; | |
- LogDebug("X360 Controller # " + xinputIndex + " unplugged"); | |
+ x360controls[ind].Disconnect(); | |
+ x360controls[ind] = null; | |
+ LogDebug("X360 Controller # " + (ind + 1) + " unplugged"); | |
} | |
string removed = Properties.Resources.ControllerWasRemoved.Replace("*Mac address*", (ind + 1).ToString()); | |
@@ -688,7 +877,6 @@ namespace DS4Windows | |
inWarnMonitor[ind] = false; | |
useDInputOnly[ind] = true; | |
OnControllerRemoved(this, ind); | |
- Thread.Sleep(XINPUT_UNPLUG_SETTLE_TIME); | |
} | |
} | |
} | |
@@ -793,10 +981,12 @@ namespace DS4Windows | |
if (!useDInputOnly[ind]) | |
{ | |
- x360Bus.Parse(cState, processingData[ind].Report, ind); | |
+ testNewReport(ref x360reports[ind], cState); | |
+ x360controls[ind]?.SendReport(x360reports[ind]); | |
+ //x360Bus.Parse(cState, processingData[ind].Report, ind); | |
// We push the translated Xinput state, and simultaneously we | |
// pull back any possible rumble data coming from Xinput consumers. | |
- if (x360Bus.Report(processingData[ind].Report, processingData[ind].Rumble)) | |
+ /*if (x360Bus.Report(processingData[ind].Report, processingData[ind].Rumble)) | |
{ | |
byte Big = processingData[ind].Rumble[3]; | |
byte Small = processingData[ind].Rumble[4]; | |
@@ -806,6 +996,14 @@ namespace DS4Windows | |
setRumble(Big, Small, ind); | |
} | |
} | |
+ */ | |
+ } | |
+ | |
+ if (_udpServer != null) | |
+ { | |
+ DualShockPadMeta padDetail = new DualShockPadMeta(); | |
+ GetPadDetailForIdx(ind, ref padDetail); | |
+ _udpServer.NewReportIncoming(ref padDetail, CurrentState[ind]); | |
} | |
// Output any synthetic events. | |
diff --git a/DS4Windows/DS4Control/ScpUtil.cs b/DS4Windows/DS4Control/ScpUtil.cs | |
index 807a926..e67a646 100644 | |
--- a/DS4Windows/DS4Control/ScpUtil.cs | |
+++ b/DS4Windows/DS4Control/ScpUtil.cs | |
@@ -315,9 +315,9 @@ namespace DS4Windows | |
dataBuffer, dataBuffer.Length, ref requiredSize, 0)) | |
{ | |
string hardwareId = dataBuffer.ToUTF16String(); | |
- //if (hardwareIds.Contains("Scp Virtual Bus Driver")) | |
+ //if (hardwareIds.Contains("Virtual Gamepad Emulation Bus")) | |
// result = true; | |
- if (hardwareId.Equals(@"root\ScpVBus")) | |
+ if (hardwareId.Equals(@"Root\ViGEmBus")) | |
result = true; | |
} | |
} | |
@@ -2843,15 +2843,15 @@ namespace DS4Windows | |
tempDev.setBTPollRate(btPollRate[device]); | |
if (xinputStatus && xinputPlug) | |
{ | |
- bool xinputResult = control.x360Bus.Plugin(device); | |
- int xinputIndex = control.x360Bus.FirstController + device; | |
- Log.LogToGui("X360 Controller # " + xinputIndex + " connected", false); | |
+ control.x360controls[device] = new Nefarius.ViGEm.Client.Targets.Xbox360Controller(control.vigemTestClient); | |
+ control.x360controls[device].Connect(); | |
+ Log.LogToGui("X360 Controller # " + (device + 1) + " connected", false); | |
} | |
else if (xinputStatus && !xinputPlug) | |
{ | |
- bool xinputResult = control.x360Bus.Unplug(device); | |
- int xinputIndex = control.x360Bus.FirstController + device; | |
- Log.LogToGui("X360 Controller # " + xinputIndex + " unplugged", false); | |
+ control.x360controls[device].Disconnect(); | |
+ control.x360controls[device] = null; | |
+ Log.LogToGui("X360 Controller # " + (device + 1) + " unplugged", false); | |
} | |
tempDev.setRumble(0, 0); | |
diff --git a/DS4Windows/DS4Forms/DS4Form.cs b/DS4Windows/DS4Forms/DS4Form.cs | |
index 3ab369c..450a311 100644 | |
--- a/DS4Windows/DS4Forms/DS4Form.cs | |
+++ b/DS4Windows/DS4Forms/DS4Form.cs | |
@@ -202,7 +202,7 @@ namespace DS4Windows | |
cBDisconnectBT.Checked = DCBTatStop; | |
cBQuickCharge.Checked = QuickCharge; | |
nUDXIPorts.Value = FirstXinputPort; | |
- Program.rootHub.x360Bus.FirstController = FirstXinputPort; | |
+ //Program.rootHub.x360Bus.FirstController = FirstXinputPort; | |
// New settings | |
this.Width = FormWidth; | |
this.Height = FormHeight; | |
@@ -2185,7 +2185,7 @@ Properties.Resources.DS4Update, MessageBoxButtons.YesNo, MessageBoxIcon.Question | |
{ | |
oldxiport = (int)Math.Round(nUDXIPorts.Value, 0); | |
FirstXinputPort = oldxiport; | |
- Program.rootHub.x360Bus.FirstController = oldxiport; | |
+ //Program.rootHub.x360Bus.FirstController = oldxiport; | |
BtnStartStop_Clicked(false); | |
finishHideDS4Check(); | |
} | |
diff --git a/DS4Windows/DS4Library/DS4Device.cs b/DS4Windows/DS4Library/DS4Device.cs | |
index df58fec..d777cfc 100644 | |
--- a/DS4Windows/DS4Library/DS4Device.cs | |
+++ b/DS4Windows/DS4Library/DS4Device.cs | |
@@ -771,7 +771,7 @@ namespace DS4Windows | |
//Console.WriteLine(MacAddress.ToString() + " " + System.DateTime.UtcNow.ToString("o") + "" + | |
// "> invalid CRC32 in BT input report: 0x" + recvCrc32.ToString("X8") + " expected: 0x" + calcCrc32.ToString("X8")); | |
- //cState.PacketCounter = pState.PacketCounter + 1; //still increase so we know there were lost packets | |
+ cState.PacketCounter = pState.PacketCounter + 1; //still increase so we know there were lost packets | |
continue; | |
} | |
} | |
@@ -854,6 +854,7 @@ namespace DS4Windows | |
utcNow = DateTime.UtcNow; // timestamp with UTC in case system time zone changes | |
resetHapticState(); | |
+ cState.PacketCounter = pState.PacketCounter + 1; | |
cState.ReportTimeStamp = utcNow; | |
cState.LX = inputReport[1]; | |
cState.LY = inputReport[2]; | |
@@ -891,6 +892,8 @@ namespace DS4Windows | |
cState.L3 = (tempByte & (1 << 6)) != 0; | |
cState.Options = (tempByte & (1 << 5)) != 0; | |
cState.Share = (tempByte & (1 << 4)) != 0; | |
+ cState.R2Btn = (inputReport[6] & (1 << 3)) != 0; | |
+ cState.L2Btn = (inputReport[6] & (1 << 2)) != 0; | |
cState.R1 = (tempByte & (1 << 1)) != 0; | |
cState.L1 = (tempByte & (1 << 0)) != 0; | |
@@ -932,6 +935,18 @@ namespace DS4Windows | |
timeStampPrevious = tempStamp; | |
elapsedDeltaTime = 0.000001 * deltaTimeCurrent; // Convert from microseconds to seconds | |
cState.elapsedTime = elapsedDeltaTime; | |
+ cState.totalMicroSec = pState.totalMicroSec + deltaTimeCurrent; | |
+ | |
+ //Simpler touch storing | |
+ cState.TrackPadTouch0.Id = (byte)(inputReport[35] & 0x7f); | |
+ cState.TrackPadTouch0.IsActive = (inputReport[35] & 0x80) == 0; | |
+ cState.TrackPadTouch0.X = (short)(((ushort)(inputReport[37] & 0x0f) << 8) | (ushort)(inputReport[36])); | |
+ cState.TrackPadTouch0.Y = (short)(((ushort)(inputReport[38]) << 4) | ((ushort)(inputReport[37] & 0xf0) >> 4)); | |
+ | |
+ cState.TrackPadTouch1.Id = (byte)(inputReport[39] & 0x7f); | |
+ cState.TrackPadTouch1.IsActive = (inputReport[39] & 0x80) == 0; | |
+ cState.TrackPadTouch1.X = (short)(((ushort)(inputReport[41] & 0x0f) << 8) | (ushort)(inputReport[40])); | |
+ cState.TrackPadTouch1.Y = (short)(((ushort)(inputReport[42]) << 4) | ((ushort)(inputReport[41] & 0xf0) >> 4)); | |
// XXX DS4State mapping needs fixup, turn touches into an array[4] of structs. And include the touchpad details there instead. | |
try | |
@@ -1349,7 +1364,7 @@ namespace DS4Windows | |
return pState; | |
} | |
- private bool isDS4Idle() | |
+ public bool isDS4Idle() | |
{ | |
if (cState.Square || cState.Cross || cState.Circle || cState.Triangle) | |
return false; | |
diff --git a/DS4Windows/DS4Library/DS4State.cs b/DS4Windows/DS4Library/DS4State.cs | |
index 66982eb..2978c2c 100644 | |
--- a/DS4Windows/DS4Library/DS4State.cs | |
+++ b/DS4Windows/DS4Library/DS4State.cs | |
@@ -4,10 +4,11 @@ namespace DS4Windows | |
{ | |
public class DS4State | |
{ | |
+ public uint PacketCounter; | |
public DateTime ReportTimeStamp; | |
public bool Square, Triangle, Circle, Cross; | |
public bool DpadUp, DpadDown, DpadLeft, DpadRight; | |
- public bool L1, L3, R1, R3; | |
+ public bool L1, L2Btn, L3, R1, R2Btn, R3; | |
public bool Share, Options, PS, Touch1, Touch2, TouchButton, TouchRight, | |
TouchLeft, Touch1Finger, Touch2Fingers; | |
public byte Touch1Identifier, Touch2Identifier; | |
@@ -24,14 +25,27 @@ namespace DS4Windows | |
public double RXUnit; | |
public double RYUnit; | |
public double elapsedTime = 0.0; | |
+ public ulong totalMicroSec = 0; | |
public SixAxis Motion = null; | |
public static readonly int DEFAULT_AXISDIR_VALUE = 127; | |
+ public struct TrackPadTouch | |
+ { | |
+ public bool IsActive; | |
+ public byte Id; | |
+ public short X; | |
+ public short Y; | |
+ } | |
+ | |
+ public TrackPadTouch TrackPadTouch0; | |
+ public TrackPadTouch TrackPadTouch1; | |
+ | |
public DS4State() | |
{ | |
+ PacketCounter = 0; | |
Square = Triangle = Circle = Cross = false; | |
DpadUp = DpadDown = DpadLeft = DpadRight = false; | |
- L1 = L3 = R1 = R3 = false; | |
+ L1 = L2Btn = L3 = R1 = R2Btn = R3 = false; | |
Share = Options = PS = Touch1 = Touch2 = TouchButton = TouchRight = TouchLeft = false; | |
Touch1Finger = Touch2Fingers = false; | |
LX = RX = LY = RY = 127; | |
@@ -48,11 +62,15 @@ namespace DS4Windows | |
RXUnit = 0.0; | |
RYUnit = 0.0; | |
elapsedTime = 0.0; | |
+ totalMicroSec = 0; | |
Motion = new SixAxis(0, 0, 0, 0, 0, 0, 0.0); | |
+ TrackPadTouch0.IsActive = false; | |
+ TrackPadTouch1.IsActive = false; | |
} | |
public DS4State(DS4State state) | |
{ | |
+ PacketCounter = state.PacketCounter; | |
ReportTimeStamp = state.ReportTimeStamp; | |
Square = state.Square; | |
Triangle = state.Triangle; | |
@@ -64,9 +82,11 @@ namespace DS4Windows | |
DpadRight = state.DpadRight; | |
L1 = state.L1; | |
L2 = state.L2; | |
+ L2Btn = state.L2Btn; | |
L3 = state.L3; | |
R1 = state.R1; | |
R2 = state.R2; | |
+ R2Btn = state.R2Btn; | |
R3 = state.R3; | |
Share = state.Share; | |
Options = state.Options; | |
@@ -96,7 +116,10 @@ namespace DS4Windows | |
RXUnit = state.RXUnit; | |
RYUnit = state.RYUnit; | |
elapsedTime = state.elapsedTime; | |
+ totalMicroSec = state.totalMicroSec; | |
Motion = state.Motion; | |
+ TrackPadTouch0 = state.TrackPadTouch0; | |
+ TrackPadTouch1 = state.TrackPadTouch1; | |
} | |
public DS4State Clone() | |
@@ -106,6 +129,7 @@ namespace DS4Windows | |
public void CopyTo(DS4State state) | |
{ | |
+ state.PacketCounter = PacketCounter; | |
state.ReportTimeStamp = ReportTimeStamp; | |
state.Square = Square; | |
state.Triangle = Triangle; | |
@@ -117,9 +141,11 @@ namespace DS4Windows | |
state.DpadRight = DpadRight; | |
state.L1 = L1; | |
state.L2 = L2; | |
+ state.L2Btn = L2Btn; | |
state.L3 = L3; | |
state.R1 = R1; | |
state.R2 = R2; | |
+ state.R2Btn = R2Btn; | |
state.R3 = R3; | |
state.Share = Share; | |
state.Options = Options; | |
@@ -149,7 +175,10 @@ namespace DS4Windows | |
state.RXUnit = RXUnit; | |
state.RYUnit = RYUnit; | |
state.elapsedTime = elapsedTime; | |
+ state.totalMicroSec = totalMicroSec; | |
state.Motion = Motion; | |
+ state.TrackPadTouch0 = TrackPadTouch0; | |
+ state.TrackPadTouch1 = TrackPadTouch1; | |
} | |
public void calculateStickAngles() | |
diff --git a/DS4Windows/DS4Windows.csproj b/DS4Windows/DS4Windows.csproj | |
index a6353ce..b6868f2 100644 | |
--- a/DS4Windows/DS4Windows.csproj | |
+++ b/DS4Windows/DS4Windows.csproj | |
@@ -123,6 +123,9 @@ | |
<Reference Include="Microsoft.Win32.TaskScheduler, Version=2.7.2.0, Culture=neutral, PublicKeyToken=c416bc1b32d97233, processorArchitecture=MSIL"> | |
<HintPath>..\packages\TaskScheduler.2.7.2\lib\net452\Microsoft.Win32.TaskScheduler.dll</HintPath> | |
</Reference> | |
+ <Reference Include="Nefarius.ViGEmClient"> | |
+ <HintPath>..\bin\Nefarius.ViGEmClient\Nefarius.ViGEmClient.dll</HintPath> | |
+ </Reference> | |
<Reference Include="System" /> | |
<Reference Include="System.Core" /> | |
<Reference Include="System.IO.Compression" /> | |
@@ -158,6 +161,7 @@ | |
<DependentUpon>ScpHub.cs</DependentUpon> | |
</Compile> | |
<Compile Include="DS4Control\ScpUtil.cs" /> | |
+ <Compile Include="DS4Control\UdpServer.cs" /> | |
<Compile Include="DS4Control\X360Device.cs"> | |
<SubType>Component</SubType> | |
</Compile> | |
@@ -1235,4 +1239,4 @@ for %25%25l in (%25langs%25) do ( | |
<Target Name="AfterBuild"> | |
</Target> | |
--> | |
-</Project> | |
\ No newline at end of file | |
+</Project> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment