From 686757105c83a1485117ff5f5d30b2fad4df39b1 Mon Sep 17 00:00:00 2001
From: MutantAura <44103205+MutantAura@users.noreply.github.com>
Date: Mon, 3 Jan 2022 11:49:29 +0000
Subject: [PATCH] Implement analog stick range modifier (#2783)
* adjust position vector + GUI
* remove brackets
* Update configuration
* Update ConfigurationFileFormat.cs
* rebase + review changes
* spacing
* revert deletion
* fix profile loading
* spacing
* comment spacing
---
.../GenericControllerInputConfig.cs | 10 ++
Ryujinx.Headless.SDL2/Program.cs | 14 +++
Ryujinx.Input/HLE/NpadController.cs | 8 +-
.../Configuration/ConfigurationFileFormat.cs | 2 +-
Ryujinx/Configuration/ConfigurationState.cs | 16 ++++
Ryujinx/Ui/Windows/ControllerWindow.cs | 23 +++++
Ryujinx/Ui/Windows/ControllerWindow.glade | 92 +++++++++++++++++++
7 files changed, 160 insertions(+), 5 deletions(-)
diff --git a/Ryujinx.Common/Configuration/Hid/Controller/GenericControllerInputConfig.cs b/Ryujinx.Common/Configuration/Hid/Controller/GenericControllerInputConfig.cs
index 6c4562cfb2..aeb09c5860 100644
--- a/Ryujinx.Common/Configuration/Hid/Controller/GenericControllerInputConfig.cs
+++ b/Ryujinx.Common/Configuration/Hid/Controller/GenericControllerInputConfig.cs
@@ -24,6 +24,16 @@ namespace Ryujinx.Common.Configuration.Hid.Controller
///
public float DeadzoneRight { get; set; }
+ ///
+ /// Controller Left Analog Stick Range
+ ///
+ public float RangeLeft { get; set; }
+
+ ///
+ /// Controller Right Analog Stick Range
+ ///
+ public float RangeRight { get; set; }
+
///
/// Controller Trigger Threshold
///
diff --git a/Ryujinx.Headless.SDL2/Program.cs b/Ryujinx.Headless.SDL2/Program.cs
index 2b169478e0..6e2172e379 100644
--- a/Ryujinx.Headless.SDL2/Program.cs
+++ b/Ryujinx.Headless.SDL2/Program.cs
@@ -196,6 +196,8 @@ namespace Ryujinx.Headless.SDL2
ControllerType = ControllerType.JoyconPair,
DeadzoneLeft = 0.1f,
DeadzoneRight = 0.1f,
+ RangeLeft = 1.0f,
+ RangeRight = 1.0f,
TriggerThreshold = 0.5f,
LeftJoycon = new LeftJoyconCommonConfig
{
@@ -299,6 +301,18 @@ namespace Ryujinx.Headless.SDL2
Logger.Info?.Print(LogClass.Application, $"{config.PlayerIndex} configured with {inputTypeName} \"{config.Id}\"");
+ // If both stick ranges are 0 (usually indicative of an outdated profile load) then both sticks will be set to 1.0.
+ if (config is StandardControllerInputConfig controllerConfig)
+ {
+ if (controllerConfig.RangeLeft <= 0.0f && controllerConfig.RangeRight <= 0.0f)
+ {
+ controllerConfig.RangeLeft = 1.0f;
+ controllerConfig.RangeRight = 1.0f;
+
+ Logger.Info?.Print(LogClass.Application, $"{config.PlayerIndex} stick range reset. Save the profile now to update your configuration");
+ }
+ }
+
return config;
}
diff --git a/Ryujinx.Input/HLE/NpadController.cs b/Ryujinx.Input/HLE/NpadController.cs
index 79c18ecf7f..2af114d21e 100644
--- a/Ryujinx.Input/HLE/NpadController.cs
+++ b/Ryujinx.Input/HLE/NpadController.cs
@@ -381,8 +381,8 @@ namespace Ryujinx.Input.HLE
(float leftAxisX, float leftAxisY) = State.GetStick(StickInputId.Left);
(float rightAxisX, float rightAxisY) = State.GetStick(StickInputId.Right);
- state.LStick = ClampToCircle(ApplyDeadzone(leftAxisX, leftAxisY, controllerConfig.DeadzoneLeft));
- state.RStick = ClampToCircle(ApplyDeadzone(rightAxisX, rightAxisY, controllerConfig.DeadzoneRight));
+ state.LStick = ClampToCircle(ApplyDeadzone(leftAxisX, leftAxisY, controllerConfig.DeadzoneLeft), controllerConfig.RangeLeft);
+ state.RStick = ClampToCircle(ApplyDeadzone(rightAxisX, rightAxisY, controllerConfig.DeadzoneRight), controllerConfig.RangeRight);
}
return state;
@@ -412,9 +412,9 @@ namespace Ryujinx.Input.HLE
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static JoystickPosition ClampToCircle(JoystickPosition position)
+ private static JoystickPosition ClampToCircle(JoystickPosition position, float range)
{
- Vector2 point = new Vector2(position.Dx, position.Dy);
+ Vector2 point = new Vector2(position.Dx, position.Dy) * range;
if (point.Length() > short.MaxValue)
{
diff --git a/Ryujinx/Configuration/ConfigurationFileFormat.cs b/Ryujinx/Configuration/ConfigurationFileFormat.cs
index b06e04e0dd..9eb11a9e7a 100644
--- a/Ryujinx/Configuration/ConfigurationFileFormat.cs
+++ b/Ryujinx/Configuration/ConfigurationFileFormat.cs
@@ -14,7 +14,7 @@ namespace Ryujinx.Configuration
///
/// The current version of the file format
///
- public const int CurrentVersion = 34;
+ public const int CurrentVersion = 35;
///
/// Version of the configuration file format
diff --git a/Ryujinx/Configuration/ConfigurationState.cs b/Ryujinx/Configuration/ConfigurationState.cs
index 90fb3f6f58..fdc28201e9 100644
--- a/Ryujinx/Configuration/ConfigurationState.cs
+++ b/Ryujinx/Configuration/ConfigurationState.cs
@@ -975,6 +975,22 @@ namespace Ryujinx.Configuration
configurationFileUpdated = true;
}
+ if (configurationFileFormat.Version < 35)
+ {
+ Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 35.");
+
+ foreach (InputConfig config in configurationFileFormat.InputConfig)
+ {
+ if (config is StandardControllerInputConfig controllerConfig)
+ {
+ controllerConfig.RangeLeft = 1.0f;
+ controllerConfig.RangeRight = 1.0f;
+ }
+ }
+
+ configurationFileUpdated = true;
+ }
+
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
Graphics.BackendThreading.Value = configurationFileFormat.BackendThreading;
Graphics.ResScale.Value = configurationFileFormat.ResScale;
diff --git a/Ryujinx/Ui/Windows/ControllerWindow.cs b/Ryujinx/Ui/Windows/ControllerWindow.cs
index 4b7ca36304..36a233269d 100644
--- a/Ryujinx/Ui/Windows/ControllerWindow.cs
+++ b/Ryujinx/Ui/Windows/ControllerWindow.cs
@@ -38,6 +38,8 @@ namespace Ryujinx.Ui.Windows
[GUI] Adjustment _controllerWeakRumble;
[GUI] Adjustment _controllerDeadzoneLeft;
[GUI] Adjustment _controllerDeadzoneRight;
+ [GUI] Adjustment _controllerRangeLeft;
+ [GUI] Adjustment _controllerRangeRight;
[GUI] Adjustment _controllerTriggerThreshold;
[GUI] Adjustment _slotNumber;
[GUI] Adjustment _altSlotNumber;
@@ -59,9 +61,11 @@ namespace Ryujinx.Ui.Windows
[GUI] Grid _leftStickKeyboard;
[GUI] Grid _leftStickController;
[GUI] Box _deadZoneLeftBox;
+ [GUI] Box _rangeLeftBox;
[GUI] Grid _rightStickKeyboard;
[GUI] Grid _rightStickController;
[GUI] Box _deadZoneRightBox;
+ [GUI] Box _rangeRightBox;
[GUI] Grid _leftSideTriggerBox;
[GUI] Grid _rightSideTriggerBox;
[GUI] Box _triggerThresholdBox;
@@ -316,6 +320,8 @@ namespace Ryujinx.Ui.Windows
_rightStickController.Hide();
_deadZoneLeftBox.Hide();
_deadZoneRightBox.Hide();
+ _rangeLeftBox.Hide();
+ _rangeRightBox.Hide();
_triggerThresholdBox.Hide();
_motionBox.Hide();
_rumbleBox.Hide();
@@ -416,6 +422,8 @@ namespace Ryujinx.Ui.Windows
_controllerWeakRumble.Value = 1;
_controllerDeadzoneLeft.Value = 0;
_controllerDeadzoneRight.Value = 0;
+ _controllerRangeLeft.Value = 1;
+ _controllerRangeRight.Value = 1;
_controllerTriggerThreshold.Value = 0;
_mirrorInput.Active = false;
_enableMotion.Active = false;
@@ -510,12 +518,23 @@ namespace Ryujinx.Ui.Windows
_enableRumble.Active = controllerConfig.Rumble.EnableRumble;
_controllerDeadzoneLeft.Value = controllerConfig.DeadzoneLeft;
_controllerDeadzoneRight.Value = controllerConfig.DeadzoneRight;
+ _controllerRangeLeft.Value = controllerConfig.RangeLeft;
+ _controllerRangeRight.Value = controllerConfig.RangeRight;
_controllerTriggerThreshold.Value = controllerConfig.TriggerThreshold;
_sensitivity.Value = controllerConfig.Motion.Sensitivity;
_gyroDeadzone.Value = controllerConfig.Motion.GyroDeadzone;
_enableMotion.Active = controllerConfig.Motion.EnableMotion;
_enableCemuHook.Active = controllerConfig.Motion.MotionBackend == MotionInputBackendType.CemuHook;
+ // If both stick ranges are 0 (usually indicative of an outdated profile load) then both sticks will be set to 1.0.
+ if (_controllerRangeLeft.Value <= 0.0 && _controllerRangeRight.Value <= 0.0)
+ {
+ _controllerRangeLeft.Value = 1.0;
+ _controllerRangeRight.Value = 1.0;
+
+ Logger.Info?.Print(LogClass.Application, $"{config.PlayerIndex} stick range reset. Save the profile now to update your configuration");
+ }
+
if (controllerConfig.Motion is CemuHookMotionConfigController cemuHookMotionConfig)
{
_slotNumber.Value = cemuHookMotionConfig.Slot;
@@ -678,6 +697,8 @@ namespace Ryujinx.Ui.Windows
PlayerIndex = _playerIndex,
DeadzoneLeft = (float)_controllerDeadzoneLeft.Value,
DeadzoneRight = (float)_controllerDeadzoneRight.Value,
+ RangeLeft = (float)_controllerRangeLeft.Value,
+ RangeRight = (float)_controllerRangeRight.Value,
TriggerThreshold = (float)_controllerTriggerThreshold.Value,
LeftJoycon = new LeftJoyconCommonConfig
{
@@ -1013,6 +1034,8 @@ namespace Ryujinx.Ui.Windows
ControllerType = ControllerType.JoyconPair,
DeadzoneLeft = 0.1f,
DeadzoneRight = 0.1f,
+ RangeLeft = 1.0f,
+ RangeRight = 1.0f,
TriggerThreshold = 0.5f,
LeftJoycon = new LeftJoyconCommonConfig
{
diff --git a/Ryujinx/Ui/Windows/ControllerWindow.glade b/Ryujinx/Ui/Windows/ControllerWindow.glade
index a396df03cb..ff4c7149db 100644
--- a/Ryujinx/Ui/Windows/ControllerWindow.glade
+++ b/Ryujinx/Ui/Windows/ControllerWindow.glade
@@ -33,6 +33,18 @@
0.01
0.10000000000000001
+
+
False
@@ -1692,6 +1744,46 @@
4
+
+
+ True
+ False
+ 10
+ vertical
+
+
+ True
+ False
+ start
+ Range Right
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ _controllerRangeRight
+ 2
+ 2
+
+
+ True
+ True
+ 1
+
+
+
+
+ False
+ True
+ 5
+
+
False