input.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  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 <vector>
  10. #include "common/logging/log.h"
  11. #include "common/param_package.h"
  12. #include "common/uuid.h"
  13. namespace Common::Input {
  14. // Type of data that is expected to receive or send
  15. enum class InputType {
  16. None,
  17. Battery,
  18. Button,
  19. Stick,
  20. Analog,
  21. Trigger,
  22. Motion,
  23. Touch,
  24. Color,
  25. Vibration,
  26. Nfc,
  27. IrSensor,
  28. };
  29. // Internal battery charge level
  30. enum class BatteryLevel : u32 {
  31. None,
  32. Empty,
  33. Critical,
  34. Low,
  35. Medium,
  36. Full,
  37. Charging,
  38. };
  39. enum class PollingMode {
  40. // Constant polling of buttons, analogs and motion data
  41. Active,
  42. // Only update on button change, digital analogs
  43. Passive,
  44. // Enable near field communication polling
  45. NFC,
  46. // Enable infrared camera polling
  47. IR,
  48. // Enable ring controller polling
  49. Ring,
  50. };
  51. enum class CameraFormat {
  52. Size320x240,
  53. Size160x120,
  54. Size80x60,
  55. Size40x30,
  56. Size20x15,
  57. None,
  58. };
  59. // Different results that can happen from a device request
  60. enum class DriverResult {
  61. Success,
  62. WrongReply,
  63. Timeout,
  64. UnsupportedControllerType,
  65. HandleInUse,
  66. ErrorReadingData,
  67. ErrorWritingData,
  68. NoDeviceDetected,
  69. InvalidHandle,
  70. InvalidParameters,
  71. NotSupported,
  72. Disabled,
  73. Delayed,
  74. Unknown,
  75. };
  76. // Nfc reply from the controller
  77. enum class NfcState {
  78. Success,
  79. NewAmiibo,
  80. WaitingForAmiibo,
  81. AmiiboRemoved,
  82. InvalidTagType,
  83. NotSupported,
  84. WrongDeviceState,
  85. WriteFailed,
  86. Unknown,
  87. };
  88. // Hint for amplification curve to be used
  89. enum class VibrationAmplificationType {
  90. Linear,
  91. Exponential,
  92. };
  93. // Analog properties for calibration
  94. struct AnalogProperties {
  95. // Anything below this value will be detected as zero
  96. float deadzone{};
  97. // Anything above this values will be detected as one
  98. float range{1.0f};
  99. // Minimum value to be detected as active
  100. float threshold{0.5f};
  101. // Drift correction applied to the raw data
  102. float offset{};
  103. // Invert direction of the sensor data
  104. bool inverted{};
  105. // Invert the state if it's converted to a button
  106. bool inverted_button{};
  107. // Press once to activate, press again to release
  108. bool toggle{};
  109. };
  110. // Single analog sensor data
  111. struct AnalogStatus {
  112. float value{};
  113. float raw_value{};
  114. AnalogProperties properties{};
  115. };
  116. // Button data
  117. struct ButtonStatus {
  118. Common::UUID uuid{};
  119. bool value{};
  120. // Invert value of the button
  121. bool inverted{};
  122. // Press once to activate, press again to release
  123. bool toggle{};
  124. // Spams the button when active
  125. bool turbo{};
  126. // Internal lock for the toggle status
  127. bool locked{};
  128. };
  129. // Internal battery data
  130. using BatteryStatus = BatteryLevel;
  131. // Analog and digital joystick data
  132. struct StickStatus {
  133. Common::UUID uuid{};
  134. AnalogStatus x{};
  135. AnalogStatus y{};
  136. bool left{};
  137. bool right{};
  138. bool up{};
  139. bool down{};
  140. };
  141. // Analog and digital trigger data
  142. struct TriggerStatus {
  143. Common::UUID uuid{};
  144. AnalogStatus analog{};
  145. ButtonStatus pressed{};
  146. };
  147. // 3D vector representing motion input
  148. struct MotionSensor {
  149. AnalogStatus x{};
  150. AnalogStatus y{};
  151. AnalogStatus z{};
  152. };
  153. // Motion data used to calculate controller orientation
  154. struct MotionStatus {
  155. // Gyroscope vector measurement in radians/s.
  156. MotionSensor gyro{};
  157. // Acceleration vector measurement in G force
  158. MotionSensor accel{};
  159. // Time since last measurement in microseconds
  160. u64 delta_timestamp{};
  161. // Request to update after reading the value
  162. bool force_update{};
  163. };
  164. // Data of a single point on a touch screen
  165. struct TouchStatus {
  166. ButtonStatus pressed{};
  167. AnalogStatus x{};
  168. AnalogStatus y{};
  169. int id{};
  170. };
  171. // Physical controller color in RGB format
  172. struct BodyColorStatus {
  173. u32 body{};
  174. u32 buttons{};
  175. u32 left_grip{};
  176. u32 right_grip{};
  177. };
  178. // HD rumble data
  179. struct VibrationStatus {
  180. f32 low_amplitude{};
  181. f32 low_frequency{};
  182. f32 high_amplitude{};
  183. f32 high_frequency{};
  184. VibrationAmplificationType type;
  185. };
  186. // Physical controller LED pattern
  187. struct LedStatus {
  188. bool led_1{};
  189. bool led_2{};
  190. bool led_3{};
  191. bool led_4{};
  192. };
  193. // Raw data from camera
  194. struct CameraStatus {
  195. CameraFormat format{CameraFormat::None};
  196. std::vector<u8> data{};
  197. };
  198. struct NfcStatus {
  199. NfcState state{NfcState::Unknown};
  200. u8 uuid_length;
  201. u8 protocol;
  202. u8 tag_type;
  203. std::array<u8, 10> uuid;
  204. };
  205. struct MifareData {
  206. u8 command;
  207. u8 sector;
  208. std::array<u8, 0x6> key;
  209. std::array<u8, 0x10> data;
  210. };
  211. struct MifareRequest {
  212. std::array<MifareData, 0x10> data;
  213. };
  214. // List of buttons to be passed to Qt that can be translated
  215. enum class ButtonNames {
  216. Undefined,
  217. Invalid,
  218. // This will display the engine name instead of the button name
  219. Engine,
  220. // This will display the button by value instead of the button name
  221. Value,
  222. // Joycon button names
  223. ButtonLeft,
  224. ButtonRight,
  225. ButtonDown,
  226. ButtonUp,
  227. ButtonA,
  228. ButtonB,
  229. ButtonX,
  230. ButtonY,
  231. ButtonPlus,
  232. ButtonMinus,
  233. ButtonHome,
  234. ButtonCapture,
  235. ButtonStickL,
  236. ButtonStickR,
  237. TriggerL,
  238. TriggerZL,
  239. TriggerSL,
  240. TriggerR,
  241. TriggerZR,
  242. TriggerSR,
  243. // GC button names
  244. TriggerZ,
  245. ButtonStart,
  246. // DS4 button names
  247. L1,
  248. L2,
  249. L3,
  250. R1,
  251. R2,
  252. R3,
  253. Circle,
  254. Cross,
  255. Square,
  256. Triangle,
  257. Share,
  258. Options,
  259. Home,
  260. Touch,
  261. // Mouse buttons
  262. ButtonMouseWheel,
  263. ButtonBackward,
  264. ButtonForward,
  265. ButtonTask,
  266. ButtonExtra,
  267. };
  268. // Callback data consisting of an input type and the equivalent data status
  269. struct CallbackStatus {
  270. InputType type{InputType::None};
  271. ButtonStatus button_status{};
  272. StickStatus stick_status{};
  273. AnalogStatus analog_status{};
  274. TriggerStatus trigger_status{};
  275. MotionStatus motion_status{};
  276. TouchStatus touch_status{};
  277. BodyColorStatus color_status{};
  278. BatteryStatus battery_status{};
  279. VibrationStatus vibration_status{};
  280. CameraFormat camera_status{CameraFormat::None};
  281. NfcStatus nfc_status{};
  282. std::vector<u8> raw_data{};
  283. };
  284. // Triggered once every input change
  285. struct InputCallback {
  286. std::function<void(const CallbackStatus&)> on_change;
  287. };
  288. /// An abstract class template for an input device (a button, an analog input, etc.).
  289. class InputDevice {
  290. public:
  291. virtual ~InputDevice() = default;
  292. // Force input device to update data regardless of the current state
  293. virtual void ForceUpdate() {}
  294. // Sets the function to be triggered when input changes
  295. void SetCallback(InputCallback callback_) {
  296. callback = std::move(callback_);
  297. }
  298. // Triggers the function set in the callback
  299. void TriggerOnChange(const CallbackStatus& status) {
  300. if (callback.on_change) {
  301. callback.on_change(status);
  302. }
  303. }
  304. private:
  305. InputCallback callback;
  306. };
  307. /// An abstract class template for an output device (rumble, LED pattern, polling mode).
  308. class OutputDevice {
  309. public:
  310. virtual ~OutputDevice() = default;
  311. virtual DriverResult SetLED([[maybe_unused]] const LedStatus& led_status) {
  312. return DriverResult::NotSupported;
  313. }
  314. virtual DriverResult SetVibration([[maybe_unused]] const VibrationStatus& vibration_status) {
  315. return DriverResult::NotSupported;
  316. }
  317. virtual bool IsVibrationEnabled() {
  318. return false;
  319. }
  320. virtual DriverResult SetPollingMode([[maybe_unused]] PollingMode polling_mode) {
  321. return DriverResult::NotSupported;
  322. }
  323. virtual DriverResult SetCameraFormat([[maybe_unused]] CameraFormat camera_format) {
  324. return DriverResult::NotSupported;
  325. }
  326. virtual NfcState SupportsNfc() const {
  327. return NfcState::NotSupported;
  328. }
  329. virtual NfcState StartNfcPolling() {
  330. return NfcState::NotSupported;
  331. }
  332. virtual NfcState StopNfcPolling() {
  333. return NfcState::NotSupported;
  334. }
  335. virtual NfcState ReadAmiiboData([[maybe_unused]] std::vector<u8>& out_data) {
  336. return NfcState::NotSupported;
  337. }
  338. virtual NfcState WriteNfcData([[maybe_unused]] const std::vector<u8>& data) {
  339. return NfcState::NotSupported;
  340. }
  341. virtual NfcState ReadMifareData([[maybe_unused]] const MifareRequest& request,
  342. [[maybe_unused]] MifareRequest& out_data) {
  343. return NfcState::NotSupported;
  344. }
  345. virtual NfcState WriteMifareData([[maybe_unused]] const MifareRequest& request) {
  346. return NfcState::NotSupported;
  347. }
  348. };
  349. /// An abstract class template for a factory that can create input devices.
  350. template <typename InputDeviceType>
  351. class Factory {
  352. public:
  353. virtual ~Factory() = default;
  354. virtual std::unique_ptr<InputDeviceType> Create(const Common::ParamPackage&) = 0;
  355. };
  356. namespace Impl {
  357. template <typename InputDeviceType>
  358. using FactoryListType = std::unordered_map<std::string, std::shared_ptr<Factory<InputDeviceType>>>;
  359. template <typename InputDeviceType>
  360. struct FactoryList {
  361. static FactoryListType<InputDeviceType> list;
  362. };
  363. template <typename InputDeviceType>
  364. FactoryListType<InputDeviceType> FactoryList<InputDeviceType>::list;
  365. } // namespace Impl
  366. /**
  367. * Registers an input device factory.
  368. * @tparam InputDeviceType the type of input devices the factory can create
  369. * @param name the name of the factory. Will be used to match the "engine" parameter when creating
  370. * a device
  371. * @param factory the factory object to register
  372. */
  373. template <typename InputDeviceType>
  374. void RegisterFactory(const std::string& name, std::shared_ptr<Factory<InputDeviceType>> factory) {
  375. auto pair = std::make_pair(name, std::move(factory));
  376. if (!Impl::FactoryList<InputDeviceType>::list.insert(std::move(pair)).second) {
  377. LOG_ERROR(Input, "Factory '{}' already registered", name);
  378. }
  379. }
  380. inline void RegisterInputFactory(const std::string& name,
  381. std::shared_ptr<Factory<InputDevice>> factory) {
  382. RegisterFactory<InputDevice>(name, std::move(factory));
  383. }
  384. inline void RegisterOutputFactory(const std::string& name,
  385. std::shared_ptr<Factory<OutputDevice>> factory) {
  386. RegisterFactory<OutputDevice>(name, std::move(factory));
  387. }
  388. /**
  389. * Unregisters an input device factory.
  390. * @tparam InputDeviceType the type of input devices the factory can create
  391. * @param name the name of the factory to unregister
  392. */
  393. template <typename InputDeviceType>
  394. void UnregisterFactory(const std::string& name) {
  395. if (Impl::FactoryList<InputDeviceType>::list.erase(name) == 0) {
  396. LOG_ERROR(Input, "Factory '{}' not registered", name);
  397. }
  398. }
  399. inline void UnregisterInputFactory(const std::string& name) {
  400. UnregisterFactory<InputDevice>(name);
  401. }
  402. inline void UnregisterOutputFactory(const std::string& name) {
  403. UnregisterFactory<OutputDevice>(name);
  404. }
  405. /**
  406. * Create an input device from given parameters.
  407. * @tparam InputDeviceType the type of input devices to create
  408. * @param params a serialized ParamPackage string that contains all parameters for creating the
  409. * device
  410. */
  411. template <typename InputDeviceType>
  412. std::unique_ptr<InputDeviceType> CreateDeviceFromString(const std::string& params) {
  413. const Common::ParamPackage package(params);
  414. const std::string engine = package.Get("engine", "null");
  415. const auto& factory_list = Impl::FactoryList<InputDeviceType>::list;
  416. const auto pair = factory_list.find(engine);
  417. if (pair == factory_list.end()) {
  418. if (engine != "null") {
  419. LOG_ERROR(Input, "Unknown engine name: {}", engine);
  420. }
  421. return std::make_unique<InputDeviceType>();
  422. }
  423. return pair->second->Create(package);
  424. }
  425. inline std::unique_ptr<InputDevice> CreateInputDeviceFromString(const std::string& params) {
  426. return CreateDeviceFromString<InputDevice>(params);
  427. }
  428. inline std::unique_ptr<OutputDevice> CreateOutputDeviceFromString(const std::string& params) {
  429. return CreateDeviceFromString<OutputDevice>(params);
  430. }
  431. /**
  432. * Create an input device from given parameters.
  433. * @tparam InputDeviceType the type of input devices to create
  434. * @param package A ParamPackage that contains all parameters for creating the device
  435. */
  436. template <typename InputDeviceType>
  437. std::unique_ptr<InputDeviceType> CreateDevice(const ParamPackage& package) {
  438. const std::string engine = package.Get("engine", "null");
  439. const auto& factory_list = Impl::FactoryList<InputDeviceType>::list;
  440. const auto pair = factory_list.find(engine);
  441. if (pair == factory_list.end()) {
  442. if (engine != "null") {
  443. LOG_ERROR(Input, "Unknown engine name: {}", engine);
  444. }
  445. return std::make_unique<InputDeviceType>();
  446. }
  447. return pair->second->Create(package);
  448. }
  449. inline std::unique_ptr<InputDevice> CreateInputDevice(const ParamPackage& package) {
  450. return CreateDevice<InputDevice>(package);
  451. }
  452. inline std::unique_ptr<OutputDevice> CreateOutputDevice(const ParamPackage& package) {
  453. return CreateDevice<OutputDevice>(package);
  454. }
  455. } // namespace Common::Input