npad.h 17 KB

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