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 + + 2 + 1.000000000000000003 + 0.01 + 0.10000000000000001 + + + 2 + 1.000000000000000003 + 0.01 + 0.10000000000000001 + 1 0.5 @@ -775,6 +787,46 @@ 4 + + + True + False + 10 + vertical + + + True + False + start + Range Left + + + False + True + 0 + + + + + True + True + _controllerRangeLeft + 2 + 2 + + + True + True + 1 + + + + + False + True + 5 + + 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