Use a struct for HID shared memory (based on libnx struct)

This commit is contained in:
gdkchan 2020-01-03 00:31:13 -03:00
parent f9847590d9
commit 77293d77ce
22 changed files with 410 additions and 424 deletions

View file

@ -113,7 +113,7 @@ namespace Ryujinx.HLE.HOS
public int GlobalAccessLogMode { get; set; }
internal long HidBaseAddress { get; private set; }
internal ulong HidBaseAddress { get; private set; }
internal FileSystemServer FsServer { get; private set; }
internal EmulatedGameCard GameCard { get; private set; }
@ -172,7 +172,7 @@ namespace Ryujinx.HLE.HOS
ulong iirsPa = region.Address + HidSize + FontSize;
ulong timePa = region.Address + HidSize + FontSize + IirsSize;
HidBaseAddress = (long)(hidPa - DramMemoryMap.DramBase);
HidBaseAddress = hidPa - DramMemoryMap.DramBase;
KPageList hidPageList = new KPageList();
KPageList fontPageList = new KPageList();

View file

@ -2,141 +2,100 @@
namespace Ryujinx.HLE.Input
{
public abstract class BaseController : IHidDevice
public class BaseController
{
protected ControllerStatus HidControllerType;
protected ControllerId ControllerId;
private long _currentLayoutOffset;
private long _mainLayoutOffset;
protected long DeviceStateOffset => Offset + 0x4188;
protected Switch Device { get; }
public long Offset { get; private set; }
public bool Connected { get; protected set; }
protected ControllerStatus ControllerType;
public ControllerHeader Header { get; private set; }
public ControllerStateHeader CurrentStateHeader { get; private set; }
public ControllerDeviceState DeviceState { get; private set; }
public ControllerLayouts CurrentLayout { get; private set; }
public ControllerState LastInputState { get; set; }
public ControllerConnectionState ConnectionState { get; protected set; }
private ControllerId _controllerId;
private ControllerLayouts _currentLayout;
private HidControllerHeader _header;
private HidControllerMisc _misc;
protected ControllerConnectionState ConnectionState;
public BaseController(Switch device, ControllerStatus controllerType)
{
Device = device;
HidControllerType = controllerType;
Device = device;
ControllerType = controllerType;
}
protected void Initialize(
bool isHalf,
(NpadColor left, NpadColor right) bodyColors,
(NpadColor left, NpadColor right) buttonColors,
(NpadColor Left, NpadColor Right) bodyColors,
(NpadColor Left, NpadColor Right) buttonColors,
ControllerColorDescription singleColorDesc = 0,
ControllerColorDescription splitColorDesc = 0,
NpadColor singleBodyColor = 0,
NpadColor singleButtonColor = 0
)
NpadColor singleButtonColor = 0)
{
Header = new ControllerHeader()
_header = new HidControllerHeader()
{
IsJoyConHalf = isHalf ? 1 : 0,
LeftBodyColor = bodyColors.left,
LeftButtonColor = buttonColors.left,
RightBodyColor = bodyColors.right,
RightButtonColor = buttonColors.right,
Status = HidControllerType,
SingleBodyColor = singleBodyColor,
SingleButtonColor = singleButtonColor,
SplitColorDescription = splitColorDesc,
SingleColorDescription = singleColorDesc,
Type = ControllerType,
IsHalf = isHalf,
LeftColorBody = bodyColors.Left,
LeftColorButtons = buttonColors.Left,
RightColorBody = bodyColors.Right,
RightColorButtons = buttonColors.Right,
SingleColorBody = singleBodyColor,
SingleColorButtons = singleButtonColor,
SplitColorsDescriptor = splitColorDesc,
SingleColorsDescriptor = singleColorDesc
};
CurrentStateHeader = new ControllerStateHeader
{
EntryCount = HidEntryCount,
MaxEntryCount = HidEntryCount - 1,
CurrentEntryIndex = -1
};
DeviceState = new ControllerDeviceState()
_misc = new HidControllerMisc()
{
PowerInfo0BatteryState = BatteryState.Percent100,
PowerInfo1BatteryState = BatteryState.Percent100,
PowerInfo2BatteryState = BatteryState.Percent100,
DeviceType = ControllerDeviceType.NPadLeftController | ControllerDeviceType.NPadRightController,
DeviceFlags = DeviceFlags.PowerInfo0Connected
| DeviceFlags.PowerInfo1Connected
| DeviceFlags.PowerInfo2Connected
};
LastInputState = new ControllerState()
{
SamplesTimestamp = -1,
SamplesTimestamp2 = -1
DeviceFlags = DeviceFlags.PowerInfo0Connected |
DeviceFlags.PowerInfo1Connected |
DeviceFlags.PowerInfo2Connected
};
}
public virtual void Connect(ControllerId controllerId)
{
ControllerId = controllerId;
_controllerId = controllerId;
Offset = Device.Hid.HidPosition + HidControllersOffset + (int)controllerId * HidControllerSize;
ref HidSharedMemory sharedMemory = ref Device.Hid.SharedMemory;
_mainLayoutOffset = Offset + HidControllerHeaderSize
+ ((int)ControllerLayouts.Main * HidControllerLayoutsSize);
ref HidController controller = ref sharedMemory.Controllers[(int)controllerId];
Device.Memory.ZeroFill((ulong)Offset, 0x5000);
Device.Memory.Write((ulong)Offset, Header);
Device.Memory.Write((ulong)DeviceStateOffset, DeviceState);
Connected = true;
controller.Header = _header;
controller.Misc = _misc;
}
public void SetLayout(ControllerLayouts controllerLayout)
{
CurrentLayout = controllerLayout;
_currentLayoutOffset = Offset + HidControllerHeaderSize
+ ((int)controllerLayout * HidControllerLayoutsSize);
_currentLayout = controllerLayout;
}
public void SendInput(
ControllerButtons buttons,
JoystickPosition leftStick,
JoystickPosition rightStick)
public void SendInput(ControllerButtons buttons, JoystickPosition leftStick, JoystickPosition rightStick)
{
ControllerState currentInput = new ControllerState()
{
SamplesTimestamp = (long)LastInputState.SamplesTimestamp + 1,
SamplesTimestamp2 = (long)LastInputState.SamplesTimestamp + 1,
ButtonState = buttons,
ConnectionState = ConnectionState,
LeftStick = leftStick,
RightStick = rightStick
};
ref HidSharedMemory sharedMemory = ref Device.Hid.SharedMemory;
ControllerStateHeader newInputStateHeader = new ControllerStateHeader
{
EntryCount = HidEntryCount,
MaxEntryCount = HidEntryCount - 1,
CurrentEntryIndex = (CurrentStateHeader.CurrentEntryIndex + 1) % HidEntryCount,
Timestamp = GetTimestamp(),
};
ref HidControllerLayout layout = ref sharedMemory.Controllers[(int)_controllerId].Layouts[(int)_currentLayout];
Device.Memory.Write((ulong)_currentLayoutOffset, newInputStateHeader);
Device.Memory.Write((ulong)_mainLayoutOffset, newInputStateHeader);
layout.Header.NumEntries = 17;
layout.Header.MaxEntryIndex = 16;
long currentInputStateOffset = HidControllersLayoutHeaderSize
+ newInputStateHeader.CurrentEntryIndex * HidControllersInputEntrySize;
layout.Header.LatestEntry = (layout.Header.LatestEntry + 1) % 17;
Device.Memory.Write((ulong)(_currentLayoutOffset + currentInputStateOffset), currentInput);
Device.Memory.Write((ulong)(_mainLayoutOffset + currentInputStateOffset), currentInput);
layout.Header.TimestampTicks = GetTimestamp();
LastInputState = currentInput;
CurrentStateHeader = newInputStateHeader;
ref HidControllerInputEntry entry = ref layout.Entries[(int)layout.Header.LatestEntry];
entry.Timestamp++;
entry.Timestamp2++;
entry.Buttons = buttons;
entry.ConnectionState = ConnectionState;
entry.Joysticks[0] = leftStick;
entry.Joysticks[1] = rightStick;
}
}
}

View file

@ -19,7 +19,7 @@
public override void Connect(ControllerId controllerId)
{
if (HidControllerType != ControllerStatus.NpadLeft && HidControllerType != ControllerStatus.NpadRight)
if (ControllerType != ControllerStatus.NpadLeft && ControllerType != ControllerStatus.NpadRight)
{
_isHalf = false;
}
@ -27,7 +27,9 @@
ConnectionState = ControllerConnectionState.ControllerStateConnected;
if (controllerId == ControllerId.ControllerHandheld)
{
ConnectionState |= ControllerConnectionState.ControllerStateWired;
}
ControllerColorDescription singleColorDesc =
ControllerColorDescription.ColorDescriptionColorsNonexistent;
@ -37,32 +39,33 @@
NpadColor singleBodyColor = NpadColor.Black;
NpadColor singleButtonColor = NpadColor.Black;
Initialize(_isHalf,
Initialize(
_isHalf,
(_npadBodyColors.Left, _npadBodyColors.Right),
(_npadButtonColors.Left, _npadButtonColors.Right),
singleColorDesc,
splitColorDesc,
singleBodyColor,
singleButtonColor );
singleButtonColor);
base.Connect(controllerId);
var _currentLayout = ControllerLayouts.HandheldJoined;
var currentLayout = ControllerLayouts.HandheldJoined;
switch (HidControllerType)
switch (ControllerType)
{
case ControllerStatus.NpadLeft:
_currentLayout = ControllerLayouts.Left;
currentLayout = ControllerLayouts.Left;
break;
case ControllerStatus.NpadRight:
_currentLayout = ControllerLayouts.Right;
currentLayout = ControllerLayouts.Right;
break;
case ControllerStatus.NpadPair:
_currentLayout = ControllerLayouts.Joined;
currentLayout = ControllerLayouts.Joined;
break;
}
SetLayout(_currentLayout);
SetLayout(currentLayout);
}
}
}

View file

@ -2,17 +2,11 @@
{
public class ProController : BaseController
{
private bool _wired = false;
private readonly NpadColor _bodyColor;
private readonly NpadColor _buttonColor;
private NpadColor _bodyColor;
private NpadColor _buttonColor;
public ProController(Switch device,
NpadColor bodyColor,
NpadColor buttonColor) : base(device, ControllerStatus.ProController)
public ProController(Switch device, NpadColor bodyColor, NpadColor buttonColor) : base(device, ControllerStatus.ProController)
{
_wired = true;
_bodyColor = bodyColor;
_buttonColor = buttonColor;
}
@ -26,7 +20,8 @@
ConnectionState = ControllerConnectionState.ControllerStateConnected | ControllerConnectionState.ControllerStateWired;
Initialize(false,
Initialize(
false,
(0, 0),
(0, 0),
singleColorDesc,

View file

@ -2,7 +2,7 @@
{
public enum BatteryState : int
{
// TODO : Check if these are the correct states
// TODO: Check if these are the correct states
Percent0 = 0,
Percent25 = 1,
Percent50 = 2,

View file

@ -1,18 +0,0 @@
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.Input
{
[StructLayout(LayoutKind.Sequential)]
public unsafe struct ControllerDeviceState
{
public ControllerDeviceType DeviceType;
public int Padding;
public DeviceFlags DeviceFlags;
public int UnintendedHomeButtonInputProtectionEnabled;
public BatteryState PowerInfo0BatteryState;
public BatteryState PowerInfo1BatteryState;
public BatteryState PowerInfo2BatteryState;
public fixed byte ControllerMac[16];
public fixed byte ControllerMac2[16];
}
}

View file

@ -7,6 +7,6 @@ namespace Ryujinx.HLE.Input
{
ProController = 1 << 0,
NPadLeftController = 1 << 4,
NPadRightController = 1 << 5,
NPadRightController = 1 << 5
}
}

View file

@ -1,19 +0,0 @@
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.Input
{
[StructLayout(LayoutKind.Sequential)]
public struct ControllerHeader
{
public ControllerStatus Status;
public int IsJoyConHalf;
public ControllerColorDescription SingleColorDescription;
public NpadColor SingleBodyColor;
public NpadColor SingleButtonColor;
public ControllerColorDescription SplitColorDescription;
public NpadColor RightBodyColor;
public NpadColor RightButtonColor;
public NpadColor LeftBodyColor;
public NpadColor LeftButtonColor;
}
}

View file

@ -1,15 +0,0 @@
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.Input
{
[StructLayout(LayoutKind.Sequential)]
public struct ControllerState
{
public long SamplesTimestamp;
public long SamplesTimestamp2;
public ControllerButtons ButtonState;
public JoystickPosition LeftStick;
public JoystickPosition RightStick;
public ControllerConnectionState ConnectionState;
}
}

View file

@ -1,6 +1,6 @@
namespace Ryujinx.HLE.Input
{
public enum NpadColor : int //Thanks to CTCaer
public enum NpadColor : int
{
Black = 0,

View file

@ -7,59 +7,33 @@ namespace Ryujinx.HLE.Input
{
public partial class Hid
{
private Switch _device;
private readonly Switch _device;
private long _touchScreenOffset;
private long _touchEntriesOffset;
private long _keyboardOffset;
private ulong _sharedMemoryAddress;
private TouchHeader _currentTouchHeader;
private KeyboardHeader _currentKeyboardHeader;
private KeyboardEntry _currentKeyboardEntry;
internal ref HidSharedMemory SharedMemory => ref _device.Memory.GetRef<HidSharedMemory>(_sharedMemoryAddress);
public BaseController PrimaryController { get; private set; }
internal long HidPosition;
public Hid(Switch device, long hidPosition)
public Hid(Switch device, ulong sharedMemoryAddress)
{
_device = device;
HidPosition = hidPosition;
_device = device;
_sharedMemoryAddress = sharedMemoryAddress;
device.Memory.ZeroFill((ulong)hidPosition, Horizon.HidSize);
_currentTouchHeader = new TouchHeader()
{
CurrentEntryIndex = -1,
};
_currentKeyboardHeader = new KeyboardHeader()
{
CurrentEntryIndex = -1,
};
_currentKeyboardEntry = new KeyboardEntry()
{
SamplesTimestamp = -1,
SamplesTimestamp2 = -1
};
_touchScreenOffset = HidPosition + HidTouchScreenOffset;
_touchEntriesOffset = _touchScreenOffset + HidTouchHeaderSize;
_keyboardOffset = HidPosition + HidKeyboardOffset;
device.Memory.ZeroFill(sharedMemoryAddress, Horizon.HidSize);
}
private static ControllerStatus ConvertControllerTypeToState(ControllerType controllerType)
{
switch (controllerType)
return controllerType switch
{
case ControllerType.Handheld: return ControllerStatus.Handheld;
case ControllerType.NpadLeft: return ControllerStatus.NpadLeft;
case ControllerType.NpadRight: return ControllerStatus.NpadRight;
case ControllerType.NpadPair: return ControllerStatus.NpadPair;
case ControllerType.ProController: return ControllerStatus.ProController;
default: throw new NotImplementedException();
}
ControllerType.Handheld => ControllerStatus.Handheld,
ControllerType.NpadLeft => ControllerStatus.NpadLeft,
ControllerType.NpadRight => ControllerStatus.NpadRight,
ControllerType.NpadPair => ControllerStatus.NpadPair,
ControllerType.ProController => ControllerStatus.ProController,
_ => throw new NotImplementedException(),
};
}
public void InitializePrimaryController(ControllerType controllerType)
@ -73,18 +47,17 @@ namespace Ryujinx.HLE.Input
}
else
{
PrimaryController = new NpadController(ConvertControllerTypeToState(controllerType),
_device,
(NpadColor.BodyNeonRed, NpadColor.BodyNeonRed),
(NpadColor.ButtonsNeonBlue, NpadColor.ButtonsNeonBlue));
PrimaryController = new NpadController(
ConvertControllerTypeToState(controllerType),
_device,
(NpadColor.BodyNeonRed, NpadColor.BodyNeonRed),
(NpadColor.ButtonsNeonBlue, NpadColor.ButtonsNeonBlue));
}
PrimaryController.Connect(controllerId);
}
public ControllerButtons UpdateStickButtons(
JoystickPosition leftStick,
JoystickPosition rightStick)
public static ControllerButtons UpdateStickButtons(JoystickPosition leftStick, JoystickPosition rightStick)
{
ControllerButtons result = 0;
@ -130,93 +103,71 @@ namespace Ryujinx.HLE.Input
return result;
}
public void SetTouchPoints(params TouchPoint[] points)
{
long timestamp = GetTimestamp();
long sampleCounter = _currentTouchHeader.SamplesTimestamp + 1;
ref HidSharedMemory sharedMemory = ref SharedMemory;
var newTouchHeader = new TouchHeader
ref HidTouchScreen touchScreen = ref sharedMemory.Touchscreen;
touchScreen.Header.NumEntries = 17;
touchScreen.Header.MaxEntryIndex = 16;
touchScreen.Header.LatestEntry = (touchScreen.Header.LatestEntry + 1) % 17;
touchScreen.Header.TimestampTicks = GetTimestamp();
ulong timestamp = touchScreen.Header.Timestamp + 1;
touchScreen.Header.Timestamp = timestamp;
ref HidTouchScreenEntry entry = ref touchScreen.Entries[(int)touchScreen.Header.LatestEntry];
entry.Header.Timestamp = timestamp;
entry.Header.NumTouches = (ulong)points.Length;
for (int index = 0; index < points.Length; index++)
{
CurrentEntryIndex = (_currentTouchHeader.CurrentEntryIndex + 1) % HidEntryCount,
EntryCount = HidEntryCount,
MaxEntries = HidEntryCount - 1,
SamplesTimestamp = sampleCounter,
Timestamp = timestamp,
};
long currentTouchEntryOffset = _touchEntriesOffset + newTouchHeader.CurrentEntryIndex * HidTouchEntrySize;
TouchEntry touchEntry = new TouchEntry()
{
SamplesTimestamp = sampleCounter,
TouchCount = points.Length
};
_device.Memory.Write((ulong)currentTouchEntryOffset, touchEntry);
currentTouchEntryOffset += HidTouchEntryHeaderSize;
for (int i = 0; i < points.Length; i++)
{
TouchData touch = new TouchData()
entry.Touches[index] = new HidTouchScreenEntryTouch()
{
Angle = points[i].Angle,
DiameterX = points[i].DiameterX,
DiameterY = points[i].DiameterY,
Index = i,
SampleTimestamp = sampleCounter,
X = points[i].X,
Y = points[i].Y
Timestamp = timestamp,
TouchIndex = (uint)index,
X = points[index].X,
Y = points[index].Y,
DiameterX = points[index].DiameterX,
DiameterY = points[index].DiameterY,
Angle = points[index].Angle
};
_device.Memory.Write((ulong)currentTouchEntryOffset, touch);
currentTouchEntryOffset += HidTouchEntryTouchSize;
}
_device.Memory.Write((ulong)_touchScreenOffset, newTouchHeader);
_currentTouchHeader = newTouchHeader;
}
public unsafe void WriteKeyboard(Keyboard keyboard)
{
long timestamp = GetTimestamp();
ref HidSharedMemory sharedMemory = ref SharedMemory;
var newKeyboardHeader = new KeyboardHeader()
{
CurrentEntryIndex = (_currentKeyboardHeader.CurrentEntryIndex + 1) % HidEntryCount,
EntryCount = HidEntryCount,
MaxEntries = HidEntryCount - 1,
Timestamp = timestamp,
};
ref HidKeyboard kbd = ref sharedMemory.Keyboard;
_device.Memory.Write((ulong)_keyboardOffset, newKeyboardHeader);
kbd.Header.NumEntries = 17;
kbd.Header.MaxEntryIndex = 16;
long keyboardEntryOffset = _keyboardOffset + HidKeyboardHeaderSize;
keyboardEntryOffset += newKeyboardHeader.CurrentEntryIndex * HidKeyboardEntrySize;
kbd.Header.LatestEntry = (kbd.Header.LatestEntry + 1) % 17;
var newkeyboardEntry = new KeyboardEntry()
{
SamplesTimestamp = _currentKeyboardEntry.SamplesTimestamp + 1,
SamplesTimestamp2 = _currentKeyboardEntry.SamplesTimestamp2 + 1,
Modifier = keyboard.Modifier,
};
kbd.Header.TimestampTicks = GetTimestamp();
kbd.Entries[(int)kbd.Header.LatestEntry].Timestamp++;
kbd.Entries[(int)kbd.Header.LatestEntry].Timestamp2++;
for (int index = 0; index < keyboard.Keys.Length; index++)
{
newkeyboardEntry.Keys[index] = keyboard.Keys[index];
kbd.Entries[(int)kbd.Header.LatestEntry].Keys[index] = keyboard.Keys[index];
}
_device.Memory.Write((ulong)keyboardEntryOffset, newkeyboardEntry);
_currentKeyboardEntry = newkeyboardEntry;
_currentKeyboardHeader = newKeyboardHeader;
kbd.Entries[(int)kbd.Header.LatestEntry].Modifier = keyboard.Modifier;
}
internal static long GetTimestamp()
internal static ulong GetTimestamp()
{
return PerformanceCounter.ElapsedMilliseconds * 19200;
return (ulong)PerformanceCounter.ElapsedMilliseconds * 19200;
}
}
}

View file

@ -0,0 +1,259 @@
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.Input
{
struct Array2<T> where T : unmanaged { T _e0; T _e1; public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref _e0, 2)[index]; }
struct Array3<T> where T : unmanaged { T _e0; Array2<T> _e1; public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref _e0, 3)[index]; }
struct Array4<T> where T : unmanaged { T _e0; Array3<T> _e1; public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref _e0, 4)[index]; }
struct Array5<T> where T : unmanaged { T _e0; Array4<T> _e1; public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref _e0, 5)[index]; }
struct Array6<T> where T : unmanaged { T _e0; Array5<T> _e1; public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref _e0, 6)[index]; }
struct Array7<T> where T : unmanaged { T _e0; Array6<T> _e1; public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref _e0, 7)[index]; }
struct Array8<T> where T : unmanaged { T _e0; Array7<T> _e1; public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref _e0, 8)[index]; }
struct Array9<T> where T : unmanaged { T _e0; Array8<T> _e1; public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref _e0, 9)[index]; }
struct Array10<T> where T : unmanaged { T _e0; Array9<T> _e1; public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref _e0, 10)[index]; }
struct Array11<T> where T : unmanaged { T _e0; Array10<T> _e1; public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref _e0, 11)[index]; }
struct Array12<T> where T : unmanaged { T _e0; Array11<T> _e1; public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref _e0, 12)[index]; }
struct Array13<T> where T : unmanaged { T _e0; Array12<T> _e1; public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref _e0, 13)[index]; }
struct Array14<T> where T : unmanaged { T _e0; Array13<T> _e1; public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref _e0, 14)[index]; }
struct Array15<T> where T : unmanaged { T _e0; Array14<T> _e1; public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref _e0, 15)[index]; }
struct Array16<T> where T : unmanaged { T _e0; Array15<T> _e1; public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref _e0, 16)[index]; }
struct Array17<T> where T : unmanaged { T _e0; Array16<T> _e1; public ref T this[int index] => ref MemoryMarshal.CreateSpan(ref _e0, 17)[index]; }
struct HidBool
{
private uint _value;
public static implicit operator bool(HidBool value)
{
return (value._value & 1) != 0;
}
public static implicit operator HidBool(bool value)
{
return new HidBool() { _value = value ? 1u : 0u };
}
}
struct MousePosition
{
public int X;
public int Y;
public int VelocityX;
public int VelocityY;
public int ScrollVelocityX;
public int ScrollVelocityY;
}
struct HidVector
{
public float X;
public float Y;
public float Z;
}
struct SixAxisSensorValues
{
public HidVector Accelerometer;
public HidVector Gyroscope;
public HidVector Unk;
public Array3<HidVector> Orientation;
}
struct HidTouchScreenHeader
{
public ulong TimestampTicks;
public ulong NumEntries;
public ulong LatestEntry;
public ulong MaxEntryIndex;
public ulong Timestamp;
}
struct HidTouchScreenEntryHeader
{
public ulong Timestamp;
public ulong NumTouches;
}
struct HidTouchScreenEntryTouch
{
public ulong Timestamp;
public uint Padding;
public uint TouchIndex;
public uint X;
public uint Y;
public uint DiameterX;
public uint DiameterY;
public uint Angle;
public uint Padding2;
}
struct HidTouchScreenEntry
{
public HidTouchScreenEntryHeader Header;
public Array16<HidTouchScreenEntryTouch> Touches;
public ulong Unk;
}
unsafe struct HidTouchScreen
{
public HidTouchScreenHeader Header;
public Array17<HidTouchScreenEntry> Entries;
public fixed byte Padding[0x3c0];
}
struct HidMouseHeader
{
public ulong TimestampTicks;
public ulong NumEntries;
public ulong LatestEntry;
public ulong MaxEntryIndex;
}
struct HidMouseEntry
{
public ulong Timestamp;
public ulong Timestamp_2;
public MousePosition Position;
public ulong Buttons;
}
unsafe struct HidMouse
{
public HidMouseHeader Header;
public Array17<HidMouseEntry> Entries;
public fixed byte Padding[0xB0];
}
struct HidKeyboardHeader
{
public ulong TimestampTicks;
public ulong NumEntries;
public ulong LatestEntry;
public ulong MaxEntryIndex;
}
unsafe struct HidKeyboardEntry
{
public ulong Timestamp;
public ulong Timestamp2;
public ulong Modifier;
public fixed uint Keys[8];
}
unsafe struct HidKeyboard
{
public HidKeyboardHeader Header;
public Array17<HidKeyboardEntry> Entries;
public fixed byte Padding[0x28];
}
unsafe struct HidControllerMAC
{
public ulong Timestamp;
public fixed byte Mac[0x8];
public ulong Unk;
public ulong Timestamp2;
}
struct HidControllerHeader
{
public ControllerStatus Type;
public HidBool IsHalf;
public ControllerColorDescription SingleColorsDescriptor;
public NpadColor SingleColorBody;
public NpadColor SingleColorButtons;
public ControllerColorDescription SplitColorsDescriptor;
public NpadColor LeftColorBody;
public NpadColor LeftColorButtons;
public NpadColor RightColorBody;
public NpadColor RightColorButtons;
}
struct HidControllerLayoutHeader
{
public ulong TimestampTicks;
public ulong NumEntries;
public ulong LatestEntry;
public ulong MaxEntryIndex;
}
struct HidControllerInputEntry
{
public ulong Timestamp;
public ulong Timestamp2;
public ControllerButtons Buttons;
public Array2<JoystickPosition> Joysticks;
public ControllerConnectionState ConnectionState;
}
struct HidControllerLayout
{
public HidControllerLayoutHeader Header;
public Array17<HidControllerInputEntry> Entries;
}
struct HidControllerSixAxisHeader
{
public ulong Timestamp;
public ulong NumEntries;
public ulong LatestEntry;
public ulong MaxEntryIndex;
}
struct HidControllerSixAxisEntry
{
public ulong Timestamp;
public ulong Unk1;
public ulong Timestamp2;
public SixAxisSensorValues Values;
public ulong Unk3;
}
struct HidControllerSixAxisLayout
{
public HidControllerSixAxisHeader Header;
public Array17<HidControllerSixAxisEntry> Entries;
}
unsafe struct HidControllerMisc
{
public ControllerDeviceType DeviceType;
public uint Padding;
public DeviceFlags DeviceFlags;
public uint UnintendedHomeButtonInputProtectionEnabled;
public BatteryState PowerInfo0BatteryState;
public BatteryState PowerInfo1BatteryState;
public BatteryState PowerInfo2BatteryState;
public fixed byte Unk1[0x20];
HidControllerMAC MacLeft;
HidControllerMAC MacRight;
}
unsafe struct HidController
{
public HidControllerHeader Header;
public Array7<HidControllerLayout> Layouts;
public Array6<HidControllerSixAxisLayout> Sixaxis;
public HidControllerMisc Misc;
public fixed byte Unk2[0xDF8];
}
unsafe struct HidSharedMemory
{
public fixed byte Header[0x400];
public HidTouchScreen Touchscreen;
public HidMouse Mouse;
public HidKeyboard Keyboard;
public fixed byte UnkSection1[0x400];
public fixed byte UnkSection2[0x400];
public fixed byte UnkSection3[0x400];
public fixed byte UnkSection4[0x400];
public fixed byte UnkSection5[0x200];
public fixed byte UnkSection6[0x200];
public fixed byte UnkSection7[0x200];
public fixed byte UnkSection8[0x800];
public fixed byte ControllerSerials[0x4000];
public Array10<HidController> Controllers;
public fixed byte UnkSection9[0x4600];
}
}

View file

@ -1,63 +0,0 @@
namespace Ryujinx.HLE.Input
{
public partial class Hid
{
/*
* Reference:
* https://github.com/reswitched/libtransistor/blob/development/lib/hid.c
* https://github.com/reswitched/libtransistor/blob/development/include/libtransistor/hid.h
* https://github.com/switchbrew/libnx/blob/master/nx/source/services/hid.c
* https://github.com/switchbrew/libnx/blob/master/nx/include/switch/services/hid.h
*/
internal const int HidHeaderSize = 0x400;
internal const int HidTouchScreenSize = 0x3000;
internal const int HidMouseSize = 0x400;
internal const int HidKeyboardSize = 0x400;
internal const int HidUnkSection1Size = 0x400;
internal const int HidUnkSection2Size = 0x400;
internal const int HidUnkSection3Size = 0x400;
internal const int HidUnkSection4Size = 0x400;
internal const int HidUnkSection5Size = 0x200;
internal const int HidUnkSection6Size = 0x200;
internal const int HidUnkSection7Size = 0x200;
internal const int HidUnkSection8Size = 0x800;
internal const int HidControllerSerialsSize = 0x4000;
internal const int HidControllersSize = 0x32000;
internal const int HidUnkSection9Size = 0x800;
internal const int HidKeyboardHeaderSize = 0x20;
internal const int HidKeyboardEntrySize = 0x38;
internal const int HidTouchHeaderSize = 0x28;
internal const int HidTouchEntrySize = 0x298;
internal const int HidTouchEntryHeaderSize = 0x10;
internal const int HidTouchEntryTouchSize = 0x28;
internal const int HidControllerSize = 0x5000;
internal const int HidControllerHeaderSize = 0x28;
internal const int HidControllerLayoutsSize = 0x350;
internal const int HidControllersLayoutHeaderSize = 0x20;
internal const int HidControllersInputEntrySize = 0x30;
internal const int HidHeaderOffset = 0;
internal const int HidTouchScreenOffset = HidHeaderOffset + HidHeaderSize;
internal const int HidMouseOffset = HidTouchScreenOffset + HidTouchScreenSize;
internal const int HidKeyboardOffset = HidMouseOffset + HidMouseSize;
internal const int HidUnkSection1Offset = HidKeyboardOffset + HidKeyboardSize;
internal const int HidUnkSection2Offset = HidUnkSection1Offset + HidUnkSection1Size;
internal const int HidUnkSection3Offset = HidUnkSection2Offset + HidUnkSection2Size;
internal const int HidUnkSection4Offset = HidUnkSection3Offset + HidUnkSection3Size;
internal const int HidUnkSection5Offset = HidUnkSection4Offset + HidUnkSection4Size;
internal const int HidUnkSection6Offset = HidUnkSection5Offset + HidUnkSection5Size;
internal const int HidUnkSection7Offset = HidUnkSection6Offset + HidUnkSection6Size;
internal const int HidUnkSection8Offset = HidUnkSection7Offset + HidUnkSection7Size;
internal const int HidControllerSerialsOffset = HidUnkSection8Offset + HidUnkSection8Size;
internal const int HidControllersOffset = HidControllerSerialsOffset + HidControllerSerialsSize;
internal const int HidUnkSection9Offset = HidControllersOffset + HidControllersSize;
internal const int HidEntryCount = 17;
}
}

View file

@ -1,8 +0,0 @@
namespace Ryujinx.HLE.Input
{
interface IHidDevice
{
long Offset { get; }
bool Connected { get; }
}
}

View file

@ -2,7 +2,7 @@ namespace Ryujinx.HLE.Input
{
public struct Keyboard
{
public int Modifier;
public int[] Keys;
public uint Modifier;
public uint[] Keys;
}
}

View file

@ -1,13 +0,0 @@
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.Input
{
[StructLayout(LayoutKind.Sequential)]
public unsafe struct KeyboardEntry
{
public long SamplesTimestamp;
public long SamplesTimestamp2;
public long Modifier;
public fixed int Keys[8];
}
}

View file

@ -1,13 +0,0 @@
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.Input
{
[StructLayout(LayoutKind.Sequential)]
public struct KeyboardHeader
{
public long Timestamp;
public long EntryCount;
public long CurrentEntryIndex;
public long MaxEntries;
}
}

View file

@ -1,18 +0,0 @@
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.Input
{
[StructLayout(LayoutKind.Sequential)]
public struct TouchData
{
public long SampleTimestamp;
public int Padding;
public int Index;
public int X;
public int Y;
public int DiameterX;
public int DiameterY;
public int Angle;
public int Padding2;
}
}

View file

@ -1,14 +0,0 @@
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.Input
{
[StructLayout(LayoutKind.Sequential)]
public struct TouchHeader
{
public long Timestamp;
public long EntryCount;
public long CurrentEntryIndex;
public long MaxEntries;
public long SamplesTimestamp;
}
}

View file

@ -2,10 +2,10 @@ namespace Ryujinx.HLE.Input
{
public struct TouchPoint
{
public int X;
public int Y;
public int DiameterX;
public int DiameterY;
public int Angle;
public uint X;
public uint Y;
public uint DiameterX;
public uint DiameterY;
public uint Angle;
}
}

View file

@ -185,7 +185,7 @@ namespace Ryujinx.Ui
hidKeyboard = new HLE.Input.Keyboard
{
Modifier = 0,
Keys = new int[0x8]
Keys = new uint[0x8]
};
}
@ -214,7 +214,7 @@ namespace Ryujinx.Ui
Dy = rightJoystickDy
};
currentButton |= _device.Hid.UpdateStickButtons(leftJoystick, rightJoystick);
currentButton |= Hid.UpdateStickButtons(leftJoystick, rightJoystick);
bool hasTouch = false;
@ -255,8 +255,8 @@ namespace Ryujinx.Ui
TouchPoint currentPoint = new TouchPoint
{
X = mX,
Y = mY,
X = (uint)mX,
Y = (uint)mY,
// Placeholder values till more data is acquired
DiameterX = 10,

View file

@ -221,21 +221,21 @@ namespace Ryujinx.Ui
HLE.Input.Keyboard hidKeyboard = new HLE.Input.Keyboard
{
Modifier = 0,
Keys = new int[0x8]
Keys = new uint[0x8]
};
foreach (KeyMappingEntry entry in KeyMapping)
{
int value = keyboard[entry.TargetKey] ? 1 : 0;
hidKeyboard.Keys[entry.Target / 0x20] |= (value << (entry.Target % 0x20));
hidKeyboard.Keys[entry.Target / 0x20] |= (uint)value << (entry.Target % 0x20);
}
foreach (KeyMappingEntry entry in KeyModifierMapping)
{
int value = keyboard[entry.TargetKey] ? 1 : 0;
hidKeyboard.Modifier |= value << entry.Target;
hidKeyboard.Modifier |= (uint)value << entry.Target;
}
return hidKeyboard;