From dc5e34f1be2e29cd35c2eebd440682e809780a03 Mon Sep 17 00:00:00 2001 From: Travis Nickles Date: Wed, 17 Apr 2019 21:29:16 -0500 Subject: [PATCH] Test DS4 emulation --- DS4Windows/DS4Control/ControlService.cs | 84 +++++++++---- DS4Windows/DS4Control/DS4OutDevice.cs | 83 +++++++++++++ DS4Windows/DS4Control/OutputDevice.cs | 15 +++ DS4Windows/DS4Control/ScpUtil.cs | 43 ++++++- DS4Windows/DS4Control/Xbox360OutDevice.cs | 141 ++++++++++++++++++++++ DS4Windows/DS4Library/DS4Devices.cs | 10 ++ DS4Windows/DS4Windows.csproj | 3 + DS4Windows/HidLibrary/NativeMethods.cs | 3 + 8 files changed, 355 insertions(+), 27 deletions(-) create mode 100644 DS4Windows/DS4Control/DS4OutDevice.cs create mode 100644 DS4Windows/DS4Control/OutputDevice.cs create mode 100644 DS4Windows/DS4Control/Xbox360OutDevice.cs diff --git a/DS4Windows/DS4Control/ControlService.cs b/DS4Windows/DS4Control/ControlService.cs index fd5f350..c38b1e2 100644 --- a/DS4Windows/DS4Control/ControlService.cs +++ b/DS4Windows/DS4Control/ControlService.cs @@ -11,15 +11,13 @@ using System.Diagnostics; using Nefarius.ViGEm.Client; using Nefarius.ViGEm.Client.Targets; using Nefarius.ViGEm.Client.Targets.Xbox360; +using Nefarius.ViGEm.Client.Targets.DualShock4; namespace DS4Windows { public class ControlService { 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]; @@ -34,10 +32,12 @@ 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(), + public OutputDevice[] outputDevices = new OutputDevice[4] { null, null, null, null }; + //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 affectedDevs = new List() { @@ -424,14 +424,28 @@ namespace DS4Windows { LogDebug("Plugging in X360 Controller #" + (i + 1)); useDInputOnly[i] = false; - x360controls[i] = new Xbox360Controller(vigemTestClient); + + DS4OutDevice tempDS4 = new DS4OutDevice(vigemTestClient); + outputDevices[i] = tempDS4; int devIndex = i; - x360controls[i].FeedbackReceived += (sender, args) => + tempDS4.cont.FeedbackReceived += (sender, args) => { SetDevRumble(device, args.LargeMotor, args.SmallMotor, devIndex); }; - - x360controls[i].Connect(); + + tempDS4.Connect(); + //x360controls[i] = new Xbox360Controller(vigemTestClient); + /*Xbox360Controller bacon = new Xbox360Controller(vigemTestClient); + Xbox360OutDevice tempXbox = new Xbox360OutDevice(vigemTestClient); + outputDevices[i] = tempXbox; + int devIndex = i; + tempXbox.cont.FeedbackReceived += (sender, args) => + { + SetDevRumble(device, args.LargeMotor, args.SmallMotor, devIndex); + }; + + tempXbox.Connect(); + */ LogDebug("X360 Controller #" + (i + 1) + " connected"); } else @@ -568,8 +582,10 @@ namespace DS4Windows } CurrentState[i].Battery = PreviousState[i].Battery = 0; // Reset for the next connection's initial status change. - x360controls[i]?.Disconnect(); - x360controls[i] = null; + //x360controls[i]?.Disconnect(); + outputDevices[i]?.Disconnect(); + outputDevices[i] = null; + //x360controls[i] = null; useDInputOnly[i] = true; DS4Controllers[i] = null; touchPad[i] = null; @@ -681,14 +697,18 @@ namespace DS4Windows { LogDebug("Plugging in X360 Controller #" + (Index + 1)); useDInputOnly[Index] = false; - x360controls[Index] = new Xbox360Controller(vigemTestClient); + //x360controls[Index] = new Xbox360Controller(vigemTestClient); + Xbox360OutDevice tempXbox = new Xbox360OutDevice(vigemTestClient); + outputDevices[Index] = tempXbox; int devIndex = Index; - x360controls[Index].FeedbackReceived += (sender, args) => + //x360controls[Index].FeedbackReceived += (sender, args) => + tempXbox.cont.FeedbackReceived += (sender, args) => { SetDevRumble(device, args.LargeMotor, args.SmallMotor, devIndex); }; - - x360controls[Index].Connect(); + + //x360controls[Index].Connect(); + tempXbox.Connect(); LogDebug("X360 Controller #" + (Index + 1) + " connected"); } else @@ -723,7 +743,7 @@ namespace DS4Windows return true; } - private void testNewReport(ref Xbox360Report xboxreport, DS4State state, + /*private void testNewReport(ref Xbox360Report xboxreport, DS4State state, int device) { Xbox360Buttons tempButtons = 0; @@ -818,8 +838,9 @@ namespace DS4Windows goto case SASteeringWheelEmulationAxisType.None; } } + */ - private short AxisScale(Int32 Value, Boolean Flip) + /*private short AxisScale(Int32 Value, Boolean Flip) { unchecked { @@ -832,6 +853,7 @@ namespace DS4Windows return (short)(temp * outputResolution + (-32768)); } } + */ private void CheckProfileOptions(int ind, DS4Device device, bool startUp=false) { @@ -1048,8 +1070,8 @@ namespace DS4Windows { if (!useDInputOnly[ind]) { - x360controls[ind].Disconnect(); - x360controls[ind] = null; + outputDevices[ind].Disconnect(); + outputDevices[ind] = null; useDInputOnly[ind] = true; LogDebug("X360 Controller #" + (ind + 1) + " unplugged"); } @@ -1059,13 +1081,23 @@ namespace DS4Windows if (!getDInputOnly(ind)) { LogDebug("Plugging in X360 Controller #" + (ind + 1)); - x360controls[ind] = new Xbox360Controller(vigemTestClient); + Xbox360OutDevice tempXbox = new Xbox360OutDevice(vigemTestClient); + outputDevices[ind] = tempXbox; + tempXbox.cont.FeedbackReceived += (eventsender, args) => + { + SetDevRumble(device, args.LargeMotor, args.SmallMotor, ind); + }; + + tempXbox.Connect(); + + /*x360controls[ind] = new Xbox360Controller(vigemTestClient); x360controls[ind].FeedbackReceived += (eventsender, args) => { SetDevRumble(device, args.LargeMotor, args.SmallMotor, ind); }; x360controls[ind].Connect(); + */ useDInputOnly[ind] = false; LogDebug("X360 Controller #" + (ind + 1) + " connected"); } @@ -1101,8 +1133,10 @@ namespace DS4Windows CurrentState[ind].Battery = PreviousState[ind].Battery = 0; // Reset for the next connection's initial status change. if (!useDInputOnly[ind]) { - x360controls[ind].Disconnect(); - x360controls[ind] = null; + outputDevices[ind].Disconnect(); + outputDevices[ind] = null; + //x360controls[ind].Disconnect(); + //x360controls[ind] = null; LogDebug("X360 Controller # " + (ind + 1) + " unplugged"); } @@ -1241,8 +1275,10 @@ namespace DS4Windows if (!useDInputOnly[ind]) { - testNewReport(ref x360reports[ind], cState, ind); - x360controls[ind]?.SendReport(x360reports[ind]); + outputDevices[ind]?.ConvertandSendReport(cState, ind); + //testNewReport(ref x360reports[ind], cState, ind); + //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. diff --git a/DS4Windows/DS4Control/DS4OutDevice.cs b/DS4Windows/DS4Control/DS4OutDevice.cs new file mode 100644 index 0000000..a1fef13 --- /dev/null +++ b/DS4Windows/DS4Control/DS4OutDevice.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Nefarius.ViGEm.Client; +using Nefarius.ViGEm.Client.Targets; +using Nefarius.ViGEm.Client.Targets.DualShock4; + +namespace DS4Windows +{ + class DS4OutDevice : OutputDevice + { + public DualShock4Controller cont; + private DualShock4Report report; + + public DS4OutDevice(ViGEmClient client) + { + cont = new DualShock4Controller(client); + report = new DualShock4Report(); + } + + public override void ConvertandSendReport(DS4State state, int device) + { + DualShock4Buttons tempButtons = 0; + DualShock4DPadValues tempDPad = DualShock4DPadValues.None; + DualShock4SpecialButtons tempSpecial = 0; + + unchecked + { + if (state.Share) tempButtons |= DualShock4Buttons.Share; + if (state.L3) tempButtons |= DualShock4Buttons.ThumbLeft; + if (state.R3) tempButtons |= DualShock4Buttons.ThumbRight; + if (state.Options) tempButtons |= DualShock4Buttons.Options; + + if (state.DpadUp && state.DpadRight) tempDPad = DualShock4DPadValues.Northeast; + else if (state.DpadUp) tempDPad = DualShock4DPadValues.North; + else if (state.DpadRight && state.DpadDown) tempDPad = DualShock4DPadValues.Southeast; + else if (state.DpadRight) tempDPad = DualShock4DPadValues.East; + else if (state.DpadDown && state.DpadLeft) tempDPad = DualShock4DPadValues.Southwest; + else if (state.DpadDown) tempDPad = DualShock4DPadValues.South; + else if (state.DpadLeft && state.DpadUp) tempDPad = DualShock4DPadValues.Northwest; + else if (state.DpadLeft) tempDPad = DualShock4DPadValues.West; + /*if (state.DpadUp) tempDPad = (state.DpadRight) ? DualShock4DPadValues.Northeast : DualShock4DPadValues.North; + if (state.DpadRight) tempDPad = (state.DpadDown) ? DualShock4DPadValues.Southeast : DualShock4DPadValues.East; + if (state.DpadDown) tempDPad = (state.DpadLeft) ? DualShock4DPadValues.Southwest : DualShock4DPadValues.South; + if (state.DpadLeft) tempDPad = (state.DpadUp) ? DualShock4DPadValues.Northwest : DualShock4DPadValues.West; + */ + + if (state.L1) tempButtons |= DualShock4Buttons.ShoulderLeft; + if (state.R1) tempButtons |= DualShock4Buttons.ShoulderRight; + //if (state.L2Btn) tempButtons |= DualShock4Buttons.TriggerLeft; + //if (state.R2Btn) tempButtons |= DualShock4Buttons.TriggerRight; + if (state.L2 > 0) tempButtons |= DualShock4Buttons.TriggerLeft; + if (state.R2 > 0) tempButtons |= DualShock4Buttons.TriggerRight; + + if (state.Triangle) tempButtons |= DualShock4Buttons.Triangle; + if (state.Circle) tempButtons |= DualShock4Buttons.Circle; + if (state.Cross) tempButtons |= DualShock4Buttons.Cross; + if (state.Square) tempButtons |= DualShock4Buttons.Square; + if (state.PS) tempSpecial |= DualShock4SpecialButtons.Ps; + if (state.TouchButton) tempSpecial |= DualShock4SpecialButtons.Touchpad; + //report.SetButtonsFull(tempButtons); + report.Buttons = (ushort)tempButtons; + report.SetDPad(tempDPad); + report.SpecialButtons = (byte)tempSpecial; + } + + + report.LeftTrigger = state.L2; + report.RightTrigger = state.R2; + report.LeftThumbX = state.LX; + report.LeftThumbY = state.LY; + report.RightThumbX = state.RX; + report.RightThumbY = state.RY; + + cont.SendReport(report); + } + + public override void Connect() => cont.Connect(); + public override void Disconnect() => cont.Disconnect(); + } +} diff --git a/DS4Windows/DS4Control/OutputDevice.cs b/DS4Windows/DS4Control/OutputDevice.cs new file mode 100644 index 0000000..37d76ef --- /dev/null +++ b/DS4Windows/DS4Control/OutputDevice.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DS4Windows +{ + public abstract class OutputDevice + { + public abstract void ConvertandSendReport(DS4State state, int device); + public abstract void Connect(); + public abstract void Disconnect(); + } +} diff --git a/DS4Windows/DS4Control/ScpUtil.cs b/DS4Windows/DS4Control/ScpUtil.cs index 0519925..32ad9fc 100644 --- a/DS4Windows/DS4Control/ScpUtil.cs +++ b/DS4Windows/DS4Control/ScpUtil.cs @@ -335,6 +335,34 @@ namespace DS4Windows return result; } + internal static string GetDeviceProperty(string deviceInstanceId, + NativeMethods.DEVPROPKEY prop) + { + string result = string.Empty; + NativeMethods.SP_DEVINFO_DATA deviceInfoData = new NativeMethods.SP_DEVINFO_DATA(); + deviceInfoData.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(deviceInfoData); + var dataBuffer = new byte[4096]; + ulong propertyType = 0; + var requiredSize = 0; + + Guid hidGuid = new Guid(); + NativeMethods.HidD_GetHidGuid(ref hidGuid); + IntPtr deviceInfoSet = NativeMethods.SetupDiGetClassDevs(ref hidGuid, deviceInstanceId, 0, NativeMethods.DIGCF_PRESENT | NativeMethods.DIGCF_DEVICEINTERFACE); + NativeMethods.SetupDiEnumDeviceInfo(deviceInfoSet, 0, ref deviceInfoData); + if (NativeMethods.SetupDiGetDeviceProperty(deviceInfoSet, ref deviceInfoData, ref prop, ref propertyType, + dataBuffer, dataBuffer.Length, ref requiredSize, 0)) + { + result = dataBuffer.ToUTF16String(); + } + + if (deviceInfoSet.ToInt64() != NativeMethods.INVALID_HANDLE_VALUE) + { + NativeMethods.SetupDiDestroyDeviceInfoList(deviceInfoSet); + } + + return result; + } + public static bool IsHidGuardianInstalled() { return CheckForSysDevice(@"Root\HidGuardian"); @@ -3063,20 +3091,29 @@ namespace DS4Windows tempDev.setBTPollRate(btPollRate[device]); if (xinputStatus && xinputPlug) { - control.x360controls[device] = new Nefarius.ViGEm.Client.Targets.Xbox360Controller(control.vigemTestClient); + Xbox360OutDevice tempXbox = new Xbox360OutDevice(control.vigemTestClient); + control.outputDevices[device] = tempXbox; + tempXbox.cont.FeedbackReceived += (eventsender, args) => + { + control.SetDevRumble(tempDev, args.LargeMotor, args.SmallMotor, device); + }; + + tempXbox.Connect(); + /*control.x360controls[device] = new Nefarius.ViGEm.Client.Targets.Xbox360Controller(control.vigemTestClient); control.x360controls[device].FeedbackReceived += (eventsender, args) => { control.SetDevRumble(tempDev, args.LargeMotor, args.SmallMotor, device); }; control.x360controls[device].Connect(); + */ Global.useDInputOnly[device] = false; AppLogger.LogToGui("X360 Controller #" + (device + 1) + " connected", false); } else if (xinputStatus && !xinputPlug) { - control.x360controls[device].Disconnect(); - control.x360controls[device] = null; + control.outputDevices[device].Disconnect(); + control.outputDevices[device] = null; Global.useDInputOnly[device] = true; AppLogger.LogToGui("X360 Controller #" + (device + 1) + " unplugged", false); } diff --git a/DS4Windows/DS4Control/Xbox360OutDevice.cs b/DS4Windows/DS4Control/Xbox360OutDevice.cs new file mode 100644 index 0000000..f2f83d2 --- /dev/null +++ b/DS4Windows/DS4Control/Xbox360OutDevice.cs @@ -0,0 +1,141 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Nefarius.ViGEm.Client; +using Nefarius.ViGEm.Client.Targets; +using Nefarius.ViGEm.Client.Targets.Xbox360; + +namespace DS4Windows +{ + public class Xbox360OutDevice : OutputDevice + { + private const int inputResolution = 127 - (-128); + private const float reciprocalInputResolution = 1 / (float)inputResolution; + private const int outputResolution = 32767 - (-32768); + + public Xbox360Controller cont; + private Xbox360Report report; + + public Xbox360OutDevice(ViGEmClient client) + { + cont = new Xbox360Controller(client); + report = new Xbox360Report(); + } + + public override void ConvertandSendReport(DS4State state, int device) + { + Xbox360Buttons tempButtons = 0; + + unchecked + { + 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; + report.SetButtonsFull(tempButtons); + } + + report.LeftTrigger = state.L2; + report.RightTrigger = state.R2; + + SASteeringWheelEmulationAxisType steeringWheelMappedAxis = Global.GetSASteeringWheelEmulationAxis(device); + switch (steeringWheelMappedAxis) + { + case SASteeringWheelEmulationAxisType.None: + report.LeftThumbX = AxisScale(state.LX, false); + report.LeftThumbY = AxisScale(state.LY, true); + report.RightThumbX = AxisScale(state.RX, false); + report.RightThumbY = AxisScale(state.RY, true); + break; + + case SASteeringWheelEmulationAxisType.LX: + report.LeftThumbX = (short)state.SASteeringWheelEmulationUnit; + report.LeftThumbY = AxisScale(state.LY, true); + report.RightThumbX = AxisScale(state.RX, false); + report.RightThumbY = AxisScale(state.RY, true); + break; + + case SASteeringWheelEmulationAxisType.LY: + report.LeftThumbX = AxisScale(state.LX, false); + report.LeftThumbY = (short)state.SASteeringWheelEmulationUnit; + report.RightThumbX = AxisScale(state.RX, false); + report.RightThumbY = AxisScale(state.RY, true); + break; + + case SASteeringWheelEmulationAxisType.RX: + report.LeftThumbX = AxisScale(state.LX, false); + report.LeftThumbY = AxisScale(state.LY, true); + report.RightThumbX = (short)state.SASteeringWheelEmulationUnit; + report.RightThumbY = AxisScale(state.RY, true); + break; + + case SASteeringWheelEmulationAxisType.RY: + report.LeftThumbX = AxisScale(state.LX, false); + report.LeftThumbY = AxisScale(state.LY, true); + report.RightThumbX = AxisScale(state.RX, false); + report.RightThumbY = (short)state.SASteeringWheelEmulationUnit; + break; + + case SASteeringWheelEmulationAxisType.L2R2: + report.LeftTrigger = report.RightTrigger = 0; + if (state.SASteeringWheelEmulationUnit >= 0) report.LeftTrigger = (Byte)state.SASteeringWheelEmulationUnit; + else report.RightTrigger = (Byte)state.SASteeringWheelEmulationUnit; + goto case SASteeringWheelEmulationAxisType.None; + + case SASteeringWheelEmulationAxisType.VJoy1X: + case SASteeringWheelEmulationAxisType.VJoy2X: + DS4Windows.VJoyFeeder.vJoyFeeder.FeedAxisValue(state.SASteeringWheelEmulationUnit, ((((uint)steeringWheelMappedAxis) - ((uint)SASteeringWheelEmulationAxisType.VJoy1X)) / 3) + 1, DS4Windows.VJoyFeeder.HID_USAGES.HID_USAGE_X); + goto case SASteeringWheelEmulationAxisType.None; + + case SASteeringWheelEmulationAxisType.VJoy1Y: + case SASteeringWheelEmulationAxisType.VJoy2Y: + DS4Windows.VJoyFeeder.vJoyFeeder.FeedAxisValue(state.SASteeringWheelEmulationUnit, ((((uint)steeringWheelMappedAxis) - ((uint)SASteeringWheelEmulationAxisType.VJoy1X)) / 3) + 1, DS4Windows.VJoyFeeder.HID_USAGES.HID_USAGE_Y); + goto case SASteeringWheelEmulationAxisType.None; + + case SASteeringWheelEmulationAxisType.VJoy1Z: + case SASteeringWheelEmulationAxisType.VJoy2Z: + DS4Windows.VJoyFeeder.vJoyFeeder.FeedAxisValue(state.SASteeringWheelEmulationUnit, ((((uint)steeringWheelMappedAxis) - ((uint)SASteeringWheelEmulationAxisType.VJoy1X)) / 3) + 1, DS4Windows.VJoyFeeder.HID_USAGES.HID_USAGE_Z); + goto case SASteeringWheelEmulationAxisType.None; + + default: + // Should never come here but just in case use the NONE case as default handler.... + goto case SASteeringWheelEmulationAxisType.None; + } + + cont.SendReport(report); + } + + private short AxisScale(Int32 Value, Boolean Flip) + { + unchecked + { + 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)); + } + } + + public override void Connect() => cont.Connect(); + public override void Disconnect() => cont.Disconnect(); + } +} diff --git a/DS4Windows/DS4Library/DS4Devices.cs b/DS4Windows/DS4Library/DS4Devices.cs index 5bd9074..ce039d6 100644 --- a/DS4Windows/DS4Library/DS4Devices.cs +++ b/DS4Windows/DS4Library/DS4Devices.cs @@ -61,12 +61,22 @@ namespace DS4Windows return deviceInstanceId; } + private static bool IsRealDS4(HidDevice hDevice) + { + string deviceInstanceId = devicePathToInstanceId(hDevice.DevicePath); + string temp = Global.GetDeviceProperty(deviceInstanceId, + NativeMethods.DEVPKEY_Device_UINumber); + return string.IsNullOrEmpty(temp); + } + // Enumerates ds4 controllers in the system public static void findControllers() { lock (Devices) { IEnumerable hDevices = HidDevices.EnumerateDS4(knownDevices); + hDevices = hDevices.Where(dev => IsRealDS4(dev)).Select(dev => dev); + //hDevices = from dev in hDevices where IsRealDS4(dev) select dev; // Sort Bluetooth first in case USB is also connected on the same controller. hDevices = hDevices.OrderBy((HidDevice d) => { return DS4Device.HidConnectionType(d); }); diff --git a/DS4Windows/DS4Windows.csproj b/DS4Windows/DS4Windows.csproj index 591d71b..0a3e6a1 100644 --- a/DS4Windows/DS4Windows.csproj +++ b/DS4Windows/DS4Windows.csproj @@ -138,6 +138,7 @@ + @@ -146,9 +147,11 @@ + + UserControl diff --git a/DS4Windows/HidLibrary/NativeMethods.cs b/DS4Windows/HidLibrary/NativeMethods.cs index 8ee0adf..1fca5dd 100644 --- a/DS4Windows/HidLibrary/NativeMethods.cs +++ b/DS4Windows/HidLibrary/NativeMethods.cs @@ -234,6 +234,9 @@ namespace DS4Windows internal static DEVPROPKEY DEVPKEY_Device_HardwareIds = new DEVPROPKEY { fmtid = new Guid(0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0), pid = 3 }; + internal static DEVPROPKEY DEVPKEY_Device_UINumber = + new DEVPROPKEY { fmtid = new Guid(0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0), pid = 18 }; + [DllImport("setupapi.dll", EntryPoint = "SetupDiGetDeviceRegistryProperty")] public static extern bool SetupDiGetDeviceRegistryProperty(IntPtr deviceInfoSet, ref SP_DEVINFO_DATA deviceInfoData, int propertyVal, ref int propertyRegDataType, byte[] propertyBuffer, int propertyBufferSize, ref int requiredSize);