diff options
author | mageven <62494521+mageven@users.noreply.github.com> | 2020-08-24 02:24:11 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-23 22:54:11 +0200 |
commit | 27179d02180396750cc2ea08ac1e2cc5a91a8763 (patch) | |
tree | d9fb3e03f4553b0aad2c9dec7e74e38f864e199c /Ryujinx.HLE/HOS/Services | |
parent | 01ff648bdf46b85409d1a834987a69150de7adb9 (diff) |
Improve multi-controller support in HID and Controller Applet (#1453)
* Initial commit
Enable proper LED patterns
Toggle Hotkeys only on focus
Ignore Handheld on Docked mode
Remove PrimaryController
Validate NpadIdType
Rewrite NpadDevices to process config in update loop
Cleanup
* Notify in log periodically when no matched controllers
* Remove duplicate StructArrayHelpers in favor of Common.Memory
Fix struct padding CS0169 warns in Touchscreen
* Remove GTK markup from Controller Applet
Use IList instead of List
Explicit list capacity in 1ms loop
Fix formatting
* Restrict ControllerWindow to show valid controller types
Add selected player name to ControllerWindow title
* ControllerWindow: Fix controller type initial value
NpadDevices: Simplify default battery charge
* Address AcK's comments
Use explicit types and fix formatting
* Remove HashSet for SupportedPlayers
Fixes potential exceptions due to race
* Fix ControllerSupportArg struct packing
Also comes with two revisions of struct for 4/8 players max.
Diffstat (limited to 'Ryujinx.HLE/HOS/Services')
15 files changed, 214 insertions, 174 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Hid.cs b/Ryujinx.HLE/HOS/Services/Hid/Hid.cs index c355a050..2db67619 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Hid.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Hid.cs @@ -1,5 +1,7 @@ using Ryujinx.Common; using Ryujinx.HLE.Exceptions; +using Ryujinx.Common.Configuration.Hid; +using System.Collections.Generic; using System.Runtime.CompilerServices; namespace Ryujinx.HLE.HOS.Services.Hid @@ -65,6 +67,24 @@ namespace Ryujinx.HLE.HOS.Services.Hid Npads = new NpadDevices(_device, true); } + internal void RefreshInputConfig(List<InputConfig> inputConfig) + { + ControllerConfig[] npadConfig = new ControllerConfig[inputConfig.Count]; + + for (int i = 0; i < npadConfig.Length; ++i) + { + npadConfig[i].Player = (PlayerIndex)inputConfig[i].PlayerIndex; + npadConfig[i].Type = (ControllerType)inputConfig[i].ControllerType; + } + + _device.Hid.Npads.Configure(npadConfig); + } + + internal void RefreshInputConfigEvent(object _, ReactiveEventArgs<List<InputConfig>> args) + { + RefreshInputConfig(args.NewValue); + } + public ControllerKeys UpdateStickButtons(JoystickPosition leftStick, JoystickPosition rightStick) { ControllerKeys result = 0; diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs index 1c882887..334af975 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs @@ -1,74 +1,118 @@ -using System; +using Ryujinx.Common; using Ryujinx.Common.Logging; +using Ryujinx.Common.Memory; using Ryujinx.HLE.HOS.Kernel.Threading; +using System; +using System.Collections.Generic; namespace Ryujinx.HLE.HOS.Services.Hid { public class NpadDevices : BaseDevice { - internal NpadJoyHoldType JoyHold = NpadJoyHoldType.Vertical; + private const BatteryCharge DefaultBatteryCharge = BatteryCharge.Percent100; + + private const int NoMatchNotifyFrequencyMs = 2000; + private int _activeCount; + private long _lastNotifyTimestamp; + + public const int MaxControllers = 9; // Players 1-8 and Handheld + private ControllerType[] _configuredTypes; + private KEvent[] _styleSetUpdateEvents; + private bool[] _supportedPlayers; + + internal NpadJoyHoldType JoyHold { get; set; } internal bool SixAxisActive = false; // TODO: link to hidserver when implemented + internal ControllerType SupportedStyleSets { get; set; } - private enum FilterState + public NpadDevices(Switch device, bool active = true) : base(device, active) { - Unconfigured = 0, - Configured = 1, - Accepted = 2 + _configuredTypes = new ControllerType[MaxControllers]; + + SupportedStyleSets = ControllerType.Handheld | ControllerType.JoyconPair | + ControllerType.JoyconLeft | ControllerType.JoyconRight | + ControllerType.ProController; + + _supportedPlayers = new bool[MaxControllers]; + _supportedPlayers.AsSpan().Fill(true); + + _styleSetUpdateEvents = new KEvent[MaxControllers]; + for (int i = 0; i < _styleSetUpdateEvents.Length; ++i) + { + _styleSetUpdateEvents[i] = new KEvent(_device.System.KernelContext); + } + + _activeCount = 0; + + JoyHold = NpadJoyHoldType.Vertical; } - private struct NpadConfig + internal ref KEvent GetStyleSetUpdateEvent(PlayerIndex player) { - public ControllerType ConfiguredType; - public FilterState State; + return ref _styleSetUpdateEvents[(int)player]; } - private const int _maxControllers = 9; // Players1-8 and Handheld - private NpadConfig[] _configuredNpads; + internal void ClearSupportedPlayers() + { + _supportedPlayers.AsSpan().Clear(); + } - private ControllerType _supportedStyleSets = ControllerType.ProController | - ControllerType.JoyconPair | - ControllerType.JoyconLeft | - ControllerType.JoyconRight | - ControllerType.Handheld; + internal void SetSupportedPlayer(PlayerIndex player, bool supported = true) + { + _supportedPlayers[(int)player] = supported; + } - public ControllerType SupportedStyleSets + internal IEnumerable<PlayerIndex> GetSupportedPlayers() { - get => _supportedStyleSets; - set + for (int i = 0; i < _supportedPlayers.Length; ++i) { - if (_supportedStyleSets != value) // Deal with spamming + if (_supportedPlayers[i]) { - _supportedStyleSets = value; - MatchControllers(); + yield return (PlayerIndex)i; } } } - public PlayerIndex PrimaryController { get; set; } = PlayerIndex.Unknown; + public bool Validate(int playerMin, int playerMax, ControllerType acceptedTypes, out int configuredCount, out PlayerIndex primaryIndex) + { + primaryIndex = PlayerIndex.Unknown; + configuredCount = 0; - private KEvent[] _styleSetUpdateEvents; + for (int i = 0; i < MaxControllers; ++i) + { + ControllerType npad = _configuredTypes[i]; - private static readonly Array3<BatteryCharge> _fullBattery; + if (npad == ControllerType.Handheld && _device.System.State.DockedMode) + { + continue; + } - public NpadDevices(Switch device, bool active = true) : base(device, active) - { - _configuredNpads = new NpadConfig[_maxControllers]; + ControllerType currentType = _device.Hid.SharedMemory.Npads[i].Header.Type; - _styleSetUpdateEvents = new KEvent[_maxControllers]; + if (currentType != ControllerType.None && (npad & acceptedTypes) != 0 && _supportedPlayers[i]) + { + configuredCount++; + if (primaryIndex == PlayerIndex.Unknown) + { + primaryIndex = (PlayerIndex)i; + } + } + } - for (int i = 0; i < _styleSetUpdateEvents.Length; ++i) + if (configuredCount < playerMin || configuredCount > playerMax || primaryIndex == PlayerIndex.Unknown) { - _styleSetUpdateEvents[i] = new KEvent(_device.System.KernelContext); + return false; } - _fullBattery[0] = _fullBattery[1] = _fullBattery[2] = BatteryCharge.Percent100; + return true; } - public void AddControllers(params ControllerConfig[] configs) + public void Configure(params ControllerConfig[] configs) { + _configuredTypes = new ControllerType[MaxControllers]; + for (int i = 0; i < configs.Length; ++i) { - PlayerIndex player = configs[i].Player; + PlayerIndex player = configs[i].Player; ControllerType controllerType = configs[i].Type; if (player > PlayerIndex.Handheld) @@ -81,77 +125,87 @@ namespace Ryujinx.HLE.HOS.Services.Hid player = PlayerIndex.Handheld; } - _configuredNpads[(int)player] = new NpadConfig { ConfiguredType = controllerType, State = FilterState.Configured }; - } + _configuredTypes[(int)player] = controllerType; - MatchControllers(); + Logger.Info?.Print(LogClass.Hid, $"Configured Controller {controllerType} to {player}"); + } } - private void MatchControllers() + public void Update(IList<GamepadInput> states) { - PrimaryController = PlayerIndex.Unknown; + Remap(); + + UpdateAllEntries(); + + // Update configured inputs + for (int i = 0; i < states.Count; ++i) + { + UpdateInput(states[i]); + } + } - for (int i = 0; i < _configuredNpads.Length; ++i) + private void Remap() + { + // Remap/Init if necessary + for (int i = 0; i < MaxControllers; ++i) { - ref NpadConfig config = ref _configuredNpads[i]; + ControllerType config = _configuredTypes[i]; - if (config.State == FilterState.Unconfigured) + // Remove Handheld config when Docked + if (config == ControllerType.Handheld && _device.System.State.DockedMode) { - continue; // Ignore unconfigured + config = ControllerType.None; } - if ((config.ConfiguredType & _supportedStyleSets) == 0) + // Auto-remap ProController and JoyconPair + if (config == ControllerType.JoyconPair && (SupportedStyleSets & ControllerType.JoyconPair) == 0 && (SupportedStyleSets & ControllerType.ProController) != 0) { - Logger.Warning?.Print(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 + config = ControllerType.ProController; + } + else if (config == ControllerType.ProController && (SupportedStyleSets & ControllerType.ProController) == 0 && (SupportedStyleSets & ControllerType.JoyconPair) != 0) + { + config = ControllerType.JoyconPair; + } - continue; + // Check StyleSet and PlayerSet + if ((config & SupportedStyleSets) == 0 || !_supportedPlayers[i]) + { + config = ControllerType.None; } - InitController((PlayerIndex)i, config.ConfiguredType); + SetupNpad((PlayerIndex)i, config); } - // Couldn't find any matching configuration. Reassign to something that works. - if (PrimaryController == PlayerIndex.Unknown) + if (_activeCount == 0 && PerformanceCounter.ElapsedMilliseconds > _lastNotifyTimestamp + NoMatchNotifyFrequencyMs) { - 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.Warning?.Print(LogClass.Hid, $"No matching controllers found. Reassigning input as ControllerType {controllerType}..."); - - InitController(controllerType == ControllerType.Handheld ? PlayerIndex.Handheld : PlayerIndex.Player1, controllerType); - - return; - } - } - - Logger.Error?.Print(LogClass.Hid, "Couldn't find any appropriate controller."); + Logger.Warning?.Print(LogClass.Hid, $"No matching controllers found. Application requests '{SupportedStyleSets}' on '{string.Join(", ", GetSupportedPlayers())}'"); + _lastNotifyTimestamp = PerformanceCounter.ElapsedMilliseconds; } } - internal ref KEvent GetStyleSetUpdateEvent(PlayerIndex player) + private void SetupNpad(PlayerIndex player, ControllerType type) { - return ref _styleSetUpdateEvents[(int)player]; - } + ref ShMemNpad controller = ref _device.Hid.SharedMemory.Npads[(int)player]; - private void InitController(PlayerIndex player, ControllerType type) - { - if (type == ControllerType.Handheld) + ControllerType oldType = controller.Header.Type; + + if (oldType == type) { - player = PlayerIndex.Handheld; + return; // Already configured } - ref ShMemNpad controller = ref _device.Hid.SharedMemory.Npads[(int)player]; - controller = new ShMemNpad(); // Zero it + if (type == ControllerType.None) + { + _styleSetUpdateEvents[(int)player].ReadableEvent.Signal(); // Signal disconnect + _activeCount--; + + Logger.Info?.Print(LogClass.Hid, $"Disconnected Controller {oldType} from {player}"); + + return; + } + // TODO: Allow customizing colors at config NpadStateHeader defaultHeader = new NpadStateHeader { @@ -168,7 +222,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid NpadSystemProperties.PowerInfo1Connected | NpadSystemProperties.PowerInfo2Connected; - controller.BatteryState = _fullBattery; + controller.BatteryState.ToSpan().Fill(DefaultBatteryCharge); switch (type) { @@ -217,19 +271,13 @@ namespace Ryujinx.HLE.HOS.Services.Hid controller.Header = defaultHeader; - if (PrimaryController == PlayerIndex.Unknown) - { - PrimaryController = player; - } - - _configuredNpads[(int)player].State = FilterState.Accepted; - _styleSetUpdateEvents[(int)player].ReadableEvent.Signal(); + _activeCount++; - Logger.Info?.Print(LogClass.Hid, $"Connected ControllerType {type} to PlayerIndex {player}"); + Logger.Info?.Print(LogClass.Hid, $"Connected Controller {type} to {player}"); } - private static NpadLayoutsIndex ControllerTypeToLayout(ControllerType controllerType) + private static NpadLayoutsIndex ControllerTypeToNpadLayout(ControllerType controllerType) => controllerType switch { ControllerType.ProController => NpadLayoutsIndex.ProController, @@ -241,43 +289,28 @@ namespace Ryujinx.HLE.HOS.Services.Hid _ => NpadLayoutsIndex.SystemExternal }; - public void SetGamepadsInput(params GamepadInput[] states) + private void UpdateInput(GamepadInput state) { - UpdateAllEntries(); - - for (int i = 0; i < states.Length; ++i) - { - SetGamepadState(states[i].PlayerId, states[i].Buttons, states[i].LStick, states[i].RStick); - } - } - - private void SetGamepadState(PlayerIndex player, ControllerKeys buttons, - JoystickPosition leftJoystick, JoystickPosition rightJoystick) - { - if (player == PlayerIndex.Auto) - { - player = PrimaryController; - } - - if (player == PlayerIndex.Unknown) + if (state.PlayerId == PlayerIndex.Unknown) { return; } - if (_configuredNpads[(int)player].State != FilterState.Accepted) + ref ShMemNpad currentNpad = ref _device.Hid.SharedMemory.Npads[(int)state.PlayerId]; + + if (currentNpad.Header.Type == ControllerType.None) { return; } - ref ShMemNpad currentNpad = ref _device.Hid.SharedMemory.Npads[(int)player]; - ref NpadLayout currentLayout = ref currentNpad.Layouts[(int)ControllerTypeToLayout(currentNpad.Header.Type)]; + ref NpadLayout currentLayout = ref currentNpad.Layouts[(int)ControllerTypeToNpadLayout(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; + currentEntry.Buttons = state.Buttons; + currentEntry.LStickX = state.LStick.Dx; + currentEntry.LStickY = state.LStick.Dy; + currentEntry.RStickX = state.RStick.Dx; + currentEntry.RStickY = state.RStick.Dy; // Mirror data to Default layout just in case ref NpadLayout mainLayout = ref currentNpad.Layouts[(int)NpadLayoutsIndex.SystemExternal]; diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidServer/HidUtils.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/HidUtils.cs index c2cd8432..9db5b518 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidServer/HidUtils.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/HidUtils.cs @@ -35,5 +35,19 @@ namespace Ryujinx.HLE.HOS.Services.Hid.HidServer PlayerIndex.Unknown => NpadIdType.Unknown, _ => throw new ArgumentOutOfRangeException(nameof(index)) }; + + public static long GetLedPatternFromNpadId(NpadIdType npadIdType) + => npadIdType switch + { + NpadIdType.Player1 => 0b0001, + NpadIdType.Player2 => 0b0011, + NpadIdType.Player3 => 0b0111, + NpadIdType.Player4 => 0b1111, + NpadIdType.Player5 => 0b1001, + NpadIdType.Player6 => 0b0101, + NpadIdType.Player7 => 0b1101, + NpadIdType.Player8 => 0b0110, + _ => 0b0000 + }; } }
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs b/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs index 3059d947..ec4c0980 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs @@ -594,9 +594,18 @@ namespace Ryujinx.HLE.HOS.Services.Hid NpadIdType[] supportedPlayerIds = new NpadIdType[arraySize]; + context.Device.Hid.Npads.ClearSupportedPlayers(); + for (int i = 0; i < arraySize; ++i) { - supportedPlayerIds[i] = context.Memory.Read<NpadIdType>((ulong)(context.Request.PtrBuff[0].Position + i * 4)); + NpadIdType id = context.Memory.Read<NpadIdType>((ulong)(context.Request.PtrBuff[0].Position + i * 4)); + + if (id >= 0) + { + context.Device.Hid.Npads.SetSupportedPlayer(HidUtils.GetIndexFromNpadIdType(id)); + } + + supportedPlayerIds[i] = id; } Logger.Stub?.PrintStub(LogClass.ServiceHid, $"{arraySize} " + string.Join(",", supportedPlayerIds)); @@ -665,9 +674,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid // GetPlayerLedPattern(uint NpadId) -> ulong LedPattern public ResultCode GetPlayerLedPattern(ServiceCtx context) { - int npadId = context.RequestData.ReadInt32(); + NpadIdType npadId = (NpadIdType)context.RequestData.ReadInt32(); - long ledPattern = 0; + long ledPattern = HidUtils.GetLedPatternFromNpadId(npadId); context.ResponseData.Write(ledPattern); diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/DebugPad/DebugPad.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/DebugPad/DebugPad.cs index e68924da..3fbaa304 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/DebugPad/DebugPad.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/DebugPad/DebugPad.cs @@ -1,3 +1,5 @@ +using Ryujinx.Common.Memory; + namespace Ryujinx.HLE.HOS.Services.Hid { unsafe struct ShMemDebugPad diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/HidSharedMemory.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/HidSharedMemory.cs index d2bd8a23..d950425d 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/HidSharedMemory.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/HidSharedMemory.cs @@ -1,5 +1,4 @@ -using System; -using System.Runtime.InteropServices; +using Ryujinx.Common.Memory; namespace Ryujinx.HLE.HOS.Services.Hid { diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Keyboard/Keyboard.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Keyboard/Keyboard.cs index dcfa5aa1..e2c1844f 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Keyboard/Keyboard.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Keyboard/Keyboard.cs @@ -1,3 +1,5 @@ +using Ryujinx.Common.Memory; + namespace Ryujinx.HLE.HOS.Services.Hid { unsafe struct ShMemKeyboard diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/Mouse.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/Mouse.cs index c1f45c5c..6b99e04a 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/Mouse.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Mouse/Mouse.cs @@ -1,4 +1,6 @@ +using Ryujinx.Common.Memory; + namespace Ryujinx.HLE.HOS.Services.Hid { unsafe struct ShMemMouse diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/Npad.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/Npad.cs index 0bb2628f..4ef83f3d 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/Npad.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/Npad.cs @@ -1,3 +1,5 @@ +using Ryujinx.Common.Memory; + namespace Ryujinx.HLE.HOS.Services.Hid { // TODO: Add missing structs diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayout.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayout.cs index 9851a6b1..24c4f4d4 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayout.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayout.cs @@ -1,3 +1,5 @@ +using Ryujinx.Common.Memory; + namespace Ryujinx.HLE.HOS.Services.Hid { struct NpadLayout diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadSixAxis.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadSixAxis.cs index 5f65db39..a0a39fdc 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadSixAxis.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadSixAxis.cs @@ -1,3 +1,5 @@ +using Ryujinx.Common.Memory; + namespace Ryujinx.HLE.HOS.Services.Hid { struct NpadSixAxis diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/StructArrayHelpers.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/StructArrayHelpers.cs deleted file mode 100644 index f40d16a0..00000000 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/StructArrayHelpers.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.HOS.Services.Hid -{ -#pragma warning disable CS0169 - 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; - } -#pragma warning restore CS0169 -}
\ 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 index 618ddd98..5f12295c 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreen.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreen.cs @@ -1,3 +1,5 @@ +using Ryujinx.Common.Memory; + namespace Ryujinx.HLE.HOS.Services.Hid { unsafe struct ShMemTouchScreen diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenState.cs index a0a9cf23..1c85e291 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenState.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenState.cs @@ -1,3 +1,5 @@ +using Ryujinx.Common.Memory; + namespace Ryujinx.HLE.HOS.Services.Hid { struct TouchScreenState diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenStateData.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenStateData.cs index 872064b3..4d4c48d1 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenStateData.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Touchscreen/TouchScreenStateData.cs @@ -3,13 +3,17 @@ namespace Ryujinx.HLE.HOS.Services.Hid struct TouchScreenStateData { public ulong SampleTimestamp; +#pragma warning disable CS0169 uint _padding; +#pragma warning restore CS0169 public uint TouchIndex; public uint X; public uint Y; public uint DiameterX; public uint DiameterY; public uint Angle; +#pragma warning disable CS0169 uint _padding2; +#pragma warning restore CS0169 } }
\ No newline at end of file |