diff --git a/src/Ryujinx.Common/Configuration/Hid/Controller/RumbleConfigController.cs b/src/Ryujinx.Common/Configuration/Hid/Controller/RumbleConfigController.cs
index ee8ab457d..f190996c1 100644
--- a/src/Ryujinx.Common/Configuration/Hid/Controller/RumbleConfigController.cs
+++ b/src/Ryujinx.Common/Configuration/Hid/Controller/RumbleConfigController.cs
@@ -16,5 +16,10 @@ namespace Ryujinx.Common.Configuration.Hid.Controller
/// Enable Rumble
///
public bool EnableRumble { get; set; }
+
+ ///
+ /// Enable HD Rumble support
+ /// = 0)
+ {
+ return true;
+ }
+
+ if (!String.IsNullOrEmpty(SDL_GetError()))
+ {
+ Logger.Error?.PrintMsg(LogClass.Hid, SDL_GetError());
+ SDL_ClearError();
+ }
+ return false;
}
}
-
private static int EncodeLowFreq(float lowFreq)
{
float lf = Math.Clamp(lowFreq, 40.875885f, 626.286133f);
- return (int)Math.Round(32 * Math.Log2(lf * 0.1f)) - 0x40;
+ return (int) Math.Round(32 * Math.Log2(lf * 0.1f) - 0x40);
}
private static int EncodeHighFreq(float highFreq)
{
float hf = Math.Clamp(highFreq, 81.75177f, 1252.572266f);
- return ((int)Math.Round(32 * Math.Log2(hf * 0.1f)) - 0x60) * 4;
+ return (int) Math.Round((32 * Math.Log2(hf * 0.1f) - 0x60) * 4);
}
private static int EncodeLowAmp(float rawAmp)
{
- int encodedAmp = 0;
+ double encodedAmp = 0;
if (rawAmp is > 0 and < 0.012f)
{
@@ -92,15 +103,15 @@ namespace Ryujinx.Input.SDL3
}
else if (rawAmp is >= 0.012f and < 0.112f)
{
- encodedAmp = (int)Math.Round(4 * Math.Log2(rawAmp * 110f));
+ encodedAmp = 4 * Math.Log2(rawAmp * 110f);
}
else if (rawAmp is >= 0.112f and < 0.225f)
{
- encodedAmp = (int)Math.Round(16 * Math.Log2(rawAmp * 17f));
+ encodedAmp = 16 * Math.Log2(rawAmp * 17f);
}
else if (rawAmp is >= 0.225f and <= 1f)
{
- encodedAmp = (int)Math.Round(32 * Math.Log2(rawAmp * 8.7f));
+ encodedAmp = 32 * Math.Log2(rawAmp * 8.7f);
}
return (int)Math.Floor(encodedAmp / 2.0) + 64;
@@ -108,7 +119,7 @@ namespace Ryujinx.Input.SDL3
private static int EncodeHighAmp(float rawAmp)
{
- int encodedAmp = 0;
+ double encodedAmp = 0;
if (rawAmp is > 0 and < 0.012f)
{
@@ -116,23 +127,23 @@ namespace Ryujinx.Input.SDL3
}
else if (rawAmp is >= 0.012f and < 0.112f)
{
- encodedAmp = (int)Math.Round(4 * Math.Log2(rawAmp * 110f));
+ encodedAmp = 4 * Math.Log2(rawAmp * 110f);
}
else if (rawAmp is >= 0.112f and < 0.225f)
{
- encodedAmp = (int)Math.Round(16 * Math.Log2(rawAmp * 17f));
+ encodedAmp = 16 * Math.Log2(rawAmp * 17f);
}
else if (rawAmp is >= 0.225f and <= 1f)
{
- encodedAmp = (int)Math.Round(32 * Math.Log2(rawAmp * 8.7f));
+ encodedAmp = 32 * Math.Log2(rawAmp * 8.7f);
}
- return encodedAmp * 2;
+ return (int) Math.Round(encodedAmp * 2);
}
public bool HdRumble(VibrationValue left, VibrationValue right)
{
- WriteHdRumble(EncodeLowFreq(left.FrequencyLow),
+ return WriteHdRumble(EncodeLowFreq(left.FrequencyLow),
EncodeLowAmp(left.AmplitudeLow),
EncodeHighFreq(left.FrequencyHigh),
EncodeHighAmp(left.AmplitudeHigh),
@@ -140,7 +151,34 @@ namespace Ryujinx.Input.SDL3
EncodeLowAmp(right.AmplitudeLow),
EncodeHighFreq(right.FrequencyHigh),
EncodeHighAmp(right.AmplitudeHigh));
- return true;
+ }
+
+ private int SendHDRumble(byte* data, nuint length)
+ {
+ int result = 0;
+ ulong currentTicks = SDL_GetTicks();
+
+ // Ditch rumble if we haven't hit the poll-rate yet.
+ // TODO: figure out a better way to do this
+ // While the polling check makes the rumble accurate, it also causes it to miss signals.
+ if ((currentTicks - _lastWriteTicks) < 8) // https://docs.handheldlegend.com/s/progcc-3/doc/lag-comparison-aAR1mV3JLX
+ {
+ return result;
+ }
+
+ SDL_LockJoysticks();
+ {
+ // Fun fact: Mario Kart 8 Deluxe sends rumble packets
+ // where the amplitude is zero, but the frequency isn't.
+ result = SDL_hid_write(_hidHandle, data, length);
+ if (result >= 0)
+ {
+ _lastWriteTicks = currentTicks;
+ }
+ }
+ SDL_UnlockJoysticks();
+
+ return result;
}
public void Dispose()
@@ -148,4 +186,18 @@ namespace Ryujinx.Input.SDL3
SDL_hid_close(_hidHandle);
}
}
+
+ public enum HDRumbleSupported : ushort
+ {
+ JoyConLeft = 0x2006,
+ JoyConRight = 0x2007,
+ JoyconPair = 0x2008,
+ ProController = 0x2009,
+ JoyconGrip = 0x200e,
+ Joycon2Right = 0x2066,
+ Joycon2Left = 0x2067,
+ Joycon2Pair = 0x2068,
+ Switch2ProController = 0x2069,
+ GamecubeController = 0x2073
+ }
}
diff --git a/src/Ryujinx.Input.SDL3/SDL3Gamepad.cs b/src/Ryujinx.Input.SDL3/SDL3Gamepad.cs
index e4c8ca44d..490d2a1c0 100644
--- a/src/Ryujinx.Input.SDL3/SDL3Gamepad.cs
+++ b/src/Ryujinx.Input.SDL3/SDL3Gamepad.cs
@@ -177,10 +177,12 @@ namespace Ryujinx.Input.SDL3
return _hdRumble?.HdRumble(left, right) ?? false;
}
- public void Rumble(float lowFrequency, float highFrequency, uint durationMs)
+ public bool Rumble(float lowFrequency, float highFrequency, uint durationMs)
{
if ((Features & GamepadFeaturesFlag.Rumble) == 0)
- return;
+ {
+ return false;
+ }
ushort lowFrequencyRaw = (ushort)(lowFrequency * ushort.MaxValue);
ushort highFrequencyRaw = (ushort)(highFrequency * ushort.MaxValue);
@@ -199,6 +201,15 @@ namespace Ryujinx.Input.SDL3
if (!SDL_RumbleGamepad(_gamepadHandle, lowFrequencyRaw, highFrequencyRaw, durationMs))
Logger.Error?.Print(LogClass.Hid, "Rumble is not supported on this game controller.");
}
+
+ if (!String.IsNullOrEmpty(SDL_GetError()))
+ {
+ Logger.Error?.PrintMsg(LogClass.Hid, SDL_GetError());
+ SDL_ClearError();
+ return false;
+ }
+
+ return true;
}
public Vector3 GetMotionData(MotionInputId inputId)
diff --git a/src/Ryujinx.Input.SDL3/SDL3JoyCon.cs b/src/Ryujinx.Input.SDL3/SDL3JoyCon.cs
index 5e40de5e0..cb71a038f 100644
--- a/src/Ryujinx.Input.SDL3/SDL3JoyCon.cs
+++ b/src/Ryujinx.Input.SDL3/SDL3JoyCon.cs
@@ -163,7 +163,7 @@ namespace Ryujinx.Input.SDL3
public void SetTriggerThreshold(float triggerThreshold)
{
-
+ // No operations
}
public bool HDRumble(VibrationValue left, VibrationValue right)
@@ -171,10 +171,12 @@ namespace Ryujinx.Input.SDL3
return _hdRumble?.HdRumble(left, right) ?? false;
}
- public void Rumble(float lowFrequency, float highFrequency, uint durationMs)
+ public bool Rumble(float lowFrequency, float highFrequency, uint durationMs)
{
if ((Features & GamepadFeaturesFlag.Rumble) == 0)
- return;
+ {
+ return false;
+ }
ushort lowFrequencyRaw = (ushort)(lowFrequency * ushort.MaxValue);
ushort highFrequencyRaw = (ushort)(highFrequency * ushort.MaxValue);
@@ -193,6 +195,15 @@ namespace Ryujinx.Input.SDL3
if (!SDL_RumbleGamepad(_gamepadHandle, lowFrequencyRaw, highFrequencyRaw, durationMs))
Logger.Error?.Print(LogClass.Hid, "Rumble is not supported on this game controller.");
}
+
+ if (!String.IsNullOrEmpty(SDL_GetError()))
+ {
+ Logger.Error?.PrintMsg(LogClass.Hid, SDL_GetError());
+ SDL_ClearError();
+ return false;
+ }
+
+ return true;
}
public Vector3 GetMotionData(MotionInputId inputId)
diff --git a/src/Ryujinx.Input.SDL3/SDL3JoyConPair.cs b/src/Ryujinx.Input.SDL3/SDL3JoyConPair.cs
index e176cea1d..016254e0d 100644
--- a/src/Ryujinx.Input.SDL3/SDL3JoyConPair.cs
+++ b/src/Ryujinx.Input.SDL3/SDL3JoyConPair.cs
@@ -1,4 +1,7 @@
-using Ryujinx.Common.Configuration.Hid;
+using Gommon;
+using Ryujinx.Common.Configuration.Hid;
+using Ryujinx.Common.Logging;
+using Ryujinx.HLE.HOS.Services.Hid;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
@@ -61,7 +64,14 @@ namespace Ryujinx.Input.SDL3
return left.IsPressed(inputId) || right.IsPressed(inputId);
}
- public void Rumble(float lowFrequency, float highFrequency, uint durationMs)
+ public bool HDRumble(VibrationValue left, VibrationValue right)
+ {
+ // return _hdRumble?.HdRumble(left, right) ?? false;
+ // TODO: Track rumble and motion on both controllers
+ return false;
+ }
+
+ public bool Rumble(float lowFrequency, float highFrequency, uint durationMs)
{
if (lowFrequency != 0)
{
@@ -78,6 +88,15 @@ namespace Ryujinx.Input.SDL3
left.Rumble(0, 0, durationMs);
right.Rumble(0, 0, durationMs);
}
+
+ if (!SDL_GetError().IsNullOrEmpty())
+ {
+ Logger.Error?.PrintMsg(LogClass.Hid, SDL_GetError());
+ SDL_ClearError();
+ return false;
+ }
+
+ return true;
}
public void SetConfiguration(InputConfig configuration)
diff --git a/src/Ryujinx.Input.SDL3/SDL3Keyboard.cs b/src/Ryujinx.Input.SDL3/SDL3Keyboard.cs
index 3c4d1c0b2..c04f60e9e 100644
--- a/src/Ryujinx.Input.SDL3/SDL3Keyboard.cs
+++ b/src/Ryujinx.Input.SDL3/SDL3Keyboard.cs
@@ -1,6 +1,7 @@
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Keyboard;
using SDL;
+using Ryujinx.HLE.HOS.Services.Hid;
using System;
using System.Collections.Generic;
using System.Numerics;
@@ -385,9 +386,14 @@ namespace Ryujinx.Input.SDL3
// No operations
}
- public void Rumble(float lowFrequency, float highFrequency, uint durationMs)
+ public bool HDRumble(VibrationValue left, VibrationValue right)
{
- // No operations
+ return false;
+ }
+
+ public bool Rumble(float lowFrequency, float highFrequency, uint durationMs)
+ {
+ return false;
}
public Vector3 GetMotionData(MotionInputId inputId)
diff --git a/src/Ryujinx.Input.SDL3/SDL3Mouse.cs b/src/Ryujinx.Input.SDL3/SDL3Mouse.cs
index 95933bc9a..f296d7c84 100644
--- a/src/Ryujinx.Input.SDL3/SDL3Mouse.cs
+++ b/src/Ryujinx.Input.SDL3/SDL3Mouse.cs
@@ -1,4 +1,5 @@
using Ryujinx.Common.Configuration.Hid;
+using Ryujinx.HLE.HOS.Services.Hid;
using System;
using System.Drawing;
using System.Numerics;
@@ -66,7 +67,12 @@ namespace Ryujinx.Input.SDL3
throw new NotImplementedException();
}
- public void Rumble(float lowFrequency, float highFrequency, uint durationMs)
+ public bool HDRumble(VibrationValue left, VibrationValue right)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool Rumble(float lowFrequency, float highFrequency, uint durationMs)
{
throw new NotImplementedException();
}
diff --git a/src/Ryujinx.Input/HLE/NpadController.cs b/src/Ryujinx.Input/HLE/NpadController.cs
index 87cff4334..fccf2cb50 100644
--- a/src/Ryujinx.Input/HLE/NpadController.cs
+++ b/src/Ryujinx.Input/HLE/NpadController.cs
@@ -554,34 +554,37 @@ namespace Ryujinx.Input.HLE
{
if (queue.TryDequeue(out (VibrationValue, VibrationValue) dualVibrationValue))
{
- if (_config is StandardControllerInputConfig controllerConfig && controllerConfig.Rumble.EnableRumble)
+ if (_config is not StandardControllerInputConfig controllerConfig ||
+ !controllerConfig.Rumble.EnableRumble)
{
- VibrationValue leftVibrationValue = dualVibrationValue.Item1;
- VibrationValue rightVibrationValue = dualVibrationValue.Item2;
-
- float low = Math.Min(1f, (float)((rightVibrationValue.AmplitudeLow * 0.85 + rightVibrationValue.AmplitudeHigh * 0.15) * controllerConfig.Rumble.StrongRumble));
- float high = Math.Min(1f, (float)((leftVibrationValue.AmplitudeLow * 0.15 + leftVibrationValue.AmplitudeHigh * 0.85) * controllerConfig.Rumble.WeakRumble));
-
- leftVibrationValue.AmplitudeLow *= controllerConfig.Rumble.WeakRumble;
- leftVibrationValue.AmplitudeHigh *= controllerConfig.Rumble.StrongRumble;
- rightVibrationValue.AmplitudeLow *= controllerConfig.Rumble.WeakRumble;
- rightVibrationValue.AmplitudeHigh *= controllerConfig.Rumble.StrongRumble;
-
- if (_gamepad?.HDRumble(leftVibrationValue, rightVibrationValue) == false)
- {
- _gamepad.Rumble(low, high, uint.MaxValue);
- }
-
- Logger.Debug?.Print(LogClass.Hid, $"Effect for {controllerConfig.PlayerIndex} " +
- $"L.low.amp={leftVibrationValue.AmplitudeLow}, " +
- $"L.high.amp={leftVibrationValue.AmplitudeHigh}, " +
- $"L.low.freq={leftVibrationValue.FrequencyLow}, " +
- $"L.high.freq={leftVibrationValue.FrequencyHigh}, " +
- $"R.low.amp={rightVibrationValue.AmplitudeLow}, " +
- $"R.high.amp={rightVibrationValue.AmplitudeHigh} " +
- $"R.low.freq={rightVibrationValue.FrequencyLow}, " +
- $"R.high.freq={rightVibrationValue.FrequencyHigh}");
+ return;
}
+
+ VibrationValue leftVibrationValue = dualVibrationValue.Item1;
+ VibrationValue rightVibrationValue = dualVibrationValue.Item2;
+
+ leftVibrationValue.AmplitudeLow *= controllerConfig.Rumble.WeakRumble;
+ leftVibrationValue.AmplitudeHigh *= controllerConfig.Rumble.StrongRumble;
+ rightVibrationValue.AmplitudeLow *= controllerConfig.Rumble.WeakRumble;
+ rightVibrationValue.AmplitudeHigh *= controllerConfig.Rumble.StrongRumble;
+
+ if (!controllerConfig.Rumble.UseHDRumble || _gamepad?.HDRumble(leftVibrationValue, rightVibrationValue) == false)
+ {
+ float low = Math.Min(1f, (float)((rightVibrationValue.AmplitudeLow * 0.85 + rightVibrationValue.AmplitudeHigh * 0.15)));
+ float high = Math.Min(1f, (float)((leftVibrationValue.AmplitudeLow * 0.15 + leftVibrationValue.AmplitudeHigh * 0.85)));
+ _gamepad.Rumble(low, high, 0xFFFFFFFF);
+ }
+
+ Logger.Debug?.Print(LogClass.Hid, $"Effect for {controllerConfig.PlayerIndex} " +
+ // Value=value/multiplier * multiplier (result)
+ $"L.low.amp={leftVibrationValue.AmplitudeLow / controllerConfig.Rumble.WeakRumble} * {controllerConfig.Rumble.WeakRumble} ({leftVibrationValue.AmplitudeLow}), " +
+ $"L.high.amp={leftVibrationValue.AmplitudeHigh / controllerConfig.Rumble.WeakRumble} * {controllerConfig.Rumble.WeakRumble} ({leftVibrationValue.AmplitudeHigh}), " +
+ $"L.low.freq={leftVibrationValue.FrequencyLow / controllerConfig.Rumble.WeakRumble} * {controllerConfig.Rumble.WeakRumble} ({leftVibrationValue.FrequencyLow}), " +
+ $"L.high.freq={leftVibrationValue.FrequencyHigh / controllerConfig.Rumble.WeakRumble} * {controllerConfig.Rumble.WeakRumble} ({leftVibrationValue.FrequencyHigh}), " +
+ $"R.low.amp={rightVibrationValue.AmplitudeLow / controllerConfig.Rumble.StrongRumble} * {controllerConfig.Rumble.StrongRumble} ({rightVibrationValue.AmplitudeLow}), " +
+ $"R.high.amp={rightVibrationValue.AmplitudeHigh / controllerConfig.Rumble.StrongRumble} * {controllerConfig.Rumble.StrongRumble} ({rightVibrationValue.AmplitudeHigh}), " +
+ $"R.low.freq={rightVibrationValue.FrequencyLow / controllerConfig.Rumble.StrongRumble} * {controllerConfig.Rumble.StrongRumble} ({rightVibrationValue.FrequencyLow}), " +
+ $"R.high.freq={rightVibrationValue.FrequencyHigh / controllerConfig.Rumble.StrongRumble} * {controllerConfig.Rumble.StrongRumble} ({rightVibrationValue.FrequencyHigh})");
}
}
}
diff --git a/src/Ryujinx.Input/IGamepad.cs b/src/Ryujinx.Input/IGamepad.cs
index a59b72375..ee0c5ac33 100644
--- a/src/Ryujinx.Input/IGamepad.cs
+++ b/src/Ryujinx.Input/IGamepad.cs
@@ -71,10 +71,7 @@ namespace Ryujinx.Input
///
/// The vibration data for the left side
/// The vibration data for the right side
- bool HDRumble(VibrationValue left, VibrationValue right)
- {
- return false;
- }
+ bool HDRumble(VibrationValue left, VibrationValue right);
///
/// Starts a rumble effect on the gamepad.
@@ -82,10 +79,10 @@ namespace Ryujinx.Input
/// The intensity of the low frequency from 0.0f to 1.0f
/// The intensity of the high frequency from 0.0f to 1.0f
/// The duration of the rumble effect in milliseconds.
- void Rumble(float lowFrequency, float highFrequency, uint durationMs);
+ bool Rumble(float lowFrequency, float highFrequency, uint durationMs);
///
- /// Get a snaphost of the state of the gamepad that is remapped with the informations from the set via .
+ /// Get a snaphost of the state of the gamepad that is remapped with the information from the set via .
///
/// A remapped snaphost of the state of the gamepad.
GamepadStateSnapshot GetMappedStateSnapshot();
diff --git a/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs b/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs
index 16da0ea3d..22b3f7736 100644
--- a/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs
+++ b/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs
@@ -1323,6 +1323,7 @@ namespace Ryujinx.UI.Common.Configuration
EnableRumble = false,
StrongRumble = 1f,
WeakRumble = 1f,
+ UseHDRumble = true
};
}
}
diff --git a/src/Ryujinx/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json
index 56ad0c840..41f2fddeb 100644
--- a/src/Ryujinx/Assets/Locales/en_US.json
+++ b/src/Ryujinx/Assets/Locales/en_US.json
@@ -455,6 +455,8 @@
"ControllerSettingsRumble": "Rumble",
"ControllerSettingsRumbleStrongMultiplier": "Strong Rumble Multiplier",
"ControllerSettingsRumbleWeakMultiplier": "Weak Rumble Multiplier",
+ "ControllerSettingsRumbleUseHDRumble": "Enable HD Rumble",
+ "HDRumbleTooltip": "EXPERIMENTAL.\n\nSends more data to the controller for better rumble.\n\nCurrently only supports first-party Nintendo Switch controllers.\n\nLeave OFF if unsure.",
"DialogMessageSaveNotAvailableMessage": "There is no savedata for {0} [{1:x16}]",
"DialogMessageSaveNotAvailableCreateSaveMessage": "Would you like to create savedata for this game?",
"DialogConfirmationTitle": "Ryujinx - Confirmation",
diff --git a/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs b/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs
index d8461fdae..79d25e8d9 100644
--- a/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs
+++ b/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs
@@ -222,6 +222,7 @@ namespace Ryujinx.Headless
StrongRumble = 1f,
WeakRumble = 1f,
EnableRumble = false,
+ UseHDRumble = true
},
};
}
diff --git a/src/Ryujinx/Input/AvaloniaKeyboard.cs b/src/Ryujinx/Input/AvaloniaKeyboard.cs
index f13577adf..f4c9e88bf 100644
--- a/src/Ryujinx/Input/AvaloniaKeyboard.cs
+++ b/src/Ryujinx/Input/AvaloniaKeyboard.cs
@@ -1,5 +1,6 @@
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Keyboard;
+using Ryujinx.HLE.HOS.Services.Hid;
using Ryujinx.Input;
using System;
using System.Collections.Generic;
@@ -149,9 +150,20 @@ namespace Ryujinx.Ava.Input
}
}
- public void SetTriggerThreshold(float triggerThreshold) { }
+ public void SetTriggerThreshold(float triggerThreshold)
+ {
+ // No operations
+ }
- public void Rumble(float lowFrequency, float highFrequency, uint durationMs) { }
+ public bool HDRumble(VibrationValue left, VibrationValue right)
+ {
+ return false;
+ }
+
+ public bool Rumble(float lowFrequency, float highFrequency, uint durationMs)
+ {
+ return false;
+ }
public Vector3 GetMotionData(MotionInputId inputId) => Vector3.Zero;
diff --git a/src/Ryujinx/Input/AvaloniaMouse.cs b/src/Ryujinx/Input/AvaloniaMouse.cs
index 1aa2d586a..3f19078f6 100644
--- a/src/Ryujinx/Input/AvaloniaMouse.cs
+++ b/src/Ryujinx/Input/AvaloniaMouse.cs
@@ -1,4 +1,5 @@
using Ryujinx.Common.Configuration.Hid;
+using Ryujinx.HLE.HOS.Services.Hid;
using Ryujinx.Input;
using System;
using System.Drawing;
@@ -63,8 +64,13 @@ namespace Ryujinx.Ava.Input
{
throw new NotImplementedException();
}
+
+ public bool HDRumble(VibrationValue left, VibrationValue right)
+ {
+ throw new NotImplementedException();
+ }
- public void Rumble(float lowFrequency, float highFrequency, uint durationMs)
+ public bool Rumble(float lowFrequency, float highFrequency, uint durationMs)
{
throw new NotImplementedException();
}
diff --git a/src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs b/src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs
index 3571f56e9..468d569db 100644
--- a/src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs
+++ b/src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs
@@ -19,6 +19,7 @@ namespace Ryujinx.Ava.UI.Models.Input
public float WeakRumble { get; set; }
public float StrongRumble { get; set; }
+ public bool UseHDRumble { get; set; }
public string Id { get; set; }
public ControllerType ControllerType { get; set; }
@@ -482,6 +483,7 @@ namespace Ryujinx.Ava.UI.Models.Input
EnableRumble = controllerInput.Rumble.EnableRumble;
WeakRumble = controllerInput.Rumble.WeakRumble;
StrongRumble = controllerInput.Rumble.StrongRumble;
+ UseHDRumble = controllerInput.Rumble.UseHDRumble;
}
}
}
@@ -539,6 +541,7 @@ namespace Ryujinx.Ava.UI.Models.Input
EnableRumble = EnableRumble,
WeakRumble = WeakRumble,
StrongRumble = StrongRumble,
+ UseHDRumble = UseHDRumble,
},
Version = InputConfig.CurrentVersion,
DeadzoneLeft = DeadzoneLeft,
diff --git a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs
index 9c300dfd9..d68b8cf4b 100644
--- a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs
@@ -685,6 +685,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
StrongRumble = 1f,
WeakRumble = 1f,
EnableRumble = false,
+ UseHDRumble = true
},
};
}
diff --git a/src/Ryujinx/UI/ViewModels/Input/RumbleInputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/RumbleInputViewModel.cs
index 8ad33cf4c..7d55cc87a 100644
--- a/src/Ryujinx/UI/ViewModels/Input/RumbleInputViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/Input/RumbleInputViewModel.cs
@@ -23,5 +23,16 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
OnPropertyChanged();
}
}
+
+ private bool _enableHDRumble;
+ public bool EnableHDRumble
+ {
+ get => _enableHDRumble;
+ set
+ {
+ _enableHDRumble = value;
+ OnPropertyChanged();
+ }
+ }
}
}
diff --git a/src/Ryujinx/UI/Views/Input/RumbleInputView.axaml b/src/Ryujinx/UI/Views/Input/RumbleInputView.axaml
index 52b656e72..a12de70a4 100644
--- a/src/Ryujinx/UI/Views/Input/RumbleInputView.axaml
+++ b/src/Ryujinx/UI/Views/Input/RumbleInputView.axaml
@@ -55,6 +55,15 @@
Margin="5,0"
Text="{Binding WeakRumble, StringFormat=\{0:0.00\}}" />
+
+
+
diff --git a/src/Ryujinx/UI/Views/Input/RumbleInputView.axaml.cs b/src/Ryujinx/UI/Views/Input/RumbleInputView.axaml.cs
index 6a19d8f10..b6ffe3218 100644
--- a/src/Ryujinx/UI/Views/Input/RumbleInputView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Input/RumbleInputView.axaml.cs
@@ -24,6 +24,7 @@ namespace Ryujinx.Ava.UI.Views.Input
{
StrongRumble = config.StrongRumble,
WeakRumble = config.WeakRumble,
+ EnableHDRumble = config.UseHDRumble
};
InitializeComponent();
@@ -49,6 +50,7 @@ namespace Ryujinx.Ava.UI.Views.Input
GamepadInputConfig config = viewModel.Config;
config.StrongRumble = content._viewModel.StrongRumble;
config.WeakRumble = content._viewModel.WeakRumble;
+ config.UseHDRumble = content._viewModel.EnableHDRumble;
};
await contentDialog.ShowAsync();