hid.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. // Copyright 2015 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #ifndef _MSC_VER
  7. #include <cstddef>
  8. #endif
  9. #include "common/bit_field.h"
  10. #include "common/common_funcs.h"
  11. #include "common/common_types.h"
  12. #include "core/settings.h"
  13. namespace Service {
  14. class Interface;
  15. namespace HID {
  16. /**
  17. * Structure of a Pad controller state.
  18. */
  19. struct PadState {
  20. union {
  21. u32 hex;
  22. BitField<0, 1, u32> a;
  23. BitField<1, 1, u32> b;
  24. BitField<2, 1, u32> select;
  25. BitField<3, 1, u32> start;
  26. BitField<4, 1, u32> right;
  27. BitField<5, 1, u32> left;
  28. BitField<6, 1, u32> up;
  29. BitField<7, 1, u32> down;
  30. BitField<8, 1, u32> r;
  31. BitField<9, 1, u32> l;
  32. BitField<10, 1, u32> x;
  33. BitField<11, 1, u32> y;
  34. BitField<14, 1, u32> zl;
  35. BitField<15, 1, u32> zr;
  36. BitField<24, 1, u32> c_right;
  37. BitField<25, 1, u32> c_left;
  38. BitField<26, 1, u32> c_up;
  39. BitField<27, 1, u32> c_down;
  40. BitField<28, 1, u32> circle_right;
  41. BitField<29, 1, u32> circle_left;
  42. BitField<30, 1, u32> circle_up;
  43. BitField<31, 1, u32> circle_down;
  44. };
  45. };
  46. /**
  47. * Structure of a single entry of Pad state history within HID shared memory
  48. */
  49. struct PadDataEntry {
  50. PadState current_state;
  51. PadState delta_additions;
  52. PadState delta_removals;
  53. s16 circle_pad_x;
  54. s16 circle_pad_y;
  55. };
  56. /**
  57. * Structure of a single entry of touch state history within HID shared memory
  58. */
  59. struct TouchDataEntry {
  60. u16 x; ///< Y-coordinate of a touchpad press on the lower screen
  61. u16 y; ///< X-coordinate of a touchpad press on the lower screen
  62. BitField<0, 7, u32> valid; ///< Set to 1 when this entry contains actual X/Y data, otherwise 0
  63. };
  64. /**
  65. * Structure of a single entry of accelerometer state history within HID shared memory
  66. */
  67. struct AccelerometerDataEntry {
  68. s16 x;
  69. s16 y;
  70. s16 z;
  71. };
  72. /**
  73. * Structure of a single entry of gyroscope state history within HID shared memory
  74. */
  75. struct GyroscopeDataEntry {
  76. s16 x;
  77. s16 y;
  78. s16 z;
  79. };
  80. /**
  81. * Structure of data stored in HID shared memory
  82. */
  83. struct SharedMem {
  84. /// Pad data, this is used for buttons and the circle pad
  85. struct {
  86. s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0
  87. s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks`
  88. u32 index; ///< Index of the last updated pad state entry
  89. INSERT_PADDING_WORDS(0x2);
  90. PadState current_state; ///< Current state of the pad buttons
  91. // TODO(bunnei): Implement `raw_circle_pad_data` field
  92. u32 raw_circle_pad_data; ///< Raw (analog) circle pad data, before being converted
  93. INSERT_PADDING_WORDS(0x1);
  94. std::array<PadDataEntry, 8> entries; ///< Last 8 pad entries
  95. } pad;
  96. /// Touchpad data, this is used for touchpad input
  97. struct {
  98. s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0
  99. s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks`
  100. u32 index; ///< Index of the last updated touch entry
  101. INSERT_PADDING_WORDS(0x1);
  102. // TODO(bunnei): Implement `raw_entry` field
  103. TouchDataEntry raw_entry; ///< Raw (analog) touch data, before being converted
  104. std::array<TouchDataEntry, 8> entries; ///< Last 8 touch entries, in pixel coordinates
  105. } touch;
  106. /// Accelerometer data
  107. struct {
  108. s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0
  109. s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks`
  110. u32 index; ///< Index of the last updated accelerometer entry
  111. INSERT_PADDING_WORDS(0x1);
  112. AccelerometerDataEntry raw_entry;
  113. INSERT_PADDING_BYTES(2);
  114. std::array<AccelerometerDataEntry, 8> entries;
  115. } accelerometer;
  116. /// Gyroscope data
  117. struct {
  118. s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0
  119. s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks`
  120. u32 index; ///< Index of the last updated accelerometer entry
  121. INSERT_PADDING_WORDS(0x1);
  122. GyroscopeDataEntry raw_entry;
  123. INSERT_PADDING_BYTES(2);
  124. std::array<GyroscopeDataEntry, 32> entries;
  125. } gyroscope;
  126. };
  127. /**
  128. * Structure of calibrate params that GetGyroscopeLowCalibrateParam returns
  129. */
  130. struct GyroscopeCalibrateParam {
  131. struct {
  132. // TODO (wwylele): figure out the exact meaning of these params
  133. s16 zero_point;
  134. s16 positive_unit_point;
  135. s16 negative_unit_point;
  136. } x, y, z;
  137. };
  138. // TODO: MSVC does not support using offsetof() on non-static data members even though this
  139. // is technically allowed since C++11. This macro should be enabled once MSVC adds
  140. // support for that.
  141. #ifndef _MSC_VER
  142. #define ASSERT_REG_POSITION(field_name, position) \
  143. static_assert(offsetof(SharedMem, field_name) == position * 4, \
  144. "Field " #field_name " has invalid position")
  145. ASSERT_REG_POSITION(pad.index_reset_ticks, 0x0);
  146. ASSERT_REG_POSITION(touch.index_reset_ticks, 0x2A);
  147. #undef ASSERT_REG_POSITION
  148. #endif // !defined(_MSC_VER)
  149. // Pre-defined PadStates for single button presses
  150. const PadState PAD_NONE = {{0}};
  151. const PadState PAD_A = {{1u << 0}};
  152. const PadState PAD_B = {{1u << 1}};
  153. const PadState PAD_SELECT = {{1u << 2}};
  154. const PadState PAD_START = {{1u << 3}};
  155. const PadState PAD_RIGHT = {{1u << 4}};
  156. const PadState PAD_LEFT = {{1u << 5}};
  157. const PadState PAD_UP = {{1u << 6}};
  158. const PadState PAD_DOWN = {{1u << 7}};
  159. const PadState PAD_R = {{1u << 8}};
  160. const PadState PAD_L = {{1u << 9}};
  161. const PadState PAD_X = {{1u << 10}};
  162. const PadState PAD_Y = {{1u << 11}};
  163. const PadState PAD_ZL = {{1u << 14}};
  164. const PadState PAD_ZR = {{1u << 15}};
  165. const PadState PAD_C_RIGHT = {{1u << 24}};
  166. const PadState PAD_C_LEFT = {{1u << 25}};
  167. const PadState PAD_C_UP = {{1u << 26}};
  168. const PadState PAD_C_DOWN = {{1u << 27}};
  169. const PadState PAD_CIRCLE_RIGHT = {{1u << 28}};
  170. const PadState PAD_CIRCLE_LEFT = {{1u << 29}};
  171. const PadState PAD_CIRCLE_UP = {{1u << 30}};
  172. const PadState PAD_CIRCLE_DOWN = {{1u << 31}};
  173. /**
  174. * HID::GetIPCHandles service function
  175. * Inputs:
  176. * None
  177. * Outputs:
  178. * 1 : Result of function, 0 on success, otherwise error code
  179. * 2 : IPC Command Structure translate-header
  180. * 3 : Handle to HID shared memory
  181. * 4 : Event signaled by HID
  182. * 5 : Event signaled by HID
  183. * 6 : Event signaled by HID
  184. * 7 : Gyroscope event
  185. * 8 : Event signaled by HID
  186. */
  187. void GetIPCHandles(Interface* self);
  188. /**
  189. * HID::EnableAccelerometer service function
  190. * Inputs:
  191. * None
  192. * Outputs:
  193. * 1 : Result of function, 0 on success, otherwise error code
  194. */
  195. void EnableAccelerometer(Interface* self);
  196. /**
  197. * HID::DisableAccelerometer service function
  198. * Inputs:
  199. * None
  200. * Outputs:
  201. * 1 : Result of function, 0 on success, otherwise error code
  202. */
  203. void DisableAccelerometer(Interface* self);
  204. /**
  205. * HID::EnableGyroscopeLow service function
  206. * Inputs:
  207. * None
  208. * Outputs:
  209. * 1 : Result of function, 0 on success, otherwise error code
  210. */
  211. void EnableGyroscopeLow(Interface* self);
  212. /**
  213. * HID::DisableGyroscopeLow service function
  214. * Inputs:
  215. * None
  216. * Outputs:
  217. * 1 : Result of function, 0 on success, otherwise error code
  218. */
  219. void DisableGyroscopeLow(Interface* self);
  220. /**
  221. * HID::GetSoundVolume service function
  222. * Inputs:
  223. * None
  224. * Outputs:
  225. * 1 : Result of function, 0 on success, otherwise error code
  226. * 2 : u8 output value
  227. */
  228. void GetSoundVolume(Interface* self);
  229. /**
  230. * HID::GetGyroscopeLowRawToDpsCoefficient service function
  231. * Inputs:
  232. * None
  233. * Outputs:
  234. * 1 : Result of function, 0 on success, otherwise error code
  235. * 2 : float output value
  236. */
  237. void GetGyroscopeLowRawToDpsCoefficient(Service::Interface* self);
  238. /**
  239. * HID::GetGyroscopeLowCalibrateParam service function
  240. * Inputs:
  241. * None
  242. * Outputs:
  243. * 1 : Result of function, 0 on success, otherwise error code
  244. * 2~6 (18 bytes) : struct GyroscopeCalibrateParam
  245. */
  246. void GetGyroscopeLowCalibrateParam(Service::Interface* self);
  247. /// Initialize HID service
  248. void Init();
  249. /// Shutdown HID service
  250. void Shutdown();
  251. }
  252. }