From dc02ac08caa84456e8b280a3347ac8907b5249ff Mon Sep 17 00:00:00 2001 From: emmauss Date: Tue, 20 Nov 2018 02:01:36 +0200 Subject: [PATCH] Support other switch controller types (#487) * Make controllers modular, support changing controller type * return readable events * signal hid events * fix style --- Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs | 37 ++- Ryujinx.HLE/Hid/Hid.cs | 273 ------------------ Ryujinx.HLE/Hid/HidControllerButtons.cs | 35 --- Ryujinx.HLE/Hid/HidControllerType.cs | 14 - Ryujinx.HLE/Input/Hid.cs | 140 +++++++++ Ryujinx.HLE/Input/HidBaseController.cs | 76 +++++ Ryujinx.HLE/Input/HidControllerButtons.cs | 35 +++ .../{Hid => Input}/HidControllerColorDesc.cs | 0 .../{Hid => Input}/HidControllerConnState.cs | 0 Ryujinx.HLE/{Hid => Input}/HidControllerId.cs | 0 .../{Hid => Input}/HidControllerLayouts.cs | 0 Ryujinx.HLE/Input/HidControllerType.cs | 14 + .../{Hid => Input}/HidJoystickPosition.cs | 0 Ryujinx.HLE/Input/HidNpadController.cs | 86 ++++++ Ryujinx.HLE/Input/HidProController.cs | 44 +++ Ryujinx.HLE/{Hid => Input}/HidTouchPoint.cs | 0 Ryujinx.HLE/Input/HidValues.cs | 64 ++++ Ryujinx.HLE/Input/IHidDevice.cs | 12 + .../JoyConColor.cs => Input/NpadColor.cs} | 2 +- Ryujinx/Config.cs | 23 +- Ryujinx/Ryujinx.conf | 3 + Ryujinx/Ui/GLScreen.cs | 29 +- ...{JoyConController.cs => NpadController.cs} | 48 +-- .../Ui/{JoyConKeyboard.cs => NpadKeyboard.cs} | 48 +-- 24 files changed, 574 insertions(+), 409 deletions(-) delete mode 100644 Ryujinx.HLE/Hid/Hid.cs delete mode 100644 Ryujinx.HLE/Hid/HidControllerButtons.cs delete mode 100644 Ryujinx.HLE/Hid/HidControllerType.cs create mode 100644 Ryujinx.HLE/Input/Hid.cs create mode 100644 Ryujinx.HLE/Input/HidBaseController.cs create mode 100644 Ryujinx.HLE/Input/HidControllerButtons.cs rename Ryujinx.HLE/{Hid => Input}/HidControllerColorDesc.cs (100%) rename Ryujinx.HLE/{Hid => Input}/HidControllerConnState.cs (100%) rename Ryujinx.HLE/{Hid => Input}/HidControllerId.cs (100%) rename Ryujinx.HLE/{Hid => Input}/HidControllerLayouts.cs (100%) create mode 100644 Ryujinx.HLE/Input/HidControllerType.cs rename Ryujinx.HLE/{Hid => Input}/HidJoystickPosition.cs (100%) create mode 100644 Ryujinx.HLE/Input/HidNpadController.cs create mode 100644 Ryujinx.HLE/Input/HidProController.cs rename Ryujinx.HLE/{Hid => Input}/HidTouchPoint.cs (100%) create mode 100644 Ryujinx.HLE/Input/HidValues.cs create mode 100644 Ryujinx.HLE/Input/IHidDevice.cs rename Ryujinx.HLE/{Hid/JoyConColor.cs => Input/NpadColor.cs} (92%) rename Ryujinx/Ui/{JoyConController.cs => NpadController.cs} (89%) rename Ryujinx/Ui/{JoyConKeyboard.cs => NpadKeyboard.cs} (80%) diff --git a/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs b/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs index e54ca8125..1af734ffc 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs @@ -23,7 +23,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid private bool UsbFullKeyControllerEnabled; private HidNpadJoyHoldType NpadJoyHoldType; - private HidNpadStyle NpadStyleTag; + private HidNpadStyle NpadStyleSet; private HidNpadJoyAssignmentMode NpadJoyAssignmentMode; private HidNpadHandheldActivationMode NpadHandheldActivationMode; private HidGyroscopeZeroDriftMode GyroscopeZeroDriftMode; @@ -153,7 +153,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid PalmaOperationCompleteEvent = new KEvent(System); NpadJoyHoldType = HidNpadJoyHoldType.Vertical; - NpadStyleTag = HidNpadStyle.FullKey | HidNpadStyle.Dual | HidNpadStyle.Left | HidNpadStyle.Right; + NpadStyleSet = HidNpadStyle.FullKey | HidNpadStyle.Dual | HidNpadStyle.Left | HidNpadStyle.Right | HidNpadStyle.Handheld; NpadJoyAssignmentMode = HidNpadJoyAssignmentMode.Dual; NpadHandheldActivationMode = HidNpadHandheldActivationMode.Dual; GyroscopeZeroDriftMode = HidGyroscopeZeroDriftMode.Standard; @@ -161,6 +161,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid SensorFusionParams = new HidSensorFusionParameters(); AccelerometerParams = new HidAccelerometerParameters(); VibrationValue = new HidVibrationValue(); + + // TODO: signal event at right place + XpadIdEvent.ReadableEvent.Signal(); } // CreateAppletResource(nn::applet::AppletResourceUserId) -> object @@ -218,7 +221,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid { long XpadId = Context.RequestData.ReadInt64(); - if (Context.Process.HandleTable.GenerateHandle(XpadIdEvent, out XpadIdEventHandle) != KernelResult.Success) + if (Context.Process.HandleTable.GenerateHandle(XpadIdEvent.ReadableEvent, out XpadIdEventHandle) != KernelResult.Success) { throw new InvalidOperationException("Out of handles!"); } @@ -652,12 +655,14 @@ namespace Ryujinx.HLE.HOS.Services.Hid // SetSupportedNpadStyleSet(nn::applet::AppletResourceUserId, nn::hid::NpadStyleTag) public long SetSupportedNpadStyleSet(ServiceCtx Context) { - NpadStyleTag = (HidNpadStyle)Context.RequestData.ReadInt32(); + NpadStyleSet = (HidNpadStyle)Context.RequestData.ReadInt32(); long AppletResourceUserId = Context.RequestData.ReadInt64(); Logger.PrintStub(LogClass.ServiceHid, $"Stubbed. AppletResourceUserId: {AppletResourceUserId} - " + - $"NpadStyleTag: {NpadStyleTag}"); + $"NpadStyleSet: {NpadStyleSet}"); + + NpadStyleSetUpdateEvent.ReadableEvent.Signal(); return 0; } @@ -667,10 +672,10 @@ namespace Ryujinx.HLE.HOS.Services.Hid { long AppletResourceUserId = Context.RequestData.ReadInt64(); - Context.ResponseData.Write((int)NpadStyleTag); + Context.ResponseData.Write((int)NpadStyleSet); Logger.PrintStub(LogClass.ServiceHid, $"Stubbed. AppletResourceUserId: {AppletResourceUserId} - " + - $"NpadStyleTag: {NpadStyleTag}"); + $"NpadStyleSet: {NpadStyleSet}"); return 0; } @@ -714,7 +719,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid int NpadId = Context.RequestData.ReadInt32(); long NpadStyleSet = Context.RequestData.ReadInt64(); - if (Context.Process.HandleTable.GenerateHandle(NpadStyleSetUpdateEvent, out int Handle) != KernelResult.Success) + if (Context.Process.HandleTable.GenerateHandle(NpadStyleSetUpdateEvent.ReadableEvent, out int Handle) != KernelResult.Success) { throw new InvalidOperationException("Out of handles!"); } @@ -1348,6 +1353,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid Logger.PrintStub(LogClass.ServiceHid, $"Stubbed. PalmaConnectionHandle: {PalmaConnectionHandle}"); + PalmaOperationCompleteEvent.ReadableEvent.Signal(); + return 0; } @@ -1356,7 +1363,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid { int PalmaConnectionHandle = Context.RequestData.ReadInt32(); - if (Context.Process.HandleTable.GenerateHandle(PalmaOperationCompleteEvent, out int Handle) != KernelResult.Success) + if (Context.Process.HandleTable.GenerateHandle(PalmaOperationCompleteEvent.ReadableEvent, out int Handle) != KernelResult.Success) { throw new InvalidOperationException("Out of handles!"); } @@ -1392,6 +1399,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid Logger.PrintStub(LogClass.ServiceHid, $"Stubbed. PalmaConnectionHandle: {PalmaConnectionHandle} - " + $"Unknown0: {Unknown0}"); + PalmaOperationCompleteEvent.ReadableEvent.Signal(); + return 0; } @@ -1404,6 +1413,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid Logger.PrintStub(LogClass.ServiceHid, $"Stubbed. PalmaConnectionHandle: {PalmaConnectionHandle} - " + $"FrModeType: {FrModeType}"); + PalmaOperationCompleteEvent.ReadableEvent.Signal(); + return 0; } @@ -1426,6 +1437,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid Logger.PrintStub(LogClass.ServiceHid, $"Stubbed. PalmaConnectionHandle: {PalmaConnectionHandle} - " + $"EnabledPalmaStep: {EnabledPalmaStep}"); + PalmaOperationCompleteEvent.ReadableEvent.Signal(); + return 0; } @@ -1436,6 +1449,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid Logger.PrintStub(LogClass.ServiceHid, $"Stubbed. PalmaConnectionHandle: {PalmaConnectionHandle}"); + PalmaOperationCompleteEvent.ReadableEvent.Signal(); + return 0; } @@ -1446,6 +1461,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid Logger.PrintStub(LogClass.ServiceHid, $"Stubbed. PalmaConnectionHandle: {PalmaConnectionHandle}"); + PalmaOperationCompleteEvent.ReadableEvent.Signal(); + return 0; } @@ -1475,6 +1492,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid $"Unknown0: {Unknown0} - " + $"Unknown1: {Unknown1}"); + PalmaOperationCompleteEvent.ReadableEvent.Signal(); + return 0; } diff --git a/Ryujinx.HLE/Hid/Hid.cs b/Ryujinx.HLE/Hid/Hid.cs deleted file mode 100644 index 21580223e..000000000 --- a/Ryujinx.HLE/Hid/Hid.cs +++ /dev/null @@ -1,273 +0,0 @@ -using Ryujinx.Common; -using Ryujinx.HLE.HOS; -using System; - -namespace Ryujinx.HLE.Input -{ - public class Hid - { - /* - * Reference: - * https://github.com/reswitched/libtransistor/blob/development/lib/hid.c - * https://github.com/reswitched/libtransistor/blob/development/include/libtransistor/hid.h - * https://github.com/switchbrew/libnx/blob/master/nx/source/services/hid.c - * https://github.com/switchbrew/libnx/blob/master/nx/include/switch/services/hid.h - */ - - private const int HidHeaderSize = 0x400; - private const int HidTouchScreenSize = 0x3000; - private const int HidMouseSize = 0x400; - private const int HidKeyboardSize = 0x400; - private const int HidUnkSection1Size = 0x400; - private const int HidUnkSection2Size = 0x400; - private const int HidUnkSection3Size = 0x400; - private const int HidUnkSection4Size = 0x400; - private const int HidUnkSection5Size = 0x200; - private const int HidUnkSection6Size = 0x200; - private const int HidUnkSection7Size = 0x200; - private const int HidUnkSection8Size = 0x800; - private const int HidControllerSerialsSize = 0x4000; - private const int HidControllersSize = 0x32000; - private const int HidUnkSection9Size = 0x800; - - private const int HidTouchHeaderSize = 0x28; - private const int HidTouchEntrySize = 0x298; - - private const int HidTouchEntryHeaderSize = 0x10; - private const int HidTouchEntryTouchSize = 0x28; - - private const int HidControllerSize = 0x5000; - private const int HidControllerHeaderSize = 0x28; - private const int HidControllerLayoutsSize = 0x350; - - private const int HidControllersLayoutHeaderSize = 0x20; - private const int HidControllersInputEntrySize = 0x30; - - private const int HidHeaderOffset = 0; - private const int HidTouchScreenOffset = HidHeaderOffset + HidHeaderSize; - private const int HidMouseOffset = HidTouchScreenOffset + HidTouchScreenSize; - private const int HidKeyboardOffset = HidMouseOffset + HidMouseSize; - private const int HidUnkSection1Offset = HidKeyboardOffset + HidKeyboardSize; - private const int HidUnkSection2Offset = HidUnkSection1Offset + HidUnkSection1Size; - private const int HidUnkSection3Offset = HidUnkSection2Offset + HidUnkSection2Size; - private const int HidUnkSection4Offset = HidUnkSection3Offset + HidUnkSection3Size; - private const int HidUnkSection5Offset = HidUnkSection4Offset + HidUnkSection4Size; - private const int HidUnkSection6Offset = HidUnkSection5Offset + HidUnkSection5Size; - private const int HidUnkSection7Offset = HidUnkSection6Offset + HidUnkSection6Size; - private const int HidUnkSection8Offset = HidUnkSection7Offset + HidUnkSection7Size; - private const int HidControllerSerialsOffset = HidUnkSection8Offset + HidUnkSection8Size; - private const int HidControllersOffset = HidControllerSerialsOffset + HidControllerSerialsSize; - private const int HidUnkSection9Offset = HidControllersOffset + HidControllersSize; - - private const int HidEntryCount = 17; - - private Switch Device; - - private long HidPosition; - - public Hid(Switch Device, long HidPosition) - { - this.Device = Device; - this.HidPosition = HidPosition; - - Device.Memory.FillWithZeros(HidPosition, Horizon.HidSize); - - InitializeJoyconPair( - JoyConColor.Body_Neon_Red, - JoyConColor.Buttons_Neon_Red, - JoyConColor.Body_Neon_Blue, - JoyConColor.Buttons_Neon_Blue); - } - - private void InitializeJoyconPair( - JoyConColor LeftColorBody, - JoyConColor LeftColorButtons, - JoyConColor RightColorBody, - JoyConColor RightColorButtons) - { - long BaseControllerOffset = HidPosition + HidControllersOffset + 8 * HidControllerSize; - - HidControllerType Type = HidControllerType.ControllerType_Handheld; - - bool IsHalf = false; - - HidControllerColorDesc SingleColorDesc = - HidControllerColorDesc.ColorDesc_ColorsNonexistent; - - JoyConColor SingleColorBody = JoyConColor.Black; - JoyConColor SingleColorButtons = JoyConColor.Black; - - HidControllerColorDesc SplitColorDesc = 0; - - Device.Memory.WriteInt32(BaseControllerOffset + 0x00, (int)Type); - - Device.Memory.WriteInt32(BaseControllerOffset + 0x04, IsHalf ? 1 : 0); - - Device.Memory.WriteInt32(BaseControllerOffset + 0x08, (int)SingleColorDesc); - Device.Memory.WriteInt32(BaseControllerOffset + 0x0c, (int)SingleColorBody); - Device.Memory.WriteInt32(BaseControllerOffset + 0x10, (int)SingleColorButtons); - Device.Memory.WriteInt32(BaseControllerOffset + 0x14, (int)SplitColorDesc); - - Device.Memory.WriteInt32(BaseControllerOffset + 0x18, (int)LeftColorBody); - Device.Memory.WriteInt32(BaseControllerOffset + 0x1c, (int)LeftColorButtons); - - Device.Memory.WriteInt32(BaseControllerOffset + 0x20, (int)RightColorBody); - Device.Memory.WriteInt32(BaseControllerOffset + 0x24, (int)RightColorButtons); - } - - private HidControllerButtons UpdateStickButtons( - HidJoystickPosition LeftStick, - HidJoystickPosition RightStick) - { - HidControllerButtons Result = 0; - - if (RightStick.DX < 0) - { - Result |= HidControllerButtons.KEY_RSTICK_LEFT; - } - - if (RightStick.DX > 0) - { - Result |= HidControllerButtons.KEY_RSTICK_RIGHT; - } - - if (RightStick.DY < 0) - { - Result |= HidControllerButtons.KEY_RSTICK_DOWN; - } - - if (RightStick.DY > 0) - { - Result |= HidControllerButtons.KEY_RSTICK_UP; - } - - if (LeftStick.DX < 0) - { - Result |= HidControllerButtons.KEY_LSTICK_LEFT; - } - - if (LeftStick.DX > 0) - { - Result |= HidControllerButtons.KEY_LSTICK_RIGHT; - } - - if (LeftStick.DY < 0) - { - Result |= HidControllerButtons.KEY_LSTICK_DOWN; - } - - if (LeftStick.DY > 0) - { - Result |= HidControllerButtons.KEY_LSTICK_UP; - } - - return Result; - } - - public void SetJoyconButton( - HidControllerId ControllerId, - HidControllerLayouts ControllerLayout, - HidControllerButtons Buttons, - HidJoystickPosition LeftStick, - HidJoystickPosition RightStick) - { - Buttons |= UpdateStickButtons(LeftStick, RightStick); - - long ControllerOffset = HidPosition + HidControllersOffset; - - ControllerOffset += (int)ControllerId * HidControllerSize; - - ControllerOffset += HidControllerHeaderSize; - - ControllerOffset += (int)ControllerLayout * HidControllerLayoutsSize; - - long LastEntry = Device.Memory.ReadInt64(ControllerOffset + 0x10); - - long CurrEntry = (LastEntry + 1) % HidEntryCount; - - long Timestamp = GetTimestamp(); - - Device.Memory.WriteInt64(ControllerOffset + 0x00, Timestamp); - Device.Memory.WriteInt64(ControllerOffset + 0x08, HidEntryCount); - Device.Memory.WriteInt64(ControllerOffset + 0x10, CurrEntry); - Device.Memory.WriteInt64(ControllerOffset + 0x18, HidEntryCount - 1); - - ControllerOffset += HidControllersLayoutHeaderSize; - - long LastEntryOffset = ControllerOffset + LastEntry * HidControllersInputEntrySize; - - ControllerOffset += CurrEntry * HidControllersInputEntrySize; - - long SampleCounter = Device.Memory.ReadInt64(LastEntryOffset) + 1; - - Device.Memory.WriteInt64(ControllerOffset + 0x00, SampleCounter); - Device.Memory.WriteInt64(ControllerOffset + 0x08, SampleCounter); - - Device.Memory.WriteInt64(ControllerOffset + 0x10, (uint)Buttons); - - Device.Memory.WriteInt32(ControllerOffset + 0x18, LeftStick.DX); - Device.Memory.WriteInt32(ControllerOffset + 0x1c, LeftStick.DY); - - Device.Memory.WriteInt32(ControllerOffset + 0x20, RightStick.DX); - Device.Memory.WriteInt32(ControllerOffset + 0x24, RightStick.DY); - - Device.Memory.WriteInt64(ControllerOffset + 0x28, - (uint)HidControllerConnState.Controller_State_Connected | - (uint)HidControllerConnState.Controller_State_Wired); - } - - public void SetTouchPoints(params HidTouchPoint[] Points) - { - long TouchScreenOffset = HidPosition + HidTouchScreenOffset; - - long LastEntry = Device.Memory.ReadInt64(TouchScreenOffset + 0x10); - - long CurrEntry = (LastEntry + 1) % HidEntryCount; - - long Timestamp = GetTimestamp(); - - Device.Memory.WriteInt64(TouchScreenOffset + 0x00, Timestamp); - Device.Memory.WriteInt64(TouchScreenOffset + 0x08, HidEntryCount); - Device.Memory.WriteInt64(TouchScreenOffset + 0x10, CurrEntry); - Device.Memory.WriteInt64(TouchScreenOffset + 0x18, HidEntryCount - 1); - Device.Memory.WriteInt64(TouchScreenOffset + 0x20, Timestamp); - - long TouchEntryOffset = TouchScreenOffset + HidTouchHeaderSize; - - long LastEntryOffset = TouchEntryOffset + LastEntry * HidTouchEntrySize; - - long SampleCounter = Device.Memory.ReadInt64(LastEntryOffset) + 1; - - TouchEntryOffset += CurrEntry * HidTouchEntrySize; - - Device.Memory.WriteInt64(TouchEntryOffset + 0x00, SampleCounter); - Device.Memory.WriteInt64(TouchEntryOffset + 0x08, Points.Length); - - TouchEntryOffset += HidTouchEntryHeaderSize; - - const int Padding = 0; - - int Index = 0; - - foreach (HidTouchPoint Point in Points) - { - Device.Memory.WriteInt64(TouchEntryOffset + 0x00, Timestamp); - Device.Memory.WriteInt32(TouchEntryOffset + 0x08, Padding); - Device.Memory.WriteInt32(TouchEntryOffset + 0x0c, Index++); - Device.Memory.WriteInt32(TouchEntryOffset + 0x10, Point.X); - Device.Memory.WriteInt32(TouchEntryOffset + 0x14, Point.Y); - Device.Memory.WriteInt32(TouchEntryOffset + 0x18, Point.DiameterX); - Device.Memory.WriteInt32(TouchEntryOffset + 0x1c, Point.DiameterY); - Device.Memory.WriteInt32(TouchEntryOffset + 0x20, Point.Angle); - Device.Memory.WriteInt32(TouchEntryOffset + 0x24, Padding); - - TouchEntryOffset += HidTouchEntryTouchSize; - } - } - - private static long GetTimestamp() - { - return PerformanceCounter.ElapsedMilliseconds * 19200; - } - } -} diff --git a/Ryujinx.HLE/Hid/HidControllerButtons.cs b/Ryujinx.HLE/Hid/HidControllerButtons.cs deleted file mode 100644 index f41d17e1d..000000000 --- a/Ryujinx.HLE/Hid/HidControllerButtons.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; - -namespace Ryujinx.HLE.Input -{ - [Flags] - public enum HidControllerButtons - { - KEY_A = (1 << 0), - KEY_B = (1 << 1), - KEY_X = (1 << 2), - KEY_Y = (1 << 3), - KEY_LSTICK = (1 << 4), - KEY_RSTICK = (1 << 5), - KEY_L = (1 << 6), - KEY_R = (1 << 7), - KEY_ZL = (1 << 8), - KEY_ZR = (1 << 9), - KEY_PLUS = (1 << 10), - KEY_MINUS = (1 << 11), - KEY_DLEFT = (1 << 12), - KEY_DUP = (1 << 13), - KEY_DRIGHT = (1 << 14), - KEY_DDOWN = (1 << 15), - KEY_LSTICK_LEFT = (1 << 16), - KEY_LSTICK_UP = (1 << 17), - KEY_LSTICK_RIGHT = (1 << 18), - KEY_LSTICK_DOWN = (1 << 19), - KEY_RSTICK_LEFT = (1 << 20), - KEY_RSTICK_UP = (1 << 21), - KEY_RSTICK_RIGHT = (1 << 22), - KEY_RSTICK_DOWN = (1 << 23), - KEY_SL = (1 << 24), - KEY_SR = (1 << 25) - } -} \ No newline at end of file diff --git a/Ryujinx.HLE/Hid/HidControllerType.cs b/Ryujinx.HLE/Hid/HidControllerType.cs deleted file mode 100644 index ea8ddfd4e..000000000 --- a/Ryujinx.HLE/Hid/HidControllerType.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace Ryujinx.HLE.Input -{ - [Flags] - public enum HidControllerType - { - ControllerType_ProController = (1 << 0), - ControllerType_Handheld = (1 << 1), - ControllerType_JoyconPair = (1 << 2), - ControllerType_JoyconLeft = (1 << 3), - ControllerType_JoyconRight = (1 << 4) - } -} \ No newline at end of file diff --git a/Ryujinx.HLE/Input/Hid.cs b/Ryujinx.HLE/Input/Hid.cs new file mode 100644 index 000000000..edcfe42d2 --- /dev/null +++ b/Ryujinx.HLE/Input/Hid.cs @@ -0,0 +1,140 @@ +using Ryujinx.Common; +using Ryujinx.HLE.HOS; + +namespace Ryujinx.HLE.Input +{ + public partial class Hid + { + private Switch Device; + + public HidControllerBase PrimaryController { get; private set; } + + internal long HidPosition; + + public Hid(Switch Device, long HidPosition) + { + this.Device = Device; + this.HidPosition = HidPosition; + + Device.Memory.FillWithZeros(HidPosition, Horizon.HidSize); + } + + public void InitilizePrimaryController(HidControllerType ControllerType) + { + HidControllerId ControllerId = ControllerType == HidControllerType.Handheld ? + HidControllerId.CONTROLLER_HANDHELD : HidControllerId.CONTROLLER_PLAYER_1; + + if (ControllerType == HidControllerType.ProController) + { + PrimaryController = new HidProController(Device); + } + else + { + PrimaryController = new HidNpadController(ControllerType, + Device, + (NpadColor.Body_Neon_Red, NpadColor.Body_Neon_Red), + (NpadColor.Buttons_Neon_Blue, NpadColor.Buttons_Neon_Blue)); + } + + PrimaryController.Connect(ControllerId); + } + + private HidControllerButtons UpdateStickButtons( + HidJoystickPosition LeftStick, + HidJoystickPosition RightStick) + { + HidControllerButtons Result = 0; + + if (RightStick.DX < 0) + { + Result |= HidControllerButtons.RStickLeft; + } + + if (RightStick.DX > 0) + { + Result |= HidControllerButtons.RStickRight; + } + + if (RightStick.DY < 0) + { + Result |= HidControllerButtons.RStickDown; + } + + if (RightStick.DY > 0) + { + Result |= HidControllerButtons.RStickUp; + } + + if (LeftStick.DX < 0) + { + Result |= HidControllerButtons.LStickLeft; + } + + if (LeftStick.DX > 0) + { + Result |= HidControllerButtons.LStickRight; + } + + if (LeftStick.DY < 0) + { + Result |= HidControllerButtons.LStickDown; + } + + if (LeftStick.DY > 0) + { + Result |= HidControllerButtons.LStickUp; + } + + return Result; + } + + public void SetTouchPoints(params HidTouchPoint[] Points) + { + long TouchScreenOffset = HidPosition + HidTouchScreenOffset; + long LastEntry = Device.Memory.ReadInt64(TouchScreenOffset + 0x10); + long CurrEntry = (LastEntry + 1) % HidEntryCount; + long Timestamp = GetTimestamp(); + + Device.Memory.WriteInt64(TouchScreenOffset + 0x00, Timestamp); + Device.Memory.WriteInt64(TouchScreenOffset + 0x08, HidEntryCount); + Device.Memory.WriteInt64(TouchScreenOffset + 0x10, CurrEntry); + Device.Memory.WriteInt64(TouchScreenOffset + 0x18, HidEntryCount - 1); + Device.Memory.WriteInt64(TouchScreenOffset + 0x20, Timestamp); + + long TouchEntryOffset = TouchScreenOffset + HidTouchHeaderSize; + long LastEntryOffset = TouchEntryOffset + LastEntry * HidTouchEntrySize; + long SampleCounter = Device.Memory.ReadInt64(LastEntryOffset) + 1; + + TouchEntryOffset += CurrEntry * HidTouchEntrySize; + + Device.Memory.WriteInt64(TouchEntryOffset + 0x00, SampleCounter); + Device.Memory.WriteInt64(TouchEntryOffset + 0x08, Points.Length); + + TouchEntryOffset += HidTouchEntryHeaderSize; + + const int Padding = 0; + + int Index = 0; + + foreach (HidTouchPoint Point in Points) + { + Device.Memory.WriteInt64(TouchEntryOffset + 0x00, SampleCounter); + Device.Memory.WriteInt32(TouchEntryOffset + 0x08, Padding); + Device.Memory.WriteInt32(TouchEntryOffset + 0x0c, Index++); + Device.Memory.WriteInt32(TouchEntryOffset + 0x10, Point.X); + Device.Memory.WriteInt32(TouchEntryOffset + 0x14, Point.Y); + Device.Memory.WriteInt32(TouchEntryOffset + 0x18, Point.DiameterX); + Device.Memory.WriteInt32(TouchEntryOffset + 0x1c, Point.DiameterY); + Device.Memory.WriteInt32(TouchEntryOffset + 0x20, Point.Angle); + Device.Memory.WriteInt32(TouchEntryOffset + 0x24, Padding); + + TouchEntryOffset += HidTouchEntryTouchSize; + } + } + + internal static long GetTimestamp() + { + return PerformanceCounter.ElapsedMilliseconds * 19200; + } + } +} diff --git a/Ryujinx.HLE/Input/HidBaseController.cs b/Ryujinx.HLE/Input/HidBaseController.cs new file mode 100644 index 000000000..9b9bb7ea9 --- /dev/null +++ b/Ryujinx.HLE/Input/HidBaseController.cs @@ -0,0 +1,76 @@ +using static Ryujinx.HLE.Input.Hid; + +namespace Ryujinx.HLE.Input +{ + public abstract class HidControllerBase : IHidDevice + { + protected HidControllerType HidControllerType; + protected Switch Device; + protected HidControllerId ControllerId; + + public long Offset { get; private set; } + public bool Connected { get; protected set; } + + public HidControllerBase(HidControllerType ControllerType, Switch Device) + { + this.Device = Device; + + HidControllerType = ControllerType; + } + + public virtual void Connect(HidControllerId ControllerId) + { + this.ControllerId = ControllerId; + + Offset = Device.Hid.HidPosition + HidControllersOffset + (int)ControllerId * HidControllerSize; + + Device.Memory.FillWithZeros(Offset, 0x5000); + + Device.Memory.WriteInt32(Offset + 0x00, (int)HidControllerType); + } + + public abstract void SendInput( + HidControllerButtons Buttons, + HidJoystickPosition LeftStick, + HidJoystickPosition RightStick); + + protected long WriteInput( + HidControllerButtons Buttons, + HidJoystickPosition LeftStick, + HidJoystickPosition RightStick, + HidControllerLayouts ControllerLayout) + { + long ControllerOffset = Offset + HidControllerHeaderSize; + + ControllerOffset += (int)ControllerLayout * HidControllerLayoutsSize; + + long LastEntry = Device.Memory.ReadInt64(ControllerOffset + 0x10); + long CurrEntry = (LastEntry + 1) % HidEntryCount; + long Timestamp = GetTimestamp(); + + Device.Memory.WriteInt64(ControllerOffset + 0x00, Timestamp); + Device.Memory.WriteInt64(ControllerOffset + 0x08, HidEntryCount); + Device.Memory.WriteInt64(ControllerOffset + 0x10, CurrEntry); + Device.Memory.WriteInt64(ControllerOffset + 0x18, HidEntryCount - 1); + + ControllerOffset += HidControllersLayoutHeaderSize; + + long LastEntryOffset = ControllerOffset + LastEntry * HidControllersInputEntrySize; + + ControllerOffset += CurrEntry * HidControllersInputEntrySize; + + long SampleCounter = Device.Memory.ReadInt64(LastEntryOffset) + 1; + + Device.Memory.WriteInt64(ControllerOffset + 0x00, SampleCounter); + Device.Memory.WriteInt64(ControllerOffset + 0x08, SampleCounter); + Device.Memory.WriteInt64(ControllerOffset + 0x10, (uint)Buttons); + + Device.Memory.WriteInt32(ControllerOffset + 0x18, LeftStick.DX); + Device.Memory.WriteInt32(ControllerOffset + 0x1c, LeftStick.DY); + Device.Memory.WriteInt32(ControllerOffset + 0x20, RightStick.DX); + Device.Memory.WriteInt32(ControllerOffset + 0x24, RightStick.DY); + + return ControllerOffset; + } + } +} diff --git a/Ryujinx.HLE/Input/HidControllerButtons.cs b/Ryujinx.HLE/Input/HidControllerButtons.cs new file mode 100644 index 000000000..07a3a118e --- /dev/null +++ b/Ryujinx.HLE/Input/HidControllerButtons.cs @@ -0,0 +1,35 @@ +using System; + +namespace Ryujinx.HLE.Input +{ + [Flags] + public enum HidControllerButtons + { + A = 1 << 0, + B = 1 << 1, + X = 1 << 2, + Y = 1 << 3, + StickLeft = 1 << 4, + StickRight = 1 << 5, + L = 1 << 6, + R = 1 << 7, + Zl = 1 << 8, + Zr = 1 << 9, + Plus = 1 << 10, + Minus = 1 << 11, + DpadLeft = 1 << 12, + DpadUp = 1 << 13, + DPadRight = 1 << 14, + DpadDown = 1 << 15, + LStickLeft = 1 << 16, + LStickUp = 1 << 17, + LStickRight = 1 << 18, + LStickDown = 1 << 19, + RStickLeft = 1 << 20, + RStickUp = 1 << 21, + RStickRight = 1 << 22, + RStickDown = 1 << 23, + Sl = 1 << 24, + Sr = 1 << 25 + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/Hid/HidControllerColorDesc.cs b/Ryujinx.HLE/Input/HidControllerColorDesc.cs similarity index 100% rename from Ryujinx.HLE/Hid/HidControllerColorDesc.cs rename to Ryujinx.HLE/Input/HidControllerColorDesc.cs diff --git a/Ryujinx.HLE/Hid/HidControllerConnState.cs b/Ryujinx.HLE/Input/HidControllerConnState.cs similarity index 100% rename from Ryujinx.HLE/Hid/HidControllerConnState.cs rename to Ryujinx.HLE/Input/HidControllerConnState.cs diff --git a/Ryujinx.HLE/Hid/HidControllerId.cs b/Ryujinx.HLE/Input/HidControllerId.cs similarity index 100% rename from Ryujinx.HLE/Hid/HidControllerId.cs rename to Ryujinx.HLE/Input/HidControllerId.cs diff --git a/Ryujinx.HLE/Hid/HidControllerLayouts.cs b/Ryujinx.HLE/Input/HidControllerLayouts.cs similarity index 100% rename from Ryujinx.HLE/Hid/HidControllerLayouts.cs rename to Ryujinx.HLE/Input/HidControllerLayouts.cs diff --git a/Ryujinx.HLE/Input/HidControllerType.cs b/Ryujinx.HLE/Input/HidControllerType.cs new file mode 100644 index 000000000..74bca365c --- /dev/null +++ b/Ryujinx.HLE/Input/HidControllerType.cs @@ -0,0 +1,14 @@ +using System; + +namespace Ryujinx.HLE.Input +{ + [Flags] + public enum HidControllerType + { + ProController = 1 << 0, + Handheld = 1 << 1, + NpadPair = 1 << 2, + NpadLeft = 1 << 3, + NpadRight = 1 << 4 + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/Hid/HidJoystickPosition.cs b/Ryujinx.HLE/Input/HidJoystickPosition.cs similarity index 100% rename from Ryujinx.HLE/Hid/HidJoystickPosition.cs rename to Ryujinx.HLE/Input/HidJoystickPosition.cs diff --git a/Ryujinx.HLE/Input/HidNpadController.cs b/Ryujinx.HLE/Input/HidNpadController.cs new file mode 100644 index 000000000..7b3fa64c4 --- /dev/null +++ b/Ryujinx.HLE/Input/HidNpadController.cs @@ -0,0 +1,86 @@ +namespace Ryujinx.HLE.Input +{ + public class HidNpadController : HidControllerBase + { + private (NpadColor Left, NpadColor Right) NpadBodyColors; + private (NpadColor Left, NpadColor Right) NpadButtonColors; + + private HidControllerLayouts CurrentLayout; + + private bool IsHalf; + + public HidNpadController( + HidControllerType ControllerType, + Switch Device, + (NpadColor, NpadColor) NpadBodyColors, + (NpadColor, NpadColor) NpadButtonColors) : base(ControllerType, Device) + { + this.NpadBodyColors = NpadBodyColors; + this.NpadButtonColors = NpadButtonColors; + + CurrentLayout = HidControllerLayouts.Handheld_Joined; + + switch (ControllerType) + { + case HidControllerType.NpadLeft: + CurrentLayout = HidControllerLayouts.Left; + break; + case HidControllerType.NpadRight: + CurrentLayout = HidControllerLayouts.Right; + break; + case HidControllerType.NpadPair: + CurrentLayout = HidControllerLayouts.Joined; + break; + } + } + + public override void Connect(HidControllerId ControllerId) + { + if(HidControllerType != HidControllerType.NpadLeft && HidControllerType != HidControllerType.NpadRight) + { + IsHalf = false; + } + + base.Connect(CurrentLayout == HidControllerLayouts.Handheld_Joined ? HidControllerId.CONTROLLER_HANDHELD : ControllerId); + + HidControllerColorDesc SingleColorDesc = + HidControllerColorDesc.ColorDesc_ColorsNonexistent; + + HidControllerColorDesc SplitColorDesc = 0; + + NpadColor SingleColorBody = NpadColor.Black; + NpadColor SingleColorButtons = NpadColor.Black; + + Device.Memory.WriteInt32(Offset + 0x04, IsHalf ? 1 : 0); + + if (IsHalf) + { + Device.Memory.WriteInt32(Offset + 0x08, (int)SingleColorDesc); + Device.Memory.WriteInt32(Offset + 0x0c, (int)SingleColorBody); + Device.Memory.WriteInt32(Offset + 0x10, (int)SingleColorButtons); + Device.Memory.WriteInt32(Offset + 0x14, (int)SplitColorDesc); + } + else + { + Device.Memory.WriteInt32(Offset + 0x18, (int)NpadBodyColors.Left); + Device.Memory.WriteInt32(Offset + 0x1c, (int)NpadButtonColors.Left); + Device.Memory.WriteInt32(Offset + 0x20, (int)NpadBodyColors.Right); + Device.Memory.WriteInt32(Offset + 0x24, (int)NpadButtonColors.Right); + } + + Connected = true; + } + + public override void SendInput + (HidControllerButtons Buttons, + HidJoystickPosition LeftStick, + HidJoystickPosition RightStick) + { + long ControllerOffset = WriteInput(Buttons, LeftStick, RightStick, CurrentLayout); + + Device.Memory.WriteInt64(ControllerOffset + 0x28, + (Connected ? (uint)HidControllerConnState.Controller_State_Connected : 0) | + (CurrentLayout == HidControllerLayouts.Handheld_Joined ? (uint)HidControllerConnState.Controller_State_Wired : 0)); + } + } +} diff --git a/Ryujinx.HLE/Input/HidProController.cs b/Ryujinx.HLE/Input/HidProController.cs new file mode 100644 index 000000000..40c79fede --- /dev/null +++ b/Ryujinx.HLE/Input/HidProController.cs @@ -0,0 +1,44 @@ +namespace Ryujinx.HLE.Input +{ + public class HidProController : HidControllerBase + { + bool Wired = false; + + public HidProController(Switch Device) : base(HidControllerType.ProController, Device) + { + Wired = true; + } + + public override void Connect(HidControllerId ControllerId) + { + base.Connect(ControllerId); + + HidControllerColorDesc SingleColorDesc = + HidControllerColorDesc.ColorDesc_ColorsNonexistent; + + HidControllerColorDesc SplitColorDesc = 0; + + NpadColor SingleColorBody = NpadColor.Black; + NpadColor SingleColorButtons = NpadColor.Black; + + Device.Memory.WriteInt32(Offset + 0x08, (int)SingleColorDesc); + Device.Memory.WriteInt32(Offset + 0x0c, (int)SingleColorBody); + Device.Memory.WriteInt32(Offset + 0x10, (int)SingleColorButtons); + Device.Memory.WriteInt32(Offset + 0x14, (int)SplitColorDesc); + + Connected = true; + } + + public override void SendInput( + HidControllerButtons Buttons, + HidJoystickPosition LeftStick, + HidJoystickPosition RightStick) + { + long ControllerOffset = WriteInput(Buttons, LeftStick, RightStick, HidControllerLayouts.Pro_Controller); + + Device.Memory.WriteInt64(ControllerOffset + 0x28, + (Connected ? (uint)HidControllerConnState.Controller_State_Connected : 0) | + (Wired ? (uint)HidControllerConnState.Controller_State_Wired : 0)); + } + } +} diff --git a/Ryujinx.HLE/Hid/HidTouchPoint.cs b/Ryujinx.HLE/Input/HidTouchPoint.cs similarity index 100% rename from Ryujinx.HLE/Hid/HidTouchPoint.cs rename to Ryujinx.HLE/Input/HidTouchPoint.cs diff --git a/Ryujinx.HLE/Input/HidValues.cs b/Ryujinx.HLE/Input/HidValues.cs new file mode 100644 index 000000000..62bf07077 --- /dev/null +++ b/Ryujinx.HLE/Input/HidValues.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ryujinx.HLE.Input +{ + public partial class Hid + { + /* + * Reference: + * https://github.com/reswitched/libtransistor/blob/development/lib/hid.c + * https://github.com/reswitched/libtransistor/blob/development/include/libtransistor/hid.h + * https://github.com/switchbrew/libnx/blob/master/nx/source/services/hid.c + * https://github.com/switchbrew/libnx/blob/master/nx/include/switch/services/hid.h + */ + + internal const int HidHeaderSize = 0x400; + internal const int HidTouchScreenSize = 0x3000; + internal const int HidMouseSize = 0x400; + internal const int HidKeyboardSize = 0x400; + internal const int HidUnkSection1Size = 0x400; + internal const int HidUnkSection2Size = 0x400; + internal const int HidUnkSection3Size = 0x400; + internal const int HidUnkSection4Size = 0x400; + internal const int HidUnkSection5Size = 0x200; + internal const int HidUnkSection6Size = 0x200; + internal const int HidUnkSection7Size = 0x200; + internal const int HidUnkSection8Size = 0x800; + internal const int HidControllerSerialsSize = 0x4000; + internal const int HidControllersSize = 0x32000; + internal const int HidUnkSection9Size = 0x800; + + internal const int HidTouchHeaderSize = 0x28; + internal const int HidTouchEntrySize = 0x298; + + internal const int HidTouchEntryHeaderSize = 0x10; + internal const int HidTouchEntryTouchSize = 0x28; + + internal const int HidControllerSize = 0x5000; + internal const int HidControllerHeaderSize = 0x28; + internal const int HidControllerLayoutsSize = 0x350; + + internal const int HidControllersLayoutHeaderSize = 0x20; + internal const int HidControllersInputEntrySize = 0x30; + + internal const int HidHeaderOffset = 0; + internal const int HidTouchScreenOffset = HidHeaderOffset + HidHeaderSize; + internal const int HidMouseOffset = HidTouchScreenOffset + HidTouchScreenSize; + internal const int HidKeyboardOffset = HidMouseOffset + HidMouseSize; + internal const int HidUnkSection1Offset = HidKeyboardOffset + HidKeyboardSize; + internal const int HidUnkSection2Offset = HidUnkSection1Offset + HidUnkSection1Size; + internal const int HidUnkSection3Offset = HidUnkSection2Offset + HidUnkSection2Size; + internal const int HidUnkSection4Offset = HidUnkSection3Offset + HidUnkSection3Size; + internal const int HidUnkSection5Offset = HidUnkSection4Offset + HidUnkSection4Size; + internal const int HidUnkSection6Offset = HidUnkSection5Offset + HidUnkSection5Size; + internal const int HidUnkSection7Offset = HidUnkSection6Offset + HidUnkSection6Size; + internal const int HidUnkSection8Offset = HidUnkSection7Offset + HidUnkSection7Size; + internal const int HidControllerSerialsOffset = HidUnkSection8Offset + HidUnkSection8Size; + internal const int HidControllersOffset = HidControllerSerialsOffset + HidControllerSerialsSize; + internal const int HidUnkSection9Offset = HidControllersOffset + HidControllersSize; + + internal const int HidEntryCount = 17; + } +} diff --git a/Ryujinx.HLE/Input/IHidDevice.cs b/Ryujinx.HLE/Input/IHidDevice.cs new file mode 100644 index 000000000..cc67b01a5 --- /dev/null +++ b/Ryujinx.HLE/Input/IHidDevice.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ryujinx.HLE.Input +{ + interface IHidDevice + { + long Offset { get; } + bool Connected { get; } + } +} diff --git a/Ryujinx.HLE/Hid/JoyConColor.cs b/Ryujinx.HLE/Input/NpadColor.cs similarity index 92% rename from Ryujinx.HLE/Hid/JoyConColor.cs rename to Ryujinx.HLE/Input/NpadColor.cs index 514ec21b0..b152b789e 100644 --- a/Ryujinx.HLE/Hid/JoyConColor.cs +++ b/Ryujinx.HLE/Input/NpadColor.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.Input { - public enum JoyConColor //Thanks to CTCaer + public enum NpadColor //Thanks to CTCaer { Black = 0, diff --git a/Ryujinx/Config.cs b/Ryujinx/Config.cs index dcead6483..216ed0a57 100644 --- a/Ryujinx/Config.cs +++ b/Ryujinx/Config.cs @@ -1,10 +1,11 @@ using LibHac; using Ryujinx.Common.Logging; using Ryujinx.HLE; +using Ryujinx.HLE.Input; using Ryujinx.UI.Input; using System; -using System.Globalization; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Reflection; @@ -13,8 +14,8 @@ namespace Ryujinx { public static class Config { - public static JoyConKeyboard JoyConKeyboard { get; private set; } - public static JoyConController JoyConController { get; private set; } + public static NpadKeyboard NpadKeyboard { get; private set; } + public static NpadController NpadController { get; private set; } public static void Read(Switch device) { @@ -73,9 +74,13 @@ namespace Ryujinx ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None; - JoyConKeyboard = new JoyConKeyboard( + HidControllerType ControllerType = Enum.Parse(parser.Value("Controller_Type")); - new JoyConKeyboardLeft + device.Hid.InitilizePrimaryController(ControllerType); + + NpadKeyboard = new NpadKeyboard( + + new NpadKeyboardLeft { StickUp = Convert.ToInt16(parser.Value("Controls_Left_JoyConKeyboard_Stick_Up")), StickDown = Convert.ToInt16(parser.Value("Controls_Left_JoyConKeyboard_Stick_Down")), @@ -91,7 +96,7 @@ namespace Ryujinx ButtonZl = Convert.ToInt16(parser.Value("Controls_Left_JoyConKeyboard_Button_ZL")) }, - new JoyConKeyboardRight + new NpadKeyboardRight { StickUp = Convert.ToInt16(parser.Value("Controls_Right_JoyConKeyboard_Stick_Up")), StickDown = Convert.ToInt16(parser.Value("Controls_Right_JoyConKeyboard_Stick_Down")), @@ -107,14 +112,14 @@ namespace Ryujinx ButtonZr = Convert.ToInt16(parser.Value("Controls_Right_JoyConKeyboard_Button_ZR")) }); - JoyConController = new JoyConController( + NpadController = new NpadController( 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), - new JoyConControllerLeft + new NpadControllerLeft { Stick = ToId(parser.Value("Controls_Left_JoyConController_Stick")), StickButton = ToId(parser.Value("Controls_Left_JoyConController_Stick_Button")), @@ -127,7 +132,7 @@ namespace Ryujinx ButtonZl = ToId(parser.Value("Controls_Left_JoyConController_Button_ZL")) }, - new JoyConControllerRight + new NpadControllerRight { Stick = ToId(parser.Value("Controls_Right_JoyConController_Stick")), StickButton = ToId(parser.Value("Controls_Right_JoyConController_Stick_Button")), diff --git a/Ryujinx/Ryujinx.conf b/Ryujinx/Ryujinx.conf index 45f545d00..5b646a2ad 100644 --- a/Ryujinx/Ryujinx.conf +++ b/Ryujinx/Ryujinx.conf @@ -46,6 +46,9 @@ GamePad_Trigger_Threshold = 0.5 #Whether or not to enable Controller support GamePad_Enable = true +#The primary controller's type. Supported Values: ProController, Handheld, NpadPair, NpadLeft, NpadRight +Controller_Type = Handheld + #https://github.com/opentk/opentk/blob/develop/src/OpenTK/Input/Key.cs Controls_Left_JoyConKeyboard_Stick_Up = 105 Controls_Left_JoyConKeyboard_Stick_Down = 101 diff --git a/Ryujinx/Ui/GLScreen.cs b/Ryujinx/Ui/GLScreen.cs index a654d1503..6acb199c1 100644 --- a/Ryujinx/Ui/GLScreen.cs +++ b/Ryujinx/Ui/GLScreen.cs @@ -142,25 +142,24 @@ namespace Ryujinx { KeyboardState keyboard = _keyboard.Value; - currentButton = Config.JoyConKeyboard.GetButtons(keyboard); + currentButton = Config.NpadKeyboard.GetButtons(keyboard); - (leftJoystickDx, leftJoystickDy) = Config.JoyConKeyboard.GetLeftStick(keyboard); + (leftJoystickDx, leftJoystickDy) = Config.NpadKeyboard.GetLeftStick(keyboard); - (rightJoystickDx, rightJoystickDy) = Config.JoyConKeyboard.GetRightStick(keyboard); + (rightJoystickDx, rightJoystickDy) = Config.NpadKeyboard.GetRightStick(keyboard); } - - //Controller Input - currentButton |= Config.JoyConController.GetButtons(); + + currentButton |= Config.NpadController.GetButtons(); //Keyboard has priority stick-wise if (leftJoystickDx == 0 && leftJoystickDy == 0) { - (leftJoystickDx, leftJoystickDy) = Config.JoyConController.GetLeftStick(); + (leftJoystickDx, leftJoystickDy) = Config.NpadController.GetLeftStick(); } if (rightJoystickDx == 0 && rightJoystickDy == 0) { - (rightJoystickDx, rightJoystickDy) = Config.JoyConController.GetRightStick(); + (rightJoystickDx, rightJoystickDy) = Config.NpadController.GetRightStick(); } leftJoystick = new HidJoystickPosition @@ -234,19 +233,9 @@ namespace Ryujinx _device.Hid.SetTouchPoints(); } - _device.Hid.SetJoyconButton( - HidControllerId.CONTROLLER_HANDHELD, - HidControllerLayouts.Handheld_Joined, - currentButton, - leftJoystick, - rightJoystick); + HidControllerBase controller = _device.Hid.PrimaryController; - _device.Hid.SetJoyconButton( - HidControllerId.CONTROLLER_HANDHELD, - HidControllerLayouts.Main, - currentButton, - leftJoystick, - rightJoystick); + controller.SendInput(currentButton, leftJoystick, rightJoystick); } private new void RenderFrame() diff --git a/Ryujinx/Ui/JoyConController.cs b/Ryujinx/Ui/NpadController.cs similarity index 89% rename from Ryujinx/Ui/JoyConController.cs rename to Ryujinx/Ui/NpadController.cs index 28b631b23..58d2d46a2 100644 --- a/Ryujinx/Ui/JoyConController.cs +++ b/Ryujinx/Ui/NpadController.cs @@ -32,7 +32,7 @@ namespace Ryujinx.UI.Input RJoystick } - public struct JoyConControllerLeft + public struct NpadControllerLeft { public ControllerInputId Stick; public ControllerInputId StickButton; @@ -45,7 +45,7 @@ namespace Ryujinx.UI.Input public ControllerInputId ButtonZl; } - public struct JoyConControllerRight + public struct NpadControllerRight { public ControllerInputId Stick; public ControllerInputId StickButton; @@ -58,23 +58,23 @@ namespace Ryujinx.UI.Input public ControllerInputId ButtonZr; } - public class JoyConController + public class NpadController { public bool Enabled { private set; get; } public int Index { private set; get; } public float Deadzone { private set; get; } public float TriggerThreshold { private set; get; } - public JoyConControllerLeft Left { private set; get; } - public JoyConControllerRight Right { private set; get; } + public NpadControllerLeft Left { private set; get; } + public NpadControllerRight Right { private set; get; } - public JoyConController( + public NpadController( bool enabled, int index, float deadzone, float triggerThreshold, - JoyConControllerLeft left, - JoyConControllerRight right) + NpadControllerLeft left, + NpadControllerRight right) { Enabled = enabled; Index = index; @@ -101,23 +101,23 @@ namespace Ryujinx.UI.Input HidControllerButtons buttons = 0; - if (IsPressed(gpState, Left.DPadUp)) buttons |= HidControllerButtons.KEY_DUP; - if (IsPressed(gpState, Left.DPadDown)) buttons |= HidControllerButtons.KEY_DDOWN; - if (IsPressed(gpState, Left.DPadLeft)) buttons |= HidControllerButtons.KEY_DLEFT; - if (IsPressed(gpState, Left.DPadRight)) buttons |= HidControllerButtons.KEY_DRIGHT; - if (IsPressed(gpState, Left.StickButton)) buttons |= HidControllerButtons.KEY_LSTICK; - if (IsPressed(gpState, Left.ButtonMinus)) buttons |= HidControllerButtons.KEY_MINUS; - if (IsPressed(gpState, Left.ButtonL)) buttons |= HidControllerButtons.KEY_L; - if (IsPressed(gpState, Left.ButtonZl)) buttons |= HidControllerButtons.KEY_ZL; + if (IsPressed(gpState, Left.DPadUp)) buttons |= HidControllerButtons.DpadUp; + if (IsPressed(gpState, Left.DPadDown)) buttons |= HidControllerButtons.DpadDown; + if (IsPressed(gpState, Left.DPadLeft)) buttons |= HidControllerButtons.DpadLeft; + if (IsPressed(gpState, Left.DPadRight)) buttons |= HidControllerButtons.DPadRight; + if (IsPressed(gpState, Left.StickButton)) buttons |= HidControllerButtons.StickLeft; + if (IsPressed(gpState, Left.ButtonMinus)) buttons |= HidControllerButtons.Minus; + if (IsPressed(gpState, Left.ButtonL)) buttons |= HidControllerButtons.L; + if (IsPressed(gpState, Left.ButtonZl)) buttons |= HidControllerButtons.Zl; - if (IsPressed(gpState, Right.ButtonA)) buttons |= HidControllerButtons.KEY_A; - if (IsPressed(gpState, Right.ButtonB)) buttons |= HidControllerButtons.KEY_B; - if (IsPressed(gpState, Right.ButtonX)) buttons |= HidControllerButtons.KEY_X; - if (IsPressed(gpState, Right.ButtonY)) buttons |= HidControllerButtons.KEY_Y; - if (IsPressed(gpState, Right.StickButton)) buttons |= HidControllerButtons.KEY_RSTICK; - if (IsPressed(gpState, Right.ButtonPlus)) buttons |= HidControllerButtons.KEY_PLUS; - if (IsPressed(gpState, Right.ButtonR)) buttons |= HidControllerButtons.KEY_R; - if (IsPressed(gpState, Right.ButtonZr)) buttons |= HidControllerButtons.KEY_ZR; + if (IsPressed(gpState, Right.ButtonA)) buttons |= HidControllerButtons.A; + if (IsPressed(gpState, Right.ButtonB)) buttons |= HidControllerButtons.B; + if (IsPressed(gpState, Right.ButtonX)) buttons |= HidControllerButtons.X; + if (IsPressed(gpState, Right.ButtonY)) buttons |= HidControllerButtons.Y; + if (IsPressed(gpState, Right.StickButton)) buttons |= HidControllerButtons.StickRight; + if (IsPressed(gpState, Right.ButtonPlus)) buttons |= HidControllerButtons.Plus; + if (IsPressed(gpState, Right.ButtonR)) buttons |= HidControllerButtons.R; + if (IsPressed(gpState, Right.ButtonZr)) buttons |= HidControllerButtons.Zr; return buttons; } diff --git a/Ryujinx/Ui/JoyConKeyboard.cs b/Ryujinx/Ui/NpadKeyboard.cs similarity index 80% rename from Ryujinx/Ui/JoyConKeyboard.cs rename to Ryujinx/Ui/NpadKeyboard.cs index fd399fe8d..704c61abc 100644 --- a/Ryujinx/Ui/JoyConKeyboard.cs +++ b/Ryujinx/Ui/NpadKeyboard.cs @@ -3,7 +3,7 @@ using Ryujinx.HLE.Input; namespace Ryujinx.UI.Input { - public struct JoyConKeyboardLeft + public struct NpadKeyboardLeft { public int StickUp; public int StickDown; @@ -19,7 +19,7 @@ namespace Ryujinx.UI.Input public int ButtonZl; } - public struct JoyConKeyboardRight + public struct NpadKeyboardRight { public int StickUp; public int StickDown; @@ -35,14 +35,14 @@ namespace Ryujinx.UI.Input public int ButtonZr; } - public class JoyConKeyboard + public class NpadKeyboard { - public JoyConKeyboardLeft Left; - public JoyConKeyboardRight Right; + public NpadKeyboardLeft Left; + public NpadKeyboardRight Right; - public JoyConKeyboard( - JoyConKeyboardLeft left, - JoyConKeyboardRight right) + public NpadKeyboard( + NpadKeyboardLeft left, + NpadKeyboardRight right) { Left = left; Right = right; @@ -52,23 +52,23 @@ namespace Ryujinx.UI.Input { HidControllerButtons buttons = 0; - if (keyboard[(Key)Left.StickButton]) buttons |= HidControllerButtons.KEY_LSTICK; - if (keyboard[(Key)Left.DPadUp]) buttons |= HidControllerButtons.KEY_DUP; - if (keyboard[(Key)Left.DPadDown]) buttons |= HidControllerButtons.KEY_DDOWN; - if (keyboard[(Key)Left.DPadLeft]) buttons |= HidControllerButtons.KEY_DLEFT; - if (keyboard[(Key)Left.DPadRight]) buttons |= HidControllerButtons.KEY_DRIGHT; - if (keyboard[(Key)Left.ButtonMinus]) buttons |= HidControllerButtons.KEY_MINUS; - if (keyboard[(Key)Left.ButtonL]) buttons |= HidControllerButtons.KEY_L; - if (keyboard[(Key)Left.ButtonZl]) buttons |= HidControllerButtons.KEY_ZL; + if (keyboard[(Key)Left.StickButton]) buttons |= HidControllerButtons.StickLeft; + if (keyboard[(Key)Left.DPadUp]) buttons |= HidControllerButtons.DpadUp; + if (keyboard[(Key)Left.DPadDown]) buttons |= HidControllerButtons.DpadDown; + if (keyboard[(Key)Left.DPadLeft]) buttons |= HidControllerButtons.DpadLeft; + if (keyboard[(Key)Left.DPadRight]) buttons |= HidControllerButtons.DPadRight; + if (keyboard[(Key)Left.ButtonMinus]) buttons |= HidControllerButtons.Minus; + if (keyboard[(Key)Left.ButtonL]) buttons |= HidControllerButtons.L; + if (keyboard[(Key)Left.ButtonZl]) buttons |= HidControllerButtons.Zl; - if (keyboard[(Key)Right.StickButton]) buttons |= HidControllerButtons.KEY_RSTICK; - if (keyboard[(Key)Right.ButtonA]) buttons |= HidControllerButtons.KEY_A; - if (keyboard[(Key)Right.ButtonB]) buttons |= HidControllerButtons.KEY_B; - if (keyboard[(Key)Right.ButtonX]) buttons |= HidControllerButtons.KEY_X; - if (keyboard[(Key)Right.ButtonY]) buttons |= HidControllerButtons.KEY_Y; - if (keyboard[(Key)Right.ButtonPlus]) buttons |= HidControllerButtons.KEY_PLUS; - if (keyboard[(Key)Right.ButtonR]) buttons |= HidControllerButtons.KEY_R; - if (keyboard[(Key)Right.ButtonZr]) buttons |= HidControllerButtons.KEY_ZR; + if (keyboard[(Key)Right.StickButton]) buttons |= HidControllerButtons.StickRight; + if (keyboard[(Key)Right.ButtonA]) buttons |= HidControllerButtons.A; + if (keyboard[(Key)Right.ButtonB]) buttons |= HidControllerButtons.B; + if (keyboard[(Key)Right.ButtonX]) buttons |= HidControllerButtons.X; + if (keyboard[(Key)Right.ButtonY]) buttons |= HidControllerButtons.Y; + if (keyboard[(Key)Right.ButtonPlus]) buttons |= HidControllerButtons.Plus; + if (keyboard[(Key)Right.ButtonR]) buttons |= HidControllerButtons.R; + if (keyboard[(Key)Right.ButtonZr]) buttons |= HidControllerButtons.Zr; return buttons; }