Hid.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. using Ryujinx.OsHle;
  2. using System;
  3. using System.Runtime.InteropServices;
  4. namespace Ryujinx
  5. {
  6. public class Hid
  7. {
  8. /*
  9. Thanks to:
  10. https://github.com/reswitched/libtransistor/blob/development/lib/hid.c
  11. https://github.com/reswitched/libtransistor/blob/development/include/libtransistor/hid.h
  12. https://github.com/switchbrew/libnx/blob/master/nx/source/services/hid.c
  13. https://github.com/switchbrew/libnx/blob/master/nx/include/switch/services/hid.h
  14. struct HidSharedMemory
  15. {
  16. header[0x400];
  17. touchscreen[0x3000];
  18. mouse[0x400];
  19. keyboard[0x400];
  20. unkSection1[0x400];
  21. unkSection2[0x400];
  22. unkSection3[0x400];
  23. unkSection4[0x400];
  24. unkSection5[0x200];
  25. unkSection6[0x200];
  26. unkSection7[0x200];
  27. unkSection8[0x800];
  28. controllerSerials[0x4000];
  29. controllers[0x5000 * 10];
  30. unkSection9[0x4600];
  31. }
  32. */
  33. private const int Hid_Num_Entries = 16;
  34. private Switch Ns;
  35. private long SharedMemOffset;
  36. public Hid(Switch Ns)
  37. {
  38. this.Ns = Ns;
  39. }
  40. public void Init(long HidOffset)
  41. {
  42. unsafe
  43. {
  44. if (HidOffset == 0 || HidOffset + Horizon.HidSize > uint.MaxValue)
  45. {
  46. return;
  47. }
  48. SharedMemOffset = HidOffset;
  49. uint InnerOffset = (uint)Marshal.SizeOf(typeof(HidSharedMemHeader));
  50. IntPtr HidPtr = new IntPtr(Ns.Ram.ToInt64() + (uint)SharedMemOffset + InnerOffset);
  51. HidTouchScreen TouchScreen = new HidTouchScreen();
  52. TouchScreen.Header.TimestampTicks = (ulong)Environment.TickCount;
  53. TouchScreen.Header.NumEntries = (ulong)Hid_Num_Entries;
  54. TouchScreen.Header.LatestEntry = 0;
  55. TouchScreen.Header.MaxEntryIndex = (ulong)Hid_Num_Entries - 1;
  56. TouchScreen.Header.Timestamp = (ulong)Environment.TickCount;
  57. //TODO: Write this structure when the input is implemented
  58. //Marshal.StructureToPtr(TouchScreen, HidPtr, false);
  59. InnerOffset += (uint)Marshal.SizeOf(typeof(HidTouchScreen));
  60. HidPtr = new IntPtr(Ns.Ram.ToInt64() + (uint)SharedMemOffset + InnerOffset);
  61. HidMouse Mouse = new HidMouse();
  62. Mouse.Header.TimestampTicks = (ulong)Environment.TickCount;
  63. Mouse.Header.NumEntries = (ulong)Hid_Num_Entries;
  64. Mouse.Header.LatestEntry = 0;
  65. Mouse.Header.MaxEntryIndex = (ulong)Hid_Num_Entries - 1;
  66. //TODO: Write this structure when the input is implemented
  67. //Marshal.StructureToPtr(Mouse, HidPtr, false);
  68. InnerOffset += (uint)Marshal.SizeOf(typeof(HidMouse));
  69. HidPtr = new IntPtr(Ns.Ram.ToInt64() + (uint)SharedMemOffset + InnerOffset);
  70. HidKeyboard Keyboard = new HidKeyboard();
  71. Keyboard.Header.TimestampTicks = (ulong)Environment.TickCount;
  72. Keyboard.Header.NumEntries = (ulong)Hid_Num_Entries;
  73. Keyboard.Header.LatestEntry = 0;
  74. Keyboard.Header.MaxEntryIndex = (ulong)Hid_Num_Entries - 1;
  75. //TODO: Write this structure when the input is implemented
  76. //Marshal.StructureToPtr(Keyboard, HidPtr, false);
  77. InnerOffset += (uint)Marshal.SizeOf(typeof(HidKeyboard)) +
  78. (uint)Marshal.SizeOf(typeof(HidUnknownSection1)) +
  79. (uint)Marshal.SizeOf(typeof(HidUnknownSection2)) +
  80. (uint)Marshal.SizeOf(typeof(HidUnknownSection3)) +
  81. (uint)Marshal.SizeOf(typeof(HidUnknownSection4)) +
  82. (uint)Marshal.SizeOf(typeof(HidUnknownSection5)) +
  83. (uint)Marshal.SizeOf(typeof(HidUnknownSection6)) +
  84. (uint)Marshal.SizeOf(typeof(HidUnknownSection7)) +
  85. (uint)Marshal.SizeOf(typeof(HidUnknownSection8)) +
  86. (uint)Marshal.SizeOf(typeof(HidControllerSerials));
  87. //Increase the loop to initialize more controller.
  88. for (int i = 8; i < Enum.GetNames(typeof(HidControllerID)).Length - 1; i++)
  89. {
  90. HidPtr = new IntPtr(Ns.Ram.ToInt64() + (uint)SharedMemOffset + InnerOffset + (uint)(Marshal.SizeOf(typeof(HidController)) * i));
  91. HidController Controller = new HidController();
  92. Controller.Header.Type = (uint)(HidControllerType.ControllerType_Handheld | HidControllerType.ControllerType_JoyconPair);
  93. Controller.Header.IsHalf = 0;
  94. Controller.Header.SingleColorsDescriptor = (uint)(HidControllerColorDescription.ColorDesc_ColorsNonexistent);
  95. Controller.Header.SingleColorBody = 0;
  96. Controller.Header.SingleColorButtons = 0;
  97. Controller.Header.SplitColorsDescriptor = 0;
  98. Controller.Header.LeftColorBody = (uint)JoyConColor.Body_Neon_Red;
  99. Controller.Header.LeftColorButtons = (uint)JoyConColor.Buttons_Neon_Red;
  100. Controller.Header.RightColorBody = (uint)JoyConColor.Body_Neon_Blue;
  101. Controller.Header.RightColorButtons = (uint)JoyConColor.Buttons_Neon_Blue;
  102. Controller.Layouts = new HidControllerLayout[Enum.GetNames(typeof(HidControllerLayouts)).Length];
  103. Controller.Layouts[(int)HidControllerLayouts.Main] = new HidControllerLayout();
  104. Controller.Layouts[(int)HidControllerLayouts.Main].Header.LatestEntry = (ulong)Hid_Num_Entries;
  105. Marshal.StructureToPtr(Controller, HidPtr, false);
  106. }
  107. Logging.Info("HID Initialized!");
  108. }
  109. }
  110. public void SendControllerButtons(HidControllerID ControllerId,
  111. HidControllerLayouts Layout,
  112. HidControllerKeys Buttons,
  113. JoystickPosition LeftJoystick,
  114. JoystickPosition RightJoystick)
  115. {
  116. uint InnerOffset = (uint)Marshal.SizeOf(typeof(HidSharedMemHeader)) +
  117. (uint)Marshal.SizeOf(typeof(HidTouchScreen)) +
  118. (uint)Marshal.SizeOf(typeof(HidMouse)) +
  119. (uint)Marshal.SizeOf(typeof(HidKeyboard)) +
  120. (uint)Marshal.SizeOf(typeof(HidUnknownSection1)) +
  121. (uint)Marshal.SizeOf(typeof(HidUnknownSection2)) +
  122. (uint)Marshal.SizeOf(typeof(HidUnknownSection3)) +
  123. (uint)Marshal.SizeOf(typeof(HidUnknownSection4)) +
  124. (uint)Marshal.SizeOf(typeof(HidUnknownSection5)) +
  125. (uint)Marshal.SizeOf(typeof(HidUnknownSection6)) +
  126. (uint)Marshal.SizeOf(typeof(HidUnknownSection7)) +
  127. (uint)Marshal.SizeOf(typeof(HidUnknownSection8)) +
  128. (uint)Marshal.SizeOf(typeof(HidControllerSerials)) +
  129. ((uint)(Marshal.SizeOf(typeof(HidController)) * (int)ControllerId)) +
  130. (uint)Marshal.SizeOf(typeof(HidControllerHeader)) +
  131. (uint)Layout * (uint)Marshal.SizeOf(typeof(HidControllerLayout));
  132. IntPtr HidPtr = new IntPtr(Ns.Ram.ToInt64() + (uint)SharedMemOffset + InnerOffset);
  133. HidControllerLayoutHeader OldControllerHeaderLayout = (HidControllerLayoutHeader)Marshal.PtrToStructure(HidPtr, typeof(HidControllerLayoutHeader));
  134. HidControllerLayoutHeader ControllerLayoutHeader = new HidControllerLayoutHeader
  135. {
  136. TimestampTicks = (ulong)Environment.TickCount,
  137. NumEntries = (ulong)Hid_Num_Entries,
  138. MaxEntryIndex = (ulong)Hid_Num_Entries - 1,
  139. LatestEntry = (OldControllerHeaderLayout.LatestEntry < (ulong)Hid_Num_Entries ? OldControllerHeaderLayout.LatestEntry + 1 : 0)
  140. };
  141. Marshal.StructureToPtr(ControllerLayoutHeader, HidPtr, false);
  142. InnerOffset += (uint)Marshal.SizeOf(typeof(HidControllerLayoutHeader)) + (uint)((uint)(ControllerLayoutHeader.LatestEntry) * Marshal.SizeOf(typeof(HidControllerInputEntry)));
  143. HidPtr = new IntPtr(Ns.Ram.ToInt64() + (uint)SharedMemOffset + InnerOffset);
  144. HidControllerInputEntry ControllerInputEntry = new HidControllerInputEntry();
  145. ControllerInputEntry.Timestamp = (ulong)Environment.TickCount;
  146. ControllerInputEntry.Timestamp_2 = (ulong)Environment.TickCount;
  147. ControllerInputEntry.Buttons = (ulong)Buttons;
  148. ControllerInputEntry.Joysticks = new JoystickPosition[(int)HidControllerJoystick.Joystick_Num_Sticks];
  149. ControllerInputEntry.Joysticks[(int)HidControllerJoystick.Joystick_Left] = LeftJoystick;
  150. ControllerInputEntry.Joysticks[(int)HidControllerJoystick.Joystick_Right] = RightJoystick;
  151. ControllerInputEntry.ConnectionState = (ulong)(HidControllerConnectionState.Controller_State_Connected | HidControllerConnectionState.Controller_State_Wired);
  152. Marshal.StructureToPtr(ControllerInputEntry, HidPtr, false);
  153. }
  154. }
  155. }