input_poller.cpp 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180
  1. // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "common/common_types.h"
  4. #include "common/input.h"
  5. #include "input_common/input_engine.h"
  6. #include "input_common/input_poller.h"
  7. namespace InputCommon {
  8. class DummyInput final : public Common::Input::InputDevice {
  9. public:
  10. explicit DummyInput() = default;
  11. };
  12. class InputFromButton final : public Common::Input::InputDevice {
  13. public:
  14. explicit InputFromButton(PadIdentifier identifier_, int button_, bool turbo_, bool toggle_,
  15. bool inverted_, InputEngine* input_engine_)
  16. : identifier(identifier_), button(button_), turbo(turbo_), toggle(toggle_),
  17. inverted(inverted_), input_engine(input_engine_) {
  18. UpdateCallback engine_callback{[this]() { OnChange(); }};
  19. const InputIdentifier input_identifier{
  20. .identifier = identifier,
  21. .type = EngineInputType::Button,
  22. .index = button,
  23. .callback = engine_callback,
  24. };
  25. last_button_value = false;
  26. callback_key = input_engine->SetCallback(input_identifier);
  27. }
  28. ~InputFromButton() override {
  29. input_engine->DeleteCallback(callback_key);
  30. }
  31. Common::Input::ButtonStatus GetStatus() const {
  32. return {
  33. .value = input_engine->GetButton(identifier, button),
  34. .inverted = inverted,
  35. .toggle = toggle,
  36. .turbo = turbo,
  37. };
  38. }
  39. void ForceUpdate() override {
  40. const Common::Input::CallbackStatus status{
  41. .type = Common::Input::InputType::Button,
  42. .button_status = GetStatus(),
  43. };
  44. last_button_value = status.button_status.value;
  45. TriggerOnChange(status);
  46. }
  47. void OnChange() {
  48. const Common::Input::CallbackStatus status{
  49. .type = Common::Input::InputType::Button,
  50. .button_status = GetStatus(),
  51. };
  52. if (status.button_status.value != last_button_value) {
  53. last_button_value = status.button_status.value;
  54. TriggerOnChange(status);
  55. }
  56. }
  57. private:
  58. const PadIdentifier identifier;
  59. const int button;
  60. const bool turbo;
  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 turbo_,
  70. bool toggle_, bool inverted_, InputEngine* input_engine_)
  71. : identifier(identifier_), button(button_), direction(direction_), turbo(turbo_),
  72. toggle(toggle_), 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() override {
  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. .turbo = turbo,
  92. };
  93. }
  94. void ForceUpdate() override {
  95. const Common::Input::CallbackStatus status{
  96. .type = Common::Input::InputType::Button,
  97. .button_status = GetStatus(),
  98. };
  99. last_button_value = status.button_status.value;
  100. TriggerOnChange(status);
  101. }
  102. void OnChange() {
  103. const Common::Input::CallbackStatus status{
  104. .type = Common::Input::InputType::Button,
  105. .button_status = GetStatus(),
  106. };
  107. if (status.button_status.value != last_button_value) {
  108. last_button_value = status.button_status.value;
  109. TriggerOnChange(status);
  110. }
  111. }
  112. private:
  113. const PadIdentifier identifier;
  114. const int button;
  115. const u8 direction;
  116. const bool turbo;
  117. const bool toggle;
  118. const bool inverted;
  119. int callback_key;
  120. bool last_button_value;
  121. InputEngine* input_engine;
  122. };
  123. class InputFromStick final : public Common::Input::InputDevice {
  124. public:
  125. explicit InputFromStick(PadIdentifier identifier_, int axis_x_, int axis_y_,
  126. Common::Input::AnalogProperties properties_x_,
  127. Common::Input::AnalogProperties properties_y_,
  128. InputEngine* input_engine_)
  129. : identifier(identifier_), axis_x(axis_x_), axis_y(axis_y_), properties_x(properties_x_),
  130. properties_y(properties_y_),
  131. input_engine(input_engine_), invert_axis_y{input_engine_->GetEngineName() == "sdl"} {
  132. UpdateCallback engine_callback{[this]() { OnChange(); }};
  133. const InputIdentifier x_input_identifier{
  134. .identifier = identifier,
  135. .type = EngineInputType::Analog,
  136. .index = axis_x,
  137. .callback = engine_callback,
  138. };
  139. const InputIdentifier y_input_identifier{
  140. .identifier = identifier,
  141. .type = EngineInputType::Analog,
  142. .index = axis_y,
  143. .callback = engine_callback,
  144. };
  145. last_axis_x_value = 0.0f;
  146. last_axis_y_value = 0.0f;
  147. callback_key_x = input_engine->SetCallback(x_input_identifier);
  148. callback_key_y = input_engine->SetCallback(y_input_identifier);
  149. }
  150. ~InputFromStick() override {
  151. input_engine->DeleteCallback(callback_key_x);
  152. input_engine->DeleteCallback(callback_key_y);
  153. }
  154. Common::Input::StickStatus GetStatus() const {
  155. Common::Input::StickStatus status;
  156. status.x = {
  157. .raw_value = input_engine->GetAxis(identifier, axis_x),
  158. .properties = properties_x,
  159. };
  160. status.y = {
  161. .raw_value = input_engine->GetAxis(identifier, axis_y),
  162. .properties = properties_y,
  163. };
  164. // This is a workaround to keep compatibility with old yuzu versions. Vertical axis is
  165. // inverted on SDL compared to Nintendo
  166. if (invert_axis_y) {
  167. status.y.raw_value = -status.y.raw_value;
  168. }
  169. return status;
  170. }
  171. void ForceUpdate() override {
  172. const Common::Input::CallbackStatus status{
  173. .type = Common::Input::InputType::Stick,
  174. .stick_status = GetStatus(),
  175. };
  176. last_axis_x_value = status.stick_status.x.raw_value;
  177. last_axis_y_value = status.stick_status.y.raw_value;
  178. TriggerOnChange(status);
  179. }
  180. void OnChange() {
  181. const Common::Input::CallbackStatus status{
  182. .type = Common::Input::InputType::Stick,
  183. .stick_status = GetStatus(),
  184. };
  185. if (status.stick_status.x.raw_value != last_axis_x_value ||
  186. status.stick_status.y.raw_value != last_axis_y_value) {
  187. last_axis_x_value = status.stick_status.x.raw_value;
  188. last_axis_y_value = status.stick_status.y.raw_value;
  189. TriggerOnChange(status);
  190. }
  191. }
  192. private:
  193. const PadIdentifier identifier;
  194. const int axis_x;
  195. const int axis_y;
  196. const Common::Input::AnalogProperties properties_x;
  197. const Common::Input::AnalogProperties properties_y;
  198. int callback_key_x;
  199. int callback_key_y;
  200. float last_axis_x_value;
  201. float last_axis_y_value;
  202. InputEngine* input_engine;
  203. const bool invert_axis_y;
  204. };
  205. class InputFromTouch final : public Common::Input::InputDevice {
  206. public:
  207. explicit InputFromTouch(PadIdentifier identifier_, int button_, bool toggle_, bool inverted_,
  208. int axis_x_, int axis_y_, Common::Input::AnalogProperties properties_x_,
  209. Common::Input::AnalogProperties properties_y_,
  210. InputEngine* input_engine_)
  211. : identifier(identifier_), button(button_), toggle(toggle_), inverted(inverted_),
  212. axis_x(axis_x_), axis_y(axis_y_), properties_x(properties_x_),
  213. properties_y(properties_y_), input_engine(input_engine_) {
  214. UpdateCallback engine_callback{[this]() { OnChange(); }};
  215. const InputIdentifier button_input_identifier{
  216. .identifier = identifier,
  217. .type = EngineInputType::Button,
  218. .index = button,
  219. .callback = engine_callback,
  220. };
  221. const InputIdentifier x_input_identifier{
  222. .identifier = identifier,
  223. .type = EngineInputType::Analog,
  224. .index = axis_x,
  225. .callback = engine_callback,
  226. };
  227. const InputIdentifier y_input_identifier{
  228. .identifier = identifier,
  229. .type = EngineInputType::Analog,
  230. .index = axis_y,
  231. .callback = engine_callback,
  232. };
  233. last_axis_x_value = 0.0f;
  234. last_axis_y_value = 0.0f;
  235. last_button_value = false;
  236. callback_key_button = input_engine->SetCallback(button_input_identifier);
  237. callback_key_x = input_engine->SetCallback(x_input_identifier);
  238. callback_key_y = input_engine->SetCallback(y_input_identifier);
  239. }
  240. ~InputFromTouch() override {
  241. input_engine->DeleteCallback(callback_key_button);
  242. input_engine->DeleteCallback(callback_key_x);
  243. input_engine->DeleteCallback(callback_key_y);
  244. }
  245. Common::Input::TouchStatus GetStatus() const {
  246. Common::Input::TouchStatus status{};
  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 button;
  279. const bool toggle;
  280. const bool inverted;
  281. const int axis_x;
  282. const int axis_y;
  283. const Common::Input::AnalogProperties properties_x;
  284. const Common::Input::AnalogProperties properties_y;
  285. int callback_key_button;
  286. int callback_key_x;
  287. int callback_key_y;
  288. bool last_button_value;
  289. float last_axis_x_value;
  290. float last_axis_y_value;
  291. InputEngine* input_engine;
  292. };
  293. class InputFromTrigger final : public Common::Input::InputDevice {
  294. public:
  295. explicit InputFromTrigger(PadIdentifier identifier_, int button_, bool toggle_, bool inverted_,
  296. int axis_, Common::Input::AnalogProperties properties_,
  297. InputEngine* input_engine_)
  298. : identifier(identifier_), button(button_), toggle(toggle_), inverted(inverted_),
  299. axis(axis_), properties(properties_), input_engine(input_engine_) {
  300. UpdateCallback engine_callback{[this]() { OnChange(); }};
  301. const InputIdentifier button_input_identifier{
  302. .identifier = identifier,
  303. .type = EngineInputType::Button,
  304. .index = button,
  305. .callback = engine_callback,
  306. };
  307. const InputIdentifier axis_input_identifier{
  308. .identifier = identifier,
  309. .type = EngineInputType::Analog,
  310. .index = axis,
  311. .callback = engine_callback,
  312. };
  313. last_axis_value = 0.0f;
  314. last_button_value = false;
  315. callback_key_button = input_engine->SetCallback(button_input_identifier);
  316. axis_callback_key = input_engine->SetCallback(axis_input_identifier);
  317. }
  318. ~InputFromTrigger() override {
  319. input_engine->DeleteCallback(callback_key_button);
  320. input_engine->DeleteCallback(axis_callback_key);
  321. }
  322. Common::Input::TriggerStatus GetStatus() const {
  323. const Common::Input::AnalogStatus analog_status{
  324. .raw_value = input_engine->GetAxis(identifier, axis),
  325. .properties = properties,
  326. };
  327. const Common::Input::ButtonStatus button_status{
  328. .value = input_engine->GetButton(identifier, button),
  329. .inverted = inverted,
  330. .toggle = toggle,
  331. };
  332. return {
  333. .analog = analog_status,
  334. .pressed = button_status,
  335. };
  336. }
  337. void OnChange() {
  338. const Common::Input::CallbackStatus status{
  339. .type = Common::Input::InputType::Trigger,
  340. .trigger_status = GetStatus(),
  341. };
  342. if (status.trigger_status.analog.raw_value != last_axis_value ||
  343. status.trigger_status.pressed.value != last_button_value) {
  344. last_axis_value = status.trigger_status.analog.raw_value;
  345. last_button_value = status.trigger_status.pressed.value;
  346. TriggerOnChange(status);
  347. }
  348. }
  349. private:
  350. const PadIdentifier identifier;
  351. const int button;
  352. const bool toggle;
  353. const bool inverted;
  354. const int axis;
  355. const Common::Input::AnalogProperties properties;
  356. int callback_key_button;
  357. int axis_callback_key;
  358. bool last_button_value;
  359. float last_axis_value;
  360. InputEngine* input_engine;
  361. };
  362. class InputFromAnalog final : public Common::Input::InputDevice {
  363. public:
  364. explicit InputFromAnalog(PadIdentifier identifier_, int axis_,
  365. Common::Input::AnalogProperties properties_,
  366. InputEngine* input_engine_)
  367. : identifier(identifier_), axis(axis_), properties(properties_),
  368. input_engine(input_engine_) {
  369. UpdateCallback engine_callback{[this]() { OnChange(); }};
  370. const InputIdentifier input_identifier{
  371. .identifier = identifier,
  372. .type = EngineInputType::Analog,
  373. .index = axis,
  374. .callback = engine_callback,
  375. };
  376. last_axis_value = 0.0f;
  377. callback_key = input_engine->SetCallback(input_identifier);
  378. }
  379. ~InputFromAnalog() override {
  380. input_engine->DeleteCallback(callback_key);
  381. }
  382. Common::Input::AnalogStatus GetStatus() const {
  383. return {
  384. .raw_value = input_engine->GetAxis(identifier, axis),
  385. .properties = properties,
  386. };
  387. }
  388. void OnChange() {
  389. const Common::Input::CallbackStatus status{
  390. .type = Common::Input::InputType::Analog,
  391. .analog_status = GetStatus(),
  392. };
  393. if (status.analog_status.raw_value != last_axis_value) {
  394. last_axis_value = status.analog_status.raw_value;
  395. TriggerOnChange(status);
  396. }
  397. }
  398. private:
  399. const PadIdentifier identifier;
  400. const int axis;
  401. const Common::Input::AnalogProperties properties;
  402. int callback_key;
  403. float last_axis_value;
  404. InputEngine* input_engine;
  405. };
  406. class InputFromBattery final : public Common::Input::InputDevice {
  407. public:
  408. explicit InputFromBattery(PadIdentifier identifier_, InputEngine* input_engine_)
  409. : identifier(identifier_), input_engine(input_engine_) {
  410. UpdateCallback engine_callback{[this]() { OnChange(); }};
  411. const InputIdentifier input_identifier{
  412. .identifier = identifier,
  413. .type = EngineInputType::Battery,
  414. .index = 0,
  415. .callback = engine_callback,
  416. };
  417. last_battery_value = Common::Input::BatteryStatus::Charging;
  418. callback_key = input_engine->SetCallback(input_identifier);
  419. }
  420. ~InputFromBattery() override {
  421. input_engine->DeleteCallback(callback_key);
  422. }
  423. Common::Input::BatteryStatus GetStatus() const {
  424. return input_engine->GetBattery(identifier);
  425. }
  426. void ForceUpdate() override {
  427. const Common::Input::CallbackStatus status{
  428. .type = Common::Input::InputType::Battery,
  429. .battery_status = GetStatus(),
  430. };
  431. last_battery_value = status.battery_status;
  432. TriggerOnChange(status);
  433. }
  434. void OnChange() {
  435. const Common::Input::CallbackStatus status{
  436. .type = Common::Input::InputType::Battery,
  437. .battery_status = GetStatus(),
  438. };
  439. if (status.battery_status != last_battery_value) {
  440. last_battery_value = status.battery_status;
  441. TriggerOnChange(status);
  442. }
  443. }
  444. private:
  445. const PadIdentifier identifier;
  446. int callback_key;
  447. Common::Input::BatteryStatus last_battery_value;
  448. InputEngine* input_engine;
  449. };
  450. class InputFromColor final : public Common::Input::InputDevice {
  451. public:
  452. explicit InputFromColor(PadIdentifier identifier_, InputEngine* input_engine_)
  453. : identifier(identifier_), input_engine(input_engine_) {
  454. UpdateCallback engine_callback{[this]() { OnChange(); }};
  455. const InputIdentifier input_identifier{
  456. .identifier = identifier,
  457. .type = EngineInputType::Color,
  458. .index = 0,
  459. .callback = engine_callback,
  460. };
  461. last_color_value = {};
  462. callback_key = input_engine->SetCallback(input_identifier);
  463. }
  464. ~InputFromColor() override {
  465. input_engine->DeleteCallback(callback_key);
  466. }
  467. Common::Input::BodyColorStatus GetStatus() const {
  468. return input_engine->GetColor(identifier);
  469. }
  470. void ForceUpdate() override {
  471. const Common::Input::CallbackStatus status{
  472. .type = Common::Input::InputType::Color,
  473. .color_status = GetStatus(),
  474. };
  475. last_color_value = status.color_status;
  476. TriggerOnChange(status);
  477. }
  478. void OnChange() {
  479. const Common::Input::CallbackStatus status{
  480. .type = Common::Input::InputType::Color,
  481. .color_status = GetStatus(),
  482. };
  483. if (status.color_status.body != last_color_value.body) {
  484. last_color_value = status.color_status;
  485. TriggerOnChange(status);
  486. }
  487. }
  488. private:
  489. const PadIdentifier identifier;
  490. int callback_key;
  491. Common::Input::BodyColorStatus last_color_value;
  492. InputEngine* input_engine;
  493. };
  494. class InputFromMotion final : public Common::Input::InputDevice {
  495. public:
  496. explicit InputFromMotion(PadIdentifier identifier_, int motion_sensor_, float gyro_threshold_,
  497. InputEngine* input_engine_)
  498. : identifier(identifier_), motion_sensor(motion_sensor_), gyro_threshold(gyro_threshold_),
  499. input_engine(input_engine_) {
  500. UpdateCallback engine_callback{[this]() { OnChange(); }};
  501. const InputIdentifier input_identifier{
  502. .identifier = identifier,
  503. .type = EngineInputType::Motion,
  504. .index = motion_sensor,
  505. .callback = engine_callback,
  506. };
  507. callback_key = input_engine->SetCallback(input_identifier);
  508. }
  509. ~InputFromMotion() override {
  510. input_engine->DeleteCallback(callback_key);
  511. }
  512. Common::Input::MotionStatus GetStatus() const {
  513. const auto basic_motion = input_engine->GetMotion(identifier, motion_sensor);
  514. Common::Input::MotionStatus status{};
  515. const Common::Input::AnalogProperties properties = {
  516. .deadzone = 0.0f,
  517. .range = 1.0f,
  518. .threshold = gyro_threshold,
  519. .offset = 0.0f,
  520. };
  521. status.accel.x = {.raw_value = basic_motion.accel_x, .properties = properties};
  522. status.accel.y = {.raw_value = basic_motion.accel_y, .properties = properties};
  523. status.accel.z = {.raw_value = basic_motion.accel_z, .properties = properties};
  524. status.gyro.x = {.raw_value = basic_motion.gyro_x, .properties = properties};
  525. status.gyro.y = {.raw_value = basic_motion.gyro_y, .properties = properties};
  526. status.gyro.z = {.raw_value = basic_motion.gyro_z, .properties = properties};
  527. status.delta_timestamp = basic_motion.delta_timestamp;
  528. return status;
  529. }
  530. void OnChange() {
  531. const Common::Input::CallbackStatus status{
  532. .type = Common::Input::InputType::Motion,
  533. .motion_status = GetStatus(),
  534. };
  535. TriggerOnChange(status);
  536. }
  537. private:
  538. const PadIdentifier identifier;
  539. const int motion_sensor;
  540. const float gyro_threshold;
  541. int callback_key;
  542. InputEngine* input_engine;
  543. };
  544. class InputFromAxisMotion final : public Common::Input::InputDevice {
  545. public:
  546. explicit InputFromAxisMotion(PadIdentifier identifier_, int axis_x_, int axis_y_, int axis_z_,
  547. Common::Input::AnalogProperties properties_x_,
  548. Common::Input::AnalogProperties properties_y_,
  549. Common::Input::AnalogProperties properties_z_,
  550. InputEngine* input_engine_)
  551. : identifier(identifier_), axis_x(axis_x_), axis_y(axis_y_), axis_z(axis_z_),
  552. properties_x(properties_x_), properties_y(properties_y_), properties_z(properties_z_),
  553. input_engine(input_engine_) {
  554. UpdateCallback engine_callback{[this]() { OnChange(); }};
  555. const InputIdentifier x_input_identifier{
  556. .identifier = identifier,
  557. .type = EngineInputType::Analog,
  558. .index = axis_x,
  559. .callback = engine_callback,
  560. };
  561. const InputIdentifier y_input_identifier{
  562. .identifier = identifier,
  563. .type = EngineInputType::Analog,
  564. .index = axis_y,
  565. .callback = engine_callback,
  566. };
  567. const InputIdentifier z_input_identifier{
  568. .identifier = identifier,
  569. .type = EngineInputType::Analog,
  570. .index = axis_z,
  571. .callback = engine_callback,
  572. };
  573. last_axis_x_value = 0.0f;
  574. last_axis_y_value = 0.0f;
  575. last_axis_z_value = 0.0f;
  576. callback_key_x = input_engine->SetCallback(x_input_identifier);
  577. callback_key_y = input_engine->SetCallback(y_input_identifier);
  578. callback_key_z = input_engine->SetCallback(z_input_identifier);
  579. }
  580. ~InputFromAxisMotion() override {
  581. input_engine->DeleteCallback(callback_key_x);
  582. input_engine->DeleteCallback(callback_key_y);
  583. input_engine->DeleteCallback(callback_key_z);
  584. }
  585. Common::Input::MotionStatus GetStatus() const {
  586. Common::Input::MotionStatus status{};
  587. status.gyro.x = {
  588. .raw_value = input_engine->GetAxis(identifier, axis_x),
  589. .properties = properties_x,
  590. };
  591. status.gyro.y = {
  592. .raw_value = input_engine->GetAxis(identifier, axis_y),
  593. .properties = properties_y,
  594. };
  595. status.gyro.z = {
  596. .raw_value = input_engine->GetAxis(identifier, axis_z),
  597. .properties = properties_z,
  598. };
  599. status.delta_timestamp = 1000;
  600. status.force_update = true;
  601. return status;
  602. }
  603. void ForceUpdate() override {
  604. const Common::Input::CallbackStatus status{
  605. .type = Common::Input::InputType::Motion,
  606. .motion_status = GetStatus(),
  607. };
  608. last_axis_x_value = status.motion_status.gyro.x.raw_value;
  609. last_axis_y_value = status.motion_status.gyro.y.raw_value;
  610. last_axis_z_value = status.motion_status.gyro.z.raw_value;
  611. TriggerOnChange(status);
  612. }
  613. void OnChange() {
  614. const Common::Input::CallbackStatus status{
  615. .type = Common::Input::InputType::Motion,
  616. .motion_status = GetStatus(),
  617. };
  618. if (status.motion_status.gyro.x.raw_value != last_axis_x_value ||
  619. status.motion_status.gyro.y.raw_value != last_axis_y_value ||
  620. status.motion_status.gyro.z.raw_value != last_axis_z_value) {
  621. last_axis_x_value = status.motion_status.gyro.x.raw_value;
  622. last_axis_y_value = status.motion_status.gyro.y.raw_value;
  623. last_axis_z_value = status.motion_status.gyro.z.raw_value;
  624. TriggerOnChange(status);
  625. }
  626. }
  627. private:
  628. const PadIdentifier identifier;
  629. const int axis_x;
  630. const int axis_y;
  631. const int axis_z;
  632. const Common::Input::AnalogProperties properties_x;
  633. const Common::Input::AnalogProperties properties_y;
  634. const Common::Input::AnalogProperties properties_z;
  635. int callback_key_x;
  636. int callback_key_y;
  637. int callback_key_z;
  638. float last_axis_x_value;
  639. float last_axis_y_value;
  640. float last_axis_z_value;
  641. InputEngine* input_engine;
  642. };
  643. class InputFromCamera final : public Common::Input::InputDevice {
  644. public:
  645. explicit InputFromCamera(PadIdentifier identifier_, InputEngine* input_engine_)
  646. : identifier(identifier_), input_engine(input_engine_) {
  647. UpdateCallback engine_callback{[this]() { OnChange(); }};
  648. const InputIdentifier input_identifier{
  649. .identifier = identifier,
  650. .type = EngineInputType::Camera,
  651. .index = 0,
  652. .callback = engine_callback,
  653. };
  654. callback_key = input_engine->SetCallback(input_identifier);
  655. }
  656. ~InputFromCamera() override {
  657. input_engine->DeleteCallback(callback_key);
  658. }
  659. Common::Input::CameraStatus GetStatus() const {
  660. return input_engine->GetCamera(identifier);
  661. }
  662. void ForceUpdate() override {
  663. OnChange();
  664. }
  665. void OnChange() {
  666. const auto camera_status = GetStatus();
  667. const Common::Input::CallbackStatus status{
  668. .type = Common::Input::InputType::IrSensor,
  669. .camera_status = camera_status.format,
  670. .raw_data = camera_status.data,
  671. };
  672. TriggerOnChange(status);
  673. }
  674. private:
  675. const PadIdentifier identifier;
  676. int callback_key;
  677. InputEngine* input_engine;
  678. };
  679. class InputFromNfc final : public Common::Input::InputDevice {
  680. public:
  681. explicit InputFromNfc(PadIdentifier identifier_, InputEngine* input_engine_)
  682. : identifier(identifier_), input_engine(input_engine_) {
  683. UpdateCallback engine_callback{[this]() { OnChange(); }};
  684. const InputIdentifier input_identifier{
  685. .identifier = identifier,
  686. .type = EngineInputType::Nfc,
  687. .index = 0,
  688. .callback = engine_callback,
  689. };
  690. callback_key = input_engine->SetCallback(input_identifier);
  691. }
  692. ~InputFromNfc() override {
  693. input_engine->DeleteCallback(callback_key);
  694. }
  695. Common::Input::NfcStatus GetStatus() const {
  696. return input_engine->GetNfc(identifier);
  697. }
  698. void ForceUpdate() override {
  699. OnChange();
  700. }
  701. void OnChange() {
  702. const auto nfc_status = GetStatus();
  703. const Common::Input::CallbackStatus status{
  704. .type = Common::Input::InputType::Nfc,
  705. .nfc_status = nfc_status.state,
  706. .raw_data = nfc_status.data,
  707. };
  708. TriggerOnChange(status);
  709. }
  710. private:
  711. const PadIdentifier identifier;
  712. int callback_key;
  713. InputEngine* input_engine;
  714. };
  715. class OutputFromIdentifier final : public Common::Input::OutputDevice {
  716. public:
  717. explicit OutputFromIdentifier(PadIdentifier identifier_, InputEngine* input_engine_)
  718. : identifier(identifier_), input_engine(input_engine_) {}
  719. Common::Input::DriverResult SetLED(const Common::Input::LedStatus& led_status) override {
  720. return input_engine->SetLeds(identifier, led_status);
  721. }
  722. Common::Input::DriverResult SetVibration(
  723. const Common::Input::VibrationStatus& vibration_status) override {
  724. return input_engine->SetVibration(identifier, vibration_status);
  725. }
  726. bool IsVibrationEnabled() override {
  727. return input_engine->IsVibrationEnabled(identifier);
  728. }
  729. Common::Input::DriverResult SetPollingMode(Common::Input::PollingMode polling_mode) override {
  730. return input_engine->SetPollingMode(identifier, polling_mode);
  731. }
  732. Common::Input::DriverResult SetCameraFormat(
  733. Common::Input::CameraFormat camera_format) override {
  734. return input_engine->SetCameraFormat(identifier, camera_format);
  735. }
  736. Common::Input::NfcState SupportsNfc() const override {
  737. return input_engine->SupportsNfc(identifier);
  738. }
  739. Common::Input::NfcState WriteNfcData(const std::vector<u8>& data) override {
  740. return input_engine->WriteNfcData(identifier, data);
  741. }
  742. private:
  743. const PadIdentifier identifier;
  744. InputEngine* input_engine;
  745. };
  746. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateButtonDevice(
  747. const Common::ParamPackage& params) {
  748. const PadIdentifier identifier = {
  749. .guid = Common::UUID{params.Get("guid", "")},
  750. .port = static_cast<std::size_t>(params.Get("port", 0)),
  751. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  752. };
  753. const auto button_id = params.Get("button", 0);
  754. const auto keyboard_key = params.Get("code", 0);
  755. const auto toggle = params.Get("toggle", false) != 0;
  756. const auto inverted = params.Get("inverted", false) != 0;
  757. const auto turbo = params.Get("turbo", false) != 0;
  758. input_engine->PreSetController(identifier);
  759. input_engine->PreSetButton(identifier, button_id);
  760. input_engine->PreSetButton(identifier, keyboard_key);
  761. if (keyboard_key != 0) {
  762. return std::make_unique<InputFromButton>(identifier, keyboard_key, turbo, toggle, inverted,
  763. input_engine.get());
  764. }
  765. return std::make_unique<InputFromButton>(identifier, button_id, turbo, toggle, inverted,
  766. input_engine.get());
  767. }
  768. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateHatButtonDevice(
  769. const Common::ParamPackage& params) {
  770. const PadIdentifier identifier = {
  771. .guid = Common::UUID{params.Get("guid", "")},
  772. .port = static_cast<std::size_t>(params.Get("port", 0)),
  773. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  774. };
  775. const auto button_id = params.Get("hat", 0);
  776. const auto direction = input_engine->GetHatButtonId(params.Get("direction", ""));
  777. const auto toggle = params.Get("toggle", false) != 0;
  778. const auto inverted = params.Get("inverted", false) != 0;
  779. const auto turbo = params.Get("turbo", false) != 0;
  780. input_engine->PreSetController(identifier);
  781. input_engine->PreSetHatButton(identifier, button_id);
  782. return std::make_unique<InputFromHatButton>(identifier, button_id, direction, turbo, toggle,
  783. inverted, input_engine.get());
  784. }
  785. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateStickDevice(
  786. const Common::ParamPackage& params) {
  787. const auto deadzone = std::clamp(params.Get("deadzone", 0.15f), 0.0f, 1.0f);
  788. const auto range = std::clamp(params.Get("range", 0.95f), 0.25f, 1.50f);
  789. const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
  790. const PadIdentifier identifier = {
  791. .guid = Common::UUID{params.Get("guid", "")},
  792. .port = static_cast<std::size_t>(params.Get("port", 0)),
  793. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  794. };
  795. const auto axis_x = params.Get("axis_x", 0);
  796. const Common::Input::AnalogProperties properties_x = {
  797. .deadzone = deadzone,
  798. .range = range,
  799. .threshold = threshold,
  800. .offset = std::clamp(params.Get("offset_x", 0.0f), -1.0f, 1.0f),
  801. .inverted = params.Get("invert_x", "+") == "-",
  802. };
  803. const auto axis_y = params.Get("axis_y", 1);
  804. const Common::Input::AnalogProperties properties_y = {
  805. .deadzone = deadzone,
  806. .range = range,
  807. .threshold = threshold,
  808. .offset = std::clamp(params.Get("offset_y", 0.0f), -1.0f, 1.0f),
  809. .inverted = params.Get("invert_y", "+") != "+",
  810. };
  811. input_engine->PreSetController(identifier);
  812. input_engine->PreSetAxis(identifier, axis_x);
  813. input_engine->PreSetAxis(identifier, axis_y);
  814. return std::make_unique<InputFromStick>(identifier, axis_x, axis_y, properties_x, properties_y,
  815. input_engine.get());
  816. }
  817. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateAnalogDevice(
  818. const Common::ParamPackage& params) {
  819. const PadIdentifier identifier = {
  820. .guid = Common::UUID{params.Get("guid", "")},
  821. .port = static_cast<std::size_t>(params.Get("port", 0)),
  822. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  823. };
  824. const auto axis = params.Get("axis", 0);
  825. const Common::Input::AnalogProperties properties = {
  826. .deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f),
  827. .range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f),
  828. .threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f),
  829. .offset = std::clamp(params.Get("offset", 0.0f), -1.0f, 1.0f),
  830. .inverted = params.Get("invert", "+") == "-",
  831. .inverted_button = params.Get("inverted", false) != 0,
  832. .toggle = params.Get("toggle", false) != 0,
  833. };
  834. input_engine->PreSetController(identifier);
  835. input_engine->PreSetAxis(identifier, axis);
  836. return std::make_unique<InputFromAnalog>(identifier, axis, properties, input_engine.get());
  837. }
  838. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateTriggerDevice(
  839. const Common::ParamPackage& params) {
  840. const PadIdentifier identifier = {
  841. .guid = Common::UUID{params.Get("guid", "")},
  842. .port = static_cast<std::size_t>(params.Get("port", 0)),
  843. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  844. };
  845. const auto button = params.Get("button", 0);
  846. const auto toggle = params.Get("toggle", false) != 0;
  847. const auto inverted = params.Get("inverted", false) != 0;
  848. const auto axis = params.Get("axis", 0);
  849. const Common::Input::AnalogProperties properties = {
  850. .deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f),
  851. .range = std::clamp(params.Get("range", 1.0f), 0.25f, 2.50f),
  852. .threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f),
  853. .offset = std::clamp(params.Get("offset", 0.0f), -1.0f, 1.0f),
  854. .inverted = params.Get("invert", false) != 0,
  855. };
  856. input_engine->PreSetController(identifier);
  857. input_engine->PreSetAxis(identifier, axis);
  858. input_engine->PreSetButton(identifier, button);
  859. return std::make_unique<InputFromTrigger>(identifier, button, toggle, inverted, axis,
  860. properties, input_engine.get());
  861. }
  862. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateTouchDevice(
  863. const Common::ParamPackage& params) {
  864. const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
  865. const auto range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f);
  866. const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
  867. const PadIdentifier identifier = {
  868. .guid = Common::UUID{params.Get("guid", "")},
  869. .port = static_cast<std::size_t>(params.Get("port", 0)),
  870. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  871. };
  872. const auto button = params.Get("button", 0);
  873. const auto toggle = params.Get("toggle", false) != 0;
  874. const auto inverted = params.Get("inverted", false) != 0;
  875. const auto axis_x = params.Get("axis_x", 0);
  876. const Common::Input::AnalogProperties properties_x = {
  877. .deadzone = deadzone,
  878. .range = range,
  879. .threshold = threshold,
  880. .offset = std::clamp(params.Get("offset_x", 0.0f), -1.0f, 1.0f),
  881. .inverted = params.Get("invert_x", "+") == "-",
  882. };
  883. const auto axis_y = params.Get("axis_y", 1);
  884. const Common::Input::AnalogProperties properties_y = {
  885. .deadzone = deadzone,
  886. .range = range,
  887. .threshold = threshold,
  888. .offset = std::clamp(params.Get("offset_y", 0.0f), -1.0f, 1.0f),
  889. .inverted = params.Get("invert_y", false) != 0,
  890. };
  891. input_engine->PreSetController(identifier);
  892. input_engine->PreSetAxis(identifier, axis_x);
  893. input_engine->PreSetAxis(identifier, axis_y);
  894. input_engine->PreSetButton(identifier, button);
  895. return std::make_unique<InputFromTouch>(identifier, button, toggle, inverted, axis_x, axis_y,
  896. properties_x, properties_y, input_engine.get());
  897. }
  898. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateBatteryDevice(
  899. const Common::ParamPackage& params) {
  900. const PadIdentifier identifier = {
  901. .guid = Common::UUID{params.Get("guid", "")},
  902. .port = static_cast<std::size_t>(params.Get("port", 0)),
  903. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  904. };
  905. input_engine->PreSetController(identifier);
  906. return std::make_unique<InputFromBattery>(identifier, input_engine.get());
  907. }
  908. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateColorDevice(
  909. const Common::ParamPackage& params) {
  910. const PadIdentifier identifier = {
  911. .guid = Common::UUID{params.Get("guid", "")},
  912. .port = static_cast<std::size_t>(params.Get("port", 0)),
  913. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  914. };
  915. input_engine->PreSetController(identifier);
  916. return std::make_unique<InputFromColor>(identifier, input_engine.get());
  917. }
  918. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateMotionDevice(
  919. Common::ParamPackage params) {
  920. const PadIdentifier identifier = {
  921. .guid = Common::UUID{params.Get("guid", "")},
  922. .port = static_cast<std::size_t>(params.Get("port", 0)),
  923. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  924. };
  925. if (params.Has("motion")) {
  926. const auto motion_sensor = params.Get("motion", 0);
  927. const auto gyro_threshold = params.Get("threshold", 0.007f);
  928. input_engine->PreSetController(identifier);
  929. input_engine->PreSetMotion(identifier, motion_sensor);
  930. return std::make_unique<InputFromMotion>(identifier, motion_sensor, gyro_threshold,
  931. input_engine.get());
  932. }
  933. const auto deadzone = std::clamp(params.Get("deadzone", 0.15f), 0.0f, 1.0f);
  934. const auto range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f);
  935. const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
  936. const auto axis_x = params.Get("axis_x", 0);
  937. const Common::Input::AnalogProperties properties_x = {
  938. .deadzone = deadzone,
  939. .range = range,
  940. .threshold = threshold,
  941. .offset = std::clamp(params.Get("offset_x", 0.0f), -1.0f, 1.0f),
  942. .inverted = params.Get("invert_x", "+") == "-",
  943. };
  944. const auto axis_y = params.Get("axis_y", 1);
  945. const Common::Input::AnalogProperties properties_y = {
  946. .deadzone = deadzone,
  947. .range = range,
  948. .threshold = threshold,
  949. .offset = std::clamp(params.Get("offset_y", 0.0f), -1.0f, 1.0f),
  950. .inverted = params.Get("invert_y", "+") != "+",
  951. };
  952. const auto axis_z = params.Get("axis_z", 1);
  953. const Common::Input::AnalogProperties properties_z = {
  954. .deadzone = deadzone,
  955. .range = range,
  956. .threshold = threshold,
  957. .offset = std::clamp(params.Get("offset_z", 0.0f), -1.0f, 1.0f),
  958. .inverted = params.Get("invert_z", "+") != "+",
  959. };
  960. input_engine->PreSetController(identifier);
  961. input_engine->PreSetAxis(identifier, axis_x);
  962. input_engine->PreSetAxis(identifier, axis_y);
  963. input_engine->PreSetAxis(identifier, axis_z);
  964. return std::make_unique<InputFromAxisMotion>(identifier, axis_x, axis_y, axis_z, properties_x,
  965. properties_y, properties_z, input_engine.get());
  966. }
  967. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateCameraDevice(
  968. const Common::ParamPackage& params) {
  969. const PadIdentifier identifier = {
  970. .guid = Common::UUID{params.Get("guid", "")},
  971. .port = static_cast<std::size_t>(params.Get("port", 0)),
  972. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  973. };
  974. input_engine->PreSetController(identifier);
  975. return std::make_unique<InputFromCamera>(identifier, input_engine.get());
  976. }
  977. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateNfcDevice(
  978. const Common::ParamPackage& params) {
  979. const PadIdentifier identifier = {
  980. .guid = Common::UUID{params.Get("guid", "")},
  981. .port = static_cast<std::size_t>(params.Get("port", 0)),
  982. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  983. };
  984. input_engine->PreSetController(identifier);
  985. return std::make_unique<InputFromNfc>(identifier, input_engine.get());
  986. }
  987. InputFactory::InputFactory(std::shared_ptr<InputEngine> input_engine_)
  988. : input_engine(std::move(input_engine_)) {}
  989. std::unique_ptr<Common::Input::InputDevice> InputFactory::Create(
  990. const Common::ParamPackage& params) {
  991. if (params.Has("battery")) {
  992. return CreateBatteryDevice(params);
  993. }
  994. if (params.Has("color")) {
  995. return CreateColorDevice(params);
  996. }
  997. if (params.Has("camera")) {
  998. return CreateCameraDevice(params);
  999. }
  1000. if (params.Has("nfc")) {
  1001. return CreateNfcDevice(params);
  1002. }
  1003. if (params.Has("button") && params.Has("axis")) {
  1004. return CreateTriggerDevice(params);
  1005. }
  1006. if (params.Has("button") && params.Has("axis_x") && params.Has("axis_y")) {
  1007. return CreateTouchDevice(params);
  1008. }
  1009. if (params.Has("button") || params.Has("code")) {
  1010. return CreateButtonDevice(params);
  1011. }
  1012. if (params.Has("hat")) {
  1013. return CreateHatButtonDevice(params);
  1014. }
  1015. if (params.Has("axis_x") && params.Has("axis_y") && params.Has("axis_z")) {
  1016. return CreateMotionDevice(params);
  1017. }
  1018. if (params.Has("motion")) {
  1019. return CreateMotionDevice(params);
  1020. }
  1021. if (params.Has("axis_x") && params.Has("axis_y")) {
  1022. return CreateStickDevice(params);
  1023. }
  1024. if (params.Has("axis")) {
  1025. return CreateAnalogDevice(params);
  1026. }
  1027. LOG_ERROR(Input, "Invalid parameters given");
  1028. return std::make_unique<DummyInput>();
  1029. }
  1030. OutputFactory::OutputFactory(std::shared_ptr<InputEngine> input_engine_)
  1031. : input_engine(std::move(input_engine_)) {}
  1032. std::unique_ptr<Common::Input::OutputDevice> OutputFactory::Create(
  1033. const Common::ParamPackage& params) {
  1034. const PadIdentifier identifier = {
  1035. .guid = Common::UUID{params.Get("guid", "")},
  1036. .port = static_cast<std::size_t>(params.Get("port", 0)),
  1037. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  1038. };
  1039. input_engine->PreSetController(identifier);
  1040. return std::make_unique<OutputFromIdentifier>(identifier, input_engine.get());
  1041. }
  1042. } // namespace InputCommon