input.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. // SPDX-FileCopyrightText: 2017 Citra Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <functional>
  5. #include <memory>
  6. #include <string>
  7. #include <unordered_map>
  8. #include <utility>
  9. #include "common/logging/log.h"
  10. #include "common/param_package.h"
  11. #include "common/uuid.h"
  12. namespace Common::Input {
  13. // Type of data that is expected to recieve or send
  14. enum class InputType {
  15. None,
  16. Battery,
  17. Button,
  18. Stick,
  19. Analog,
  20. Trigger,
  21. Motion,
  22. Touch,
  23. Color,
  24. Vibration,
  25. Nfc,
  26. IrSensor,
  27. };
  28. // Internal battery charge level
  29. enum class BatteryLevel : u32 {
  30. None,
  31. Empty,
  32. Critical,
  33. Low,
  34. Medium,
  35. Full,
  36. Charging,
  37. };
  38. enum class PollingMode {
  39. // Constant polling of buttons, analogs and motion data
  40. Active,
  41. // Only update on button change, digital analogs
  42. Pasive,
  43. // Enable near field communication polling
  44. NFC,
  45. // Enable infrared camera polling
  46. IR,
  47. };
  48. enum class CameraFormat {
  49. Size320x240,
  50. Size160x120,
  51. Size80x60,
  52. Size40x30,
  53. Size20x15,
  54. None,
  55. };
  56. // Vibration reply from the controller
  57. enum class VibrationError {
  58. None,
  59. NotSupported,
  60. Disabled,
  61. Unknown,
  62. };
  63. // Polling mode reply from the controller
  64. enum class PollingError {
  65. None,
  66. NotSupported,
  67. Unknown,
  68. };
  69. // Ir camera reply from the controller
  70. enum class CameraError {
  71. None,
  72. NotSupported,
  73. Unknown,
  74. };
  75. // Hint for amplification curve to be used
  76. enum class VibrationAmplificationType {
  77. Linear,
  78. Exponential,
  79. Test,
  80. };
  81. // Analog properties for calibration
  82. struct AnalogProperties {
  83. // Anything below this value will be detected as zero
  84. float deadzone{};
  85. // Anyting above this values will be detected as one
  86. float range{1.0f};
  87. // Minimum value to be detected as active
  88. float threshold{0.5f};
  89. // Drift correction applied to the raw data
  90. float offset{};
  91. // Invert direction of the sensor data
  92. bool inverted{};
  93. // Press once to activate, press again to release
  94. bool toggle{};
  95. };
  96. // Single analog sensor data
  97. struct AnalogStatus {
  98. float value{};
  99. float raw_value{};
  100. AnalogProperties properties{};
  101. };
  102. // Button data
  103. struct ButtonStatus {
  104. Common::UUID uuid{};
  105. bool value{};
  106. // Invert value of the button
  107. bool inverted{};
  108. // Press once to activate, press again to release
  109. bool toggle{};
  110. // Internal lock for the toggle status
  111. bool locked{};
  112. };
  113. // Internal battery data
  114. using BatteryStatus = BatteryLevel;
  115. // Analog and digital joystick data
  116. struct StickStatus {
  117. Common::UUID uuid{};
  118. AnalogStatus x{};
  119. AnalogStatus y{};
  120. bool left{};
  121. bool right{};
  122. bool up{};
  123. bool down{};
  124. };
  125. // Analog and digital trigger data
  126. struct TriggerStatus {
  127. Common::UUID uuid{};
  128. AnalogStatus analog{};
  129. ButtonStatus pressed{};
  130. };
  131. // 3D vector representing motion input
  132. struct MotionSensor {
  133. AnalogStatus x{};
  134. AnalogStatus y{};
  135. AnalogStatus z{};
  136. };
  137. // Motion data used to calculate controller orientation
  138. struct MotionStatus {
  139. // Gyroscope vector measurement in radians/s.
  140. MotionSensor gyro{};
  141. // Acceleration vector measurement in G force
  142. MotionSensor accel{};
  143. // Time since last measurement in microseconds
  144. u64 delta_timestamp{};
  145. // Request to update after reading the value
  146. bool force_update{};
  147. };
  148. // Data of a single point on a touch screen
  149. struct TouchStatus {
  150. ButtonStatus pressed{};
  151. AnalogStatus x{};
  152. AnalogStatus y{};
  153. int id{};
  154. };
  155. // Physical controller color in RGB format
  156. struct BodyColorStatus {
  157. u32 body{};
  158. u32 buttons{};
  159. };
  160. // HD rumble data
  161. struct VibrationStatus {
  162. f32 low_amplitude{};
  163. f32 low_frequency{};
  164. f32 high_amplitude{};
  165. f32 high_frequency{};
  166. VibrationAmplificationType type;
  167. };
  168. // Physical controller LED pattern
  169. struct LedStatus {
  170. bool led_1{};
  171. bool led_2{};
  172. bool led_3{};
  173. bool led_4{};
  174. };
  175. // Raw data fom camera
  176. struct CameraStatus {
  177. CameraFormat format{CameraFormat::None};
  178. std::vector<u8> data{};
  179. };
  180. // List of buttons to be passed to Qt that can be translated
  181. enum class ButtonNames {
  182. Undefined,
  183. Invalid,
  184. // This will display the engine name instead of the button name
  185. Engine,
  186. // This will display the button by value instead of the button name
  187. Value,
  188. ButtonLeft,
  189. ButtonRight,
  190. ButtonDown,
  191. ButtonUp,
  192. TriggerZ,
  193. TriggerR,
  194. TriggerL,
  195. ButtonA,
  196. ButtonB,
  197. ButtonX,
  198. ButtonY,
  199. ButtonStart,
  200. // DS4 button names
  201. L1,
  202. L2,
  203. L3,
  204. R1,
  205. R2,
  206. R3,
  207. Circle,
  208. Cross,
  209. Square,
  210. Triangle,
  211. Share,
  212. Options,
  213. Home,
  214. Touch,
  215. // Mouse buttons
  216. ButtonMouseWheel,
  217. ButtonBackward,
  218. ButtonForward,
  219. ButtonTask,
  220. ButtonExtra,
  221. };
  222. // Callback data consisting of an input type and the equivalent data status
  223. struct CallbackStatus {
  224. InputType type{InputType::None};
  225. ButtonStatus button_status{};
  226. StickStatus stick_status{};
  227. AnalogStatus analog_status{};
  228. TriggerStatus trigger_status{};
  229. MotionStatus motion_status{};
  230. TouchStatus touch_status{};
  231. BodyColorStatus color_status{};
  232. BatteryStatus battery_status{};
  233. VibrationStatus vibration_status{};
  234. CameraStatus camera_status{};
  235. };
  236. // Triggered once every input change
  237. struct InputCallback {
  238. std::function<void(const CallbackStatus&)> on_change;
  239. };
  240. /// An abstract class template for an input device (a button, an analog input, etc.).
  241. class InputDevice {
  242. public:
  243. virtual ~InputDevice() = default;
  244. // Request input device to update if necessary
  245. virtual void SoftUpdate() {}
  246. // Force input device to update data regardless of the current state
  247. virtual void ForceUpdate() {}
  248. // Sets the function to be triggered when input changes
  249. void SetCallback(InputCallback callback_) {
  250. callback = std::move(callback_);
  251. }
  252. // Triggers the function set in the callback
  253. void TriggerOnChange(const CallbackStatus& status) {
  254. if (callback.on_change) {
  255. callback.on_change(status);
  256. }
  257. }
  258. private:
  259. InputCallback callback;
  260. };
  261. /// An abstract class template for an output device (rumble, LED pattern, polling mode).
  262. class OutputDevice {
  263. public:
  264. virtual ~OutputDevice() = default;
  265. virtual void SetLED([[maybe_unused]] const LedStatus& led_status) {}
  266. virtual VibrationError SetVibration([[maybe_unused]] const VibrationStatus& vibration_status) {
  267. return VibrationError::NotSupported;
  268. }
  269. virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) {
  270. return PollingError::NotSupported;
  271. }
  272. virtual CameraError SetCameraFormat([[maybe_unused]] CameraFormat camera_format) {
  273. return CameraError::NotSupported;
  274. }
  275. };
  276. /// An abstract class template for a factory that can create input devices.
  277. template <typename InputDeviceType>
  278. class Factory {
  279. public:
  280. virtual ~Factory() = default;
  281. virtual std::unique_ptr<InputDeviceType> Create(const Common::ParamPackage&) = 0;
  282. };
  283. namespace Impl {
  284. template <typename InputDeviceType>
  285. using FactoryListType = std::unordered_map<std::string, std::shared_ptr<Factory<InputDeviceType>>>;
  286. template <typename InputDeviceType>
  287. struct FactoryList {
  288. static FactoryListType<InputDeviceType> list;
  289. };
  290. template <typename InputDeviceType>
  291. FactoryListType<InputDeviceType> FactoryList<InputDeviceType>::list;
  292. } // namespace Impl
  293. /**
  294. * Registers an input device factory.
  295. * @tparam InputDeviceType the type of input devices the factory can create
  296. * @param name the name of the factory. Will be used to match the "engine" parameter when creating
  297. * a device
  298. * @param factory the factory object to register
  299. */
  300. template <typename InputDeviceType>
  301. void RegisterFactory(const std::string& name, std::shared_ptr<Factory<InputDeviceType>> factory) {
  302. auto pair = std::make_pair(name, std::move(factory));
  303. if (!Impl::FactoryList<InputDeviceType>::list.insert(std::move(pair)).second) {
  304. LOG_ERROR(Input, "Factory '{}' already registered", name);
  305. }
  306. }
  307. /**
  308. * Unregisters an input device factory.
  309. * @tparam InputDeviceType the type of input devices the factory can create
  310. * @param name the name of the factory to unregister
  311. */
  312. template <typename InputDeviceType>
  313. void UnregisterFactory(const std::string& name) {
  314. if (Impl::FactoryList<InputDeviceType>::list.erase(name) == 0) {
  315. LOG_ERROR(Input, "Factory '{}' not registered", name);
  316. }
  317. }
  318. /**
  319. * Create an input device from given paramters.
  320. * @tparam InputDeviceType the type of input devices to create
  321. * @param params a serialized ParamPackage string that contains all parameters for creating the
  322. * device
  323. */
  324. template <typename InputDeviceType>
  325. std::unique_ptr<InputDeviceType> CreateDeviceFromString(const std::string& params) {
  326. const Common::ParamPackage package(params);
  327. const std::string engine = package.Get("engine", "null");
  328. const auto& factory_list = Impl::FactoryList<InputDeviceType>::list;
  329. const auto pair = factory_list.find(engine);
  330. if (pair == factory_list.end()) {
  331. if (engine != "null") {
  332. LOG_ERROR(Input, "Unknown engine name: {}", engine);
  333. }
  334. return std::make_unique<InputDeviceType>();
  335. }
  336. return pair->second->Create(package);
  337. }
  338. /**
  339. * Create an input device from given paramters.
  340. * @tparam InputDeviceType the type of input devices to create
  341. * @param A ParamPackage that contains all parameters for creating the device
  342. */
  343. template <typename InputDeviceType>
  344. std::unique_ptr<InputDeviceType> CreateDevice(const Common::ParamPackage package) {
  345. const std::string engine = package.Get("engine", "null");
  346. const auto& factory_list = Impl::FactoryList<InputDeviceType>::list;
  347. const auto pair = factory_list.find(engine);
  348. if (pair == factory_list.end()) {
  349. if (engine != "null") {
  350. LOG_ERROR(Input, "Unknown engine name: {}", engine);
  351. }
  352. return std::make_unique<InputDeviceType>();
  353. }
  354. return pair->second->Create(package);
  355. }
  356. } // namespace Common::Input