emulated_controller.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <array>
  5. #include <functional>
  6. #include <memory>
  7. #include <mutex>
  8. #include <unordered_map>
  9. #include <vector>
  10. #include "common/common_types.h"
  11. #include "common/input.h"
  12. #include "common/param_package.h"
  13. #include "common/settings.h"
  14. #include "common/vector_math.h"
  15. #include "core/hid/hid_types.h"
  16. #include "core/hid/irs_types.h"
  17. #include "core/hid/motion_input.h"
  18. namespace Core::HID {
  19. const std::size_t max_emulated_controllers = 2;
  20. const std::size_t output_devices_size = 4;
  21. struct ControllerMotionInfo {
  22. Common::Input::MotionStatus raw_status{};
  23. MotionInput emulated{};
  24. };
  25. using ButtonDevices =
  26. std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeButton::NumButtons>;
  27. using StickDevices =
  28. std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeAnalog::NumAnalogs>;
  29. using ControllerMotionDevices =
  30. std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeMotion::NumMotions>;
  31. using TriggerDevices =
  32. std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeTrigger::NumTriggers>;
  33. using ColorDevices =
  34. std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
  35. using BatteryDevices =
  36. std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
  37. using CameraDevices =
  38. std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
  39. using RingAnalogDevices =
  40. std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
  41. using NfcDevices =
  42. std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
  43. using OutputDevices = std::array<std::unique_ptr<Common::Input::OutputDevice>, output_devices_size>;
  44. using ButtonParams = std::array<Common::ParamPackage, Settings::NativeButton::NumButtons>;
  45. using StickParams = std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs>;
  46. using ControllerMotionParams = std::array<Common::ParamPackage, Settings::NativeMotion::NumMotions>;
  47. using TriggerParams = std::array<Common::ParamPackage, Settings::NativeTrigger::NumTriggers>;
  48. using ColorParams = std::array<Common::ParamPackage, max_emulated_controllers>;
  49. using BatteryParams = std::array<Common::ParamPackage, max_emulated_controllers>;
  50. using CameraParams = std::array<Common::ParamPackage, max_emulated_controllers>;
  51. using RingAnalogParams = std::array<Common::ParamPackage, max_emulated_controllers>;
  52. using NfcParams = std::array<Common::ParamPackage, max_emulated_controllers>;
  53. using OutputParams = std::array<Common::ParamPackage, output_devices_size>;
  54. using ButtonValues = std::array<Common::Input::ButtonStatus, Settings::NativeButton::NumButtons>;
  55. using SticksValues = std::array<Common::Input::StickStatus, Settings::NativeAnalog::NumAnalogs>;
  56. using TriggerValues =
  57. std::array<Common::Input::TriggerStatus, Settings::NativeTrigger::NumTriggers>;
  58. using ControllerMotionValues = std::array<ControllerMotionInfo, Settings::NativeMotion::NumMotions>;
  59. using ColorValues = std::array<Common::Input::BodyColorStatus, max_emulated_controllers>;
  60. using BatteryValues = std::array<Common::Input::BatteryStatus, max_emulated_controllers>;
  61. using CameraValues = Common::Input::CameraStatus;
  62. using RingAnalogValue = Common::Input::AnalogStatus;
  63. using NfcValues = Common::Input::NfcStatus;
  64. using VibrationValues = std::array<Common::Input::VibrationStatus, max_emulated_controllers>;
  65. struct AnalogSticks {
  66. AnalogStickState left{};
  67. AnalogStickState right{};
  68. };
  69. struct ControllerColors {
  70. NpadControllerColor fullkey{};
  71. NpadControllerColor left{};
  72. NpadControllerColor right{};
  73. };
  74. struct BatteryLevelState {
  75. NpadPowerInfo dual{};
  76. NpadPowerInfo left{};
  77. NpadPowerInfo right{};
  78. };
  79. struct CameraState {
  80. Core::IrSensor::ImageTransferProcessorFormat format{};
  81. std::vector<u8> data{};
  82. std::size_t sample{};
  83. };
  84. struct RingSensorForce {
  85. f32 force;
  86. };
  87. using NfcState = Common::Input::NfcStatus;
  88. struct ControllerMotion {
  89. Common::Vec3f accel{};
  90. Common::Vec3f gyro{};
  91. Common::Vec3f rotation{};
  92. Common::Vec3f euler{};
  93. std::array<Common::Vec3f, 3> orientation{};
  94. bool is_at_rest{};
  95. };
  96. enum EmulatedDeviceIndex : u8 {
  97. LeftIndex,
  98. RightIndex,
  99. DualIndex,
  100. AllDevices,
  101. };
  102. using MotionState = std::array<ControllerMotion, 2>;
  103. struct ControllerStatus {
  104. // Data from input_common
  105. ButtonValues button_values{};
  106. SticksValues stick_values{};
  107. ControllerMotionValues motion_values{};
  108. TriggerValues trigger_values{};
  109. ColorValues color_values{};
  110. BatteryValues battery_values{};
  111. VibrationValues vibration_values{};
  112. CameraValues camera_values{};
  113. RingAnalogValue ring_analog_value{};
  114. NfcValues nfc_values{};
  115. // Data for HID services
  116. HomeButtonState home_button_state{};
  117. CaptureButtonState capture_button_state{};
  118. NpadButtonState npad_button_state{};
  119. DebugPadButton debug_pad_button_state{};
  120. AnalogSticks analog_stick_state{};
  121. MotionState motion_state{};
  122. NpadGcTriggerState gc_trigger_state{};
  123. ControllerColors colors_state{};
  124. BatteryLevelState battery_state{};
  125. CameraState camera_state{};
  126. RingSensorForce ring_analog_state{};
  127. NfcState nfc_state{};
  128. Common::Input::PollingMode left_polling_mode{};
  129. Common::Input::PollingMode right_polling_mode{};
  130. };
  131. enum class ControllerTriggerType {
  132. Button,
  133. Stick,
  134. Trigger,
  135. Motion,
  136. Color,
  137. Battery,
  138. Vibration,
  139. IrSensor,
  140. RingController,
  141. Nfc,
  142. Connected,
  143. Disconnected,
  144. Type,
  145. All,
  146. };
  147. struct ControllerUpdateCallback {
  148. std::function<void(ControllerTriggerType)> on_change;
  149. bool is_npad_service;
  150. };
  151. class EmulatedController {
  152. public:
  153. /**
  154. * Contains all input data (buttons, joysticks, vibration, and motion) within this controller.
  155. * @param npad_id_type npad id type for this specific controller
  156. */
  157. explicit EmulatedController(NpadIdType npad_id_type_);
  158. ~EmulatedController();
  159. YUZU_NON_COPYABLE(EmulatedController);
  160. YUZU_NON_MOVEABLE(EmulatedController);
  161. /// Converts the controller type from settings to npad type
  162. static NpadStyleIndex MapSettingsTypeToNPad(Settings::ControllerType type);
  163. /// Converts npad type to the equivalent of controller type from settings
  164. static Settings::ControllerType MapNPadToSettingsType(NpadStyleIndex type);
  165. /// Gets the NpadIdType for this controller
  166. NpadIdType GetNpadIdType() const;
  167. /// Sets the NpadStyleIndex for this controller
  168. void SetNpadStyleIndex(NpadStyleIndex npad_type_);
  169. /**
  170. * Gets the NpadStyleIndex for this controller
  171. * @param get_temporary_value If true tmp_npad_type will be returned
  172. * @return NpadStyleIndex set on the controller
  173. */
  174. NpadStyleIndex GetNpadStyleIndex(bool get_temporary_value = false) const;
  175. /**
  176. * Sets the supported controller types. Disconnects the controller if current type is not
  177. * supported
  178. * @param supported_styles bitflag with supported types
  179. */
  180. void SetSupportedNpadStyleTag(NpadStyleTag supported_styles);
  181. /**
  182. * Sets the connected status to true
  183. * @param use_temporary_value If true tmp_npad_type will be used
  184. */
  185. void Connect(bool use_temporary_value = false);
  186. /// Sets the connected status to false
  187. void Disconnect();
  188. /**
  189. * Is the emulated connected
  190. * @param get_temporary_value If true tmp_is_connected will be returned
  191. * @return true if the controller has the connected status
  192. */
  193. bool IsConnected(bool get_temporary_value = false) const;
  194. /// Removes all callbacks created from input devices
  195. void UnloadInput();
  196. /**
  197. * Sets the emulated controller into configuring mode
  198. * This prevents the modification of the HID state of the emulated controller by input commands
  199. */
  200. void EnableConfiguration();
  201. /// Returns the emulated controller into normal mode, allowing the modification of the HID state
  202. void DisableConfiguration();
  203. /// Enables Home and Screenshot buttons
  204. void EnableSystemButtons();
  205. /// Disables Home and Screenshot buttons
  206. void DisableSystemButtons();
  207. /// Sets Home and Screenshot buttons to false
  208. void ResetSystemButtons();
  209. /// Returns true if the emulated controller is in configuring mode
  210. bool IsConfiguring() const;
  211. /// Reload all input devices
  212. void ReloadInput();
  213. /// Overrides current mapped devices with the stored configuration and reloads all input devices
  214. void ReloadFromSettings();
  215. /// Updates current colors with the ones stored in the configuration
  216. void ReloadColorsFromSettings();
  217. /// Saves the current mapped configuration
  218. void SaveCurrentConfig();
  219. /// Reverts any mapped changes made that weren't saved
  220. void RestoreConfig();
  221. /// Returns a vector of mapped devices from the mapped button and stick parameters
  222. std::vector<Common::ParamPackage> GetMappedDevices() const;
  223. // Returns the current mapped button device
  224. Common::ParamPackage GetButtonParam(std::size_t index) const;
  225. // Returns the current mapped stick device
  226. Common::ParamPackage GetStickParam(std::size_t index) const;
  227. // Returns the current mapped motion device
  228. Common::ParamPackage GetMotionParam(std::size_t index) const;
  229. /**
  230. * Updates the current mapped button device
  231. * @param param ParamPackage with controller data to be mapped
  232. */
  233. void SetButtonParam(std::size_t index, Common::ParamPackage param);
  234. /**
  235. * Updates the current mapped stick device
  236. * @param param ParamPackage with controller data to be mapped
  237. */
  238. void SetStickParam(std::size_t index, Common::ParamPackage param);
  239. /**
  240. * Updates the current mapped motion device
  241. * @param param ParamPackage with controller data to be mapped
  242. */
  243. void SetMotionParam(std::size_t index, Common::ParamPackage param);
  244. /// Auto calibrates the current motion devices
  245. void StartMotionCalibration();
  246. /// Returns the latest button status from the controller with parameters
  247. ButtonValues GetButtonsValues() const;
  248. /// Returns the latest analog stick status from the controller with parameters
  249. SticksValues GetSticksValues() const;
  250. /// Returns the latest trigger status from the controller with parameters
  251. TriggerValues GetTriggersValues() const;
  252. /// Returns the latest motion status from the controller with parameters
  253. ControllerMotionValues GetMotionValues() const;
  254. /// Returns the latest color status from the controller with parameters
  255. ColorValues GetColorsValues() const;
  256. /// Returns the latest battery status from the controller with parameters
  257. BatteryValues GetBatteryValues() const;
  258. /// Returns the latest camera status from the controller with parameters
  259. CameraValues GetCameraValues() const;
  260. /// Returns the latest status of analog input from the ring sensor with parameters
  261. RingAnalogValue GetRingSensorValues() const;
  262. /// Returns the latest status of button input for the hid::HomeButton service
  263. HomeButtonState GetHomeButtons() const;
  264. /// Returns the latest status of button input for the hid::CaptureButton service
  265. CaptureButtonState GetCaptureButtons() const;
  266. /// Returns the latest status of button input for the hid::Npad service
  267. NpadButtonState GetNpadButtons() const;
  268. /// Returns the latest status of button input for the debug pad service
  269. DebugPadButton GetDebugPadButtons() const;
  270. /// Returns the latest status of stick input from the mouse
  271. AnalogSticks GetSticks() const;
  272. /// Returns the latest status of trigger input from the mouse
  273. NpadGcTriggerState GetTriggers() const;
  274. /// Returns the latest status of motion input from the mouse
  275. MotionState GetMotions() const;
  276. /// Returns the latest color value from the controller
  277. ControllerColors GetColors() const;
  278. /// Returns the latest battery status from the controller
  279. BatteryLevelState GetBattery() const;
  280. /// Returns the latest camera status from the controller
  281. const CameraState& GetCamera() const;
  282. /// Returns the latest ringcon force sensor value
  283. RingSensorForce GetRingSensorForce() const;
  284. /// Returns the latest ntag status from the controller
  285. const NfcState& GetNfc() const;
  286. /**
  287. * Sends a specific vibration to the output device
  288. * @return true if vibration had no errors
  289. */
  290. bool SetVibration(std::size_t device_index, VibrationValue vibration);
  291. /**
  292. * Sends a small vibration to the output device
  293. * @return true if SetVibration was successful
  294. */
  295. bool IsVibrationEnabled(std::size_t device_index);
  296. /**
  297. * Sets the desired data to be polled from a controller
  298. * @param device_index index of the controller to set the polling mode
  299. * @param polling_mode type of input desired buttons, gyro, nfc, ir, etc.
  300. * @return driver result from this command
  301. */
  302. Common::Input::DriverResult SetPollingMode(EmulatedDeviceIndex device_index,
  303. Common::Input::PollingMode polling_mode);
  304. /**
  305. * Get the current polling mode from a controller
  306. * @param device_index index of the controller to set the polling mode
  307. * @return current polling mode
  308. */
  309. Common::Input::PollingMode GetPollingMode(EmulatedDeviceIndex device_index) const;
  310. /**
  311. * Sets the desired camera format to be polled from a controller
  312. * @param camera_format size of each frame
  313. * @return true if SetCameraFormat was successful
  314. */
  315. bool SetCameraFormat(Core::IrSensor::ImageTransferProcessorFormat camera_format);
  316. // Returns the current mapped ring device
  317. Common::ParamPackage GetRingParam() const;
  318. /**
  319. * Updates the current mapped ring device
  320. * @param param ParamPackage with ring sensor data to be mapped
  321. */
  322. void SetRingParam(Common::ParamPackage param);
  323. /// Returns true if the device has nfc support
  324. bool HasNfc() const;
  325. /// Sets the joycon in nfc mode and increments the handle count
  326. bool AddNfcHandle();
  327. /// Decrements the handle count if zero sets the joycon in active mode
  328. bool RemoveNfcHandle();
  329. /// Start searching for nfc tags
  330. bool StartNfcPolling();
  331. /// Stop searching for nfc tags
  332. bool StopNfcPolling();
  333. /// Returns true if the nfc tag was readable
  334. bool ReadAmiiboData(std::vector<u8>& data);
  335. /// Returns true if the nfc tag was written
  336. bool WriteNfc(const std::vector<u8>& data);
  337. /// Returns true if the nfc tag was readable
  338. bool ReadMifareData(const Common::Input::MifareRequest& request,
  339. Common::Input::MifareRequest& out_data);
  340. /// Returns true if the nfc tag was written
  341. bool WriteMifareData(const Common::Input::MifareRequest& request);
  342. /// Returns the led pattern corresponding to this emulated controller
  343. LedPattern GetLedPattern() const;
  344. /// Asks the output device to change the player led pattern
  345. void SetLedPattern();
  346. /// Changes sensitivity of the motion sensor
  347. void SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode mode);
  348. /**
  349. * Adds a callback to the list of events
  350. * @param update_callback A ConsoleUpdateCallback that will be triggered
  351. * @return an unique key corresponding to the callback index in the list
  352. */
  353. int SetCallback(ControllerUpdateCallback update_callback);
  354. /**
  355. * Removes a callback from the list stopping any future events to this object
  356. * @param key Key corresponding to the callback index in the list
  357. */
  358. void DeleteCallback(int key);
  359. /// Swaps the state of the turbo buttons and updates motion input
  360. void StatusUpdate();
  361. private:
  362. /// creates input devices from params
  363. void LoadDevices();
  364. /// Set the params for TAS devices
  365. void LoadTASParams();
  366. /// Set the params for virtual pad devices
  367. void LoadVirtualGamepadParams();
  368. /**
  369. * @param use_temporary_value If true tmp_npad_type will be used
  370. * @return true if the controller style is fullkey
  371. */
  372. bool IsControllerFullkey(bool use_temporary_value = false) const;
  373. /**
  374. * Checks the current controller type against the supported_style_tag
  375. * @param use_temporary_value If true tmp_npad_type will be used
  376. * @return true if the controller is supported
  377. */
  378. bool IsControllerSupported(bool use_temporary_value = false) const;
  379. /**
  380. * Updates the button status of the controller
  381. * @param callback A CallbackStatus containing the button status
  382. * @param index Button ID of the to be updated
  383. */
  384. void SetButton(const Common::Input::CallbackStatus& callback, std::size_t index,
  385. Common::UUID uuid);
  386. /**
  387. * Updates the analog stick status of the controller
  388. * @param callback A CallbackStatus containing the analog stick status
  389. * @param index stick ID of the to be updated
  390. */
  391. void SetStick(const Common::Input::CallbackStatus& callback, std::size_t index,
  392. Common::UUID uuid);
  393. /**
  394. * Updates the trigger status of the controller
  395. * @param callback A CallbackStatus containing the trigger status
  396. * @param index trigger ID of the to be updated
  397. */
  398. void SetTrigger(const Common::Input::CallbackStatus& callback, std::size_t index,
  399. Common::UUID uuid);
  400. /**
  401. * Updates the motion status of the controller
  402. * @param callback A CallbackStatus containing gyro and accelerometer data
  403. * @param index motion ID of the to be updated
  404. */
  405. void SetMotion(const Common::Input::CallbackStatus& callback, std::size_t index);
  406. /**
  407. * Updates the color status of the controller
  408. * @param callback A CallbackStatus containing the color status
  409. * @param index color ID of the to be updated
  410. */
  411. void SetColors(const Common::Input::CallbackStatus& callback, std::size_t index);
  412. /**
  413. * Updates the battery status of the controller
  414. * @param callback A CallbackStatus containing the battery status
  415. * @param index battery ID of the to be updated
  416. */
  417. void SetBattery(const Common::Input::CallbackStatus& callback, std::size_t index);
  418. /**
  419. * Updates the camera status of the controller
  420. * @param callback A CallbackStatus containing the camera status
  421. */
  422. void SetCamera(const Common::Input::CallbackStatus& callback);
  423. /**
  424. * Updates the ring analog sensor status of the ring controller
  425. * @param callback A CallbackStatus containing the force status
  426. */
  427. void SetRingAnalog(const Common::Input::CallbackStatus& callback);
  428. /**
  429. * Updates the nfc status of the controller
  430. * @param callback A CallbackStatus containing the nfc status
  431. */
  432. void SetNfc(const Common::Input::CallbackStatus& callback);
  433. /**
  434. * Converts a color format from bgra to rgba
  435. * @param color in bgra format
  436. * @return NpadColor in rgba format
  437. */
  438. NpadColor GetNpadColor(u32 color);
  439. /**
  440. * Triggers a callback that something has changed on the controller status
  441. * @param type Input type of the event to trigger
  442. * @param is_service_update indicates if this event should only be sent to HID services
  443. */
  444. void TriggerOnChange(ControllerTriggerType type, bool is_service_update);
  445. NpadButton GetTurboButtonMask() const;
  446. const NpadIdType npad_id_type;
  447. NpadStyleIndex npad_type{NpadStyleIndex::None};
  448. NpadStyleIndex original_npad_type{NpadStyleIndex::None};
  449. NpadStyleTag supported_style_tag{NpadStyleSet::All};
  450. bool is_connected{false};
  451. bool is_configuring{false};
  452. bool is_initalized{false};
  453. bool system_buttons_enabled{true};
  454. f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard};
  455. u32 turbo_button_state{0};
  456. std::size_t nfc_handles{0};
  457. // Temporary values to avoid doing changes while the controller is in configuring mode
  458. NpadStyleIndex tmp_npad_type{NpadStyleIndex::None};
  459. bool tmp_is_connected{false};
  460. ButtonParams button_params;
  461. StickParams stick_params;
  462. ControllerMotionParams motion_params;
  463. TriggerParams trigger_params;
  464. BatteryParams battery_params;
  465. ColorParams color_params;
  466. CameraParams camera_params;
  467. RingAnalogParams ring_params;
  468. NfcParams nfc_params;
  469. OutputParams output_params;
  470. ButtonDevices button_devices;
  471. StickDevices stick_devices;
  472. ControllerMotionDevices motion_devices;
  473. TriggerDevices trigger_devices;
  474. BatteryDevices battery_devices;
  475. ColorDevices color_devices;
  476. CameraDevices camera_devices;
  477. RingAnalogDevices ring_analog_devices;
  478. NfcDevices nfc_devices;
  479. OutputDevices output_devices;
  480. // TAS related variables
  481. ButtonParams tas_button_params;
  482. StickParams tas_stick_params;
  483. ButtonDevices tas_button_devices;
  484. StickDevices tas_stick_devices;
  485. // Virtual gamepad related variables
  486. ButtonParams virtual_button_params;
  487. StickParams virtual_stick_params;
  488. ControllerMotionParams virtual_motion_params;
  489. ButtonDevices virtual_button_devices;
  490. StickDevices virtual_stick_devices;
  491. ControllerMotionDevices virtual_motion_devices;
  492. mutable std::mutex mutex;
  493. mutable std::mutex callback_mutex;
  494. mutable std::mutex npad_mutex;
  495. mutable std::mutex connect_mutex;
  496. std::unordered_map<int, ControllerUpdateCallback> callback_list;
  497. int last_callback_key = 0;
  498. // Stores the current status of all controller input
  499. ControllerStatus controller;
  500. };
  501. } // namespace Core::HID