diff options
| author | Mary <me@thog.eu> | 2021-04-14 12:28:43 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-04-14 12:28:43 +0200 |
| commit | 6cb22c9d38622225f9f787f483bd73369774cf77 (patch) | |
| tree | 715a40903ceab05546f7392e5b0f429de75bdd02 /Ryujinx.Common/Configuration | |
| parent | 978b69b706fc085d66b01e2dd27ef6d4acebf335 (diff) | |
Miria: The Death of OpenTK 3 (#2194)
* openal: Update to OpenTK 4
* Ryujinx.Graphics.OpenGL: Update to OpenTK 4
* Entirely removed OpenTK 3, still wip
* Use SPB for context creation and handling
Still need to test on GLX and readd input support
* Start implementing a new input system
So far only gamepad are supported, no configuration possible via UI but detected via hotplug/removal
Button mapping backend is implemented
TODO: front end, configuration handling and configuration migration
TODO: keyboard support
* Enforce RGB only framebuffer on the GLWidget
Fix possible transparent window
* Implement UI gamepad frontend
Also fix bad mapping of minus button and ensure gamepad config is updated in real time
* Handle controller being disconnected and reconnected again
* Revert "Enforce RGB only framebuffer on the GLWidget"
This reverts commit 0949715d1a03ec793e35e37f7b610cbff2d63965.
* Fix first color clear
* Filter SDL2 events a bit
* Start working on the keyboard detail
- Rework configuration classes a bit to be more clean.
- Integrate fully the keyboard configuration to the front end (TODO: assigner)
- Start skeleton for the GTK3 keyboard driver
* Add KeyboardStateSnapshot and its integration
* Implement keyboard assigner and GTK3 key mapping
TODO: controller configuration mapping and IGamepad implementation for keyboard
* Add missing SR and SL definitions
* Fix copy pasta mistake on config for previous commit
* Implement IGamepad interface for GTK3 keyboard
* Fix some implementation still being commented in the controller ui for keyboard
* Port screen handle code
* Remove all configuration management code and move HidNew to Hid
* Rename InputConfigNew to InputConfig
* Add a version field to the input config
* Prepare serialization and deserialization of new input config and migrate profile loading and saving
* Support input configuration saving to config and bump config version to 23.
* Clean up in ConfigurationState
* Reference SPB via a nuget package
* Move new input system to Ryujinx.Input project and SDL2 detail to Ryujinx.Input.SDL2
* move GTK3 input to the right directory
* Fix triggers on SDL2
* Update to SDL2 2.0.14 via our own fork
* Update buttons definition for SDL2 2.0.14 and report gamepad features
* Implement motion support again with SDL2
TODO: cemu hooks integration
* Switch to latest of nightly SDL2
* SDL2: Fix bugs in gamepad id matching allowing different gamepad to match on the same device index
* Ensure values are set in UI when the gamepad get hot plugged
* Avoid trying to add controllers in the Update method and don't open SDL2 gamepad instance before checking ids
This fixes permanent rumble of pro controller in some hotplug scenario
* Fix more UI bugs
* Move legcay motion code around before reintegration
* gamecontroller UI tweaks here and there
* Hide Motion on non motion configurations
* Update the TODO grave
Some TODO were fixed long time ago or are quite oudated...
* Integrate cemu hooks motion configuration
* Integrate cemu hooks configuration options to the UI again
* cemuhooks => cemuhooks
* Add cemu hook support again
* Fix regression on normal motion and fix some very nasty bugs around
* Fix for XCB multithreads issue on Linux
* Enable motion by default
* Block inputs in the main view when in the controller configuration window
* Some fixes for the controller ui again
* Add joycon support and fixes other hints
* Bug fixes and clean up
- Invert default mapping if not a Nintendo controller
- Keep alive the controller being selected on the controller window (allow to avoid big delay for controller needing time to init when doing button assignment)
- Clean up hints in use
- Remove debug logs around
- Fixes potential double free with SDL2Gamepad
* Move the button assigner and motion logic to the Ryujinx.Input project
* Reimplement raw keyboard hle input
Also move out the logic of the hotkeys
* Move all remaining Input manager stuffs to the Ryujinx.Input project
* Increment configuration version yet again because of master changes
* Ensure input config isn't null when not present
* Fixes for VS not being nice
* Fix broken gamepad caching logic causing crashes on ui
* Ensure the background context is destroyed
* Update dependencies
* Readd retrocompat with old format of the config to avoid parsing and crashes on those versions
Also updated the debug Config.json
* Document new input APIs
* Isolate SDL2Driver to the project and remove external export of it
* Add support for external gamepad db mappings on SDL2
* Last clean up before PR
* Addresses first part of comments
* Address gdkchan's comments
* Do not use JsonException
* Last comment fixes
Diffstat (limited to 'Ryujinx.Common/Configuration')
30 files changed, 702 insertions, 522 deletions
diff --git a/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs b/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs index 32e76375..1d47051a 100644 --- a/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs +++ b/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs @@ -14,7 +14,7 @@ namespace Ryujinx.Configuration /// <summary> /// The current version of the file format /// </summary> - public const int CurrentVersion = 23; + public const int CurrentVersion = 24; public int Version { get; set; } @@ -224,14 +224,23 @@ namespace Ryujinx.Configuration public KeyboardHotkeys Hotkeys { get; set; } /// <summary> - /// Keyboard control bindings + /// Legacy keyboard control bindings /// </summary> - public List<KeyboardConfig> KeyboardConfig { get; set; } + /// <remarks>Kept for file format compatibility (to avoid possible failure when parsing configuration on old versions)</remarks> + /// TODO: Remove this when those older versions aren't in use anymore. + public List<object> KeyboardConfig { get; set; } /// <summary> - /// Controller control bindings + /// Legacy controller control bindings /// </summary> - public List<ControllerConfig> ControllerConfig { get; set; } + /// <remarks>Kept for file format compatibility (to avoid possible failure when parsing configuration on old versions)</remarks> + /// TODO: Remove this when those older versions aren't in use anymore. + public List<object> ControllerConfig { get; set; } + + /// <summary> + /// Input configurations + /// </summary> + public List<InputConfig> InputConfig { get; set; } /// <summary> /// Loads a configuration file from disk diff --git a/Ryujinx.Common/Configuration/ConfigurationState.cs b/Ryujinx.Common/Configuration/ConfigurationState.cs index 1e26b4f4..7063110f 100644 --- a/Ryujinx.Common/Configuration/ConfigurationState.cs +++ b/Ryujinx.Common/Configuration/ConfigurationState.cs @@ -1,8 +1,8 @@ using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Hid; +using Ryujinx.Common.Configuration.Hid.Keyboard; using Ryujinx.Common.Logging; -using Ryujinx.Configuration.Hid; using Ryujinx.Configuration.System; using Ryujinx.Configuration.Ui; using System; @@ -405,21 +405,6 @@ namespace Ryujinx.Configuration public ConfigurationFileFormat ToFileFormat() { - List<ControllerConfig> controllerConfigList = new List<ControllerConfig>(); - List<KeyboardConfig> keyboardConfigList = new List<KeyboardConfig>(); - - foreach (InputConfig inputConfig in Hid.InputConfig.Value) - { - if (inputConfig is ControllerConfig controllerConfig) - { - controllerConfigList.Add(controllerConfig); - } - else if (inputConfig is KeyboardConfig keyboardConfig) - { - keyboardConfigList.Add(keyboardConfig); - } - } - ConfigurationFileFormat configurationFile = new ConfigurationFileFormat { Version = ConfigurationFileFormat.CurrentVersion, @@ -479,8 +464,9 @@ namespace Ryujinx.Configuration StartFullscreen = Ui.StartFullscreen, EnableKeyboard = Hid.EnableKeyboard, Hotkeys = Hid.Hotkeys, - KeyboardConfig = keyboardConfigList, - ControllerConfig = controllerConfigList + KeyboardConfig = new List<object>(), + ControllerConfig = new List<object>(), + InputConfig = Hid.InputConfig, }; return configurationFile; @@ -543,54 +529,57 @@ namespace Ryujinx.Configuration }; Hid.InputConfig.Value = new List<InputConfig> { - new KeyboardConfig - { - Index = 0, - ControllerType = ControllerType.JoyconPair, - PlayerIndex = PlayerIndex.Player1, - LeftJoycon = new NpadKeyboardLeft - { - StickUp = Key.W, - StickDown = Key.S, - StickLeft = Key.A, - StickRight = Key.D, - StickButton = Key.F, - DPadUp = Key.Up, - DPadDown = Key.Down, - DPadLeft = Key.Left, - DPadRight = Key.Right, - ButtonMinus = Key.Minus, - ButtonL = Key.E, - ButtonZl = Key.Q, - ButtonSl = Key.Home, - ButtonSr = Key.End - }, - RightJoycon = new NpadKeyboardRight - { - StickUp = Key.I, - StickDown = Key.K, - StickLeft = Key.J, - StickRight = Key.L, - StickButton = Key.H, - ButtonA = Key.Z, - ButtonB = Key.X, - ButtonX = Key.C, - ButtonY = Key.V, - ButtonPlus = Key.Plus, - ButtonR = Key.U, - ButtonZr = Key.O, - ButtonSl = Key.PageUp, - ButtonSr = Key.PageDown - }, - EnableMotion = false, - MirrorInput = false, - Slot = 0, - AltSlot = 0, - Sensitivity = 100, - GyroDeadzone = 1, - DsuServerHost = "127.0.0.1", - DsuServerPort = 26760 - } + new StandardKeyboardInputConfig + { + Version = InputConfig.CurrentVersion, + Backend = InputBackendType.WindowKeyboard, + Id = "0", + PlayerIndex = PlayerIndex.Player1, + ControllerType = ControllerType.JoyconPair, + LeftJoycon = new LeftJoyconCommonConfig<Key> + { + DpadUp = Key.Up, + DpadDown = Key.Down, + DpadLeft = Key.Left, + DpadRight = Key.Right, + ButtonMinus = Key.Minus, + ButtonL = Key.E, + ButtonZl = Key.Q, + ButtonSl = Key.Unbound, + ButtonSr = Key.Unbound + }, + + LeftJoyconStick = new JoyconConfigKeyboardStick<Key> + { + StickUp = Key.W, + StickDown = Key.S, + StickLeft = Key.A, + StickRight = Key.D, + StickButton = Key.F, + }, + + RightJoycon = new RightJoyconCommonConfig<Key> + { + ButtonA = Key.Z, + ButtonB = Key.X, + ButtonX = Key.C, + ButtonY = Key.V, + ButtonPlus = Key.Plus, + ButtonR = Key.U, + ButtonZr = Key.O, + ButtonSl = Key.Unbound, + ButtonSr = Key.Unbound + }, + + RightJoyconStick = new JoyconConfigKeyboardStick<Key> + { + StickUp = Key.I, + StickDown = Key.K, + StickLeft = Key.J, + StickRight = Key.L, + StickButton = Key.H, + } + } }; } @@ -643,80 +632,6 @@ namespace Ryujinx.Configuration configurationFileUpdated = true; } - if (configurationFileFormat.Version < 6) - { - Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 6."); - - configurationFileFormat.ControllerConfig = new List<ControllerConfig>(); - configurationFileFormat.KeyboardConfig = new List<KeyboardConfig> - { - new KeyboardConfig - { - Index = 0, - ControllerType = ControllerType.JoyconPair, - PlayerIndex = PlayerIndex.Player1, - LeftJoycon = new NpadKeyboardLeft - { - StickUp = Key.W, - StickDown = Key.S, - StickLeft = Key.A, - StickRight = Key.D, - StickButton = Key.F, - DPadUp = Key.Up, - DPadDown = Key.Down, - DPadLeft = Key.Left, - DPadRight = Key.Right, - ButtonMinus = Key.Minus, - ButtonL = Key.E, - ButtonZl = Key.Q, - ButtonSl = Key.Unbound, - ButtonSr = Key.Unbound - }, - RightJoycon = new NpadKeyboardRight - { - StickUp = Key.I, - StickDown = Key.K, - StickLeft = Key.J, - StickRight = Key.L, - StickButton = Key.H, - ButtonA = Key.Z, - ButtonB = Key.X, - ButtonX = Key.C, - ButtonY = Key.V, - ButtonPlus = Key.Plus, - ButtonR = Key.U, - ButtonZr = Key.O, - ButtonSl = Key.Unbound, - ButtonSr = Key.Unbound - }, - EnableMotion = false, - MirrorInput = false, - Slot = 0, - AltSlot = 0, - Sensitivity = 100, - GyroDeadzone = 1, - DsuServerHost = "127.0.0.1", - DsuServerPort = 26760 - } - }; - - configurationFileUpdated = true; - } - - // Only needed for version 6 configurations. - if (configurationFileFormat.Version == 6) - { - Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 7."); - - for (int i = 0; i < configurationFileFormat.KeyboardConfig.Count; i++) - { - if (configurationFileFormat.KeyboardConfig[i].Index != KeyboardConfig.AllKeyboardsIndex) - { - configurationFileFormat.KeyboardConfig[i].Index++; - } - } - } - if (configurationFileFormat.Version < 8) { Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 8."); @@ -826,9 +741,67 @@ namespace Ryujinx.Configuration configurationFileUpdated = true; } - List<InputConfig> inputConfig = new List<InputConfig>(); - inputConfig.AddRange(configurationFileFormat.ControllerConfig); - inputConfig.AddRange(configurationFileFormat.KeyboardConfig); + if (configurationFileFormat.Version < 24) + { + Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 24."); + + configurationFileFormat.InputConfig = new List<InputConfig> + { + new StandardKeyboardInputConfig + { + Version = InputConfig.CurrentVersion, + Backend = InputBackendType.WindowKeyboard, + Id = "0", + PlayerIndex = PlayerIndex.Player1, + ControllerType = ControllerType.JoyconPair, + LeftJoycon = new LeftJoyconCommonConfig<Key> + { + DpadUp = Key.Up, + DpadDown = Key.Down, + DpadLeft = Key.Left, + DpadRight = Key.Right, + ButtonMinus = Key.Minus, + ButtonL = Key.E, + ButtonZl = Key.Q, + ButtonSl = Key.Unbound, + ButtonSr = Key.Unbound + }, + + LeftJoyconStick = new JoyconConfigKeyboardStick<Key> + { + StickUp = Key.W, + StickDown = Key.S, + StickLeft = Key.A, + StickRight = Key.D, + StickButton = Key.F, + }, + + RightJoycon = new RightJoyconCommonConfig<Key> + { + ButtonA = Key.Z, + ButtonB = Key.X, + ButtonX = Key.C, + ButtonY = Key.V, + ButtonPlus = Key.Plus, + ButtonR = Key.U, + ButtonZr = Key.O, + ButtonSl = Key.Unbound, + ButtonSr = Key.Unbound + }, + + RightJoyconStick = new JoyconConfigKeyboardStick<Key> + { + StickUp = Key.I, + StickDown = Key.K, + StickLeft = Key.J, + StickRight = Key.L, + StickButton = Key.H, + } + } + }; + + configurationFileUpdated = true; + } Graphics.ResScale.Value = configurationFileFormat.ResScale; Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom; @@ -880,7 +853,12 @@ namespace Ryujinx.Configuration Ui.StartFullscreen.Value = configurationFileFormat.StartFullscreen; Hid.EnableKeyboard.Value = configurationFileFormat.EnableKeyboard; Hid.Hotkeys.Value = configurationFileFormat.Hotkeys; - Hid.InputConfig.Value = inputConfig; + Hid.InputConfig.Value = configurationFileFormat.InputConfig; + + if (Hid.InputConfig.Value == null) + { + Hid.InputConfig.Value = new List<InputConfig>(); + } if (configurationFileUpdated) { diff --git a/Ryujinx.Common/Configuration/Hid/Controller/GamepadInputId.cs b/Ryujinx.Common/Configuration/Hid/Controller/GamepadInputId.cs new file mode 100644 index 00000000..cae65fc9 --- /dev/null +++ b/Ryujinx.Common/Configuration/Hid/Controller/GamepadInputId.cs @@ -0,0 +1,54 @@ +namespace Ryujinx.Common.Configuration.Hid.Controller +{ + public enum GamepadInputId : byte + { + Unbound, + A, + B, + X, + Y, + LeftStick, + RightStick, + LeftShoulder, + RightShoulder, + + // Likely axis + LeftTrigger, + // Likely axis + RightTrigger, + + DpadUp, + DpadDown, + DpadLeft, + DpadRight, + + // Special buttons + + Minus, + Plus, + + Back = Minus, + Start = Plus, + + Guide, + Misc1, + + // Xbox Elite paddle + Paddle1, + Paddle2, + Paddle3, + Paddle4, + + // PS5 touchpad button + Touchpad, + + // Virtual buttons for single joycon + SingleLeftTrigger0, + SingleRightTrigger0, + + SingleLeftTrigger1, + SingleRightTrigger1, + + Count + } +} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/GenericControllerInputConfig.cs b/Ryujinx.Common/Configuration/Hid/Controller/GenericControllerInputConfig.cs new file mode 100644 index 00000000..e3423bb5 --- /dev/null +++ b/Ryujinx.Common/Configuration/Hid/Controller/GenericControllerInputConfig.cs @@ -0,0 +1,37 @@ +using Ryujinx.Common.Configuration.Hid.Controller.Motion; + +namespace Ryujinx.Common.Configuration.Hid.Controller +{ + public class GenericControllerInputConfig<Button, Stick> : GenericInputConfigurationCommon<Button> where Button : unmanaged where Stick : unmanaged + { + /// <summary> + /// Left JoyCon Controller Stick Bindings + /// </summary> + public JoyconConfigControllerStick<Button, Stick> LeftJoyconStick { get; set; } + + /// <summary> + /// Right JoyCon Controller Stick Bindings + /// </summary> + public JoyconConfigControllerStick<Button, Stick> RightJoyconStick { get; set; } + + /// <summary> + /// Controller Left Analog Stick Deadzone + /// </summary> + public float DeadzoneLeft { get; set; } + + /// <summary> + /// Controller Right Analog Stick Deadzone + /// </summary> + public float DeadzoneRight { get; set; } + + /// <summary> + /// Controller Trigger Threshold + /// </summary> + public float TriggerThreshold { get; set; } + + /// <summary> + /// Controller Motion Settings + /// </summary> + public MotionConfigController Motion { get; set; } + } +} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/JoyconConfigControllerStick.cs b/Ryujinx.Common/Configuration/Hid/Controller/JoyconConfigControllerStick.cs new file mode 100644 index 00000000..0a9ca9dd --- /dev/null +++ b/Ryujinx.Common/Configuration/Hid/Controller/JoyconConfigControllerStick.cs @@ -0,0 +1,10 @@ +namespace Ryujinx.Common.Configuration.Hid.Controller +{ + public class JoyconConfigControllerStick<Button, Stick> where Button: unmanaged where Stick: unmanaged + { + public Stick Joystick { get; set; } + public bool InvertStickX { get; set; } + public bool InvertStickY { get; set; } + public Button StickButton { get; set; } + } +} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/Motion/CemuHookMotionConfigController.cs b/Ryujinx.Common/Configuration/Hid/Controller/Motion/CemuHookMotionConfigController.cs new file mode 100644 index 00000000..2a5a73ff --- /dev/null +++ b/Ryujinx.Common/Configuration/Hid/Controller/Motion/CemuHookMotionConfigController.cs @@ -0,0 +1,30 @@ +namespace Ryujinx.Common.Configuration.Hid.Controller.Motion +{ + public class CemuHookMotionConfigController : MotionConfigController + { + /// <summary> + /// Motion Controller Slot + /// </summary> + public int Slot { get; set; } + + /// <summary> + /// Motion Controller Alternative Slot, for RightJoyCon in Pair mode + /// </summary> + public int AltSlot { get; set; } + + /// <summary> + /// Mirror motion input in Pair mode + /// </summary> + public bool MirrorInput { get; set; } + + /// <summary> + /// Host address of the DSU Server + /// </summary> + public string DsuServerHost { get; set; } + + /// <summary> + /// Port of the DSU Server + /// </summary> + public int DsuServerPort { get; set; } + } +} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/Motion/JsonMotionConfigControllerConverter.cs b/Ryujinx.Common/Configuration/Hid/Controller/Motion/JsonMotionConfigControllerConverter.cs new file mode 100644 index 00000000..d1c2e4e8 --- /dev/null +++ b/Ryujinx.Common/Configuration/Hid/Controller/Motion/JsonMotionConfigControllerConverter.cs @@ -0,0 +1,76 @@ +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Ryujinx.Common.Configuration.Hid.Controller.Motion +{ + class JsonMotionConfigControllerConverter : JsonConverter<MotionConfigController> + { + private static MotionInputBackendType GetMotionInputBackendType(ref Utf8JsonReader reader) + { + // Temporary reader to get the backend type + Utf8JsonReader tempReader = reader; + + MotionInputBackendType result = MotionInputBackendType.Invalid; + + while (tempReader.Read()) + { + // NOTE: We scan all properties ignoring the depth entirely on purpose. + // The reason behind this is that we cannot track in a reliable way the depth of the object because Utf8JsonReader never emit the first TokenType == StartObject if the json start with an object. + // As such, this code will try to parse very field named "motion_backend" to the correct enum. + if (tempReader.TokenType == JsonTokenType.PropertyName) + { + string propertyName = tempReader.GetString(); + + if (propertyName.Equals("motion_backend")) + { + tempReader.Read(); + + if (tempReader.TokenType == JsonTokenType.String) + { + string backendTypeRaw = tempReader.GetString(); + + if (!Enum.TryParse(backendTypeRaw, out result)) + { + result = MotionInputBackendType.Invalid; + } + else + { + break; + } + } + } + } + } + + return result; + } + + public override MotionConfigController Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + MotionInputBackendType motionBackendType = GetMotionInputBackendType(ref reader); + + return motionBackendType switch + { + MotionInputBackendType.GamepadDriver => (MotionConfigController)JsonSerializer.Deserialize(ref reader, typeof(StandardMotionConfigController), options), + MotionInputBackendType.CemuHook => (MotionConfigController)JsonSerializer.Deserialize(ref reader, typeof(CemuHookMotionConfigController), options), + _ => throw new InvalidOperationException($"Unknown backend type {motionBackendType}"), + }; + } + + public override void Write(Utf8JsonWriter writer, MotionConfigController value, JsonSerializerOptions options) + { + switch (value.MotionBackend) + { + case MotionInputBackendType.GamepadDriver: + JsonSerializer.Serialize(writer, value as StandardMotionConfigController, options); + break; + case MotionInputBackendType.CemuHook: + JsonSerializer.Serialize(writer, value as CemuHookMotionConfigController, options); + break; + default: + throw new ArgumentException($"Unknown motion backend type {value.MotionBackend}"); + } + } + } +} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigController.cs b/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigController.cs new file mode 100644 index 00000000..832aae0d --- /dev/null +++ b/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigController.cs @@ -0,0 +1,22 @@ +namespace Ryujinx.Common.Configuration.Hid.Controller.Motion +{ + public class MotionConfigController + { + public MotionInputBackendType MotionBackend { get; set; } + + /// <summary> + /// Gyro Sensitivity + /// </summary> + public int Sensitivity { get; set; } + + /// <summary> + /// Gyro Deadzone + /// </summary> + public double GyroDeadzone { get; set; } + + /// <summary> + /// Enable Motion Controls + /// </summary> + public bool EnableMotion { get; set; } + } +} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionInputBackendType.cs b/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionInputBackendType.cs new file mode 100644 index 00000000..45d654ed --- /dev/null +++ b/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionInputBackendType.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.Common.Configuration.Hid.Controller.Motion +{ + public enum MotionInputBackendType : byte + { + Invalid, + GamepadDriver, + CemuHook + } +} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/Motion/StandardMotionConfigController.cs b/Ryujinx.Common/Configuration/Hid/Controller/Motion/StandardMotionConfigController.cs new file mode 100644 index 00000000..df925444 --- /dev/null +++ b/Ryujinx.Common/Configuration/Hid/Controller/Motion/StandardMotionConfigController.cs @@ -0,0 +1,4 @@ +namespace Ryujinx.Common.Configuration.Hid.Controller.Motion +{ + public class StandardMotionConfigController : MotionConfigController { } +} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/StandardControllerInputConfig.cs b/Ryujinx.Common/Configuration/Hid/Controller/StandardControllerInputConfig.cs new file mode 100644 index 00000000..4154a42b --- /dev/null +++ b/Ryujinx.Common/Configuration/Hid/Controller/StandardControllerInputConfig.cs @@ -0,0 +1,4 @@ +namespace Ryujinx.Common.Configuration.Hid.Controller +{ + public class StandardControllerInputConfig : GenericControllerInputConfig<GamepadInputId, StickInputId> { } +} diff --git a/Ryujinx.Common/Configuration/Hid/Controller/StickInputId.cs b/Ryujinx.Common/Configuration/Hid/Controller/StickInputId.cs new file mode 100644 index 00000000..87945a75 --- /dev/null +++ b/Ryujinx.Common/Configuration/Hid/Controller/StickInputId.cs @@ -0,0 +1,11 @@ +namespace Ryujinx.Common.Configuration.Hid.Controller +{ + public enum StickInputId : byte + { + Unbound, + Left, + Right, + + Count + } +} diff --git a/Ryujinx.Common/Configuration/Hid/ControllerConfig.cs b/Ryujinx.Common/Configuration/Hid/ControllerConfig.cs deleted file mode 100644 index 3e414055..00000000 --- a/Ryujinx.Common/Configuration/Hid/ControllerConfig.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace Ryujinx.Common.Configuration.Hid -{ - public class ControllerConfig : InputConfig - { - /// <summary> - /// Controller Left Analog Stick Deadzone - /// </summary> - public float DeadzoneLeft { get; set; } - - /// <summary> - /// Controller Right Analog Stick Deadzone - /// </summary> - public float DeadzoneRight { get; set; } - - /// <summary> - /// Controller Trigger Threshold - /// </summary> - public float TriggerThreshold { get; set; } - - /// <summary> - /// Left JoyCon Controller Bindings - /// </summary> - public NpadControllerLeft LeftJoycon { get; set; } - - /// <summary> - /// Right JoyCon Controller Bindings - /// </summary> - public NpadControllerRight RightJoycon { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/Hid/ControllerInputId.cs b/Ryujinx.Common/Configuration/Hid/ControllerInputId.cs deleted file mode 100644 index 606a1b0c..00000000 --- a/Ryujinx.Common/Configuration/Hid/ControllerInputId.cs +++ /dev/null @@ -1,46 +0,0 @@ -namespace Ryujinx.Common.Configuration.Hid -{ - public enum ControllerInputId - { - Button0, - Button1, - Button2, - Button3, - Button4, - Button5, - Button6, - Button7, - Button8, - Button9, - Button10, - Button11, - Button12, - Button13, - Button14, - Button15, - Button16, - Button17, - Button18, - Button19, - Button20, - Axis0, - Axis1, - Axis2, - Axis3, - Axis4, - Axis5, - Hat0Up, - Hat0Down, - Hat0Left, - Hat0Right, - Hat1Up, - Hat1Down, - Hat1Left, - Hat1Right, - Hat2Up, - Hat2Down, - Hat2Left, - Hat2Right, - Unbound - } -} diff --git a/Ryujinx.Common/Configuration/Hid/GenericInputConfigurationCommon.cs b/Ryujinx.Common/Configuration/Hid/GenericInputConfigurationCommon.cs new file mode 100644 index 00000000..3d43817e --- /dev/null +++ b/Ryujinx.Common/Configuration/Hid/GenericInputConfigurationCommon.cs @@ -0,0 +1,15 @@ +namespace Ryujinx.Common.Configuration.Hid +{ + public class GenericInputConfigurationCommon<Button> : InputConfig where Button : unmanaged + { + /// <summary> + /// Left JoyCon Controller Bindings + /// </summary> + public LeftJoyconCommonConfig<Button> LeftJoycon { get; set; } + + /// <summary> + /// Right JoyCon Controller Bindings + /// </summary> + public RightJoyconCommonConfig<Button> RightJoycon { get; set; } + } +} diff --git a/Ryujinx.Common/Configuration/Hid/InputBackendType.cs b/Ryujinx.Common/Configuration/Hid/InputBackendType.cs new file mode 100644 index 00000000..9e944f9e --- /dev/null +++ b/Ryujinx.Common/Configuration/Hid/InputBackendType.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.Common.Configuration.Hid +{ + public enum InputBackendType + { + Invalid, + WindowKeyboard, + GamepadSDL2, + } +} diff --git a/Ryujinx.Common/Configuration/Hid/InputConfig.cs b/Ryujinx.Common/Configuration/Hid/InputConfig.cs index 7ccb989b..d204eba4 100644 --- a/Ryujinx.Common/Configuration/Hid/InputConfig.cs +++ b/Ryujinx.Common/Configuration/Hid/InputConfig.cs @@ -1,60 +1,29 @@ -namespace Ryujinx.Common.Configuration.Hid +namespace Ryujinx.Common.Configuration.Hid { public class InputConfig { /// <summary> - /// Controller Device Index + /// The current version of the input file format /// </summary> - public int Index { get; set; } + public const int CurrentVersion = 1; - /// <summary> - /// Controller's Type - /// </summary> - public ControllerType ControllerType { get; set; } + public int Version { get; set; } - /// <summary> - /// Player's Index for the controller - /// </summary> - public PlayerIndex PlayerIndex { get; set; } - - /// <summary> - /// Motion Controller Slot - /// </summary> - public int Slot { get; set; } - - /// <summary> - /// Motion Controller Alternative Slot, for RightJoyCon in Pair mode - /// </summary> - public int AltSlot { get; set; } + public InputBackendType Backend { get; set; } /// <summary> - /// Mirror motion input in Pair mode + /// Controller id /// </summary> - public bool MirrorInput { get; set; } + public string Id { get; set; } /// <summary> - /// Host address of the DSU Server - /// </summary> - public string DsuServerHost { get; set; } - - /// <summary> - /// Port of the DSU Server - /// </summary> - public int DsuServerPort { get; set; } - - /// <summary> - /// Gyro Sensitivity + /// Controller's Type /// </summary> - public int Sensitivity { get; set; } + public ControllerType ControllerType { get; set; } /// <summary> - /// Gyro Deadzone - /// </summary> - public double GyroDeadzone { get; set; } - - /// <summary> - /// Enable Motion Controls + /// Player's Index for the controller /// </summary> - public bool EnableMotion { get; set; } + public PlayerIndex PlayerIndex { get; set; } } -}
\ No newline at end of file +} diff --git a/Ryujinx.Common/Configuration/Hid/JsonInputConfigConverter.cs b/Ryujinx.Common/Configuration/Hid/JsonInputConfigConverter.cs new file mode 100644 index 00000000..7223ad45 --- /dev/null +++ b/Ryujinx.Common/Configuration/Hid/JsonInputConfigConverter.cs @@ -0,0 +1,78 @@ +using Ryujinx.Common.Configuration.Hid.Controller; +using Ryujinx.Common.Configuration.Hid.Keyboard; +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Ryujinx.Common.Configuration.Hid +{ + class JsonInputConfigConverter : JsonConverter<InputConfig> + { + private static InputBackendType GetInputBackendType(ref Utf8JsonReader reader) + { + // Temporary reader to get the backend type + Utf8JsonReader tempReader = reader; + + InputBackendType result = InputBackendType.Invalid; + + while (tempReader.Read()) + { + // NOTE: We scan all properties ignoring the depth entirely on purpose. + // The reason behind this is that we cannot track in a reliable way the depth of the object because Utf8JsonReader never emit the first TokenType == StartObject if the json start with an object. + // As such, this code will try to parse very field named "backend" to the correct enum. + if (tempReader.TokenType == JsonTokenType.PropertyName) + { + string propertyName = tempReader.GetString(); + + if (propertyName.Equals("backend")) + { + tempReader.Read(); + + if (tempReader.TokenType == JsonTokenType.String) + { + string backendTypeRaw = tempReader.GetString(); + + if (!Enum.TryParse(backendTypeRaw, out result)) + { + result = InputBackendType.Invalid; + } + else + { + break; + } + } + } + } + } + + return result; + } + + public override InputConfig Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + InputBackendType backendType = GetInputBackendType(ref reader); + + return backendType switch + { + InputBackendType.WindowKeyboard => (InputConfig)JsonSerializer.Deserialize(ref reader, typeof(StandardKeyboardInputConfig), options), + InputBackendType.GamepadSDL2 => (InputConfig)JsonSerializer.Deserialize(ref reader, typeof(StandardControllerInputConfig), options), + _ => throw new InvalidOperationException($"Unknown backend type {backendType}"), + }; + } + + public override void Write(Utf8JsonWriter writer, InputConfig value, JsonSerializerOptions options) + { + switch (value.Backend) + { + case InputBackendType.WindowKeyboard: + JsonSerializer.Serialize(writer, value as StandardKeyboardInputConfig, options); + break; + case InputBackendType.GamepadSDL2: + JsonSerializer.Serialize(writer, value as StandardControllerInputConfig, options); + break; + default: + throw new ArgumentException($"Unknown backend type {value.Backend}"); + } + } + } +} diff --git a/Ryujinx.Common/Configuration/Hid/Key.cs b/Ryujinx.Common/Configuration/Hid/Key.cs index 67177eec..194843a3 100644 --- a/Ryujinx.Common/Configuration/Hid/Key.cs +++ b/Ryujinx.Common/Configuration/Hid/Key.cs @@ -1,154 +1,139 @@ -namespace Ryujinx.Configuration.Hid +namespace Ryujinx.Common.Configuration.Hid { public enum Key { - Unknown = 0, - ShiftLeft = 1, - LShift = 1, - ShiftRight = 2, - RShift = 2, - ControlLeft = 3, - LControl = 3, - ControlRight = 4, - RControl = 4, - AltLeft = 5, - LAlt = 5, - AltRight = 6, - RAlt = 6, - WinLeft = 7, - LWin = 7, - WinRight = 8, - RWin = 8, - Menu = 9, - F1 = 10, - F2 = 11, - F3 = 12, - F4 = 13, - F5 = 14, - F6 = 15, - F7 = 16, - F8 = 17, - F9 = 18, - F10 = 19, - F11 = 20, - F12 = 21, - F13 = 22, - F14 = 23, - F15 = 24, - F16 = 25, - F17 = 26, - F18 = 27, - F19 = 28, - F20 = 29, - F21 = 30, - F22 = 31, - F23 = 32, - F24 = 33, - F25 = 34, - F26 = 35, - F27 = 36, - F28 = 37, - F29 = 38, - F30 = 39, - F31 = 40, - F32 = 41, - F33 = 42, - F34 = 43, - F35 = 44, - Up = 45, - Down = 46, - Left = 47, - Right = 48, - Enter = 49, - Escape = 50, - Space = 51, - Tab = 52, - BackSpace = 53, - Back = 53, - Insert = 54, - Delete = 55, - PageUp = 56, - PageDown = 57, - Home = 58, - End = 59, - CapsLock = 60, - ScrollLock = 61, - PrintScreen = 62, - Pause = 63, - NumLock = 64, - Clear = 65, - Sleep = 66, - Keypad0 = 67, - Keypad1 = 68, - Keypad2 = 69, - Keypad3 = 70, - Keypad4 = 71, - Keypad5 = 72, - Keypad6 = 73, - Keypad7 = 74, - Keypad8 = 75, - Keypad9 = 76, - KeypadDivide = 77, - KeypadMultiply = 78, - KeypadSubtract = 79, - KeypadMinus = 79, - KeypadAdd = 80, - KeypadPlus = 80, - KeypadDecimal = 81, - KeypadPeriod = 81, - KeypadEnter = 82, - A = 83, - B = 84, - C = 85, - D = 86, - E = 87, - F = 88, - G = 89, - H = 90, - I = 91, - J = 92, - K = 93, - L = 94, - M = 95, - N = 96, - O = 97, - P = 98, - Q = 99, - R = 100, - S = 101, - T = 102, - U = 103, - V = 104, - W = 105, - X = 106, - Y = 107, - Z = 108, - Number0 = 109, - Number1 = 110, - Number2 = 111, - Number3 = 112, - Number4 = 113, - Number5 = 114, - Number6 = 115, - Number7 = 116, - Number8 = 117, - Number9 = 118, - Tilde = 119, - Grave = 119, - Minus = 120, - Plus = 121, - BracketLeft = 122, - LBracket = 122, - BracketRight = 123, - RBracket = 123, - Semicolon = 124, - Quote = 125, - Comma = 126, - Period = 127, - Slash = 128, - BackSlash = 129, - NonUSBackSlash = 130, - LastKey = 131, - Unbound + Unknown, + ShiftLeft, + ShiftRight, + ControlLeft, + ControlRight, + AltLeft, + AltRight, + WinLeft, + WinRight, + Menu, + F1, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12, + F13, + F14, + F15, + F16, + F17, + F18, + F19, + F20, + F21, + F22, + F23, + F24, + F25, + F26, + F27, + F28, + F29, + F30, + F31, + F32, + F33, + F34, + F35, + Up, + Down, + Left, + Right, + Enter, + Escape, + Space, + Tab, + BackSpace, + Insert, + Delete, + PageUp, + PageDown, + Home, + End, + CapsLock, + ScrollLock, + PrintScreen, + Pause, + NumLock, + Clear, + Keypad0, + Keypad1, + Keypad2, + Keypad3, + Keypad4, + Keypad5, + Keypad6, + Keypad7, + Keypad8, + Keypad9, + KeypadDivide, + KeypadMultiply, + KeypadSubtract, + KeypadAdd, + KeypadDecimal, + KeypadEnter, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + T, + U, + V, + W, + X, + Y, + Z, + Number0, + Number1, + Number2, + Number3, + Number4, + Number5, + Number6, + Number7, + Number8, + Number9, + Tilde, + Grave, + Minus, + Plus, + BracketLeft, + BracketRight, + Semicolon, + Quote, + Comma, + Period, + Slash, + BackSlash, + Unbound, + + Count } } diff --git a/Ryujinx.Common/Configuration/Hid/Keyboard/GenericKeyboardInputConfig.cs b/Ryujinx.Common/Configuration/Hid/Keyboard/GenericKeyboardInputConfig.cs new file mode 100644 index 00000000..b6c82c93 --- /dev/null +++ b/Ryujinx.Common/Configuration/Hid/Keyboard/GenericKeyboardInputConfig.cs @@ -0,0 +1,15 @@ +namespace Ryujinx.Common.Configuration.Hid.Keyboard +{ + public class GenericKeyboardInputConfig<Key> : GenericInputConfigurationCommon<Key> where Key : unmanaged + { + /// <summary> + /// Left JoyCon Controller Stick Bindings + /// </summary> + public JoyconConfigKeyboardStick<Key> LeftJoyconStick { get; set; } + + /// <summary> + /// Right JoyCon Controller Stick Bindings + /// </summary> + public JoyconConfigKeyboardStick<Key> RightJoyconStick { get; set; } + } +} diff --git a/Ryujinx.Common/Configuration/Hid/Keyboard/JoyconConfigKeyboardStick.cs b/Ryujinx.Common/Configuration/Hid/Keyboard/JoyconConfigKeyboardStick.cs new file mode 100644 index 00000000..cadc17e8 --- /dev/null +++ b/Ryujinx.Common/Configuration/Hid/Keyboard/JoyconConfigKeyboardStick.cs @@ -0,0 +1,11 @@ +namespace Ryujinx.Common.Configuration.Hid.Keyboard +{ + public class JoyconConfigKeyboardStick<Key> where Key: unmanaged + { + public Key StickUp { get; set; } + public Key StickDown { get; set; } + public Key StickLeft { get; set; } + public Key StickRight { get; set; } + public Key StickButton { get; set; } + } +} diff --git a/Ryujinx.Common/Configuration/Hid/Keyboard/StandardKeyboardInputConfig.cs b/Ryujinx.Common/Configuration/Hid/Keyboard/StandardKeyboardInputConfig.cs new file mode 100644 index 00000000..054d777d --- /dev/null +++ b/Ryujinx.Common/Configuration/Hid/Keyboard/StandardKeyboardInputConfig.cs @@ -0,0 +1,4 @@ +namespace Ryujinx.Common.Configuration.Hid.Keyboard +{ + public class StandardKeyboardInputConfig : GenericKeyboardInputConfig<Key> { } +} diff --git a/Ryujinx.Common/Configuration/Hid/KeyboardConfig.cs b/Ryujinx.Common/Configuration/Hid/KeyboardConfig.cs deleted file mode 100644 index 4e217ae5..00000000 --- a/Ryujinx.Common/Configuration/Hid/KeyboardConfig.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Ryujinx.Common.Configuration.Hid -{ - public class KeyboardConfig : InputConfig - { - // DO NOT MODIFY - public const uint AllKeyboardsIndex = 0; - - /// <summary> - /// Left JoyCon Keyboard Bindings - /// </summary> - public NpadKeyboardLeft LeftJoycon { get; set; } - - /// <summary> - /// Right JoyCon Keyboard Bindings - /// </summary> - public NpadKeyboardRight RightJoycon { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs b/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs index 19cc0487..8e9f168d 100644 --- a/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs +++ b/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs @@ -1,6 +1,4 @@ -using Ryujinx.Configuration.Hid; - -namespace Ryujinx.Common.Configuration.Hid +namespace Ryujinx.Common.Configuration.Hid { public struct KeyboardHotkeys { diff --git a/Ryujinx.Common/Configuration/Hid/LeftJoyconCommonConfig.cs b/Ryujinx.Common/Configuration/Hid/LeftJoyconCommonConfig.cs new file mode 100644 index 00000000..a57240c4 --- /dev/null +++ b/Ryujinx.Common/Configuration/Hid/LeftJoyconCommonConfig.cs @@ -0,0 +1,15 @@ +namespace Ryujinx.Common.Configuration.Hid +{ + public class LeftJoyconCommonConfig<Button> + { + public Button ButtonMinus { get; set; } + public Button ButtonL { get; set; } + public Button ButtonZl { get; set; } + public Button ButtonSl { get; set; } + public Button ButtonSr { get; set; } + public Button DpadUp { get; set; } + public Button DpadDown { get; set; } + public Button DpadLeft { get; set; } + public Button DpadRight { get; set; } + } +} diff --git a/Ryujinx.Common/Configuration/Hid/NpadControllerLeft.cs b/Ryujinx.Common/Configuration/Hid/NpadControllerLeft.cs deleted file mode 100644 index 00816e56..00000000 --- a/Ryujinx.Common/Configuration/Hid/NpadControllerLeft.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Ryujinx.Common.Configuration.Hid -{ - public struct NpadControllerLeft - { - public ControllerInputId StickX { get; set; } - public bool InvertStickX { get; set; } - public ControllerInputId StickY { get; set; } - public bool InvertStickY { get; set; } - public ControllerInputId StickButton { get; set; } - public ControllerInputId ButtonMinus { get; set; } - public ControllerInputId ButtonL { get; set; } - public ControllerInputId ButtonZl { get; set; } - public ControllerInputId ButtonSl { get; set; } - public ControllerInputId ButtonSr { get; set; } - public ControllerInputId DPadUp { get; set; } - public ControllerInputId DPadDown { get; set; } - public ControllerInputId DPadLeft { get; set; } - public ControllerInputId DPadRight { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/Hid/NpadControllerRight.cs b/Ryujinx.Common/Configuration/Hid/NpadControllerRight.cs deleted file mode 100644 index b7b289cc..00000000 --- a/Ryujinx.Common/Configuration/Hid/NpadControllerRight.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Ryujinx.Common.Configuration.Hid -{ - public struct NpadControllerRight - { - public ControllerInputId StickX { get; set; } - public bool InvertStickX { get; set; } - public ControllerInputId StickY { get; set; } - public bool InvertStickY { get; set; } - public ControllerInputId StickButton { get; set; } - public ControllerInputId ButtonA { get; set; } - public ControllerInputId ButtonB { get; set; } - public ControllerInputId ButtonX { get; set; } - public ControllerInputId ButtonY { get; set; } - public ControllerInputId ButtonPlus { get; set; } - public ControllerInputId ButtonR { get; set; } - public ControllerInputId ButtonZr { get; set; } - public ControllerInputId ButtonSl { get; set; } - public ControllerInputId ButtonSr { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/Hid/NpadKeyboardLeft.cs b/Ryujinx.Common/Configuration/Hid/NpadKeyboardLeft.cs deleted file mode 100644 index 6b78f5b6..00000000 --- a/Ryujinx.Common/Configuration/Hid/NpadKeyboardLeft.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Ryujinx.Configuration.Hid; - -namespace Ryujinx.Common.Configuration.Hid -{ - public struct NpadKeyboardLeft - { - public Key StickUp { get; set; } - public Key StickDown { get; set; } - public Key StickLeft { get; set; } - public Key StickRight { get; set; } - public Key StickButton { get; set; } - public Key DPadUp { get; set; } - public Key DPadDown { get; set; } - public Key DPadLeft { get; set; } - public Key DPadRight { get; set; } - public Key ButtonMinus { get; set; } - public Key ButtonL { get; set; } - public Key ButtonZl { get; set; } - public Key ButtonSl { get; set; } - public Key ButtonSr { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/Hid/NpadKeyboardRight.cs b/Ryujinx.Common/Configuration/Hid/NpadKeyboardRight.cs deleted file mode 100644 index e2109902..00000000 --- a/Ryujinx.Common/Configuration/Hid/NpadKeyboardRight.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Ryujinx.Configuration.Hid; - -namespace Ryujinx.Common.Configuration.Hid -{ - public struct NpadKeyboardRight - { - public Key StickUp { get; set; } - public Key StickDown { get; set; } - public Key StickLeft { get; set; } - public Key StickRight { get; set; } - public Key StickButton { get; set; } - public Key ButtonA { get; set; } - public Key ButtonB { get; set; } - public Key ButtonX { get; set; } - public Key ButtonY { get; set; } - public Key ButtonPlus { get; set; } - public Key ButtonR { get; set; } - public Key ButtonZr { get; set; } - public Key ButtonSl { get; set; } - public Key ButtonSr { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Common/Configuration/Hid/RightJoyconCommonConfig.cs b/Ryujinx.Common/Configuration/Hid/RightJoyconCommonConfig.cs new file mode 100644 index 00000000..ca2d0176 --- /dev/null +++ b/Ryujinx.Common/Configuration/Hid/RightJoyconCommonConfig.cs @@ -0,0 +1,15 @@ +namespace Ryujinx.Common.Configuration.Hid +{ + public class RightJoyconCommonConfig<Button> + { + public Button ButtonPlus { get; set; } + public Button ButtonR { get; set; } + public Button ButtonZr { get; set; } + public Button ButtonSl { get; set; } + public Button ButtonSr { get; set; } + public Button ButtonX { get; set; } + public Button ButtonB { get; set; } + public Button ButtonY { get; set; } + public Button ButtonA { get; set; } + } +}
\ No newline at end of file |
