forked from Mirror/Ryujinx
3443023a08
* hid: Rewrite shared memory management This entirely rewrite our ancient (and original) HID shared memory interface to be more usable and accurate. HID update logics were updated to reflect those changes but should work still the same way it previously did. This need heavy testing just in case to avoid possible regressions. * Silence warnings * Address gdkchan's comments * Address Ac_K's comments * Address one missing nit
109 lines
4.2 KiB
C#
109 lines
4.2 KiB
C#
using Ryujinx.Common;
|
|
using Ryujinx.HLE.Exceptions;
|
|
using Ryujinx.Common.Configuration.Hid;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.CompilerServices;
|
|
using Ryujinx.Common.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.Mouse;
|
|
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard;
|
|
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugPad;
|
|
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.TouchScreen;
|
|
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad;
|
|
|
|
namespace Ryujinx.HLE.HOS.Services.Hid
|
|
{
|
|
public class Hid
|
|
{
|
|
private readonly Switch _device;
|
|
|
|
private readonly ulong _hidMemoryAddress;
|
|
|
|
internal ref SharedMemory SharedMemory => ref _device.Memory.GetRef<SharedMemory>(_hidMemoryAddress);
|
|
|
|
internal const int SharedMemEntryCount = 17;
|
|
|
|
public DebugPadDevice DebugPad;
|
|
public TouchDevice Touchscreen;
|
|
public MouseDevice Mouse;
|
|
public KeyboardDevice Keyboard;
|
|
public NpadDevices Npads;
|
|
|
|
private static void CheckTypeSizeOrThrow<T>(int expectedSize)
|
|
{
|
|
if (Unsafe.SizeOf<T>() != expectedSize)
|
|
{
|
|
throw new InvalidStructLayoutException<T>(expectedSize);
|
|
}
|
|
}
|
|
|
|
static Hid()
|
|
{
|
|
CheckTypeSizeOrThrow<RingLifo<DebugPadState>>(0x2c8);
|
|
CheckTypeSizeOrThrow<RingLifo<TouchScreenState>>(0x2C38);
|
|
CheckTypeSizeOrThrow<RingLifo<MouseState>>(0x350);
|
|
CheckTypeSizeOrThrow<RingLifo<KeyboardState>>(0x3D8);
|
|
CheckTypeSizeOrThrow<Array10<NpadState>>(0x32000);
|
|
CheckTypeSizeOrThrow<SharedMemory>(Horizon.HidSize);
|
|
}
|
|
|
|
public Hid(in Switch device, ulong sharedHidMemoryAddress)
|
|
{
|
|
_device = device;
|
|
_hidMemoryAddress = sharedHidMemoryAddress;
|
|
|
|
SharedMemory = SharedMemory.Create();
|
|
}
|
|
|
|
public void InitDevices()
|
|
{
|
|
DebugPad = new DebugPadDevice(_device, true);
|
|
Touchscreen = new TouchDevice(_device, true);
|
|
Mouse = new MouseDevice(_device, false);
|
|
Keyboard = new KeyboardDevice(_device, false);
|
|
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)
|
|
{
|
|
const int stickButtonThreshold = short.MaxValue / 2;
|
|
ControllerKeys result = 0;
|
|
|
|
result |= (leftStick.Dx < -stickButtonThreshold) ? ControllerKeys.LStickLeft : result;
|
|
result |= (leftStick.Dx > stickButtonThreshold) ? ControllerKeys.LStickRight : result;
|
|
result |= (leftStick.Dy < -stickButtonThreshold) ? ControllerKeys.LStickDown : result;
|
|
result |= (leftStick.Dy > stickButtonThreshold) ? ControllerKeys.LStickUp : result;
|
|
|
|
result |= (rightStick.Dx < -stickButtonThreshold) ? ControllerKeys.RStickLeft : result;
|
|
result |= (rightStick.Dx > stickButtonThreshold) ? ControllerKeys.RStickRight : result;
|
|
result |= (rightStick.Dy < -stickButtonThreshold) ? ControllerKeys.RStickDown : result;
|
|
result |= (rightStick.Dy > stickButtonThreshold) ? ControllerKeys.RStickUp : result;
|
|
|
|
return result;
|
|
}
|
|
|
|
internal static ulong GetTimestampTicks()
|
|
{
|
|
return (ulong)PerformanceCounter.ElapsedMilliseconds * 19200;
|
|
}
|
|
}
|
|
}
|