From f4e879a1e6ad810aa38c1c020467a2589441871b Mon Sep 17 00:00:00 2001 From: Mary-nyan Date: Thu, 24 Nov 2022 15:26:29 +0100 Subject: [PATCH] Reduce usage of Marshal.PtrToStructure and Marshal.StructureToPtr (#3805) * common: Make BinaryReaderExtensions Read & Write take unamanged types This allows us to not rely on Marshal.PtrToStructure and Marshal.StructureToPtr for those. * common: Make MemoryHelper Read & Write takes unamanged types * Update Marshal.SizeOf => Unsafe.SizeOf when appropriate and start moving software applet to unmanaged types --- .../Extensions/BinaryReaderExtensions.cs | 43 +++---------------- Ryujinx.Cpu/MemoryHelper.cs | 27 +++--------- .../SoftwareKeyboardApplet.cs | 23 +++++----- .../SoftwareKeyboardCustomizeDic.cs | 5 +-- .../SoftwareKeyboardDictSet.cs | 6 +-- .../SoftwareKeyboardUserWord.cs | 5 +-- .../FriendService/Types/UserPresence.cs | 22 +++++++--- .../Friend/ServiceCreator/IFriendService.cs | 13 +----- .../Types/NotificationInfo.cs | 10 ++--- .../QueryPlayStatisticsManager.cs | 3 +- .../Time/Clock/Types/ClockSnapshot.cs | 13 +++++- .../HOS/Services/Time/IStaticServiceForPsc.cs | 13 +++--- .../HOS/Services/Time/TimeZone/TimeZone.cs | 5 ++- .../CemuHook/Protocol/ControllerData.cs | 18 +++----- .../CemuHook/Protocol/ControllerInfo.cs | 13 +++--- .../CemuHook/Protocol/SharedResponse.cs | 6 +-- 16 files changed, 88 insertions(+), 137 deletions(-) diff --git a/Ryujinx.Common/Extensions/BinaryReaderExtensions.cs b/Ryujinx.Common/Extensions/BinaryReaderExtensions.cs index 2c24678d11..ea404d2a22 100644 --- a/Ryujinx.Common/Extensions/BinaryReaderExtensions.cs +++ b/Ryujinx.Common/Extensions/BinaryReaderExtensions.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Ryujinx.Common @@ -7,49 +8,15 @@ namespace Ryujinx.Common public static class BinaryReaderExtensions { public unsafe static T ReadStruct(this BinaryReader reader) - where T : struct + where T : unmanaged { - int size = Marshal.SizeOf(); - - byte[] data = reader.ReadBytes(size); - - fixed (byte* ptr = data) - { - return Marshal.PtrToStructure((IntPtr)ptr); - } - } - - public unsafe static T[] ReadStructArray(this BinaryReader reader, int count) - where T : struct - { - int size = Marshal.SizeOf(); - - T[] result = new T[count]; - - for (int i = 0; i < count; i++) - { - byte[] data = reader.ReadBytes(size); - - fixed (byte* ptr = data) - { - result[i] = Marshal.PtrToStructure((IntPtr)ptr); - } - } - - return result; + return MemoryMarshal.Cast(reader.ReadBytes(Unsafe.SizeOf()))[0]; } public unsafe static void WriteStruct(this BinaryWriter writer, T value) - where T : struct + where T : unmanaged { - long size = Marshal.SizeOf(); - - byte[] data = new byte[size]; - - fixed (byte* ptr = data) - { - Marshal.StructureToPtr(value, (IntPtr)ptr, false); - } + ReadOnlySpan data = MemoryMarshal.Cast(MemoryMarshal.CreateReadOnlySpan(ref value, 1)); writer.Write(data); } diff --git a/Ryujinx.Cpu/MemoryHelper.cs b/Ryujinx.Cpu/MemoryHelper.cs index 6194d5b2d3..64ff360e52 100644 --- a/Ryujinx.Cpu/MemoryHelper.cs +++ b/Ryujinx.Cpu/MemoryHelper.cs @@ -1,6 +1,7 @@ using Ryujinx.Memory; using System; using System.IO; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; @@ -23,34 +24,18 @@ namespace Ryujinx.Cpu } } - public unsafe static T Read(IVirtualMemoryManager memory, ulong position) where T : struct + public unsafe static T Read(IVirtualMemoryManager memory, ulong position) where T : unmanaged { - long size = Marshal.SizeOf(); - - byte[] data = new byte[size]; - - memory.Read(position, data); - - fixed (byte* ptr = data) - { - return Marshal.PtrToStructure((IntPtr)ptr); - } + return MemoryMarshal.Cast(memory.GetSpan(position, Unsafe.SizeOf()))[0]; } - public unsafe static ulong Write(IVirtualMemoryManager memory, ulong position, T value) where T : struct + public unsafe static ulong Write(IVirtualMemoryManager memory, ulong position, T value) where T : unmanaged { - long size = Marshal.SizeOf(); - - byte[] data = new byte[size]; - - fixed (byte* ptr = data) - { - Marshal.StructureToPtr(value, (IntPtr)ptr, false); - } + ReadOnlySpan data = MemoryMarshal.Cast(MemoryMarshal.CreateReadOnlySpan(ref value, 1)); memory.Write(position, data); - return (ulong)size; + return (ulong)data.Length; } public static string ReadAsciiString(IVirtualMemoryManager memory, ulong position, long maxSize = -1) diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs index e287318a6e..74073420ff 100644 --- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs +++ b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs @@ -1,4 +1,5 @@ -using Ryujinx.Common.Configuration.Hid; +using Ryujinx.Common; +using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Applets.SoftwareKeyboard; using Ryujinx.HLE.HOS.Services.Am.AppletAE; @@ -9,6 +10,7 @@ using Ryujinx.Memory; using System; using System.Diagnostics; using System.IO; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; @@ -78,13 +80,13 @@ namespace Ryujinx.HLE.HOS.Applets var launchParams = _normalSession.Pop(); var keyboardConfig = _normalSession.Pop(); - _isBackground = keyboardConfig.Length == Marshal.SizeOf(); + _isBackground = keyboardConfig.Length == Unsafe.SizeOf(); if (_isBackground) { // Initialize the keyboard applet in background mode. - _keyboardBackgroundInitialize = ReadStruct(keyboardConfig); + _keyboardBackgroundInitialize = MemoryMarshal.Read(keyboardConfig); _backgroundState = InlineKeyboardState.Uninitialized; if (_device.UiHandler == null) @@ -342,7 +344,7 @@ namespace Ryujinx.HLE.HOS.Applets else { int wordsCount = reader.ReadInt32(); - int wordSize = Marshal.SizeOf(); + int wordSize = Unsafe.SizeOf(); remaining = stream.Length - stream.Position; if (wordsCount > MaxUserWords) @@ -359,8 +361,7 @@ namespace Ryujinx.HLE.HOS.Applets for (int word = 0; word < wordsCount; word++) { - byte[] wordData = reader.ReadBytes(wordSize); - _keyboardBackgroundUserWords[word] = ReadStruct(wordData); + _keyboardBackgroundUserWords[word] = reader.ReadStruct(); } } } @@ -369,27 +370,25 @@ namespace Ryujinx.HLE.HOS.Applets case InlineKeyboardRequest.SetCustomizeDic: // Read the custom dic data. remaining = stream.Length - stream.Position; - if (remaining != Marshal.SizeOf()) + if (remaining != Unsafe.SizeOf()) { Logger.Warning?.Print(LogClass.ServiceAm, $"Received invalid Software Keyboard Customize Dic of {remaining} bytes"); } else { - var keyboardDicData = reader.ReadBytes((int)remaining); - _keyboardBackgroundDic = ReadStruct(keyboardDicData); + _keyboardBackgroundDic = reader.ReadStruct(); } break; case InlineKeyboardRequest.SetCustomizedDictionaries: // Read the custom dictionaries data. remaining = stream.Length - stream.Position; - if (remaining != Marshal.SizeOf()) + if (remaining != Unsafe.SizeOf()) { Logger.Warning?.Print(LogClass.ServiceAm, $"Received invalid Software Keyboard DictSet of {remaining} bytes"); } else { - var keyboardDictData = reader.ReadBytes((int)remaining); - _keyboardBackgroundDictSet = ReadStruct(keyboardDictData); + _keyboardBackgroundDictSet = reader.ReadStruct(); } break; case InlineKeyboardRequest.Calc: diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCustomizeDic.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCustomizeDic.cs index 538fb9274b..53c8c89504 100644 --- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCustomizeDic.cs +++ b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCustomizeDic.cs @@ -5,10 +5,9 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard /// /// A structure used by SetCustomizeDic request to software keyboard. /// - [StructLayout(LayoutKind.Sequential, Pack = 4)] + [StructLayout(LayoutKind.Sequential, Size = 0x70)] struct SoftwareKeyboardCustomizeDic { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 112)] - public byte[] Unknown; + // Unknown } } diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardDictSet.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardDictSet.cs index b4ffdb9082..3855488164 100644 --- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardDictSet.cs +++ b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardDictSet.cs @@ -1,4 +1,5 @@ -using System.Runtime.InteropServices; +using Ryujinx.Common.Memory; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { @@ -21,8 +22,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard /// /// Array of word entries in the buffer. /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)] - public ulong[] Entries; + public Array24 Entries; /// /// Number of used entries in the Entries field. diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUserWord.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUserWord.cs index 08f1c3d33a..f1bfec2b30 100644 --- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUserWord.cs +++ b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUserWord.cs @@ -5,10 +5,9 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard /// /// A structure used by SetUserWordInfo request to the software keyboard. /// - [StructLayout(LayoutKind.Sequential, Pack = 4)] + [StructLayout(LayoutKind.Sequential, Size = 0x64)] struct SoftwareKeyboardUserWord { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)] - public byte[] Unknown; + // Unknown } } diff --git a/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/UserPresence.cs b/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/UserPresence.cs index e7568a4aa5..058c5646a5 100644 --- a/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/UserPresence.cs +++ b/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/FriendService/Types/UserPresence.cs @@ -1,9 +1,12 @@ -using Ryujinx.HLE.HOS.Services.Account.Acc; +using Ryujinx.Common.Memory; +using Ryujinx.HLE.HOS.Services.Account.Acc; +using System; using System.Runtime.InteropServices; +using System.Text; namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator.FriendService { - [StructLayout(LayoutKind.Sequential, Pack = 0x8, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 0x8)] struct UserPresence { public UserId UserId; @@ -13,15 +16,20 @@ namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator.FriendService [MarshalAs(UnmanagedType.I1)] public bool SamePresenceGroupApplication; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x3)] - public char[] Unknown; + public Array3 Unknown; + private AppKeyValueStorageHolder _appKeyValueStorage; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0xC0)] - public char[] AppKeyValueStorage; + public Span AppKeyValueStorage => MemoryMarshal.Cast(MemoryMarshal.CreateSpan(ref _appKeyValueStorage, AppKeyValueStorageHolder.Size)); + + [StructLayout(LayoutKind.Sequential, Pack = 0x1, Size = Size)] + private struct AppKeyValueStorageHolder + { + public const int Size = 0xC0; + } public override string ToString() { - return $"UserPresence {{ UserId: {UserId}, LastTimeOnlineTimestamp: {LastTimeOnlineTimestamp}, Status: {Status}, AppKeyValueStorage: {AppKeyValueStorage} }}"; + return $"UserPresence {{ UserId: {UserId}, LastTimeOnlineTimestamp: {LastTimeOnlineTimestamp}, Status: {Status}, AppKeyValueStorage: {Encoding.ASCII.GetString(AppKeyValueStorage)} }}"; } } } \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/IFriendService.cs b/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/IFriendService.cs index ec947414f2..8159d09189 100644 --- a/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/IFriendService.cs +++ b/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/IFriendService.cs @@ -236,23 +236,14 @@ namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator ulong position = context.Request.PtrBuff[0].Position; ulong size = context.Request.PtrBuff[0].Size; - byte[] bufferContent = new byte[size]; - - context.Memory.Read(position, bufferContent); + ReadOnlySpan userPresenceInputArray = MemoryMarshal.Cast(context.Memory.GetSpan(position, (int)size)); if (uuid.IsNull) { return ResultCode.InvalidArgument; } - int elementCount = bufferContent.Length / Marshal.SizeOf(); - - using (BinaryReader bufferReader = new BinaryReader(new MemoryStream(bufferContent))) - { - UserPresence[] userPresenceInputArray = bufferReader.ReadStructArray(elementCount); - - Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { UserId = uuid.ToString(), userPresenceInputArray }); - } + Logger.Stub?.PrintStub(LogClass.ServiceFriend, new { UserId = uuid.ToString(), userPresenceInputArray = userPresenceInputArray.ToArray() }); return ResultCode.Success; } diff --git a/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/NotificationService/Types/NotificationInfo.cs b/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/NotificationService/Types/NotificationInfo.cs index 1bd6f01189..e710bf064c 100644 --- a/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/NotificationService/Types/NotificationInfo.cs +++ b/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/NotificationService/Types/NotificationInfo.cs @@ -1,15 +1,13 @@ -using System.Runtime.InteropServices; +using Ryujinx.Common.Memory; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator.NotificationService { - [StructLayout(LayoutKind.Sequential, Pack = 0x8, Size = 0x10)] + [StructLayout(LayoutKind.Sequential, Size = 0x10)] struct NotificationInfo { public NotificationEventType Type; - - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x4)] - public char[] Padding; - + private Array4 _padding; public long NetworkUserIdPlaceholder; } } \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs b/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs index fc6635fa75..1d6cc118e5 100644 --- a/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs +++ b/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs @@ -5,6 +5,7 @@ using Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService.Types; using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService @@ -75,7 +76,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService for (int i = 0; i < filteredApplicationPlayStatistics.Count(); i++) { - MemoryHelper.Write(context.Memory, outputPosition + (ulong)(i * Marshal.SizeOf()), filteredApplicationPlayStatistics.ElementAt(i).Value); + MemoryHelper.Write(context.Memory, outputPosition + (ulong)(i * Unsafe.SizeOf()), filteredApplicationPlayStatistics.ElementAt(i).Value); } context.ResponseData.Write(filteredApplicationPlayStatistics.Count()); diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/Types/ClockSnapshot.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/Types/ClockSnapshot.cs index df1f151fe7..07c1b405f8 100644 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/Types/ClockSnapshot.cs +++ b/Ryujinx.HLE/HOS/Services/Time/Clock/Types/ClockSnapshot.cs @@ -1,4 +1,5 @@ using Ryujinx.HLE.HOS.Services.Time.TimeZone; +using System; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Time.Clock @@ -16,14 +17,22 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock public CalendarAdditionalInfo NetworkCalendarAdditionalTime; public SteadyClockTimePoint SteadyClockTimePoint; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x24)] - public char[] LocationName; + private LocationNameStorageHolder _locationName; + + public Span LocationName => MemoryMarshal.Cast(MemoryMarshal.CreateSpan(ref _locationName, LocationNameStorageHolder.Size)); [MarshalAs(UnmanagedType.I1)] public bool IsAutomaticCorrectionEnabled; public byte Type; public ushort Unknown; + + [StructLayout(LayoutKind.Sequential, Pack = 1, Size = Size)] + private struct LocationNameStorageHolder + { + public const int Size = 0x24; + } + public static ResultCode GetCurrentTime(out long currentTime, SteadyClockTimePoint steadyClockTimePoint, SystemClockContext context) { currentTime = 0; diff --git a/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForPsc.cs b/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForPsc.cs index 441e4267b4..4f35181210 100644 --- a/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForPsc.cs +++ b/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForPsc.cs @@ -8,7 +8,9 @@ using Ryujinx.HLE.HOS.Services.Time.TimeZone; using System; using System.Diagnostics; using System.IO; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Text; namespace Ryujinx.HLE.HOS.Services.Time { @@ -281,7 +283,7 @@ namespace Ryujinx.HLE.HOS.Services.Time { byte type = context.RequestData.ReadByte(); - context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf()); + context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Unsafe.SizeOf()); context.RequestData.BaseStream.Position += 7; @@ -372,12 +374,9 @@ namespace Ryujinx.HLE.HOS.Services.Time return result; } - char[] tzName = deviceLocationName.ToCharArray(); - char[] locationName = new char[0x24]; + ReadOnlySpan tzName = Encoding.ASCII.GetBytes(deviceLocationName); - Array.Copy(tzName, locationName, tzName.Length); - - clockSnapshot.LocationName = locationName; + tzName.CopyTo(clockSnapshot.LocationName); result = ClockSnapshot.GetCurrentTime(out clockSnapshot.UserTime, currentTimePoint, clockSnapshot.UserContext); @@ -414,7 +413,7 @@ namespace Ryujinx.HLE.HOS.Services.Time private ClockSnapshot ReadClockSnapshotFromBuffer(ServiceCtx context, IpcPtrBuffDesc ipcDesc) { - Debug.Assert(ipcDesc.Size == (ulong)Marshal.SizeOf()); + Debug.Assert(ipcDesc.Size == (ulong)Unsafe.SizeOf()); byte[] temp = new byte[ipcDesc.Size]; diff --git a/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZone.cs b/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZone.cs index 12f6e90d43..f7477e97db 100644 --- a/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZone.cs +++ b/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZone.cs @@ -5,6 +5,7 @@ using Ryujinx.HLE.Utilities; using System; using System.Buffers.Binary; using System.IO; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; @@ -890,14 +891,14 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone long streamLength = reader.BaseStream.Length; - if (streamLength < Marshal.SizeOf()) + if (streamLength < Unsafe.SizeOf()) { return false; } TzifHeader header = reader.ReadStruct(); - streamLength -= Marshal.SizeOf(); + streamLength -= Unsafe.SizeOf(); int ttisGMTCount = Detzcode32(header.TtisGMTCount); int ttisSTDCount = Detzcode32(header.TtisSTDCount); diff --git a/Ryujinx.Input/Motion/CemuHook/Protocol/ControllerData.cs b/Ryujinx.Input/Motion/CemuHook/Protocol/ControllerData.cs index 9ff8dc9107..7fb72344c1 100644 --- a/Ryujinx.Input/Motion/CemuHook/Protocol/ControllerData.cs +++ b/Ryujinx.Input/Motion/CemuHook/Protocol/ControllerData.cs @@ -1,16 +1,15 @@ -using System.Runtime.InteropServices; +using Ryujinx.Common.Memory; +using System.Runtime.InteropServices; namespace Ryujinx.Input.Motion.CemuHook.Protocol { [StructLayout(LayoutKind.Sequential, Pack = 1)] struct ControllerDataRequest { - public MessageType Type; + public MessageType Type; public SubscriberType SubscriberType; - public byte Slot; - - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] - public byte[] MacAddress; + public byte Slot; + public Array6 MacAddress; } [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -27,11 +26,8 @@ namespace Ryujinx.Input.Motion.CemuHook.Protocol public uint DPadAnalog; public ulong MainButtonsAnalog; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] - public byte[] Touch1; - - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] - public byte[] Touch2; + public Array6 Touch1; + public Array6 Touch2; public ulong MotionTimestamp; public float AccelerometerX; diff --git a/Ryujinx.Input/Motion/CemuHook/Protocol/ControllerInfo.cs b/Ryujinx.Input/Motion/CemuHook/Protocol/ControllerInfo.cs index d483633eba..63d4524a8c 100644 --- a/Ryujinx.Input/Motion/CemuHook/Protocol/ControllerInfo.cs +++ b/Ryujinx.Input/Motion/CemuHook/Protocol/ControllerInfo.cs @@ -1,21 +1,20 @@ -using System.Runtime.InteropServices; +using Ryujinx.Common.Memory; +using System.Runtime.InteropServices; namespace Ryujinx.Input.Motion.CemuHook.Protocol { [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct ControllerInfoResponse { - public SharedResponse Shared; - private byte _zero; + public SharedResponse Shared; + private byte _zero; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct ControllerInfoRequest { public MessageType Type; - public int PortsCount; - - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] - public byte[] PortIndices; + public int PortsCount; + public Array4 PortIndices; } } \ No newline at end of file diff --git a/Ryujinx.Input/Motion/CemuHook/Protocol/SharedResponse.cs b/Ryujinx.Input/Motion/CemuHook/Protocol/SharedResponse.cs index 0593286d32..e2e1ee9b48 100644 --- a/Ryujinx.Input/Motion/CemuHook/Protocol/SharedResponse.cs +++ b/Ryujinx.Input/Motion/CemuHook/Protocol/SharedResponse.cs @@ -1,4 +1,5 @@ -using System.Runtime.InteropServices; +using Ryujinx.Common.Memory; +using System.Runtime.InteropServices; namespace Ryujinx.Input.Motion.CemuHook.Protocol { @@ -11,8 +12,7 @@ namespace Ryujinx.Input.Motion.CemuHook.Protocol public DeviceModelType ModelType; public ConnectionType ConnectionType; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] - public byte[] MacAddress; + public Array6 MacAddress; public BatteryStatus BatteryStatus; }