npad.h 23 KB

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