From faa48ef5adfcefd80f6a23cbb509d0e58f5dfc25 Mon Sep 17 00:00:00 2001 From: aoiyu_ <139608541+aoiyu-dev@users.noreply.github.com> Date: Wed, 15 Jan 2025 23:36:05 -0600 Subject: [PATCH 1/3] Add Riffmaster support for shadPS4 + Added shadPS4 Mapper for Riffmaster + Added a new setting to control the sensitivity of the Riffmaster's tilt for Overdrive. + Added the ability to change the pickup effect via clicking down the thumbstick. --- .../.idea/.gitignore | 13 +++ .../.idea/encodings.xml | 4 + .../.idea/indexLayout.xml | 8 ++ .idea/.idea.RB4InstrumentMapper/.idea/vcs.xml | 6 ++ Program/Mapping/MapperFactory.cs | 32 ++++++-- .../shadPS4/RiffmastershadPS4Mapper.cs | 82 +++++++++++++++++++ Program/Mapping/MappingSettings.cs | 1 + Program/Parsing/ParsingUtils.cs | 20 +++++ Program/Properties/Settings.Designer.cs | 15 ++++ Program/Windows/MainWindow.xaml | 1 + Program/Windows/MainWindow.xaml.cs | 22 ++++- Program/Windows/SettingsWindow.xaml | 4 +- Program/Windows/SettingsWindow.xaml.cs | 4 +- 13 files changed, 204 insertions(+), 8 deletions(-) create mode 100644 .idea/.idea.RB4InstrumentMapper/.idea/.gitignore create mode 100644 .idea/.idea.RB4InstrumentMapper/.idea/encodings.xml create mode 100644 .idea/.idea.RB4InstrumentMapper/.idea/indexLayout.xml create mode 100644 .idea/.idea.RB4InstrumentMapper/.idea/vcs.xml create mode 100644 Program/Mapping/Mappers/shadPS4/RiffmastershadPS4Mapper.cs diff --git a/.idea/.idea.RB4InstrumentMapper/.idea/.gitignore b/.idea/.idea.RB4InstrumentMapper/.idea/.gitignore new file mode 100644 index 0000000..f2b00d0 --- /dev/null +++ b/.idea/.idea.RB4InstrumentMapper/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/modules.xml +/.idea.RB4InstrumentMapper.iml +/contentModel.xml +/projectSettingsUpdater.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.RB4InstrumentMapper/.idea/encodings.xml b/.idea/.idea.RB4InstrumentMapper/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/.idea/.idea.RB4InstrumentMapper/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/.idea.RB4InstrumentMapper/.idea/indexLayout.xml b/.idea/.idea.RB4InstrumentMapper/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/.idea/.idea.RB4InstrumentMapper/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.RB4InstrumentMapper/.idea/vcs.xml b/.idea/.idea.RB4InstrumentMapper/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/.idea.RB4InstrumentMapper/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Program/Mapping/MapperFactory.cs b/Program/Mapping/MapperFactory.cs index bbe4480..d579842 100644 --- a/Program/Mapping/MapperFactory.cs +++ b/Program/Mapping/MapperFactory.cs @@ -10,6 +10,7 @@ public enum MappingMode ViGEmBus = 1, vJoy = 2, RPCS3 = 3, + shadPS4 = 4, } /// @@ -155,7 +156,7 @@ public static DeviceMapper GetByInterfaceIds(IBackendClient client, HashSet new GamepadViGEmMapper(c), (c) => new GamepadvJoyMapper(c), - // No RPCS3 mapper, as this is for testing only + // No RPCS3 or shadPS4 mapper, as this is for testing only + (c) => new GamepadViGEmMapper(c), (c) => new GamepadViGEmMapper(c) ); #else @@ -220,24 +227,37 @@ public static DeviceMapper GetGuitarMapper(IBackendClient client) createViGEm = (c) => new RiffmasterViGEmMapper(c); else createViGEm = (c) => new GuitarViGEmMapper(c); + + // I (aoiyu_) am not 100% sure if the base guitars share the same problems as the Riffmaster. + // Sorry if they do, I just don't have a non-Riffmaster to test on. + CreateMapper createshadPS4; + if (isRiffmaster) + createshadPS4 = (c) => new RiffmastershadPS4Mapper(c); + else + createshadPS4 = (c) => new GuitarViGEmMapper(c); return GetMapper(client, createViGEm, (c) => new GuitarvJoyMapper(c), - (c) => new GuitarRPCS3Mapper(c) + (c) => new GuitarRPCS3Mapper(c), + createshadPS4 ); } public static DeviceMapper GetDrumsMapper(IBackendClient client) => GetMapper(client, (c) => new DrumsViGEmMapper(c), (c) => new DrumsvJoyMapper(c), - (c) => new DrumsRPCS3Mapper(c) + (c) => new DrumsRPCS3Mapper(c), + // No mapping differences that I (aoiyu_) know of. + (c) => new DrumsViGEmMapper(c) ); public static DeviceMapper GetGHLGuitarMapper(IBackendClient client) => GetMapper(client, (c) => new GHLGuitarViGEmMapper(c), (c) => new GHLGuitarvJoyMapper(c), // No mapping differences between RPCS3 and ViGEm modes + (c) => new GHLGuitarViGEmMapper(c), + // No mapping differences that I (aoiyu_) know of. (c) => new GHLGuitarViGEmMapper(c) ); @@ -251,7 +271,9 @@ public static DeviceMapper GetWirelessLegacyMapper(IBackendClient client) public static DeviceMapper GetFallbackMapper(IBackendClient client) => GetMapper(client, (c) => new FallbackViGEmMapper(c), (c) => new FallbackvJoyMapper(c), - (c) => new FallbackRPCS3Mapper(c) + (c) => new FallbackRPCS3Mapper(c), + // No mapping differences that I (aoiyu_) know of. + (c) => new FallbackViGEmMapper(c) ); } } \ No newline at end of file diff --git a/Program/Mapping/Mappers/shadPS4/RiffmastershadPS4Mapper.cs b/Program/Mapping/Mappers/shadPS4/RiffmastershadPS4Mapper.cs new file mode 100644 index 0000000..093ccaa --- /dev/null +++ b/Program/Mapping/Mappers/shadPS4/RiffmastershadPS4Mapper.cs @@ -0,0 +1,82 @@ +using System; +using Nefarius.ViGEm.Client.Targets; +using Nefarius.ViGEm.Client.Targets.Xbox360; +using RB4InstrumentMapper.Parsing; + +namespace RB4InstrumentMapper.Mapping +{ + /// + /// Maps Riffmaster guitar inputs to a ViGEmBus device with modifications to support shadPS4. + /// + internal class RiffmastershadPS4Mapper : ViGEmMapper + { + public RiffmastershadPS4Mapper(IBackendClient client) + : base(client) + { + } + + private static int currentPickup = 0; + private static bool pickupDown = false; + + protected override XboxResult OnMessageReceived(byte command, ReadOnlySpan data) + { + switch (command) + { + case XboxRiffmasterInput.CommandId: + return ParseInput(data); + + default: + return XboxResult.Success; + } + } + + private unsafe XboxResult ParseInput(ReadOnlySpan data) + { + if (!ParsingUtils.TryRead(data, out XboxRiffmasterInput guitarReport)) + return XboxResult.InvalidMessage; + + HandleReport(device, guitarReport); + + // Send data + return SubmitReport(); + } + + /// + /// Maps guitar input data to an Xbox 360 controller. + /// + internal static void HandleReport(IXbox360Controller device, in XboxRiffmasterInput report) + { + // Guitar inputs + GuitarViGEmMapper.HandleReport(device, report.Base); + + // Whammy Bar + device.SetAxisValue(Xbox360Axis.LeftThumbY, report.Base.WhammyBar.ScaleToPositiveInt16()); + + // Tilt + device.SetAxisValue(Xbox360Axis.RightThumbY, (-1 * (int)Math.Round(report.Base.Tilt.ScaleToInt16() * MappingSettings.RiffmasterSensitivity)).ClampToShort()); + + // Joystick + device.SetButtonState(Xbox360Button.LeftThumb, report.JoystickClick | report.Base.LowerFretsPressed); + + // Pickup + HandlePickup(report); + device.SetSliderValue(Xbox360Slider.LeftTrigger, (byte)(currentPickup * 51 - 25)); + } + + private static void HandlePickup(XboxRiffmasterInput report) + { + bool pickupSetDown = ((XboxGamepadButton)report.Base.Buttons).HasFlag(XboxGamepadButton.LeftStickPress); + if (pickupSetDown && !pickupDown) + { + pickupDown = true; + currentPickup++; + if (currentPickup > 4) + currentPickup = 0; + } + else if (!pickupSetDown && pickupDown) + { + pickupDown = false; + } + } + } +} diff --git a/Program/Mapping/MappingSettings.cs b/Program/Mapping/MappingSettings.cs index 55dc2fb..49b17d9 100644 --- a/Program/Mapping/MappingSettings.cs +++ b/Program/Mapping/MappingSettings.cs @@ -9,5 +9,6 @@ public static class MappingSettings /// Whether or not to use accurate drum mappings (only applies to ViGEmBus mode). /// public static bool UseAccurateDrumMappings { get; set; } = false; + public static double RiffmasterSensitivity { get; set; } = 1.5; } } \ No newline at end of file diff --git a/Program/Parsing/ParsingUtils.cs b/Program/Parsing/ParsingUtils.cs index 1d145fe..47bc55a 100644 --- a/Program/Parsing/ParsingUtils.cs +++ b/Program/Parsing/ParsingUtils.cs @@ -107,6 +107,14 @@ public static short ScaleToInt16(this byte input) { return (short)(((input ^ 0x80) << 8) | input); } + + /// + /// Scales a byte to a short, starting from 0. + /// + public static short ScaleToPositiveInt16(this byte input) + { + return (short)(((input / 2) << 8) | input); + } /// /// Scales a byte to an unsigned short. @@ -115,5 +123,17 @@ public static ushort ScaleToUInt16(this byte input) { return (ushort)((input << 8) | input); } + + /// + /// Clamps an int to a short. + /// + public static short ClampToShort(this int input) + { + if (input > short.MaxValue) + return short.MaxValue; + else if (input < short.MinValue) + return short.MinValue; + return (short)input; + } } } diff --git a/Program/Properties/Settings.Designer.cs b/Program/Properties/Settings.Designer.cs index 60a2600..09463cf 100644 --- a/Program/Properties/Settings.Designer.cs +++ b/Program/Properties/Settings.Designer.cs @@ -70,5 +70,20 @@ public bool accurateDrumMaps { this["accurateDrumMaps"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("1.5")] + public double riffmasterTiltSensitivity + { + get + { + return ((double)(this["riffmasterTiltSensitivity"])); + } + set + { + this["riffmasterTiltSensitivity"] = value; + } + } } } diff --git a/Program/Windows/MainWindow.xaml b/Program/Windows/MainWindow.xaml index 5b0db67..26c00e1 100644 --- a/Program/Windows/MainWindow.xaml +++ b/Program/Windows/MainWindow.xaml @@ -37,6 +37,7 @@ +