aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AtomicStorage.cs6
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledData.cs7
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledDataStruct.cs65
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/RingLifo.cs2
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadState.cs6
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardModifier.cs3
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardState.cs6
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseState.cs6
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadCommonState.cs6
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadGcTriggerState.cs6
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorState.cs6
-rw-r--r--Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchScreenState.cs6
12 files changed, 91 insertions, 34 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AtomicStorage.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AtomicStorage.cs
index 45b92ba9..da53e421 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AtomicStorage.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/AtomicStorage.cs
@@ -2,7 +2,7 @@
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common
{
- struct AtomicStorage<T> where T: unmanaged
+ struct AtomicStorage<T> where T: unmanaged, ISampledDataStruct
{
public ulong SamplingNumber;
public T Object;
@@ -14,9 +14,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common
public void SetObject(ref T obj)
{
- ISampledData samplingProvider = obj as ISampledData;
+ ulong samplingNumber = ISampledDataStruct.GetSamplingNumber(ref obj);
- Interlocked.Exchange(ref SamplingNumber, samplingProvider.SamplingNumber);
+ Interlocked.Exchange(ref SamplingNumber, samplingNumber);
Thread.MemoryBarrier();
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledData.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledData.cs
deleted file mode 100644
index 08f76747..00000000
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledData.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common
-{
- interface ISampledData
- {
- ulong SamplingNumber { get; }
- }
-}
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledDataStruct.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledDataStruct.cs
new file mode 100644
index 00000000..a382c0c2
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledDataStruct.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Buffers.Binary;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common
+{
+ /// <summary>
+ /// This is a "marker interface" to add some compile-time safety to a convention-based optimization.
+ ///
+ /// Any struct implementing this interface should:
+ /// - use <c>StructLayoutAttribute</c> (and related attributes) to explicity control how the struct is laid out in memory.
+ /// - ensure that the method <c>ISampledDataStruct.GetSamplingNumberFieldOffset()</c> correctly returns the offset, in bytes,
+ /// to the ulong "Sampling Number" field within the struct. Most types have it as the first field, so the default offset is 0.
+ ///
+ /// Example:
+ ///
+ /// <c>
+ /// [StructLayout(LayoutKind.Sequential, Pack = 8)]
+ /// struct DebugPadState : ISampledDataStruct
+ /// {
+ /// public ulong SamplingNumber; // 1st field, so no need to add special handling to GetSamplingNumberFieldOffset()
+ /// // other members...
+ /// }
+ ///
+ /// [StructLayout(LayoutKind.Sequential, Pack = 8)]
+ /// struct SixAxisSensorState : ISampledDataStruct
+ /// {
+ /// public ulong DeltaTime;
+ /// public ulong SamplingNumber; // Not the first field - needs special handling in GetSamplingNumberFieldOffset()
+ /// // other members...
+ /// }
+ /// </c>
+ /// </summary>
+ internal interface ISampledDataStruct
+ {
+ // No Instance Members - marker interface only
+
+ public static ulong GetSamplingNumber<T>(ref T sampledDataStruct) where T : unmanaged, ISampledDataStruct
+ {
+ ReadOnlySpan<T> structSpan = MemoryMarshal.CreateReadOnlySpan(ref sampledDataStruct, 1);
+
+ ReadOnlySpan<byte> byteSpan = MemoryMarshal.Cast<T, byte>(structSpan);
+
+ int fieldOffset = GetSamplingNumberFieldOffset(ref sampledDataStruct);
+
+ if (fieldOffset > 0)
+ {
+ byteSpan = byteSpan.Slice(fieldOffset);
+ }
+
+ ulong value = BinaryPrimitives.ReadUInt64LittleEndian(byteSpan);
+
+ return value;
+ }
+
+ private static int GetSamplingNumberFieldOffset<T>(ref T sampledDataStruct) where T : unmanaged, ISampledDataStruct
+ {
+ return sampledDataStruct switch
+ {
+ Npad.SixAxisSensorState _ => sizeof(ulong),
+ _ => 0
+ };
+ }
+ }
+}
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/RingLifo.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/RingLifo.cs
index 615e3893..ae654d6f 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/RingLifo.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/RingLifo.cs
@@ -5,7 +5,7 @@ using System.Threading;
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common
{
- struct RingLifo<T> where T: unmanaged
+ struct RingLifo<T> where T: unmanaged, ISampledDataStruct
{
private const ulong MaxEntries = 17;
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadState.cs
index 3e1e1ad8..0846cfc7 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadState.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/DebugPad/DebugPadState.cs
@@ -1,15 +1,15 @@
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common;
+using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugPad
{
- struct DebugPadState : ISampledData
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ struct DebugPadState : ISampledDataStruct
{
public ulong SamplingNumber;
public DebugPadAttribute Attributes;
public DebugPadButton Buttons;
public AnalogStickState AnalogStickR;
public AnalogStickState AnalogStickL;
-
- ulong ISampledData.SamplingNumber => SamplingNumber;
}
}
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardModifier.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardModifier.cs
index 72d1603a..839a4e82 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardModifier.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardModifier.cs
@@ -2,9 +2,8 @@
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard
{
- // TODO: This seems entirely wrong
[Flags]
- enum KeyboardModifier : uint
+ enum KeyboardModifier : ulong
{
None = 0,
Control = 1 << 0,
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardState.cs
index 37608506..4de92813 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardState.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Keyboard/KeyboardState.cs
@@ -1,13 +1,13 @@
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common;
+using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard
{
- struct KeyboardState : ISampledData
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ struct KeyboardState : ISampledDataStruct
{
public ulong SamplingNumber;
public KeyboardModifier Modifiers;
public KeyboardKey Keys;
-
- ulong ISampledData.SamplingNumber => SamplingNumber;
}
}
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseState.cs
index 67ad6bf1..c953c794 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseState.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Mouse/MouseState.cs
@@ -1,8 +1,10 @@
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common;
+using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Mouse
{
- struct MouseState : ISampledData
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ struct MouseState : ISampledDataStruct
{
public ulong SamplingNumber;
public int X;
@@ -13,7 +15,5 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Mouse
public int WheelDeltaY;
public MouseButton Buttons;
public MouseAttribute Attributes;
-
- ulong ISampledData.SamplingNumber => SamplingNumber;
}
}
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadCommonState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadCommonState.cs
index eaccef80..64f75ce9 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadCommonState.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadCommonState.cs
@@ -1,8 +1,10 @@
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common;
+using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad
{
- struct NpadCommonState : ISampledData
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ struct NpadCommonState : ISampledDataStruct
{
public ulong SamplingNumber;
public NpadButton Buttons;
@@ -10,7 +12,5 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad
public AnalogStickState AnalogStickR;
public NpadAttribute Attributes;
private uint _reserved;
-
- ulong ISampledData.SamplingNumber => SamplingNumber;
}
}
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadGcTriggerState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadGcTriggerState.cs
index 52668f85..bddd6212 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadGcTriggerState.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadGcTriggerState.cs
@@ -1,15 +1,15 @@
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common;
+using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad
{
- struct NpadGcTriggerState : ISampledData
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ struct NpadGcTriggerState : ISampledDataStruct
{
#pragma warning disable CS0649
public ulong SamplingNumber;
public uint TriggerL;
public uint TriggerR;
#pragma warning restore CS0649
-
- ulong ISampledData.SamplingNumber => SamplingNumber;
}
} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorState.cs
index d024b0b0..18be3276 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorState.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/SixAxisSensorState.cs
@@ -1,9 +1,11 @@
using Ryujinx.Common.Memory;
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common;
+using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad
{
- struct SixAxisSensorState : ISampledData
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ struct SixAxisSensorState : ISampledDataStruct
{
public ulong DeltaTime;
public ulong SamplingNumber;
@@ -13,7 +15,5 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad
public Array9<float> Direction;
public SixAxisSensorAttribute Attributes;
private uint _reserved;
-
- ulong ISampledData.SamplingNumber => SamplingNumber;
}
} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchScreenState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchScreenState.cs
index 8203e49b..cdd4cc45 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchScreenState.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchScreenState.cs
@@ -1,15 +1,15 @@
using Ryujinx.Common.Memory;
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common;
+using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.TouchScreen
{
- struct TouchScreenState : ISampledData
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ struct TouchScreenState : ISampledDataStruct
{
public ulong SamplingNumber;
public int TouchesCount;
private int _reserved;
public Array16<TouchState> Touches;
-
- ulong ISampledData.SamplingNumber => SamplingNumber;
}
}