emulated_controller.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. // Copyright 2021 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include <functional>
  7. #include <memory>
  8. #include <mutex>
  9. #include <unordered_map>
  10. #include "common/common_types.h"
  11. #include "common/input.h"
  12. #include "common/param_package.h"
  13. #include "common/point.h"
  14. #include "common/quaternion.h"
  15. #include "common/settings.h"
  16. #include "common/vector_math.h"
  17. #include "core/hid/hid_types.h"
  18. #include "core/hid/motion_input.h"
  19. namespace Core::HID {
  20. const std::size_t max_emulated_controllers = 2;
  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 BatteryDevices =
  34. std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
  35. using OutputDevices =
  36. std::array<std::unique_ptr<Common::Input::OutputDevice>, max_emulated_controllers>;
  37. using ButtonParams = std::array<Common::ParamPackage, Settings::NativeButton::NumButtons>;
  38. using StickParams = std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs>;
  39. using ControllerMotionParams = std::array<Common::ParamPackage, Settings::NativeMotion::NumMotions>;
  40. using TriggerParams = std::array<Common::ParamPackage, Settings::NativeTrigger::NumTriggers>;
  41. using BatteryParams = std::array<Common::ParamPackage, max_emulated_controllers>;
  42. using OutputParams = std::array<Common::ParamPackage, max_emulated_controllers>;
  43. using ButtonValues = std::array<Common::Input::ButtonStatus, Settings::NativeButton::NumButtons>;
  44. using SticksValues = std::array<Common::Input::StickStatus, Settings::NativeAnalog::NumAnalogs>;
  45. using TriggerValues =
  46. std::array<Common::Input::TriggerStatus, Settings::NativeTrigger::NumTriggers>;
  47. using ControllerMotionValues = std::array<ControllerMotionInfo, Settings::NativeMotion::NumMotions>;
  48. using ColorValues = std::array<Common::Input::BodyColorStatus, max_emulated_controllers>;
  49. using BatteryValues = std::array<Common::Input::BatteryStatus, max_emulated_controllers>;
  50. using VibrationValues = std::array<Common::Input::VibrationStatus, max_emulated_controllers>;
  51. struct AnalogSticks {
  52. AnalogStickState left{};
  53. AnalogStickState right{};
  54. };
  55. struct ControllerColors {
  56. NpadControllerColor fullkey{};
  57. NpadControllerColor left{};
  58. NpadControllerColor right{};
  59. };
  60. struct BatteryLevelState {
  61. NpadPowerInfo dual{};
  62. NpadPowerInfo left{};
  63. NpadPowerInfo right{};
  64. };
  65. struct ControllerMotion {
  66. Common::Vec3f accel{};
  67. Common::Vec3f gyro{};
  68. Common::Vec3f rotation{};
  69. std::array<Common::Vec3f, 3> orientation{};
  70. bool is_at_rest{};
  71. };
  72. enum EmulatedDeviceIndex : u8 {
  73. LeftIndex,
  74. RightIndex,
  75. DualIndex,
  76. AllDevices,
  77. };
  78. using MotionState = std::array<ControllerMotion, 2>;
  79. struct ControllerStatus {
  80. // Data from input_common
  81. ButtonValues button_values{};
  82. SticksValues stick_values{};
  83. ControllerMotionValues motion_values{};
  84. TriggerValues trigger_values{};
  85. ColorValues color_values{};
  86. BatteryValues battery_values{};
  87. VibrationValues vibration_values{};
  88. // Data for HID serices
  89. NpadButtonState npad_button_state{};
  90. DebugPadButton debug_pad_button_state{};
  91. AnalogSticks analog_stick_state{};
  92. MotionState motion_state{};
  93. NpadGcTriggerState gc_trigger_state{};
  94. ControllerColors colors_state{};
  95. BatteryLevelState battery_state{};
  96. };
  97. enum class ControllerTriggerType {
  98. Button,
  99. Stick,
  100. Trigger,
  101. Motion,
  102. Color,
  103. Battery,
  104. Vibration,
  105. Connected,
  106. Disconnected,
  107. Type,
  108. All,
  109. };
  110. struct ControllerUpdateCallback {
  111. std::function<void(ControllerTriggerType)> on_change;
  112. bool is_npad_service;
  113. };
  114. class EmulatedController {
  115. public:
  116. /**
  117. * Contains all input data (buttons, joysticks, vibration, and motion) within this controller.
  118. * @param npad_id_type npad id type for this specific controller
  119. */
  120. explicit EmulatedController(NpadIdType npad_id_type_);
  121. ~EmulatedController();
  122. YUZU_NON_COPYABLE(EmulatedController);
  123. YUZU_NON_MOVEABLE(EmulatedController);
  124. /// Converts the controller type from settings to npad type
  125. static NpadStyleIndex MapSettingsTypeToNPad(Settings::ControllerType type);
  126. /// Converts npad type to the equivalent of controller type from settings
  127. static Settings::ControllerType MapNPadToSettingsType(NpadStyleIndex type);
  128. /// Gets the NpadIdType for this controller
  129. NpadIdType GetNpadIdType() const;
  130. /// Sets the NpadStyleIndex for this controller
  131. void SetNpadStyleIndex(NpadStyleIndex npad_type_);
  132. /**
  133. * Gets the NpadStyleIndex for this controller
  134. * @param get_temporary_value If true tmp_npad_type will be returned
  135. * @return NpadStyleIndex set on the controller
  136. */
  137. NpadStyleIndex GetNpadStyleIndex(bool get_temporary_value = false) const;
  138. /// Sets the connected status to true
  139. void Connect();
  140. /// Sets the connected status to false
  141. void Disconnect();
  142. /**
  143. * Is the emulated connected
  144. * @param get_temporary_value If true tmp_is_connected will be returned
  145. * @return true if the controller has the connected status
  146. */
  147. bool IsConnected(bool get_temporary_value = false) const;
  148. /// Returns true if vibration is enabled
  149. bool IsVibrationEnabled() const;
  150. /// Removes all callbacks created from input devices
  151. void UnloadInput();
  152. /**
  153. * Sets the emulated controller into configuring mode
  154. * This prevents the modification of the HID state of the emulated controller by input commands
  155. */
  156. void EnableConfiguration();
  157. /// Returns the emulated controller into normal mode, allowing the modification of the HID state
  158. void DisableConfiguration();
  159. /// Returns true if the emulated controller is in configuring mode
  160. bool IsConfiguring() const;
  161. /// Reload all input devices
  162. void ReloadInput();
  163. /// Overrides current mapped devices with the stored configuration and reloads all input devices
  164. void ReloadFromSettings();
  165. /// Saves the current mapped configuration
  166. void SaveCurrentConfig();
  167. /// Reverts any mapped changes made that weren't saved
  168. void RestoreConfig();
  169. /// Returns a vector of mapped devices from the mapped button and stick parameters
  170. std::vector<Common::ParamPackage> GetMappedDevices(EmulatedDeviceIndex device_index) const;
  171. // Returns the current mapped button device
  172. Common::ParamPackage GetButtonParam(std::size_t index) const;
  173. // Returns the current mapped stick device
  174. Common::ParamPackage GetStickParam(std::size_t index) const;
  175. // Returns the current mapped motion device
  176. Common::ParamPackage GetMotionParam(std::size_t index) const;
  177. /**
  178. * Updates the current mapped button device
  179. * @param param ParamPackage with controller data to be mapped
  180. */
  181. void SetButtonParam(std::size_t index, Common::ParamPackage param);
  182. /**
  183. * Updates the current mapped stick device
  184. * @param param ParamPackage with controller data to be mapped
  185. */
  186. void SetStickParam(std::size_t index, Common::ParamPackage param);
  187. /**
  188. * Updates the current mapped motion device
  189. * @param param ParamPackage with controller data to be mapped
  190. */
  191. void SetMotionParam(std::size_t index, Common::ParamPackage param);
  192. /// Returns the latest button status from the controller with parameters
  193. ButtonValues GetButtonsValues() const;
  194. /// Returns the latest analog stick status from the controller with parameters
  195. SticksValues GetSticksValues() const;
  196. /// Returns the latest trigger status from the controller with parameters
  197. TriggerValues GetTriggersValues() const;
  198. /// Returns the latest motion status from the controller with parameters
  199. ControllerMotionValues GetMotionValues() const;
  200. /// Returns the latest color status from the controller with parameters
  201. ColorValues GetColorsValues() const;
  202. /// Returns the latest battery status from the controller with parameters
  203. BatteryValues GetBatteryValues() const;
  204. /// Returns the latest status of button input for the npad service
  205. NpadButtonState GetNpadButtons() const;
  206. /// Returns the latest status of button input for the debug pad service
  207. DebugPadButton GetDebugPadButtons() const;
  208. /// Returns the latest status of stick input from the mouse
  209. AnalogSticks GetSticks() const;
  210. /// Returns the latest status of trigger input from the mouse
  211. NpadGcTriggerState GetTriggers() const;
  212. /// Returns the latest status of motion input from the mouse
  213. MotionState GetMotions() const;
  214. /// Returns the latest color value from the controller
  215. ControllerColors GetColors() const;
  216. /// Returns the latest battery status from the controller
  217. BatteryLevelState GetBattery() const;
  218. /**
  219. * Sends a specific vibration to the output device
  220. * @return returns true if vibration had no errors
  221. */
  222. bool SetVibration(std::size_t device_index, VibrationValue vibration);
  223. /**
  224. * Sends a small vibration to the output device
  225. * @return returns true if SetVibration was successfull
  226. */
  227. bool TestVibration(std::size_t device_index);
  228. /// Returns the led pattern corresponding to this emulated controller
  229. LedPattern GetLedPattern() const;
  230. /// Asks the output device to change the player led pattern
  231. void SetLedPattern();
  232. /**
  233. * Adds a callback to the list of events
  234. * @param update_callback A ConsoleUpdateCallback that will be triggered
  235. * @return an unique key corresponding to the callback index in the list
  236. */
  237. int SetCallback(ControllerUpdateCallback update_callback);
  238. /**
  239. * Removes a callback from the list stopping any future events to this object
  240. * @param key Key corresponding to the callback index in the list
  241. */
  242. void DeleteCallback(int key);
  243. private:
  244. /// creates input devices from params
  245. void LoadDevices();
  246. /// Set the params for TAS devices
  247. void LoadTASParams();
  248. /**
  249. * Updates the button status of the controller
  250. * @param callback A CallbackStatus containing the button status
  251. * @param index Button ID of the to be updated
  252. */
  253. void SetButton(Common::Input::CallbackStatus callback, std::size_t index, Common::UUID uuid);
  254. /**
  255. * Updates the analog stick status of the controller
  256. * @param callback A CallbackStatus containing the analog stick status
  257. * @param index stick ID of the to be updated
  258. */
  259. void SetStick(Common::Input::CallbackStatus callback, std::size_t index, Common::UUID uuid);
  260. /**
  261. * Updates the trigger status of the controller
  262. * @param callback A CallbackStatus containing the trigger status
  263. * @param index trigger ID of the to be updated
  264. */
  265. void SetTrigger(Common::Input::CallbackStatus callback, std::size_t index, Common::UUID uuid);
  266. /**
  267. * Updates the motion status of the controller
  268. * @param callback A CallbackStatus containing gyro and accelerometer data
  269. * @param index motion ID of the to be updated
  270. */
  271. void SetMotion(Common::Input::CallbackStatus callback, std::size_t index);
  272. /**
  273. * Updates the battery status of the controller
  274. * @param callback A CallbackStatus containing the battery status
  275. * @param index Button ID of the to be updated
  276. */
  277. void SetBattery(Common::Input::CallbackStatus callback, std::size_t index);
  278. /**
  279. * Triggers a callback that something has changed on the controller status
  280. * @param type Input type of the event to trigger
  281. * @param is_service_update indicates if this event should only be sent to HID services
  282. */
  283. void TriggerOnChange(ControllerTriggerType type, bool is_service_update);
  284. NpadIdType npad_id_type;
  285. NpadStyleIndex npad_type{NpadStyleIndex::None};
  286. bool is_connected{false};
  287. bool is_configuring{false};
  288. f32 motion_sensitivity{0.01f};
  289. bool force_update_motion{false};
  290. // Temporary values to avoid doing changes while the controller is in configuring mode
  291. NpadStyleIndex tmp_npad_type{NpadStyleIndex::None};
  292. bool tmp_is_connected{false};
  293. ButtonParams button_params;
  294. StickParams stick_params;
  295. ControllerMotionParams motion_params;
  296. TriggerParams trigger_params;
  297. BatteryParams battery_params;
  298. OutputParams output_params;
  299. ButtonDevices button_devices;
  300. StickDevices stick_devices;
  301. ControllerMotionDevices motion_devices;
  302. TriggerDevices trigger_devices;
  303. BatteryDevices battery_devices;
  304. OutputDevices output_devices;
  305. // TAS related variables
  306. ButtonParams tas_button_params;
  307. StickParams tas_stick_params;
  308. ButtonDevices tas_button_devices;
  309. StickDevices tas_stick_devices;
  310. mutable std::mutex mutex;
  311. std::unordered_map<int, ControllerUpdateCallback> callback_list;
  312. int last_callback_key = 0;
  313. // Stores the current status of all controller input
  314. ControllerStatus controller;
  315. };
  316. } // namespace Core::HID