emulated_controller.h 12 KB

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