aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.HLE/DeviceMemory.cs6
-rw-r--r--Ryujinx.HLE/Exceptions/InvalidStructLayoutException.cs15
-rw-r--r--Ryujinx.HLE/HOS/Applets/AppletManager.cs1
-rw-r--r--Ryujinx.HLE/HOS/Applets/Controller/ControllerApplet.cs114
-rw-r--r--Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArg.cs11
-rw-r--r--Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArgHeader.cs13
-rw-r--r--Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArgPrivate.cs14
-rw-r--r--Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportMode.cs9
-rw-r--r--Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportResultInfo.cs10
-rw-r--r--Ryujinx.HLE/HOS/Applets/IApplet.cs6
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs17
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Hid.cs88
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidDevices/BaseDevice.cs29
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidDevices/DebugPadDevice.cs24
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidDevices/KeyboardDevice.cs32
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidDevices/MouseDevice.cs37
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs332
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidDevices/TouchDevice.cs46
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/ControllerConfig.cs8
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/GamepadInput.cs10
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/JoystickPosition.cs (renamed from Ryujinx.HLE/Input/Controller/Types/JoystickPosition.cs)2
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/KeyboardInput.cs8
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/TouchPoint.cs11
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidServer/HidUtils.cs65
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/HidNpadHandheldActivationMode.cs (renamed from Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadHandheldActivationMode.cs)0
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/HidNpadJoyAssignmentMode.cs (renamed from Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadJoyAssignmentMode.cs)0
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/HidNpadJoyDeviceType.cs (renamed from Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadJoyDeviceType.cs)0
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/HidAccelerometerParameters.cs (renamed from Ryujinx.HLE/HOS/Services/Hid/Types/SixAxis/HidAccelerometerParameters.cs)0
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/HidGyroscopeZeroDriftMode.cs (renamed from Ryujinx.HLE/HOS/Services/Hid/Types/SixAxis/HidGyroscopeZeroDriftMode.cs)0
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/HidSensorFusionParameters.cs (renamed from Ryujinx.HLE/HOS/Services/Hid/Types/SixAxis/HidSensorFusionParameters.cs)0
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDevicePosition.cs (renamed from Ryujinx.HLE/HOS/Services/Hid/Types/Vibration/HidVibrationDevicePosition.cs)0
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDeviceType.cs (renamed from Ryujinx.HLE/HOS/Services/Hid/Types/Vibration/HidVibrationDeviceType.cs)0
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDeviceValue.cs (renamed from Ryujinx.HLE/HOS/Services/Hid/Types/Vibration/HidVibrationDeviceValue.cs)0
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationValue.cs (renamed from Ryujinx.HLE/HOS/Services/Hid/Types/Vibration/HidVibrationValue.cs)0
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs85
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Irs/IIrSensorServer.cs11
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/Boolean32.cs9
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerKeys.cs45
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerType.cs19
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadJoyHoldType.cs8
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadStyle.cs16
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadColor.cs37
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadIdType.cs (renamed from Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadIdType.cs)2
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/Npad/PlayerIndex.cs17
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/CommonEntriesHeader.cs11
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/DebugPad/DebugPad.cs9
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/DebugPad/DebugPadEntry.cs8
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/HidSharedMemory.cs24
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Keyboard/Keyboard.cs9
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Keyboard/KeyboardState.cs10
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/Mouse.cs10
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/MousePosition.cs12
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/MouseState.cs10
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/BatterCharge.cs11
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/DeviceType.cs26
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/HidVector.cs9
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/Npad.cs21
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadColorDescription.cs (renamed from Ryujinx.HLE/Input/Controller/Types/ControllerColorDescription.cs)4
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadConnectionState.cs13
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadJoyHoldType.cs8
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayout.cs8
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayoutsIndex.cs13
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadSixAxis.cs8
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadState.cs14
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadStatesHeader.cs16
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadSystemProperties.cs22
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/SixAxisState.cs14
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/StructArrayHelpers.cs53
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreen.cs9
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenState.cs10
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenStateData.cs15
-rw-r--r--Ryujinx.HLE/HOS/Services/Nfc/Nfp/UserManager/IUser.cs4
-rw-r--r--Ryujinx.HLE/HOS/Services/Nfc/Nfp/UserManager/Types/Device.cs5
-rw-r--r--Ryujinx.HLE/Input/Controller/BaseController.cs142
-rw-r--r--Ryujinx.HLE/Input/Controller/NpadController.cs68
-rw-r--r--Ryujinx.HLE/Input/Controller/ProController.cs42
-rw-r--r--Ryujinx.HLE/Input/Controller/Types/BatteryState.cs12
-rw-r--r--Ryujinx.HLE/Input/Controller/Types/ControllerButtons.cs35
-rw-r--r--Ryujinx.HLE/Input/Controller/Types/ControllerConnectionState.cs11
-rw-r--r--Ryujinx.HLE/Input/Controller/Types/ControllerDeviceState.cs18
-rw-r--r--Ryujinx.HLE/Input/Controller/Types/ControllerDeviceType.cs12
-rw-r--r--Ryujinx.HLE/Input/Controller/Types/ControllerHeader.cs19
-rw-r--r--Ryujinx.HLE/Input/Controller/Types/ControllerId.cs16
-rw-r--r--Ryujinx.HLE/Input/Controller/Types/ControllerLayouts.cs13
-rw-r--r--Ryujinx.HLE/Input/Controller/Types/ControllerState.cs15
-rw-r--r--Ryujinx.HLE/Input/Controller/Types/ControllerStateHeader.cs13
-rw-r--r--Ryujinx.HLE/Input/Controller/Types/ControllerStatus.cs14
-rw-r--r--Ryujinx.HLE/Input/Controller/Types/DeviceFlags.cs22
-rw-r--r--Ryujinx.HLE/Input/Controller/Types/HotkeyButtons.cs10
-rw-r--r--Ryujinx.HLE/Input/Controller/Types/NpadColor.cs23
-rw-r--r--Ryujinx.HLE/Input/Hid.cs218
-rw-r--r--Ryujinx.HLE/Input/HidValues.cs63
-rw-r--r--Ryujinx.HLE/Input/IHidDevice.cs8
-rw-r--r--Ryujinx.HLE/Input/Keyboard/Keyboard.cs8
-rw-r--r--Ryujinx.HLE/Input/Keyboard/KeyboardEntry.cs15
-rw-r--r--Ryujinx.HLE/Input/Keyboard/KeyboardHeader.cs13
-rw-r--r--Ryujinx.HLE/Input/Touch/TouchData.cs18
-rw-r--r--Ryujinx.HLE/Input/Touch/TouchEntry.cs11
-rw-r--r--Ryujinx.HLE/Input/Touch/TouchHeader.cs14
-rw-r--r--Ryujinx.HLE/Input/Touch/TouchPoint.cs11
-rw-r--r--Ryujinx.HLE/Switch.cs3
-rw-r--r--Ryujinx/Ui/GLRenderer.cs28
-rw-r--r--Ryujinx/Ui/KeyboardControls.cs53
-rw-r--r--Ryujinx/Ui/MainWindow.cs15
-rw-r--r--Ryujinx/Ui/NpadController.cs44
105 files changed, 1503 insertions, 1047 deletions
diff --git a/Ryujinx.HLE/DeviceMemory.cs b/Ryujinx.HLE/DeviceMemory.cs
index 38864bc2..22945b83 100644
--- a/Ryujinx.HLE/DeviceMemory.cs
+++ b/Ryujinx.HLE/DeviceMemory.cs
@@ -1,6 +1,7 @@
using ARMeilleure.Memory;
using System;
using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
namespace Ryujinx.HLE
{
@@ -64,6 +65,11 @@ namespace Ryujinx.HLE
return Marshal.PtrToStructure<T>((IntPtr)(_ramPtr + position));
}
+ public unsafe ref T GetStructRef<T>(long position)
+ {
+ return ref Unsafe.AsRef<T>((void*)(IntPtr)(_ramPtr + position));
+ }
+
public void WriteSByte(long position, sbyte value)
{
WriteByte(position, (byte)value);
diff --git a/Ryujinx.HLE/Exceptions/InvalidStructLayoutException.cs b/Ryujinx.HLE/Exceptions/InvalidStructLayoutException.cs
new file mode 100644
index 00000000..f4ccb7ba
--- /dev/null
+++ b/Ryujinx.HLE/Exceptions/InvalidStructLayoutException.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace Ryujinx.HLE.Exceptions
+{
+ public class InvalidStructLayoutException<T> : Exception
+ {
+ static readonly Type _structType = typeof(T);
+
+ public InvalidStructLayoutException(string message) : base(message) {}
+
+ public InvalidStructLayoutException(int expectedSize) :
+ base($"Type {_structType.Name} has the wrong size. Expected: {expectedSize} bytes, Got: {Unsafe.SizeOf<T>()} bytes") {}
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Applets/AppletManager.cs b/Ryujinx.HLE/HOS/Applets/AppletManager.cs
index e7314540..1cba9ec9 100644
--- a/Ryujinx.HLE/HOS/Applets/AppletManager.cs
+++ b/Ryujinx.HLE/HOS/Applets/AppletManager.cs
@@ -13,6 +13,7 @@ namespace Ryujinx.HLE.HOS.Applets
_appletMapping = new Dictionary<AppletId, Type>
{
{ AppletId.PlayerSelect, typeof(PlayerSelectApplet) },
+ { AppletId.Controller, typeof(ControllerApplet) },
{ AppletId.SoftwareKeyboard, typeof(SoftwareKeyboardApplet) }
};
}
diff --git a/Ryujinx.HLE/HOS/Applets/Controller/ControllerApplet.cs b/Ryujinx.HLE/HOS/Applets/Controller/ControllerApplet.cs
new file mode 100644
index 00000000..5bfffdb2
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Applets/Controller/ControllerApplet.cs
@@ -0,0 +1,114 @@
+using System;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using Ryujinx.Common.Logging;
+using Ryujinx.HLE.HOS.Services.Hid;
+using Ryujinx.HLE.HOS.Services.Am.AppletAE;
+
+using static Ryujinx.HLE.HOS.Services.Hid.HidServer.HidUtils;
+
+namespace Ryujinx.HLE.HOS.Applets
+{
+ internal class ControllerApplet : IApplet
+ {
+ private Horizon _system;
+
+ private AppletSession _normalSession;
+
+ public event EventHandler AppletStateChanged;
+
+ public ControllerApplet(Horizon system)
+ {
+ _system = system;
+ }
+
+ unsafe public ResultCode Start(AppletSession normalSession,
+ AppletSession interactiveSession)
+ {
+ _normalSession = normalSession;
+
+ byte[] launchParams = _normalSession.Pop();
+ byte[] controllerSupportArgPrivate = _normalSession.Pop();
+ ControllerSupportArgPrivate privateArg = IApplet.ReadStruct<ControllerSupportArgPrivate>(controllerSupportArgPrivate);
+
+ Logger.PrintStub(LogClass.ServiceHid, $"ControllerApplet ArgPriv {privateArg.PrivateSize} {privateArg.ArgSize} {privateArg.Mode}" +
+ $"HoldType:{(NpadJoyHoldType)privateArg.NpadJoyHoldType} StyleSets:{(ControllerType)privateArg.NpadStyleSet}");
+
+ if (privateArg.Mode != ControllerSupportMode.ShowControllerSupport)
+ {
+ _normalSession.Push(BuildResponse()); // Dummy response for other modes
+ AppletStateChanged?.Invoke(this, null);
+
+ return ResultCode.Success;
+ }
+
+ byte[] controllerSupportArg = _normalSession.Pop();
+
+ ControllerSupportArgHeader argHeader;
+
+ if (privateArg.ArgSize == Marshal.SizeOf<ControllerSupportArg>())
+ {
+ ControllerSupportArg arg = IApplet.ReadStruct<ControllerSupportArg>(controllerSupportArg);
+ argHeader = arg.Header;
+ // Read enable text here?
+ }
+ else
+ {
+ Logger.PrintStub(LogClass.ServiceHid, $"Unknown revision of ControllerSupportArg.");
+
+ argHeader = IApplet.ReadStruct<ControllerSupportArgHeader>(controllerSupportArg); // Read just the header
+ }
+
+ Logger.PrintStub(LogClass.ServiceHid, $"ControllerApplet Arg {argHeader.PlayerCountMin} {argHeader.PlayerCountMax} {argHeader.EnableTakeOverConnection} {argHeader.EnableSingleMode}");
+
+ // Currently, the only purpose of this applet is to help
+ // choose the primary input controller for the game
+ // TODO: Ideally should hook back to HID.Controller. When applet is called, can choose appropriate controller and attach to appropriate id.
+ if (argHeader.PlayerCountMin > 1)
+ {
+ Logger.PrintWarning(LogClass.ServiceHid, "More than one controller was requested.");
+ }
+
+ ControllerSupportResultInfo result = new ControllerSupportResultInfo
+ {
+ PlayerCount = 1,
+ SelectedId = (uint)GetNpadIdTypeFromIndex(_system.Device.Hid.Npads.PrimaryController)
+ };
+
+ Logger.PrintStub(LogClass.ServiceHid, $"ControllerApplet ReturnResult {result.PlayerCount} {result.SelectedId}");
+
+ _normalSession.Push(BuildResponse(result));
+ AppletStateChanged?.Invoke(this, null);
+
+ return ResultCode.Success;
+ }
+
+ public ResultCode GetResult()
+ {
+ return ResultCode.Success;
+ }
+
+ private byte[] BuildResponse(ControllerSupportResultInfo result)
+ {
+ using (MemoryStream stream = new MemoryStream())
+ using (BinaryWriter writer = new BinaryWriter(stream))
+ {
+ writer.Write(MemoryMarshal.AsBytes(MemoryMarshal.CreateReadOnlySpan(ref result, Unsafe.SizeOf<ControllerSupportResultInfo>())));
+
+ return stream.ToArray();
+ }
+ }
+
+ private byte[] BuildResponse()
+ {
+ using (MemoryStream stream = new MemoryStream())
+ using (BinaryWriter writer = new BinaryWriter(stream))
+ {
+ writer.Write((ulong)ResultCode.Success);
+
+ return stream.ToArray();
+ }
+ }
+ }
+}
diff --git a/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArg.cs b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArg.cs
new file mode 100644
index 00000000..62ebff30
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArg.cs
@@ -0,0 +1,11 @@
+namespace Ryujinx.HLE.HOS.Applets
+{
+ // (8.0.0+ version)
+ unsafe struct ControllerSupportArg
+ {
+ public ControllerSupportArgHeader Header;
+ public fixed uint IdentificationColor[8];
+ public byte EnableExplainText;
+ public fixed byte ExplainText[8 * 0x81];
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArgHeader.cs b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArgHeader.cs
new file mode 100644
index 00000000..dfe26093
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArgHeader.cs
@@ -0,0 +1,13 @@
+namespace Ryujinx.HLE.HOS.Applets
+{
+ struct ControllerSupportArgHeader
+ {
+ public sbyte PlayerCountMin;
+ public sbyte PlayerCountMax;
+ public byte EnableTakeOverConnection;
+ public byte EnableLeftJustify;
+ public byte EnablePermitJoyDual;
+ public byte EnableSingleMode;
+ public byte EnableIdentificationColor;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArgPrivate.cs b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArgPrivate.cs
new file mode 100644
index 00000000..2e393de4
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArgPrivate.cs
@@ -0,0 +1,14 @@
+namespace Ryujinx.HLE.HOS.Applets
+{
+ struct ControllerSupportArgPrivate
+ {
+ public uint PrivateSize;
+ public uint ArgSize;
+ public byte Flag0;
+ public byte Flag1;
+ public ControllerSupportMode Mode;
+ public byte ControllerSupportCaller;
+ public uint NpadStyleSet;
+ public uint NpadJoyHoldType;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportMode.cs b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportMode.cs
new file mode 100644
index 00000000..9496c1dd
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportMode.cs
@@ -0,0 +1,9 @@
+namespace Ryujinx.HLE.HOS.Applets
+{
+ enum ControllerSupportMode : byte
+ {
+ ShowControllerSupport = 0,
+ ShowControllerStrapGuide = 1,
+ ShowControllerFirmwareUpdate = 2
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportResultInfo.cs b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportResultInfo.cs
new file mode 100644
index 00000000..4fcd37db
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportResultInfo.cs
@@ -0,0 +1,10 @@
+namespace Ryujinx.HLE.HOS.Applets
+{
+ unsafe struct ControllerSupportResultInfo
+ {
+ public sbyte PlayerCount;
+ fixed byte _padding[3];
+ public uint SelectedId;
+ public uint Result;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Applets/IApplet.cs b/Ryujinx.HLE/HOS/Applets/IApplet.cs
index c2d4aada..b10ede68 100644
--- a/Ryujinx.HLE/HOS/Applets/IApplet.cs
+++ b/Ryujinx.HLE/HOS/Applets/IApplet.cs
@@ -1,5 +1,6 @@
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
using System;
+using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Applets
{
@@ -11,5 +12,10 @@ namespace Ryujinx.HLE.HOS.Applets
AppletSession interactiveSession);
ResultCode GetResult();
+
+ static T ReadStruct<T>(ReadOnlySpan<byte> data) where T : struct
+ {
+ return MemoryMarshal.Cast<byte, T>(data)[0];
+ }
}
}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs
index e142838c..ed54eb98 100644
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs
+++ b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs
@@ -41,7 +41,7 @@ namespace Ryujinx.HLE.HOS.Applets
var keyboardConfig = _normalSession.Pop();
var transferMemory = _normalSession.Pop();
- _keyboardConfig = ReadStruct<SoftwareKeyboardConfig>(keyboardConfig);
+ _keyboardConfig = IApplet.ReadStruct<SoftwareKeyboardConfig>(keyboardConfig);
if (_keyboardConfig.UseUtf8)
{
@@ -176,20 +176,5 @@ namespace Ryujinx.HLE.HOS.Applets
return stream.ToArray();
}
}
-
- private static T ReadStruct<T>(byte[] data)
- where T : struct
- {
- GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
-
- try
- {
- return Marshal.PtrToStructure<T>(handle.AddrOfPinnedObject());
- }
- finally
- {
- handle.Free();
- }
- }
}
}
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Hid.cs b/Ryujinx.HLE/HOS/Services/Hid/Hid.cs
new file mode 100644
index 00000000..e07577ed
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Hid.cs
@@ -0,0 +1,88 @@
+using Ryujinx.Common;
+using Ryujinx.HLE.Exceptions;
+using System.Runtime.CompilerServices;
+
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ public class Hid
+ {
+ private readonly Switch _device;
+ private long _hidMemoryAddress;
+
+ internal ref HidSharedMemory SharedMemory => ref _device.Memory.GetStructRef<HidSharedMemory>(_hidMemoryAddress);
+ internal const int SharedMemEntryCount = 17;
+
+ public DebugPadDevice DebugPad;
+ public TouchDevice Touchscreen;
+ public MouseDevice Mouse;
+ public KeyboardDevice Keyboard;
+ public NpadDevices Npads;
+
+ static Hid()
+ {
+ if (Unsafe.SizeOf<ShMemDebugPad>() != 0x400)
+ {
+ throw new InvalidStructLayoutException<ShMemDebugPad>(0x400);
+ }
+ if (Unsafe.SizeOf<ShMemTouchScreen>() != 0x3000)
+ {
+ throw new InvalidStructLayoutException<ShMemTouchScreen>(0x3000);
+ }
+ if (Unsafe.SizeOf<ShMemKeyboard>() != 0x400)
+ {
+ throw new InvalidStructLayoutException<ShMemKeyboard>(0x400);
+ }
+ if (Unsafe.SizeOf<ShMemMouse>() != 0x400)
+ {
+ throw new InvalidStructLayoutException<ShMemMouse>(0x400);
+ }
+ if (Unsafe.SizeOf<ShMemNpad>() != 0x5000)
+ {
+ throw new InvalidStructLayoutException<ShMemNpad>(0x5000);
+ }
+ if (Unsafe.SizeOf<HidSharedMemory>() != Horizon.HidSize)
+ {
+ throw new InvalidStructLayoutException<HidSharedMemory>(Horizon.HidSize);
+ }
+ }
+
+ public Hid(in Switch device, long sharedHidMemoryAddress)
+ {
+ _device = device;
+ _hidMemoryAddress = sharedHidMemoryAddress;
+
+ device.Memory.FillWithZeros(sharedHidMemoryAddress, Horizon.HidSize);
+ }
+
+ public void InitDevices()
+ {
+ DebugPad = new DebugPadDevice(_device, true);
+ Touchscreen = new TouchDevice(_device, true);
+ Mouse = new MouseDevice(_device, false);
+ Keyboard = new KeyboardDevice(_device, false);
+ Npads = new NpadDevices(_device, true);
+ }
+
+ public ControllerKeys UpdateStickButtons(JoystickPosition leftStick, JoystickPosition rightStick)
+ {
+ ControllerKeys result = 0;
+
+ result |= (leftStick.Dx < 0) ? ControllerKeys.LStickLeft : result;
+ result |= (leftStick.Dx > 0) ? ControllerKeys.LStickRight : result;
+ result |= (leftStick.Dy < 0) ? ControllerKeys.LStickDown : result;
+ result |= (leftStick.Dy > 0) ? ControllerKeys.LStickUp : result;
+
+ result |= (rightStick.Dx < 0) ? ControllerKeys.RStickLeft : result;
+ result |= (rightStick.Dx > 0) ? ControllerKeys.RStickRight : result;
+ result |= (rightStick.Dy < 0) ? ControllerKeys.RStickDown : result;
+ result |= (rightStick.Dy > 0) ? ControllerKeys.RStickUp : result;
+
+ return result;
+ }
+
+ internal static ulong GetTimestampTicks()
+ {
+ return (ulong)PerformanceCounter.ElapsedMilliseconds * 19200;
+ }
+ }
+}
diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/BaseDevice.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/BaseDevice.cs
new file mode 100644
index 00000000..59d6dfa3
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/BaseDevice.cs
@@ -0,0 +1,29 @@
+using static Ryujinx.HLE.HOS.Services.Hid.Hid;
+
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ public abstract class BaseDevice
+ {
+ protected readonly Switch _device;
+ public bool Active;
+
+ public BaseDevice(Switch device, bool active)
+ {
+ _device = device;
+ Active = active;
+ }
+
+ internal static int UpdateEntriesHeader(ref CommonEntriesHeader header, out int previousEntry)
+ {
+ header.NumEntries = SharedMemEntryCount;
+ header.MaxEntryIndex = SharedMemEntryCount - 1;
+
+ previousEntry = (int)header.LatestEntry;
+ header.LatestEntry = (header.LatestEntry + 1) % SharedMemEntryCount;
+
+ header.TimestampTicks = GetTimestampTicks();
+
+ return (int)header.LatestEntry; // EntryCount shouldn't overflow int
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/DebugPadDevice.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/DebugPadDevice.cs
new file mode 100644
index 00000000..77e9205f
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/DebugPadDevice.cs
@@ -0,0 +1,24 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ public class DebugPadDevice : BaseDevice
+ {
+ public DebugPadDevice(Switch device, bool active) : base(device, active) { }
+
+ public void Update()
+ {
+ ref ShMemDebugPad debugPad = ref _device.Hid.SharedMemory.DebugPad;
+
+ int currentIndex = UpdateEntriesHeader(ref debugPad.Header, out int previousIndex);
+
+ if (!Active)
+ {
+ return;
+ }
+
+ ref DebugPadEntry currentEntry = ref debugPad.Entries[currentIndex];
+ DebugPadEntry previousEntry = debugPad.Entries[previousIndex];
+
+ currentEntry.SampleTimestamp = previousEntry.SampleTimestamp + 1;
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/KeyboardDevice.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/KeyboardDevice.cs
new file mode 100644
index 00000000..e8ed6a3e
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/KeyboardDevice.cs
@@ -0,0 +1,32 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ public class KeyboardDevice : BaseDevice
+ {
+ public KeyboardDevice(Switch device, bool active) : base(device, active) { }
+
+ public unsafe void Update(KeyboardInput keyState)
+ {
+ ref ShMemKeyboard keyboard = ref _device.Hid.SharedMemory.Keyboard;
+
+ int currentIndex = UpdateEntriesHeader(ref keyboard.Header, out int previousIndex);
+
+ if (!Active)
+ {
+ return;
+ }
+
+ ref KeyboardState currentEntry = ref keyboard.Entries[currentIndex];
+ KeyboardState previousEntry = keyboard.Entries[previousIndex];
+
+ currentEntry.SampleTimestamp = previousEntry.SampleTimestamp + 1;
+ currentEntry.SampleTimestamp2 = previousEntry.SampleTimestamp2 + 1;
+
+ for (int i = 0; i < 8; ++i)
+ {
+ currentEntry.Keys[i] = (uint)keyState.Keys[i];
+ }
+
+ currentEntry.Modifier = (ulong)keyState.Modifier;
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/MouseDevice.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/MouseDevice.cs
new file mode 100644
index 00000000..ee58a563
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/MouseDevice.cs
@@ -0,0 +1,37 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ public class MouseDevice : BaseDevice
+ {
+ public MouseDevice(Switch device, bool active) : base(device, active) { }
+
+ public void Update(int mouseX, int mouseY, int buttons = 0, int scrollX = 0, int scrollY = 0)
+ {
+ ref ShMemMouse mouse = ref _device.Hid.SharedMemory.Mouse;
+
+ int currentIndex = UpdateEntriesHeader(ref mouse.Header, out int previousIndex);
+
+ if (!Active)
+ {
+ return;
+ }
+
+ ref MouseState currentEntry = ref mouse.Entries[currentIndex];
+ MouseState previousEntry = mouse.Entries[previousIndex];
+
+ currentEntry.SampleTimestamp = previousEntry.SampleTimestamp + 1;
+ currentEntry.SampleTimestamp2 = previousEntry.SampleTimestamp2 + 1;
+
+ currentEntry.Buttons = (ulong)buttons;
+
+ currentEntry.Position = new MousePosition
+ {
+ X = mouseX,
+ Y = mouseY,
+ VelocityX = mouseX - previousEntry.Position.X,
+ VelocityY = mouseY - previousEntry.Position.Y,
+ ScrollVelocityX = scrollX,
+ ScrollVelocityY = scrollY
+ };
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs
new file mode 100644
index 00000000..ff330312
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs
@@ -0,0 +1,332 @@
+using System;
+using Ryujinx.HLE.HOS.Kernel.Threading;
+using Ryujinx.Common.Logging;
+
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ public class NpadDevices : BaseDevice
+ {
+ internal NpadJoyHoldType JoyHold = NpadJoyHoldType.Vertical;
+ internal bool SixAxisActive = false; // TODO: link to hidserver when implemented
+
+ enum FilterState
+ {
+ Unconfigured = 0,
+ Configured = 1,
+ Accepted = 2
+ }
+
+ struct NpadConfig
+ {
+ public ControllerType ConfiguredType;
+ public FilterState State;
+ }
+
+ private const int _maxControllers = 9; // Players1-8 and Handheld
+ private NpadConfig[] _configuredNpads;
+
+ private ControllerType _supportedStyleSets = ControllerType.ProController |
+ ControllerType.JoyconPair |
+ ControllerType.JoyconLeft |
+ ControllerType.JoyconRight |
+ ControllerType.Handheld;
+
+ public ControllerType SupportedStyleSets
+ {
+ get { return _supportedStyleSets; }
+ set
+ {
+ if (_supportedStyleSets != value) // Deal with spamming
+ {
+ _supportedStyleSets = value;
+ MatchControllers();
+ }
+ }
+ }
+
+ public PlayerIndex PrimaryController { get; set; } = PlayerIndex.Unknown;
+
+ KEvent[] _styleSetUpdateEvents;
+
+ static readonly Array3<BatteryCharge> _fullBattery;
+
+ public NpadDevices(Switch device, bool active = true) : base(device, active)
+ {
+ _configuredNpads = new NpadConfig[_maxControllers];
+
+ _styleSetUpdateEvents = new KEvent[_maxControllers];
+
+ for (int i = 0; i < _styleSetUpdateEvents.Length; ++i)
+ {
+ _styleSetUpdateEvents[i] = new KEvent(_device.System);
+ }
+
+ _fullBattery[0] = _fullBattery[1] = _fullBattery[2] = BatteryCharge.Percent100;
+ }
+
+ public void AddControllers(params ControllerConfig[] configs)
+ {
+ for (int i = 0; i < configs.Length; ++i)
+ {
+ PlayerIndex player = configs[i].Player;
+ ControllerType controllerType = configs[i].Type;
+
+ if (player > PlayerIndex.Handheld)
+ {
+ throw new ArgumentOutOfRangeException("Player must be Player1-8 or Handheld");
+ }
+
+ if (controllerType == ControllerType.Handheld)
+ {
+ player = PlayerIndex.Handheld;
+ }
+
+ _configuredNpads[(int)player] = new NpadConfig { ConfiguredType = controllerType, State = FilterState.Configured };
+ }
+
+ MatchControllers();
+ }
+
+ void MatchControllers()
+ {
+ PrimaryController = PlayerIndex.Unknown;
+
+ for (int i = 0; i < _configuredNpads.Length; ++i)
+ {
+ ref NpadConfig config = ref _configuredNpads[i];
+
+ if (config.State == FilterState.Unconfigured)
+ {
+ continue; // Ignore unconfigured
+ }
+
+ if ((config.ConfiguredType & _supportedStyleSets) == 0)
+ {
+ Logger.PrintWarning(LogClass.Hid, $"ControllerType {config.ConfiguredType} (connected to {(PlayerIndex)i}) not supported by game. Removing...");
+
+ config.State = FilterState.Configured;
+ _device.Hid.SharedMemory.Npads[i] = new ShMemNpad(); // Zero it
+
+ continue;
+ }
+
+ InitController((PlayerIndex)i, config.ConfiguredType);
+ }
+
+ // Couldn't find any matching configuration. Reassign to something that works.
+ if (PrimaryController == PlayerIndex.Unknown)
+ {
+ ControllerType[] npadsTypeList = (ControllerType[])Enum.GetValues(typeof(ControllerType));
+
+ // Skip None Type
+ for (int i = 1; i < npadsTypeList.Length; ++i)
+ {
+ ControllerType controllerType = npadsTypeList[i];
+ if ((controllerType & _supportedStyleSets) != 0)
+ {
+ Logger.PrintWarning(LogClass.Hid, $"No matching controllers found. Reassigning input as ControllerType {controllerType}...");
+
+ InitController(controllerType == ControllerType.Handheld ? PlayerIndex.Handheld : PlayerIndex.Player1, controllerType);
+
+ return;
+ }
+ }
+
+ Logger.PrintError(LogClass.Hid, "Couldn't find any appropriate controller.");
+ }
+ }
+
+ internal ref KEvent GetStyleSetUpdateEvent(PlayerIndex player)
+ {
+ return ref _styleSetUpdateEvents[(int)player];
+ }
+
+ void InitController(PlayerIndex player, ControllerType type)
+ {
+ if (type == ControllerType.Handheld)
+ {
+ player = PlayerIndex.Handheld;
+ }
+
+ ref ShMemNpad controller = ref _device.Hid.SharedMemory.Npads[(int)player];
+
+ controller = new ShMemNpad(); // Zero it
+
+ // TODO: Allow customizing colors at config
+ NpadStateHeader defaultHeader = new NpadStateHeader
+ {
+ IsHalf = false,
+ SingleColorBody = NpadColor.BodyGray,
+ SingleColorButtons = NpadColor.ButtonGray,
+ LeftColorBody = NpadColor.BodyNeonBlue,
+ LeftColorButtons = NpadColor.ButtonGray,
+ RightColorBody = NpadColor.BodyNeonRed,
+ RightColorButtons = NpadColor.ButtonGray
+ };
+
+ controller.SystemProperties = NpadSystemProperties.PowerInfo0Connected |
+ NpadSystemProperties.PowerInfo1Connected |
+ NpadSystemProperties.PowerInfo2Connected;
+
+ controller.BatteryState = _fullBattery;
+
+ switch (type)
+ {
+ case ControllerType.ProController:
+ defaultHeader.Type = ControllerType.ProController;
+ controller.DeviceType = DeviceType.FullKey;
+ controller.SystemProperties |= NpadSystemProperties.AbxyButtonOriented |
+ NpadSystemProperties.PlusButtonCapability |
+ NpadSystemProperties.MinusButtonCapability;
+ break;
+ case ControllerType.Handheld:
+ defaultHeader.Type = ControllerType.Handheld;
+ controller.DeviceType = DeviceType.HandheldLeft |
+ DeviceType.HandheldRight;
+ controller.SystemProperties |= NpadSystemProperties.AbxyButtonOriented |
+ NpadSystemProperties.PlusButtonCapability |
+ NpadSystemProperties.MinusButtonCapability;
+ break;
+ case ControllerType.JoyconPair:
+ defaultHeader.Type = ControllerType.JoyconPair;
+ controller.DeviceType = DeviceType.JoyLeft |
+ DeviceType.JoyRight;
+ controller.SystemProperties |= NpadSystemProperties.AbxyButtonOriented |
+ NpadSystemProperties.PlusButtonCapability |
+ NpadSystemProperties.MinusButtonCapability;
+ break;
+ case ControllerType.JoyconLeft:
+ defaultHeader.Type = ControllerType.JoyconLeft;
+ defaultHeader.IsHalf = true;
+ controller.DeviceType = DeviceType.JoyLeft;
+ controller.SystemProperties |= NpadSystemProperties.SlSrButtonOriented |
+ NpadSystemProperties.MinusButtonCapability;
+ break;
+ case ControllerType.JoyconRight:
+ defaultHeader.Type = ControllerType.JoyconRight;
+ defaultHeader.IsHalf = true;
+ controller.DeviceType = DeviceType.JoyRight;
+ controller.SystemProperties |= NpadSystemProperties.SlSrButtonOriented |
+ NpadSystemProperties.PlusButtonCapability;
+ break;
+ case ControllerType.Pokeball:
+ defaultHeader.Type = ControllerType.Pokeball;
+ controller.DeviceType = DeviceType.Palma;
+ break;
+ }
+
+ controller.Header = defaultHeader;
+
+ if (PrimaryController == PlayerIndex.Unknown)
+ {
+ PrimaryController = player;
+ }
+
+ _configuredNpads[(int)player].State = FilterState.Accepted;
+
+ _styleSetUpdateEvents[(int)player].ReadableEvent.Signal();
+
+ Logger.PrintInfo(LogClass.Hid, $"Connected ControllerType {type} to PlayerIndex {player}");
+ }
+
+ static NpadLayoutsIndex ControllerTypeToLayout(ControllerType controllerType)
+ => controllerType switch
+ {
+ ControllerType.ProController => NpadLayoutsIndex.ProController,
+ ControllerType.Handheld => NpadLayoutsIndex.Handheld,
+ ControllerType.JoyconPair => NpadLayoutsIndex.JoyDual,
+ ControllerType.JoyconLeft => NpadLayoutsIndex.JoyLeft,
+ ControllerType.JoyconRight => NpadLayoutsIndex.JoyRight,
+ ControllerType.Pokeball => NpadLayoutsIndex.Pokeball,
+ _ => NpadLayoutsIndex.SystemExternal
+ };
+
+ public void SetGamepadsInput(params GamepadInput[] states)
+ {
+ UpdateAllEntries();
+
+ for (int i = 0; i < states.Length; ++i)
+ {
+ SetGamepadState(states[i].PlayerId, states[i].Buttons, states[i].LStick, states[i].RStick);
+ }
+ }
+
+ void SetGamepadState(PlayerIndex player, ControllerKeys buttons,
+ JoystickPosition leftJoystick, JoystickPosition rightJoystick)
+ {
+ if (player == PlayerIndex.Auto)
+ {
+ player = PrimaryController;
+ }
+
+ if (player == PlayerIndex.Unknown)
+ {
+ return;
+ }
+
+ if (_configuredNpads[(int)player].State != FilterState.Accepted)
+ {
+ return;
+ }
+
+ ref ShMemNpad currentNpad = ref _device.Hid.SharedMemory.Npads[(int)player];
+ ref NpadLayout currentLayout = ref currentNpad.Layouts[(int)ControllerTypeToLayout(currentNpad.Header.Type)];
+ ref NpadState currentEntry = ref currentLayout.Entries[(int)currentLayout.Header.LatestEntry];
+
+ currentEntry.Buttons = buttons;
+ currentEntry.LStickX = leftJoystick.Dx;
+ currentEntry.LStickY = leftJoystick.Dy;
+ currentEntry.RStickX = rightJoystick.Dx;
+ currentEntry.RStickY = rightJoystick.Dy;
+
+ // Mirror data to Default layout just in case
+ ref NpadLayout mainLayout = ref currentNpad.Layouts[(int)NpadLayoutsIndex.SystemExternal];
+ mainLayout.Entries[(int)mainLayout.Header.LatestEntry] = currentEntry;
+ }
+
+ void UpdateAllEntries()
+ {
+ ref Array10<ShMemNpad> controllers = ref _device.Hid.SharedMemory.Npads;
+ for (int i = 0; i < controllers.Length; ++i)
+ {
+ ref Array7<NpadLayout> layouts = ref controllers[i].Layouts;
+ for (int l = 0; l < layouts.Length; ++l)
+ {
+ ref NpadLayout currentLayout = ref layouts[l];
+ int currentIndex = UpdateEntriesHeader(ref currentLayout.Header, out int previousIndex);
+
+ ref NpadState currentEntry = ref currentLayout.Entries[currentIndex];
+ NpadState previousEntry = currentLayout.Entries[previousIndex];
+
+ currentEntry.SampleTimestamp = previousEntry.SampleTimestamp + 1;
+ currentEntry.SampleTimestamp2 = previousEntry.SampleTimestamp2 + 1;
+
+ if (controllers[i].Header.Type == ControllerType.None)
+ {
+ continue;
+ }
+
+ currentEntry.ConnectionState = NpadConnectionState.ControllerStateConnected;
+
+ switch (controllers[i].Header.Type)
+ {
+ case ControllerType.Handheld:
+ case ControllerType.ProController:
+ currentEntry.ConnectionState |= NpadConnectionState.ControllerStateWired;
+ break;
+ case ControllerType.JoyconPair:
+ currentEntry.ConnectionState |= NpadConnectionState.JoyLeftConnected |
+ NpadConnectionState.JoyRightConnected;
+ break;
+ case ControllerType.JoyconLeft:
+ currentEntry.ConnectionState |= NpadConnectionState.JoyLeftConnected;
+ break;
+ case ControllerType.JoyconRight:
+ currentEntry.ConnectionState |= NpadConnectionState.JoyRightConnected;
+ break;
+ }
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/TouchDevice.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/TouchDevice.cs
new file mode 100644
index 00000000..10c34453
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/TouchDevice.cs
@@ -0,0 +1,46 @@
+using System;
+
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ public class TouchDevice : BaseDevice
+ {
+ public TouchDevice(Switch device, bool active) : base(device, active) { }
+
+ public void Update(params TouchPoint[] points)
+ {
+ ref ShMemTouchScreen touchscreen = ref _device.Hid.SharedMemory.TouchScreen;
+
+ int currentIndex = UpdateEntriesHeader(ref touchscreen.Header, out int previousIndex);
+
+ if (!Active)
+ {
+ return;
+ }
+
+ ref TouchScreenState currentEntry = ref touchscreen.Entries[currentIndex];
+ TouchScreenState previousEntry = touchscreen.Entries[previousIndex];
+
+ currentEntry.SampleTimestamp = previousEntry.SampleTimestamp + 1;
+ currentEntry.SampleTimestamp2 = previousEntry.SampleTimestamp2 + 1;
+
+ currentEntry.NumTouches = (ulong)points.Length;
+
+ int pointsLength = Math.Min(points.Length, currentEntry.Touches.Length);
+
+ for (int i = 0; i < pointsLength; ++i)
+ {
+ TouchPoint pi = points[i];
+ currentEntry.Touches[i] = new TouchScreenStateData
+ {
+ SampleTimestamp = currentEntry.SampleTimestamp,
+ X = pi.X,
+ Y = pi.Y,
+ TouchIndex = (uint)i,
+ DiameterX = pi.DiameterX,
+ DiameterY = pi.DiameterY,
+ Angle = pi.Angle
+ };
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/ControllerConfig.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/ControllerConfig.cs
new file mode 100644
index 00000000..e59ba312
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/ControllerConfig.cs
@@ -0,0 +1,8 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ public struct ControllerConfig
+ {
+ public PlayerIndex Player;
+ public ControllerType Type;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/GamepadInput.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/GamepadInput.cs
new file mode 100644
index 00000000..2488057e
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/GamepadInput.cs
@@ -0,0 +1,10 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ public struct GamepadInput
+ {
+ public PlayerIndex PlayerId;
+ public ControllerKeys Buttons;
+ public JoystickPosition LStick;
+ public JoystickPosition RStick;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/Input/Controller/Types/JoystickPosition.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/JoystickPosition.cs
index 1442bc60..6df477d6 100644
--- a/Ryujinx.HLE/Input/Controller/Types/JoystickPosition.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/JoystickPosition.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.Input
+namespace Ryujinx.HLE.HOS.Services.Hid
{
public struct JoystickPosition
{
diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/KeyboardInput.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/KeyboardInput.cs
new file mode 100644
index 00000000..26681270
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/KeyboardInput.cs
@@ -0,0 +1,8 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ public struct KeyboardInput
+ {
+ public int Modifier;
+ public int[] Keys;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/TouchPoint.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/TouchPoint.cs
new file mode 100644
index 00000000..d1172dd0
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/TouchPoint.cs
@@ -0,0 +1,11 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ public struct TouchPoint
+ {
+ public uint X;
+ public uint Y;
+ public uint DiameterX;
+ public uint DiameterY;
+ public uint Angle;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidServer/HidUtils.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/HidUtils.cs
index c89ea306..c2cd8432 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/HidServer/HidUtils.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/HidUtils.cs
@@ -1,46 +1,39 @@
-using Ryujinx.HLE.Input;
-using System;
+using System;
namespace Ryujinx.HLE.HOS.Services.Hid.HidServer
{
static class HidUtils
{
- public static ControllerId GetIndexFromNpadIdType(HidNpadIdType npadIdType)
+ public static PlayerIndex GetIndexFromNpadIdType(NpadIdType npadIdType)
+ => npadIdType switch
{
- switch (npadIdType)
- {
- case HidNpadIdType.Player1: return ControllerId.ControllerPlayer1;
- case HidNpadIdType.Player2: return ControllerId.ControllerPlayer2;
- case HidNpadIdType.Player3: return ControllerId.ControllerPlayer3;
- case HidNpadIdType.Player4: return ControllerId.ControllerPlayer4;
- case HidNpadIdType.Player5: return ControllerId.ControllerPlayer5;
- case HidNpadIdType.Player6: return ControllerId.ControllerPlayer6;
- case HidNpadIdType.Player7: return ControllerId.ControllerPlayer7;
- case HidNpadIdType.Player8: return ControllerId.ControllerPlayer8;
- case HidNpadIdType.Handheld: return ControllerId.ControllerHandheld;
- case HidNpadIdType.Unknown: return ControllerId.ControllerUnknown;
+ NpadIdType.Player1 => PlayerIndex.Player1,
+ NpadIdType.Player2 => PlayerIndex.Player2,
+ NpadIdType.Player3 => PlayerIndex.Player3,
+ NpadIdType.Player4 => PlayerIndex.Player4,
+ NpadIdType.Player5 => PlayerIndex.Player5,
+ NpadIdType.Player6 => PlayerIndex.Player6,
+ NpadIdType.Player7 => PlayerIndex.Player7,
+ NpadIdType.Player8 => PlayerIndex.Player8,
+ NpadIdType.Handheld => PlayerIndex.Handheld,
+ NpadIdType.Unknown => PlayerIndex.Unknown,
+ _ => throw new ArgumentOutOfRangeException(nameof(npadIdType))
+ };
- default: throw new ArgumentOutOfRangeException(nameof(npadIdType));
- }
- }
-
- public static HidNpadIdType GetNpadIdTypeFromIndex(ControllerId index)
+ public static NpadIdType GetNpadIdTypeFromIndex(PlayerIndex index)
+ => index switch
{
- switch (index)
- {
- case ControllerId.ControllerPlayer1: return HidNpadIdType.Player1;
- case ControllerId.ControllerPlayer2: return HidNpadIdType.Player2;
- case ControllerId.ControllerPlayer3: return HidNpadIdType.Player3;
- case ControllerId.ControllerPlayer4: return HidNpadIdType.Player4;
- case ControllerId.ControllerPlayer5: return HidNpadIdType.Player5;
- case ControllerId.ControllerPlayer6: return HidNpadIdType.Player6;
- case ControllerId.ControllerPlayer7: return HidNpadIdType.Player7;
- case ControllerId.ControllerPlayer8: return HidNpadIdType.Player8;
- case ControllerId.ControllerHandheld: return HidNpadIdType.Handheld;
- case ControllerId.ControllerUnknown: return HidNpadIdType.Unknown;
-
- default: throw new ArgumentOutOfRangeException(nameof(index));
- }
- }
+ PlayerIndex.Player1 => NpadIdType.Player1,
+ PlayerIndex.Player2 => NpadIdType.Player2,
+ PlayerIndex.Player3 => NpadIdType.Player3,
+ PlayerIndex.Player4 => NpadIdType.Player4,
+ PlayerIndex.Player5 => NpadIdType.Player5,
+ PlayerIndex.Player6 => NpadIdType.Player6,
+ PlayerIndex.Player7 => NpadIdType.Player7,
+ PlayerIndex.Player8 => NpadIdType.Player8,
+ PlayerIndex.Handheld => NpadIdType.Handheld,
+ PlayerIndex.Unknown => NpadIdType.Unknown,
+ _ => throw new ArgumentOutOfRangeException(nameof(index))
+ };
}
} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadHandheldActivationMode.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/HidNpadHandheldActivationMode.cs
index 0aa8334d..0aa8334d 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadHandheldActivationMode.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/HidNpadHandheldActivationMode.cs
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadJoyAssignmentMode.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/HidNpadJoyAssignmentMode.cs
index a2e22661..a2e22661 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadJoyAssignmentMode.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/HidNpadJoyAssignmentMode.cs
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadJoyDeviceType.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/HidNpadJoyDeviceType.cs
index d0b34def..d0b34def 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadJoyDeviceType.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/HidNpadJoyDeviceType.cs
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SixAxis/HidAccelerometerParameters.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/HidAccelerometerParameters.cs
index fe7e4cc9..fe7e4cc9 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/SixAxis/HidAccelerometerParameters.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/HidAccelerometerParameters.cs
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SixAxis/HidGyroscopeZeroDriftMode.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/HidGyroscopeZeroDriftMode.cs
index cd3aa318..cd3aa318 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/SixAxis/HidGyroscopeZeroDriftMode.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/HidGyroscopeZeroDriftMode.cs
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SixAxis/HidSensorFusionParameters.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/HidSensorFusionParameters.cs
index cadf5ec0..cadf5ec0 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/SixAxis/HidSensorFusionParameters.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/HidSensorFusionParameters.cs
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Vibration/HidVibrationDevicePosition.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDevicePosition.cs
index 0ab84af3..0ab84af3 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/Vibration/HidVibrationDevicePosition.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDevicePosition.cs
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Vibration/HidVibrationDeviceType.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDeviceType.cs
index cf9e6498..cf9e6498 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/Vibration/HidVibrationDeviceType.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDeviceType.cs
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Vibration/HidVibrationDeviceValue.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDeviceValue.cs
index 7905ecfd..7905ecfd 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/Vibration/HidVibrationDeviceValue.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDeviceValue.cs
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Vibration/HidVibrationValue.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationValue.cs
index 7211396e..7211396e 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/Vibration/HidVibrationValue.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationValue.cs
diff --git a/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs b/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs
index 1af9baf8..e34c4213 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs
@@ -3,7 +3,6 @@ using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.HLE.HOS.Services.Hid.HidServer;
-using Ryujinx.HLE.Input;
using System;
namespace Ryujinx.HLE.HOS.Services.Hid
@@ -11,7 +10,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid
[Service("hid")]
class IHidServer : IpcService
{
- private KEvent _npadStyleSetUpdateEvent;
private KEvent _xpadIdEvent;
private KEvent _palmaOperationCompleteEvent;
@@ -22,8 +20,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid
private bool _vibrationPermitted;
private bool _usbFullKeyControllerEnabled;
- private HidNpadJoyHoldType _npadJoyHoldType;
- private HidNpadStyle _npadStyleSet;
private HidNpadJoyAssignmentMode _npadJoyAssignmentMode;
private HidNpadHandheldActivationMode _npadHandheldActivationMode;
private HidGyroscopeZeroDriftMode _gyroscopeZeroDriftMode;
@@ -39,12 +35,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid
public IHidServer(ServiceCtx context)
{
- _npadStyleSetUpdateEvent = new KEvent(context.Device.System);
_xpadIdEvent = new KEvent(context.Device.System);
_palmaOperationCompleteEvent = new KEvent(context.Device.System);
- _npadJoyHoldType = HidNpadJoyHoldType.Vertical;
- _npadStyleSet = HidNpadStyle.FullKey | HidNpadStyle.Dual | HidNpadStyle.Left | HidNpadStyle.Right | HidNpadStyle.Handheld;
_npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Dual;
_npadHandheldActivationMode = HidNpadHandheldActivationMode.Dual;
_gyroscopeZeroDriftMode = HidGyroscopeZeroDriftMode.Standard;
@@ -85,6 +78,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
{
long appletResourceUserId = context.RequestData.ReadInt64();
+ context.Device.Hid.Touchscreen.Active = true;
Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
return ResultCode.Success;
@@ -96,6 +90,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
{
long appletResourceUserId = context.RequestData.ReadInt64();
+ context.Device.Hid.Mouse.Active = true;
Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
return ResultCode.Success;
@@ -107,6 +102,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
{
long appletResourceUserId = context.RequestData.ReadInt64();
+ context.Device.Hid.Keyboard.Active = true;
Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
return ResultCode.Success;
@@ -542,13 +538,15 @@ namespace Ryujinx.HLE.HOS.Services.Hid
// SetSupportedNpadStyleSet(nn::applet::AppletResourceUserId, nn::hid::NpadStyleTag)
public ResultCode SetSupportedNpadStyleSet(ServiceCtx context)
{
- _npadStyleSet = (HidNpadStyle)context.RequestData.ReadInt32();
-
+ ControllerType type = (ControllerType)context.RequestData.ReadInt32();
long appletResourceUserId = context.RequestData.ReadInt64();
- Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, _npadStyleSet });
+ Logger.PrintStub(LogClass.ServiceHid, new {
+ appletResourceUserId,
+ type
+ });
- _npadStyleSetUpdateEvent.ReadableEvent.Signal();
+ context.Device.Hid.Npads.SupportedStyleSets = type;
return ResultCode.Success;
}
@@ -559,9 +557,12 @@ namespace Ryujinx.HLE.HOS.Services.Hid
{
long appletResourceUserId = context.RequestData.ReadInt64();
- context.ResponseData.Write((int)_npadStyleSet);
+ context.ResponseData.Write((int)context.Device.Hid.Npads.SupportedStyleSets);
- Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, _npadStyleSet });
+ Logger.PrintStub(LogClass.ServiceHid, new {
+ appletResourceUserId,
+ context.Device.Hid.Npads.SupportedStyleSets
+ });
return ResultCode.Success;
}
@@ -570,10 +571,17 @@ namespace Ryujinx.HLE.HOS.Services.Hid
// SetSupportedNpadIdType(nn::applet::AppletResourceUserId, array<NpadIdType, 9>)
public ResultCode SetSupportedNpadIdType(ServiceCtx context)
{
- long appletResourceUserId = context.RequestData.ReadInt64();
- ControllerId npadIdType = (ControllerId)context.RequestData.ReadInt64();
+ long appletResourceUserId = context.RequestData.ReadInt64();
+ long arraySize = context.Request.PtrBuff[0].Size / 4;
- Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, npadIdType });
+ NpadIdType[] supportedPlayerIds = new NpadIdType[arraySize];
+
+ for (int i = 0; i < arraySize; ++i)
+ {
+ supportedPlayerIds[i] = (NpadIdType)context.Memory.ReadInt32(context.Request.PtrBuff[0].Position + i * 4);
+ }
+
+ Logger.PrintStub(LogClass.ServiceHid, $"{arraySize} " + string.Join(",", supportedPlayerIds));
return ResultCode.Success;
}
@@ -584,6 +592,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
{
long appletResourceUserId = context.RequestData.ReadInt64();
+ context.Device.Hid.Npads.Active = true;
Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
return ResultCode.Success;
@@ -595,6 +604,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
{
long appletResourceUserId = context.RequestData.ReadInt64();
+ context.Device.Hid.Npads.Active = false;
Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
return ResultCode.Success;
@@ -604,11 +614,12 @@ namespace Ryujinx.HLE.HOS.Services.Hid
// AcquireNpadStyleSetUpdateEventHandle(nn::applet::AppletResourceUserId, uint, ulong) -> nn::sf::NativeHandle
public ResultCode AcquireNpadStyleSetUpdateEventHandle(ServiceCtx context)
{
- long appletResourceUserId = context.RequestData.ReadInt64();
- int npadId = context.RequestData.ReadInt32();
- long npadStyleSet = context.RequestData.ReadInt64();
+ PlayerIndex npadId = HidUtils.GetIndexFromNpadIdType((NpadIdType)context.RequestData.ReadInt32());
+ long appletResourceUserId = context.RequestData.ReadInt64();
+ long npadStyleSet = context.RequestData.ReadInt64();
- if (context.Process.HandleTable.GenerateHandle(_npadStyleSetUpdateEvent.ReadableEvent, out int handle) != KernelResult.Success)
+ KEvent evnt = context.Device.Hid.Npads.GetStyleSetUpdateEvent(npadId);
+ if (context.Process.HandleTable.GenerateHandle(evnt.ReadableEvent, out int handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
@@ -624,8 +635,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid
// DisconnectNpad(nn::applet::AppletResourceUserId, uint NpadIdType)
public ResultCode DisconnectNpad(ServiceCtx context)
{
- long appletResourceUserId = context.RequestData.ReadInt64();
- int npadIdType = context.RequestData.ReadInt32();
+ NpadIdType npadIdType = (NpadIdType)context.RequestData.ReadInt32();
+ long appletResourceUserId = context.RequestData.ReadInt64();
Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, npadIdType });
@@ -651,10 +662,10 @@ namespace Ryujinx.HLE.HOS.Services.Hid
// ActivateNpadWithRevision(nn::applet::AppletResourceUserId, int Unknown)
public ResultCode ActivateNpadWithRevision(ServiceCtx context)
{
+ int revision = context.RequestData.ReadInt32();
long appletResourceUserId = context.RequestData.ReadInt64();
- int unknown = context.RequestData.ReadInt32();
- Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, unknown });
+ Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, revision });
return ResultCode.Success;
}
@@ -664,9 +675,12 @@ namespace Ryujinx.HLE.HOS.Services.Hid
public ResultCode SetNpadJoyHoldType(ServiceCtx context)
{
long appletResourceUserId = context.RequestData.ReadInt64();
- _npadJoyHoldType = (HidNpadJoyHoldType)context.RequestData.ReadInt64();
+ context.Device.Hid.Npads.JoyHold = (NpadJoyHoldType)context.RequestData.ReadInt64();
- Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, _npadJoyHoldType });
+ Logger.PrintStub(LogClass.ServiceHid, new {
+ appletResourceUserId,
+ context.Device.Hid.Npads.JoyHold
+ });
return ResultCode.Success;
}
@@ -677,9 +691,12 @@ namespace Ryujinx.HLE.HOS.Services.Hid
{
long appletResourceUserId = context.RequestData.ReadInt64();
- context.ResponseData.Write((long)_npadJoyHoldType);
+ context.ResponseData.Write((long)context.Device.Hid.Npads.JoyHold);
- Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, _npadJoyHoldType });
+ Logger.PrintStub(LogClass.ServiceHid, new {
+ appletResourceUserId,
+ context.Device.Hid.Npads.JoyHold
+ });
return ResultCode.Success;
}
@@ -688,8 +705,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid
// SetNpadJoyAssignmentModeSingleByDefault(uint HidControllerId, nn::applet::AppletResourceUserId)
public ResultCode SetNpadJoyAssignmentModeSingleByDefault(ServiceCtx context)
{
- ControllerId hidControllerId = (ControllerId)context.RequestData.ReadInt32();
- long appletResourceUserId = context.RequestData.ReadInt64();
+ PlayerIndex hidControllerId = (PlayerIndex)context.RequestData.ReadInt32();
+ long appletResourceUserId = context.RequestData.ReadInt64();
_npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Single;
@@ -702,7 +719,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
// SetNpadJoyAssignmentModeSingle(uint HidControllerId, nn::applet::AppletResourceUserId, long HidNpadJoyDeviceType)
public ResultCode SetNpadJoyAssignmentModeSingle(ServiceCtx context)
{
- ControllerId hidControllerId = (ControllerId)context.RequestData.ReadInt32();
+ PlayerIndex hidControllerId = (PlayerIndex)context.RequestData.ReadInt32();
long appletResourceUserId = context.RequestData.ReadInt64();
HidNpadJoyDeviceType hidNpadJoyDeviceType = (HidNpadJoyDeviceType)context.RequestData.ReadInt64();
@@ -717,8 +734,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid
// SetNpadJoyAssignmentModeDual(uint HidControllerId, nn::applet::AppletResourceUserId)
public ResultCode SetNpadJoyAssignmentModeDual(ServiceCtx context)
{
- ControllerId hidControllerId = (ControllerId)context.RequestData.ReadInt32();
- long appletResourceUserId = context.RequestData.ReadInt64();
+ PlayerIndex hidControllerId = HidUtils.GetIndexFromNpadIdType((NpadIdType)context.RequestData.ReadInt32());
+ long appletResourceUserId = context.RequestData.ReadInt64();
_npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Dual;
@@ -831,7 +848,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
// SetNpadJoyAssignmentModeSingleWithDestination(uint HidControllerId, long HidNpadJoyDeviceType, nn::applet::AppletResourceUserId) -> bool Unknown0, uint Unknown1
public ResultCode SetNpadJoyAssignmentModeSingleWithDestination(ServiceCtx context)
{
- ControllerId hidControllerId = (ControllerId)context.RequestData.ReadInt32();
+ PlayerIndex hidControllerId = (PlayerIndex)context.RequestData.ReadInt32();
HidNpadJoyDeviceType hidNpadJoyDeviceType = (HidNpadJoyDeviceType)context.RequestData.ReadInt64();
long appletResourceUserId = context.RequestData.ReadInt64();
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Irs/IIrSensorServer.cs b/Ryujinx.HLE/HOS/Services/Hid/Irs/IIrSensorServer.cs
index cd571f11..4851a259 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Irs/IIrSensorServer.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/Irs/IIrSensorServer.cs
@@ -2,7 +2,6 @@
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Services.Hid.HidServer;
-using Ryujinx.HLE.Input;
using System;
namespace Ryujinx.HLE.HOS.Services.Hid.Irs
@@ -57,16 +56,16 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Irs
// GetNpadIrCameraHandle(u32) -> nn::irsensor::IrCameraHandle
public ResultCode GetNpadIrCameraHandle(ServiceCtx context)
{
- HidNpadIdType npadIdType = (HidNpadIdType)context.RequestData.ReadUInt32();
+ NpadIdType npadIdType = (NpadIdType)context.RequestData.ReadUInt32();
- if (npadIdType > HidNpadIdType.Player8 &&
- npadIdType != HidNpadIdType.Unknown &&
- npadIdType != HidNpadIdType.Handheld)
+ if (npadIdType > NpadIdType.Player8 &&
+ npadIdType != NpadIdType.Unknown &&
+ npadIdType != NpadIdType.Handheld)
{
return ResultCode.NpadIdOutOfRange;
}
- ControllerId irCameraHandle = HidUtils.GetIndexFromNpadIdType(npadIdType);
+ PlayerIndex irCameraHandle = HidUtils.GetIndexFromNpadIdType(npadIdType);
context.ResponseData.Write((int)irCameraHandle);
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Boolean32.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/Boolean32.cs
new file mode 100644
index 00000000..5a8d51c6
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/Boolean32.cs
@@ -0,0 +1,9 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ struct Boolean32
+ {
+ private uint _value;
+ public static implicit operator bool(Boolean32 value) => (value._value & 1) != 0;
+ public static implicit operator Boolean32(bool value) => new Boolean32() { _value = value ? 1u : 0u };
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerKeys.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerKeys.cs
new file mode 100644
index 00000000..db0319ed
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerKeys.cs
@@ -0,0 +1,45 @@
+using System;
+
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ [Flags]
+ public enum ControllerKeys : long
+ {
+ A = 1 << 0,
+ B = 1 << 1,
+ X = 1 << 2,
+ Y = 1 << 3,
+ LStick = 1 << 4,
+ RStick = 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,
+ SlLeft = 1 << 24,
+ SrLeft = 1 << 25,
+ SlRight = 1 << 26,
+ SrRight = 1 << 27,
+
+ // Generic Catch-all
+ Up = DpadUp | LStickUp | RStickUp,
+ Down = DpadDown | LStickDown | RStickDown,
+ Left = DpadLeft | LStickLeft | RStickLeft,
+ Right = DpadRight | LStickRight | RStickRight,
+ Sl = SlLeft | SlRight,
+ Sr = SrLeft | SrRight
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerType.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerType.cs
new file mode 100644
index 00000000..f65c3079
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerType.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ [Flags]
+ public enum ControllerType : int
+ {
+ None,
+ ProController = 1 << 0,
+ Handheld = 1 << 1,
+ JoyconPair = 1 << 2,
+ JoyconLeft = 1 << 3,
+ JoyconRight = 1 << 4,
+ Invalid = 1 << 5,
+ Pokeball = 1 << 6,
+ SystemExternal = 1 << 29,
+ System = 1 << 30
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadJoyHoldType.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadJoyHoldType.cs
deleted file mode 100644
index 3bd3aa91..00000000
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadJoyHoldType.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.HLE.HOS.Services.Hid
-{
- public enum HidNpadJoyHoldType
- {
- Vertical,
- Horizontal
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadStyle.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadStyle.cs
deleted file mode 100644
index 93717acf..00000000
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadStyle.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-
-namespace Ryujinx.HLE.HOS.Services.Hid
-{
- [Flags]
- public enum HidNpadStyle
- {
- None,
- FullKey = 1 << 0,
- Handheld = 1 << 1,
- Dual = 1 << 2,
- Left = 1 << 3,
- Right = 1 << 4,
- Invalid = 1 << 5
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadColor.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadColor.cs
new file mode 100644
index 00000000..57b4b366
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadColor.cs
@@ -0,0 +1,37 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ public enum NpadColor : int
+ {
+ BodyGray = 0x828282,
+ BodyNeonRed = 0xFF3C28,
+ BodyNeonBlue = 0x0AB9E6,
+ BodyNeonYellow = 0xE6FF00,
+ BodyNeonGreen = 0x1EDC00,
+ BodyNeonPink = 0xFF3278,
+ BodyRed = 0xE10F00,
+ BodyBlue = 0x4655F5,
+ BodyNeonPurple = 0xB400E6,
+ BodyNeonOrange = 0xFAA005,
+ BodyPokemonLetsGoPikachu = 0xFFDC00,
+ BodyPokemonLetsGoEevee = 0xC88C32,
+ BodyNintendoLaboCreatorsContestEdition = 0xD7AA73,
+ BodyAnimalCrossingSpecialEditionLeftJoyCon = 0x82FF96,
+ BodyAnimalCrossingSpecialEditionRightJoyCon = 0x96F5F5,
+
+ ButtonGray = 0x0F0F0F,
+ ButtonNeonRed = 0x1E0A0A,
+ ButtonNeonBlue = 0x001E1E,
+ ButtonNeonYellow = 0x142800,
+ ButtonNeonGreen = 0x002800,
+ ButtonNeonPink = 0x28001E,
+ ButtonRed = 0x280A0A,
+ ButtonBlue = 0x00000A,
+ ButtonNeonPurple = 0x140014,
+ ButtonNeonOrange = 0x0F0A00,
+ ButtonPokemonLetsGoPikachu = 0x322800,
+ ButtonPokemonLetsGoEevee = 0x281900,
+ ButtonNintendoLaboCreatorsContestEdition = 0x1E1914,
+ ButtonAnimalCrossingSpecialEditionLeftJoyCon = 0x0A1E0A,
+ ButtonAnimalCrossingSpecialEditionRightJoyCon = 0x0A1E28
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadIdType.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadIdType.cs
index 9a3989de..5f6a68cb 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/HidNpadIdType.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadIdType.cs
@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Hid
{
- public enum HidNpadIdType
+ public enum NpadIdType
{
Player1 = 0,
Player2 = 1,
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/PlayerIndex.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/PlayerIndex.cs
new file mode 100644
index 00000000..f4ced5df
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/PlayerIndex.cs
@@ -0,0 +1,17 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ public enum PlayerIndex : int
+ {
+ Player1 = 0,
+ Player2 = 1,
+ Player3 = 2,
+ Player4 = 3,
+ Player5 = 4,
+ Player6 = 5,
+ Player7 = 6,
+ Player8 = 7,
+ Handheld = 8,
+ Unknown = 9,
+ Auto = 10 // Shouldn't be used directly
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/CommonEntriesHeader.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/CommonEntriesHeader.cs
new file mode 100644
index 00000000..f83fdcdf
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/CommonEntriesHeader.cs
@@ -0,0 +1,11 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ struct CommonEntriesHeader
+ {
+ public ulong TimestampTicks;
+ public ulong NumEntries;
+ public ulong LatestEntry;
+ public ulong MaxEntryIndex;
+ }
+}
+
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/DebugPad/DebugPad.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/DebugPad/DebugPad.cs
new file mode 100644
index 00000000..e68924da
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/DebugPad/DebugPad.cs
@@ -0,0 +1,9 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ unsafe struct ShMemDebugPad
+ {
+ public CommonEntriesHeader Header;
+ public Array17<DebugPadEntry> Entries;
+ fixed byte _padding[0x138];
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/DebugPad/DebugPadEntry.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/DebugPad/DebugPadEntry.cs
new file mode 100644
index 00000000..4a3e7a2e
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/DebugPad/DebugPadEntry.cs
@@ -0,0 +1,8 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ unsafe struct DebugPadEntry
+ {
+ public ulong SampleTimestamp;
+ fixed byte _unknown[0x20];
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/HidSharedMemory.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/HidSharedMemory.cs
new file mode 100644
index 00000000..d2bd8a23
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/HidSharedMemory.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ // TODO: Add missing structs
+ unsafe struct HidSharedMemory
+ {
+ public ShMemDebugPad DebugPad;
+ public ShMemTouchScreen TouchScreen;
+ public ShMemMouse Mouse;
+ public ShMemKeyboard Keyboard;
+ public fixed byte BasicXpad[0x4 * 0x400];
+ public fixed byte HomeButton[0x200];
+ public fixed byte SleepButton[0x200];
+ public fixed byte CaptureButton[0x200];
+ public fixed byte InputDetector[0x10 * 0x80];
+ public fixed byte UniquePad[0x10 * 0x400];
+ public Array10<ShMemNpad> Npads;
+ public fixed byte Gesture[0x800];
+ public fixed byte ConsoleSixAxisSensor[0x20];
+ fixed byte _padding[0x3de0];
+ }
+}
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Keyboard/Keyboard.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Keyboard/Keyboard.cs
new file mode 100644
index 00000000..dcfa5aa1
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Keyboard/Keyboard.cs
@@ -0,0 +1,9 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ unsafe struct ShMemKeyboard
+ {
+ public CommonEntriesHeader Header;
+ public Array17<KeyboardState> Entries;
+ fixed byte _padding[0x28];
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Keyboard/KeyboardState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Keyboard/KeyboardState.cs
new file mode 100644
index 00000000..1f54a4fd
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Keyboard/KeyboardState.cs
@@ -0,0 +1,10 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ unsafe struct KeyboardState
+ {
+ public ulong SampleTimestamp;
+ public ulong SampleTimestamp2;
+ public ulong Modifier;
+ public fixed uint Keys[8];
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/Mouse.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/Mouse.cs
new file mode 100644
index 00000000..c1f45c5c
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/Mouse.cs
@@ -0,0 +1,10 @@
+
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ unsafe struct ShMemMouse
+ {
+ public CommonEntriesHeader Header;
+ public Array17<MouseState> Entries;
+ fixed byte _padding[0xB0];
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/MousePosition.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/MousePosition.cs
new file mode 100644
index 00000000..e94c9e0c
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/MousePosition.cs
@@ -0,0 +1,12 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ struct MousePosition
+ {
+ public int X;
+ public int Y;
+ public int VelocityX;
+ public int VelocityY;
+ public int ScrollVelocityX;
+ public int ScrollVelocityY;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/MouseState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/MouseState.cs
new file mode 100644
index 00000000..7856b09d
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/MouseState.cs
@@ -0,0 +1,10 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ struct MouseState
+ {
+ public ulong SampleTimestamp;
+ public ulong SampleTimestamp2;
+ public MousePosition Position;
+ public ulong Buttons;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/BatterCharge.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/BatterCharge.cs
new file mode 100644
index 00000000..b94ab172
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/BatterCharge.cs
@@ -0,0 +1,11 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ enum BatteryCharge : int
+ {
+ Percent0 = 0,
+ Percent25 = 1,
+ Percent50 = 2,
+ Percent75 = 3,
+ Percent100 = 4
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/DeviceType.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/DeviceType.cs
new file mode 100644
index 00000000..f6d7b783
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/DeviceType.cs
@@ -0,0 +1,26 @@
+using System;
+
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ [Flags]
+ enum DeviceType : int
+ {
+ FullKey = 1 << 0,
+ DebugPad = 1 << 1,
+ HandheldLeft = 1 << 2,
+ HandheldRight = 1 << 3,
+ JoyLeft = 1 << 4,
+ JoyRight = 1 << 5,
+ Palma = 1 << 6, // Poké Ball Plus
+ FamicomLeft = 1 << 7,
+ FamicomRight = 1 << 8,
+ NESLeft = 1 << 9,
+ NESRight = 1 << 10,
+ HandheldFamicomLeft = 1 << 11,
+ HandheldFamicomRight = 1 << 12,
+ HandheldNESLeft = 1 << 13,
+ HandheldNESRight = 1 << 14,
+ Lucia = 1 << 15,
+ System = 1 << 31
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/HidVector.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/HidVector.cs
new file mode 100644
index 00000000..b41bcb2e
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/HidVector.cs
@@ -0,0 +1,9 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ struct HidVector
+ {
+ public float X;
+ public float Y;
+ public float Z;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/Npad.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/Npad.cs
new file mode 100644
index 00000000..0bb2628f
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/Npad.cs
@@ -0,0 +1,21 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ // TODO: Add missing structs
+ unsafe struct ShMemNpad
+ {
+ public NpadStateHeader Header;
+ public Array7<NpadLayout> Layouts; // One for each NpadLayoutsIndex
+ public Array6<NpadSixAxis> Sixaxis;
+ public DeviceType DeviceType;
+ uint _padding1;
+ public NpadSystemProperties SystemProperties;
+ public uint NpadSystemButtonProperties;
+ public Array3<BatteryCharge> BatteryState;
+ public fixed byte NfcXcdDeviceHandleHeader[0x20];
+ public fixed byte NfcXcdDeviceHandleState[0x20 * 2];
+ public ulong Mutex;
+ public fixed byte NpadGcTriggerHeader[0x20];
+ public fixed byte NpadGcTriggerState[0x18 * 17];
+ fixed byte _padding2[0xC38];
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/Input/Controller/Types/ControllerColorDescription.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadColorDescription.cs
index c31f41a3..ccc7cb8d 100644
--- a/Ryujinx.HLE/Input/Controller/Types/ControllerColorDescription.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadColorDescription.cs
@@ -1,9 +1,9 @@
using System;
-namespace Ryujinx.HLE.Input
+namespace Ryujinx.HLE.HOS.Services.Hid
{
[Flags]
- public enum ControllerColorDescription : int
+ enum NpadColorDescription : int
{
ColorDescriptionColorsNonexistent = (1 << 1)
}
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadConnectionState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadConnectionState.cs
new file mode 100644
index 00000000..60f64fd3
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadConnectionState.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ [Flags]
+ enum NpadConnectionState : long
+ {
+ ControllerStateConnected = (1 << 0),
+ ControllerStateWired = (1 << 1),
+ JoyLeftConnected = (1 << 2),
+ JoyRightConnected = (1 << 4)
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadJoyHoldType.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadJoyHoldType.cs
new file mode 100644
index 00000000..a6f29760
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadJoyHoldType.cs
@@ -0,0 +1,8 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ enum NpadJoyHoldType
+ {
+ Vertical,
+ Horizontal
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayout.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayout.cs
new file mode 100644
index 00000000..9851a6b1
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayout.cs
@@ -0,0 +1,8 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ struct NpadLayout
+ {
+ public CommonEntriesHeader Header;
+ public Array17<NpadState> Entries;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayoutsIndex.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayoutsIndex.cs
new file mode 100644
index 00000000..29eb8d3d
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayoutsIndex.cs
@@ -0,0 +1,13 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ enum NpadLayoutsIndex : int
+ {
+ ProController = 0,
+ Handheld = 1,
+ JoyDual = 2,
+ JoyLeft = 3,
+ JoyRight = 4,
+ Pokeball = 5,
+ SystemExternal = 6
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadSixAxis.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadSixAxis.cs
new file mode 100644
index 00000000..5f65db39
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadSixAxis.cs
@@ -0,0 +1,8 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ struct NpadSixAxis
+ {
+ public CommonEntriesHeader Header;
+ public Array17<SixAxisState> Entries;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadState.cs
new file mode 100644
index 00000000..60a5f9d3
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadState.cs
@@ -0,0 +1,14 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ struct NpadState
+ {
+ public ulong SampleTimestamp;
+ public ulong SampleTimestamp2;
+ public ControllerKeys Buttons;
+ public int LStickX;
+ public int LStickY;
+ public int RStickX;
+ public int RStickY;
+ public NpadConnectionState ConnectionState;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadStatesHeader.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadStatesHeader.cs
new file mode 100644
index 00000000..006d4357
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadStatesHeader.cs
@@ -0,0 +1,16 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ struct NpadStateHeader
+ {
+ public ControllerType Type;
+ public Boolean32 IsHalf;
+ public NpadColorDescription SingleColorsDescriptor;
+ public NpadColor SingleColorBody;
+ public NpadColor SingleColorButtons;
+ public NpadColorDescription SplitColorsDescriptor;
+ public NpadColor LeftColorBody;
+ public NpadColor LeftColorButtons;
+ public NpadColor RightColorBody;
+ public NpadColor RightColorButtons;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadSystemProperties.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadSystemProperties.cs
new file mode 100644
index 00000000..708f7da9
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadSystemProperties.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ [Flags]
+ enum NpadSystemProperties : long
+ {
+ PowerInfo0Charging = 1 << 0,
+ PowerInfo1Charging = 1 << 1,
+ PowerInfo2Charging = 1 << 2,
+ PowerInfo0Connected = 1 << 3,
+ PowerInfo1Connected = 1 << 4,
+ PowerInfo2Connected = 1 << 5,
+ UnsupportedButtonPressedNpadSystem = 1 << 9,
+ UnsupportedButtonPressedNpadSystemExt = 1 << 10,
+ AbxyButtonOriented = 1 << 11,
+ SlSrButtonOriented = 1 << 12,
+ PlusButtonCapability = 1 << 13,
+ MinusButtonCapability = 1 << 14,
+ DirectionalButtonsSupported = 1 << 15
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/SixAxisState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/SixAxisState.cs
new file mode 100644
index 00000000..0a799916
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/SixAxisState.cs
@@ -0,0 +1,14 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ unsafe struct SixAxisState
+ {
+ public ulong SampleTimestamp;
+ ulong _unknown1;
+ public ulong SampleTimestamp2;
+ public HidVector Accelerometer;
+ public HidVector Gyroscope;
+ HidVector unknownSensor;
+ public fixed float Orientation[9];
+ ulong _unknown2;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/StructArrayHelpers.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/StructArrayHelpers.cs
new file mode 100644
index 00000000..f513cf8b
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/StructArrayHelpers.cs
@@ -0,0 +1,53 @@
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ struct Array2<T> where T : unmanaged
+ {
+ T e0, e1;
+ public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref e0, 2)[index];
+ public int Length => 2;
+ }
+
+ struct Array3<T> where T : unmanaged
+ {
+ T e0, e1, e2;
+ public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref e0, 3)[index];
+ public int Length => 3;
+ }
+
+ struct Array6<T> where T : unmanaged
+ {
+ T e0, e1, e2, e3, e4, e5;
+ public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref e0, 6)[index];
+ public int Length => 6;
+ }
+
+ struct Array7<T> where T : unmanaged
+ {
+ T e0, e1, e2, e3, e4, e5, e6;
+ public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref e0, 7)[index];
+ public int Length => 7;
+ }
+
+ struct Array10<T> where T : unmanaged
+ {
+ T e0, e1, e2, e3, e4, e5, e6, e7, e8, e9;
+ public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref e0, 10)[index];
+ public int Length => 10;
+ }
+
+ struct Array16<T> where T : unmanaged
+ {
+ T e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15;
+ public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref e0, 16)[index];
+ public int Length => 16;
+ }
+
+ struct Array17<T> where T : unmanaged
+ {
+ T e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16;
+ public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref e0, 17)[index];
+ public int Length => 17;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreen.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreen.cs
new file mode 100644
index 00000000..618ddd98
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreen.cs
@@ -0,0 +1,9 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ unsafe struct ShMemTouchScreen
+ {
+ public CommonEntriesHeader Header;
+ public Array17<TouchScreenState> Entries;
+ fixed byte _padding[0x3c8];
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenState.cs
new file mode 100644
index 00000000..a0a9cf23
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenState.cs
@@ -0,0 +1,10 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ struct TouchScreenState
+ {
+ public ulong SampleTimestamp;
+ public ulong SampleTimestamp2;
+ public ulong NumTouches;
+ public Array16<TouchScreenStateData> Touches;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenStateData.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenStateData.cs
new file mode 100644
index 00000000..872064b3
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenStateData.cs
@@ -0,0 +1,15 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ struct TouchScreenStateData
+ {
+ public ulong SampleTimestamp;
+ uint _padding;
+ public uint TouchIndex;
+ public uint X;
+ public uint Y;
+ public uint DiameterX;
+ public uint DiameterY;
+ public uint Angle;
+ uint _padding2;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Nfc/Nfp/UserManager/IUser.cs b/Ryujinx.HLE/HOS/Services/Nfc/Nfp/UserManager/IUser.cs
index d26b4eb9..3f6518e5 100644
--- a/Ryujinx.HLE/HOS/Services/Nfc/Nfp/UserManager/IUser.cs
+++ b/Ryujinx.HLE/HOS/Services/Nfc/Nfp/UserManager/IUser.cs
@@ -43,8 +43,8 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
// TODO: When we will be able to add multiple controllers add one entry by controller here.
Device device1 = new Device
{
- NpadIdType = HidNpadIdType.Player1,
- Handle = HidUtils.GetIndexFromNpadIdType(HidNpadIdType.Player1),
+ NpadIdType = NpadIdType.Player1,
+ Handle = HidUtils.GetIndexFromNpadIdType(NpadIdType.Player1),
State = DeviceState.Initialized
};
diff --git a/Ryujinx.HLE/HOS/Services/Nfc/Nfp/UserManager/Types/Device.cs b/Ryujinx.HLE/HOS/Services/Nfc/Nfp/UserManager/Types/Device.cs
index 40e7c880..7eaf4ac8 100644
--- a/Ryujinx.HLE/HOS/Services/Nfc/Nfp/UserManager/Types/Device.cs
+++ b/Ryujinx.HLE/HOS/Services/Nfc/Nfp/UserManager/Types/Device.cs
@@ -1,6 +1,5 @@
using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.HLE.HOS.Services.Hid;
-using Ryujinx.HLE.Input;
namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.UserManager
{
@@ -14,7 +13,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.UserManager
public DeviceState State = DeviceState.Unavailable;
- public ControllerId Handle;
- public HidNpadIdType NpadIdType;
+ public PlayerIndex Handle;
+ public NpadIdType NpadIdType;
}
} \ No newline at end of file
diff --git a/Ryujinx.HLE/Input/Controller/BaseController.cs b/Ryujinx.HLE/Input/Controller/BaseController.cs
deleted file mode 100644
index dfd54a83..00000000
--- a/Ryujinx.HLE/Input/Controller/BaseController.cs
+++ /dev/null
@@ -1,142 +0,0 @@
-using static Ryujinx.HLE.Input.Hid;
-
-namespace Ryujinx.HLE.Input
-{
- public abstract class BaseController : IHidDevice
- {
- protected ControllerStatus HidControllerType;
- protected ControllerId ControllerId;
-
- private long _currentLayoutOffset;
- private long _mainLayoutOffset;
-
- protected long DeviceStateOffset => Offset + 0x4188;
-
- protected Switch Device { get; }
-
- public long Offset { get; private set; }
- public bool Connected { get; protected set; }
-
- public ControllerHeader Header { get; private set; }
- public ControllerStateHeader CurrentStateHeader { get; private set; }
- public ControllerDeviceState DeviceState { get; private set; }
- public ControllerLayouts CurrentLayout { get; private set; }
- public ControllerState LastInputState { get; set; }
- public ControllerConnectionState ConnectionState { get; protected set; }
-
- public BaseController(Switch device, ControllerStatus controllerType)
- {
- Device = device;
- HidControllerType = controllerType;
- }
-
- protected void Initialize(
- bool isHalf,
- (NpadColor left, NpadColor right) bodyColors,
- (NpadColor left, NpadColor right) buttonColors,
- ControllerColorDescription singleColorDesc = 0,
- ControllerColorDescription splitColorDesc = 0,
- NpadColor singleBodyColor = 0,
- NpadColor singleButtonColor = 0
- )
- {
- Header = new ControllerHeader()
- {
- IsJoyConHalf = isHalf ? 1 : 0,
- LeftBodyColor = bodyColors.left,
- LeftButtonColor = buttonColors.left,
- RightBodyColor = bodyColors.right,
- RightButtonColor = buttonColors.right,
- Status = HidControllerType,
- SingleBodyColor = singleBodyColor,
- SingleButtonColor = singleButtonColor,
- SplitColorDescription = splitColorDesc,
- SingleColorDescription = singleColorDesc,
- };
-
- CurrentStateHeader = new ControllerStateHeader
- {
- EntryCount = HidEntryCount,
- MaxEntryCount = HidEntryCount - 1,
- CurrentEntryIndex = -1
- };
-
- DeviceState = new ControllerDeviceState()
- {
- PowerInfo0BatteryState = BatteryState.Percent100,
- PowerInfo1BatteryState = BatteryState.Percent100,
- PowerInfo2BatteryState = BatteryState.Percent100,
- DeviceType = ControllerDeviceType.NPadLeftController | ControllerDeviceType.NPadRightController,
- DeviceFlags = DeviceFlags.PowerInfo0Connected
- | DeviceFlags.PowerInfo1Connected
- | DeviceFlags.PowerInfo2Connected
- };
-
- LastInputState = new ControllerState()
- {
- SamplesTimestamp = -1,
- SamplesTimestamp2 = -1
- };
- }
-
- public virtual void Connect(ControllerId controllerId)
- {
- ControllerId = controllerId;
-
- Offset = Device.Hid.HidPosition + HidControllersOffset + (int)controllerId * HidControllerSize;
-
- _mainLayoutOffset = Offset + HidControllerHeaderSize
- + ((int)ControllerLayouts.Main * HidControllerLayoutsSize);
-
- Device.Memory.FillWithZeros(Offset, 0x5000);
- Device.Memory.WriteStruct(Offset, Header);
- Device.Memory.WriteStruct(DeviceStateOffset, DeviceState);
-
- Connected = true;
- }
-
- public void SetLayout(ControllerLayouts controllerLayout)
- {
- CurrentLayout = controllerLayout;
-
- _currentLayoutOffset = Offset + HidControllerHeaderSize
- + ((int)controllerLayout * HidControllerLayoutsSize);
- }
-
- public void SendInput(
- ControllerButtons buttons,
- JoystickPosition leftStick,
- JoystickPosition rightStick)
- {
- ControllerState currentInput = new ControllerState()
- {
- SamplesTimestamp = (long)LastInputState.SamplesTimestamp + 1,
- SamplesTimestamp2 = (long)LastInputState.SamplesTimestamp + 1,
- ButtonState = buttons,
- ConnectionState = ConnectionState,
- LeftStick = leftStick,
- RightStick = rightStick
- };
-
- ControllerStateHeader newInputStateHeader = new ControllerStateHeader
- {
- EntryCount = HidEntryCount,
- MaxEntryCount = HidEntryCount - 1,
- CurrentEntryIndex = (CurrentStateHeader.CurrentEntryIndex + 1) % HidEntryCount,
- Timestamp = GetTimestamp(),
- };
-
- Device.Memory.WriteStruct(_currentLayoutOffset, newInputStateHeader);
- Device.Memory.WriteStruct(_mainLayoutOffset, newInputStateHeader);
-
- long currentInputStateOffset = HidControllersLayoutHeaderSize
- + newInputStateHeader.CurrentEntryIndex * HidControllersInputEntrySize;
-
- Device.Memory.WriteStruct(_currentLayoutOffset + currentInputStateOffset, currentInput);
- Device.Memory.WriteStruct(_mainLayoutOffset + currentInputStateOffset, currentInput);
-
- LastInputState = currentInput;
- CurrentStateHeader = newInputStateHeader;
- }
- }
-}
diff --git a/Ryujinx.HLE/Input/Controller/NpadController.cs b/Ryujinx.HLE/Input/Controller/NpadController.cs
deleted file mode 100644
index b4304b8f..00000000
--- a/Ryujinx.HLE/Input/Controller/NpadController.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-namespace Ryujinx.HLE.Input
-{
- public class NpadController : BaseController
- {
- private (NpadColor Left, NpadColor Right) _npadBodyColors;
- private (NpadColor Left, NpadColor Right) _npadButtonColors;
-
- private bool _isHalf;
-
- public NpadController(
- ControllerStatus controllerStatus,
- Switch device,
- (NpadColor, NpadColor) npadBodyColors,
- (NpadColor, NpadColor) npadButtonColors) : base(device, controllerStatus)
- {
- _npadBodyColors = npadBodyColors;
- _npadButtonColors = npadButtonColors;
- }
-
- public override void Connect(ControllerId controllerId)
- {
- if (HidControllerType != ControllerStatus.NpadLeft && HidControllerType != ControllerStatus.NpadRight)
- {
- _isHalf = false;
- }
-
- ConnectionState = ControllerConnectionState.ControllerStateConnected;
-
- if (controllerId == ControllerId.ControllerHandheld)
- ConnectionState |= ControllerConnectionState.ControllerStateWired;
-
- ControllerColorDescription singleColorDesc =
- ControllerColorDescription.ColorDescriptionColorsNonexistent;
-
- ControllerColorDescription splitColorDesc = 0;
-
- NpadColor singleBodyColor = NpadColor.Black;
- NpadColor singleButtonColor = NpadColor.Black;
-
- Initialize(_isHalf,
- (_npadBodyColors.Left, _npadBodyColors.Right),
- (_npadButtonColors.Left, _npadButtonColors.Right),
- singleColorDesc,
- splitColorDesc,
- singleBodyColor,
- singleButtonColor );
-
- base.Connect(controllerId);
-
- var _currentLayout = ControllerLayouts.HandheldJoined;
-
- switch (HidControllerType)
- {
- case ControllerStatus.NpadLeft:
- _currentLayout = ControllerLayouts.Left;
- break;
- case ControllerStatus.NpadRight:
- _currentLayout = ControllerLayouts.Right;
- break;
- case ControllerStatus.NpadPair:
- _currentLayout = ControllerLayouts.Joined;
- break;
- }
-
- SetLayout(_currentLayout);
- }
- }
-}
diff --git a/Ryujinx.HLE/Input/Controller/ProController.cs b/Ryujinx.HLE/Input/Controller/ProController.cs
deleted file mode 100644
index ae574260..00000000
--- a/Ryujinx.HLE/Input/Controller/ProController.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-namespace Ryujinx.HLE.Input
-{
- public class ProController : BaseController
- {
- private bool _wired = false;
-
- private NpadColor _bodyColor;
- private NpadColor _buttonColor;
-
- public ProController(Switch device,
- NpadColor bodyColor,
- NpadColor buttonColor) : base(device, ControllerStatus.ProController)
- {
- _wired = true;
-
- _bodyColor = bodyColor;
- _buttonColor = buttonColor;
- }
-
- public override void Connect(ControllerId controllerId)
- {
- ControllerColorDescription singleColorDesc =
- ControllerColorDescription.ColorDescriptionColorsNonexistent;
-
- ControllerColorDescription splitColorDesc = 0;
-
- ConnectionState = ControllerConnectionState.ControllerStateConnected | ControllerConnectionState.ControllerStateWired;
-
- Initialize(false,
- (0, 0),
- (0, 0),
- singleColorDesc,
- splitColorDesc,
- _bodyColor,
- _buttonColor);
-
- base.Connect(controllerId);
-
- SetLayout(ControllerLayouts.ProController);
- }
- }
-}
diff --git a/Ryujinx.HLE/Input/Controller/Types/BatteryState.cs b/Ryujinx.HLE/Input/Controller/Types/BatteryState.cs
deleted file mode 100644
index 4279d7a0..00000000
--- a/Ryujinx.HLE/Input/Controller/Types/BatteryState.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Ryujinx.HLE.Input
-{
- public enum BatteryState : int
- {
- // TODO : Check if these are the correct states
- Percent0 = 0,
- Percent25 = 1,
- Percent50 = 2,
- Percent75 = 3,
- Percent100 = 4
- }
-}
diff --git a/Ryujinx.HLE/Input/Controller/Types/ControllerButtons.cs b/Ryujinx.HLE/Input/Controller/Types/ControllerButtons.cs
deleted file mode 100644
index 879257f2..00000000
--- a/Ryujinx.HLE/Input/Controller/Types/ControllerButtons.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System;
-
-namespace Ryujinx.HLE.Input
-{
- [Flags]
- public enum ControllerButtons : long
- {
- 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/Input/Controller/Types/ControllerConnectionState.cs b/Ryujinx.HLE/Input/Controller/Types/ControllerConnectionState.cs
deleted file mode 100644
index 526da1ff..00000000
--- a/Ryujinx.HLE/Input/Controller/Types/ControllerConnectionState.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System;
-
-namespace Ryujinx.HLE.Input
-{
- [Flags]
- public enum ControllerConnectionState : long
- {
- ControllerStateConnected = (1 << 0),
- ControllerStateWired = (1 << 1)
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Input/Controller/Types/ControllerDeviceState.cs b/Ryujinx.HLE/Input/Controller/Types/ControllerDeviceState.cs
deleted file mode 100644
index 45895a1e..00000000
--- a/Ryujinx.HLE/Input/Controller/Types/ControllerDeviceState.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.Input
-{
- [StructLayout(LayoutKind.Sequential)]
- public unsafe struct ControllerDeviceState
- {
- public ControllerDeviceType DeviceType;
- public int Padding;
- public DeviceFlags DeviceFlags;
- public int UnintendedHomeButtonInputProtectionEnabled;
- public BatteryState PowerInfo0BatteryState;
- public BatteryState PowerInfo1BatteryState;
- public BatteryState PowerInfo2BatteryState;
- public fixed byte ControllerMac[16];
- public fixed byte ControllerMac2[16];
- }
-}
diff --git a/Ryujinx.HLE/Input/Controller/Types/ControllerDeviceType.cs b/Ryujinx.HLE/Input/Controller/Types/ControllerDeviceType.cs
deleted file mode 100644
index 8043d8a0..00000000
--- a/Ryujinx.HLE/Input/Controller/Types/ControllerDeviceType.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-
-namespace Ryujinx.HLE.Input
-{
- [Flags]
- public enum ControllerDeviceType : int
- {
- ProController = 1 << 0,
- NPadLeftController = 1 << 4,
- NPadRightController = 1 << 5,
- }
-}
diff --git a/Ryujinx.HLE/Input/Controller/Types/ControllerHeader.cs b/Ryujinx.HLE/Input/Controller/Types/ControllerHeader.cs
deleted file mode 100644
index cbb5b6f5..00000000
--- a/Ryujinx.HLE/Input/Controller/Types/ControllerHeader.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.Input
-{
- [StructLayout(LayoutKind.Sequential)]
- public struct ControllerHeader
- {
- public ControllerStatus Status;
- public int IsJoyConHalf;
- public ControllerColorDescription SingleColorDescription;
- public NpadColor SingleBodyColor;
- public NpadColor SingleButtonColor;
- public ControllerColorDescription SplitColorDescription;
- public NpadColor RightBodyColor;
- public NpadColor RightButtonColor;
- public NpadColor LeftBodyColor;
- public NpadColor LeftButtonColor;
- }
-}
diff --git a/Ryujinx.HLE/Input/Controller/Types/ControllerId.cs b/Ryujinx.HLE/Input/Controller/Types/ControllerId.cs
deleted file mode 100644
index c82056c6..00000000
--- a/Ryujinx.HLE/Input/Controller/Types/ControllerId.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-namespace Ryujinx.HLE.Input
-{
- public enum ControllerId
- {
- ControllerPlayer1 = 0,
- ControllerPlayer2 = 1,
- ControllerPlayer3 = 2,
- ControllerPlayer4 = 3,
- ControllerPlayer5 = 4,
- ControllerPlayer6 = 5,
- ControllerPlayer7 = 6,
- ControllerPlayer8 = 7,
- ControllerHandheld = 8,
- ControllerUnknown = 9
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Input/Controller/Types/ControllerLayouts.cs b/Ryujinx.HLE/Input/Controller/Types/ControllerLayouts.cs
deleted file mode 100644
index fedc0399..00000000
--- a/Ryujinx.HLE/Input/Controller/Types/ControllerLayouts.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Ryujinx.HLE.Input
-{
- public enum ControllerLayouts
- {
- ProController = 0,
- HandheldJoined = 1,
- Joined = 2,
- Left = 3,
- Right = 4,
- MainNoAnalog = 5,
- Main = 6
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Input/Controller/Types/ControllerState.cs b/Ryujinx.HLE/Input/Controller/Types/ControllerState.cs
deleted file mode 100644
index 4847438d..00000000
--- a/Ryujinx.HLE/Input/Controller/Types/ControllerState.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.Input
-{
- [StructLayout(LayoutKind.Sequential)]
- public struct ControllerState
- {
- public long SamplesTimestamp;
- public long SamplesTimestamp2;
- public ControllerButtons ButtonState;
- public JoystickPosition LeftStick;
- public JoystickPosition RightStick;
- public ControllerConnectionState ConnectionState;
- }
-}
diff --git a/Ryujinx.HLE/Input/Controller/Types/ControllerStateHeader.cs b/Ryujinx.HLE/Input/Controller/Types/ControllerStateHeader.cs
deleted file mode 100644
index f885c00c..00000000
--- a/Ryujinx.HLE/Input/Controller/Types/ControllerStateHeader.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.Input
-{
- [StructLayout(LayoutKind.Sequential)]
- public struct ControllerStateHeader
- {
- public long Timestamp;
- public long EntryCount;
- public long CurrentEntryIndex;
- public long MaxEntryCount;
- }
-}
diff --git a/Ryujinx.HLE/Input/Controller/Types/ControllerStatus.cs b/Ryujinx.HLE/Input/Controller/Types/ControllerStatus.cs
deleted file mode 100644
index 9444d7b0..00000000
--- a/Ryujinx.HLE/Input/Controller/Types/ControllerStatus.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-
-namespace Ryujinx.HLE.Input
-{
- [Flags]
- public enum ControllerStatus : int
- {
- 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/Input/Controller/Types/DeviceFlags.cs b/Ryujinx.HLE/Input/Controller/Types/DeviceFlags.cs
deleted file mode 100644
index 53913175..00000000
--- a/Ryujinx.HLE/Input/Controller/Types/DeviceFlags.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System;
-
-namespace Ryujinx.HLE.Input
-{
- [Flags]
- public enum DeviceFlags : long
- {
- PowerInfo0Charging = 1 << 0,
- PowerInfo1Charging = 1 << 1,
- PowerInfo2Charging = 1 << 2,
- PowerInfo0Connected = 1 << 3,
- PowerInfo1Connected = 1 << 4,
- PowerInfo2Connected = 1 << 5,
- UnsupportedButtonPressedNpadSystem = 1 << 9,
- UnsupportedButtonPressedNpadSystemExt = 1 << 10,
- AbxyButtonOriented = 1 << 11,
- SlSrButtonOriented = 1 << 12,
- PlusButtonCapability = 1 << 13,
- MinusButtonCapability = 1 << 14,
- DirectionalButtonsSupported = 1 << 15
- }
-}
diff --git a/Ryujinx.HLE/Input/Controller/Types/HotkeyButtons.cs b/Ryujinx.HLE/Input/Controller/Types/HotkeyButtons.cs
deleted file mode 100644
index be76ee1e..00000000
--- a/Ryujinx.HLE/Input/Controller/Types/HotkeyButtons.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-
-namespace Ryujinx.HLE.Input
-{
- [Flags]
- public enum HotkeyButtons
- {
- ToggleVSync = 1 << 0,
- }
-}
diff --git a/Ryujinx.HLE/Input/Controller/Types/NpadColor.cs b/Ryujinx.HLE/Input/Controller/Types/NpadColor.cs
deleted file mode 100644
index a60f94aa..00000000
--- a/Ryujinx.HLE/Input/Controller/Types/NpadColor.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-namespace Ryujinx.HLE.Input
-{
- public enum NpadColor : int //Thanks to CTCaer
- {
- Black = 0,
-
- BodyGrey = 0x828282,
- BodyNeonBlue = 0x0AB9E6,
- BodyNeonRed = 0xFF3C28,
- BodyNeonYellow = 0xE6FF00,
- BodyNeonPink = 0xFF3278,
- BodyNeonGreen = 0x1EDC00,
- BodyRed = 0xE10F00,
-
- ButtonsGrey = 0x0F0F0F,
- ButtonsNeonBlue = 0x001E1E,
- ButtonsNeonRed = 0x1E0A0A,
- ButtonsNeonYellow = 0x142800,
- ButtonsNeonPink = 0x28001E,
- ButtonsNeonGreen = 0x002800,
- ButtonsRed = 0x280A0A
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Input/Hid.cs b/Ryujinx.HLE/Input/Hid.cs
deleted file mode 100644
index 5cb7f09d..00000000
--- a/Ryujinx.HLE/Input/Hid.cs
+++ /dev/null
@@ -1,218 +0,0 @@
-using Ryujinx.Common;
-using Ryujinx.Configuration.Hid;
-using Ryujinx.HLE.HOS;
-using System;
-
-namespace Ryujinx.HLE.Input
-{
- public partial class Hid
- {
- private Switch _device;
-
- private long _touchScreenOffset;
- private long _touchEntriesOffset;
- private long _keyboardOffset;
-
- private TouchHeader _currentTouchHeader;
- private KeyboardHeader _currentKeyboardHeader;
- private KeyboardEntry _currentKeyboardEntry;
-
- public BaseController PrimaryController { get; private set; }
-
- internal long HidPosition;
-
- public Hid(Switch device, long hidPosition)
- {
- _device = device;
- HidPosition = hidPosition;
-
- device.Memory.FillWithZeros(hidPosition, Horizon.HidSize);
-
- _currentTouchHeader = new TouchHeader()
- {
- CurrentEntryIndex = -1,
- };
-
- _currentKeyboardHeader = new KeyboardHeader()
- {
- CurrentEntryIndex = -1,
- };
-
- _currentKeyboardEntry = new KeyboardEntry()
- {
- SamplesTimestamp = -1,
- SamplesTimestamp2 = -1
- };
-
- _touchScreenOffset = HidPosition + HidTouchScreenOffset;
- _touchEntriesOffset = _touchScreenOffset + HidTouchHeaderSize;
- _keyboardOffset = HidPosition + HidKeyboardOffset;
- }
-
- private static ControllerStatus ConvertControllerTypeToState(ControllerType controllerType)
- {
- switch (controllerType)
- {
- case ControllerType.Handheld: return ControllerStatus.Handheld;
- case ControllerType.NpadLeft: return ControllerStatus.NpadLeft;
- case ControllerType.NpadRight: return ControllerStatus.NpadRight;
- case ControllerType.NpadPair: return ControllerStatus.NpadPair;
- case ControllerType.ProController: return ControllerStatus.ProController;
- default: throw new NotImplementedException();
- }
- }
-
- public void InitializePrimaryController(ControllerType controllerType)
- {
- ControllerId controllerId = controllerType == ControllerType.Handheld ?
- ControllerId.ControllerHandheld : ControllerId.ControllerPlayer1;
-
- if (controllerType == ControllerType.ProController)
- {
- PrimaryController = new ProController(_device, NpadColor.Black, NpadColor.Black);
- }
- else
- {
- PrimaryController = new NpadController(ConvertControllerTypeToState(controllerType),
- _device,
- (NpadColor.BodyNeonRed, NpadColor.BodyNeonRed),
- (NpadColor.ButtonsNeonBlue, NpadColor.ButtonsNeonBlue));
- }
-
- PrimaryController.Connect(controllerId);
- }
-
- public ControllerButtons UpdateStickButtons(
- JoystickPosition leftStick,
- JoystickPosition rightStick)
- {
- ControllerButtons result = 0;
-
- if (rightStick.Dx < 0)
- {
- result |= ControllerButtons.RStickLeft;
- }
-
- if (rightStick.Dx > 0)
- {
- result |= ControllerButtons.RStickRight;
- }
-
- if (rightStick.Dy < 0)
- {
- result |= ControllerButtons.RStickDown;
- }
-
- if (rightStick.Dy > 0)
- {
- result |= ControllerButtons.RStickUp;
- }
-
- if (leftStick.Dx < 0)
- {
- result |= ControllerButtons.LStickLeft;
- }
-
- if (leftStick.Dx > 0)
- {
- result |= ControllerButtons.LStickRight;
- }
-
- if (leftStick.Dy < 0)
- {
- result |= ControllerButtons.LStickDown;
- }
-
- if (leftStick.Dy > 0)
- {
- result |= ControllerButtons.LStickUp;
- }
-
- return result;
- }
- public void SetTouchPoints(params TouchPoint[] points)
- {
- long timestamp = GetTimestamp();
- long sampleCounter = _currentTouchHeader.SamplesTimestamp + 1;
-
- var newTouchHeader = new TouchHeader
- {
- CurrentEntryIndex = (_currentTouchHeader.CurrentEntryIndex + 1) % HidEntryCount,
- EntryCount = HidEntryCount,
- MaxEntries = HidEntryCount - 1,
- SamplesTimestamp = sampleCounter,
- Timestamp = timestamp,
- };
-
- long currentTouchEntryOffset = _touchEntriesOffset + newTouchHeader.CurrentEntryIndex * HidTouchEntrySize;
-
- TouchEntry touchEntry = new TouchEntry()
- {
- SamplesTimestamp = sampleCounter,
- TouchCount = points.Length
- };
-
- _device.Memory.WriteStruct(currentTouchEntryOffset, touchEntry);
-
- currentTouchEntryOffset += HidTouchEntryHeaderSize;
-
- for (int i = 0; i < points.Length; i++)
- {
- TouchData touch = new TouchData()
- {
- Angle = points[i].Angle,
- DiameterX = points[i].DiameterX,
- DiameterY = points[i].DiameterY,
- Index = i,
- SampleTimestamp = sampleCounter,
- X = points[i].X,
- Y = points[i].Y
- };
-
- _device.Memory.WriteStruct(currentTouchEntryOffset, touch);
-
- currentTouchEntryOffset += HidTouchEntryTouchSize;
- }
-
- _device.Memory.WriteStruct(_touchScreenOffset, newTouchHeader);
-
- _currentTouchHeader = newTouchHeader;
- }
-
- public unsafe void WriteKeyboard(Keyboard keyboard)
- {
- long timestamp = GetTimestamp();
-
- var newKeyboardHeader = new KeyboardHeader()
- {
- CurrentEntryIndex = (_currentKeyboardHeader.CurrentEntryIndex + 1) % HidEntryCount,
- EntryCount = HidEntryCount,
- MaxEntries = HidEntryCount - 1,
- Timestamp = timestamp,
- };
-
- _device.Memory.WriteStruct(_keyboardOffset, newKeyboardHeader);
-
- long keyboardEntryOffset = _keyboardOffset + HidKeyboardHeaderSize;
- keyboardEntryOffset += newKeyboardHeader.CurrentEntryIndex * HidKeyboardEntrySize;
-
- var newkeyboardEntry = new KeyboardEntry()
- {
- SamplesTimestamp = _currentKeyboardEntry.SamplesTimestamp + 1,
- SamplesTimestamp2 = _currentKeyboardEntry.SamplesTimestamp2 + 1,
- Keys = keyboard.Keys,
- Modifier = keyboard.Modifier,
- };
-
- _device.Memory.WriteStruct(keyboardEntryOffset, newkeyboardEntry);
-
- _currentKeyboardEntry = newkeyboardEntry;
- _currentKeyboardHeader = newKeyboardHeader;
- }
-
- internal static long GetTimestamp()
- {
- return PerformanceCounter.ElapsedMilliseconds * 19200;
- }
- }
-}
diff --git a/Ryujinx.HLE/Input/HidValues.cs b/Ryujinx.HLE/Input/HidValues.cs
deleted file mode 100644
index 06fe8fc0..00000000
--- a/Ryujinx.HLE/Input/HidValues.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-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 HidKeyboardHeaderSize = 0x20;
- internal const int HidKeyboardEntrySize = 0x38;
-
- 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
deleted file mode 100644
index 0b07e767..00000000
--- a/Ryujinx.HLE/Input/IHidDevice.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.HLE.Input
-{
- interface IHidDevice
- {
- long Offset { get; }
- bool Connected { get; }
- }
-}
diff --git a/Ryujinx.HLE/Input/Keyboard/Keyboard.cs b/Ryujinx.HLE/Input/Keyboard/Keyboard.cs
deleted file mode 100644
index 7220e518..00000000
--- a/Ryujinx.HLE/Input/Keyboard/Keyboard.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.HLE.Input
-{
- public struct Keyboard
- {
- public int Modifier;
- public int[] Keys;
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Input/Keyboard/KeyboardEntry.cs b/Ryujinx.HLE/Input/Keyboard/KeyboardEntry.cs
deleted file mode 100644
index be7d9399..00000000
--- a/Ryujinx.HLE/Input/Keyboard/KeyboardEntry.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.Input
-{
- [StructLayout(LayoutKind.Sequential)]
- public struct KeyboardEntry
- {
- public long SamplesTimestamp;
- public long SamplesTimestamp2;
- public long Modifier;
-
- [MarshalAs(UnmanagedType.ByValArray , SizeConst = 0x8)]
- public int[] Keys;
- }
-}
diff --git a/Ryujinx.HLE/Input/Keyboard/KeyboardHeader.cs b/Ryujinx.HLE/Input/Keyboard/KeyboardHeader.cs
deleted file mode 100644
index 882ccbab..00000000
--- a/Ryujinx.HLE/Input/Keyboard/KeyboardHeader.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.Input
-{
- [StructLayout(LayoutKind.Sequential)]
- public struct KeyboardHeader
- {
- public long Timestamp;
- public long EntryCount;
- public long CurrentEntryIndex;
- public long MaxEntries;
- }
-}
diff --git a/Ryujinx.HLE/Input/Touch/TouchData.cs b/Ryujinx.HLE/Input/Touch/TouchData.cs
deleted file mode 100644
index 8489ef70..00000000
--- a/Ryujinx.HLE/Input/Touch/TouchData.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.Input
-{
- [StructLayout(LayoutKind.Sequential)]
- public struct TouchData
- {
- public long SampleTimestamp;
- public int Padding;
- public int Index;
- public int X;
- public int Y;
- public int DiameterX;
- public int DiameterY;
- public int Angle;
- public int Padding2;
- }
-}
diff --git a/Ryujinx.HLE/Input/Touch/TouchEntry.cs b/Ryujinx.HLE/Input/Touch/TouchEntry.cs
deleted file mode 100644
index 2ef09d75..00000000
--- a/Ryujinx.HLE/Input/Touch/TouchEntry.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.Input
-{
- [StructLayout(LayoutKind.Sequential)]
- public unsafe struct TouchEntry
- {
- public long SamplesTimestamp;
- public long TouchCount;
- }
-}
diff --git a/Ryujinx.HLE/Input/Touch/TouchHeader.cs b/Ryujinx.HLE/Input/Touch/TouchHeader.cs
deleted file mode 100644
index dd93137c..00000000
--- a/Ryujinx.HLE/Input/Touch/TouchHeader.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.Input
-{
- [StructLayout(LayoutKind.Sequential)]
- public struct TouchHeader
- {
- public long Timestamp;
- public long EntryCount;
- public long CurrentEntryIndex;
- public long MaxEntries;
- public long SamplesTimestamp;
- }
-}
diff --git a/Ryujinx.HLE/Input/Touch/TouchPoint.cs b/Ryujinx.HLE/Input/Touch/TouchPoint.cs
deleted file mode 100644
index a9b095de..00000000
--- a/Ryujinx.HLE/Input/Touch/TouchPoint.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace Ryujinx.HLE.Input
-{
- public struct TouchPoint
- {
- public int X;
- public int Y;
- public int DiameterX;
- public int DiameterY;
- public int Angle;
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Switch.cs b/Ryujinx.HLE/Switch.cs
index 3cd290bd..040fbf1c 100644
--- a/Ryujinx.HLE/Switch.cs
+++ b/Ryujinx.HLE/Switch.cs
@@ -7,8 +7,8 @@ using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.HOS;
using Ryujinx.HLE.HOS.Services;
+using Ryujinx.HLE.HOS.Services.Hid;
using Ryujinx.HLE.HOS.SystemState;
-using Ryujinx.HLE.Input;
using System;
using System.Threading;
@@ -61,6 +61,7 @@ namespace Ryujinx.HLE
Statistics = new PerformanceStatistics();
Hid = new Hid(this, System.HidBaseAddress);
+ Hid.InitDevices();
VsyncEvent = new AutoResetEvent(true);
}
diff --git a/Ryujinx/Ui/GLRenderer.cs b/Ryujinx/Ui/GLRenderer.cs
index 1105004a..f69d88ce 100644
--- a/Ryujinx/Ui/GLRenderer.cs
+++ b/Ryujinx/Ui/GLRenderer.cs
@@ -7,7 +7,7 @@ using OpenTK.Platform;
using Ryujinx.Configuration;
using Ryujinx.Graphics.OpenGL;
using Ryujinx.HLE;
-using Ryujinx.HLE.Input;
+using Ryujinx.HLE.HOS.Services.Hid;
using Ryujinx.Ui;
using System;
using System.Collections.Generic;
@@ -382,10 +382,10 @@ namespace Ryujinx.Ui
}
HotkeyButtons currentHotkeyButtons = 0;
- ControllerButtons currentButton = 0;
+ ControllerKeys currentButton = 0;
JoystickPosition leftJoystick;
JoystickPosition rightJoystick;
- HLE.Input.Keyboard? hidKeyboard = null;
+ KeyboardInput? hidKeyboard = null;
int leftJoystickDx = 0;
int leftJoystickDy = 0;
@@ -417,7 +417,7 @@ namespace Ryujinx.Ui
if (!hidKeyboard.HasValue)
{
- hidKeyboard = new HLE.Input.Keyboard
+ hidKeyboard = new KeyboardInput
{
Modifier = 0,
Keys = new int[0x8]
@@ -489,8 +489,8 @@ namespace Ryujinx.Ui
TouchPoint currentPoint = new TouchPoint
{
- X = mX,
- Y = mY,
+ X = (uint)mX,
+ Y = (uint)mY,
// Placeholder values till more data is acquired
DiameterX = 10,
@@ -500,23 +500,29 @@ namespace Ryujinx.Ui
hasTouch = true;
- _device.Hid.SetTouchPoints(currentPoint);
+ _device.Hid.Touchscreen.Update(currentPoint);
}
}
if (!hasTouch)
{
- _device.Hid.SetTouchPoints();
+ _device.Hid.Touchscreen.Update();
}
if (ConfigurationState.Instance.Hid.EnableKeyboard && hidKeyboard.HasValue)
{
- _device.Hid.WriteKeyboard(hidKeyboard.Value);
+ _device.Hid.Keyboard.Update(hidKeyboard.Value);
}
- BaseController controller = _device.Hid.PrimaryController;
+ _device.Hid.DebugPad.Update();
- controller.SendInput(currentButton, leftJoystick, rightJoystick);
+ _device.Hid.Npads.SetGamepadsInput(new GamepadInput
+ {
+ PlayerId = PlayerIndex.Auto,
+ Buttons = currentButton,
+ LStick = leftJoystick,
+ RStick = rightJoystick
+ });
// Toggle vsync
if (currentHotkeyButtons.HasFlag(HotkeyButtons.ToggleVSync) &&
diff --git a/Ryujinx/Ui/KeyboardControls.cs b/Ryujinx/Ui/KeyboardControls.cs
index db9c0cda..1f19fe32 100644
--- a/Ryujinx/Ui/KeyboardControls.cs
+++ b/Ryujinx/Ui/KeyboardControls.cs
@@ -1,32 +1,39 @@
-using OpenTK.Input;
-using Ryujinx.HLE.Input;
+using System;
+using OpenTK.Input;
+using Ryujinx.HLE.HOS.Services.Hid;
using Ryujinx.UI.Input;
namespace Ryujinx.Ui
{
+ [Flags]
+ public enum HotkeyButtons
+ {
+ ToggleVSync = 1 << 0,
+ }
+
public static class KeyboardControls
{
- public static ControllerButtons GetButtons(NpadKeyboard npad, KeyboardState keyboard)
+ public static ControllerKeys GetButtons(NpadKeyboard npad, KeyboardState keyboard)
{
- ControllerButtons buttons = 0;
-
- if (keyboard[(Key)npad.LeftJoycon.StickButton]) buttons |= ControllerButtons.StickLeft;
- if (keyboard[(Key)npad.LeftJoycon.DPadUp]) buttons |= ControllerButtons.DpadUp;
- if (keyboard[(Key)npad.LeftJoycon.DPadDown]) buttons |= ControllerButtons.DpadDown;
- if (keyboard[(Key)npad.LeftJoycon.DPadLeft]) buttons |= ControllerButtons.DpadLeft;
- if (keyboard[(Key)npad.LeftJoycon.DPadRight]) buttons |= ControllerButtons.DPadRight;
- if (keyboard[(Key)npad.LeftJoycon.ButtonMinus]) buttons |= ControllerButtons.Minus;
- if (keyboard[(Key)npad.LeftJoycon.ButtonL]) buttons |= ControllerButtons.L;
- if (keyboard[(Key)npad.LeftJoycon.ButtonZl]) buttons |= ControllerButtons.Zl;
+ ControllerKeys buttons = 0;
+
+ if (keyboard[(Key)npad.LeftJoycon.StickButton]) buttons |= ControllerKeys.LStick;
+ if (keyboard[(Key)npad.LeftJoycon.DPadUp]) buttons |= ControllerKeys.DpadUp;
+ if (keyboard[(Key)npad.LeftJoycon.DPadDown]) buttons |= ControllerKeys.DpadDown;
+ if (keyboard[(Key)npad.LeftJoycon.DPadLeft]) buttons |= ControllerKeys.DpadLeft;
+ if (keyboard[(Key)npad.LeftJoycon.DPadRight]) buttons |= ControllerKeys.DpadRight;
+ if (keyboard[(Key)npad.LeftJoycon.ButtonMinus]) buttons |= ControllerKeys.Minus;
+ if (keyboard[(Key)npad.LeftJoycon.ButtonL]) buttons |= ControllerKeys.L | ControllerKeys.Sl;
+ if (keyboard[(Key)npad.LeftJoycon.ButtonZl]) buttons |= ControllerKeys.Zl;
- if (keyboard[(Key)npad.RightJoycon.StickButton]) buttons |= ControllerButtons.StickRight;
- if (keyboard[(Key)npad.RightJoycon.ButtonA]) buttons |= ControllerButtons.A;
- if (keyboard[(Key)npad.RightJoycon.ButtonB]) buttons |= ControllerButtons.B;
- if (keyboard[(Key)npad.RightJoycon.ButtonX]) buttons |= ControllerButtons.X;
- if (keyboard[(Key)npad.RightJoycon.ButtonY]) buttons |= ControllerButtons.Y;
- if (keyboard[(Key)npad.RightJoycon.ButtonPlus]) buttons |= ControllerButtons.Plus;
- if (keyboard[(Key)npad.RightJoycon.ButtonR]) buttons |= ControllerButtons.R;
- if (keyboard[(Key)npad.RightJoycon.ButtonZr]) buttons |= ControllerButtons.Zr;
+ if (keyboard[(Key)npad.RightJoycon.StickButton]) buttons |= ControllerKeys.RStick;
+ if (keyboard[(Key)npad.RightJoycon.ButtonA]) buttons |= ControllerKeys.A;
+ if (keyboard[(Key)npad.RightJoycon.ButtonB]) buttons |= ControllerKeys.B;
+ if (keyboard[(Key)npad.RightJoycon.ButtonX]) buttons |= ControllerKeys.X;
+ if (keyboard[(Key)npad.RightJoycon.ButtonY]) buttons |= ControllerKeys.Y;
+ if (keyboard[(Key)npad.RightJoycon.ButtonPlus]) buttons |= ControllerKeys.Plus;
+ if (keyboard[(Key)npad.RightJoycon.ButtonR]) buttons |= ControllerKeys.R | ControllerKeys.Sr;
+ if (keyboard[(Key)npad.RightJoycon.ButtonZr]) buttons |= ControllerKeys.Zr;
return buttons;
}
@@ -216,9 +223,9 @@ namespace Ryujinx.Ui
new KeyMappingEntry { TargetKey = Key.NumLock, Target = 10 },
};
- public static HLE.Input.Keyboard GetKeysDown(NpadKeyboard npad, KeyboardState keyboard)
+ public static KeyboardInput GetKeysDown(NpadKeyboard npad, KeyboardState keyboard)
{
- HLE.Input.Keyboard hidKeyboard = new HLE.Input.Keyboard
+ KeyboardInput hidKeyboard = new KeyboardInput
{
Modifier = 0,
Keys = new int[0x8]
diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs
index 2415280b..4bbfc78b 100644
--- a/Ryujinx/Ui/MainWindow.cs
+++ b/Ryujinx/Ui/MainWindow.cs
@@ -10,6 +10,7 @@ using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.OpenGL;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.FileSystem.Content;
+using Ryujinx.HLE.HOS.Services.Hid;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -446,7 +447,19 @@ namespace Ryujinx.Ui
private void CreateGameWindow(HLE.Switch device)
{
- device.Hid.InitializePrimaryController(ConfigurationState.Instance.Hid.ControllerType);
+ ControllerType type = (Ryujinx.Configuration.Hid.ControllerType)ConfigurationState.Instance.Hid.ControllerType switch {
+ Ryujinx.Configuration.Hid.ControllerType.ProController => ControllerType.ProController,
+ Ryujinx.Configuration.Hid.ControllerType.Handheld => ControllerType.Handheld,
+ Ryujinx.Configuration.Hid.ControllerType.NpadPair => ControllerType.JoyconPair,
+ Ryujinx.Configuration.Hid.ControllerType.NpadLeft => ControllerType.JoyconLeft,
+ Ryujinx.Configuration.Hid.ControllerType.NpadRight => ControllerType.JoyconRight,
+ _ => ControllerType.Handheld
+ };
+
+ device.Hid.Npads.AddControllers(new ControllerConfig {
+ Player = PlayerIndex.Player1,
+ Type = type
+ });
_gLWidget = new GLRenderer(_emulationContext);
diff --git a/Ryujinx/Ui/NpadController.cs b/Ryujinx/Ui/NpadController.cs
index 67961b49..b92f687c 100644
--- a/Ryujinx/Ui/NpadController.cs
+++ b/Ryujinx/Ui/NpadController.cs
@@ -1,7 +1,7 @@
using OpenTK;
using OpenTK.Input;
using Ryujinx.Common.Configuration.Hid;
-using Ryujinx.HLE.Input;
+using Ryujinx.HLE.HOS.Services.Hid;
using System;
using InnerNpadController = Ryujinx.Common.Configuration.Hid.NpadController;
@@ -24,7 +24,7 @@ namespace Ryujinx.Ui.Input
return _inner.Enabled && Joystick.GetState(_inner.Index).IsConnected;
}
- public ControllerButtons GetButtons()
+ public ControllerKeys GetButtons()
{
if (!IsEnabled())
{
@@ -33,30 +33,30 @@ namespace Ryujinx.Ui.Input
JoystickState joystickState = Joystick.GetState(_inner.Index);
- ControllerButtons buttons = 0;
-
- if (IsActivated(joystickState, _inner.LeftJoycon.DPadUp)) buttons |= ControllerButtons.DpadUp;
- if (IsActivated(joystickState, _inner.LeftJoycon.DPadDown)) buttons |= ControllerButtons.DpadDown;
- if (IsActivated(joystickState, _inner.LeftJoycon.DPadLeft)) buttons |= ControllerButtons.DpadLeft;
- if (IsActivated(joystickState, _inner.LeftJoycon.DPadRight)) buttons |= ControllerButtons.DPadRight;
- if (IsActivated(joystickState, _inner.LeftJoycon.StickButton)) buttons |= ControllerButtons.StickLeft;
- if (IsActivated(joystickState, _inner.LeftJoycon.ButtonMinus)) buttons |= ControllerButtons.Minus;
- if (IsActivated(joystickState, _inner.LeftJoycon.ButtonL)) buttons |= ControllerButtons.L;
- if (IsActivated(joystickState, _inner.LeftJoycon.ButtonZl)) buttons |= ControllerButtons.Zl;
-
- if (IsActivated(joystickState, _inner.RightJoycon.ButtonA)) buttons |= ControllerButtons.A;
- if (IsActivated(joystickState, _inner.RightJoycon.ButtonB)) buttons |= ControllerButtons.B;
- if (IsActivated(joystickState, _inner.RightJoycon.ButtonX)) buttons |= ControllerButtons.X;
- if (IsActivated(joystickState, _inner.RightJoycon.ButtonY)) buttons |= ControllerButtons.Y;
- if (IsActivated(joystickState, _inner.RightJoycon.StickButton)) buttons |= ControllerButtons.StickRight;
- if (IsActivated(joystickState, _inner.RightJoycon.ButtonPlus)) buttons |= ControllerButtons.Plus;
- if (IsActivated(joystickState, _inner.RightJoycon.ButtonR)) buttons |= ControllerButtons.R;
- if (IsActivated(joystickState, _inner.RightJoycon.ButtonZr)) buttons |= ControllerButtons.Zr;
+ ControllerKeys buttons = 0;
+
+ if (IsActivated(joystickState, _inner.LeftJoycon.DPadUp)) buttons |= ControllerKeys.DpadUp;
+ if (IsActivated(joystickState, _inner.LeftJoycon.DPadDown)) buttons |= ControllerKeys.DpadDown;
+ if (IsActivated(joystickState, _inner.LeftJoycon.DPadLeft)) buttons |= ControllerKeys.DpadLeft;
+ if (IsActivated(joystickState, _inner.LeftJoycon.DPadRight)) buttons |= ControllerKeys.DpadRight;
+ if (IsActivated(joystickState, _inner.LeftJoycon.StickButton)) buttons |= ControllerKeys.LStick;
+ if (IsActivated(joystickState, _inner.LeftJoycon.ButtonMinus)) buttons |= ControllerKeys.Minus;
+ if (IsActivated(joystickState, _inner.LeftJoycon.ButtonL)) buttons |= ControllerKeys.L | ControllerKeys.Sl;
+ if (IsActivated(joystickState, _inner.LeftJoycon.ButtonZl)) buttons |= ControllerKeys.Zl;
+
+ if (IsActivated(joystickState, _inner.RightJoycon.ButtonA)) buttons |= ControllerKeys.A;
+ if (IsActivated(joystickState, _inner.RightJoycon.ButtonB)) buttons |= ControllerKeys.B;
+ if (IsActivated(joystickState, _inner.RightJoycon.ButtonX)) buttons |= ControllerKeys.X;
+ if (IsActivated(joystickState, _inner.RightJoycon.ButtonY)) buttons |= ControllerKeys.Y;
+ if (IsActivated(joystickState, _inner.RightJoycon.StickButton)) buttons |= ControllerKeys.RStick;
+ if (IsActivated(joystickState, _inner.RightJoycon.ButtonPlus)) buttons |= ControllerKeys.Plus;
+ if (IsActivated(joystickState, _inner.RightJoycon.ButtonR)) buttons |= ControllerKeys.R | ControllerKeys.Sr;
+ if (IsActivated(joystickState, _inner.RightJoycon.ButtonZr)) buttons |= ControllerKeys.Zr;
return buttons;
}
- private bool IsActivated(JoystickState joystickState,ControllerInputId controllerInputId)
+ private bool IsActivated(JoystickState joystickState, ControllerInputId controllerInputId)
{
if (controllerInputId <= ControllerInputId.Button20)
{