BaseController.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. using static Ryujinx.HLE.Input.Hid;
  2. namespace Ryujinx.HLE.Input
  3. {
  4. public abstract class BaseController : IHidDevice
  5. {
  6. protected ControllerStatus HidControllerType;
  7. protected ControllerId ControllerId;
  8. private long _currentLayoutOffset;
  9. private long _mainLayoutOffset;
  10. protected long DeviceStateOffset => Offset + 0x4188;
  11. protected Switch Device { get; }
  12. public long Offset { get; private set; }
  13. public bool Connected { get; protected set; }
  14. public ControllerHeader Header { get; private set; }
  15. public ControllerStateHeader CurrentStateHeader { get; private set; }
  16. public ControllerDeviceState DeviceState { get; private set; }
  17. public ControllerLayouts CurrentLayout { get; private set; }
  18. public ControllerState LastInputState { get; set; }
  19. public ControllerConnectionState ConnectionState { get; protected set; }
  20. public BaseController(Switch device, ControllerStatus controllerType)
  21. {
  22. Device = device;
  23. HidControllerType = controllerType;
  24. }
  25. protected void Initialize(
  26. bool isHalf,
  27. (NpadColor left, NpadColor right) bodyColors,
  28. (NpadColor left, NpadColor right) buttonColors,
  29. ControllerColorDescription singleColorDesc = 0,
  30. ControllerColorDescription splitColorDesc = 0,
  31. NpadColor singleBodyColor = 0,
  32. NpadColor singleButtonColor = 0
  33. )
  34. {
  35. Header = new ControllerHeader()
  36. {
  37. IsJoyConHalf = isHalf ? 1 : 0,
  38. LeftBodyColor = bodyColors.left,
  39. LeftButtonColor = buttonColors.left,
  40. RightBodyColor = bodyColors.right,
  41. RightButtonColor = buttonColors.right,
  42. Status = HidControllerType,
  43. SingleBodyColor = singleBodyColor,
  44. SingleButtonColor = singleButtonColor,
  45. SplitColorDescription = splitColorDesc,
  46. SingleColorDescription = singleColorDesc,
  47. };
  48. CurrentStateHeader = new ControllerStateHeader
  49. {
  50. EntryCount = HidEntryCount,
  51. MaxEntryCount = HidEntryCount - 1,
  52. CurrentEntryIndex = -1
  53. };
  54. DeviceState = new ControllerDeviceState()
  55. {
  56. PowerInfo0BatteryState = BatteryState.Percent100,
  57. PowerInfo1BatteryState = BatteryState.Percent100,
  58. PowerInfo2BatteryState = BatteryState.Percent100,
  59. DeviceType = ControllerDeviceType.NPadLeftController | ControllerDeviceType.NPadRightController,
  60. DeviceFlags = DeviceFlags.PowerInfo0Connected
  61. | DeviceFlags.PowerInfo1Connected
  62. | DeviceFlags.PowerInfo2Connected
  63. };
  64. LastInputState = new ControllerState()
  65. {
  66. SamplesTimestamp = -1,
  67. SamplesTimestamp2 = -1
  68. };
  69. }
  70. public virtual void Connect(ControllerId controllerId)
  71. {
  72. ControllerId = controllerId;
  73. Offset = Device.Hid.HidPosition + HidControllersOffset + (int)controllerId * HidControllerSize;
  74. _mainLayoutOffset = Offset + HidControllerHeaderSize
  75. + ((int)ControllerLayouts.Main * HidControllerLayoutsSize);
  76. Device.Memory.FillWithZeros(Offset, 0x5000);
  77. Device.Memory.WriteStruct(Offset, Header);
  78. Device.Memory.WriteStruct(DeviceStateOffset, DeviceState);
  79. Connected = true;
  80. }
  81. public void SetLayout(ControllerLayouts controllerLayout)
  82. {
  83. CurrentLayout = controllerLayout;
  84. _currentLayoutOffset = Offset + HidControllerHeaderSize
  85. + ((int)controllerLayout * HidControllerLayoutsSize);
  86. }
  87. public void SendInput(
  88. ControllerButtons buttons,
  89. JoystickPosition leftStick,
  90. JoystickPosition rightStick)
  91. {
  92. ControllerState currentInput = new ControllerState()
  93. {
  94. SamplesTimestamp = (long)LastInputState.SamplesTimestamp + 1,
  95. SamplesTimestamp2 = (long)LastInputState.SamplesTimestamp + 1,
  96. ButtonState = buttons,
  97. ConnectionState = ConnectionState,
  98. LeftStick = leftStick,
  99. RightStick = rightStick
  100. };
  101. ControllerStateHeader newInputStateHeader = new ControllerStateHeader
  102. {
  103. EntryCount = HidEntryCount,
  104. MaxEntryCount = HidEntryCount - 1,
  105. CurrentEntryIndex = (CurrentStateHeader.CurrentEntryIndex + 1) % HidEntryCount,
  106. Timestamp = GetTimestamp(),
  107. };
  108. Device.Memory.WriteStruct(_currentLayoutOffset, newInputStateHeader);
  109. Device.Memory.WriteStruct(_mainLayoutOffset, newInputStateHeader);
  110. long currentInputStateOffset = HidControllersLayoutHeaderSize
  111. + newInputStateHeader.CurrentEntryIndex * HidControllersInputEntrySize;
  112. Device.Memory.WriteStruct(_currentLayoutOffset + currentInputStateOffset, currentInput);
  113. Device.Memory.WriteStruct(_mainLayoutOffset + currentInputStateOffset, currentInput);
  114. LastInputState = currentInput;
  115. CurrentStateHeader = newInputStateHeader;
  116. }
  117. }
  118. }