From d9c8b7d937ced3fcef1afca9d89724b8b209b1b7 Mon Sep 17 00:00:00 2001 From: agnostk Date: Sun, 3 Nov 2024 16:58:14 -0300 Subject: [PATCH] feat: add DebugMouse HID (#163) --- src/Ryujinx.HLE/HOS/Services/Hid/Hid.cs | 4 +++ .../Hid/HidDevices/DebugMouseDevice.cs | 29 +++++++++++++++++++ .../HOS/Services/Hid/IHidServer.cs | 20 +++++++++++++ .../DebugMouse/DebugMouseAttribute.cs | 12 ++++++++ .../DebugMouse/DebugMouseButton.cs | 15 ++++++++++ .../DebugMouse/DebugMouseState.cs | 19 ++++++++++++ .../Hid/Types/SharedMemory/SharedMemory.cs | 7 +++++ 7 files changed, 106 insertions(+) create mode 100644 src/Ryujinx.HLE/HOS/Services/Hid/HidDevices/DebugMouseDevice.cs create mode 100644 src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugMouse/DebugMouseAttribute.cs create mode 100644 src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugMouse/DebugMouseButton.cs create mode 100644 src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugMouse/DebugMouseState.cs diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Hid.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Hid.cs index dbcbe1870..66b5a5cba 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Hid.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Hid.cs @@ -5,6 +5,7 @@ using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Kernel.Memory; using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory; using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugMouse; using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugPad; using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard; using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Mouse; @@ -28,6 +29,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid public DebugPadDevice DebugPad; public TouchDevice Touchscreen; public MouseDevice Mouse; + public DebugMouseDevice DebugMouse; public KeyboardDevice Keyboard; public NpadDevices Npads; @@ -44,6 +46,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid CheckTypeSizeOrThrow>(0x2c8); CheckTypeSizeOrThrow>(0x2C38); CheckTypeSizeOrThrow>(0x350); + CheckTypeSizeOrThrow>(0x350); CheckTypeSizeOrThrow>(0x3D8); CheckTypeSizeOrThrow>(0x32000); CheckTypeSizeOrThrow(Horizon.HidSize); @@ -64,6 +67,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid DebugPad = new DebugPadDevice(_device, true); Touchscreen = new TouchDevice(_device, true); Mouse = new MouseDevice(_device, false); + DebugMouse = new DebugMouseDevice(_device, false); Keyboard = new KeyboardDevice(_device, false); Npads = new NpadDevices(_device, true); } diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/HidDevices/DebugMouseDevice.cs b/src/Ryujinx.HLE/HOS/Services/Hid/HidDevices/DebugMouseDevice.cs new file mode 100644 index 000000000..cb917444b --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Hid/HidDevices/DebugMouseDevice.cs @@ -0,0 +1,29 @@ +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugMouse; + +namespace Ryujinx.HLE.HOS.Services.Hid +{ + public class DebugMouseDevice : BaseDevice + { + public DebugMouseDevice(Switch device, bool active) : base(device, active) { } + + public void Update() + { + ref RingLifo lifo = ref _device.Hid.SharedMemory.DebugMouse; + + ref DebugMouseState previousEntry = ref lifo.GetCurrentEntryRef(); + + DebugMouseState newState = new() + { + SamplingNumber = previousEntry.SamplingNumber + 1, + }; + + if (Active) + { + // TODO: This is a debug device only present in dev environment, do we want to support it? + } + + lifo.Write(ref newState); + } + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs b/src/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs index e3f505f37..556e35ea6 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs @@ -130,6 +130,26 @@ namespace Ryujinx.HLE.HOS.Services.Hid return ResultCode.Success; } + + [CommandCmif(26)] + // ActivateDebugMouse(nn::applet::AppletResourceUserId) + public ResultCode ActivateDebugMouse(ServiceCtx context) + { + long appletResourceUserId = context.RequestData.ReadInt64(); + + context.Device.Hid.DebugMouse.Active = true; + + // Initialize entries to avoid issues with some games. + + for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++) + { + context.Device.Hid.DebugMouse.Update(); + } + + Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId }); + + return ResultCode.Success; + } [CommandCmif(31)] // ActivateKeyboard(nn::applet::AppletResourceUserId) diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugMouse/DebugMouseAttribute.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugMouse/DebugMouseAttribute.cs new file mode 100644 index 000000000..0b55277d4 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugMouse/DebugMouseAttribute.cs @@ -0,0 +1,12 @@ +using System; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugMouse +{ + [Flags] + enum DebugMouseAttribute : uint + { + None = 0, + Transferable = 1 << 0, + IsConnected = 1 << 1, + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugMouse/DebugMouseButton.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugMouse/DebugMouseButton.cs new file mode 100644 index 000000000..c07fa84af --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugMouse/DebugMouseButton.cs @@ -0,0 +1,15 @@ +using System; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugMouse +{ + [Flags] + enum DebugMouseButton : uint + { + None = 0, + Left = 1 << 0, + Right = 1 << 1, + Middle = 1 << 2, + Forward = 1 << 3, + Back = 1 << 4, + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugMouse/DebugMouseState.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugMouse/DebugMouseState.cs new file mode 100644 index 000000000..e2860c9f5 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugMouse/DebugMouseState.cs @@ -0,0 +1,19 @@ +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugMouse +{ + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct DebugMouseState : ISampledDataStruct + { + public ulong SamplingNumber; + public int X; + public int Y; + public int DeltaX; + public int DeltaY; + public int WheelDeltaX; + public int WheelDeltaY; + public DebugMouseButton Buttons; + public DebugMouseAttribute Attributes; + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/SharedMemory.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/SharedMemory.cs index d6283eb57..59d8f4489 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/SharedMemory.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/SharedMemory.cs @@ -1,5 +1,6 @@ using Ryujinx.Common.Memory; using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugMouse; using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugPad; using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard; using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Mouse; @@ -44,6 +45,12 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory /// [FieldOffset(0x9A00)] public Array10 Npads; + + /// + /// Debug mouse. + /// + [FieldOffset(0x3DC00)] + public RingLifo DebugMouse; public static SharedMemory Create() {