input_poller.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975
  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() = default;
  12. };
  13. class InputFromButton final : public Common::Input::InputDevice {
  14. public:
  15. explicit InputFromButton(PadIdentifier identifier_, int button_, bool toggle_, bool inverted_,
  16. InputEngine* input_engine_)
  17. : identifier(identifier_), button(button_), toggle(toggle_), inverted(inverted_),
  18. input_engine(input_engine_) {
  19. UpdateCallback engine_callback{[this]() { OnChange(); }};
  20. const InputIdentifier input_identifier{
  21. .identifier = identifier,
  22. .type = EngineInputType::Button,
  23. .index = button,
  24. .callback = engine_callback,
  25. };
  26. last_button_value = false;
  27. callback_key = input_engine->SetCallback(input_identifier);
  28. }
  29. ~InputFromButton() override {
  30. input_engine->DeleteCallback(callback_key);
  31. }
  32. Common::Input::ButtonStatus GetStatus() const {
  33. return {
  34. .value = input_engine->GetButton(identifier, button),
  35. .inverted = inverted,
  36. .toggle = toggle,
  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 toggle;
  61. const bool inverted;
  62. int callback_key;
  63. bool last_button_value;
  64. InputEngine* input_engine;
  65. };
  66. class InputFromHatButton final : public Common::Input::InputDevice {
  67. public:
  68. explicit InputFromHatButton(PadIdentifier identifier_, int button_, u8 direction_, bool toggle_,
  69. bool inverted_, InputEngine* input_engine_)
  70. : identifier(identifier_), button(button_), direction(direction_), toggle(toggle_),
  71. inverted(inverted_), input_engine(input_engine_) {
  72. UpdateCallback engine_callback{[this]() { OnChange(); }};
  73. const InputIdentifier input_identifier{
  74. .identifier = identifier,
  75. .type = EngineInputType::HatButton,
  76. .index = button,
  77. .callback = engine_callback,
  78. };
  79. last_button_value = false;
  80. callback_key = input_engine->SetCallback(input_identifier);
  81. }
  82. ~InputFromHatButton() override {
  83. input_engine->DeleteCallback(callback_key);
  84. }
  85. Common::Input::ButtonStatus GetStatus() const {
  86. return {
  87. .value = input_engine->GetHatButton(identifier, button, direction),
  88. .inverted = inverted,
  89. .toggle = toggle,
  90. };
  91. }
  92. void ForceUpdate() override {
  93. const Common::Input::CallbackStatus status{
  94. .type = Common::Input::InputType::Button,
  95. .button_status = GetStatus(),
  96. };
  97. last_button_value = status.button_status.value;
  98. TriggerOnChange(status);
  99. }
  100. void OnChange() {
  101. const Common::Input::CallbackStatus status{
  102. .type = Common::Input::InputType::Button,
  103. .button_status = GetStatus(),
  104. };
  105. if (status.button_status.value != last_button_value) {
  106. last_button_value = status.button_status.value;
  107. TriggerOnChange(status);
  108. }
  109. }
  110. private:
  111. const PadIdentifier identifier;
  112. const int button;
  113. const u8 direction;
  114. const bool toggle;
  115. const bool inverted;
  116. int callback_key;
  117. bool last_button_value;
  118. InputEngine* input_engine;
  119. };
  120. class InputFromStick final : public Common::Input::InputDevice {
  121. public:
  122. explicit InputFromStick(PadIdentifier identifier_, int axis_x_, int axis_y_,
  123. Common::Input::AnalogProperties properties_x_,
  124. Common::Input::AnalogProperties properties_y_,
  125. InputEngine* input_engine_)
  126. : identifier(identifier_), axis_x(axis_x_), axis_y(axis_y_), properties_x(properties_x_),
  127. properties_y(properties_y_),
  128. input_engine(input_engine_), invert_axis_y{input_engine_->GetEngineName() == "sdl"} {
  129. UpdateCallback engine_callback{[this]() { OnChange(); }};
  130. const InputIdentifier x_input_identifier{
  131. .identifier = identifier,
  132. .type = EngineInputType::Analog,
  133. .index = axis_x,
  134. .callback = engine_callback,
  135. };
  136. const InputIdentifier y_input_identifier{
  137. .identifier = identifier,
  138. .type = EngineInputType::Analog,
  139. .index = axis_y,
  140. .callback = engine_callback,
  141. };
  142. last_axis_x_value = 0.0f;
  143. last_axis_y_value = 0.0f;
  144. callback_key_x = input_engine->SetCallback(x_input_identifier);
  145. callback_key_y = input_engine->SetCallback(y_input_identifier);
  146. }
  147. ~InputFromStick() override {
  148. input_engine->DeleteCallback(callback_key_x);
  149. input_engine->DeleteCallback(callback_key_y);
  150. }
  151. Common::Input::StickStatus GetStatus() const {
  152. Common::Input::StickStatus status;
  153. status.x = {
  154. .raw_value = input_engine->GetAxis(identifier, axis_x),
  155. .properties = properties_x,
  156. };
  157. status.y = {
  158. .raw_value = input_engine->GetAxis(identifier, axis_y),
  159. .properties = properties_y,
  160. };
  161. // This is a workaround too keep compatibility with old yuzu versions. Vertical axis is
  162. // inverted on SDL compared to Nintendo
  163. if (invert_axis_y) {
  164. status.y.raw_value = -status.y.raw_value;
  165. }
  166. return status;
  167. }
  168. void ForceUpdate() override {
  169. const Common::Input::CallbackStatus status{
  170. .type = Common::Input::InputType::Stick,
  171. .stick_status = GetStatus(),
  172. };
  173. last_axis_x_value = status.stick_status.x.raw_value;
  174. last_axis_y_value = status.stick_status.y.raw_value;
  175. TriggerOnChange(status);
  176. }
  177. void OnChange() {
  178. const Common::Input::CallbackStatus status{
  179. .type = Common::Input::InputType::Stick,
  180. .stick_status = GetStatus(),
  181. };
  182. if (status.stick_status.x.raw_value != last_axis_x_value ||
  183. status.stick_status.y.raw_value != last_axis_y_value) {
  184. last_axis_x_value = status.stick_status.x.raw_value;
  185. last_axis_y_value = status.stick_status.y.raw_value;
  186. TriggerOnChange(status);
  187. }
  188. }
  189. private:
  190. const PadIdentifier identifier;
  191. const int axis_x;
  192. const int axis_y;
  193. const Common::Input::AnalogProperties properties_x;
  194. const Common::Input::AnalogProperties properties_y;
  195. int callback_key_x;
  196. int callback_key_y;
  197. float last_axis_x_value;
  198. float last_axis_y_value;
  199. InputEngine* input_engine;
  200. const bool invert_axis_y;
  201. };
  202. class InputFromTouch final : public Common::Input::InputDevice {
  203. public:
  204. explicit InputFromTouch(PadIdentifier identifier_, int touch_id_, int button_, bool toggle_,
  205. bool inverted_, int axis_x_, int axis_y_,
  206. Common::Input::AnalogProperties properties_x_,
  207. Common::Input::AnalogProperties properties_y_,
  208. InputEngine* input_engine_)
  209. : identifier(identifier_), touch_id(touch_id_), button(button_), toggle(toggle_),
  210. inverted(inverted_), axis_x(axis_x_), axis_y(axis_y_), properties_x(properties_x_),
  211. properties_y(properties_y_), input_engine(input_engine_) {
  212. UpdateCallback engine_callback{[this]() { OnChange(); }};
  213. const InputIdentifier button_input_identifier{
  214. .identifier = identifier,
  215. .type = EngineInputType::Button,
  216. .index = button,
  217. .callback = engine_callback,
  218. };
  219. const InputIdentifier x_input_identifier{
  220. .identifier = identifier,
  221. .type = EngineInputType::Analog,
  222. .index = axis_x,
  223. .callback = engine_callback,
  224. };
  225. const InputIdentifier y_input_identifier{
  226. .identifier = identifier,
  227. .type = EngineInputType::Analog,
  228. .index = axis_y,
  229. .callback = engine_callback,
  230. };
  231. last_axis_x_value = 0.0f;
  232. last_axis_y_value = 0.0f;
  233. last_button_value = false;
  234. callback_key_button = input_engine->SetCallback(button_input_identifier);
  235. callback_key_x = input_engine->SetCallback(x_input_identifier);
  236. callback_key_y = input_engine->SetCallback(y_input_identifier);
  237. }
  238. ~InputFromTouch() override {
  239. input_engine->DeleteCallback(callback_key_button);
  240. input_engine->DeleteCallback(callback_key_x);
  241. input_engine->DeleteCallback(callback_key_y);
  242. }
  243. Common::Input::TouchStatus GetStatus() const {
  244. Common::Input::TouchStatus status;
  245. status.id = touch_id;
  246. status.pressed = {
  247. .value = input_engine->GetButton(identifier, button),
  248. .inverted = inverted,
  249. .toggle = toggle,
  250. };
  251. status.x = {
  252. .raw_value = input_engine->GetAxis(identifier, axis_x),
  253. .properties = properties_x,
  254. };
  255. status.y = {
  256. .raw_value = input_engine->GetAxis(identifier, axis_y),
  257. .properties = properties_y,
  258. };
  259. return status;
  260. }
  261. void OnChange() {
  262. const Common::Input::CallbackStatus status{
  263. .type = Common::Input::InputType::Touch,
  264. .touch_status = GetStatus(),
  265. };
  266. if (status.touch_status.x.raw_value != last_axis_x_value ||
  267. status.touch_status.y.raw_value != last_axis_y_value ||
  268. status.touch_status.pressed.value != last_button_value) {
  269. last_axis_x_value = status.touch_status.x.raw_value;
  270. last_axis_y_value = status.touch_status.y.raw_value;
  271. last_button_value = status.touch_status.pressed.value;
  272. TriggerOnChange(status);
  273. }
  274. }
  275. private:
  276. const PadIdentifier identifier;
  277. const int touch_id;
  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 InputFromMotion final : public Common::Input::InputDevice {
  451. public:
  452. explicit InputFromMotion(PadIdentifier identifier_, int motion_sensor_, float gyro_threshold_,
  453. InputEngine* input_engine_)
  454. : identifier(identifier_), motion_sensor(motion_sensor_), gyro_threshold(gyro_threshold_),
  455. 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() override {
  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.0f,
  473. .range = 1.0f,
  474. .threshold = gyro_threshold,
  475. .offset = 0.0f,
  476. };
  477. status.accel.x = {.raw_value = basic_motion.accel_x, .properties = properties};
  478. status.accel.y = {.raw_value = basic_motion.accel_y, .properties = properties};
  479. status.accel.z = {.raw_value = basic_motion.accel_z, .properties = properties};
  480. status.gyro.x = {.raw_value = basic_motion.gyro_x, .properties = properties};
  481. status.gyro.y = {.raw_value = basic_motion.gyro_y, .properties = properties};
  482. status.gyro.z = {.raw_value = basic_motion.gyro_z, .properties = properties};
  483. status.delta_timestamp = basic_motion.delta_timestamp;
  484. return status;
  485. }
  486. void OnChange() {
  487. const Common::Input::CallbackStatus status{
  488. .type = Common::Input::InputType::Motion,
  489. .motion_status = GetStatus(),
  490. };
  491. TriggerOnChange(status);
  492. }
  493. private:
  494. const PadIdentifier identifier;
  495. const int motion_sensor;
  496. const float gyro_threshold;
  497. int callback_key;
  498. InputEngine* input_engine;
  499. };
  500. class InputFromAxisMotion final : public Common::Input::InputDevice {
  501. public:
  502. explicit InputFromAxisMotion(PadIdentifier identifier_, int axis_x_, int axis_y_, int axis_z_,
  503. Common::Input::AnalogProperties properties_x_,
  504. Common::Input::AnalogProperties properties_y_,
  505. Common::Input::AnalogProperties properties_z_,
  506. InputEngine* input_engine_)
  507. : identifier(identifier_), axis_x(axis_x_), axis_y(axis_y_), axis_z(axis_z_),
  508. properties_x(properties_x_), properties_y(properties_y_), properties_z(properties_z_),
  509. input_engine(input_engine_) {
  510. UpdateCallback engine_callback{[this]() { OnChange(); }};
  511. const InputIdentifier x_input_identifier{
  512. .identifier = identifier,
  513. .type = EngineInputType::Analog,
  514. .index = axis_x,
  515. .callback = engine_callback,
  516. };
  517. const InputIdentifier y_input_identifier{
  518. .identifier = identifier,
  519. .type = EngineInputType::Analog,
  520. .index = axis_y,
  521. .callback = engine_callback,
  522. };
  523. const InputIdentifier z_input_identifier{
  524. .identifier = identifier,
  525. .type = EngineInputType::Analog,
  526. .index = axis_z,
  527. .callback = engine_callback,
  528. };
  529. last_axis_x_value = 0.0f;
  530. last_axis_y_value = 0.0f;
  531. last_axis_z_value = 0.0f;
  532. callback_key_x = input_engine->SetCallback(x_input_identifier);
  533. callback_key_y = input_engine->SetCallback(y_input_identifier);
  534. callback_key_z = input_engine->SetCallback(z_input_identifier);
  535. }
  536. ~InputFromAxisMotion() override {
  537. input_engine->DeleteCallback(callback_key_x);
  538. input_engine->DeleteCallback(callback_key_y);
  539. input_engine->DeleteCallback(callback_key_z);
  540. }
  541. Common::Input::MotionStatus GetStatus() const {
  542. Common::Input::MotionStatus status{};
  543. status.gyro.x = {
  544. .raw_value = input_engine->GetAxis(identifier, axis_x),
  545. .properties = properties_x,
  546. };
  547. status.gyro.y = {
  548. .raw_value = input_engine->GetAxis(identifier, axis_y),
  549. .properties = properties_y,
  550. };
  551. status.gyro.z = {
  552. .raw_value = input_engine->GetAxis(identifier, axis_z),
  553. .properties = properties_z,
  554. };
  555. status.delta_timestamp = 5000;
  556. status.force_update = true;
  557. return status;
  558. }
  559. void ForceUpdate() override {
  560. const Common::Input::CallbackStatus status{
  561. .type = Common::Input::InputType::Motion,
  562. .motion_status = GetStatus(),
  563. };
  564. last_axis_x_value = status.motion_status.gyro.x.raw_value;
  565. last_axis_y_value = status.motion_status.gyro.y.raw_value;
  566. last_axis_z_value = status.motion_status.gyro.z.raw_value;
  567. TriggerOnChange(status);
  568. }
  569. void OnChange() {
  570. const Common::Input::CallbackStatus status{
  571. .type = Common::Input::InputType::Motion,
  572. .motion_status = GetStatus(),
  573. };
  574. if (status.motion_status.gyro.x.raw_value != last_axis_x_value ||
  575. status.motion_status.gyro.y.raw_value != last_axis_y_value ||
  576. status.motion_status.gyro.z.raw_value != last_axis_z_value) {
  577. last_axis_x_value = status.motion_status.gyro.x.raw_value;
  578. last_axis_y_value = status.motion_status.gyro.y.raw_value;
  579. last_axis_z_value = status.motion_status.gyro.z.raw_value;
  580. TriggerOnChange(status);
  581. }
  582. }
  583. private:
  584. const PadIdentifier identifier;
  585. const int axis_x;
  586. const int axis_y;
  587. const int axis_z;
  588. const Common::Input::AnalogProperties properties_x;
  589. const Common::Input::AnalogProperties properties_y;
  590. const Common::Input::AnalogProperties properties_z;
  591. int callback_key_x;
  592. int callback_key_y;
  593. int callback_key_z;
  594. float last_axis_x_value;
  595. float last_axis_y_value;
  596. float last_axis_z_value;
  597. InputEngine* input_engine;
  598. };
  599. class OutputFromIdentifier final : public Common::Input::OutputDevice {
  600. public:
  601. explicit OutputFromIdentifier(PadIdentifier identifier_, InputEngine* input_engine_)
  602. : identifier(identifier_), input_engine(input_engine_) {}
  603. void SetLED(const Common::Input::LedStatus& led_status) override {
  604. input_engine->SetLeds(identifier, led_status);
  605. }
  606. Common::Input::VibrationError SetVibration(
  607. const Common::Input::VibrationStatus& vibration_status) override {
  608. return input_engine->SetRumble(identifier, vibration_status);
  609. }
  610. Common::Input::PollingError SetPollingMode(Common::Input::PollingMode polling_mode) override {
  611. return input_engine->SetPollingMode(identifier, polling_mode);
  612. }
  613. private:
  614. const PadIdentifier identifier;
  615. InputEngine* input_engine;
  616. };
  617. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateButtonDevice(
  618. const Common::ParamPackage& params) {
  619. const PadIdentifier identifier = {
  620. .guid = Common::UUID{params.Get("guid", "")},
  621. .port = static_cast<std::size_t>(params.Get("port", 0)),
  622. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  623. };
  624. const auto button_id = params.Get("button", 0);
  625. const auto keyboard_key = params.Get("code", 0);
  626. const auto toggle = params.Get("toggle", false);
  627. const auto inverted = params.Get("inverted", false);
  628. input_engine->PreSetController(identifier);
  629. input_engine->PreSetButton(identifier, button_id);
  630. input_engine->PreSetButton(identifier, keyboard_key);
  631. if (keyboard_key != 0) {
  632. return std::make_unique<InputFromButton>(identifier, keyboard_key, toggle, inverted,
  633. input_engine.get());
  634. }
  635. return std::make_unique<InputFromButton>(identifier, button_id, toggle, inverted,
  636. input_engine.get());
  637. }
  638. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateHatButtonDevice(
  639. const Common::ParamPackage& params) {
  640. const PadIdentifier identifier = {
  641. .guid = Common::UUID{params.Get("guid", "")},
  642. .port = static_cast<std::size_t>(params.Get("port", 0)),
  643. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  644. };
  645. const auto button_id = params.Get("hat", 0);
  646. const auto direction = input_engine->GetHatButtonId(params.Get("direction", ""));
  647. const auto toggle = params.Get("toggle", false);
  648. const auto inverted = params.Get("inverted", false);
  649. input_engine->PreSetController(identifier);
  650. input_engine->PreSetHatButton(identifier, button_id);
  651. return std::make_unique<InputFromHatButton>(identifier, button_id, direction, toggle, inverted,
  652. input_engine.get());
  653. }
  654. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateStickDevice(
  655. const Common::ParamPackage& params) {
  656. const auto deadzone = std::clamp(params.Get("deadzone", 0.15f), 0.0f, 1.0f);
  657. const auto range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f);
  658. const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
  659. const PadIdentifier identifier = {
  660. .guid = Common::UUID{params.Get("guid", "")},
  661. .port = static_cast<std::size_t>(params.Get("port", 0)),
  662. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  663. };
  664. const auto axis_x = params.Get("axis_x", 0);
  665. const Common::Input::AnalogProperties properties_x = {
  666. .deadzone = deadzone,
  667. .range = range,
  668. .threshold = threshold,
  669. .offset = std::clamp(params.Get("offset_x", 0.0f), -1.0f, 1.0f),
  670. .inverted = params.Get("invert_x", "+") == "-",
  671. };
  672. const auto axis_y = params.Get("axis_y", 1);
  673. const Common::Input::AnalogProperties properties_y = {
  674. .deadzone = deadzone,
  675. .range = range,
  676. .threshold = threshold,
  677. .offset = std::clamp(params.Get("offset_y", 0.0f), -1.0f, 1.0f),
  678. .inverted = params.Get("invert_y", "+") != "+",
  679. };
  680. input_engine->PreSetController(identifier);
  681. input_engine->PreSetAxis(identifier, axis_x);
  682. input_engine->PreSetAxis(identifier, axis_y);
  683. return std::make_unique<InputFromStick>(identifier, axis_x, axis_y, properties_x, properties_y,
  684. input_engine.get());
  685. }
  686. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateAnalogDevice(
  687. const Common::ParamPackage& params) {
  688. const PadIdentifier identifier = {
  689. .guid = Common::UUID{params.Get("guid", "")},
  690. .port = static_cast<std::size_t>(params.Get("port", 0)),
  691. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  692. };
  693. const auto axis = params.Get("axis", 0);
  694. const Common::Input::AnalogProperties properties = {
  695. .deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f),
  696. .range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f),
  697. .threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f),
  698. .offset = std::clamp(params.Get("offset", 0.0f), -1.0f, 1.0f),
  699. .inverted = params.Get("invert", "+") == "-",
  700. };
  701. input_engine->PreSetController(identifier);
  702. input_engine->PreSetAxis(identifier, axis);
  703. return std::make_unique<InputFromAnalog>(identifier, axis, properties, input_engine.get());
  704. }
  705. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateTriggerDevice(
  706. const Common::ParamPackage& params) {
  707. const PadIdentifier identifier = {
  708. .guid = Common::UUID{params.Get("guid", "")},
  709. .port = static_cast<std::size_t>(params.Get("port", 0)),
  710. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  711. };
  712. const auto button = params.Get("button", 0);
  713. const auto toggle = params.Get("toggle", false);
  714. const auto inverted = params.Get("inverted", false);
  715. const auto axis = params.Get("axis", 0);
  716. const Common::Input::AnalogProperties properties = {
  717. .deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f),
  718. .range = std::clamp(params.Get("range", 1.0f), 0.25f, 2.50f),
  719. .threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f),
  720. .offset = std::clamp(params.Get("offset", 0.0f), -1.0f, 1.0f),
  721. .inverted = params.Get("invert", false) != 0,
  722. };
  723. input_engine->PreSetController(identifier);
  724. input_engine->PreSetAxis(identifier, axis);
  725. input_engine->PreSetButton(identifier, button);
  726. return std::make_unique<InputFromTrigger>(identifier, button, toggle, inverted, axis,
  727. properties, input_engine.get());
  728. }
  729. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateTouchDevice(
  730. const Common::ParamPackage& params) {
  731. const auto touch_id = params.Get("touch_id", 0);
  732. const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
  733. const auto range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f);
  734. const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
  735. const PadIdentifier identifier = {
  736. .guid = Common::UUID{params.Get("guid", "")},
  737. .port = static_cast<std::size_t>(params.Get("port", 0)),
  738. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  739. };
  740. const auto button = params.Get("button", 0);
  741. const auto toggle = params.Get("toggle", false);
  742. const auto inverted = params.Get("inverted", false);
  743. const auto axis_x = params.Get("axis_x", 0);
  744. const Common::Input::AnalogProperties properties_x = {
  745. .deadzone = deadzone,
  746. .range = range,
  747. .threshold = threshold,
  748. .offset = std::clamp(params.Get("offset_x", 0.0f), -1.0f, 1.0f),
  749. .inverted = params.Get("invert_x", "+") == "-",
  750. };
  751. const auto axis_y = params.Get("axis_y", 1);
  752. const Common::Input::AnalogProperties properties_y = {
  753. .deadzone = deadzone,
  754. .range = range,
  755. .threshold = threshold,
  756. .offset = std::clamp(params.Get("offset_y", 0.0f), -1.0f, 1.0f),
  757. .inverted = params.Get("invert_y", false) != 0,
  758. };
  759. input_engine->PreSetController(identifier);
  760. input_engine->PreSetAxis(identifier, axis_x);
  761. input_engine->PreSetAxis(identifier, axis_y);
  762. input_engine->PreSetButton(identifier, button);
  763. return std::make_unique<InputFromTouch>(identifier, touch_id, button, toggle, inverted, axis_x,
  764. axis_y, properties_x, properties_y, input_engine.get());
  765. }
  766. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateBatteryDevice(
  767. const Common::ParamPackage& params) {
  768. const PadIdentifier identifier = {
  769. .guid = Common::UUID{params.Get("guid", "")},
  770. .port = static_cast<std::size_t>(params.Get("port", 0)),
  771. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  772. };
  773. input_engine->PreSetController(identifier);
  774. return std::make_unique<InputFromBattery>(identifier, input_engine.get());
  775. }
  776. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateMotionDevice(
  777. Common::ParamPackage params) {
  778. const PadIdentifier identifier = {
  779. .guid = Common::UUID{params.Get("guid", "")},
  780. .port = static_cast<std::size_t>(params.Get("port", 0)),
  781. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  782. };
  783. if (params.Has("motion")) {
  784. const auto motion_sensor = params.Get("motion", 0);
  785. const auto gyro_threshold = params.Get("threshold", 0.007f);
  786. input_engine->PreSetController(identifier);
  787. input_engine->PreSetMotion(identifier, motion_sensor);
  788. return std::make_unique<InputFromMotion>(identifier, motion_sensor, gyro_threshold,
  789. input_engine.get());
  790. }
  791. const auto deadzone = std::clamp(params.Get("deadzone", 0.15f), 0.0f, 1.0f);
  792. const auto range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f);
  793. const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
  794. const auto axis_x = params.Get("axis_x", 0);
  795. const Common::Input::AnalogProperties properties_x = {
  796. .deadzone = deadzone,
  797. .range = range,
  798. .threshold = threshold,
  799. .offset = std::clamp(params.Get("offset_x", 0.0f), -1.0f, 1.0f),
  800. .inverted = params.Get("invert_x", "+") == "-",
  801. };
  802. const auto axis_y = params.Get("axis_y", 1);
  803. const Common::Input::AnalogProperties properties_y = {
  804. .deadzone = deadzone,
  805. .range = range,
  806. .threshold = threshold,
  807. .offset = std::clamp(params.Get("offset_y", 0.0f), -1.0f, 1.0f),
  808. .inverted = params.Get("invert_y", "+") != "+",
  809. };
  810. const auto axis_z = params.Get("axis_z", 1);
  811. const Common::Input::AnalogProperties properties_z = {
  812. .deadzone = deadzone,
  813. .range = range,
  814. .threshold = threshold,
  815. .offset = std::clamp(params.Get("offset_z", 0.0f), -1.0f, 1.0f),
  816. .inverted = params.Get("invert_z", "+") != "+",
  817. };
  818. input_engine->PreSetController(identifier);
  819. input_engine->PreSetAxis(identifier, axis_x);
  820. input_engine->PreSetAxis(identifier, axis_y);
  821. input_engine->PreSetAxis(identifier, axis_z);
  822. return std::make_unique<InputFromAxisMotion>(identifier, axis_x, axis_y, axis_z, properties_x,
  823. properties_y, properties_z, input_engine.get());
  824. }
  825. InputFactory::InputFactory(std::shared_ptr<InputEngine> input_engine_)
  826. : input_engine(std::move(input_engine_)) {}
  827. std::unique_ptr<Common::Input::InputDevice> InputFactory::Create(
  828. const Common::ParamPackage& params) {
  829. if (params.Has("battery")) {
  830. return CreateBatteryDevice(params);
  831. }
  832. if (params.Has("button") && params.Has("axis")) {
  833. return CreateTriggerDevice(params);
  834. }
  835. if (params.Has("button") && params.Has("axis_x") && params.Has("axis_y")) {
  836. return CreateTouchDevice(params);
  837. }
  838. if (params.Has("button") || params.Has("code")) {
  839. return CreateButtonDevice(params);
  840. }
  841. if (params.Has("hat")) {
  842. return CreateHatButtonDevice(params);
  843. }
  844. if (params.Has("axis_x") && params.Has("axis_y") && params.Has("axis_z")) {
  845. return CreateMotionDevice(params);
  846. }
  847. if (params.Has("motion")) {
  848. return CreateMotionDevice(params);
  849. }
  850. if (params.Has("axis_x") && params.Has("axis_y")) {
  851. return CreateStickDevice(params);
  852. }
  853. if (params.Has("axis")) {
  854. return CreateAnalogDevice(params);
  855. }
  856. LOG_ERROR(Input, "Invalid parameters given");
  857. return std::make_unique<DummyInput>();
  858. }
  859. OutputFactory::OutputFactory(std::shared_ptr<InputEngine> input_engine_)
  860. : input_engine(std::move(input_engine_)) {}
  861. std::unique_ptr<Common::Input::OutputDevice> OutputFactory::Create(
  862. const Common::ParamPackage& params) {
  863. const PadIdentifier identifier = {
  864. .guid = Common::UUID{params.Get("guid", "")},
  865. .port = static_cast<std::size_t>(params.Get("port", 0)),
  866. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  867. };
  868. input_engine->PreSetController(identifier);
  869. return std::make_unique<OutputFromIdentifier>(identifier, input_engine.get());
  870. }
  871. } // namespace InputCommon