From 15ece494b1defe6453f591938a544d9df1adcd39 Mon Sep 17 00:00:00 2001 From: John Clemis Date: Fri, 10 Aug 2018 00:21:43 -0500 Subject: [PATCH] Initial Multiplayer Support --- CONFIG.md | 64 +++-- README.md | 14 +- Ryujinx.HLE/Hid/Hid.cs | 135 ++++++++++- Ryujinx.HLE/Hid/HidEmulatedDevices.cs | 25 ++ Ryujinx/Config.cs | 93 +++++-- Ryujinx/Ryujinx.conf | 80 +++--- Ryujinx/Ui/GLScreen.cs | 334 +++++++++++++++++++++++--- 7 files changed, 620 insertions(+), 125 deletions(-) create mode 100644 Ryujinx.HLE/Hid/HidEmulatedDevices.cs diff --git a/CONFIG.md b/CONFIG.md index b5de9fa6d..6978f95c6 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -46,6 +46,23 @@ Whether or not to enable Controller Support. +- `Handheld_Device` *(String)* + + The specific Device to be the Emulated Handheld Device. + +- `Player(1-8)_Device` *(String)* + + The specific Device to be the Emulated Player(1-8) Device. + +- `PlayerUnknown_Device` *(String)* + + The specific Device to be the Emulated PlayerUnknown Device. (This should basically always be None) + +- Valid Emulated Device Mappings + - None = Disabled + - Keyboard = The Keyboard Device + - GamePad_X = X GamePad Configuration + - `Controls_Left_JoyConKeyboard_XX` *(int)* ``` Controls_Left_JoyConKeyboard_Stick_Up (int) @@ -64,7 +81,7 @@ Keys of the Left Emulated Joycon, the values depend of the [OpenTK Enum Keys](https://github.com/opentk/opentk/blob/develop/src/OpenTK/Input/Key.cs). - OpenTK use a QWERTY layout, so pay attention if you use another Keyboard Layout. + OpenTK uses a QWERTY layout, so pay attention if you use another Keyboard Layout. Ex: `Controls_Left_JoyConKeyboard_Button_Minus = 52` > Tab key (All Layout). @@ -86,36 +103,39 @@ Keys of the right Emulated Joycon, the values depend of the [OpenTK Enum Keys](https://github.com/opentk/opentk/blob/develop/src/OpenTK/Input/Key.cs). - OpenTK use a QWERTY layout, so pay attention if you use another Keyboard Layout. + OpenTK uses a QWERTY layout, so pay attention if you use another Keyboard Layout. Ex: `Controls_Right_JoyConKeyboard_Button_A = 83` > A key (QWERTY Layout) / Q key (AZERTY Layout). -- `Controls_Left_JoyConController_XX` *(String)* +- `X_Controls_Left_JoyConController_XX` *(String)* ``` - Controls_Left_JoyConController_Stick (String) - Controls_Left_JoyConController_Stick_Button (String) - Controls_Left_JoyConController_DPad_Up (String) - Controls_Left_JoyConController_DPad_Down (String) - Controls_Left_JoyConController_DPad_Left (String) - Controls_Left_JoyConController_DPad_Right (String) - Controls_Left_JoyConController_Button_Minus (String) - Controls_Left_JoyConController_Button_L (String) - Controls_Left_JoyConController_Button_ZL (String) + X_Controls_Left_JoyConController_Stick (String) + X_Controls_Left_JoyConController_Stick_Button (String) + X_Controls_Left_JoyConController_DPad_Up (String) + X_Controls_Left_JoyConController_DPad_Down (String) + X_Controls_Left_JoyConController_DPad_Left (String) + X_Controls_Left_JoyConController_DPad_Right (String) + X_Controls_Left_JoyConController_Button_Minus (String) + X_Controls_Left_JoyConController_Button_L (String) + X_Controls_Left_JoyConController_Button_ZL (String) ``` -- `Controls_Right_JoyConController_XX` *(String)* +- `X_Controls_Right_JoyConController_XX` *(String)* ``` - Controls_Right_JoyConController_Stick (String) - Controls_Right_JoyConController_Stick_Button (String) - Controls_Right_JoyConController_Button_A (String) - Controls_Right_JoyConController_Button_B (String) - Controls_Right_JoyConController_Button_X (String) - Controls_Right_JoyConController_Button_Y (String) - Controls_Right_JoyConController_Button_Plus (String) - Controls_Right_JoyConController_Button_R (String) - Controls_Right_JoyConController_Button_ZR (String) + X_Controls_Right_JoyConController_Stick (String) + X_Controls_Right_JoyConController_Stick_Button (String) + X_Controls_Right_JoyConController_Button_A (String) + X_Controls_Right_JoyConController_Button_B (String) + X_Controls_Right_JoyConController_Button_X (String) + X_Controls_Right_JoyConController_Button_Y (String) + X_Controls_Right_JoyConController_Button_Plus (String) + X_Controls_Right_JoyConController_Button_R (String) + X_Controls_Right_JoyConController_Button_ZR (String) ``` + The "X" is the Controller Configuration Number, to add more configurations, copy the first configuration, then increment the Number "X" + change the Button Configuration as you wish. + - Valid Button Mappings - A = The A / Cross Button - B = The B / Circle Button diff --git a/README.md b/README.md index f6bac98c8..8353db858 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Experimental Switch emulator written in C# -Don't expect much from this. Some homebrew apps work, Puyo Puyo Tetris shows the intro logo (sometimes), and a handful of games boot / work; but that's about it for now. +Don't expect much from this. Some homebrew apps work, a handful of games boot / work; but that's about it for now. Contributions are always welcome. **Building** @@ -15,10 +15,10 @@ Or just drag'n'drop the *.NRO / *.NSO or the game folder on the executable if yo **Features** - - Audio is partially supported (glitched) on Windows but you need to install the OpenAL Core SDK. + - Audio is supported on Windows, but you need to install the OpenAL Core SDK. https://openal.org/downloads/OpenAL11CoreSDK.zip - - Keyboard Input is partially supported: + - Keyboard Input is supported: - Left Joycon: - Stick Up = W - Stick Down = S @@ -48,7 +48,7 @@ https://openal.org/downloads/OpenAL11CoreSDK.zip - ZR = O - For more information on how to configure these buttons see [CONFIG.md](CONFIG.md) - - Controller Input is partially supported: + - Controller Input is supported: - Left Joycon: - Analog Stick = Left Analog Stick - DPad Up = DPad Up @@ -69,7 +69,8 @@ https://openal.org/downloads/OpenAL11CoreSDK.zip - R = Right Shoulder Button - ZR = Right Trigger - For more information on how to configure these buttons see [CONFIG.md](CONFIG.md) - + - Multiple Players are supported. See [CONFIG.md](CONFIG.md) for more details. + - Config File: `Ryujinx.conf` should be present in executable folder. For more information [you can go here](CONFIG.md). @@ -95,9 +96,10 @@ Run `dotnet run -c Release -- path\to\game_exefs_and_romfs_folder` to run offici **Compatibility** -You can check out the compatibility list within the Wiki. Only a handful of games actually work. +You can check out the compatibility list within the Wiki. **Latest build** These builds are compiled automatically for each commit on the master branch. They may be unstable or might not work at all. The latest automatic build for Windows (64-bit) can be found on the [official website](https://ryujinx.org/#/Build). +However, for opening issues and testing, it is recommended to build the Master Branch as it is much more stable (Though still very experimental) diff --git a/Ryujinx.HLE/Hid/Hid.cs b/Ryujinx.HLE/Hid/Hid.cs index 43c040bb5..752117f8b 100644 --- a/Ryujinx.HLE/Hid/Hid.cs +++ b/Ryujinx.HLE/Hid/Hid.cs @@ -2,6 +2,7 @@ using Ryujinx.HLE.Logging; using Ryujinx.HLE.OsHle; using Ryujinx.HLE.OsHle.Handles; +using Ryujinx; using System; namespace Ryujinx.HLE.Input @@ -111,26 +112,148 @@ namespace Ryujinx.HLE.Input private void Init(AMemory Memory, long Position) { - InitializeJoyconPair( + if (HidEmulatedDevices.Devices.Handheld != -2) + { + InitializeJoyconPair( Memory, Position, + HidControllerId.CONTROLLER_HANDHELD, + HidControllerType.ControllerType_Handheld, JoyConColor.Body_Neon_Red, JoyConColor.Buttons_Neon_Red, JoyConColor.Body_Neon_Blue, JoyConColor.Buttons_Neon_Blue); + } + + if (HidEmulatedDevices.Devices.Player1 != -2) + { + InitializeJoyconPair( + Memory, + Position, + HidControllerId.CONTROLLER_PLAYER_1, + HidControllerType.ControllerType_JoyconPair, + JoyConColor.Body_Neon_Red, + JoyConColor.Buttons_Neon_Red, + JoyConColor.Body_Neon_Blue, + JoyConColor.Buttons_Neon_Blue); + } + + if (HidEmulatedDevices.Devices.Player2 != -2) + { + InitializeJoyconPair( + Memory, + Position, + HidControllerId.CONTROLLER_PLAYER_2, + HidControllerType.ControllerType_JoyconPair, + JoyConColor.Body_Neon_Red, + JoyConColor.Buttons_Neon_Red, + JoyConColor.Body_Neon_Blue, + JoyConColor.Buttons_Neon_Blue); + } + + if (HidEmulatedDevices.Devices.Player3 != -2) + { + InitializeJoyconPair( + Memory, + Position, + HidControllerId.CONTROLLER_PLAYER_3, + HidControllerType.ControllerType_JoyconPair, + JoyConColor.Body_Neon_Red, + JoyConColor.Buttons_Neon_Red, + JoyConColor.Body_Neon_Blue, + JoyConColor.Buttons_Neon_Blue); + } + + if (HidEmulatedDevices.Devices.Player4 != -2) + { + InitializeJoyconPair( + Memory, + Position, + HidControllerId.CONTROLLER_PLAYER_4, + HidControllerType.ControllerType_JoyconPair, + JoyConColor.Body_Neon_Red, + JoyConColor.Buttons_Neon_Red, + JoyConColor.Body_Neon_Blue, + JoyConColor.Buttons_Neon_Blue); + } + + if (HidEmulatedDevices.Devices.Player5 != -2) + { + InitializeJoyconPair( + Memory, + Position, + HidControllerId.CONTROLLER_PLAYER_5, + HidControllerType.ControllerType_JoyconPair, + JoyConColor.Body_Neon_Red, + JoyConColor.Buttons_Neon_Red, + JoyConColor.Body_Neon_Blue, + JoyConColor.Buttons_Neon_Blue); + } + + if (HidEmulatedDevices.Devices.Player6 != -2) + { + InitializeJoyconPair( + Memory, + Position, + HidControllerId.CONTROLLER_PLAYER_6, + HidControllerType.ControllerType_JoyconPair, + JoyConColor.Body_Neon_Red, + JoyConColor.Buttons_Neon_Red, + JoyConColor.Body_Neon_Blue, + JoyConColor.Buttons_Neon_Blue); + } + + if (HidEmulatedDevices.Devices.Player7 != -2) + { + InitializeJoyconPair( + Memory, + Position, + HidControllerId.CONTROLLER_PLAYER_7, + HidControllerType.ControllerType_JoyconPair, + JoyConColor.Body_Neon_Red, + JoyConColor.Buttons_Neon_Red, + JoyConColor.Body_Neon_Blue, + JoyConColor.Buttons_Neon_Blue); + } + + if (HidEmulatedDevices.Devices.Player8 != -2) + { + InitializeJoyconPair( + Memory, + Position, + HidControllerId.CONTROLLER_PLAYER_8, + HidControllerType.ControllerType_JoyconPair, + JoyConColor.Body_Neon_Red, + JoyConColor.Buttons_Neon_Red, + JoyConColor.Body_Neon_Blue, + JoyConColor.Buttons_Neon_Blue); + } + + if (HidEmulatedDevices.Devices.PlayerUnknown != -2) + { + InitializeJoyconPair( + Memory, + Position, + HidControllerId.CONTROLLER_UNKNOWN, + HidControllerType.ControllerType_JoyconPair, + JoyConColor.Body_Neon_Red, + JoyConColor.Buttons_Neon_Red, + JoyConColor.Body_Neon_Blue, + JoyConColor.Buttons_Neon_Blue); + } } private void InitializeJoyconPair( - AMemory Memory, - long Position, + AMemory Memory, + long Position, + HidControllerId ControllerId, + HidControllerType Type, JoyConColor LeftColorBody, JoyConColor LeftColorButtons, JoyConColor RightColorBody, JoyConColor RightColorButtons) { - long BaseControllerOffset = Position + HidControllersOffset + 8 * HidControllerSize; - - HidControllerType Type = HidControllerType.ControllerType_Handheld; + long BaseControllerOffset = Position + HidControllersOffset + (int)ControllerId * HidControllerSize; bool IsHalf = false; diff --git a/Ryujinx.HLE/Hid/HidEmulatedDevices.cs b/Ryujinx.HLE/Hid/HidEmulatedDevices.cs new file mode 100644 index 000000000..a3e67cf43 --- /dev/null +++ b/Ryujinx.HLE/Hid/HidEmulatedDevices.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ryujinx.HLE.Input +{ + public class HidEmulatedDevices + { + public struct EmulatedDevices + { + public int Handheld; + public int Player1; + public int Player2; + public int Player3; + public int Player4; + public int Player5; + public int Player6; + public int Player7; + public int Player8; + public int PlayerUnknown; + }; + + public static EmulatedDevices Devices; + } +} diff --git a/Ryujinx/Config.cs b/Ryujinx/Config.cs index 4ed35b3d7..2a9b516e7 100644 --- a/Ryujinx/Config.cs +++ b/Ryujinx/Config.cs @@ -1,5 +1,6 @@ using Ryujinx.UI.Input; using Ryujinx.HLE.Logging; +using Ryujinx.HLE.Input; using System; using System.Globalization; using System.Collections.Generic; @@ -11,8 +12,9 @@ namespace Ryujinx { public static class Config { - public static JoyConKeyboard JoyConKeyboard { get; private set; } - public static JoyConController JoyConController { get; private set; } + public static JoyConKeyboard JoyConKeyboard { get; private set; } + public static JoyConController[] JoyConControllers { get; private set; } + public static bool GamePadEnable { get; private set; } public static void Read(Logger Log) { @@ -34,6 +36,20 @@ namespace Ryujinx string[] FilteredLogClasses = Parser.Value("Logging_Filtered_Classes").Split(',', StringSplitOptions.RemoveEmptyEntries); + GamePadEnable = Boolean.Parse(Parser.Value("GamePad_Enable")); + + //Device Mappings + HidEmulatedDevices.Devices.Handheld = ToEmulatedDevice(Parser.Value("Handheld_Device")); // -2: None, -1: Keyboard, Everything Else: GamePad Index + HidEmulatedDevices.Devices.Player1 = ToEmulatedDevice(Parser.Value("Player1_Device")); + HidEmulatedDevices.Devices.Player2 = ToEmulatedDevice(Parser.Value("Player2_Device")); + HidEmulatedDevices.Devices.Player3 = ToEmulatedDevice(Parser.Value("Player3_Device")); + HidEmulatedDevices.Devices.Player4 = ToEmulatedDevice(Parser.Value("Player4_Device")); + HidEmulatedDevices.Devices.Player5 = ToEmulatedDevice(Parser.Value("Player5_Device")); + HidEmulatedDevices.Devices.Player6 = ToEmulatedDevice(Parser.Value("Player6_Device")); + HidEmulatedDevices.Devices.Player7 = ToEmulatedDevice(Parser.Value("Player7_Device")); + HidEmulatedDevices.Devices.Player8 = ToEmulatedDevice(Parser.Value("Player8_Device")); + HidEmulatedDevices.Devices.PlayerUnknown = ToEmulatedDevice(Parser.Value("PlayerUnknown_Device")); + //When the classes are specified on the list, we only //enable the classes that are on the list. //So, first disable everything, then enable @@ -94,38 +110,51 @@ namespace Ryujinx ButtonZR = Convert.ToInt16(Parser.Value("Controls_Right_JoyConKeyboard_Button_ZR")) }); - JoyConController = new JoyConController( - Convert.ToBoolean(Parser.Value("GamePad_Enable")), - Convert.ToInt32 (Parser.Value("GamePad_Index")), - (float)Convert.ToDouble (Parser.Value("GamePad_Deadzone"), CultureInfo.InvariantCulture), - (float)Convert.ToDouble (Parser.Value("GamePad_Trigger_Threshold"), CultureInfo.InvariantCulture), + List JoyConControllerList = new List(); + + //Populate the Controller List + for (int i = 0; i < 255; ++i) + { + if (Parser.Value(i + "_GamePad_Index") == null) break; + + JoyConController Controller = new JoyConController( + Convert.ToBoolean(GamePadEnable), + Convert.ToInt32 (Parser.Value(i + "_GamePad_Index")), + (float)Convert.ToDouble (Parser.Value(i + "_GamePad_Deadzone"), CultureInfo.InvariantCulture), + (float)Convert.ToDouble (Parser.Value(i + "_GamePad_Trigger_Threshold"), CultureInfo.InvariantCulture), new JoyConControllerLeft { - Stick = ToID(Parser.Value("Controls_Left_JoyConController_Stick")), - StickButton = ToID(Parser.Value("Controls_Left_JoyConController_Stick_Button")), - DPadUp = ToID(Parser.Value("Controls_Left_JoyConController_DPad_Up")), - DPadDown = ToID(Parser.Value("Controls_Left_JoyConController_DPad_Down")), - DPadLeft = ToID(Parser.Value("Controls_Left_JoyConController_DPad_Left")), - DPadRight = ToID(Parser.Value("Controls_Left_JoyConController_DPad_Right")), - ButtonMinus = ToID(Parser.Value("Controls_Left_JoyConController_Button_Minus")), - ButtonL = ToID(Parser.Value("Controls_Left_JoyConController_Button_L")), - ButtonZL = ToID(Parser.Value("Controls_Left_JoyConController_Button_ZL")) + Stick = ToID(Parser.Value(i + "_Controls_Left_JoyConController_Stick")), + StickButton = ToID(Parser.Value(i + "_Controls_Left_JoyConController_Stick_Button")), + DPadUp = ToID(Parser.Value(i + "_Controls_Left_JoyConController_DPad_Up")), + DPadDown = ToID(Parser.Value(i + "_Controls_Left_JoyConController_DPad_Down")), + DPadLeft = ToID(Parser.Value(i + "_Controls_Left_JoyConController_DPad_Left")), + DPadRight = ToID(Parser.Value(i + "_Controls_Left_JoyConController_DPad_Right")), + ButtonMinus = ToID(Parser.Value(i + "_Controls_Left_JoyConController_Button_Minus")), + ButtonL = ToID(Parser.Value(i + "_Controls_Left_JoyConController_Button_L")), + ButtonZL = ToID(Parser.Value(i + "_Controls_Left_JoyConController_Button_ZL")) }, new JoyConControllerRight { - Stick = ToID(Parser.Value("Controls_Right_JoyConController_Stick")), - StickButton = ToID(Parser.Value("Controls_Right_JoyConController_Stick_Button")), - ButtonA = ToID(Parser.Value("Controls_Right_JoyConController_Button_A")), - ButtonB = ToID(Parser.Value("Controls_Right_JoyConController_Button_B")), - ButtonX = ToID(Parser.Value("Controls_Right_JoyConController_Button_X")), - ButtonY = ToID(Parser.Value("Controls_Right_JoyConController_Button_Y")), - ButtonPlus = ToID(Parser.Value("Controls_Right_JoyConController_Button_Plus")), - ButtonR = ToID(Parser.Value("Controls_Right_JoyConController_Button_R")), - ButtonZR = ToID(Parser.Value("Controls_Right_JoyConController_Button_ZR")) + Stick = ToID(Parser.Value(i + "_Controls_Right_JoyConController_Stick")), + StickButton = ToID(Parser.Value(i + "_Controls_Right_JoyConController_Stick_Button")), + ButtonA = ToID(Parser.Value(i + "_Controls_Right_JoyConController_Button_A")), + ButtonB = ToID(Parser.Value(i + "_Controls_Right_JoyConController_Button_B")), + ButtonX = ToID(Parser.Value(i + "_Controls_Right_JoyConController_Button_X")), + ButtonY = ToID(Parser.Value(i + "_Controls_Right_JoyConController_Button_Y")), + ButtonPlus = ToID(Parser.Value(i + "_Controls_Right_JoyConController_Button_Plus")), + ButtonR = ToID(Parser.Value(i + "_Controls_Right_JoyConController_Button_R")), + ButtonZR = ToID(Parser.Value(i + "_Controls_Right_JoyConController_Button_ZR")) }); + + JoyConControllerList.Add(Controller); + } + + //Finally, convert that to a regular Array. + JoyConControllers = JoyConControllerList.ToArray(); } private static ControllerInputID ToID(string Key) @@ -156,6 +185,20 @@ namespace Ryujinx default: return ControllerInputID.Invalid; } } + + // -2: None, -1: Keyboard, Everything Else: GamePad Index + private static int ToEmulatedDevice(string Key) + { + switch (Key.ToUpper()) + { + case "NONE": return -2; + case "KEYBOARD": return -1; + } + + if (Key.ToUpper().StartsWith("GAMEPAD_")) return Int32.Parse(Key.Substring(Key.Length - 1)); + + return -2; + } } //https://stackoverflow.com/a/37772571 diff --git a/Ryujinx/Ryujinx.conf b/Ryujinx/Ryujinx.conf index 063bb2de4..fef59b0dd 100644 --- a/Ryujinx/Ryujinx.conf +++ b/Ryujinx/Ryujinx.conf @@ -22,18 +22,27 @@ Logging_Enable_Error = true #Filtered log classes, seperated by ", ", eg. `Logging_Filtered_Classes = Loader, ServiceFS` Logging_Filtered_Classes = -#Controller Device Index -GamePad_Index = 0 - -#Controller Analog Stick Deadzone -GamePad_Deadzone = 0.05 - -#The value of how pressed down each trigger has to be in order to register a button press -GamePad_Trigger_Threshold = 0.5 - #Whether or not to enable Controller support -GamePad_Enable = true +GamePad_Enable = false +#Device Mappings + +#Handheld Devices can not be mixed with any other players (Player 1, Player 2, etc.) +Handheld_Device = Keyboard + +Player1_Device = None +Player2_Device = None +Player3_Device = None +Player4_Device = None +Player5_Device = None +Player6_Device = None +Player7_Device = None +Player8_Device = None + +#This should always be None, as this is a Unknown Property with unknown side effects. +PlayerUnknown_Device = None + +#Keyboard Mappings #https://github.com/opentk/opentk/blob/develop/src/OpenTK/Input/Key.cs Controls_Left_JoyConKeyboard_Stick_Up = 105 Controls_Left_JoyConKeyboard_Stick_Down = 101 @@ -61,25 +70,38 @@ Controls_Right_JoyConKeyboard_Button_Plus = 121 Controls_Right_JoyConKeyboard_Button_R = 103 Controls_Right_JoyConKeyboard_Button_ZR = 97 -#Controller Controls +#Controller Mappings -Controls_Left_JoyConController_Stick_Button = LStick -Controls_Left_JoyConController_DPad_Up = DPadUp -Controls_Left_JoyConController_DPad_Down = DPadDown -Controls_Left_JoyConController_DPad_Left = DPadLeft -Controls_Left_JoyConController_DPad_Right = DPadRight -Controls_Left_JoyConController_Button_Minus = Back -Controls_Left_JoyConController_Button_L = LShoulder -Controls_Left_JoyConController_Button_ZL = LTrigger +#The left most Number ("0"_blah_blahblahblah) is which Controller Configuration the setting applies to. -Controls_Right_JoyConController_Stick_Button = RStick -Controls_Right_JoyConController_Button_A = B -Controls_Right_JoyConController_Button_B = A -Controls_Right_JoyConController_Button_X = Y -Controls_Right_JoyConController_Button_Y = X -Controls_Right_JoyConController_Button_Plus = Start -Controls_Right_JoyConController_Button_R = RShoulder -Controls_Right_JoyConController_Button_ZR = RTrigger +#Controller Configuration 0 -Controls_Left_JoyConController_Stick = LJoystick -Controls_Right_JoyConController_Stick = RJoystick \ No newline at end of file +#Controller Device Index +0_GamePad_Index = 0 + +#Controller Analog Stick Deadzone +0_GamePad_Deadzone = 0.05 + +#The value of how pressed down each trigger has to be in order to register a button press +0_GamePad_Trigger_Threshold = 0.5 + +0_Controls_Left_JoyConController_Stick_Button = LStick +0_Controls_Left_JoyConController_DPad_Up = DPadUp +0_Controls_Left_JoyConController_DPad_Down = DPadDown +0_Controls_Left_JoyConController_DPad_Left = DPadLeft +0_Controls_Left_JoyConController_DPad_Right = DPadRight +0_Controls_Left_JoyConController_Button_Minus = Back +0_Controls_Left_JoyConController_Button_L = LShoulder +0_Controls_Left_JoyConController_Button_ZL = LTrigger + +0_Controls_Right_JoyConController_Stick_Button = RStick +0_Controls_Right_JoyConController_Button_A = B +0_Controls_Right_JoyConController_Button_B = A +0_Controls_Right_JoyConController_Button_X = Y +0_Controls_Right_JoyConController_Button_Y = X +0_Controls_Right_JoyConController_Button_Plus = Start +0_Controls_Right_JoyConController_Button_R = RShoulder +0_Controls_Right_JoyConController_Button_ZR = RTrigger + +0_Controls_Left_JoyConController_Stick = LJoystick +0_Controls_Right_JoyConController_Stick = RJoystick \ No newline at end of file diff --git a/Ryujinx/Ui/GLScreen.cs b/Ryujinx/Ui/GLScreen.cs index dfc0b9a41..f9ead8ce9 100644 --- a/Ryujinx/Ui/GLScreen.cs +++ b/Ryujinx/Ui/GLScreen.cs @@ -129,51 +129,68 @@ namespace Ryujinx private new void UpdateFrame() { - HidControllerButtons CurrentButton = 0; - HidJoystickPosition LeftJoystick; - HidJoystickPosition RightJoystick; + HidControllerButtons CurrentButtonsKeyboard = new HidControllerButtons(); + HidControllerButtons[] CurrentButtonsGamePad = new HidControllerButtons[Config.JoyConControllers.Length]; + HidJoystickPosition LeftJoystickKeyboard; + HidJoystickPosition RightJoystickKeyboard; + HidJoystickPosition[] LeftJoystickGamePad = new HidJoystickPosition[Config.JoyConControllers.Length]; + HidJoystickPosition[] RightJoystickGamePad = new HidJoystickPosition[Config.JoyConControllers.Length]; - int LeftJoystickDX = 0; - int LeftJoystickDY = 0; - int RightJoystickDX = 0; - int RightJoystickDY = 0; + int LeftJoystickDXKeyboard = 0; + int LeftJoystickDYKeyboard = 0; + int RightJoystickDXKeyboard = 0; + int RightJoystickDYKeyboard = 0; + + int[] LeftJoystickDXGamePad = new int[Config.JoyConControllers.Length]; + int[] LeftJoystickDYGamePad = new int[Config.JoyConControllers.Length]; + int[] RightJoystickDXGamePad = new int[Config.JoyConControllers.Length]; + int[] RightJoystickDYGamePad = new int[Config.JoyConControllers.Length]; //Keyboard Input if (Keyboard.HasValue) { KeyboardState Keyboard = this.Keyboard.Value; - CurrentButton = Config.JoyConKeyboard.GetButtons(Keyboard); + CurrentButtonsKeyboard = Config.JoyConKeyboard.GetButtons(Keyboard); - (LeftJoystickDX, LeftJoystickDY) = Config.JoyConKeyboard.GetLeftStick(Keyboard); - - (RightJoystickDX, RightJoystickDY) = Config.JoyConKeyboard.GetRightStick(Keyboard); + (LeftJoystickDXKeyboard, LeftJoystickDYKeyboard) = Config.JoyConKeyboard.GetLeftStick(Keyboard); + (RightJoystickDXKeyboard, RightJoystickDYKeyboard) = Config.JoyConKeyboard.GetRightStick(Keyboard); } //Controller Input - CurrentButton |= Config.JoyConController.GetButtons(); - - //Keyboard has priority stick-wise - if (LeftJoystickDX == 0 && LeftJoystickDY == 0) + if (Config.GamePadEnable) { - (LeftJoystickDX, LeftJoystickDY) = Config.JoyConController.GetLeftStick(); + for (int i = 0; i < CurrentButtonsGamePad.Length; ++i) + { + CurrentButtonsGamePad[i] |= Config.JoyConControllers[i].GetButtons(); + + (LeftJoystickDXGamePad[i], LeftJoystickDYGamePad[i]) = Config.JoyConControllers[i].GetLeftStick(); + (RightJoystickDXGamePad[i], RightJoystickDYGamePad[i]) = Config.JoyConControllers[i].GetRightStick(); + + LeftJoystickGamePad[i] = new HidJoystickPosition + { + DX = LeftJoystickDXGamePad[i], + DY = LeftJoystickDYGamePad[i] + }; + + RightJoystickGamePad[i] = new HidJoystickPosition + { + DX = RightJoystickDXGamePad[i], + DY = RightJoystickDYGamePad[i] + }; + } } - if (RightJoystickDX == 0 && RightJoystickDY == 0) + LeftJoystickKeyboard = new HidJoystickPosition { - (RightJoystickDX, RightJoystickDY) = Config.JoyConController.GetRightStick(); - } - - LeftJoystick = new HidJoystickPosition - { - DX = LeftJoystickDX, - DY = LeftJoystickDY + DX = LeftJoystickDXKeyboard, + DY = LeftJoystickDYKeyboard }; - RightJoystick = new HidJoystickPosition + RightJoystickKeyboard = new HidJoystickPosition { - DX = RightJoystickDX, - DY = RightJoystickDY + DX = RightJoystickDXKeyboard, + DY = RightJoystickDYKeyboard }; bool HasTouch = false; @@ -235,19 +252,262 @@ namespace Ryujinx Ns.Hid.SetTouchPoints(); } - Ns.Hid.SetJoyconButton( - HidControllerId.CONTROLLER_HANDHELD, - HidControllerLayouts.Handheld_Joined, - CurrentButton, - LeftJoystick, - RightJoystick); + if (HidEmulatedDevices.Devices.Handheld != -2) + { + switch (HidEmulatedDevices.Devices.Handheld) + { + case -1: + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_HANDHELD, + HidControllerLayouts.Handheld_Joined, + CurrentButtonsKeyboard, + LeftJoystickKeyboard, + RightJoystickKeyboard); + break; + default: + if (HidEmulatedDevices.Devices.Handheld < 0) + throw new ArgumentException("Unknown Emulated Device Code: " + HidEmulatedDevices.Devices.Handheld + "."); + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_HANDHELD, + HidControllerLayouts.Handheld_Joined, + CurrentButtonsGamePad[HidEmulatedDevices.Devices.Handheld], + LeftJoystickGamePad[HidEmulatedDevices.Devices.Handheld], + RightJoystickGamePad[HidEmulatedDevices.Devices.Handheld]); + break; + } + } - Ns.Hid.SetJoyconButton( - HidControllerId.CONTROLLER_HANDHELD, - HidControllerLayouts.Main, + if (HidEmulatedDevices.Devices.Player1 != -2) + { + switch (HidEmulatedDevices.Devices.Player1) + { + case -1: + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_PLAYER_1, + HidControllerLayouts.Joined, + CurrentButtonsKeyboard, + LeftJoystickKeyboard, + RightJoystickKeyboard); + break; + default: + if (HidEmulatedDevices.Devices.Player1 < 0) + throw new ArgumentException("Unknown Emulated Device Code: " + HidEmulatedDevices.Devices.Player1 + "."); + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_PLAYER_1, + HidControllerLayouts.Joined, + CurrentButtonsGamePad[HidEmulatedDevices.Devices.Player1], + LeftJoystickGamePad[HidEmulatedDevices.Devices.Player1], + RightJoystickGamePad[HidEmulatedDevices.Devices.Player1]); + break; + } + } + + if (HidEmulatedDevices.Devices.Player2 != -2) + { + switch (HidEmulatedDevices.Devices.Player2) + { + case -1: + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_PLAYER_2, + HidControllerLayouts.Joined, + CurrentButtonsKeyboard, + LeftJoystickKeyboard, + RightJoystickKeyboard); + break; + default: + if (HidEmulatedDevices.Devices.Player2 < 0) + throw new ArgumentException("Unknown Emulated Device Code: " + HidEmulatedDevices.Devices.Player2 + "."); + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_PLAYER_2, + HidControllerLayouts.Joined, + CurrentButtonsGamePad[HidEmulatedDevices.Devices.Player2], + LeftJoystickGamePad[HidEmulatedDevices.Devices.Player2], + RightJoystickGamePad[HidEmulatedDevices.Devices.Player2]); + break; + } + } + + if (HidEmulatedDevices.Devices.Player3 != -2) + { + switch (HidEmulatedDevices.Devices.Player3) + { + case -1: + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_PLAYER_3, + HidControllerLayouts.Joined, + CurrentButtonsKeyboard, + LeftJoystickKeyboard, + RightJoystickKeyboard); + break; + default: + if (HidEmulatedDevices.Devices.Player3 < 0) + throw new ArgumentException("Unknown Emulated Device Code: " + HidEmulatedDevices.Devices.Player3 + "."); + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_PLAYER_3, + HidControllerLayouts.Joined, + CurrentButtonsGamePad[HidEmulatedDevices.Devices.Player3], + LeftJoystickGamePad[HidEmulatedDevices.Devices.Player3], + RightJoystickGamePad[HidEmulatedDevices.Devices.Player3]); + break; + } + } + + if (HidEmulatedDevices.Devices.Player4 != -2) + { + switch (HidEmulatedDevices.Devices.Player4) + { + case -1: + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_PLAYER_4, + HidControllerLayouts.Joined, + CurrentButtonsKeyboard, + LeftJoystickKeyboard, + RightJoystickKeyboard); + break; + default: + if (HidEmulatedDevices.Devices.Player4 < 0) + throw new ArgumentException("Unknown Emulated Device Code: " + HidEmulatedDevices.Devices.Player4 + "."); + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_PLAYER_4, + HidControllerLayouts.Joined, + CurrentButtonsGamePad[HidEmulatedDevices.Devices.Player4], + LeftJoystickGamePad[HidEmulatedDevices.Devices.Player4], + RightJoystickGamePad[HidEmulatedDevices.Devices.Player4]); + break; + } + } + + if (HidEmulatedDevices.Devices.Player5 != -2) + { + switch (HidEmulatedDevices.Devices.Player5) + { + case -1: + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_PLAYER_5, + HidControllerLayouts.Joined, + CurrentButtonsKeyboard, + LeftJoystickKeyboard, + RightJoystickKeyboard); + break; + default: + if (HidEmulatedDevices.Devices.Player5 < 0) + throw new ArgumentException("Unknown Emulated Device Code: " + HidEmulatedDevices.Devices.Player5 + "."); + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_PLAYER_5, + HidControllerLayouts.Joined, + CurrentButtonsGamePad[HidEmulatedDevices.Devices.Player5], + LeftJoystickGamePad[HidEmulatedDevices.Devices.Player5], + RightJoystickGamePad[HidEmulatedDevices.Devices.Player5]); + break; + } + } + + if (HidEmulatedDevices.Devices.Player6 != -2) + { + switch (HidEmulatedDevices.Devices.Player6) + { + case -1: + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_PLAYER_6, + HidControllerLayouts.Joined, + CurrentButtonsKeyboard, + LeftJoystickKeyboard, + RightJoystickKeyboard); + break; + default: + if (HidEmulatedDevices.Devices.Player6 < 0) + throw new ArgumentException("Unknown Emulated Device Code: " + HidEmulatedDevices.Devices.Player6 + "."); + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_PLAYER_6, + HidControllerLayouts.Joined, + CurrentButtonsGamePad[HidEmulatedDevices.Devices.Player6], + LeftJoystickGamePad[HidEmulatedDevices.Devices.Player6], + RightJoystickGamePad[HidEmulatedDevices.Devices.Player6]); + break; + } + } + + if (HidEmulatedDevices.Devices.Player7 != -2) + { + switch (HidEmulatedDevices.Devices.Player7) + { + case -1: + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_PLAYER_7, + HidControllerLayouts.Joined, + CurrentButtonsKeyboard, + LeftJoystickKeyboard, + RightJoystickKeyboard); + break; + default: + if (HidEmulatedDevices.Devices.Player7 < 0) + throw new ArgumentException("Unknown Emulated Device Code: " + HidEmulatedDevices.Devices.Player7 + "."); + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_PLAYER_7, + HidControllerLayouts.Joined, + CurrentButtonsGamePad[HidEmulatedDevices.Devices.Player7], + LeftJoystickGamePad[HidEmulatedDevices.Devices.Player7], + RightJoystickGamePad[HidEmulatedDevices.Devices.Player7]); + break; + } + } + + if (HidEmulatedDevices.Devices.Player8 != -2) + { + switch (HidEmulatedDevices.Devices.Player8) + { + case -1: + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_PLAYER_8, + HidControllerLayouts.Joined, + CurrentButtonsKeyboard, + LeftJoystickKeyboard, + RightJoystickKeyboard); + break; + default: + if (HidEmulatedDevices.Devices.Player8 < 0) + throw new ArgumentException("Unknown Emulated Device Code: " + HidEmulatedDevices.Devices.Player8 + "."); + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_PLAYER_8, + HidControllerLayouts.Joined, + CurrentButtonsGamePad[HidEmulatedDevices.Devices.Player8], + LeftJoystickGamePad[HidEmulatedDevices.Devices.Player8], + RightJoystickGamePad[HidEmulatedDevices.Devices.Player8]); + break; + } + + if (HidEmulatedDevices.Devices.PlayerUnknown != -2) + { + switch (HidEmulatedDevices.Devices.PlayerUnknown) + { + case -1: + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_UNKNOWN, + HidControllerLayouts.Joined, + CurrentButtonsKeyboard, + LeftJoystickKeyboard, + RightJoystickKeyboard); + break; + default: + if (HidEmulatedDevices.Devices.PlayerUnknown < 0) + throw new ArgumentException("Unknown Emulated Device Code: " + HidEmulatedDevices.Devices.PlayerUnknown + "."); + Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_UNKNOWN, + HidControllerLayouts.Joined, + CurrentButtonsGamePad[HidEmulatedDevices.Devices.PlayerUnknown], + LeftJoystickGamePad[HidEmulatedDevices.Devices.PlayerUnknown], + RightJoystickGamePad[HidEmulatedDevices.Devices.PlayerUnknown]); + break; + } + } + } + + /*Ns.Hid.SetJoyconButton( + HidControllerId.CONTROLLER_PLAYER_1, + HidControllerLayouts.Joined, CurrentButton, LeftJoystick, - RightJoystick); + RightJoystick);*/ } private new void RenderFrame()