npad.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  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 <atomic>
  7. #include <mutex>
  8. #include "common/bit_field.h"
  9. #include "common/common_types.h"
  10. #include "common/vector_math.h"
  11. #include "core/hid/hid_types.h"
  12. #include "core/hle/service/hid/controllers/controller_base.h"
  13. #include "core/hle/service/hid/ring_lifo.h"
  14. namespace Core::HID {
  15. class EmulatedController;
  16. enum class ControllerTriggerType;
  17. } // namespace Core::HID
  18. namespace Kernel {
  19. class KEvent;
  20. class KReadableEvent;
  21. } // namespace Kernel
  22. namespace Service::KernelHelpers {
  23. class ServiceContext;
  24. }
  25. namespace Service::HID {
  26. class Controller_NPad final : public ControllerBase {
  27. public:
  28. explicit Controller_NPad(Core::HID::HIDCore& hid_core_,
  29. KernelHelpers::ServiceContext& service_context_);
  30. ~Controller_NPad() override;
  31. // Called when the controller is initialized
  32. void OnInit() override;
  33. // When the controller is released
  34. void OnRelease() override;
  35. // When the controller is requesting an update for the shared memory
  36. void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override;
  37. // When the controller is requesting a motion update for the shared memory
  38. void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
  39. std::size_t size) override;
  40. // This is nn::hid::GyroscopeZeroDriftMode
  41. enum class GyroscopeZeroDriftMode : u32 {
  42. Loose = 0,
  43. Standard = 1,
  44. Tight = 2,
  45. };
  46. // This is nn::hid::NpadJoyHoldType
  47. enum class NpadJoyHoldType : u64 {
  48. Vertical = 0,
  49. Horizontal = 1,
  50. };
  51. // This is nn::hid::NpadJoyAssignmentMode
  52. enum class NpadJoyAssignmentMode : u32 {
  53. Dual = 0,
  54. Single = 1,
  55. };
  56. // This is nn::hid::NpadJoyDeviceType
  57. enum class NpadJoyDeviceType : s64 {
  58. Left = 0,
  59. Right = 1,
  60. };
  61. // This is nn::hid::NpadHandheldActivationMode
  62. enum class NpadHandheldActivationMode : u64 {
  63. Dual = 0,
  64. Single = 1,
  65. None = 2,
  66. };
  67. // This is nn::hid::NpadCommunicationMode
  68. enum class NpadCommunicationMode : u64 {
  69. Mode_5ms = 0,
  70. Mode_10ms = 1,
  71. Mode_15ms = 2,
  72. Default = 3,
  73. };
  74. void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set);
  75. Core::HID::NpadStyleTag 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(NpadJoyHoldType joy_hold_type);
  80. NpadJoyHoldType GetHoldType() const;
  81. void SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode);
  82. NpadHandheldActivationMode GetNpadHandheldActivationMode() const;
  83. void SetNpadCommunicationMode(NpadCommunicationMode communication_mode_);
  84. NpadCommunicationMode GetNpadCommunicationMode() const;
  85. void SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceType npad_device_type,
  86. NpadJoyAssignmentMode assignment_mode);
  87. bool VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index,
  88. const Core::HID::VibrationValue& vibration_value);
  89. void VibrateController(const Core::HID::VibrationDeviceHandle& vibration_device_handle,
  90. const Core::HID::VibrationValue& vibration_value);
  91. void VibrateControllers(
  92. const std::vector<Core::HID::VibrationDeviceHandle>& vibration_device_handles,
  93. const std::vector<Core::HID::VibrationValue>& vibration_values);
  94. Core::HID::VibrationValue GetLastVibration(
  95. const Core::HID::VibrationDeviceHandle& vibration_device_handle) const;
  96. void InitializeVibrationDevice(const Core::HID::VibrationDeviceHandle& vibration_device_handle);
  97. void InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index);
  98. void SetPermitVibrationSession(bool permit_vibration_session);
  99. bool IsVibrationDeviceMounted(
  100. const Core::HID::VibrationDeviceHandle& vibration_device_handle) const;
  101. Kernel::KReadableEvent& GetStyleSetChangedEvent(Core::HID::NpadIdType npad_id);
  102. void SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const;
  103. // Adds a new controller at an index.
  104. void AddNewControllerAt(Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id);
  105. // Adds a new controller at an index with connection status.
  106. void UpdateControllerAt(Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id,
  107. bool connected);
  108. void DisconnectNpad(Core::HID::NpadIdType npad_id);
  109. void SetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle,
  110. GyroscopeZeroDriftMode drift_mode);
  111. GyroscopeZeroDriftMode GetGyroscopeZeroDriftMode(
  112. Core::HID::SixAxisSensorHandle sixaxis_handle) const;
  113. bool IsSixAxisSensorAtRest(Core::HID::SixAxisSensorHandle sixaxis_handle) const;
  114. void SetSixAxisEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle, bool sixaxis_status);
  115. void SetSixAxisFusionEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle,
  116. bool sixaxis_fusion_status);
  117. void SetSixAxisFusionParameters(
  118. Core::HID::SixAxisSensorHandle sixaxis_handle,
  119. Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters);
  120. Core::HID::SixAxisSensorFusionParameters GetSixAxisFusionParameters(
  121. Core::HID::SixAxisSensorHandle sixaxis_handle);
  122. void ResetSixAxisFusionParameters(Core::HID::SixAxisSensorHandle sixaxis_handle);
  123. Core::HID::LedPattern GetLedPattern(Core::HID::NpadIdType npad_id);
  124. bool IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id) const;
  125. void SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled,
  126. Core::HID::NpadIdType npad_id);
  127. void SetAnalogStickUseCenterClamp(bool use_center_clamp);
  128. void ClearAllConnectedControllers();
  129. void DisconnectAllConnectedControllers();
  130. void ConnectAllDisconnectedControllers();
  131. void ClearAllControllers();
  132. void MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2);
  133. void StartLRAssignmentMode();
  134. void StopLRAssignmentMode();
  135. bool SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2);
  136. // Logical OR for all buttons presses on all controllers
  137. // Specifically for cheat engine and other features.
  138. Core::HID::NpadButton GetAndResetPressState();
  139. static bool IsNpadIdValid(Core::HID::NpadIdType npad_id);
  140. static bool IsDeviceHandleValid(const Core::HID::SixAxisSensorHandle& device_handle);
  141. static bool IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle);
  142. private:
  143. // This is nn::hid::detail::ColorAttribute
  144. enum class ColorAttribute : u32 {
  145. Ok = 0,
  146. ReadError = 1,
  147. NoController = 2,
  148. };
  149. static_assert(sizeof(ColorAttribute) == 4, "ColorAttribute is an invalid size");
  150. // This is nn::hid::detail::NpadFullKeyColorState
  151. struct NpadFullKeyColorState {
  152. ColorAttribute attribute;
  153. Core::HID::NpadControllerColor fullkey;
  154. };
  155. static_assert(sizeof(NpadFullKeyColorState) == 0xC, "NpadFullKeyColorState is an invalid size");
  156. // This is nn::hid::detail::NpadJoyColorState
  157. struct NpadJoyColorState {
  158. ColorAttribute attribute;
  159. Core::HID::NpadControllerColor left;
  160. Core::HID::NpadControllerColor right;
  161. };
  162. static_assert(sizeof(NpadJoyColorState) == 0x14, "NpadJoyColorState is an invalid size");
  163. // This is nn::hid::NpadAttribute
  164. struct NpadAttribute {
  165. union {
  166. u32 raw{};
  167. BitField<0, 1, u32> is_connected;
  168. BitField<1, 1, u32> is_wired;
  169. BitField<2, 1, u32> is_left_connected;
  170. BitField<3, 1, u32> is_left_wired;
  171. BitField<4, 1, u32> is_right_connected;
  172. BitField<5, 1, u32> is_right_wired;
  173. };
  174. };
  175. static_assert(sizeof(NpadAttribute) == 4, "NpadAttribute is an invalid size");
  176. // This is nn::hid::NpadFullKeyState
  177. // This is nn::hid::NpadHandheldState
  178. // This is nn::hid::NpadJoyDualState
  179. // This is nn::hid::NpadJoyLeftState
  180. // This is nn::hid::NpadJoyRightState
  181. // This is nn::hid::NpadPalmaState
  182. // This is nn::hid::NpadSystemExtState
  183. struct NPadGenericState {
  184. s64_le sampling_number;
  185. Core::HID::NpadButtonState npad_buttons;
  186. Core::HID::AnalogStickState l_stick;
  187. Core::HID::AnalogStickState r_stick;
  188. NpadAttribute connection_status;
  189. INSERT_PADDING_BYTES(4); // Reserved
  190. };
  191. static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size");
  192. // This is nn::hid::SixAxisSensorAttribute
  193. struct SixAxisSensorAttribute {
  194. union {
  195. u32 raw{};
  196. BitField<0, 1, u32> is_connected;
  197. BitField<1, 1, u32> is_interpolated;
  198. };
  199. };
  200. static_assert(sizeof(SixAxisSensorAttribute) == 4, "SixAxisSensorAttribute is an invalid size");
  201. // This is nn::hid::SixAxisSensorState
  202. struct SixAxisSensorState {
  203. s64 delta_time{};
  204. s64 sampling_number{};
  205. Common::Vec3f accel{};
  206. Common::Vec3f gyro{};
  207. Common::Vec3f rotation{};
  208. std::array<Common::Vec3f, 3> orientation{};
  209. SixAxisSensorAttribute attribute;
  210. INSERT_PADDING_BYTES(4); // Reserved
  211. };
  212. static_assert(sizeof(SixAxisSensorState) == 0x60, "SixAxisSensorState is an invalid size");
  213. // This is nn::hid::server::NpadGcTriggerState
  214. struct NpadGcTriggerState {
  215. s64 sampling_number{};
  216. s32 l_analog{};
  217. s32 r_analog{};
  218. };
  219. static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size");
  220. // This is nn::hid::NpadSystemProperties
  221. struct NPadSystemProperties {
  222. union {
  223. s64 raw{};
  224. BitField<0, 1, s64> is_charging_joy_dual;
  225. BitField<1, 1, s64> is_charging_joy_left;
  226. BitField<2, 1, s64> is_charging_joy_right;
  227. BitField<3, 1, s64> is_powered_joy_dual;
  228. BitField<4, 1, s64> is_powered_joy_left;
  229. BitField<5, 1, s64> is_powered_joy_right;
  230. BitField<9, 1, s64> is_system_unsupported_button;
  231. BitField<10, 1, s64> is_system_ext_unsupported_button;
  232. BitField<11, 1, s64> is_vertical;
  233. BitField<12, 1, s64> is_horizontal;
  234. BitField<13, 1, s64> use_plus;
  235. BitField<14, 1, s64> use_minus;
  236. BitField<15, 1, s64> use_directional_buttons;
  237. };
  238. };
  239. static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size");
  240. // This is nn::hid::NpadSystemButtonProperties
  241. struct NpadSystemButtonProperties {
  242. union {
  243. s32 raw{};
  244. BitField<0, 1, s32> is_home_button_protection_enabled;
  245. };
  246. };
  247. static_assert(sizeof(NpadSystemButtonProperties) == 0x4,
  248. "NPadButtonProperties is an invalid size");
  249. // This is nn::hid::system::DeviceType
  250. struct DeviceType {
  251. union {
  252. u32 raw{};
  253. BitField<0, 1, s32> fullkey;
  254. BitField<1, 1, s32> debug_pad;
  255. BitField<2, 1, s32> handheld_left;
  256. BitField<3, 1, s32> handheld_right;
  257. BitField<4, 1, s32> joycon_left;
  258. BitField<5, 1, s32> joycon_right;
  259. BitField<6, 1, s32> palma;
  260. BitField<7, 1, s32> lark_hvc_left;
  261. BitField<8, 1, s32> lark_hvc_right;
  262. BitField<9, 1, s32> lark_nes_left;
  263. BitField<10, 1, s32> lark_nes_right;
  264. BitField<11, 1, s32> handheld_lark_hvc_left;
  265. BitField<12, 1, s32> handheld_lark_hvc_right;
  266. BitField<13, 1, s32> handheld_lark_nes_left;
  267. BitField<14, 1, s32> handheld_lark_nes_right;
  268. BitField<15, 1, s32> lucia;
  269. BitField<16, 1, s32> lagon;
  270. BitField<17, 1, s32> lager;
  271. BitField<31, 1, s32> system;
  272. };
  273. };
  274. // This is nn::hid::detail::NfcXcdDeviceHandleStateImpl
  275. struct NfcXcdDeviceHandleStateImpl {
  276. u64 handle;
  277. bool is_available;
  278. bool is_activated;
  279. INSERT_PADDING_BYTES(0x6); // Reserved
  280. u64 sampling_number;
  281. };
  282. static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18,
  283. "NfcXcdDeviceHandleStateImpl is an invalid size");
  284. // This is nn::hid::system::AppletFooterUiAttributesSet
  285. struct AppletFooterUiAttributes {
  286. INSERT_PADDING_BYTES(0x4);
  287. };
  288. // This is nn::hid::system::AppletFooterUiType
  289. enum class AppletFooterUiType : u8 {
  290. None = 0,
  291. HandheldNone = 1,
  292. HandheldJoyConLeftOnly = 1,
  293. HandheldJoyConRightOnly = 3,
  294. HandheldJoyConLeftJoyConRight = 4,
  295. JoyDual = 5,
  296. JoyDualLeftOnly = 6,
  297. JoyDualRightOnly = 7,
  298. JoyLeftHorizontal = 8,
  299. JoyLeftVertical = 9,
  300. JoyRightHorizontal = 10,
  301. JoyRightVertical = 11,
  302. SwitchProController = 12,
  303. CompatibleProController = 13,
  304. CompatibleJoyCon = 14,
  305. LarkHvc1 = 15,
  306. LarkHvc2 = 16,
  307. LarkNesLeft = 17,
  308. LarkNesRight = 18,
  309. Lucia = 19,
  310. Verification = 20,
  311. Lagon = 21,
  312. };
  313. struct AppletFooterUi {
  314. AppletFooterUiAttributes attributes;
  315. AppletFooterUiType type;
  316. INSERT_PADDING_BYTES(0x5B); // Reserved
  317. };
  318. static_assert(sizeof(AppletFooterUi) == 0x60, "AppletFooterUi is an invalid size");
  319. // This is nn::hid::NpadLarkType
  320. enum class NpadLarkType : u32 {
  321. Invalid,
  322. H1,
  323. H2,
  324. NL,
  325. NR,
  326. };
  327. // This is nn::hid::NpadLuciaType
  328. enum class NpadLuciaType : u32 {
  329. Invalid,
  330. J,
  331. E,
  332. U,
  333. };
  334. // This is nn::hid::NpadLagonType
  335. enum class NpadLagonType : u32 {
  336. Invalid,
  337. };
  338. // This is nn::hid::NpadLagerType
  339. enum class NpadLagerType : u32 {
  340. Invalid,
  341. J,
  342. E,
  343. U,
  344. };
  345. // This is nn::hid::detail::NpadInternalState
  346. struct NpadInternalState {
  347. Core::HID::NpadStyleTag style_tag;
  348. NpadJoyAssignmentMode assignment_mode;
  349. NpadFullKeyColorState fullkey_color;
  350. NpadJoyColorState joycon_color;
  351. Lifo<NPadGenericState, hid_entry_count> fullkey_lifo;
  352. Lifo<NPadGenericState, hid_entry_count> handheld_lifo;
  353. Lifo<NPadGenericState, hid_entry_count> joy_dual_lifo;
  354. Lifo<NPadGenericState, hid_entry_count> joy_left_lifo;
  355. Lifo<NPadGenericState, hid_entry_count> joy_right_lifo;
  356. Lifo<NPadGenericState, hid_entry_count> palma_lifo;
  357. Lifo<NPadGenericState, hid_entry_count> system_ext_lifo;
  358. Lifo<SixAxisSensorState, hid_entry_count> sixaxis_fullkey_lifo;
  359. Lifo<SixAxisSensorState, hid_entry_count> sixaxis_handheld_lifo;
  360. Lifo<SixAxisSensorState, hid_entry_count> sixaxis_dual_left_lifo;
  361. Lifo<SixAxisSensorState, hid_entry_count> sixaxis_dual_right_lifo;
  362. Lifo<SixAxisSensorState, hid_entry_count> sixaxis_left_lifo;
  363. Lifo<SixAxisSensorState, hid_entry_count> sixaxis_right_lifo;
  364. DeviceType device_type;
  365. INSERT_PADDING_BYTES(0x4); // Reserved
  366. NPadSystemProperties system_properties;
  367. NpadSystemButtonProperties button_properties;
  368. Core::HID::NpadBatteryLevel battery_level_dual;
  369. Core::HID::NpadBatteryLevel battery_level_left;
  370. Core::HID::NpadBatteryLevel battery_level_right;
  371. union {
  372. Lifo<NfcXcdDeviceHandleStateImpl, 0x2> nfc_xcd_device_lifo{};
  373. AppletFooterUi applet_footer;
  374. };
  375. INSERT_PADDING_BYTES(0x20); // Unknown
  376. Lifo<NpadGcTriggerState, hid_entry_count> gc_trigger_lifo;
  377. NpadLarkType lark_type_l_and_main;
  378. NpadLarkType lark_type_r;
  379. NpadLuciaType lucia_type;
  380. NpadLagonType lagon_type;
  381. NpadLagerType lager_type;
  382. // FW 13.x Investigate there is some sort of bitflag related to joycons
  383. INSERT_PADDING_BYTES(0x4);
  384. INSERT_PADDING_BYTES(0xc08); // Unknown
  385. };
  386. static_assert(sizeof(NpadInternalState) == 0x5000, "NpadInternalState is an invalid size");
  387. struct VibrationData {
  388. bool device_mounted{};
  389. Core::HID::VibrationValue latest_vibration_value{};
  390. std::chrono::steady_clock::time_point last_vibration_timepoint{};
  391. };
  392. struct NpadControllerData {
  393. Core::HID::EmulatedController* device;
  394. Kernel::KEvent* styleset_changed_event{};
  395. NpadInternalState shared_memory_entry{};
  396. std::array<VibrationData, 2> vibration{};
  397. bool unintended_home_button_input_protection{};
  398. bool is_connected{};
  399. // Dual joycons can have only one side connected
  400. bool is_dual_left_connected{true};
  401. bool is_dual_right_connected{true};
  402. // Motion parameters
  403. bool sixaxis_at_rest{true};
  404. bool sixaxis_sensor_enabled{true};
  405. bool sixaxis_fusion_enabled{false};
  406. Core::HID::SixAxisSensorFusionParameters sixaxis_fusion{};
  407. GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard};
  408. // Current pad state
  409. NPadGenericState npad_pad_state{};
  410. NPadGenericState npad_libnx_state{};
  411. NpadGcTriggerState npad_trigger_state{};
  412. SixAxisSensorState sixaxis_fullkey_state{};
  413. SixAxisSensorState sixaxis_handheld_state{};
  414. SixAxisSensorState sixaxis_dual_left_state{};
  415. SixAxisSensorState sixaxis_dual_right_state{};
  416. SixAxisSensorState sixaxis_left_lifo_state{};
  417. SixAxisSensorState sixaxis_right_lifo_state{};
  418. int callback_key;
  419. };
  420. void ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx);
  421. void InitNewlyAddedController(Core::HID::NpadIdType npad_id);
  422. bool IsControllerSupported(Core::HID::NpadStyleIndex controller) const;
  423. void RequestPadStateUpdate(Core::HID::NpadIdType npad_id);
  424. void WriteEmptyEntry(NpadInternalState& npad);
  425. NpadControllerData& GetControllerFromHandle(
  426. const Core::HID::SixAxisSensorHandle& device_handle);
  427. const NpadControllerData& GetControllerFromHandle(
  428. const Core::HID::SixAxisSensorHandle& device_handle) const;
  429. NpadControllerData& GetControllerFromHandle(
  430. const Core::HID::VibrationDeviceHandle& device_handle);
  431. const NpadControllerData& GetControllerFromHandle(
  432. const Core::HID::VibrationDeviceHandle& device_handle) const;
  433. NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id);
  434. const NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) const;
  435. std::atomic<u64> press_state{};
  436. std::array<NpadControllerData, 10> controller_data{};
  437. KernelHelpers::ServiceContext& service_context;
  438. std::mutex mutex;
  439. std::vector<Core::HID::NpadIdType> supported_npad_id_types{};
  440. NpadJoyHoldType hold_type{NpadJoyHoldType::Vertical};
  441. NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual};
  442. NpadCommunicationMode communication_mode{NpadCommunicationMode::Default};
  443. bool permit_vibration_session_enabled{false};
  444. bool analog_stick_use_center_clamp{};
  445. bool is_in_lr_assignment_mode{false};
  446. };
  447. } // namespace Service::HID