Procházet zdrojové kódy

feat: add DebugMouse HID (#163)

agnostk před 1 rokem
rodič
revize
d9c8b7d937

+ 4 - 0
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<RingLifo<DebugPadState>>(0x2c8);
             CheckTypeSizeOrThrow<RingLifo<TouchScreenState>>(0x2C38);
             CheckTypeSizeOrThrow<RingLifo<MouseState>>(0x350);
+            CheckTypeSizeOrThrow<RingLifo<DebugMouseState>>(0x350);
             CheckTypeSizeOrThrow<RingLifo<KeyboardState>>(0x3D8);
             CheckTypeSizeOrThrow<Array10<NpadState>>(0x32000);
             CheckTypeSizeOrThrow<SharedMemory>(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);
         }

+ 29 - 0
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<DebugMouseState> 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);
+        }
+    }
+}

+ 20 - 0
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)

+ 12 - 0
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,
+    }
+}

+ 15 - 0
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,
+    }
+}

+ 19 - 0
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;
+    }
+}

+ 7 - 0
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
         /// </summary>
         [FieldOffset(0x9A00)]
         public Array10<NpadState> Npads;
+        
+        /// <summary>
+        /// Debug mouse.
+        /// </summary>
+        [FieldOffset(0x3DC00)]
+        public RingLifo<DebugMouseState> DebugMouse;
 
         public static SharedMemory Create()
         {