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 @@
+
diff --git a/Program/Windows/MainWindow.xaml.cs b/Program/Windows/MainWindow.xaml.cs
index 3a5546e..966f426 100644
--- a/Program/Windows/MainWindow.xaml.cs
+++ b/Program/Windows/MainWindow.xaml.cs
@@ -29,7 +29,8 @@ private enum ControllerType
None = -1,
vJoy = 0,
ViGEmBus = 1,
- RPCS3 = 2
+ RPCS3 = 2,
+ shadPS4 = 3,
}
public MainWindow()
@@ -87,6 +88,7 @@ private void Window_Loaded(object sender, RoutedEventArgs e)
Console.WriteLine("ViGEmBus found!");
vigemDeviceTypeOption.IsEnabled = true;
rpcs3DeviceTypeOption.IsEnabled = true;
+ shadPS4DeviceTypeOption.IsEnabled = true;
}
else
{
@@ -95,6 +97,8 @@ private void Window_Loaded(object sender, RoutedEventArgs e)
vigemDeviceTypeOption.IsSelected = false;
rpcs3DeviceTypeOption.IsEnabled = false;
rpcs3DeviceTypeOption.IsSelected = false;
+ shadPS4DeviceTypeOption.IsEnabled = false;
+ shadPS4DeviceTypeOption.IsSelected = false;
}
// Exit if neither ViGEmBus nor vJoy are installed
@@ -128,6 +132,7 @@ private void LoadBackendSettings()
{
SetDeviceType((ControllerType)Settings.Default.controllerDeviceType);
MappingSettings.UseAccurateDrumMappings = Settings.Default.accurateDrumMaps;
+ MappingSettings.RiffmasterSensitivity = Settings.Default.riffmasterTiltSensitivity;
}
///
@@ -300,6 +305,21 @@ private void SetDeviceType(ControllerType type)
return;
}
break;
+
+ case ControllerType.shadPS4:
+ if (shadPS4DeviceTypeOption.IsEnabled && ViGEmInstance.Initialized)
+ {
+ MapperFactory.MapperMode = MappingMode.shadPS4;
+ }
+ else
+ {
+ // Reset device type selection
+ // Setting this fires off the handler again, no extra handling is needed
+ MapperFactory.MapperMode = MappingMode.NotSet;
+ controllerDeviceTypeCombo.SelectedIndex = -1;
+ return;
+ }
+ break;
case ControllerType.None:
MapperFactory.MapperMode = MappingMode.NotSet;
diff --git a/Program/Windows/SettingsWindow.xaml b/Program/Windows/SettingsWindow.xaml
index 57b3705..a33f17f 100644
--- a/Program/Windows/SettingsWindow.xaml
+++ b/Program/Windows/SettingsWindow.xaml
@@ -6,7 +6,7 @@
xmlns:local="clr-namespace:RB4InstrumentMapper"
mc:Ignorable="d"
Title="Settings"
- Height="140" Width="350"
+ Height="180" Width="350"
ResizeMode="NoResize" WindowStartupLocation="CenterOwner"
Loaded="WindowLoaded" Closed="WindowClosed">
@@ -14,6 +14,8 @@
ToolTip="Automatically starts capture/mapping when RB4InstrumentMapper starts up."/>
+
+
diff --git a/Program/Windows/SettingsWindow.xaml.cs b/Program/Windows/SettingsWindow.xaml.cs
index cc13285..4ab9df1 100644
--- a/Program/Windows/SettingsWindow.xaml.cs
+++ b/Program/Windows/SettingsWindow.xaml.cs
@@ -18,6 +18,7 @@ private void WindowLoaded(object sender, RoutedEventArgs e)
{
autoStartCheckBox.IsChecked = Settings.Default.autoStart;
accurateDrumMapsCheckBox.IsChecked = Settings.Default.accurateDrumMaps;
+ riffmasterTiltSensitivity.Value = Settings.Default.riffmasterTiltSensitivity;
}
private void WindowClosed(object sender, EventArgs e)
@@ -29,7 +30,8 @@ private void saveButton_Click(object sender, RoutedEventArgs args)
{
Settings.Default.autoStart = autoStartCheckBox.IsChecked.GetValueOrDefault();
Settings.Default.accurateDrumMaps = accurateDrumMapsCheckBox.IsChecked.GetValueOrDefault();
-
+ Settings.Default.riffmasterTiltSensitivity = riffmasterTiltSensitivity.Value;
+
Close();
}
From 9921648d9a7b2ad224e23f015bb581ce39751674 Mon Sep 17 00:00:00 2001
From: Nathan
Date: Wed, 16 Apr 2025 19:25:10 -0600
Subject: [PATCH 2/3] Add .idea folder to .gitignore
---
.gitignore | 8 +++++---
.idea/.idea.RB4InstrumentMapper/.idea/.gitignore | 13 -------------
.idea/.idea.RB4InstrumentMapper/.idea/encodings.xml | 4 ----
.../.idea.RB4InstrumentMapper/.idea/indexLayout.xml | 8 --------
.idea/.idea.RB4InstrumentMapper/.idea/vcs.xml | 6 ------
5 files changed, 5 insertions(+), 34 deletions(-)
delete mode 100644 .idea/.idea.RB4InstrumentMapper/.idea/.gitignore
delete mode 100644 .idea/.idea.RB4InstrumentMapper/.idea/encodings.xml
delete mode 100644 .idea/.idea.RB4InstrumentMapper/.idea/indexLayout.xml
delete mode 100644 .idea/.idea.RB4InstrumentMapper/.idea/vcs.xml
diff --git a/.gitignore b/.gitignore
index 7350d1d..493247f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,3 @@
-# VS Code configuration folder
-.vscode/
-
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
@@ -34,6 +31,11 @@ bld/
# Visual Studio 2015/2017 cache/options directory
.vs/
+# VS Code configuration directory
+.vscode/
+# JetBrains cache/options directory
+.idea/
+
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
diff --git a/.idea/.idea.RB4InstrumentMapper/.idea/.gitignore b/.idea/.idea.RB4InstrumentMapper/.idea/.gitignore
deleted file mode 100644
index f2b00d0..0000000
--- a/.idea/.idea.RB4InstrumentMapper/.idea/.gitignore
+++ /dev/null
@@ -1,13 +0,0 @@
-# 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
deleted file mode 100644
index df87cf9..0000000
--- a/.idea/.idea.RB4InstrumentMapper/.idea/encodings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/.idea/.idea.RB4InstrumentMapper/.idea/indexLayout.xml b/.idea/.idea.RB4InstrumentMapper/.idea/indexLayout.xml
deleted file mode 100644
index 7b08163..0000000
--- a/.idea/.idea.RB4InstrumentMapper/.idea/indexLayout.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/.idea.RB4InstrumentMapper/.idea/vcs.xml b/.idea/.idea.RB4InstrumentMapper/.idea/vcs.xml
deleted file mode 100644
index 35eb1dd..0000000
--- a/.idea/.idea.RB4InstrumentMapper/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
From cb994c2d677e5321ffa76fe99b6938f350ddb279 Mon Sep 17 00:00:00 2001
From: Nathan
Date: Wed, 16 Apr 2025 19:29:20 -0600
Subject: [PATCH 3/3] Fix errors caused by the merge; add shadps4 option to CLI
arguments
---
RB4InstrumentMapper.CLI/Arguments.cs | 6 +++++-
RB4InstrumentMapper.GUI/Windows/MainWindow.xaml.cs | 4 ++--
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/RB4InstrumentMapper.CLI/Arguments.cs b/RB4InstrumentMapper.CLI/Arguments.cs
index 22f5eaf..819c528 100644
--- a/RB4InstrumentMapper.CLI/Arguments.cs
+++ b/RB4InstrumentMapper.CLI/Arguments.cs
@@ -109,6 +109,10 @@ public static bool TryParse(string[] args, out Arguments parsed)
{
parsed.MappingMode = MappingMode.RPCS3;
}
+ else if (modeStr.Equals("shadps4", StringComparison.OrdinalIgnoreCase))
+ {
+ parsed.MappingMode = MappingMode.shadPS4;
+ }
else
{
Console.WriteLine($"Error: Invalid mapping mode '{modeStr}'");
@@ -221,7 +225,7 @@ public static void PrintHelp()
Console.WriteLine();
Console.WriteLine("Options:");
Console.WriteLine(" --mode The mapping mode to use.");
- Console.WriteLine(" - mode: one of 'vigembus', 'vigem', 'vjoy', or 'rpcs3', case insensitive.");
+ Console.WriteLine(" - mode: one of 'vigem'/'vigembus', 'vjoy', 'rpcs3', or 'shadps4', case insensitive.");
Console.WriteLine(" --accurate-drums Use hardware-accurate drum mappings for ViGEmBus mode.");
Console.WriteLine();
Console.WriteLine(" --wait-for-devices [timeout] Wait for devices to be detected before starting (default timeout: 30s).");
diff --git a/RB4InstrumentMapper.GUI/Windows/MainWindow.xaml.cs b/RB4InstrumentMapper.GUI/Windows/MainWindow.xaml.cs
index 0a144dd..601a627 100644
--- a/RB4InstrumentMapper.GUI/Windows/MainWindow.xaml.cs
+++ b/RB4InstrumentMapper.GUI/Windows/MainWindow.xaml.cs
@@ -315,13 +315,13 @@ private void SetDeviceType(ControllerType type)
case ControllerType.shadPS4:
if (shadPS4DeviceTypeOption.IsEnabled && ViGEmInstance.Initialized)
{
- MapperFactory.MapperMode = MappingMode.shadPS4;
+ BackendSettings.MapperMode = MappingMode.shadPS4;
}
else
{
// Reset device type selection
// Setting this fires off the handler again, no extra handling is needed
- MapperFactory.MapperMode = MappingMode.NotSet;
+ BackendSettings.MapperMode = MappingMode.NotSet;
controllerDeviceTypeCombo.SelectedIndex = -1;
return;
}