Use a struct for HID shared memory (based on libnx struct)
This commit is contained in:
parent
f9847590d9
commit
77293d77ce
22 changed files with 410 additions and 424 deletions
|
@ -113,7 +113,7 @@ namespace Ryujinx.HLE.HOS
|
||||||
|
|
||||||
public int GlobalAccessLogMode { get; set; }
|
public int GlobalAccessLogMode { get; set; }
|
||||||
|
|
||||||
internal long HidBaseAddress { get; private set; }
|
internal ulong HidBaseAddress { get; private set; }
|
||||||
|
|
||||||
internal FileSystemServer FsServer { get; private set; }
|
internal FileSystemServer FsServer { get; private set; }
|
||||||
internal EmulatedGameCard GameCard { get; private set; }
|
internal EmulatedGameCard GameCard { get; private set; }
|
||||||
|
@ -172,7 +172,7 @@ namespace Ryujinx.HLE.HOS
|
||||||
ulong iirsPa = region.Address + HidSize + FontSize;
|
ulong iirsPa = region.Address + HidSize + FontSize;
|
||||||
ulong timePa = region.Address + HidSize + FontSize + IirsSize;
|
ulong timePa = region.Address + HidSize + FontSize + IirsSize;
|
||||||
|
|
||||||
HidBaseAddress = (long)(hidPa - DramMemoryMap.DramBase);
|
HidBaseAddress = hidPa - DramMemoryMap.DramBase;
|
||||||
|
|
||||||
KPageList hidPageList = new KPageList();
|
KPageList hidPageList = new KPageList();
|
||||||
KPageList fontPageList = new KPageList();
|
KPageList fontPageList = new KPageList();
|
||||||
|
|
|
@ -2,141 +2,100 @@
|
||||||
|
|
||||||
namespace Ryujinx.HLE.Input
|
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; }
|
protected Switch Device { get; }
|
||||||
|
|
||||||
public long Offset { get; private set; }
|
protected ControllerStatus ControllerType;
|
||||||
public bool Connected { get; protected set; }
|
|
||||||
|
|
||||||
public ControllerHeader Header { get; private set; }
|
private ControllerId _controllerId;
|
||||||
public ControllerStateHeader CurrentStateHeader { get; private set; }
|
private ControllerLayouts _currentLayout;
|
||||||
public ControllerDeviceState DeviceState { get; private set; }
|
|
||||||
public ControllerLayouts CurrentLayout { get; private set; }
|
private HidControllerHeader _header;
|
||||||
public ControllerState LastInputState { get; set; }
|
private HidControllerMisc _misc;
|
||||||
public ControllerConnectionState ConnectionState { get; protected set; }
|
|
||||||
|
protected ControllerConnectionState ConnectionState;
|
||||||
|
|
||||||
public BaseController(Switch device, ControllerStatus controllerType)
|
public BaseController(Switch device, ControllerStatus controllerType)
|
||||||
{
|
{
|
||||||
Device = device;
|
Device = device;
|
||||||
HidControllerType = controllerType;
|
ControllerType = controllerType;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Initialize(
|
protected void Initialize(
|
||||||
bool isHalf,
|
bool isHalf,
|
||||||
(NpadColor left, NpadColor right) bodyColors,
|
(NpadColor Left, NpadColor Right) bodyColors,
|
||||||
(NpadColor left, NpadColor right) buttonColors,
|
(NpadColor Left, NpadColor Right) buttonColors,
|
||||||
ControllerColorDescription singleColorDesc = 0,
|
ControllerColorDescription singleColorDesc = 0,
|
||||||
ControllerColorDescription splitColorDesc = 0,
|
ControllerColorDescription splitColorDesc = 0,
|
||||||
NpadColor singleBodyColor = 0,
|
NpadColor singleBodyColor = 0,
|
||||||
NpadColor singleButtonColor = 0
|
NpadColor singleButtonColor = 0)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Header = new ControllerHeader()
|
_header = new HidControllerHeader()
|
||||||
{
|
{
|
||||||
IsJoyConHalf = isHalf ? 1 : 0,
|
Type = ControllerType,
|
||||||
LeftBodyColor = bodyColors.left,
|
IsHalf = isHalf,
|
||||||
LeftButtonColor = buttonColors.left,
|
LeftColorBody = bodyColors.Left,
|
||||||
RightBodyColor = bodyColors.right,
|
LeftColorButtons = buttonColors.Left,
|
||||||
RightButtonColor = buttonColors.right,
|
RightColorBody = bodyColors.Right,
|
||||||
Status = HidControllerType,
|
RightColorButtons = buttonColors.Right,
|
||||||
SingleBodyColor = singleBodyColor,
|
SingleColorBody = singleBodyColor,
|
||||||
SingleButtonColor = singleButtonColor,
|
SingleColorButtons = singleButtonColor,
|
||||||
SplitColorDescription = splitColorDesc,
|
SplitColorsDescriptor = splitColorDesc,
|
||||||
SingleColorDescription = singleColorDesc,
|
SingleColorsDescriptor = singleColorDesc
|
||||||
};
|
};
|
||||||
|
|
||||||
CurrentStateHeader = new ControllerStateHeader
|
_misc = new HidControllerMisc()
|
||||||
{
|
|
||||||
EntryCount = HidEntryCount,
|
|
||||||
MaxEntryCount = HidEntryCount - 1,
|
|
||||||
CurrentEntryIndex = -1
|
|
||||||
};
|
|
||||||
|
|
||||||
DeviceState = new ControllerDeviceState()
|
|
||||||
{
|
{
|
||||||
PowerInfo0BatteryState = BatteryState.Percent100,
|
PowerInfo0BatteryState = BatteryState.Percent100,
|
||||||
PowerInfo1BatteryState = BatteryState.Percent100,
|
PowerInfo1BatteryState = BatteryState.Percent100,
|
||||||
PowerInfo2BatteryState = BatteryState.Percent100,
|
PowerInfo2BatteryState = BatteryState.Percent100,
|
||||||
DeviceType = ControllerDeviceType.NPadLeftController | ControllerDeviceType.NPadRightController,
|
DeviceType = ControllerDeviceType.NPadLeftController | ControllerDeviceType.NPadRightController,
|
||||||
DeviceFlags = DeviceFlags.PowerInfo0Connected
|
DeviceFlags = DeviceFlags.PowerInfo0Connected |
|
||||||
| DeviceFlags.PowerInfo1Connected
|
DeviceFlags.PowerInfo1Connected |
|
||||||
| DeviceFlags.PowerInfo2Connected
|
DeviceFlags.PowerInfo2Connected
|
||||||
};
|
|
||||||
|
|
||||||
LastInputState = new ControllerState()
|
|
||||||
{
|
|
||||||
SamplesTimestamp = -1,
|
|
||||||
SamplesTimestamp2 = -1
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Connect(ControllerId controllerId)
|
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
|
ref HidController controller = ref sharedMemory.Controllers[(int)controllerId];
|
||||||
+ ((int)ControllerLayouts.Main * HidControllerLayoutsSize);
|
|
||||||
|
|
||||||
Device.Memory.ZeroFill((ulong)Offset, 0x5000);
|
controller.Header = _header;
|
||||||
Device.Memory.Write((ulong)Offset, Header);
|
controller.Misc = _misc;
|
||||||
Device.Memory.Write((ulong)DeviceStateOffset, DeviceState);
|
|
||||||
|
|
||||||
Connected = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetLayout(ControllerLayouts controllerLayout)
|
public void SetLayout(ControllerLayouts controllerLayout)
|
||||||
{
|
{
|
||||||
CurrentLayout = controllerLayout;
|
_currentLayout = controllerLayout;
|
||||||
|
|
||||||
_currentLayoutOffset = Offset + HidControllerHeaderSize
|
|
||||||
+ ((int)controllerLayout * HidControllerLayoutsSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendInput(
|
public void SendInput(ControllerButtons buttons, JoystickPosition leftStick, JoystickPosition rightStick)
|
||||||
ControllerButtons buttons,
|
|
||||||
JoystickPosition leftStick,
|
|
||||||
JoystickPosition rightStick)
|
|
||||||
{
|
{
|
||||||
ControllerState currentInput = new ControllerState()
|
ref HidSharedMemory sharedMemory = ref Device.Hid.SharedMemory;
|
||||||
{
|
|
||||||
SamplesTimestamp = (long)LastInputState.SamplesTimestamp + 1,
|
|
||||||
SamplesTimestamp2 = (long)LastInputState.SamplesTimestamp + 1,
|
|
||||||
ButtonState = buttons,
|
|
||||||
ConnectionState = ConnectionState,
|
|
||||||
LeftStick = leftStick,
|
|
||||||
RightStick = rightStick
|
|
||||||
};
|
|
||||||
|
|
||||||
ControllerStateHeader newInputStateHeader = new ControllerStateHeader
|
ref HidControllerLayout layout = ref sharedMemory.Controllers[(int)_controllerId].Layouts[(int)_currentLayout];
|
||||||
{
|
|
||||||
EntryCount = HidEntryCount,
|
|
||||||
MaxEntryCount = HidEntryCount - 1,
|
|
||||||
CurrentEntryIndex = (CurrentStateHeader.CurrentEntryIndex + 1) % HidEntryCount,
|
|
||||||
Timestamp = GetTimestamp(),
|
|
||||||
};
|
|
||||||
|
|
||||||
Device.Memory.Write((ulong)_currentLayoutOffset, newInputStateHeader);
|
layout.Header.NumEntries = 17;
|
||||||
Device.Memory.Write((ulong)_mainLayoutOffset, newInputStateHeader);
|
layout.Header.MaxEntryIndex = 16;
|
||||||
|
|
||||||
long currentInputStateOffset = HidControllersLayoutHeaderSize
|
layout.Header.LatestEntry = (layout.Header.LatestEntry + 1) % 17;
|
||||||
+ newInputStateHeader.CurrentEntryIndex * HidControllersInputEntrySize;
|
|
||||||
|
|
||||||
Device.Memory.Write((ulong)(_currentLayoutOffset + currentInputStateOffset), currentInput);
|
layout.Header.TimestampTicks = GetTimestamp();
|
||||||
Device.Memory.Write((ulong)(_mainLayoutOffset + currentInputStateOffset), currentInput);
|
|
||||||
|
|
||||||
LastInputState = currentInput;
|
ref HidControllerInputEntry entry = ref layout.Entries[(int)layout.Header.LatestEntry];
|
||||||
CurrentStateHeader = newInputStateHeader;
|
|
||||||
|
entry.Timestamp++;
|
||||||
|
entry.Timestamp2++;
|
||||||
|
|
||||||
|
entry.Buttons = buttons;
|
||||||
|
entry.ConnectionState = ConnectionState;
|
||||||
|
entry.Joysticks[0] = leftStick;
|
||||||
|
entry.Joysticks[1] = rightStick;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
public override void Connect(ControllerId controllerId)
|
public override void Connect(ControllerId controllerId)
|
||||||
{
|
{
|
||||||
if (HidControllerType != ControllerStatus.NpadLeft && HidControllerType != ControllerStatus.NpadRight)
|
if (ControllerType != ControllerStatus.NpadLeft && ControllerType != ControllerStatus.NpadRight)
|
||||||
{
|
{
|
||||||
_isHalf = false;
|
_isHalf = false;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,9 @@
|
||||||
ConnectionState = ControllerConnectionState.ControllerStateConnected;
|
ConnectionState = ControllerConnectionState.ControllerStateConnected;
|
||||||
|
|
||||||
if (controllerId == ControllerId.ControllerHandheld)
|
if (controllerId == ControllerId.ControllerHandheld)
|
||||||
|
{
|
||||||
ConnectionState |= ControllerConnectionState.ControllerStateWired;
|
ConnectionState |= ControllerConnectionState.ControllerStateWired;
|
||||||
|
}
|
||||||
|
|
||||||
ControllerColorDescription singleColorDesc =
|
ControllerColorDescription singleColorDesc =
|
||||||
ControllerColorDescription.ColorDescriptionColorsNonexistent;
|
ControllerColorDescription.ColorDescriptionColorsNonexistent;
|
||||||
|
@ -37,7 +39,8 @@
|
||||||
NpadColor singleBodyColor = NpadColor.Black;
|
NpadColor singleBodyColor = NpadColor.Black;
|
||||||
NpadColor singleButtonColor = NpadColor.Black;
|
NpadColor singleButtonColor = NpadColor.Black;
|
||||||
|
|
||||||
Initialize(_isHalf,
|
Initialize(
|
||||||
|
_isHalf,
|
||||||
(_npadBodyColors.Left, _npadBodyColors.Right),
|
(_npadBodyColors.Left, _npadBodyColors.Right),
|
||||||
(_npadButtonColors.Left, _npadButtonColors.Right),
|
(_npadButtonColors.Left, _npadButtonColors.Right),
|
||||||
singleColorDesc,
|
singleColorDesc,
|
||||||
|
@ -47,22 +50,22 @@
|
||||||
|
|
||||||
base.Connect(controllerId);
|
base.Connect(controllerId);
|
||||||
|
|
||||||
var _currentLayout = ControllerLayouts.HandheldJoined;
|
var currentLayout = ControllerLayouts.HandheldJoined;
|
||||||
|
|
||||||
switch (HidControllerType)
|
switch (ControllerType)
|
||||||
{
|
{
|
||||||
case ControllerStatus.NpadLeft:
|
case ControllerStatus.NpadLeft:
|
||||||
_currentLayout = ControllerLayouts.Left;
|
currentLayout = ControllerLayouts.Left;
|
||||||
break;
|
break;
|
||||||
case ControllerStatus.NpadRight:
|
case ControllerStatus.NpadRight:
|
||||||
_currentLayout = ControllerLayouts.Right;
|
currentLayout = ControllerLayouts.Right;
|
||||||
break;
|
break;
|
||||||
case ControllerStatus.NpadPair:
|
case ControllerStatus.NpadPair:
|
||||||
_currentLayout = ControllerLayouts.Joined;
|
currentLayout = ControllerLayouts.Joined;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetLayout(_currentLayout);
|
SetLayout(currentLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,17 +2,11 @@
|
||||||
{
|
{
|
||||||
public class ProController : BaseController
|
public class ProController : BaseController
|
||||||
{
|
{
|
||||||
private bool _wired = false;
|
private readonly NpadColor _bodyColor;
|
||||||
|
private readonly NpadColor _buttonColor;
|
||||||
|
|
||||||
private NpadColor _bodyColor;
|
public ProController(Switch device, NpadColor bodyColor, NpadColor buttonColor) : base(device, ControllerStatus.ProController)
|
||||||
private NpadColor _buttonColor;
|
|
||||||
|
|
||||||
public ProController(Switch device,
|
|
||||||
NpadColor bodyColor,
|
|
||||||
NpadColor buttonColor) : base(device, ControllerStatus.ProController)
|
|
||||||
{
|
{
|
||||||
_wired = true;
|
|
||||||
|
|
||||||
_bodyColor = bodyColor;
|
_bodyColor = bodyColor;
|
||||||
_buttonColor = buttonColor;
|
_buttonColor = buttonColor;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +20,8 @@
|
||||||
|
|
||||||
ConnectionState = ControllerConnectionState.ControllerStateConnected | ControllerConnectionState.ControllerStateWired;
|
ConnectionState = ControllerConnectionState.ControllerStateConnected | ControllerConnectionState.ControllerStateWired;
|
||||||
|
|
||||||
Initialize(false,
|
Initialize(
|
||||||
|
false,
|
||||||
(0, 0),
|
(0, 0),
|
||||||
(0, 0),
|
(0, 0),
|
||||||
singleColorDesc,
|
singleColorDesc,
|
||||||
|
|
|
@ -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];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,6 +7,6 @@ namespace Ryujinx.HLE.Input
|
||||||
{
|
{
|
||||||
ProController = 1 << 0,
|
ProController = 1 << 0,
|
||||||
NPadLeftController = 1 << 4,
|
NPadLeftController = 1 << 4,
|
||||||
NPadRightController = 1 << 5,
|
NPadRightController = 1 << 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
namespace Ryujinx.HLE.Input
|
namespace Ryujinx.HLE.Input
|
||||||
{
|
{
|
||||||
public enum NpadColor : int //Thanks to CTCaer
|
public enum NpadColor : int
|
||||||
{
|
{
|
||||||
Black = 0,
|
Black = 0,
|
||||||
|
|
||||||
|
|
|
@ -7,59 +7,33 @@ namespace Ryujinx.HLE.Input
|
||||||
{
|
{
|
||||||
public partial class Hid
|
public partial class Hid
|
||||||
{
|
{
|
||||||
private Switch _device;
|
private readonly Switch _device;
|
||||||
|
|
||||||
private long _touchScreenOffset;
|
private ulong _sharedMemoryAddress;
|
||||||
private long _touchEntriesOffset;
|
|
||||||
private long _keyboardOffset;
|
|
||||||
|
|
||||||
private TouchHeader _currentTouchHeader;
|
internal ref HidSharedMemory SharedMemory => ref _device.Memory.GetRef<HidSharedMemory>(_sharedMemoryAddress);
|
||||||
private KeyboardHeader _currentKeyboardHeader;
|
|
||||||
private KeyboardEntry _currentKeyboardEntry;
|
|
||||||
|
|
||||||
public BaseController PrimaryController { get; private set; }
|
public BaseController PrimaryController { get; private set; }
|
||||||
|
|
||||||
internal long HidPosition;
|
public Hid(Switch device, ulong sharedMemoryAddress)
|
||||||
|
|
||||||
public Hid(Switch device, long hidPosition)
|
|
||||||
{
|
{
|
||||||
_device = device;
|
_device = device;
|
||||||
HidPosition = hidPosition;
|
_sharedMemoryAddress = sharedMemoryAddress;
|
||||||
|
|
||||||
device.Memory.ZeroFill((ulong)hidPosition, Horizon.HidSize);
|
device.Memory.ZeroFill(sharedMemoryAddress, 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ControllerStatus ConvertControllerTypeToState(ControllerType controllerType)
|
private static ControllerStatus ConvertControllerTypeToState(ControllerType controllerType)
|
||||||
{
|
{
|
||||||
switch (controllerType)
|
return controllerType switch
|
||||||
{
|
{
|
||||||
case ControllerType.Handheld: return ControllerStatus.Handheld;
|
ControllerType.Handheld => ControllerStatus.Handheld,
|
||||||
case ControllerType.NpadLeft: return ControllerStatus.NpadLeft;
|
ControllerType.NpadLeft => ControllerStatus.NpadLeft,
|
||||||
case ControllerType.NpadRight: return ControllerStatus.NpadRight;
|
ControllerType.NpadRight => ControllerStatus.NpadRight,
|
||||||
case ControllerType.NpadPair: return ControllerStatus.NpadPair;
|
ControllerType.NpadPair => ControllerStatus.NpadPair,
|
||||||
case ControllerType.ProController: return ControllerStatus.ProController;
|
ControllerType.ProController => ControllerStatus.ProController,
|
||||||
default: throw new NotImplementedException();
|
_ => throw new NotImplementedException(),
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitializePrimaryController(ControllerType controllerType)
|
public void InitializePrimaryController(ControllerType controllerType)
|
||||||
|
@ -73,7 +47,8 @@ namespace Ryujinx.HLE.Input
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PrimaryController = new NpadController(ConvertControllerTypeToState(controllerType),
|
PrimaryController = new NpadController(
|
||||||
|
ConvertControllerTypeToState(controllerType),
|
||||||
_device,
|
_device,
|
||||||
(NpadColor.BodyNeonRed, NpadColor.BodyNeonRed),
|
(NpadColor.BodyNeonRed, NpadColor.BodyNeonRed),
|
||||||
(NpadColor.ButtonsNeonBlue, NpadColor.ButtonsNeonBlue));
|
(NpadColor.ButtonsNeonBlue, NpadColor.ButtonsNeonBlue));
|
||||||
|
@ -82,9 +57,7 @@ namespace Ryujinx.HLE.Input
|
||||||
PrimaryController.Connect(controllerId);
|
PrimaryController.Connect(controllerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ControllerButtons UpdateStickButtons(
|
public static ControllerButtons UpdateStickButtons(JoystickPosition leftStick, JoystickPosition rightStick)
|
||||||
JoystickPosition leftStick,
|
|
||||||
JoystickPosition rightStick)
|
|
||||||
{
|
{
|
||||||
ControllerButtons result = 0;
|
ControllerButtons result = 0;
|
||||||
|
|
||||||
|
@ -130,93 +103,71 @@ namespace Ryujinx.HLE.Input
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetTouchPoints(params TouchPoint[] points)
|
public void SetTouchPoints(params TouchPoint[] points)
|
||||||
{
|
{
|
||||||
long timestamp = GetTimestamp();
|
ref HidSharedMemory sharedMemory = ref SharedMemory;
|
||||||
long sampleCounter = _currentTouchHeader.SamplesTimestamp + 1;
|
|
||||||
|
|
||||||
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++)
|
||||||
|
{
|
||||||
|
entry.Touches[index] = new HidTouchScreenEntryTouch()
|
||||||
{
|
{
|
||||||
CurrentEntryIndex = (_currentTouchHeader.CurrentEntryIndex + 1) % HidEntryCount,
|
|
||||||
EntryCount = HidEntryCount,
|
|
||||||
MaxEntries = HidEntryCount - 1,
|
|
||||||
SamplesTimestamp = sampleCounter,
|
|
||||||
Timestamp = timestamp,
|
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
|
||||||
};
|
};
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
Angle = points[i].Angle,
|
|
||||||
DiameterX = points[i].DiameterX,
|
|
||||||
DiameterY = points[i].DiameterY,
|
|
||||||
Index = i,
|
|
||||||
SampleTimestamp = sampleCounter,
|
|
||||||
X = points[i].X,
|
|
||||||
Y = points[i].Y
|
|
||||||
};
|
|
||||||
|
|
||||||
_device.Memory.Write((ulong)currentTouchEntryOffset, touch);
|
|
||||||
|
|
||||||
currentTouchEntryOffset += HidTouchEntryTouchSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_device.Memory.Write((ulong)_touchScreenOffset, newTouchHeader);
|
|
||||||
|
|
||||||
_currentTouchHeader = newTouchHeader;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void WriteKeyboard(Keyboard keyboard)
|
public unsafe void WriteKeyboard(Keyboard keyboard)
|
||||||
{
|
{
|
||||||
long timestamp = GetTimestamp();
|
ref HidSharedMemory sharedMemory = ref SharedMemory;
|
||||||
|
|
||||||
var newKeyboardHeader = new KeyboardHeader()
|
ref HidKeyboard kbd = ref sharedMemory.Keyboard;
|
||||||
{
|
|
||||||
CurrentEntryIndex = (_currentKeyboardHeader.CurrentEntryIndex + 1) % HidEntryCount,
|
|
||||||
EntryCount = HidEntryCount,
|
|
||||||
MaxEntries = HidEntryCount - 1,
|
|
||||||
Timestamp = timestamp,
|
|
||||||
};
|
|
||||||
|
|
||||||
_device.Memory.Write((ulong)_keyboardOffset, newKeyboardHeader);
|
kbd.Header.NumEntries = 17;
|
||||||
|
kbd.Header.MaxEntryIndex = 16;
|
||||||
|
|
||||||
long keyboardEntryOffset = _keyboardOffset + HidKeyboardHeaderSize;
|
kbd.Header.LatestEntry = (kbd.Header.LatestEntry + 1) % 17;
|
||||||
keyboardEntryOffset += newKeyboardHeader.CurrentEntryIndex * HidKeyboardEntrySize;
|
|
||||||
|
|
||||||
var newkeyboardEntry = new KeyboardEntry()
|
kbd.Header.TimestampTicks = GetTimestamp();
|
||||||
{
|
|
||||||
SamplesTimestamp = _currentKeyboardEntry.SamplesTimestamp + 1,
|
kbd.Entries[(int)kbd.Header.LatestEntry].Timestamp++;
|
||||||
SamplesTimestamp2 = _currentKeyboardEntry.SamplesTimestamp2 + 1,
|
kbd.Entries[(int)kbd.Header.LatestEntry].Timestamp2++;
|
||||||
Modifier = keyboard.Modifier,
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int index = 0; index < keyboard.Keys.Length; index++)
|
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);
|
kbd.Entries[(int)kbd.Header.LatestEntry].Modifier = keyboard.Modifier;
|
||||||
|
|
||||||
_currentKeyboardEntry = newkeyboardEntry;
|
|
||||||
_currentKeyboardHeader = newKeyboardHeader;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static long GetTimestamp()
|
internal static ulong GetTimestamp()
|
||||||
{
|
{
|
||||||
return PerformanceCounter.ElapsedMilliseconds * 19200;
|
return (ulong)PerformanceCounter.ElapsedMilliseconds * 19200;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
259
Ryujinx.HLE/Input/HidSharedMemory.cs
Normal file
259
Ryujinx.HLE/Input/HidSharedMemory.cs
Normal 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];
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
namespace Ryujinx.HLE.Input
|
|
||||||
{
|
|
||||||
interface IHidDevice
|
|
||||||
{
|
|
||||||
long Offset { get; }
|
|
||||||
bool Connected { get; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,7 +2,7 @@ namespace Ryujinx.HLE.Input
|
||||||
{
|
{
|
||||||
public struct Keyboard
|
public struct Keyboard
|
||||||
{
|
{
|
||||||
public int Modifier;
|
public uint Modifier;
|
||||||
public int[] Keys;
|
public uint[] Keys;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,10 +2,10 @@ namespace Ryujinx.HLE.Input
|
||||||
{
|
{
|
||||||
public struct TouchPoint
|
public struct TouchPoint
|
||||||
{
|
{
|
||||||
public int X;
|
public uint X;
|
||||||
public int Y;
|
public uint Y;
|
||||||
public int DiameterX;
|
public uint DiameterX;
|
||||||
public int DiameterY;
|
public uint DiameterY;
|
||||||
public int Angle;
|
public uint Angle;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -185,7 +185,7 @@ namespace Ryujinx.Ui
|
||||||
hidKeyboard = new HLE.Input.Keyboard
|
hidKeyboard = new HLE.Input.Keyboard
|
||||||
{
|
{
|
||||||
Modifier = 0,
|
Modifier = 0,
|
||||||
Keys = new int[0x8]
|
Keys = new uint[0x8]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ namespace Ryujinx.Ui
|
||||||
Dy = rightJoystickDy
|
Dy = rightJoystickDy
|
||||||
};
|
};
|
||||||
|
|
||||||
currentButton |= _device.Hid.UpdateStickButtons(leftJoystick, rightJoystick);
|
currentButton |= Hid.UpdateStickButtons(leftJoystick, rightJoystick);
|
||||||
|
|
||||||
bool hasTouch = false;
|
bool hasTouch = false;
|
||||||
|
|
||||||
|
@ -255,8 +255,8 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
TouchPoint currentPoint = new TouchPoint
|
TouchPoint currentPoint = new TouchPoint
|
||||||
{
|
{
|
||||||
X = mX,
|
X = (uint)mX,
|
||||||
Y = mY,
|
Y = (uint)mY,
|
||||||
|
|
||||||
// Placeholder values till more data is acquired
|
// Placeholder values till more data is acquired
|
||||||
DiameterX = 10,
|
DiameterX = 10,
|
||||||
|
|
|
@ -221,21 +221,21 @@ namespace Ryujinx.Ui
|
||||||
HLE.Input.Keyboard hidKeyboard = new HLE.Input.Keyboard
|
HLE.Input.Keyboard hidKeyboard = new HLE.Input.Keyboard
|
||||||
{
|
{
|
||||||
Modifier = 0,
|
Modifier = 0,
|
||||||
Keys = new int[0x8]
|
Keys = new uint[0x8]
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (KeyMappingEntry entry in KeyMapping)
|
foreach (KeyMappingEntry entry in KeyMapping)
|
||||||
{
|
{
|
||||||
int value = keyboard[entry.TargetKey] ? 1 : 0;
|
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)
|
foreach (KeyMappingEntry entry in KeyModifierMapping)
|
||||||
{
|
{
|
||||||
int value = keyboard[entry.TargetKey] ? 1 : 0;
|
int value = keyboard[entry.TargetKey] ? 1 : 0;
|
||||||
|
|
||||||
hidKeyboard.Modifier |= value << entry.Target;
|
hidKeyboard.Modifier |= (uint)value << entry.Target;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hidKeyboard;
|
return hidKeyboard;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue