input_poller.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971
  1. // Copyright 2021 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included
  4. #include "common/common_types.h"
  5. #include "common/input.h"
  6. #include "input_common/input_engine.h"
  7. #include "input_common/input_poller.h"
  8. namespace InputCommon {
  9. class DummyInput final : public Common::Input::InputDevice {
  10. public:
  11. explicit DummyInput() {}
  12. ~DummyInput() {}
  13. };
  14. class InputFromButton final : public Common::Input::InputDevice {
  15. public:
  16. explicit InputFromButton(PadIdentifier identifier_, int button_, bool toggle_, bool inverted_,
  17. InputEngine* input_engine_)
  18. : identifier(identifier_), button(button_), toggle(toggle_), inverted(inverted_),
  19. input_engine(input_engine_) {
  20. UpdateCallback engine_callback{[this]() { OnChange(); }};
  21. const InputIdentifier input_identifier{
  22. .identifier = identifier,
  23. .type = EngineInputType::Button,
  24. .index = button,
  25. .callback = engine_callback,
  26. };
  27. last_button_value = false;
  28. callback_key = input_engine->SetCallback(input_identifier);
  29. }
  30. ~InputFromButton() {
  31. input_engine->DeleteCallback(callback_key);
  32. }
  33. Common::Input::ButtonStatus GetStatus() const {
  34. return {
  35. .value = input_engine->GetButton(identifier, button),
  36. .inverted = inverted,
  37. .toggle = toggle,
  38. };
  39. }
  40. void ForceUpdate() {
  41. const Common::Input::CallbackStatus status{
  42. .type = Common::Input::InputType::Button,
  43. .button_status = GetStatus(),
  44. };
  45. last_button_value = status.button_status.value;
  46. TriggerOnChange(status);
  47. }
  48. void OnChange() {
  49. const Common::Input::CallbackStatus status{
  50. .type = Common::Input::InputType::Button,
  51. .button_status = GetStatus(),
  52. };
  53. if (status.button_status.value != last_button_value) {
  54. last_button_value = status.button_status.value;
  55. TriggerOnChange(status);
  56. }
  57. }
  58. private:
  59. const PadIdentifier identifier;
  60. const int button;
  61. const bool toggle;
  62. const bool inverted;
  63. int callback_key;
  64. bool last_button_value;
  65. InputEngine* input_engine;
  66. };
  67. class InputFromHatButton final : public Common::Input::InputDevice {
  68. public:
  69. explicit InputFromHatButton(PadIdentifier identifier_, int button_, u8 direction_, bool toggle_,
  70. bool inverted_, InputEngine* input_engine_)
  71. : identifier(identifier_), button(button_), direction(direction_), toggle(toggle_),
  72. inverted(inverted_), input_engine(input_engine_) {
  73. UpdateCallback engine_callback{[this]() { OnChange(); }};
  74. const InputIdentifier input_identifier{
  75. .identifier = identifier,
  76. .type = EngineInputType::HatButton,
  77. .index = button,
  78. .callback = engine_callback,
  79. };
  80. last_button_value = false;
  81. callback_key = input_engine->SetCallback(input_identifier);
  82. }
  83. ~InputFromHatButton() {
  84. input_engine->DeleteCallback(callback_key);
  85. }
  86. Common::Input::ButtonStatus GetStatus() const {
  87. return {
  88. .value = input_engine->GetHatButton(identifier, button, direction),
  89. .inverted = inverted,
  90. .toggle = toggle,
  91. };
  92. }
  93. void ForceUpdate() {
  94. const Common::Input::CallbackStatus status{
  95. .type = Common::Input::InputType::Button,
  96. .button_status = GetStatus(),
  97. };
  98. last_button_value = status.button_status.value;
  99. TriggerOnChange(status);
  100. }
  101. void OnChange() {
  102. const Common::Input::CallbackStatus status{
  103. .type = Common::Input::InputType::Button,
  104. .button_status = GetStatus(),
  105. };
  106. if (status.button_status.value != last_button_value) {
  107. last_button_value = status.button_status.value;
  108. TriggerOnChange(status);
  109. }
  110. }
  111. private:
  112. const PadIdentifier identifier;
  113. const int button;
  114. const u8 direction;
  115. const bool toggle;
  116. const bool inverted;
  117. int callback_key;
  118. bool last_button_value;
  119. InputEngine* input_engine;
  120. };
  121. class InputFromStick final : public Common::Input::InputDevice {
  122. public:
  123. explicit InputFromStick(PadIdentifier identifier_, int axis_x_, int axis_y_,
  124. Common::Input::AnalogProperties properties_x_,
  125. Common::Input::AnalogProperties properties_y_,
  126. InputEngine* input_engine_)
  127. : identifier(identifier_), axis_x(axis_x_), axis_y(axis_y_), properties_x(properties_x_),
  128. properties_y(properties_y_),
  129. input_engine(input_engine_), invert_axis_y{input_engine_->GetEngineName() == "sdl"} {
  130. UpdateCallback engine_callback{[this]() { OnChange(); }};
  131. const InputIdentifier x_input_identifier{
  132. .identifier = identifier,
  133. .type = EngineInputType::Analog,
  134. .index = axis_x,
  135. .callback = engine_callback,
  136. };
  137. const InputIdentifier y_input_identifier{
  138. .identifier = identifier,
  139. .type = EngineInputType::Analog,
  140. .index = axis_y,
  141. .callback = engine_callback,
  142. };
  143. last_axis_x_value = 0.0f;
  144. last_axis_y_value = 0.0f;
  145. callback_key_x = input_engine->SetCallback(x_input_identifier);
  146. callback_key_y = input_engine->SetCallback(y_input_identifier);
  147. }
  148. ~InputFromStick() {
  149. input_engine->DeleteCallback(callback_key_x);
  150. input_engine->DeleteCallback(callback_key_y);
  151. }
  152. Common::Input::StickStatus GetStatus() const {
  153. Common::Input::StickStatus status;
  154. status.x = {
  155. .raw_value = input_engine->GetAxis(identifier, axis_x),
  156. .properties = properties_x,
  157. };
  158. status.y = {
  159. .raw_value = input_engine->GetAxis(identifier, axis_y),
  160. .properties = properties_y,
  161. };
  162. // This is a workaround too keep compatibility with old yuzu versions. Vertical axis is
  163. // inverted on SDL compared to Nintendo
  164. if (invert_axis_y) {
  165. status.y.raw_value = -status.y.raw_value;
  166. }
  167. return status;
  168. }
  169. void ForceUpdate() {
  170. const Common::Input::CallbackStatus status{
  171. .type = Common::Input::InputType::Stick,
  172. .stick_status = GetStatus(),
  173. };
  174. last_axis_x_value = status.stick_status.x.raw_value;
  175. last_axis_y_value = status.stick_status.y.raw_value;
  176. TriggerOnChange(status);
  177. }
  178. void OnChange() {
  179. const Common::Input::CallbackStatus status{
  180. .type = Common::Input::InputType::Stick,
  181. .stick_status = GetStatus(),
  182. };
  183. if (status.stick_status.x.raw_value != last_axis_x_value ||
  184. status.stick_status.y.raw_value != last_axis_y_value) {
  185. last_axis_x_value = status.stick_status.x.raw_value;
  186. last_axis_y_value = status.stick_status.y.raw_value;
  187. TriggerOnChange(status);
  188. }
  189. }
  190. private:
  191. const PadIdentifier identifier;
  192. const int axis_x;
  193. const int axis_y;
  194. const Common::Input::AnalogProperties properties_x;
  195. const Common::Input::AnalogProperties properties_y;
  196. int callback_key_x;
  197. int callback_key_y;
  198. float last_axis_x_value;
  199. float last_axis_y_value;
  200. InputEngine* input_engine;
  201. const bool invert_axis_y;
  202. };
  203. class InputFromTouch final : public Common::Input::InputDevice {
  204. public:
  205. explicit InputFromTouch(PadIdentifier identifier_, int touch_id_, int button_, bool toggle_,
  206. bool inverted_, int axis_x_, int axis_y_,
  207. Common::Input::AnalogProperties properties_x_,
  208. Common::Input::AnalogProperties properties_y_,
  209. InputEngine* input_engine_)
  210. : identifier(identifier_), touch_id(touch_id_), button(button_), toggle(toggle_),
  211. inverted(inverted_), axis_x(axis_x_), axis_y(axis_y_), properties_x(properties_x_),
  212. properties_y(properties_y_), input_engine(input_engine_) {
  213. UpdateCallback engine_callback{[this]() { OnChange(); }};
  214. const InputIdentifier button_input_identifier{
  215. .identifier = identifier,
  216. .type = EngineInputType::Button,
  217. .index = button,
  218. .callback = engine_callback,
  219. };
  220. const InputIdentifier x_input_identifier{
  221. .identifier = identifier,
  222. .type = EngineInputType::Analog,
  223. .index = axis_x,
  224. .callback = engine_callback,
  225. };
  226. const InputIdentifier y_input_identifier{
  227. .identifier = identifier,
  228. .type = EngineInputType::Analog,
  229. .index = axis_y,
  230. .callback = engine_callback,
  231. };
  232. last_axis_x_value = 0.0f;
  233. last_axis_y_value = 0.0f;
  234. last_button_value = false;
  235. callback_key_button = input_engine->SetCallback(button_input_identifier);
  236. callback_key_x = input_engine->SetCallback(x_input_identifier);
  237. callback_key_y = input_engine->SetCallback(y_input_identifier);
  238. }
  239. ~InputFromTouch() {
  240. input_engine->DeleteCallback(callback_key_button);
  241. input_engine->DeleteCallback(callback_key_x);
  242. input_engine->DeleteCallback(callback_key_y);
  243. }
  244. Common::Input::TouchStatus GetStatus() const {
  245. Common::Input::TouchStatus status;
  246. status.id = touch_id;
  247. status.pressed = {
  248. .value = input_engine->GetButton(identifier, button),
  249. .inverted = inverted,
  250. .toggle = toggle,
  251. };
  252. status.x = {
  253. .raw_value = input_engine->GetAxis(identifier, axis_x),
  254. .properties = properties_x,
  255. };
  256. status.y = {
  257. .raw_value = input_engine->GetAxis(identifier, axis_y),
  258. .properties = properties_y,
  259. };
  260. return status;
  261. }
  262. void OnChange() {
  263. const Common::Input::CallbackStatus status{
  264. .type = Common::Input::InputType::Touch,
  265. .touch_status = GetStatus(),
  266. };
  267. if (status.touch_status.x.raw_value != last_axis_x_value ||
  268. status.touch_status.y.raw_value != last_axis_y_value ||
  269. status.touch_status.pressed.value != last_button_value) {
  270. last_axis_x_value = status.touch_status.x.raw_value;
  271. last_axis_y_value = status.touch_status.y.raw_value;
  272. last_button_value = status.touch_status.pressed.value;
  273. TriggerOnChange(status);
  274. }
  275. }
  276. private:
  277. const PadIdentifier identifier;
  278. const int touch_id;
  279. const int button;
  280. const bool toggle;
  281. const bool inverted;
  282. const int axis_x;
  283. const int axis_y;
  284. const Common::Input::AnalogProperties properties_x;
  285. const Common::Input::AnalogProperties properties_y;
  286. int callback_key_button;
  287. int callback_key_x;
  288. int callback_key_y;
  289. bool last_button_value;
  290. float last_axis_x_value;
  291. float last_axis_y_value;
  292. InputEngine* input_engine;
  293. };
  294. class InputFromTrigger final : public Common::Input::InputDevice {
  295. public:
  296. explicit InputFromTrigger(PadIdentifier identifier_, int button_, bool toggle_, bool inverted_,
  297. int axis_, Common::Input::AnalogProperties properties_,
  298. InputEngine* input_engine_)
  299. : identifier(identifier_), button(button_), toggle(toggle_), inverted(inverted_),
  300. axis(axis_), properties(properties_), input_engine(input_engine_) {
  301. UpdateCallback engine_callback{[this]() { OnChange(); }};
  302. const InputIdentifier button_input_identifier{
  303. .identifier = identifier,
  304. .type = EngineInputType::Button,
  305. .index = button,
  306. .callback = engine_callback,
  307. };
  308. const InputIdentifier axis_input_identifier{
  309. .identifier = identifier,
  310. .type = EngineInputType::Analog,
  311. .index = axis,
  312. .callback = engine_callback,
  313. };
  314. last_axis_value = 0.0f;
  315. last_button_value = false;
  316. callback_key_button = input_engine->SetCallback(button_input_identifier);
  317. axis_callback_key = input_engine->SetCallback(axis_input_identifier);
  318. }
  319. ~InputFromTrigger() {
  320. input_engine->DeleteCallback(callback_key_button);
  321. input_engine->DeleteCallback(axis_callback_key);
  322. }
  323. Common::Input::TriggerStatus GetStatus() const {
  324. const Common::Input::AnalogStatus analog_status{
  325. .raw_value = input_engine->GetAxis(identifier, axis),
  326. .properties = properties,
  327. };
  328. const Common::Input::ButtonStatus button_status{
  329. .value = input_engine->GetButton(identifier, button),
  330. .inverted = inverted,
  331. .toggle = toggle,
  332. };
  333. return {
  334. .analog = analog_status,
  335. .pressed = button_status,
  336. };
  337. }
  338. void OnChange() {
  339. const Common::Input::CallbackStatus status{
  340. .type = Common::Input::InputType::Trigger,
  341. .trigger_status = GetStatus(),
  342. };
  343. if (status.trigger_status.analog.raw_value != last_axis_value ||
  344. status.trigger_status.pressed.value != last_button_value) {
  345. last_axis_value = status.trigger_status.analog.raw_value;
  346. last_button_value = status.trigger_status.pressed.value;
  347. TriggerOnChange(status);
  348. }
  349. }
  350. private:
  351. const PadIdentifier identifier;
  352. const int button;
  353. const bool toggle;
  354. const bool inverted;
  355. const int axis;
  356. const Common::Input::AnalogProperties properties;
  357. int callback_key_button;
  358. int axis_callback_key;
  359. bool last_button_value;
  360. float last_axis_value;
  361. InputEngine* input_engine;
  362. };
  363. class InputFromAnalog final : public Common::Input::InputDevice {
  364. public:
  365. explicit InputFromAnalog(PadIdentifier identifier_, int axis_,
  366. Common::Input::AnalogProperties properties_,
  367. InputEngine* input_engine_)
  368. : identifier(identifier_), axis(axis_), properties(properties_),
  369. input_engine(input_engine_) {
  370. UpdateCallback engine_callback{[this]() { OnChange(); }};
  371. const InputIdentifier input_identifier{
  372. .identifier = identifier,
  373. .type = EngineInputType::Analog,
  374. .index = axis,
  375. .callback = engine_callback,
  376. };
  377. last_axis_value = 0.0f;
  378. callback_key = input_engine->SetCallback(input_identifier);
  379. }
  380. ~InputFromAnalog() {
  381. input_engine->DeleteCallback(callback_key);
  382. }
  383. Common::Input::AnalogStatus GetStatus() const {
  384. return {
  385. .raw_value = input_engine->GetAxis(identifier, axis),
  386. .properties = properties,
  387. };
  388. }
  389. void OnChange() {
  390. const Common::Input::CallbackStatus status{
  391. .type = Common::Input::InputType::Analog,
  392. .analog_status = GetStatus(),
  393. };
  394. if (status.analog_status.raw_value != last_axis_value) {
  395. last_axis_value = status.analog_status.raw_value;
  396. TriggerOnChange(status);
  397. }
  398. }
  399. private:
  400. const PadIdentifier identifier;
  401. const int axis;
  402. const Common::Input::AnalogProperties properties;
  403. int callback_key;
  404. float last_axis_value;
  405. InputEngine* input_engine;
  406. };
  407. class InputFromBattery final : public Common::Input::InputDevice {
  408. public:
  409. explicit InputFromBattery(PadIdentifier identifier_, InputEngine* input_engine_)
  410. : identifier(identifier_), input_engine(input_engine_) {
  411. UpdateCallback engine_callback{[this]() { OnChange(); }};
  412. const InputIdentifier input_identifier{
  413. .identifier = identifier,
  414. .type = EngineInputType::Battery,
  415. .index = 0,
  416. .callback = engine_callback,
  417. };
  418. last_battery_value = Common::Input::BatteryStatus::Charging;
  419. callback_key = input_engine->SetCallback(input_identifier);
  420. }
  421. ~InputFromBattery() {
  422. input_engine->DeleteCallback(callback_key);
  423. }
  424. Common::Input::BatteryStatus GetStatus() const {
  425. return static_cast<Common::Input::BatteryLevel>(input_engine->GetBattery(identifier));
  426. }
  427. void ForceUpdate() {
  428. const Common::Input::CallbackStatus status{
  429. .type = Common::Input::InputType::Battery,
  430. .battery_status = GetStatus(),
  431. };
  432. last_battery_value = status.battery_status;
  433. TriggerOnChange(status);
  434. }
  435. void OnChange() {
  436. const Common::Input::CallbackStatus status{
  437. .type = Common::Input::InputType::Battery,
  438. .battery_status = GetStatus(),
  439. };
  440. if (status.battery_status != last_battery_value) {
  441. last_battery_value = status.battery_status;
  442. TriggerOnChange(status);
  443. }
  444. }
  445. private:
  446. const PadIdentifier identifier;
  447. int callback_key;
  448. Common::Input::BatteryStatus last_battery_value;
  449. InputEngine* input_engine;
  450. };
  451. class InputFromMotion final : public Common::Input::InputDevice {
  452. public:
  453. explicit InputFromMotion(PadIdentifier identifier_, int motion_sensor_,
  454. InputEngine* input_engine_)
  455. : identifier(identifier_), motion_sensor(motion_sensor_), input_engine(input_engine_) {
  456. UpdateCallback engine_callback{[this]() { OnChange(); }};
  457. const InputIdentifier input_identifier{
  458. .identifier = identifier,
  459. .type = EngineInputType::Motion,
  460. .index = motion_sensor,
  461. .callback = engine_callback,
  462. };
  463. callback_key = input_engine->SetCallback(input_identifier);
  464. }
  465. ~InputFromMotion() {
  466. input_engine->DeleteCallback(callback_key);
  467. }
  468. Common::Input::MotionStatus GetStatus() const {
  469. const auto basic_motion = input_engine->GetMotion(identifier, motion_sensor);
  470. Common::Input::MotionStatus status{};
  471. const Common::Input::AnalogProperties properties = {
  472. .deadzone = 0.001f,
  473. .range = 1.0f,
  474. .offset = 0.0f,
  475. };
  476. status.accel.x = {.raw_value = basic_motion.accel_x, .properties = properties};
  477. status.accel.y = {.raw_value = basic_motion.accel_y, .properties = properties};
  478. status.accel.z = {.raw_value = basic_motion.accel_z, .properties = properties};
  479. status.gyro.x = {.raw_value = basic_motion.gyro_x, .properties = properties};
  480. status.gyro.y = {.raw_value = basic_motion.gyro_y, .properties = properties};
  481. status.gyro.z = {.raw_value = basic_motion.gyro_z, .properties = properties};
  482. status.delta_timestamp = basic_motion.delta_timestamp;
  483. return status;
  484. }
  485. void OnChange() {
  486. const Common::Input::CallbackStatus status{
  487. .type = Common::Input::InputType::Motion,
  488. .motion_status = GetStatus(),
  489. };
  490. TriggerOnChange(status);
  491. }
  492. private:
  493. const PadIdentifier identifier;
  494. const int motion_sensor;
  495. int callback_key;
  496. InputEngine* input_engine;
  497. };
  498. class InputFromAxisMotion final : public Common::Input::InputDevice {
  499. public:
  500. explicit InputFromAxisMotion(PadIdentifier identifier_, int axis_x_, int axis_y_, int axis_z_,
  501. Common::Input::AnalogProperties properties_x_,
  502. Common::Input::AnalogProperties properties_y_,
  503. Common::Input::AnalogProperties properties_z_,
  504. InputEngine* input_engine_)
  505. : identifier(identifier_), axis_x(axis_x_), axis_y(axis_y_), axis_z(axis_z_),
  506. properties_x(properties_x_), properties_y(properties_y_), properties_z(properties_z_),
  507. input_engine(input_engine_) {
  508. UpdateCallback engine_callback{[this]() { OnChange(); }};
  509. const InputIdentifier x_input_identifier{
  510. .identifier = identifier,
  511. .type = EngineInputType::Analog,
  512. .index = axis_x,
  513. .callback = engine_callback,
  514. };
  515. const InputIdentifier y_input_identifier{
  516. .identifier = identifier,
  517. .type = EngineInputType::Analog,
  518. .index = axis_y,
  519. .callback = engine_callback,
  520. };
  521. const InputIdentifier z_input_identifier{
  522. .identifier = identifier,
  523. .type = EngineInputType::Analog,
  524. .index = axis_z,
  525. .callback = engine_callback,
  526. };
  527. last_axis_x_value = 0.0f;
  528. last_axis_y_value = 0.0f;
  529. last_axis_z_value = 0.0f;
  530. callback_key_x = input_engine->SetCallback(x_input_identifier);
  531. callback_key_y = input_engine->SetCallback(y_input_identifier);
  532. callback_key_z = input_engine->SetCallback(z_input_identifier);
  533. }
  534. ~InputFromAxisMotion() {
  535. input_engine->DeleteCallback(callback_key_x);
  536. input_engine->DeleteCallback(callback_key_y);
  537. input_engine->DeleteCallback(callback_key_z);
  538. }
  539. Common::Input::MotionStatus GetStatus() const {
  540. Common::Input::MotionStatus status{};
  541. status.gyro.x = {
  542. .raw_value = input_engine->GetAxis(identifier, axis_x),
  543. .properties = properties_x,
  544. };
  545. status.gyro.y = {
  546. .raw_value = input_engine->GetAxis(identifier, axis_y),
  547. .properties = properties_y,
  548. };
  549. status.gyro.z = {
  550. .raw_value = input_engine->GetAxis(identifier, axis_z),
  551. .properties = properties_z,
  552. };
  553. status.delta_timestamp = 5000;
  554. status.force_update = true;
  555. return status;
  556. }
  557. void ForceUpdate() {
  558. const Common::Input::CallbackStatus status{
  559. .type = Common::Input::InputType::Motion,
  560. .motion_status = GetStatus(),
  561. };
  562. last_axis_x_value = status.motion_status.gyro.x.raw_value;
  563. last_axis_y_value = status.motion_status.gyro.y.raw_value;
  564. last_axis_z_value = status.motion_status.gyro.z.raw_value;
  565. TriggerOnChange(status);
  566. }
  567. void OnChange() {
  568. const Common::Input::CallbackStatus status{
  569. .type = Common::Input::InputType::Motion,
  570. .motion_status = GetStatus(),
  571. };
  572. if (status.motion_status.gyro.x.raw_value != last_axis_x_value ||
  573. status.motion_status.gyro.y.raw_value != last_axis_y_value ||
  574. status.motion_status.gyro.z.raw_value != last_axis_z_value) {
  575. last_axis_x_value = status.motion_status.gyro.x.raw_value;
  576. last_axis_y_value = status.motion_status.gyro.y.raw_value;
  577. last_axis_z_value = status.motion_status.gyro.z.raw_value;
  578. TriggerOnChange(status);
  579. }
  580. }
  581. private:
  582. const PadIdentifier identifier;
  583. const int axis_x;
  584. const int axis_y;
  585. const int axis_z;
  586. const Common::Input::AnalogProperties properties_x;
  587. const Common::Input::AnalogProperties properties_y;
  588. const Common::Input::AnalogProperties properties_z;
  589. int callback_key_x;
  590. int callback_key_y;
  591. int callback_key_z;
  592. float last_axis_x_value;
  593. float last_axis_y_value;
  594. float last_axis_z_value;
  595. InputEngine* input_engine;
  596. };
  597. class OutputFromIdentifier final : public Common::Input::OutputDevice {
  598. public:
  599. explicit OutputFromIdentifier(PadIdentifier identifier_, InputEngine* input_engine_)
  600. : identifier(identifier_), input_engine(input_engine_) {}
  601. virtual void SetLED(Common::Input::LedStatus led_status) {
  602. input_engine->SetLeds(identifier, led_status);
  603. }
  604. virtual Common::Input::VibrationError SetVibration(
  605. const Common::Input::VibrationStatus& vibration_status) {
  606. return input_engine->SetRumble(identifier, vibration_status);
  607. }
  608. virtual Common::Input::PollingError SetPollingMode(Common::Input::PollingMode polling_mode) {
  609. return input_engine->SetPollingMode(identifier, polling_mode);
  610. }
  611. private:
  612. const PadIdentifier identifier;
  613. InputEngine* input_engine;
  614. };
  615. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateButtonDevice(
  616. const Common::ParamPackage& params) {
  617. const PadIdentifier identifier = {
  618. .guid = Common::UUID{params.Get("guid", "")},
  619. .port = static_cast<std::size_t>(params.Get("port", 0)),
  620. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  621. };
  622. const auto button_id = params.Get("button", 0);
  623. const auto keyboard_key = params.Get("code", 0);
  624. const auto toggle = params.Get("toggle", false);
  625. const auto inverted = params.Get("inverted", false);
  626. input_engine->PreSetController(identifier);
  627. input_engine->PreSetButton(identifier, button_id);
  628. input_engine->PreSetButton(identifier, keyboard_key);
  629. if (keyboard_key != 0) {
  630. return std::make_unique<InputFromButton>(identifier, keyboard_key, toggle, inverted,
  631. input_engine.get());
  632. }
  633. return std::make_unique<InputFromButton>(identifier, button_id, toggle, inverted,
  634. input_engine.get());
  635. }
  636. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateHatButtonDevice(
  637. const Common::ParamPackage& params) {
  638. const PadIdentifier identifier = {
  639. .guid = Common::UUID{params.Get("guid", "")},
  640. .port = static_cast<std::size_t>(params.Get("port", 0)),
  641. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  642. };
  643. const auto button_id = params.Get("hat", 0);
  644. const auto direction = input_engine->GetHatButtonId(params.Get("direction", ""));
  645. const auto toggle = params.Get("toggle", false);
  646. const auto inverted = params.Get("inverted", false);
  647. input_engine->PreSetController(identifier);
  648. input_engine->PreSetHatButton(identifier, button_id);
  649. return std::make_unique<InputFromHatButton>(identifier, button_id, direction, toggle, inverted,
  650. input_engine.get());
  651. }
  652. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateStickDevice(
  653. const Common::ParamPackage& params) {
  654. const auto deadzone = std::clamp(params.Get("deadzone", 0.15f), 0.0f, 1.0f);
  655. const auto range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f);
  656. const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
  657. const PadIdentifier identifier = {
  658. .guid = Common::UUID{params.Get("guid", "")},
  659. .port = static_cast<std::size_t>(params.Get("port", 0)),
  660. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  661. };
  662. const auto axis_x = params.Get("axis_x", 0);
  663. const Common::Input::AnalogProperties properties_x = {
  664. .deadzone = deadzone,
  665. .range = range,
  666. .threshold = threshold,
  667. .offset = std::clamp(params.Get("offset_x", 0.0f), -1.0f, 1.0f),
  668. .inverted = params.Get("invert_x", "+") == "-",
  669. };
  670. const auto axis_y = params.Get("axis_y", 1);
  671. const Common::Input::AnalogProperties properties_y = {
  672. .deadzone = deadzone,
  673. .range = range,
  674. .threshold = threshold,
  675. .offset = std::clamp(params.Get("offset_y", 0.0f), -1.0f, 1.0f),
  676. .inverted = params.Get("invert_y", "+") != "+",
  677. };
  678. input_engine->PreSetController(identifier);
  679. input_engine->PreSetAxis(identifier, axis_x);
  680. input_engine->PreSetAxis(identifier, axis_y);
  681. return std::make_unique<InputFromStick>(identifier, axis_x, axis_y, properties_x, properties_y,
  682. input_engine.get());
  683. }
  684. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateAnalogDevice(
  685. const Common::ParamPackage& params) {
  686. const PadIdentifier identifier = {
  687. .guid = Common::UUID{params.Get("guid", "")},
  688. .port = static_cast<std::size_t>(params.Get("port", 0)),
  689. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  690. };
  691. const auto axis = params.Get("axis", 0);
  692. const Common::Input::AnalogProperties properties = {
  693. .deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f),
  694. .range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f),
  695. .threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f),
  696. .offset = std::clamp(params.Get("offset", 0.0f), -1.0f, 1.0f),
  697. .inverted = params.Get("invert", "+") == "-",
  698. };
  699. input_engine->PreSetController(identifier);
  700. input_engine->PreSetAxis(identifier, axis);
  701. return std::make_unique<InputFromAnalog>(identifier, axis, properties, input_engine.get());
  702. }
  703. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateTriggerDevice(
  704. const Common::ParamPackage& params) {
  705. const PadIdentifier identifier = {
  706. .guid = Common::UUID{params.Get("guid", "")},
  707. .port = static_cast<std::size_t>(params.Get("port", 0)),
  708. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  709. };
  710. const auto button = params.Get("button", 0);
  711. const auto toggle = params.Get("toggle", false);
  712. const auto inverted = params.Get("inverted", false);
  713. const auto axis = params.Get("axis", 0);
  714. const Common::Input::AnalogProperties properties = {
  715. .deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f),
  716. .range = std::clamp(params.Get("range", 1.0f), 0.25f, 2.50f),
  717. .threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f),
  718. .offset = std::clamp(params.Get("offset", 0.0f), -1.0f, 1.0f),
  719. .inverted = params.Get("invert", false) != 0,
  720. };
  721. input_engine->PreSetController(identifier);
  722. input_engine->PreSetAxis(identifier, axis);
  723. input_engine->PreSetButton(identifier, button);
  724. return std::make_unique<InputFromTrigger>(identifier, button, toggle, inverted, axis,
  725. properties, input_engine.get());
  726. }
  727. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateTouchDevice(
  728. const Common::ParamPackage& params) {
  729. const auto touch_id = params.Get("touch_id", 0);
  730. const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
  731. const auto range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f);
  732. const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
  733. const PadIdentifier identifier = {
  734. .guid = Common::UUID{params.Get("guid", "")},
  735. .port = static_cast<std::size_t>(params.Get("port", 0)),
  736. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  737. };
  738. const auto button = params.Get("button", 0);
  739. const auto toggle = params.Get("toggle", false);
  740. const auto inverted = params.Get("inverted", false);
  741. const auto axis_x = params.Get("axis_x", 0);
  742. const Common::Input::AnalogProperties properties_x = {
  743. .deadzone = deadzone,
  744. .range = range,
  745. .threshold = threshold,
  746. .offset = std::clamp(params.Get("offset_x", 0.0f), -1.0f, 1.0f),
  747. .inverted = params.Get("invert_x", "+") == "-",
  748. };
  749. const auto axis_y = params.Get("axis_y", 1);
  750. const Common::Input::AnalogProperties properties_y = {
  751. .deadzone = deadzone,
  752. .range = range,
  753. .threshold = threshold,
  754. .offset = std::clamp(params.Get("offset_y", 0.0f), -1.0f, 1.0f),
  755. .inverted = params.Get("invert_y", false) != 0,
  756. };
  757. input_engine->PreSetController(identifier);
  758. input_engine->PreSetAxis(identifier, axis_x);
  759. input_engine->PreSetAxis(identifier, axis_y);
  760. input_engine->PreSetButton(identifier, button);
  761. return std::make_unique<InputFromTouch>(identifier, touch_id, button, toggle, inverted, axis_x,
  762. axis_y, properties_x, properties_y, input_engine.get());
  763. }
  764. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateBatteryDevice(
  765. const Common::ParamPackage& params) {
  766. const PadIdentifier identifier = {
  767. .guid = Common::UUID{params.Get("guid", "")},
  768. .port = static_cast<std::size_t>(params.Get("port", 0)),
  769. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  770. };
  771. input_engine->PreSetController(identifier);
  772. return std::make_unique<InputFromBattery>(identifier, input_engine.get());
  773. }
  774. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateMotionDevice(
  775. Common::ParamPackage params) {
  776. const PadIdentifier identifier = {
  777. .guid = Common::UUID{params.Get("guid", "")},
  778. .port = static_cast<std::size_t>(params.Get("port", 0)),
  779. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  780. };
  781. if (params.Has("motion")) {
  782. const auto motion_sensor = params.Get("motion", 0);
  783. input_engine->PreSetController(identifier);
  784. input_engine->PreSetMotion(identifier, motion_sensor);
  785. return std::make_unique<InputFromMotion>(identifier, motion_sensor, input_engine.get());
  786. }
  787. const auto deadzone = std::clamp(params.Get("deadzone", 0.15f), 0.0f, 1.0f);
  788. const auto range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f);
  789. const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
  790. const auto axis_x = params.Get("axis_x", 0);
  791. const Common::Input::AnalogProperties properties_x = {
  792. .deadzone = deadzone,
  793. .range = range,
  794. .threshold = threshold,
  795. .offset = std::clamp(params.Get("offset_x", 0.0f), -1.0f, 1.0f),
  796. .inverted = params.Get("invert_x", "+") == "-",
  797. };
  798. const auto axis_y = params.Get("axis_y", 1);
  799. const Common::Input::AnalogProperties properties_y = {
  800. .deadzone = deadzone,
  801. .range = range,
  802. .threshold = threshold,
  803. .offset = std::clamp(params.Get("offset_y", 0.0f), -1.0f, 1.0f),
  804. .inverted = params.Get("invert_y", "+") != "+",
  805. };
  806. const auto axis_z = params.Get("axis_z", 1);
  807. const Common::Input::AnalogProperties properties_z = {
  808. .deadzone = deadzone,
  809. .range = range,
  810. .threshold = threshold,
  811. .offset = std::clamp(params.Get("offset_z", 0.0f), -1.0f, 1.0f),
  812. .inverted = params.Get("invert_z", "+") != "+",
  813. };
  814. input_engine->PreSetController(identifier);
  815. input_engine->PreSetAxis(identifier, axis_x);
  816. input_engine->PreSetAxis(identifier, axis_y);
  817. input_engine->PreSetAxis(identifier, axis_z);
  818. return std::make_unique<InputFromAxisMotion>(identifier, axis_x, axis_y, axis_z, properties_x,
  819. properties_y, properties_z, input_engine.get());
  820. }
  821. InputFactory::InputFactory(std::shared_ptr<InputEngine> input_engine_)
  822. : input_engine(std::move(input_engine_)) {}
  823. std::unique_ptr<Common::Input::InputDevice> InputFactory::Create(
  824. const Common::ParamPackage& params) {
  825. if (params.Has("battery")) {
  826. return CreateBatteryDevice(params);
  827. }
  828. if (params.Has("button") && params.Has("axis")) {
  829. return CreateTriggerDevice(params);
  830. }
  831. if (params.Has("button") && params.Has("axis_x") && params.Has("axis_y")) {
  832. return CreateTouchDevice(params);
  833. }
  834. if (params.Has("button") || params.Has("code")) {
  835. return CreateButtonDevice(params);
  836. }
  837. if (params.Has("hat")) {
  838. return CreateHatButtonDevice(params);
  839. }
  840. if (params.Has("axis_x") && params.Has("axis_y") && params.Has("axis_z")) {
  841. return CreateMotionDevice(params);
  842. }
  843. if (params.Has("motion")) {
  844. return CreateMotionDevice(params);
  845. }
  846. if (params.Has("axis_x") && params.Has("axis_y")) {
  847. return CreateStickDevice(params);
  848. }
  849. if (params.Has("axis")) {
  850. return CreateAnalogDevice(params);
  851. }
  852. LOG_ERROR(Input, "Invalid parameters given");
  853. return std::make_unique<DummyInput>();
  854. }
  855. OutputFactory::OutputFactory(std::shared_ptr<InputEngine> input_engine_)
  856. : input_engine(std::move(input_engine_)) {}
  857. std::unique_ptr<Common::Input::OutputDevice> OutputFactory::Create(
  858. const Common::ParamPackage& params) {
  859. const PadIdentifier identifier = {
  860. .guid = Common::UUID{params.Get("guid", "")},
  861. .port = static_cast<std::size_t>(params.Get("port", 0)),
  862. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  863. };
  864. input_engine->PreSetController(identifier);
  865. return std::make_unique<OutputFromIdentifier>(identifier, input_engine.get());
  866. }
  867. } // namespace InputCommon