From df8e0503acf00e7158abc9bab9b08d54a375a42d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20M=2E=20Gonz=C3=A1lez?= Date: Sat, 9 Nov 2024 19:32:18 -0300 Subject: [PATCH] Added (incomplete) motion controls emulation support. --- .../Motion/MotionConfigController.cs | 5 + .../Configuration/Hid/KeyboardHotkeys.cs | 3 + src/Ryujinx.Gtk3/Input/GTK3/GTK3Keyboard.cs | 4 +- src/Ryujinx.Gtk3/Input/GTK3/GTK3Mouse.cs | 4 +- src/Ryujinx.Headless.SDL2/SDL2Mouse.cs | 4 +- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 8 +- src/Ryujinx.Input.SDL2/SDL2Keyboard.cs | 4 +- .../Assigner/GamepadButtonAssigner.cs | 4 +- src/Ryujinx.Input/HLE/NpadController.cs | 133 ++++++++++++------ src/Ryujinx.Input/HLE/NpadManager.cs | 2 + src/Ryujinx.Input/IGamepad.cs | 22 +-- src/Ryujinx/AppHost.cs | 12 ++ src/Ryujinx/Assets/Locales/ar_SA.json | 1 + src/Ryujinx/Assets/Locales/de_DE.json | 1 + src/Ryujinx/Assets/Locales/el_GR.json | 1 + src/Ryujinx/Assets/Locales/en_US.json | 1 + src/Ryujinx/Assets/Locales/es_ES.json | 1 + src/Ryujinx/Assets/Locales/fr_FR.json | 1 + src/Ryujinx/Assets/Locales/he_IL.json | 1 + src/Ryujinx/Assets/Locales/it_IT.json | 1 + src/Ryujinx/Assets/Locales/ja_JP.json | 1 + src/Ryujinx/Assets/Locales/ko_KR.json | 1 + src/Ryujinx/Assets/Locales/pl_PL.json | 1 + src/Ryujinx/Assets/Locales/pt_BR.json | 1 + src/Ryujinx/Assets/Locales/ru_RU.json | 1 + src/Ryujinx/Assets/Locales/th_TH.json | 1 + src/Ryujinx/Assets/Locales/tr_TR.json | 1 + src/Ryujinx/Assets/Locales/uk_UA.json | 1 + src/Ryujinx/Assets/Locales/zh_CN.json | 1 + src/Ryujinx/Assets/Locales/zh_TW.json | 1 + src/Ryujinx/Common/KeyboardHotkeyState.cs | 1 + src/Ryujinx/Input/AvaloniaKeyboard.cs | 4 +- src/Ryujinx/Input/AvaloniaMouse.cs | 4 +- src/Ryujinx/UI/Models/Input/HotkeyConfig.cs | 13 ++ .../Views/Settings/SettingsHotkeysView.axaml | 8 +- .../Settings/SettingsHotkeysView.axaml.cs | 3 + 36 files changed, 186 insertions(+), 70 deletions(-) diff --git a/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigController.cs b/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigController.cs index 7905ef062..b3c07d949 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigController.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigController.cs @@ -21,5 +21,10 @@ public class MotionConfigController /// Enable Motion Controls /// public bool EnableMotion { get; set; } + + /// + /// Enable translating sticks to motion controls. + /// + public bool SticksToMotion { get; set; } } } diff --git a/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs b/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs index 0cb49ca8c..3f80c7d74 100644 --- a/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs +++ b/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs @@ -1,3 +1,5 @@ +using System.Collections.Generic; + namespace Ryujinx.Common.Configuration.Hid { public class KeyboardHotkeys @@ -11,5 +13,6 @@ public class KeyboardHotkeys public Key ResScaleDown { get; set; } public Key VolumeUp { get; set; } public Key VolumeDown { get; set; } + public Key ToggleMotionEmulation { get; set; } } } diff --git a/src/Ryujinx.Gtk3/Input/GTK3/GTK3Keyboard.cs b/src/Ryujinx.Gtk3/Input/GTK3/GTK3Keyboard.cs index ff7a2c3b6..e29598136 100644 --- a/src/Ryujinx.Gtk3/Input/GTK3/GTK3Keyboard.cs +++ b/src/Ryujinx.Gtk3/Input/GTK3/GTK3Keyboard.cs @@ -95,7 +95,7 @@ private static (short, short) GetStickValues(ref KeyboardStateSnapshot snapshot, return ((short)(stick.X * short.MaxValue), (short)(stick.Y * short.MaxValue)); } - public GamepadStateSnapshot GetMappedStateSnapshot() + public GamepadStateSnapshot GetMappedStateSnapshot(bool _) { KeyboardStateSnapshot rawState = GetKeyboardStateSnapshot(); GamepadStateSnapshot result = default; @@ -131,7 +131,7 @@ public GamepadStateSnapshot GetMappedStateSnapshot() return result; } - public GamepadStateSnapshot GetStateSnapshot() + public GamepadStateSnapshot GetStateSnapshot(bool _) { throw new NotSupportedException(); } diff --git a/src/Ryujinx.Gtk3/Input/GTK3/GTK3Mouse.cs b/src/Ryujinx.Gtk3/Input/GTK3/GTK3Mouse.cs index 0ab817ecb..7e41f0187 100644 --- a/src/Ryujinx.Gtk3/Input/GTK3/GTK3Mouse.cs +++ b/src/Ryujinx.Gtk3/Input/GTK3/GTK3Mouse.cs @@ -36,7 +36,7 @@ public Vector2 GetScroll() return _driver.Scroll; } - public GamepadStateSnapshot GetMappedStateSnapshot() + public GamepadStateSnapshot GetMappedStateSnapshot(bool _) { throw new NotImplementedException(); } @@ -46,7 +46,7 @@ public Vector3 GetMotionData(MotionInputId inputId) throw new NotImplementedException(); } - public GamepadStateSnapshot GetStateSnapshot() + public GamepadStateSnapshot GetStateSnapshot(bool _) { throw new NotImplementedException(); } diff --git a/src/Ryujinx.Headless.SDL2/SDL2Mouse.cs b/src/Ryujinx.Headless.SDL2/SDL2Mouse.cs index de64b4f8f..de87a827b 100644 --- a/src/Ryujinx.Headless.SDL2/SDL2Mouse.cs +++ b/src/Ryujinx.Headless.SDL2/SDL2Mouse.cs @@ -37,7 +37,7 @@ public Vector2 GetScroll() return _driver.Scroll; } - public GamepadStateSnapshot GetMappedStateSnapshot() + public GamepadStateSnapshot GetMappedStateSnapshot(bool _) { throw new NotImplementedException(); } @@ -47,7 +47,7 @@ public Vector3 GetMotionData(MotionInputId inputId) throw new NotImplementedException(); } - public GamepadStateSnapshot GetStateSnapshot() + public GamepadStateSnapshot GetStateSnapshot(bool _) { throw new NotImplementedException(); } diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index 187ca48dd..2e3829b45 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -265,14 +265,14 @@ public void SetConfiguration(InputConfig configuration) } } - public GamepadStateSnapshot GetStateSnapshot() + public GamepadStateSnapshot GetStateSnapshot(bool ignoreSticks) { - return IGamepad.GetStateSnapshot(this); + return IGamepad.GetStateSnapshot(this, ignoreSticks); } - public GamepadStateSnapshot GetMappedStateSnapshot() + public GamepadStateSnapshot GetMappedStateSnapshot(bool ignoreSticks) { - GamepadStateSnapshot rawState = GetStateSnapshot(); + GamepadStateSnapshot rawState = GetStateSnapshot(ignoreSticks); GamepadStateSnapshot result = default; lock (_userMappingLock) diff --git a/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs b/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs index bc0a7e660..c75f8ba1b 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs @@ -299,7 +299,7 @@ private static (short, short) GetStickValues(ref KeyboardStateSnapshot snapshot, return ((short)(stick.X * short.MaxValue), (short)(stick.Y * short.MaxValue)); } - public GamepadStateSnapshot GetMappedStateSnapshot() + public GamepadStateSnapshot GetMappedStateSnapshot(bool _) { KeyboardStateSnapshot rawState = GetKeyboardStateSnapshot(); GamepadStateSnapshot result = default; @@ -335,7 +335,7 @@ public GamepadStateSnapshot GetMappedStateSnapshot() return result; } - public GamepadStateSnapshot GetStateSnapshot() + public GamepadStateSnapshot GetStateSnapshot(bool _) { throw new NotSupportedException(); } diff --git a/src/Ryujinx.Input/Assigner/GamepadButtonAssigner.cs b/src/Ryujinx.Input/Assigner/GamepadButtonAssigner.cs index 80fed2b82..35b6efd1c 100644 --- a/src/Ryujinx.Input/Assigner/GamepadButtonAssigner.cs +++ b/src/Ryujinx.Input/Assigner/GamepadButtonAssigner.cs @@ -33,7 +33,7 @@ public void Initialize() { if (_gamepad != null) { - _currState = _gamepad.GetStateSnapshot(); + _currState = _gamepad.GetStateSnapshot(false); _prevState = _currState; } } @@ -43,7 +43,7 @@ public void ReadInput() if (_gamepad != null) { _prevState = _currState; - _currState = _gamepad.GetStateSnapshot(); + _currState = _gamepad.GetStateSnapshot(false); } CollectButtonStats(); diff --git a/src/Ryujinx.Input/HLE/NpadController.cs b/src/Ryujinx.Input/HLE/NpadController.cs index 380745283..429a48acc 100644 --- a/src/Ryujinx.Input/HLE/NpadController.cs +++ b/src/Ryujinx.Input/HLE/NpadController.cs @@ -208,6 +208,7 @@ public HLEKeyboardMappingEntry(Key targetKey, byte target) private IGamepad _gamepad; private InputConfig _config; + public StandardControllerInputConfig StandardControllerInputConfig => _config as StandardControllerInputConfig; public IGamepadDriver GamepadDriver { get; private set; } public GamepadStateSnapshot State { get; private set; } @@ -273,61 +274,109 @@ private void UpdateMotionInput(MotionConfigController motionConfig) } } - public void Update() + private static double Transform(double x) { - // _gamepad may be altered by other threads - var gamepad = _gamepad; + return (Math.Pow(30, Math.Abs(x)) - 1) / 20 * Math.Sign(x); + } - if (gamepad != null && GamepadDriver != null) + private void EmulateMotion(IGamepad gamepad, StandardControllerInputConfig config) + { + var (lx, ly) = gamepad.GetStick(StickInputId.Left); + var (rx, _) = gamepad.GetStick(StickInputId.Right); + + var gyroscope = new Vector3(-ly, lx, -rx) * 100; + var x = Transform(lx); + var y = Transform(ly); + var accelerometer = new Vector3((float)x, (float)y, -1); + + _leftMotionInput.Update(accelerometer, gyroscope, (ulong)PerformanceCounter.ElapsedNanoseconds / 1000, config.Motion.Sensitivity, (float)config.Motion.GyroDeadzone); + if (config.ControllerType == ConfigControllerType.JoyconPair) + _rightMotionInput = _leftMotionInput; + } + + private void ReadGamepadMotion(StandardControllerInputConfig controllerConfig, IGamepad gamepad) + { + if (gamepad.Features.HasFlag(GamepadFeaturesFlag.Motion)) { - State = gamepad.GetMappedStateSnapshot(); + Vector3 accelerometer = gamepad.GetMotionData(MotionInputId.Accelerometer); + Vector3 gyroscope = gamepad.GetMotionData(MotionInputId.Gyroscope); + + accelerometer = new Vector3(accelerometer.X, -accelerometer.Z, accelerometer.Y); + gyroscope = new Vector3(gyroscope.X, -gyroscope.Z, gyroscope.Y); + + _leftMotionInput.Update(accelerometer, gyroscope, + (ulong)PerformanceCounter.ElapsedNanoseconds / 1000, + controllerConfig.Motion.Sensitivity, (float)controllerConfig.Motion.GyroDeadzone); - if (_config is StandardControllerInputConfig controllerConfig && controllerConfig.Motion.EnableMotion) + if (controllerConfig.ControllerType == ConfigControllerType.JoyconPair) { - if (controllerConfig.Motion.MotionBackend == MotionInputBackendType.GamepadDriver) - { - if (gamepad.Features.HasFlag(GamepadFeaturesFlag.Motion)) - { - Vector3 accelerometer = gamepad.GetMotionData(MotionInputId.Accelerometer); - Vector3 gyroscope = gamepad.GetMotionData(MotionInputId.Gyroscope); + _rightMotionInput = _leftMotionInput; + } + } + } + + private void ReadCemuMotion(StandardControllerInputConfig controllerConfig) + { + if (controllerConfig.Motion is CemuHookMotionConfigController cemuControllerConfig) + { + int clientId = (int)controllerConfig.PlayerIndex; - accelerometer = new Vector3(accelerometer.X, -accelerometer.Z, accelerometer.Y); - gyroscope = new Vector3(gyroscope.X, -gyroscope.Z, gyroscope.Y); + // First of all ensure we are registered + _cemuHookClient.RegisterClient(clientId, cemuControllerConfig.DsuServerHost, + cemuControllerConfig.DsuServerPort); - _leftMotionInput.Update(accelerometer, gyroscope, (ulong)PerformanceCounter.ElapsedNanoseconds / 1000, controllerConfig.Motion.Sensitivity, (float)controllerConfig.Motion.GyroDeadzone); + // Then request and retrieve the data + _cemuHookClient.RequestData(clientId, cemuControllerConfig.Slot); + _cemuHookClient.TryGetData(clientId, cemuControllerConfig.Slot, out _leftMotionInput); - if (controllerConfig.ControllerType == ConfigControllerType.JoyconPair) - { - _rightMotionInput = _leftMotionInput; - } - } + if (controllerConfig.ControllerType == ConfigControllerType.JoyconPair) + { + if (!cemuControllerConfig.MirrorInput) + { + _cemuHookClient.RequestData(clientId, cemuControllerConfig.AltSlot); + _cemuHookClient.TryGetData(clientId, cemuControllerConfig.AltSlot, + out _rightMotionInput); } - else if (controllerConfig.Motion.MotionBackend == MotionInputBackendType.CemuHook && controllerConfig.Motion is CemuHookMotionConfigController cemuControllerConfig) + else { - int clientId = (int)controllerConfig.PlayerIndex; - - // First of all ensure we are registered - _cemuHookClient.RegisterClient(clientId, cemuControllerConfig.DsuServerHost, cemuControllerConfig.DsuServerPort); - - // Then request and retrieve the data - _cemuHookClient.RequestData(clientId, cemuControllerConfig.Slot); - _cemuHookClient.TryGetData(clientId, cemuControllerConfig.Slot, out _leftMotionInput); - - if (controllerConfig.ControllerType == ConfigControllerType.JoyconPair) - { - if (!cemuControllerConfig.MirrorInput) - { - _cemuHookClient.RequestData(clientId, cemuControllerConfig.AltSlot); - _cemuHookClient.TryGetData(clientId, cemuControllerConfig.AltSlot, out _rightMotionInput); - } - else - { - _rightMotionInput = _leftMotionInput; - } - } + _rightMotionInput = _leftMotionInput; } } } + } + + private void ReadMotion(IGamepad gamepad, StandardControllerInputConfig controllerConfig) + { + switch (controllerConfig.Motion.MotionBackend) + { + case MotionInputBackendType.GamepadDriver: + ReadGamepadMotion(controllerConfig, gamepad); + break; + case MotionInputBackendType.CemuHook: + ReadCemuMotion(controllerConfig); + break; + default: + break; + } + } + + public void Update() + { + // _gamepad may be altered by other threads + var gamepad = _gamepad; + + if (gamepad != null && GamepadDriver != null) + { + State = gamepad.GetMappedStateSnapshot(StandardControllerInputConfig?.Motion.SticksToMotion ?? false); + + if (_config is StandardControllerInputConfig controllerConfig) + { + if (controllerConfig.Motion.SticksToMotion) + EmulateMotion(gamepad, controllerConfig); + else if (controllerConfig.Motion.EnableMotion) + ReadMotion(gamepad, controllerConfig); + } + } else { // Reset states diff --git a/src/Ryujinx.Input/HLE/NpadManager.cs b/src/Ryujinx.Input/HLE/NpadManager.cs index 1dc87358d..45e62a451 100644 --- a/src/Ryujinx.Input/HLE/NpadManager.cs +++ b/src/Ryujinx.Input/HLE/NpadManager.cs @@ -50,6 +50,8 @@ public NpadManager(IGamepadDriver keyboardDriver, IGamepadDriver gamepadDriver, _gamepadDriver.OnGamepadDisconnected += HandleOnGamepadDisconnected; } + public IEnumerable Controllers => _controllers; + private void RefreshInputConfigForHLE() { lock (_lock) diff --git a/src/Ryujinx.Input/IGamepad.cs b/src/Ryujinx.Input/IGamepad.cs index 3853f2819..c484bd64d 100644 --- a/src/Ryujinx.Input/IGamepad.cs +++ b/src/Ryujinx.Input/IGamepad.cs @@ -77,35 +77,39 @@ public interface IGamepad : IDisposable /// Get a snaphost of the state of the gamepad that is remapped with the informations from the set via . /// /// A remapped snaphost of the state of the gamepad. - GamepadStateSnapshot GetMappedStateSnapshot(); + GamepadStateSnapshot GetMappedStateSnapshot(bool ignoreSticks); /// /// Get a snaphost of the state of the gamepad. /// /// A snaphost of the state of the gamepad. - GamepadStateSnapshot GetStateSnapshot(); + GamepadStateSnapshot GetStateSnapshot(bool ignoreSticks); /// /// Get a snaphost of the state of a gamepad. /// /// The gamepad to do a snapshot of + /// Forces the stick states to zero /// A snaphost of the state of the gamepad. [MethodImpl(MethodImplOptions.AggressiveInlining)] - static GamepadStateSnapshot GetStateSnapshot(IGamepad gamepad) + static GamepadStateSnapshot GetStateSnapshot(IGamepad gamepad, bool ignoreSticks) { // NOTE: Update Array size if JoystickInputId is changed. Array3> joysticksState = default; - for (StickInputId inputId = StickInputId.Left; inputId < StickInputId.Count; inputId++) + if (!ignoreSticks) { - (float state0, float state1) = gamepad.GetStick(inputId); + for (StickInputId inputId = StickInputId.Left; inputId < StickInputId.Count; inputId++) + { + (float state0, float state1) = gamepad.GetStick(inputId); - Array2 state = default; + Array2 state = default; - state[0] = state0; - state[1] = state1; + state[0] = state0; + state[1] = state1; - joysticksState[(int)inputId] = state; + joysticksState[(int)inputId] = state; + } } // NOTE: Update Array size if GamepadInputId is changed. diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs index f4bfd1169..2e589f9e2 100644 --- a/src/Ryujinx/AppHost.cs +++ b/src/Ryujinx/AppHost.cs @@ -1200,6 +1200,14 @@ private bool UpdateFrame() _viewModel.Volume = Device.GetVolume(); break; + case KeyboardHotkeyState.ToggleMotionEmulation: + foreach (var controller in NpadManager.Controllers) + { + var motion = controller?.StandardControllerInputConfig?.Motion; + if (motion != null) + motion.SticksToMotion = !motion.SticksToMotion; + } + break; case KeyboardHotkeyState.None: (_keyboardInterface as AvaloniaKeyboard).Clear(); break; @@ -1273,6 +1281,10 @@ private KeyboardHotkeyState GetHotkeyState() { state = KeyboardHotkeyState.VolumeDown; } + else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ToggleMotionEmulation)) + { + state = KeyboardHotkeyState.ToggleMotionEmulation; + } return state; } diff --git a/src/Ryujinx/Assets/Locales/ar_SA.json b/src/Ryujinx/Assets/Locales/ar_SA.json index 73e55633b..634d84c10 100644 --- a/src/Ryujinx/Assets/Locales/ar_SA.json +++ b/src/Ryujinx/Assets/Locales/ar_SA.json @@ -734,6 +734,7 @@ "RyujinxUpdaterMessage": "هل تريد تحديث ريوجينكس إلى أحدث إصدار؟", "SettingsTabHotkeysVolumeUpHotkey": "زيادة مستوى الصوت:", "SettingsTabHotkeysVolumeDownHotkey": "خفض مستوى الصوت:", + "SettingsTabHotkeysToggleMotionEmulationHotkey": "Toggle Motion Emulation:", "SettingsEnableMacroHLE": "تمكين Maro HLE", "SettingsEnableMacroHLETooltip": "محاكاة عالية المستوى لكود مايكرو وحدة معالجة الرسوميات.\n\nيعمل على تحسين الأداء، ولكنه قد يسبب خللا رسوميا في بعض الألعاب.\n\nاتركه مفعلا إذا لم تكن متأكدا.", "SettingsEnableColorSpacePassthrough": "عبور مساحة اللون", diff --git a/src/Ryujinx/Assets/Locales/de_DE.json b/src/Ryujinx/Assets/Locales/de_DE.json index 401293198..fb6f0b575 100644 --- a/src/Ryujinx/Assets/Locales/de_DE.json +++ b/src/Ryujinx/Assets/Locales/de_DE.json @@ -734,6 +734,7 @@ "RyujinxUpdaterMessage": "Möchtest du Ryujinx auf die neueste Version aktualisieren?", "SettingsTabHotkeysVolumeUpHotkey": "Lautstärke erhöhen:", "SettingsTabHotkeysVolumeDownHotkey": "Lautstärke verringern:", + "SettingsTabHotkeysToggleMotionEmulationHotkey": "Toggle Motion Emulation:", "SettingsEnableMacroHLE": "HLE Makros aktivieren", "SettingsEnableMacroHLETooltip": "High-Level-Emulation von GPU-Makrocode.\n\nVerbessert die Leistung, kann aber in einigen Spielen zu Grafikfehlern führen.\n\nBei Unsicherheit AKTIVIEREN.", "SettingsEnableColorSpacePassthrough": "Farbraum Passthrough", diff --git a/src/Ryujinx/Assets/Locales/el_GR.json b/src/Ryujinx/Assets/Locales/el_GR.json index ccdf6e0e4..2b575b8a1 100644 --- a/src/Ryujinx/Assets/Locales/el_GR.json +++ b/src/Ryujinx/Assets/Locales/el_GR.json @@ -734,6 +734,7 @@ "RyujinxUpdaterMessage": "Θέλετε να ενημερώσετε το Ryujinx στην πιο πρόσφατη έκδοση:", "SettingsTabHotkeysVolumeUpHotkey": "Αύξηση Έντασης:", "SettingsTabHotkeysVolumeDownHotkey": "Μείωση Έντασης:", + "SettingsTabHotkeysToggleMotionEmulationHotkey": "Toggle Motion Emulation:", "SettingsEnableMacroHLE": "Ενεργοποίηση του Macro HLE", "SettingsEnableMacroHLETooltip": "Προσομοίωση του κώδικα GPU Macro .\n\nΒελτιώνει την απόδοση, αλλά μπορεί να προκαλέσει γραφικά προβλήματα σε μερικά παιχνίδια.\n\nΑφήστε ΕΝΕΡΓΟ αν δεν είστε σίγουροι.", "SettingsEnableColorSpacePassthrough": "Διέλευση Χρωματικού Χώρου", diff --git a/src/Ryujinx/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json index 45befacb3..5698205b9 100644 --- a/src/Ryujinx/Assets/Locales/en_US.json +++ b/src/Ryujinx/Assets/Locales/en_US.json @@ -753,6 +753,7 @@ "RyujinxUpdaterMessage": "Do you want to update Ryujinx to the latest version?", "SettingsTabHotkeysVolumeUpHotkey": "Increase Volume:", "SettingsTabHotkeysVolumeDownHotkey": "Decrease Volume:", + "SettingsTabHotkeysToggleMotionEmulationHotkey": "Toggle Motion Emulation:", "SettingsEnableMacroHLE": "Enable Macro HLE", "SettingsEnableMacroHLETooltip": "High-level emulation of GPU Macro code.\n\nImproves performance, but may cause graphical glitches in some games.\n\nLeave ON if unsure.", "SettingsEnableColorSpacePassthrough": "Color Space Passthrough", diff --git a/src/Ryujinx/Assets/Locales/es_ES.json b/src/Ryujinx/Assets/Locales/es_ES.json index e58fa5dcf..8b4adbf5e 100644 --- a/src/Ryujinx/Assets/Locales/es_ES.json +++ b/src/Ryujinx/Assets/Locales/es_ES.json @@ -734,6 +734,7 @@ "RyujinxUpdaterMessage": "¿Quieres actualizar Ryujinx a la última versión?", "SettingsTabHotkeysVolumeUpHotkey": "Aumentar volumen:", "SettingsTabHotkeysVolumeDownHotkey": "Disminuir volumen:", + "SettingsTabHotkeysToggleMotionEmulationHotkey": "Activar emulación de movimiento:", "SettingsEnableMacroHLE": "Activar Macros HLE", "SettingsEnableMacroHLETooltip": "Emulación alto-nivel del código de Macros de GPU\n\nIncrementa el rendimiento, pero puede causar errores gráficos en algunos juegos.\n\nDeja esta opción activada si no estás seguro.", "SettingsEnableColorSpacePassthrough": "Paso de espacio de color", diff --git a/src/Ryujinx/Assets/Locales/fr_FR.json b/src/Ryujinx/Assets/Locales/fr_FR.json index 99a060650..0b5344c3c 100644 --- a/src/Ryujinx/Assets/Locales/fr_FR.json +++ b/src/Ryujinx/Assets/Locales/fr_FR.json @@ -734,6 +734,7 @@ "RyujinxUpdaterMessage": "Voulez-vous mettre à jour Ryujinx vers la dernière version ?", "SettingsTabHotkeysVolumeUpHotkey": "Augmenter le volume :", "SettingsTabHotkeysVolumeDownHotkey": "Diminuer le volume :", + "SettingsTabHotkeysToggleMotionEmulationHotkey": "Toggle Motion Emulation:", "SettingsEnableMacroHLE": "Activer les macros HLE", "SettingsEnableMacroHLETooltip": "Émulation de haut niveau du code de Macro GPU.\n\nAméliore les performances, mais peut causer des artefacts graphiques dans certains jeux.\n\nLaissez ACTIVER si vous n'êtes pas sûr.", "SettingsEnableColorSpacePassthrough": "Traversée de l'espace colorimétrique", diff --git a/src/Ryujinx/Assets/Locales/he_IL.json b/src/Ryujinx/Assets/Locales/he_IL.json index 848f78080..5d3ca213b 100644 --- a/src/Ryujinx/Assets/Locales/he_IL.json +++ b/src/Ryujinx/Assets/Locales/he_IL.json @@ -734,6 +734,7 @@ "RyujinxUpdaterMessage": "האם ברצונך לעדכן את ריוג'ינקס לגרסא האחרונה?", "SettingsTabHotkeysVolumeUpHotkey": "הגבר את עוצמת הקול:", "SettingsTabHotkeysVolumeDownHotkey": "הנמך את עוצמת הקול:", + "SettingsTabHotkeysToggleMotionEmulationHotkey": "Toggle Motion Emulation:", "SettingsEnableMacroHLE": "Enable Macro HLE", "SettingsEnableMacroHLETooltip": "אמולצייה ברמה גבוהה של כרטיס גראפי עם קוד מקרו.\n\nמשפר את ביצועי היישום אך עלול לגרום לגליצ'ים חזותיים במשחקים מסויימים.\n\nמוטב להשאיר דלוק אם אינך בטוח.", "SettingsEnableColorSpacePassthrough": "שקיפות מרחב צבע", diff --git a/src/Ryujinx/Assets/Locales/it_IT.json b/src/Ryujinx/Assets/Locales/it_IT.json index 280ebd880..e022623e3 100644 --- a/src/Ryujinx/Assets/Locales/it_IT.json +++ b/src/Ryujinx/Assets/Locales/it_IT.json @@ -734,6 +734,7 @@ "RyujinxUpdaterMessage": "Vuoi aggiornare Ryujinx all'ultima versione?", "SettingsTabHotkeysVolumeUpHotkey": "Alza il volume:", "SettingsTabHotkeysVolumeDownHotkey": "Abbassa il volume:", + "SettingsTabHotkeysToggleMotionEmulationHotkey": "Toggle Motion Emulation:", "SettingsEnableMacroHLE": "Attiva HLE macro", "SettingsEnableMacroHLETooltip": "Emulazione di alto livello del codice macro della GPU.\n\nMigliora le prestazioni, ma può causare anomalie grafiche in alcuni giochi.\n\nNel dubbio, lascia l'opzione attiva.", "SettingsEnableColorSpacePassthrough": "Passthrough dello spazio dei colori", diff --git a/src/Ryujinx/Assets/Locales/ja_JP.json b/src/Ryujinx/Assets/Locales/ja_JP.json index 61e963258..8eadcef16 100644 --- a/src/Ryujinx/Assets/Locales/ja_JP.json +++ b/src/Ryujinx/Assets/Locales/ja_JP.json @@ -734,6 +734,7 @@ "RyujinxUpdaterMessage": "Ryujinx を最新版にアップデートしますか?", "SettingsTabHotkeysVolumeUpHotkey": "音量を上げる:", "SettingsTabHotkeysVolumeDownHotkey": "音量を下げる:", + "SettingsTabHotkeysToggleMotionEmulationHotkey": "Toggle Motion Emulation:", "SettingsEnableMacroHLE": "マクロの高レベルエミュレーション (HLE) を有効にする", "SettingsEnableMacroHLETooltip": "GPU マクロコードの高レベルエミュレーションです.\n\nパフォーマンスを向上させますが, 一部のゲームでグラフィックに不具合が発生する可能性があります.\n\nよくわからない場合はオンのままにしてください.", "SettingsEnableColorSpacePassthrough": "色空間をパススルー", diff --git a/src/Ryujinx/Assets/Locales/ko_KR.json b/src/Ryujinx/Assets/Locales/ko_KR.json index a92d084e0..bb953e131 100644 --- a/src/Ryujinx/Assets/Locales/ko_KR.json +++ b/src/Ryujinx/Assets/Locales/ko_KR.json @@ -734,6 +734,7 @@ "RyujinxUpdaterMessage": "Ryujinx를 최신 버전으로 업데이트하겠습니까?", "SettingsTabHotkeysVolumeUpHotkey": "음량 증가 :", "SettingsTabHotkeysVolumeDownHotkey": "음량 감소 :", + "SettingsTabHotkeysToggleMotionEmulationHotkey": "Toggle Motion Emulation:", "SettingsEnableMacroHLE": "매크로 HLE 활성화", "SettingsEnableMacroHLETooltip": "GPU 매크로 코드의 높은 수준 에뮬레이션입니다.\n\n성능이 향상되지만 일부 게임에서 그래픽 결함이 발생할 수 있습니다.\n\n확실하지 않으면 켜 두세요.", "SettingsEnableColorSpacePassthrough": "색 공간 통과", diff --git a/src/Ryujinx/Assets/Locales/pl_PL.json b/src/Ryujinx/Assets/Locales/pl_PL.json index 9d1bd7b44..0251a80d9 100644 --- a/src/Ryujinx/Assets/Locales/pl_PL.json +++ b/src/Ryujinx/Assets/Locales/pl_PL.json @@ -734,6 +734,7 @@ "RyujinxUpdaterMessage": "Czy chcesz zaktualizować Ryujinx do najnowszej wersji?", "SettingsTabHotkeysVolumeUpHotkey": "Zwiększ Głośność:", "SettingsTabHotkeysVolumeDownHotkey": "Zmniejsz Głośność:", + "SettingsTabHotkeysToggleMotionEmulationHotkey": "Toggle Motion Emulation:", "SettingsEnableMacroHLE": "Włącz Macro HLE", "SettingsEnableMacroHLETooltip": "Wysokopoziomowa emulacja kodu GPU Macro.\n\nPoprawia wydajność, ale może powodować błędy graficzne w niektórych grach.\n\nW razie wątpliwości pozostaw WŁĄCZONE.", "SettingsEnableColorSpacePassthrough": "Przekazywanie przestrzeni kolorów", diff --git a/src/Ryujinx/Assets/Locales/pt_BR.json b/src/Ryujinx/Assets/Locales/pt_BR.json index a8c244b65..7fc302625 100644 --- a/src/Ryujinx/Assets/Locales/pt_BR.json +++ b/src/Ryujinx/Assets/Locales/pt_BR.json @@ -734,6 +734,7 @@ "RyujinxUpdaterMessage": "Você quer atualizar o Ryujinx para a última versão?", "SettingsTabHotkeysVolumeUpHotkey": "Aumentar volume:", "SettingsTabHotkeysVolumeDownHotkey": "Diminuir volume:", + "SettingsTabHotkeysToggleMotionEmulationHotkey": "Toggle Motion Emulation:", "SettingsEnableMacroHLE": "Habilitar emulação de alto nível para Macros", "SettingsEnableMacroHLETooltip": "Habilita emulação de alto nível de códigos Macro da GPU.\n\nMelhora a performance, mas pode causar problemas gráficos em alguns jogos.\n\nEm caso de dúvida, deixe ATIVADO.", "SettingsEnableColorSpacePassthrough": "Passagem de Espaço Cor", diff --git a/src/Ryujinx/Assets/Locales/ru_RU.json b/src/Ryujinx/Assets/Locales/ru_RU.json index 75fd4fe12..ddd4458e6 100644 --- a/src/Ryujinx/Assets/Locales/ru_RU.json +++ b/src/Ryujinx/Assets/Locales/ru_RU.json @@ -734,6 +734,7 @@ "RyujinxUpdaterMessage": "Обновить Ryujinx до последней версии?", "SettingsTabHotkeysVolumeUpHotkey": "Увеличить громкость:", "SettingsTabHotkeysVolumeDownHotkey": "Уменьшить громкость:", + "SettingsTabHotkeysToggleMotionEmulationHotkey": "Toggle Motion Emulation:", "SettingsEnableMacroHLE": "Использовать макрос высокоуровневой эмуляции видеоадаптера", "SettingsEnableMacroHLETooltip": "Высокоуровневая эмуляции макрокода видеоадаптера.\n\nПовышает производительность, но может вызывать графические артефакты в некоторых играх.\n\nРекомендуется оставить включенным.", "SettingsEnableColorSpacePassthrough": "Пропускать цветовое пространство", diff --git a/src/Ryujinx/Assets/Locales/th_TH.json b/src/Ryujinx/Assets/Locales/th_TH.json index 629442269..14eb0a713 100644 --- a/src/Ryujinx/Assets/Locales/th_TH.json +++ b/src/Ryujinx/Assets/Locales/th_TH.json @@ -734,6 +734,7 @@ "RyujinxUpdaterMessage": "คุณต้องการอัพเดต รียูจินซ์ เป็นเวอร์ชั่นล่าสุดหรือไม่?", "SettingsTabHotkeysVolumeUpHotkey": "เพิ่มระดับเสียง:", "SettingsTabHotkeysVolumeDownHotkey": "ลดระดับเสียง:", + "SettingsTabHotkeysToggleMotionEmulationHotkey": "Toggle Motion Emulation:", "SettingsEnableMacroHLE": "เปิดใช้งาน มาโคร HLE", "SettingsEnableMacroHLETooltip": "การจำลองระดับสูงของโค้ดมาโคร GPU\n\nปรับปรุงประสิทธิภาพ แต่อาจทำให้เกิดข้อผิดพลาดด้านกราฟิกในบางเกม\n\nปล่อยไว้หากคุณไม่แน่ใจ", "SettingsEnableColorSpacePassthrough": "ทะลุผ่านพื้นที่สี", diff --git a/src/Ryujinx/Assets/Locales/tr_TR.json b/src/Ryujinx/Assets/Locales/tr_TR.json index f74baaa18..156a35dff 100644 --- a/src/Ryujinx/Assets/Locales/tr_TR.json +++ b/src/Ryujinx/Assets/Locales/tr_TR.json @@ -734,6 +734,7 @@ "RyujinxUpdaterMessage": "Ryujinx'i en son sürüme güncellemek ister misiniz?", "SettingsTabHotkeysVolumeUpHotkey": "Sesi Arttır:", "SettingsTabHotkeysVolumeDownHotkey": "Sesi Azalt:", + "SettingsTabHotkeysToggleMotionEmulationHotkey": "Toggle Motion Emulation:", "SettingsEnableMacroHLE": "Macro HLE'yi Aktifleştir", "SettingsEnableMacroHLETooltip": "GPU Macro kodunun yüksek seviye emülasyonu.\n\nPerformansı arttırır, ama bazı oyunlarda grafik hatalarına yol açabilir.\n\nEmin değilseniz AÇIK bırakın.", "SettingsEnableColorSpacePassthrough": "Renk Alanı Geçişi", diff --git a/src/Ryujinx/Assets/Locales/uk_UA.json b/src/Ryujinx/Assets/Locales/uk_UA.json index 976edfb1b..5f179c6d0 100644 --- a/src/Ryujinx/Assets/Locales/uk_UA.json +++ b/src/Ryujinx/Assets/Locales/uk_UA.json @@ -734,6 +734,7 @@ "RyujinxUpdaterMessage": "Бажаєте оновити Ryujinx до останньої версії?", "SettingsTabHotkeysVolumeUpHotkey": "Збільшити гучність:", "SettingsTabHotkeysVolumeDownHotkey": "Зменшити гучність:", + "SettingsTabHotkeysToggleMotionEmulationHotkey": "Toggle Motion Emulation:", "SettingsEnableMacroHLE": "Увімкнути макрос HLE", "SettingsEnableMacroHLETooltip": "Високорівнева емуляція коду макросу GPU.\n\nПокращує продуктивність, але може викликати графічні збої в деяких іграх.\n\nЗалиште увімкненим, якщо не впевнені.", "SettingsEnableColorSpacePassthrough": "Наскрізний колірний простір", diff --git a/src/Ryujinx/Assets/Locales/zh_CN.json b/src/Ryujinx/Assets/Locales/zh_CN.json index 66f59ecd0..0fa8f6d76 100644 --- a/src/Ryujinx/Assets/Locales/zh_CN.json +++ b/src/Ryujinx/Assets/Locales/zh_CN.json @@ -734,6 +734,7 @@ "RyujinxUpdaterMessage": "是否更新 Ryujinx 到最新的版本?", "SettingsTabHotkeysVolumeUpHotkey": "音量加:", "SettingsTabHotkeysVolumeDownHotkey": "音量减:", + "SettingsTabHotkeysToggleMotionEmulationHotkey": "Toggle Motion Emulation:", "SettingsEnableMacroHLE": "启用 HLE 宏加速", "SettingsEnableMacroHLETooltip": "GPU 宏指令的高级模拟。\n\n提高性能表现,但一些游戏可能会出现图形错误。\n\n如果不确定,请保持开启状态。", "SettingsEnableColorSpacePassthrough": "色彩空间直通", diff --git a/src/Ryujinx/Assets/Locales/zh_TW.json b/src/Ryujinx/Assets/Locales/zh_TW.json index fc838d251..4c36b5594 100644 --- a/src/Ryujinx/Assets/Locales/zh_TW.json +++ b/src/Ryujinx/Assets/Locales/zh_TW.json @@ -734,6 +734,7 @@ "RyujinxUpdaterMessage": "您想將 Ryujinx 升級到最新版本嗎?", "SettingsTabHotkeysVolumeUpHotkey": "提高音量:", "SettingsTabHotkeysVolumeDownHotkey": "降低音量:", + "SettingsTabHotkeysToggleMotionEmulationHotkey": "Toggle Motion Emulation:", "SettingsEnableMacroHLE": "啟用 Macro HLE", "SettingsEnableMacroHLETooltip": "GPU 巨集程式碼的進階模擬。\n\n可提高效能,但在某些遊戲中可能會導致圖形閃爍。\n\n如果不確定,請保持開啟狀態。", "SettingsEnableColorSpacePassthrough": "色彩空間直通", diff --git a/src/Ryujinx/Common/KeyboardHotkeyState.cs b/src/Ryujinx/Common/KeyboardHotkeyState.cs index 6e4920988..f0737f2b9 100644 --- a/src/Ryujinx/Common/KeyboardHotkeyState.cs +++ b/src/Ryujinx/Common/KeyboardHotkeyState.cs @@ -12,5 +12,6 @@ public enum KeyboardHotkeyState ResScaleDown, VolumeUp, VolumeDown, + ToggleMotionEmulation, } } diff --git a/src/Ryujinx/Input/AvaloniaKeyboard.cs b/src/Ryujinx/Input/AvaloniaKeyboard.cs index ff88de79e..c498076a9 100644 --- a/src/Ryujinx/Input/AvaloniaKeyboard.cs +++ b/src/Ryujinx/Input/AvaloniaKeyboard.cs @@ -49,7 +49,7 @@ public KeyboardStateSnapshot GetKeyboardStateSnapshot() return IKeyboard.GetStateSnapshot(this); } - public GamepadStateSnapshot GetMappedStateSnapshot() + public GamepadStateSnapshot GetMappedStateSnapshot(bool _) { KeyboardStateSnapshot rawState = GetKeyboardStateSnapshot(); GamepadStateSnapshot result = default; @@ -85,7 +85,7 @@ public GamepadStateSnapshot GetMappedStateSnapshot() return result; } - public GamepadStateSnapshot GetStateSnapshot() + public GamepadStateSnapshot GetStateSnapshot(bool _) { throw new NotSupportedException(); } diff --git a/src/Ryujinx/Input/AvaloniaMouse.cs b/src/Ryujinx/Input/AvaloniaMouse.cs index 1aa2d586a..170ac4ddb 100644 --- a/src/Ryujinx/Input/AvaloniaMouse.cs +++ b/src/Ryujinx/Input/AvaloniaMouse.cs @@ -34,7 +34,7 @@ public Vector2 GetScroll() return _driver.Scroll; } - public GamepadStateSnapshot GetMappedStateSnapshot() + public GamepadStateSnapshot GetMappedStateSnapshot(bool _) { throw new NotImplementedException(); } @@ -44,7 +44,7 @@ public Vector3 GetMotionData(MotionInputId inputId) throw new NotImplementedException(); } - public GamepadStateSnapshot GetStateSnapshot() + public GamepadStateSnapshot GetStateSnapshot(bool _) { throw new NotImplementedException(); } diff --git a/src/Ryujinx/UI/Models/Input/HotkeyConfig.cs b/src/Ryujinx/UI/Models/Input/HotkeyConfig.cs index b5f53508b..8875e3b65 100644 --- a/src/Ryujinx/UI/Models/Input/HotkeyConfig.cs +++ b/src/Ryujinx/UI/Models/Input/HotkeyConfig.cs @@ -104,6 +104,17 @@ public Key VolumeDown } } + private Key _toggleMotionEmulation; + public Key ToggleMotionEmulation + { + get => _toggleMotionEmulation; + set + { + _toggleMotionEmulation = value; + OnPropertyChanged(); + } + } + public HotkeyConfig(KeyboardHotkeys config) { if (config != null) @@ -117,6 +128,7 @@ public HotkeyConfig(KeyboardHotkeys config) ResScaleDown = config.ResScaleDown; VolumeUp = config.VolumeUp; VolumeDown = config.VolumeDown; + ToggleMotionEmulation = config.ToggleMotionEmulation; } } @@ -133,6 +145,7 @@ public KeyboardHotkeys GetConfig() ResScaleDown = ResScaleDown, VolumeUp = VolumeUp, VolumeDown = VolumeDown, + ToggleMotionEmulation = ToggleMotionEmulation, }; return config; diff --git a/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml index bffcada05..c9bc67d58 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml +++ b/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml @@ -1,4 +1,4 @@ - + + + + + + diff --git a/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs index fb0fe2bb1..98640a906 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs +++ b/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs @@ -109,6 +109,9 @@ private void Button_IsCheckedChanged(object sender, RoutedEventArgs e) case "VolumeDown": viewModel.KeyboardHotkey.VolumeDown = buttonValue.AsHidType(); break; + case "ToggleMotionEmulation": + viewModel.KeyboardHotkey.ToggleMotionEmulation = buttonValue.AsHidType(); + break; } } };