diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..f81227089 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +[*.cs] + +# CA1416: Valider la compatibilité de la plateforme +dotnet_diagnostic.CA1416.severity = none diff --git a/ControllerCommon/ControllerCommon.csproj b/ControllerCommon/ControllerCommon.csproj index 0ccafd389..14c942fae 100644 --- a/ControllerCommon/ControllerCommon.csproj +++ b/ControllerCommon/ControllerCommon.csproj @@ -17,6 +17,9 @@ + + + diff --git a/ControllerCommon/HIDmode.cs b/ControllerCommon/HIDmode.cs new file mode 100644 index 000000000..d8e467927 --- /dev/null +++ b/ControllerCommon/HIDmode.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ControllerCommon +{ + public enum HIDmode + { + DualShock4Controller = 0, + Xbox360Controller = 1, + NoController = 2, + } +} diff --git a/ControllerCommon/PipeClient.cs b/ControllerCommon/PipeClient.cs index daa12b50b..961f57237 100644 --- a/ControllerCommon/PipeClient.cs +++ b/ControllerCommon/PipeClient.cs @@ -42,6 +42,11 @@ public PipeClient(string pipeName) client.Error += OnError; } + public override string ToString() + { + return this.GetType().Name; + } + public PipeClient(string pipeName, ILogger logger) : this(pipeName) { this.logger = logger; @@ -61,7 +66,7 @@ public void Start() return; client.Start(); - logger?.LogInformation($"Pipe Client has started"); + logger?.LogInformation("{0} has started" , this.ToString()); } public void Stop() @@ -70,7 +75,7 @@ public void Stop() return; client.Stop(); - logger?.LogInformation($"Pipe Client has stopped"); + logger?.LogInformation("{0} has stopped", this.ToString()); } private void OnServerMessage(NamedPipeConnection connection, PipeMessage message) @@ -90,7 +95,7 @@ private void OnServerMessage(NamedPipeConnection conne private void OnError(Exception exception) { - logger?.LogError("PipClient failed. {0}", exception.Message); + logger?.LogError("{0} failed. {1}", this.ToString(), exception.Message); } public void SendMessage(PipeMessage message) diff --git a/ControllerCommon/PipeMessage.cs b/ControllerCommon/PipeMessage.cs index ca841cc85..4555df4d4 100644 --- a/ControllerCommon/PipeMessage.cs +++ b/ControllerCommon/PipeMessage.cs @@ -84,7 +84,7 @@ public PipeClientScreen() [Serializable] public class PipeClientSettings : PipeMessage { - public Dictionary settings = new(); + public Dictionary settings = new(); public PipeClientSettings() { diff --git a/ControllerCommon/PipeServer.cs b/ControllerCommon/PipeServer.cs index b89ae689f..2735f00f7 100644 --- a/ControllerCommon/PipeServer.cs +++ b/ControllerCommon/PipeServer.cs @@ -83,6 +83,11 @@ public PipeServer(string pipeName) server.Error += OnError; } + public override string ToString() + { + return this.GetType().Name; + } + public PipeServer(string pipeName, ILogger logger) : this(pipeName) { this.logger = logger; @@ -94,7 +99,7 @@ public void Start() return; server.Start(); - logger?.LogInformation($"Pipe Server has started"); + logger?.LogInformation("{0} has started", this.ToString()); } public void Stop() @@ -103,7 +108,7 @@ public void Stop() return; server = null; - logger?.LogInformation($"Pipe Server has stopped"); + logger?.LogInformation("{0} has stopped", this.ToString()); } private void OnClientConnected(NamedPipeConnection connection) @@ -133,7 +138,7 @@ private void OnClientMessage(NamedPipeConnection conne private void OnError(Exception exception) { - logger?.LogError("PipeServer failed. {0}", exception.Message); + logger?.LogError("{0} failed. {1}", this.ToString(), exception.Message); } public void SendMessage(PipeMessage message) diff --git a/ControllerCommon/Profile.cs b/ControllerCommon/Profile.cs index a6e28a1d2..19b44a3d5 100644 --- a/ControllerCommon/Profile.cs +++ b/ControllerCommon/Profile.cs @@ -20,15 +20,6 @@ public enum InputStyle Mouse = 3 } - public class ProfileButton : DualShock4Button - { - public ProfileButton(int id, string name, ushort value) : base(id, name, value) - { - } - - public static ProfileButton AlwaysOn = new ProfileButton(12, "Always On", 8); - } - [Serializable] public class Profile { @@ -50,7 +41,7 @@ public class Profile public float umc_sensivity { get; set; } = 2.0f; public float umc_intensity { get; set; } = 1.0f; - public int umc_trigger { get; set; } = 0; + public uint umc_trigger { get; set; } = 0; [JsonIgnore] public ProfileErrorCode error; [JsonIgnore] public string fullpath { get; set; } @@ -81,29 +72,5 @@ public override string ToString() { return name; } - - public static Dictionary ListTriggers() - { - return new Dictionary() { - { ProfileButton.AlwaysOn.Value, ProfileButton.AlwaysOn }, - - { DualShock4Button.ThumbRight.Value, DualShock4Button.ThumbRight }, - { DualShock4Button.ThumbLeft.Value, DualShock4Button.ThumbLeft }, - - { DualShock4Button.Options.Value, DualShock4Button.Options }, - { DualShock4Button.Share.Value, DualShock4Button.Share }, - - { DualShock4Button.TriggerRight.Value, DualShock4Button.TriggerRight }, - { DualShock4Button.TriggerLeft.Value, DualShock4Button.TriggerLeft }, - - { DualShock4Button.ShoulderRight.Value, DualShock4Button.ShoulderRight }, - { DualShock4Button.ShoulderLeft.Value, DualShock4Button.ShoulderLeft }, - - { DualShock4Button.Triangle.Value, DualShock4Button.Triangle }, - { DualShock4Button.Circle.Value, DualShock4Button.Circle }, - { DualShock4Button.Cross.Value, DualShock4Button.Cross }, - { DualShock4Button.Square.Value, DualShock4Button.Square }, - }; - } } } diff --git a/ControllerCommon/Utils.cs b/ControllerCommon/Utils.cs index fd5e81f2a..45d5a536c 100644 --- a/ControllerCommon/Utils.cs +++ b/ControllerCommon/Utils.cs @@ -1,5 +1,7 @@ using Microsoft.Toolkit.Uwp.Notifications; +using SharpDX.XInput; using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Management; @@ -31,6 +33,28 @@ public enum BinaryType : uint static extern uint QueryFullProcessImageName(IntPtr hProcess, uint flags, StringBuilder text, out uint size); #endregion + [Flags] + public enum GamepadButtonFlags : uint + { + DPadUp = 1, + DPadDown = 2, + DPadLeft = 4, + DPadRight = 8, + Start = 16, + Back = 32, + LeftThumb = 64, + RightThumb = 128, + LeftShoulder = 256, + RightShoulder = 512, + LeftTrigger = 1024, + RightTrigger = 2048, + A = 4096, + B = 8192, + X = 16384, + Y = 32768, + AlwaysOn = 65536 + } + public static void SendToast(string title, string content) { string url = "file:///" + AppDomain.CurrentDomain.BaseDirectory + "Toast.png"; diff --git a/ControllerHelper/Controller.cs b/ControllerHelper/Controller.cs index e7e725789..48a935ae8 100644 --- a/ControllerHelper/Controller.cs +++ b/ControllerHelper/Controller.cs @@ -22,21 +22,4 @@ public override string ToString() return this.ProductName; } } - - class HIDmode - { - public string mode; - public string name; - - public HIDmode(string mode, string name) - { - this.mode = mode; - this.name = name; - } - - public override string ToString() - { - return this.name; - } - } } diff --git a/ControllerHelper/ControllerHelper.Designer.cs b/ControllerHelper/ControllerHelper.Designer.cs index c851b551a..b90db8dfe 100644 --- a/ControllerHelper/ControllerHelper.Designer.cs +++ b/ControllerHelper/ControllerHelper.Designer.cs @@ -286,9 +286,10 @@ private void InitializeComponent() // cB_HidMode // this.cB_HidMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - resources.ApplyResources(this.cB_HidMode, "cB_HidMode"); this.cB_HidMode.FormattingEnabled = true; + resources.ApplyResources(this.cB_HidMode, "cB_HidMode"); this.cB_HidMode.Name = "cB_HidMode"; + this.cB_HidMode.SelectedIndexChanged += new System.EventHandler(this.cB_HidMode_SelectedIndexChanged); // // gB_XinputDetails // @@ -606,6 +607,7 @@ private void InitializeComponent() resources.ApplyResources(this.cB_UMCInputButton, "cB_UMCInputButton"); this.cB_UMCInputButton.Name = "cB_UMCInputButton"; this.cB_UMCInputButton.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; + this.cB_UMCInputButton.Sorted = true; // // lb_UMCInputButton // diff --git a/ControllerHelper/ControllerHelper.cs b/ControllerHelper/ControllerHelper.cs index b4b671ab6..468167440 100644 --- a/ControllerHelper/ControllerHelper.cs +++ b/ControllerHelper/ControllerHelper.cs @@ -2,6 +2,8 @@ using Microsoft.Extensions.Logging; using Microsoft.Win32.TaskScheduler; using Nefarius.ViGEm.Client.Targets.DualShock4; +using Nefarius.ViGEm.Client.Targets.Xbox360; +using SharpDX.XInput; using System; using System.Collections.Generic; using System.Diagnostics; @@ -46,10 +48,6 @@ public partial class ControllerHelper : Form private FormWindowState CurrentWindowState; private object updateLock = new(); - private HIDmode HideDS4 = new HIDmode("DualShock4Controller", "DualShock 4 emulation"); - private HIDmode HideXBOX = new HIDmode("Xbox360Controller", "Xbox 360 emulation"); - private Dictionary HIDmodes = new(); - public string CurrentExe, CurrentPath, CurrentPathService, CurrentPathProfiles, CurrentPathLogs; private bool RunAtStartup, StartMinimized, CloseMinimises, HookMouse; @@ -121,13 +119,14 @@ public ControllerHelper(string[] Arguments, ILogger logger) UpdateTask(); } - // todo : feed me from service - cB_HidMode.Items.Add(HideDS4); - cB_HidMode.Items.Add(HideXBOX); - HIDmodes.Add("DualShock4Controller", HideDS4); - HIDmodes.Add("Xbox360Controller", HideXBOX); + foreach (HIDmode mode in (HIDmode[])Enum.GetValues(typeof(HIDmode))) + { + if (mode == HIDmode.NoController) + continue; + cB_HidMode.Items.Add(mode); + } - foreach (DualShock4Button button in Profile.ListTriggers().Values) + foreach (Utils.GamepadButtonFlags button in (Utils.GamepadButtonFlags[])Enum.GetValues(typeof(Utils.GamepadButtonFlags))) cB_UMCInputButton.Items.Add(button); // update UI @@ -424,7 +423,7 @@ public void UpdateSettings(Dictionary args) switch (name) { case "HIDmode": - cB_HidMode.SelectedItem = HIDmodes[args[name]]; + cB_HidMode.SelectedIndex = int.Parse(args[name]); break; case "HIDcloaked": cB_HIDcloak.Checked = bool.Parse(args[name]); @@ -496,9 +495,9 @@ private void tB_PullRate_Scroll(object sender, EventArgs e) PipeClient.SendMessage(new PipeClientSettings { - settings = new Dictionary + settings = new Dictionary { - { "HIDrate", tB_PullRate.Value.ToString() } + { "HIDrate", tB_PullRate.Value } } }); } @@ -512,9 +511,9 @@ private void tB_VibrationStr_Scroll(object sender, EventArgs e) PipeClient.SendMessage(new PipeClientSettings { - settings = new Dictionary + settings = new Dictionary { - { "HIDstrength", tB_VibrationStr.Value.ToString() } + { "HIDstrength", tB_VibrationStr.Value } } }); } @@ -523,11 +522,11 @@ private void b_UDPApply_Click(object sender, EventArgs e) { PipeClient.SendMessage(new PipeClientSettings { - settings = new Dictionary + settings = new Dictionary { { "DSUip", tB_UDPIP.Text }, - { "DSUport", tB_UDPPort.Value.ToString() }, - { "DSUEnabled", cB_UDPEnable.Checked.ToString() } + { "DSUport", tB_UDPPort.Value }, + { "DSUEnabled", cB_UDPEnable.Checked } } }); } @@ -647,9 +646,9 @@ private void cB_uncloak_CheckedChanged(object sender, EventArgs e) { PipeClient.SendMessage(new PipeClientSettings { - settings = new Dictionary + settings = new Dictionary { - { "HIDuncloakonclose", cB_uncloak.Checked.ToString() } + { "HIDuncloakonclose", cB_uncloak.Checked } } }); } @@ -724,8 +723,8 @@ private void lB_Profiles_SelectedIndexChanged(object sender, EventArgs e) for (int idx = 0; idx < cB_UMCInputButton.Items.Count; idx++) { - DualShock4Button button = (DualShock4Button)cB_UMCInputButton.Items[idx]; - bool selected = (button.Value & CurrentProfile.umc_trigger) != 0; + uint button = (uint)(Utils.GamepadButtonFlags)cB_UMCInputButton.Items[idx]; + bool selected = (button & CurrentProfile.umc_trigger) == button; cB_UMCInputButton.SetSelected(idx, selected); } @@ -779,8 +778,8 @@ private void b_ApplyProfile_Click(object sender, EventArgs e) CurrentProfile.umc_intensity = tB_UMCIntensity.Value; CurrentProfile.umc_trigger = 0; - foreach (DualShock4Button button in cB_UMCInputButton.SelectedItems) - CurrentProfile.umc_trigger |= button.Value; + foreach (Utils.GamepadButtonFlags button in cB_UMCInputButton.SelectedItems) + CurrentProfile.umc_trigger |= (uint)button; ProfileManager.profiles[CurrentProfile.name] = CurrentProfile; ProfileManager.UpdateProfile(CurrentProfile); @@ -839,13 +838,24 @@ private void tB_UMCIntensity_Scroll(object sender, EventArgs e) }); } + private void cB_HidMode_SelectedIndexChanged(object sender, EventArgs e) + { + PipeClient.SendMessage(new PipeClientSettings + { + settings = new Dictionary + { + { "HIDmode", cB_HidMode.SelectedItem } + } + }); + } + private void cB_HIDcloak_CheckedChanged(object sender, EventArgs e) { PipeClient.SendMessage(new PipeClientSettings { - settings = new Dictionary + settings = new Dictionary { - { "HIDcloaked", cB_HIDcloak.Checked.ToString() } + { "HIDcloaked", cB_HIDcloak.Checked } } }); } diff --git a/ControllerHelper/ControllerHelper.resx b/ControllerHelper/ControllerHelper.resx index 601e45ce6..e28922d42 100644 --- a/ControllerHelper/ControllerHelper.resx +++ b/ControllerHelper/ControllerHelper.resx @@ -3797,9 +3797,6 @@ 4 - - False - 156, 29 diff --git a/ControllerHelper/ProfileManager.cs b/ControllerHelper/ProfileManager.cs index 8cf1d52f6..0afb3a6f9 100644 --- a/ControllerHelper/ProfileManager.cs +++ b/ControllerHelper/ProfileManager.cs @@ -264,9 +264,6 @@ public void UpdateProfileWrapper(Profile profile) backpath = Path.Combine(processpath, $"xinput9_1_0.back"); } - if (!IsFileWritable(dllpath)) - SetFileWritable(dllpath); - bool dllexist = File.Exists(dllpath); bool backexist = File.Exists(backpath); @@ -299,6 +296,9 @@ public void UpdateProfileWrapper(Profile profile) if (profile.use_wrapper) { + if (!IsFileWritable(dllpath)) + SetFileWritable(dllpath); + if (dllexist && is_x360ce) continue; // skip to next file else if (!dllexist) diff --git a/ControllerService.sln b/ControllerService.sln index 2535c86b6..d87f1b113 100644 --- a/ControllerService.sln +++ b/ControllerService.sln @@ -7,7 +7,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControllerService", "Contro EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControllerHelper", "ControllerHelper\ControllerHelper.csproj", "{3BB6F372-E910-4A27-810B-64152F163709}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControllerCommon", "ControllerCommon\ControllerCommon.csproj", "{D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControllerCommon", "ControllerCommon\ControllerCommon.csproj", "{D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4A4F8C55-09C7-4B4C-9752-E2E05AF25E30}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/ControllerService/ControllerService.cs b/ControllerService/ControllerService.cs index d92908f14..f3ad325d2 100644 --- a/ControllerService/ControllerService.cs +++ b/ControllerService/ControllerService.cs @@ -1,4 +1,5 @@ using ControllerCommon; +using ControllerService.Targets; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Nefarius.ViGEm.Client; @@ -20,6 +21,8 @@ public class ControllerService : IHostedService { // controllers vars private ViGEmClient VirtualClient; + private ViGEmTarget VirtualTarget; + public XInputController XInputController; private XInputGirometer Gyrometer; private XInputAccelerometer Accelerometer; @@ -30,10 +33,12 @@ public class ControllerService : IHostedService public static string CurrentExe, CurrentPath, CurrentPathCli, CurrentPathDep; - private string DSUip, HIDmode; + private string DSUip; private bool HIDcloaked, HIDuncloakonclose, DSUEnabled; private int DSUport, HIDrate, HIDstrength; + private HIDmode HIDmode; + private readonly ILogger logger; public ControllerService(ILogger logger) @@ -54,7 +59,7 @@ public ControllerService(ILogger logger) // settings HIDcloaked = Properties.Settings.Default.HIDcloaked; HIDuncloakonclose = Properties.Settings.Default.HIDuncloakonclose; - HIDmode = Properties.Settings.Default.HIDmode; + HIDmode = (HIDmode)Properties.Settings.Default.HIDmode; DSUEnabled = Properties.Settings.Default.DSUEnabled; DSUip = Properties.Settings.Default.DSUip; DSUport = Properties.Settings.Default.DSUport; @@ -96,8 +101,8 @@ public ControllerService(ILogger logger) if (!controller.IsConnected) continue; - XInputController = new XInputController(controller, idx, HIDrate, HIDmode, logger); - XInputController.instance = dinstances[(int)idx]; + XInputController = new XInputController(controller, idx, HIDrate, logger); + XInputController.Instance = dinstances[(int)idx]; break; } @@ -117,6 +122,9 @@ public ControllerService(ILogger logger) if (Accelerometer.sensor == null) logger.LogWarning("No Accelerometer detected"); + // initialize virtual controller + UpdateVirtualController(HIDmode); + // initialize DSUClient DSUServer = new DSUServer(DSUip, DSUport, logger); DSUServer.Started += OnDSUStarted; @@ -129,6 +137,41 @@ public ControllerService(ILogger logger) PipeServer.ClientMessage += OnClientMessage; } + private void UpdateVirtualController(HIDmode mode) + { + if (VirtualTarget != null) + { + switch (VirtualTarget.HID) + { + case HIDmode.Xbox360Controller: + ((Xbox360Target)VirtualTarget)?.Disconnect(); + break; + case HIDmode.DualShock4Controller: + ((DualShock4Target)VirtualTarget)?.Disconnect(); + break; + } + } + + switch (mode) + { + default: + case HIDmode.DualShock4Controller: + VirtualTarget = new DualShock4Target(VirtualClient, XInputController.Controller, (int)XInputController.UserIndex, logger); + break; + case HIDmode.Xbox360Controller: + VirtualTarget = new Xbox360Target(VirtualClient, XInputController.Controller, (int)XInputController.UserIndex, logger); + break; + } + + if (VirtualTarget == null) + { + logger.LogCritical("Virtual controller initialization failed. Application will stop"); + throw new InvalidOperationException(); + } + + XInputController.SetTarget(VirtualTarget); + } + private void OnDSUStopped(object sender) { DSUEnabled = Properties.Settings.Default.DSUEnabled = false; @@ -160,20 +203,20 @@ private void OnClientMessage(object sender, PipeMessage message) switch (cursor.action) { case 0: // up - XInputController.target.touch.OnMouseUp((short)cursor.x, (short)cursor.y, cursor.button); + XInputController.Target.Touch.OnMouseUp((short)cursor.x, (short)cursor.y, cursor.button); break; case 1: // down - XInputController.target.touch.OnMouseDown((short)cursor.x, (short)cursor.y, cursor.button); + XInputController.Target.Touch.OnMouseDown((short)cursor.x, (short)cursor.y, cursor.button); break; case 2: // move - XInputController.target.touch.OnMouseMove((short)cursor.x, (short)cursor.y, cursor.button); + XInputController.Target.Touch.OnMouseMove((short)cursor.x, (short)cursor.y, cursor.button); break; } break; case PipeCode.CLIENT_SCREEN: PipeClientScreen screen = (PipeClientScreen)message; - XInputController.target.touch.UpdateRatio(screen.width, screen.height); + XInputController.Target.Touch.UpdateRatio(screen.width, screen.height); break; case PipeCode.CLIENT_SETTINGS: @@ -199,7 +242,7 @@ private void OnClientMessage(object sender, PipeMessage message) private void OnClientDisconnected(object sender) { - XInputController.target.touch.OnMouseUp(-1, -1, 1048576 /* MouseButtons.Left */); + XInputController.Target.Touch.OnMouseUp(-1, -1, 1048576 /* MouseButtons.Left */); } private void OnClientConnected(object sender) @@ -207,10 +250,10 @@ private void OnClientConnected(object sender) // send controller details PipeServer.SendMessage(new PipeServerController() { - ProductName = XInputController.instance.ProductName, - InstanceGuid = XInputController.instance.InstanceGuid, - ProductGuid = XInputController.instance.ProductGuid, - ProductIndex = (int)XInputController.index + ProductName = XInputController.Instance.ProductName, + InstanceGuid = XInputController.Instance.InstanceGuid, + ProductGuid = XInputController.Instance.ProductGuid, + ProductIndex = (int)XInputController.UserIndex }); // send server settings @@ -219,54 +262,56 @@ private void OnClientConnected(object sender) internal void UpdateProfile(Profile profile) { - XInputController.target.profile = profile; + XInputController.Target.Profile = profile; } - public void UpdateSettings(Dictionary args) + public void UpdateSettings(Dictionary args) { - foreach (KeyValuePair pair in args) + foreach (KeyValuePair pair in args) { string name = pair.Key; - string property = pair.Value; + object property = pair.Value; SettingsProperty setting = Properties.Settings.Default.Properties[name]; if (setting != null) { - object prev_value = Properties.Settings.Default[name].ToString(); - object value; + object prev_value = Properties.Settings.Default[name]; + object value = property; TypeCode typeCode = Type.GetTypeCode(setting.PropertyType); switch (typeCode) { case TypeCode.Boolean: - value = bool.Parse(property); - prev_value = bool.Parse((string)prev_value); + value = (bool)value; + prev_value = (bool)prev_value; break; case TypeCode.Single: case TypeCode.Decimal: - value = float.Parse(property); - prev_value = float.Parse((string)prev_value); + value = (float)value; + prev_value = (float)prev_value; break; case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: - value = int.Parse(property); - prev_value = int.Parse((string)prev_value); + value = (int)value; + prev_value = (int)prev_value; break; case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: - value = uint.Parse(property); - prev_value = uint.Parse((string)prev_value); + value = (uint)value; + prev_value = (uint)prev_value; break; default: - value = property; + value = (string)value; prev_value = (string)prev_value; break; } Properties.Settings.Default[name] = value; ApplySetting(name, prev_value, value); + + logger.LogInformation("{0} set to {1}", name, property.ToString()); } } @@ -277,8 +322,6 @@ private void ApplySetting(string name, object prev_value, object value) { if (prev_value.ToString() != value.ToString()) { - logger.LogInformation("{0} set to {1}", name, value.ToString()); - switch (name) { case "HIDcloaked": @@ -289,7 +332,7 @@ private void ApplySetting(string name, object prev_value, object value) HIDuncloakonclose = (bool)value; break; case "HIDmode": - // todo + UpdateVirtualController((HIDmode)value); break; case "HIDrate": XInputController.SetPollRate((int)value); @@ -324,7 +367,6 @@ public Task StartAsync(CancellationToken cancellationToken) Hidder.SetCloaking(HIDcloaked); // initialize virtual controller - XInputController.SetTarget(VirtualClient); XInputController.SetDSUServer(DSUServer); XInputController.SetGyroscope(Gyrometer); XInputController.SetAccelerometer(Accelerometer); @@ -336,7 +378,7 @@ public Task StartAsync(CancellationToken cancellationToken) // send notification PipeServer.SendMessage(new PipeServerToast { - title = $"{XInputController.target.GetType().Name}", + title = $"{XInputController.Target.GetType().Name}", content = "Virtual device is now connected" }); @@ -347,15 +389,15 @@ public Task StopAsync(CancellationToken cancellationToken) { try { - if (XInputController.target != null) + if (XInputController.Target != null) { - XInputController.target.Disconnect(); - logger.LogInformation("Virtual {0} disconnected", XInputController.target.GetType().Name); + XInputController.Target.Disconnect(); + logger.LogInformation("Virtual {0} disconnected", XInputController.Target.GetType().Name); // send notification PipeServer.SendMessage(new PipeServerToast { - title = $"{XInputController.target.GetType().Name}", + title = $"{XInputController.Target.GetType().Name}", content = "Virtual device is now disconnected" }); } diff --git a/ControllerService/ControllerService.csproj b/ControllerService/ControllerService.csproj index 810d7b488..fae0be691 100644 --- a/ControllerService/ControllerService.csproj +++ b/ControllerService/ControllerService.csproj @@ -29,6 +29,9 @@ + + + @@ -55,9 +58,6 @@ - - - diff --git a/ControllerService/DSUServer.cs b/ControllerService/DSUServer.cs index bac455838..f4d1e79df 100644 --- a/ControllerService/DSUServer.cs +++ b/ControllerService/DSUServer.cs @@ -147,6 +147,11 @@ public DSUServer(string ipString, int port, ILogger logger) BatteryTimer.Elapsed += UpdateBattery; } + public override string ToString() + { + return this.GetType().Name; + } + private void UpdateBattery(object sender, ElapsedEventArgs e) { if (!running) @@ -504,7 +509,7 @@ public bool Start() udpSock = null; running = false; - logger.LogCritical("DSU Server couldn't start. Port: {0} must be busy", port); + logger.LogCritical("{0} couldn't start. Port: {0} must be busy", this.ToString(), port); this.Stop(); return running; } @@ -519,7 +524,7 @@ public bool Start() BatteryTimer.Enabled = true; BatteryTimer.Start(); - logger.LogInformation("DSU Server has started. Listening to ip: {0} port: {1}", ip, port); + logger.LogInformation("{0} has started. Listening to ip: {1} port: {2}", this.ToString(), ip, port); Started?.Invoke(this); return running; @@ -534,7 +539,7 @@ public void Stop() udpSock = null; } - logger.LogInformation($"DSU Server has stopped"); + logger.LogInformation($"{0} has stopped", this.ToString()); Stopped?.Invoke(this); } @@ -601,7 +606,7 @@ private bool ReportToBuffer(ViGEmTarget hidReport, byte[] outputData, long micro //DS4 only: touchpad points for (int i = 0; i < 2; i++) { - var tpad = (i == 0) ? hidReport.touch.TrackPadTouch0 : hidReport.touch.TrackPadTouch1; + var tpad = (i == 0) ? hidReport.Touch.TrackPadTouch0 : hidReport.Touch.TrackPadTouch1; outputData[outIdx++] = tpad.IsActive ? (byte)1 : (byte)0; outputData[outIdx++] = (byte)tpad.RawTrackingNum; diff --git a/ControllerService/GlobalSuppressions.cs b/ControllerService/GlobalSuppressions.cs deleted file mode 100644 index ab3f333b8..000000000 --- a/ControllerService/GlobalSuppressions.cs +++ /dev/null @@ -1,30 +0,0 @@ -// This file is used by Code Analysis to maintain SuppressMessage -// attributes that are applied to this project. -// Project-level suppressions either have no target or are given -// a specific target and scoped to a namespace, type, member, etc. - -using System.Diagnostics.CodeAnalysis; - -[assembly: SuppressMessage("Interoperability", "CA1416:Valider la compatibilité de la plateforme", Justification = "", Scope = "member", Target = "~M:ControllerService.ControllerService.StartAsync(System.Threading.CancellationToken)~System.Threading.Tasks.Task")] -[assembly: SuppressMessage("Interoperability", "CA1416:Valider la compatibilité de la plateforme", Justification = "", Scope = "member", Target = "~M:ControllerService.ControllerService.#ctor(Microsoft.Extensions.Logging.ILogger{ControllerService.ControllerService})")] -[assembly: SuppressMessage("Interoperability", "CA1416:Valider la compatibilité de la plateforme", Justification = "", Scope = "member", Target = "~M:ControllerService.ControllerService.OnClientConnected(System.Object)")] -[assembly: SuppressMessage("Interoperability", "CA1416:Valider la compatibilité de la plateforme", Justification = "", Scope = "member", Target = "~M:ControllerService.ControllerService.OnClientMessage(System.Object,ControllerCommon.PipeMessage)")] -[assembly: SuppressMessage("Interoperability", "CA1416:Valider la compatibilité de la plateforme", Justification = "", Scope = "member", Target = "~M:ControllerService.ControllerService.StopAsync(System.Threading.CancellationToken)~System.Threading.Tasks.Task")] -[assembly: SuppressMessage("Interoperability", "CA1416:Valider la compatibilité de la plateforme", Justification = "", Scope = "member", Target = "~M:ControllerService.ControllerService.UpdateProfile(ControllerCommon.Profile)")] -[assembly: SuppressMessage("Interoperability", "CA1416:Valider la compatibilité de la plateforme", Justification = "", Scope = "member", Target = "~M:ControllerService.DSUServer.#ctor(System.String,System.Int32,Microsoft.Extensions.Logging.ILogger)")] -[assembly: SuppressMessage("Interoperability", "CA1416:Valider la compatibilité de la plateforme", Justification = "", Scope = "member", Target = "~M:ControllerService.DSUServer.ReportToBuffer(ControllerService.XInputController,System.Byte[],System.Int64,System.Int32@)~System.Boolean")] -[assembly: SuppressMessage("Interoperability", "CA1416:Valider la compatibilité de la plateforme", Justification = "", Scope = "member", Target = "~M:ControllerService.HidHide.GetRegisteredApplications~System.Collections.Generic.List{System.String}")] -[assembly: SuppressMessage("Interoperability", "CA1416:Valider la compatibilité de la plateforme", Justification = "", Scope = "member", Target = "~M:ControllerService.HidHide.ListDevices")] -[assembly: SuppressMessage("Interoperability", "CA1416:Valider la compatibilité de la plateforme", Justification = "", Scope = "member", Target = "~M:ControllerService.HidHide.RegisterDevices")] -[assembly: SuppressMessage("Interoperability", "CA1416:Valider la compatibilité de la plateforme", Justification = "", Scope = "member", Target = "~M:ControllerService.XInputAccelerometer.#ctor(Microsoft.Extensions.Logging.ILogger)")] -[assembly: SuppressMessage("Interoperability", "CA1416:Valider la compatibilité de la plateforme", Justification = "", Scope = "member", Target = "~M:ControllerService.XInputAccelerometer.AcceleroReadingChanged(Windows.Devices.Sensors.Accelerometer,Windows.Devices.Sensors.AccelerometerReadingChangedEventArgs)")] -[assembly: SuppressMessage("Interoperability", "CA1416:Valider la compatibilité de la plateforme", Justification = "", Scope = "member", Target = "~M:ControllerService.XInputController.DS4_UpdateReport(System.Object,System.Timers.ElapsedEventArgs)")] -[assembly: SuppressMessage("Interoperability", "CA1416:Valider la compatibilité de la plateforme", Justification = "", Scope = "member", Target = "~M:ControllerService.XInputGirometer.#ctor(Microsoft.Extensions.Logging.ILogger)")] -[assembly: SuppressMessage("Interoperability", "CA1416:Valider la compatibilité de la plateforme", Justification = "", Scope = "member", Target = "~M:ControllerService.XInputGirometer.GyroReadingChanged(Windows.Devices.Sensors.Gyrometer,Windows.Devices.Sensors.GyrometerReadingChangedEventArgs)")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~F:ControllerService.XInputController.accelFilter")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~F:ControllerService.XInputController.gyroFilter")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:ControllerService.ControllerService.OnDSUStarted(System.Object)")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:ControllerService.ControllerService.OnDSUStopped(System.Object)")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:ControllerService.XInputAccelerometer.#ctor(ControllerService.XInputController,Microsoft.Extensions.Logging.ILogger)")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:ControllerService.XInputController.#ctor(SharpDX.XInput.UserIndex,System.Int32,Microsoft.Extensions.Logging.ILogger)")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:ControllerService.XInputGirometer.#ctor(ControllerService.XInputController,Microsoft.Extensions.Logging.ILogger)")] diff --git a/ControllerService/HidHide.cs b/ControllerService/HidHide.cs index 000095369..cc1e456c8 100644 --- a/ControllerService/HidHide.cs +++ b/ControllerService/HidHide.cs @@ -116,7 +116,7 @@ public void SetCloaking(bool status) process.WaitForExit(); process.StandardOutput.ReadToEnd(); - logger.LogInformation("{0} cloak status set to {1}", service.XInputController.instance.ProductName, status); + logger.LogInformation("{0} cloak status set to {1}", service.XInputController.Instance.ProductName, status); } public void RegisterDevice(string deviceInstancePath) diff --git a/ControllerService/Properties/Settings.Designer.cs b/ControllerService/Properties/Settings.Designer.cs index cfdb0b48c..e7e37db9f 100644 --- a/ControllerService/Properties/Settings.Designer.cs +++ b/ControllerService/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace ControllerService.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.0.3.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -37,10 +37,10 @@ public bool HIDcloaked { [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("DualShock4Controller")] - public string HIDmode { + [global::System.Configuration.DefaultSettingValueAttribute("1")] + public int HIDmode { get { - return ((string)(this["HIDmode"])); + return ((int)(this["HIDmode"])); } set { this["HIDmode"] = value; diff --git a/ControllerService/Properties/Settings.settings b/ControllerService/Properties/Settings.settings index 0976a2616..043353979 100644 --- a/ControllerService/Properties/Settings.settings +++ b/ControllerService/Properties/Settings.settings @@ -5,8 +5,8 @@ True - - DualShock4Controller + + 1 True diff --git a/ControllerService/Targets/DualShock4Target.cs b/ControllerService/Targets/DualShock4Target.cs index 32f0772ee..399ff397b 100644 --- a/ControllerService/Targets/DualShock4Target.cs +++ b/ControllerService/Targets/DualShock4Target.cs @@ -1,4 +1,5 @@ using ControllerCommon; +using Microsoft.Extensions.Logging; using Nefarius.ViGEm.Client; using Nefarius.ViGEm.Client.Targets; using Nefarius.ViGEm.Client.Targets.DualShock4; @@ -54,18 +55,39 @@ internal class DualShock4Target : ViGEmTarget private new IDualShock4Controller vcontroller; - public DualShock4Target(ViGEmClient client, Controller controller, int index) : base(client, controller, index) + public DualShock4Target(ViGEmClient client, Controller controller, int index, ILogger logger) : base(client, controller, index, logger) { // initialize controller + HID = HIDmode.DualShock4Controller; + vcontroller = client.CreateDualShock4Controller(); vcontroller.AutoSubmitReport = false; + vcontroller.FeedbackReceived += FeedbackReceived; + } + + public void FeedbackReceived(object sender, DualShock4FeedbackReceivedEventArgs e) + { + if (!Controller.IsConnected) + return; + Vibration inputMotor = new() + { + LeftMotorSpeed = (ushort)((e.LargeMotor * ushort.MaxValue / byte.MaxValue) * strength), + RightMotorSpeed = (ushort)((e.SmallMotor * ushort.MaxValue / byte.MaxValue) * strength), + }; + Controller.SetVibration(inputMotor); + } + + public new void Connect() + { vcontroller.Connect(); + base.Connect(); } public new void Disconnect() { vcontroller.Disconnect(); + base.Disconnect(); } public new unsafe void UpdateReport() @@ -140,13 +162,13 @@ public DualShock4Target(ViGEmClient client, Controller controller, int index) : if ((state_s.wButtons & 0x0400) == 0x0400) tempSpecial |= DualShock4SpecialButton.Ps.Value; - if (touch.OutputClickButton) + if (Touch.OutputClickButton) tempSpecial |= DualShock4SpecialButton.Touchpad.Value; outDS4Report.bSpecial = (byte)(tempSpecial | (0 << 2)); } - if (!profile.whitelisted) + if (!Profile.whitelisted) { outDS4Report.wButtons = tempButtons; outDS4Report.wButtons |= tempDPad.Value; @@ -163,18 +185,18 @@ public DualShock4Target(ViGEmClient client, Controller controller, int index) : unchecked { outDS4Report.bTouchPacketsN = 0x01; - outDS4Report.sCurrentTouch.bPacketCounter = touch.TouchPacketCounter; - outDS4Report.sCurrentTouch.bIsUpTrackingNum1 = touch.TrackPadTouch0.RawTrackingNum; - outDS4Report.sCurrentTouch.bTouchData1[0] = (byte)(touch.TrackPadTouch0.X & 0xFF); + outDS4Report.sCurrentTouch.bPacketCounter = Touch.TouchPacketCounter; + outDS4Report.sCurrentTouch.bIsUpTrackingNum1 = Touch.TrackPadTouch0.RawTrackingNum; + outDS4Report.sCurrentTouch.bTouchData1[0] = (byte)(Touch.TrackPadTouch0.X & 0xFF); outDS4Report.sCurrentTouch.bTouchData1[1] = - (byte)(((touch.TrackPadTouch0.X >> 8) & 0x0F) | ((touch.TrackPadTouch0.Y << 4) & 0xF0)); - outDS4Report.sCurrentTouch.bTouchData1[2] = (byte)(touch.TrackPadTouch0.Y >> 4); + (byte)(((Touch.TrackPadTouch0.X >> 8) & 0x0F) | ((Touch.TrackPadTouch0.Y << 4) & 0xF0)); + outDS4Report.sCurrentTouch.bTouchData1[2] = (byte)(Touch.TrackPadTouch0.Y >> 4); - outDS4Report.sCurrentTouch.bIsUpTrackingNum2 = touch.TrackPadTouch1.RawTrackingNum; - outDS4Report.sCurrentTouch.bTouchData2[0] = (byte)(touch.TrackPadTouch1.X & 0xFF); + outDS4Report.sCurrentTouch.bIsUpTrackingNum2 = Touch.TrackPadTouch1.RawTrackingNum; + outDS4Report.sCurrentTouch.bTouchData2[0] = (byte)(Touch.TrackPadTouch1.X & 0xFF); outDS4Report.sCurrentTouch.bTouchData2[1] = - (byte)(((touch.TrackPadTouch1.X >> 8) & 0x0F) | ((touch.TrackPadTouch1.Y << 4) & 0xF0)); - outDS4Report.sCurrentTouch.bTouchData2[2] = (byte)(touch.TrackPadTouch1.Y >> 4); + (byte)(((Touch.TrackPadTouch1.X >> 8) & 0x0F) | ((Touch.TrackPadTouch1.Y << 4) & 0xF0)); + outDS4Report.sCurrentTouch.bTouchData2[2] = (byte)(Touch.TrackPadTouch1.Y >> 4); } outDS4Report.wGyroX = (short)(AngularVelocity.X * F_GYRO_RES_IN_DEG_SEC); // gyroPitchFull diff --git a/ControllerService/Targets/ViGEmTarget.cs b/ControllerService/Targets/ViGEmTarget.cs index 85b450be1..76d77e292 100644 --- a/ControllerService/Targets/ViGEmTarget.cs +++ b/ControllerService/Targets/ViGEmTarget.cs @@ -1,4 +1,5 @@ using ControllerCommon; +using Microsoft.Extensions.Logging; using Nefarius.ViGEm.Client; using Nefarius.ViGEm.Client.Targets; using SharpDX.XInput; @@ -36,10 +37,12 @@ protected struct XInputStateSecret protected static extern int XInputGetStateSecret14(int playerIndex, out XInputStateSecret struc); #endregion - public Profile profile; + public Profile Profile; public Controller Controller; public Gamepad Gamepad; - public DS4Touch touch; + public DS4Touch Touch; + public HIDmode HID = HIDmode.NoController; + protected readonly ILogger logger; public Vector3 AngularVelocity; public Vector3 Acceleration; @@ -50,29 +53,58 @@ protected struct XInputStateSecret protected XInputStateSecret state_s; public long microseconds; + public float strength; // rename me + protected readonly Stopwatch stopwatch; - protected int index; + protected int UserIndex; + + protected short LeftThumbX, LeftThumbY, RightThumbX, RightThumbY; - protected ViGEmTarget(ViGEmClient client, Controller controller, int index) + protected ViGEmTarget(ViGEmClient client, Controller controller, int index, ILogger logger) { + this.logger = logger; + // initialize vectors AngularVelocity = new(); Acceleration = new(); // initialize profile - profile = new(); - touch = new(); + Profile = new(); + Touch = new(); // initialize secret state state_s = new(); + // initialize controller Client = client; Controller = controller; + // initialize stopwatch stopwatch = new Stopwatch(); } - protected short LeftThumbX, LeftThumbY, RightThumbX, RightThumbY; + protected void FeedbackReceived(object sender, EventArgs e) + { + } + + public override string ToString() + { + return this.GetType().Name; + } + + public void Connect() + { + stopwatch.Start(); + + logger.LogInformation("Virtual {0} connected", HID); + } + + public void Disconnect() + { + stopwatch.Stop(); + + logger.LogInformation("Virtual {0} disconnected", HID); + } public void UpdateReport() { @@ -80,14 +112,14 @@ public void UpdateReport() microseconds = (long)(stopwatch.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))); // get current gamepad state - XInputGetStateSecret13(index, out state_s); + XInputGetStateSecret13(UserIndex, out state_s); State state = Controller.GetState(); Gamepad = state.Gamepad; // get buttons values - ushort buttons = (ushort)Gamepad.Buttons; - buttons |= (Gamepad.LeftTrigger > 0 ? (ushort)1024 : (ushort)0); - buttons |= (Gamepad.RightTrigger > 0 ? (ushort)2048 : (ushort)0); + uint buttons = (ushort)Gamepad.Buttons; + buttons |= (Gamepad.LeftTrigger > 0 ? (uint)Utils.GamepadButtonFlags.LeftTrigger : 0); + buttons |= (Gamepad.RightTrigger > 0 ? (uint)Utils.GamepadButtonFlags.RightTrigger : 0); // get sticks values LeftThumbX = Gamepad.LeftThumbX; @@ -95,12 +127,12 @@ public void UpdateReport() RightThumbX = Gamepad.RightThumbX; RightThumbY = Gamepad.RightThumbY; - if (profile.umc_enabled && ((buttons + ProfileButton.AlwaysOn.Value) & profile.umc_trigger) != 0) + if (Profile.umc_enabled && (buttons & Profile.umc_trigger) == Profile.umc_trigger) { - float intensity = profile.GetIntensity(); - float sensivity = profile.GetSensiviy(); + float intensity = Profile.GetIntensity(); + float sensivity = Profile.GetSensiviy(); - switch (profile.umc_input) + switch (Profile.umc_input) { default: case InputStyle.RightStick: @@ -114,10 +146,5 @@ public void UpdateReport() } } } - - internal void Disconnect() - { - throw new NotImplementedException(); - } } } diff --git a/ControllerService/Targets/Xbox360Target.cs b/ControllerService/Targets/Xbox360Target.cs index fa7842b8d..f3b468229 100644 --- a/ControllerService/Targets/Xbox360Target.cs +++ b/ControllerService/Targets/Xbox360Target.cs @@ -1,4 +1,6 @@ -using Nefarius.ViGEm.Client; +using ControllerCommon; +using Microsoft.Extensions.Logging; +using Nefarius.ViGEm.Client; using Nefarius.ViGEm.Client.Targets; using Nefarius.ViGEm.Client.Targets.Xbox360; using SharpDX.XInput; @@ -49,18 +51,39 @@ internal partial class Xbox360Target : ViGEmTarget private new IXbox360Controller vcontroller; - public Xbox360Target(ViGEmClient client, Controller controller, int index) : base(client, controller, index) + public Xbox360Target(ViGEmClient client, Controller controller, int index, ILogger logger) : base(client, controller, index, logger) { // initialize controller + HID = HIDmode.Xbox360Controller; + vcontroller = client.CreateXbox360Controller(); vcontroller.AutoSubmitReport = false; + vcontroller.FeedbackReceived += FeedbackReceived; + } + public new void Connect() + { vcontroller.Connect(); + base.Connect(); } public new void Disconnect() { vcontroller.Disconnect(); + base.Disconnect(); + } + + public void FeedbackReceived(object sender, Xbox360FeedbackReceivedEventArgs e) + { + if (!Controller.IsConnected) + return; + + Vibration inputMotor = new() + { + LeftMotorSpeed = (ushort)((e.LargeMotor * ushort.MaxValue / byte.MaxValue) * strength), + RightMotorSpeed = (ushort)((e.SmallMotor * ushort.MaxValue / byte.MaxValue) * strength), + }; + Controller.SetVibration(inputMotor); } public new unsafe void UpdateReport() @@ -75,7 +98,7 @@ public Xbox360Target(ViGEmClient client, Controller controller, int index) : bas vcontroller.SetAxisValue(Xbox360Axis.RightThumbX, RightThumbX); vcontroller.SetAxisValue(Xbox360Axis.RightThumbY, RightThumbY); - foreach (Xbox360Button button in (Xbox360Button[])Enum.GetValues(typeof(Xbox360Button))) + foreach (Xbox360Button button in ButtonMap) { GamepadButtonFlags value = (GamepadButtonFlags)button.Value; vcontroller.SetButtonState(button, Gamepad.Buttons.HasFlag(value)); @@ -84,7 +107,7 @@ public Xbox360Target(ViGEmClient client, Controller controller, int index) : bas vcontroller.SetSliderValue(Xbox360Slider.LeftTrigger, Gamepad.LeftTrigger); vcontroller.SetSliderValue(Xbox360Slider.RightTrigger, Gamepad.RightTrigger); - if (!profile.whitelisted) + if (!Profile.whitelisted) vcontroller.SubmitReport(); } } diff --git a/ControllerService/XInputAccelerometer.cs b/ControllerService/XInputAccelerometer.cs index 888aa49dd..af1df472c 100644 --- a/ControllerService/XInputAccelerometer.cs +++ b/ControllerService/XInputAccelerometer.cs @@ -32,13 +32,17 @@ public XInputAccelerometer(XInputController controller, ILogger logger) if (sensor != null) { sensor.ReportInterval = sensor.MinimumReportInterval; - logger.LogInformation("Accelerometer initialised"); - logger.LogInformation("Accelerometer report interval set to {0}ms", sensor.ReportInterval); + logger.LogInformation("{0} initialised. Report interval set to {1}ms", this.ToString(), sensor.ReportInterval); sensor.ReadingChanged += AcceleroReadingChanged; } } + public override string ToString() + { + return this.GetType().Name; + } + void AcceleroReadingChanged(Accelerometer sender, AccelerometerReadingChangedEventArgs args) { AccelerometerReading reading = args.Reading; @@ -53,12 +57,12 @@ void AcceleroReadingChanged(Accelerometer sender, AccelerometerReadingChangedEve this.reading.Y = (float)accelFilter.axis1Filter.Filter(reading.AccelerationZ, rate); this.reading.Z = (float)accelFilter.axis1Filter.Filter(reading.AccelerationY, rate); - if (controller.target != null) + if (controller.Target != null) { - this.reading *= controller.target.profile.accelerometer; + this.reading *= controller.Target.Profile.accelerometer; - this.reading.Z = (controller.target.profile.inverthorizontal ? -1.0f : 1.0f) * this.reading.Z; - this.reading.X = (controller.target.profile.invertvertical ? -1.0f : 1.0f) * this.reading.X; + this.reading.Z = (controller.Target.Profile.inverthorizontal ? -1.0f : 1.0f) * this.reading.Z; + this.reading.X = (controller.Target.Profile.invertvertical ? -1.0f : 1.0f) * this.reading.X; } // raise event diff --git a/ControllerService/XInputController.cs b/ControllerService/XInputController.cs index 01ed3f305..7b92f1e1f 100644 --- a/ControllerService/XInputController.cs +++ b/ControllerService/XInputController.cs @@ -21,32 +21,29 @@ namespace ControllerService public class XInputController { public Controller Controller; - public ViGEmTarget target; + public ViGEmTarget Target; - public DeviceInstance instance; + public DeviceInstance Instance; - private DSUServer server; + private DSUServer DSUServer; public XInputGirometer gyrometer; public XInputAccelerometer accelerometer; private readonly Timer UpdateTimer; - private float strength; - public UserIndex index; + public UserIndex UserIndex; private object updateLock = new(); private readonly ILogger logger; - private readonly string HIDmode; - public XInputController(Controller controller, UserIndex index, int HIDrate, string HIDmode, ILogger logger) + public XInputController(Controller controller, UserIndex index, int HIDrate, ILogger logger) { this.logger = logger; - this.HIDmode = HIDmode; // initilize controller this.Controller = controller; - this.index = index; + this.UserIndex = index; // initialize timers UpdateTimer = new Timer(HIDrate) { Enabled = false, AutoReset = true }; @@ -55,51 +52,25 @@ public XInputController(Controller controller, UserIndex index, int HIDrate, str public void SetPollRate(int HIDrate) { UpdateTimer.Interval = HIDrate; - logger.LogInformation("Virtual {0} report interval set to {1}ms", target.GetType().Name, UpdateTimer.Interval); + logger.LogInformation("Virtual {0} report interval set to {1}ms", Target.GetType().Name, UpdateTimer.Interval); } public void SetVibrationStrength(float strength) { - this.strength = strength / 100.0f; - logger.LogInformation("Virtual {0} vibration strength set to {1}%", target.GetType().Name, strength); + this.Target.strength = strength / 100.0f; + logger.LogInformation("Virtual {0} vibration strength set to {1}%", Target.GetType().Name, strength); } public Dictionary ToArgs() { return new Dictionary() { - { "ProductName", instance.ProductName }, - { "InstanceGuid", $"{instance.InstanceGuid}" }, - { "ProductGuid", $"{instance.ProductGuid}" }, - { "ProductIndex", $"{(int)index}" } + { "ProductName", Instance.ProductName }, + { "InstanceGuid", $"{Instance.InstanceGuid}" }, + { "ProductGuid", $"{Instance.ProductGuid}" }, + { "ProductIndex", $"{(int)UserIndex}" } }; } - private void XBOX_FeedbackReceived(object sender, Xbox360FeedbackReceivedEventArgs e) - { - if (!Controller.IsConnected) - return; - - Vibration inputMotor = new() - { - LeftMotorSpeed = (ushort)((e.LargeMotor * ushort.MaxValue / byte.MaxValue) * strength), - RightMotorSpeed = (ushort)((e.SmallMotor * ushort.MaxValue / byte.MaxValue) * strength), - }; - Controller.SetVibration(inputMotor); - } - - private void DS4_FeedbackReceived(object sender, DualShock4FeedbackReceivedEventArgs e) - { - if (!Controller.IsConnected) - return; - - Vibration inputMotor = new() - { - LeftMotorSpeed = (ushort)((e.LargeMotor * ushort.MaxValue / byte.MaxValue) * strength), - RightMotorSpeed = (ushort)((e.SmallMotor * ushort.MaxValue / byte.MaxValue) * strength), - }; - Controller.SetVibration(inputMotor); - } - public void SetGyroscope(XInputGirometer _gyrometer) { gyrometer = _gyrometer; @@ -114,63 +85,56 @@ public void SetAccelerometer(XInputAccelerometer _accelerometer) public void SetDSUServer(DSUServer _server) { - server = _server; + DSUServer = _server; } private void Accelerometer_ReadingChanged(object sender, Vector3 acceleration) { - target.Acceleration = acceleration; + Target.Acceleration = acceleration; } private void Girometer_ReadingChanged(object sender, Vector3 angularvelocity) { - target.AngularVelocity = angularvelocity; + Target.AngularVelocity = angularvelocity; } - public void SetTarget(ViGEmClient client) + public void SetTarget(ViGEmTarget target) { - switch (HIDmode) + this.Target = target; + + logger.LogInformation("Virtual {0} attached to {1} on slot {2}", target.HID, Instance.InstanceName, UserIndex); + logger.LogInformation("Virtual {0} report interval set to {1}ms", target.HID, UpdateTimer.Interval); + + switch (Target.HID) { - default: - case "DualShock4Controller": - target = new DualShock4Target(client, Controller, (int)index); + case HIDmode.Xbox360Controller: + ((Xbox360Target)Target)?.Connect(); break; - case "Xbox360Controller": - target = new Xbox360Target(client, Controller, (int)index); + case HIDmode.DualShock4Controller: + ((DualShock4Target)Target)?.Connect(); break; } - if (target == null) - { - logger.LogCritical("No Virtual controller detected. Application will stop"); - throw new InvalidOperationException(); - } - UpdateTimer.Elapsed += async (sender, e) => await UpdateReport(); UpdateTimer.Enabled = true; UpdateTimer.Start(); - - logger.LogInformation("Virtual {0} connected", target.GetType().Name); - logger.LogInformation("Virtual {0} attached to {1} on slot {2}", target.GetType().Name, instance.InstanceName, index); - logger.LogInformation("Virtual {0} report interval set to {1}ms", target.GetType().Name, UpdateTimer.Interval); } private Task UpdateReport() { lock (updateLock) { - // that suxx ! - switch (HIDmode) + switch(Target.HID) { - default: - case "DualShock4Controller": - ((DualShock4Target)target)?.UpdateReport(); + case HIDmode.Xbox360Controller: + ((Xbox360Target)Target)?.UpdateReport(); break; - case "Xbox360Controller": - ((Xbox360Target)target)?.UpdateReport(); + case HIDmode.DualShock4Controller: + ((DualShock4Target)Target)?.UpdateReport(); break; } - server?.NewReportIncoming(target); + + DSUServer?.NewReportIncoming(Target); } return Task.CompletedTask; diff --git a/ControllerService/XInputGirometer.cs b/ControllerService/XInputGirometer.cs index 0eb33141d..7315b6a48 100644 --- a/ControllerService/XInputGirometer.cs +++ b/ControllerService/XInputGirometer.cs @@ -33,13 +33,17 @@ public XInputGirometer(XInputController controller, ILogger logger) if (sensor != null) { sensor.ReportInterval = sensor.MinimumReportInterval; - logger.LogInformation("Gyrometer initialised"); - logger.LogInformation("Gyrometer report interval set to {0}ms", sensor.ReportInterval); + logger.LogInformation("{0} initialised. Report interval set to {1}ms", this.ToString(), sensor.ReportInterval); sensor.ReadingChanged += GyroReadingChanged; } } + public override string ToString() + { + return this.GetType().Name; + } + void GyroReadingChanged(Gyrometer sender, GyrometerReadingChangedEventArgs args) { GyrometerReading reading = args.Reading; @@ -54,12 +58,12 @@ void GyroReadingChanged(Gyrometer sender, GyrometerReadingChangedEventArgs args) this.reading.Y = (float)gyroFilter.axis1Filter.Filter(reading.AngularVelocityZ, rate); this.reading.Z = (float)gyroFilter.axis1Filter.Filter(reading.AngularVelocityY, rate); - if (controller.target != null) + if (controller.Target != null) { - this.reading *= controller.target.profile.gyrometer; + this.reading *= controller.Target.Profile.gyrometer; - this.reading.Z = (controller.target.profile.inverthorizontal ? -1.0f : 1.0f) * this.reading.Z; - this.reading.X = (controller.target.profile.invertvertical ? -1.0f : 1.0f) * this.reading.X; + this.reading.Z = (controller.Target.Profile.inverthorizontal ? -1.0f : 1.0f) * this.reading.Z; + this.reading.X = (controller.Target.Profile.invertvertical ? -1.0f : 1.0f) * this.reading.X; } // raise event