mirror of
https://github.com/cemu-project/DS4Windows.git
synced 2024-11-29 20:44:20 +01:00
Test DS4 emulation
This commit is contained in:
parent
372f9aa612
commit
dc5e34f1be
@ -11,15 +11,13 @@ using System.Diagnostics;
|
|||||||
using Nefarius.ViGEm.Client;
|
using Nefarius.ViGEm.Client;
|
||||||
using Nefarius.ViGEm.Client.Targets;
|
using Nefarius.ViGEm.Client.Targets;
|
||||||
using Nefarius.ViGEm.Client.Targets.Xbox360;
|
using Nefarius.ViGEm.Client.Targets.Xbox360;
|
||||||
|
using Nefarius.ViGEm.Client.Targets.DualShock4;
|
||||||
|
|
||||||
namespace DS4Windows
|
namespace DS4Windows
|
||||||
{
|
{
|
||||||
public class ControlService
|
public class ControlService
|
||||||
{
|
{
|
||||||
public ViGEmClient vigemTestClient = 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 const int DS4_CONTROLLER_COUNT = 4;
|
||||||
public DS4Device[] DS4Controllers = new DS4Device[DS4_CONTROLLER_COUNT];
|
public DS4Device[] DS4Controllers = new DS4Device[DS4_CONTROLLER_COUNT];
|
||||||
public Mouse[] touchPad = new Mouse[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[] buttonsdown = new bool[4] { false, false, false, false };
|
||||||
bool[] held = new bool[DS4_CONTROLLER_COUNT];
|
bool[] held = new bool[DS4_CONTROLLER_COUNT];
|
||||||
int[] oldmouse = new int[DS4_CONTROLLER_COUNT] { -1, -1, -1, -1 };
|
int[] oldmouse = new int[DS4_CONTROLLER_COUNT] { -1, -1, -1, -1 };
|
||||||
public Xbox360Controller[] x360controls = new Xbox360Controller[4] { null, null, null, null };
|
public OutputDevice[] outputDevices = new OutputDevice[4] { null, null, null, null };
|
||||||
private Xbox360Report[] x360reports = new Xbox360Report[4] { new Xbox360Report(), new Xbox360Report(),
|
//public Xbox360Controller[] x360controls = new Xbox360Controller[4] { null, null, null, null };
|
||||||
|
/*private Xbox360Report[] x360reports = new Xbox360Report[4] { new Xbox360Report(), new Xbox360Report(),
|
||||||
new Xbox360Report(), new Xbox360Report()
|
new Xbox360Report(), new Xbox360Report()
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
Thread tempThread;
|
Thread tempThread;
|
||||||
public List<string> affectedDevs = new List<string>()
|
public List<string> affectedDevs = new List<string>()
|
||||||
{
|
{
|
||||||
@ -424,14 +424,28 @@ namespace DS4Windows
|
|||||||
{
|
{
|
||||||
LogDebug("Plugging in X360 Controller #" + (i + 1));
|
LogDebug("Plugging in X360 Controller #" + (i + 1));
|
||||||
useDInputOnly[i] = false;
|
useDInputOnly[i] = false;
|
||||||
x360controls[i] = new Xbox360Controller(vigemTestClient);
|
|
||||||
|
DS4OutDevice tempDS4 = new DS4OutDevice(vigemTestClient);
|
||||||
|
outputDevices[i] = tempDS4;
|
||||||
int devIndex = i;
|
int devIndex = i;
|
||||||
x360controls[i].FeedbackReceived += (sender, args) =>
|
tempDS4.cont.FeedbackReceived += (sender, args) =>
|
||||||
{
|
{
|
||||||
SetDevRumble(device, args.LargeMotor, args.SmallMotor, devIndex);
|
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");
|
LogDebug("X360 Controller #" + (i + 1) + " connected");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -568,8 +582,10 @@ namespace DS4Windows
|
|||||||
}
|
}
|
||||||
|
|
||||||
CurrentState[i].Battery = PreviousState[i].Battery = 0; // Reset for the next connection's initial status change.
|
CurrentState[i].Battery = PreviousState[i].Battery = 0; // Reset for the next connection's initial status change.
|
||||||
x360controls[i]?.Disconnect();
|
//x360controls[i]?.Disconnect();
|
||||||
x360controls[i] = null;
|
outputDevices[i]?.Disconnect();
|
||||||
|
outputDevices[i] = null;
|
||||||
|
//x360controls[i] = null;
|
||||||
useDInputOnly[i] = true;
|
useDInputOnly[i] = true;
|
||||||
DS4Controllers[i] = null;
|
DS4Controllers[i] = null;
|
||||||
touchPad[i] = null;
|
touchPad[i] = null;
|
||||||
@ -681,14 +697,18 @@ namespace DS4Windows
|
|||||||
{
|
{
|
||||||
LogDebug("Plugging in X360 Controller #" + (Index + 1));
|
LogDebug("Plugging in X360 Controller #" + (Index + 1));
|
||||||
useDInputOnly[Index] = false;
|
useDInputOnly[Index] = false;
|
||||||
x360controls[Index] = new Xbox360Controller(vigemTestClient);
|
//x360controls[Index] = new Xbox360Controller(vigemTestClient);
|
||||||
|
Xbox360OutDevice tempXbox = new Xbox360OutDevice(vigemTestClient);
|
||||||
|
outputDevices[Index] = tempXbox;
|
||||||
int devIndex = Index;
|
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);
|
SetDevRumble(device, args.LargeMotor, args.SmallMotor, devIndex);
|
||||||
};
|
};
|
||||||
|
|
||||||
x360controls[Index].Connect();
|
//x360controls[Index].Connect();
|
||||||
|
tempXbox.Connect();
|
||||||
LogDebug("X360 Controller #" + (Index + 1) + " connected");
|
LogDebug("X360 Controller #" + (Index + 1) + " connected");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -723,7 +743,7 @@ namespace DS4Windows
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testNewReport(ref Xbox360Report xboxreport, DS4State state,
|
/*private void testNewReport(ref Xbox360Report xboxreport, DS4State state,
|
||||||
int device)
|
int device)
|
||||||
{
|
{
|
||||||
Xbox360Buttons tempButtons = 0;
|
Xbox360Buttons tempButtons = 0;
|
||||||
@ -818,8 +838,9 @@ namespace DS4Windows
|
|||||||
goto case SASteeringWheelEmulationAxisType.None;
|
goto case SASteeringWheelEmulationAxisType.None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
private short AxisScale(Int32 Value, Boolean Flip)
|
/*private short AxisScale(Int32 Value, Boolean Flip)
|
||||||
{
|
{
|
||||||
unchecked
|
unchecked
|
||||||
{
|
{
|
||||||
@ -832,6 +853,7 @@ namespace DS4Windows
|
|||||||
return (short)(temp * outputResolution + (-32768));
|
return (short)(temp * outputResolution + (-32768));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
private void CheckProfileOptions(int ind, DS4Device device, bool startUp=false)
|
private void CheckProfileOptions(int ind, DS4Device device, bool startUp=false)
|
||||||
{
|
{
|
||||||
@ -1048,8 +1070,8 @@ namespace DS4Windows
|
|||||||
{
|
{
|
||||||
if (!useDInputOnly[ind])
|
if (!useDInputOnly[ind])
|
||||||
{
|
{
|
||||||
x360controls[ind].Disconnect();
|
outputDevices[ind].Disconnect();
|
||||||
x360controls[ind] = null;
|
outputDevices[ind] = null;
|
||||||
useDInputOnly[ind] = true;
|
useDInputOnly[ind] = true;
|
||||||
LogDebug("X360 Controller #" + (ind + 1) + " unplugged");
|
LogDebug("X360 Controller #" + (ind + 1) + " unplugged");
|
||||||
}
|
}
|
||||||
@ -1059,13 +1081,23 @@ namespace DS4Windows
|
|||||||
if (!getDInputOnly(ind))
|
if (!getDInputOnly(ind))
|
||||||
{
|
{
|
||||||
LogDebug("Plugging in X360 Controller #" + (ind + 1));
|
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) =>
|
x360controls[ind].FeedbackReceived += (eventsender, args) =>
|
||||||
{
|
{
|
||||||
SetDevRumble(device, args.LargeMotor, args.SmallMotor, ind);
|
SetDevRumble(device, args.LargeMotor, args.SmallMotor, ind);
|
||||||
};
|
};
|
||||||
|
|
||||||
x360controls[ind].Connect();
|
x360controls[ind].Connect();
|
||||||
|
*/
|
||||||
useDInputOnly[ind] = false;
|
useDInputOnly[ind] = false;
|
||||||
LogDebug("X360 Controller #" + (ind + 1) + " connected");
|
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.
|
CurrentState[ind].Battery = PreviousState[ind].Battery = 0; // Reset for the next connection's initial status change.
|
||||||
if (!useDInputOnly[ind])
|
if (!useDInputOnly[ind])
|
||||||
{
|
{
|
||||||
x360controls[ind].Disconnect();
|
outputDevices[ind].Disconnect();
|
||||||
x360controls[ind] = null;
|
outputDevices[ind] = null;
|
||||||
|
//x360controls[ind].Disconnect();
|
||||||
|
//x360controls[ind] = null;
|
||||||
LogDebug("X360 Controller # " + (ind + 1) + " unplugged");
|
LogDebug("X360 Controller # " + (ind + 1) + " unplugged");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1241,8 +1275,10 @@ namespace DS4Windows
|
|||||||
|
|
||||||
if (!useDInputOnly[ind])
|
if (!useDInputOnly[ind])
|
||||||
{
|
{
|
||||||
testNewReport(ref x360reports[ind], cState, ind);
|
outputDevices[ind]?.ConvertandSendReport(cState, ind);
|
||||||
x360controls[ind]?.SendReport(x360reports[ind]);
|
//testNewReport(ref x360reports[ind], cState, ind);
|
||||||
|
//x360controls[ind]?.SendReport(x360reports[ind]);
|
||||||
|
|
||||||
//x360Bus.Parse(cState, processingData[ind].Report, ind);
|
//x360Bus.Parse(cState, processingData[ind].Report, ind);
|
||||||
// We push the translated Xinput state, and simultaneously we
|
// We push the translated Xinput state, and simultaneously we
|
||||||
// pull back any possible rumble data coming from Xinput consumers.
|
// pull back any possible rumble data coming from Xinput consumers.
|
||||||
|
83
DS4Windows/DS4Control/DS4OutDevice.cs
Normal file
83
DS4Windows/DS4Control/DS4OutDevice.cs
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
15
DS4Windows/DS4Control/OutputDevice.cs
Normal file
15
DS4Windows/DS4Control/OutputDevice.cs
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -335,6 +335,34 @@ namespace DS4Windows
|
|||||||
return result;
|
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()
|
public static bool IsHidGuardianInstalled()
|
||||||
{
|
{
|
||||||
return CheckForSysDevice(@"Root\HidGuardian");
|
return CheckForSysDevice(@"Root\HidGuardian");
|
||||||
@ -3063,20 +3091,29 @@ namespace DS4Windows
|
|||||||
tempDev.setBTPollRate(btPollRate[device]);
|
tempDev.setBTPollRate(btPollRate[device]);
|
||||||
if (xinputStatus && xinputPlug)
|
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.x360controls[device].FeedbackReceived += (eventsender, args) =>
|
||||||
{
|
{
|
||||||
control.SetDevRumble(tempDev, args.LargeMotor, args.SmallMotor, device);
|
control.SetDevRumble(tempDev, args.LargeMotor, args.SmallMotor, device);
|
||||||
};
|
};
|
||||||
|
|
||||||
control.x360controls[device].Connect();
|
control.x360controls[device].Connect();
|
||||||
|
*/
|
||||||
Global.useDInputOnly[device] = false;
|
Global.useDInputOnly[device] = false;
|
||||||
AppLogger.LogToGui("X360 Controller #" + (device + 1) + " connected", false);
|
AppLogger.LogToGui("X360 Controller #" + (device + 1) + " connected", false);
|
||||||
}
|
}
|
||||||
else if (xinputStatus && !xinputPlug)
|
else if (xinputStatus && !xinputPlug)
|
||||||
{
|
{
|
||||||
control.x360controls[device].Disconnect();
|
control.outputDevices[device].Disconnect();
|
||||||
control.x360controls[device] = null;
|
control.outputDevices[device] = null;
|
||||||
Global.useDInputOnly[device] = true;
|
Global.useDInputOnly[device] = true;
|
||||||
AppLogger.LogToGui("X360 Controller #" + (device + 1) + " unplugged", false);
|
AppLogger.LogToGui("X360 Controller #" + (device + 1) + " unplugged", false);
|
||||||
}
|
}
|
||||||
|
141
DS4Windows/DS4Control/Xbox360OutDevice.cs
Normal file
141
DS4Windows/DS4Control/Xbox360OutDevice.cs
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -61,12 +61,22 @@ namespace DS4Windows
|
|||||||
return deviceInstanceId;
|
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
|
// Enumerates ds4 controllers in the system
|
||||||
public static void findControllers()
|
public static void findControllers()
|
||||||
{
|
{
|
||||||
lock (Devices)
|
lock (Devices)
|
||||||
{
|
{
|
||||||
IEnumerable<HidDevice> hDevices = HidDevices.EnumerateDS4(knownDevices);
|
IEnumerable<HidDevice> 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.
|
// Sort Bluetooth first in case USB is also connected on the same controller.
|
||||||
hDevices = hDevices.OrderBy<HidDevice, ConnectionType>((HidDevice d) => { return DS4Device.HidConnectionType(d); });
|
hDevices = hDevices.OrderBy<HidDevice, ConnectionType>((HidDevice d) => { return DS4Device.HidConnectionType(d); });
|
||||||
|
|
||||||
|
@ -138,6 +138,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="DS4Control\ControlService.cs" />
|
<Compile Include="DS4Control\ControlService.cs" />
|
||||||
<Compile Include="DS4Control\DS4LightBar.cs" />
|
<Compile Include="DS4Control\DS4LightBar.cs" />
|
||||||
|
<Compile Include="DS4Control\DS4OutDevice.cs" />
|
||||||
<Compile Include="DS4Control\DS4StateFieldMapping.cs" />
|
<Compile Include="DS4Control\DS4StateFieldMapping.cs" />
|
||||||
<Compile Include="DS4Control\InputMethods.cs" />
|
<Compile Include="DS4Control\InputMethods.cs" />
|
||||||
<Compile Include="DS4Control\ITouchpadBehaviour.cs" />
|
<Compile Include="DS4Control\ITouchpadBehaviour.cs" />
|
||||||
@ -146,9 +147,11 @@
|
|||||||
<Compile Include="DS4Control\Mouse.cs" />
|
<Compile Include="DS4Control\Mouse.cs" />
|
||||||
<Compile Include="DS4Control\MouseCursor.cs" />
|
<Compile Include="DS4Control\MouseCursor.cs" />
|
||||||
<Compile Include="DS4Control\MouseWheel.cs" />
|
<Compile Include="DS4Control\MouseWheel.cs" />
|
||||||
|
<Compile Include="DS4Control\OutputDevice.cs" />
|
||||||
<Compile Include="DS4Control\ScpUtil.cs" />
|
<Compile Include="DS4Control\ScpUtil.cs" />
|
||||||
<Compile Include="DS4Control\UdpServer.cs" />
|
<Compile Include="DS4Control\UdpServer.cs" />
|
||||||
<Compile Include="DS4Control\Util.cs" />
|
<Compile Include="DS4Control\Util.cs" />
|
||||||
|
<Compile Include="DS4Control\Xbox360OutDevice.cs" />
|
||||||
<Compile Include="DS4Forms\LanguagePackComboBox.cs">
|
<Compile Include="DS4Forms\LanguagePackComboBox.cs">
|
||||||
<SubType>UserControl</SubType>
|
<SubType>UserControl</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -234,6 +234,9 @@ namespace DS4Windows
|
|||||||
internal static DEVPROPKEY DEVPKEY_Device_HardwareIds =
|
internal static DEVPROPKEY DEVPKEY_Device_HardwareIds =
|
||||||
new DEVPROPKEY { fmtid = new Guid(0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0), pid = 3 };
|
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")]
|
[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);
|
public static extern bool SetupDiGetDeviceRegistryProperty(IntPtr deviceInfoSet, ref SP_DEVINFO_DATA deviceInfoData, int propertyVal, ref int propertyRegDataType, byte[] propertyBuffer, int propertyBufferSize, ref int requiredSize);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user