npad.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include "common/common_types.h"
  7. #include "core/frontend/input.h"
  8. #include "core/hle/service/hid/controllers/controller_base.h"
  9. #include "core/settings.h"
  10. namespace Service::HID {
  11. class Controller_NPad final : public ControllerBase {
  12. public:
  13. Controller_NPad();
  14. ~Controller_NPad() override;
  15. // Called when the controller is initialized
  16. void OnInit() override;
  17. // When the controller is released
  18. void OnRelease() override;
  19. // When the controller is requesting an update for the shared memory
  20. void OnUpdate(u8* data, std::size_t size) override;
  21. // Called when input devices should be loaded
  22. void OnLoadInputDevices() override;
  23. struct NPadType {
  24. union {
  25. u32_le raw{};
  26. BitField<0, 1, u32_le> pro_controller;
  27. BitField<1, 1, u32_le> handheld;
  28. BitField<2, 1, u32_le> joycon_dual;
  29. BitField<3, 1, u32_le> joycon_left;
  30. BitField<4, 1, u32_le> joycon_right;
  31. BitField<6, 1, u32_le> pokeball; // TODO(ogniK): Confirm when possible
  32. };
  33. };
  34. static_assert(sizeof(NPadType) == 4, "NPadType is an invalid size");
  35. struct Vibration {
  36. f32 amp_low;
  37. f32 freq_low;
  38. f32 amp_high;
  39. f32 freq_high;
  40. };
  41. static_assert(sizeof(Vibration) == 0x10, "Vibration is an invalid size");
  42. enum class NpadHoldType : u64 {
  43. Vertical = 0,
  44. Horizontal = 1,
  45. };
  46. enum class NPadAssignments : u32_le {
  47. Dual = 0,
  48. Single = 1,
  49. };
  50. enum class NPadControllerType {
  51. None,
  52. ProController,
  53. Handheld,
  54. JoyDual,
  55. JoyLeft,
  56. JoyRight,
  57. Pokeball,
  58. };
  59. struct LedPattern {
  60. explicit LedPattern(u64 light1, u64 light2, u64 light3, u64 light4) {
  61. position1.Assign(light1);
  62. position1.Assign(light2);
  63. position1.Assign(light3);
  64. position1.Assign(light4);
  65. }
  66. union {
  67. u64 raw{};
  68. BitField<0, 1, u64> position1;
  69. BitField<1, 1, u64> position2;
  70. BitField<2, 1, u64> position3;
  71. BitField<3, 1, u64> position4;
  72. };
  73. };
  74. void SetSupportedStyleSet(NPadType style_set);
  75. NPadType GetSupportedStyleSet() const;
  76. void SetSupportedNPadIdTypes(u8* data, std::size_t length);
  77. void GetSupportedNpadIdTypes(u32* data, std::size_t max_length);
  78. std::size_t GetSupportedNPadIdTypesSize() const;
  79. void SetHoldType(NpadHoldType joy_hold_type);
  80. NpadHoldType GetHoldType() const;
  81. void SetNpadMode(u32 npad_id, NPadAssignments assignment_mode);
  82. void VibrateController(const std::vector<u32>& controller_ids,
  83. const std::vector<Vibration>& vibrations);
  84. Kernel::SharedPtr<Kernel::Event> GetStyleSetChangedEvent() const;
  85. Vibration GetLastVibration() const;
  86. void AddNewController(NPadControllerType controller);
  87. void ConnectNPad(u32 npad_id);
  88. void DisconnectNPad(u32 npad_id);
  89. LedPattern GetLedPattern(u32 npad_id);
  90. void SetVibrationEnabled(bool can_vibrate);
  91. private:
  92. struct CommonHeader {
  93. s64_le timestamp;
  94. s64_le total_entry_count;
  95. s64_le last_entry_index;
  96. s64_le entry_count;
  97. };
  98. static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
  99. struct ControllerColor {
  100. u32_le body_color;
  101. u32_le button_color;
  102. };
  103. static_assert(sizeof(ControllerColor) == 8, "ControllerColor is an invalid size");
  104. struct ControllerPadState {
  105. union {
  106. u64_le raw{};
  107. // Button states
  108. BitField<0, 1, u64_le> a;
  109. BitField<1, 1, u64_le> b;
  110. BitField<2, 1, u64_le> x;
  111. BitField<3, 1, u64_le> y;
  112. BitField<4, 1, u64_le> l_stick;
  113. BitField<5, 1, u64_le> r_stick;
  114. BitField<6, 1, u64_le> l;
  115. BitField<7, 1, u64_le> r;
  116. BitField<8, 1, u64_le> zl;
  117. BitField<9, 1, u64_le> zr;
  118. BitField<10, 1, u64_le> plus;
  119. BitField<11, 1, u64_le> minus;
  120. // D-Pad
  121. BitField<12, 1, u64_le> d_left;
  122. BitField<13, 1, u64_le> d_up;
  123. BitField<14, 1, u64_le> d_right;
  124. BitField<15, 1, u64_le> d_down;
  125. // Left JoyStick
  126. BitField<16, 1, u64_le> l_stick_left;
  127. BitField<17, 1, u64_le> l_stick_up;
  128. BitField<18, 1, u64_le> l_stick_right;
  129. BitField<19, 1, u64_le> l_stick_down;
  130. // Right JoyStick
  131. BitField<20, 1, u64_le> r_stick_left;
  132. BitField<21, 1, u64_le> r_stick_up;
  133. BitField<22, 1, u64_le> r_stick_right;
  134. BitField<23, 1, u64_le> r_stick_down;
  135. // Not always active?
  136. BitField<24, 1, u64_le> sl;
  137. BitField<25, 1, u64_le> sr;
  138. };
  139. };
  140. static_assert(sizeof(ControllerPadState) == 8, "ControllerPadState is an invalid size");
  141. struct AnalogPosition {
  142. s32_le x;
  143. s32_le y;
  144. };
  145. static_assert(sizeof(AnalogPosition) == 8, "AnalogPosition is an invalid size");
  146. struct ConnectionState {
  147. union {
  148. u32_le raw{};
  149. BitField<0, 1, u32_le> IsConnected;
  150. BitField<1, 1, u32_le> IsWired;
  151. BitField<2, 1, u32_le> IsLeftJoyConnected;
  152. BitField<3, 1, u32_le> IsLeftJoyWired;
  153. BitField<4, 1, u32_le> IsRightJoyConnected;
  154. BitField<5, 1, u32_le> IsRightJoyWired;
  155. };
  156. };
  157. static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size");
  158. struct GenericStates {
  159. s64_le timestamp;
  160. s64_le timestamp2;
  161. ControllerPadState pad_states;
  162. AnalogPosition l_stick;
  163. AnalogPosition r_stick;
  164. ConnectionState connection_status;
  165. };
  166. static_assert(sizeof(GenericStates) == 0x30, "NPadGenericStates is an invalid size");
  167. struct NPadGeneric {
  168. CommonHeader common;
  169. std::array<GenericStates, 17> npad;
  170. };
  171. static_assert(sizeof(NPadGeneric) == 0x350, "NPadGeneric is an invalid size");
  172. enum class ColorReadError : u32_le {
  173. ReadOk = 0,
  174. ColorDoesntExist = 1,
  175. NoController = 2,
  176. };
  177. struct NPadProperties {
  178. union {
  179. s64_le raw{};
  180. BitField<11, 1, s64_le> is_vertical;
  181. BitField<12, 1, s64_le> is_horizontal;
  182. BitField<13, 1, s64_le> use_plus;
  183. BitField<14, 1, s64_le> use_minus;
  184. };
  185. };
  186. struct NPadDevice {
  187. union {
  188. u32_le raw{};
  189. BitField<0, 1, s32_le> pro_controller;
  190. BitField<1, 1, s32_le> handheld;
  191. BitField<2, 1, s32_le> handheld_left;
  192. BitField<3, 1, s32_le> handheld_right;
  193. BitField<4, 1, s32_le> joycon_left;
  194. BitField<5, 1, s32_le> joycon_right;
  195. BitField<6, 1, s32_le> pokeball;
  196. };
  197. };
  198. struct NPadEntry {
  199. NPadType joy_styles;
  200. NPadAssignments pad_assignment;
  201. ColorReadError single_color_error;
  202. ControllerColor single_color;
  203. ColorReadError dual_color_error;
  204. ControllerColor left_color;
  205. ControllerColor right_color;
  206. NPadGeneric main_controller_states;
  207. NPadGeneric handheld_states;
  208. NPadGeneric dual_states;
  209. NPadGeneric left_joy_states;
  210. NPadGeneric right_joy_states;
  211. NPadGeneric pokeball_states;
  212. NPadGeneric libnx; // TODO(ogniK): Find out what this actually is, libnx seems to only be
  213. // relying on this for the time being
  214. INSERT_PADDING_BYTES(
  215. 0x708 *
  216. 6); // TODO(ogniK): SixAxis states, require more information before implementation
  217. NPadDevice device_type;
  218. NPadProperties properties;
  219. INSERT_PADDING_WORDS(1);
  220. std::array<u32, 3> battery_level;
  221. INSERT_PADDING_BYTES(0x5c);
  222. INSERT_PADDING_BYTES(0xdf8);
  223. };
  224. static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size");
  225. struct ControllerHolder {
  226. Controller_NPad::NPadControllerType type;
  227. bool is_connected;
  228. };
  229. NPadType style{};
  230. std::array<NPadEntry, 10> shared_memory_entries{};
  231. std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID>
  232. buttons;
  233. std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID> sticks;
  234. std::vector<u32> supported_npad_id_types{};
  235. NpadHoldType hold_type{NpadHoldType::Vertical};
  236. Kernel::SharedPtr<Kernel::Event> styleset_changed_event;
  237. Vibration last_processed_vibration{};
  238. std::array<ControllerHolder, 10> connected_controllers{};
  239. bool can_controllers_vibrate{true};
  240. void InitNewlyAddedControler(std::size_t controller_idx);
  241. };
  242. } // namespace Service::HID