input_poller.cpp 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200
  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,
  706. };
  707. TriggerOnChange(status);
  708. }
  709. private:
  710. const PadIdentifier identifier;
  711. int callback_key;
  712. InputEngine* input_engine;
  713. };
  714. class OutputFromIdentifier final : public Common::Input::OutputDevice {
  715. public:
  716. explicit OutputFromIdentifier(PadIdentifier identifier_, InputEngine* input_engine_)
  717. : identifier(identifier_), input_engine(input_engine_) {}
  718. Common::Input::DriverResult SetLED(const Common::Input::LedStatus& led_status) override {
  719. return input_engine->SetLeds(identifier, led_status);
  720. }
  721. Common::Input::DriverResult SetVibration(
  722. const Common::Input::VibrationStatus& vibration_status) override {
  723. return input_engine->SetVibration(identifier, vibration_status);
  724. }
  725. bool IsVibrationEnabled() override {
  726. return input_engine->IsVibrationEnabled(identifier);
  727. }
  728. Common::Input::DriverResult SetPollingMode(Common::Input::PollingMode polling_mode) override {
  729. return input_engine->SetPollingMode(identifier, polling_mode);
  730. }
  731. Common::Input::DriverResult SetCameraFormat(
  732. Common::Input::CameraFormat camera_format) override {
  733. return input_engine->SetCameraFormat(identifier, camera_format);
  734. }
  735. Common::Input::NfcState SupportsNfc() const override {
  736. return input_engine->SupportsNfc(identifier);
  737. }
  738. Common::Input::NfcState StartNfcPolling() {
  739. return input_engine->StartNfcPolling(identifier);
  740. }
  741. Common::Input::NfcState StopNfcPolling() {
  742. return input_engine->StopNfcPolling(identifier);
  743. }
  744. Common::Input::NfcState ReadAmiiboData(std::vector<u8>& out_data) {
  745. return input_engine->ReadAmiiboData(identifier, out_data);
  746. }
  747. Common::Input::NfcState WriteNfcData(const std::vector<u8>& data) override {
  748. return input_engine->WriteNfcData(identifier, data);
  749. }
  750. Common::Input::NfcState ReadMifareData(const Common::Input::MifareRequest& request,
  751. Common::Input::MifareRequest& out_data) {
  752. return input_engine->ReadMifareData(identifier, request, out_data);
  753. }
  754. Common::Input::NfcState WriteMifareData(const Common::Input::MifareRequest& request) {
  755. return input_engine->WriteMifareData(identifier, request);
  756. }
  757. private:
  758. const PadIdentifier identifier;
  759. InputEngine* input_engine;
  760. };
  761. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateButtonDevice(
  762. const Common::ParamPackage& params) {
  763. const PadIdentifier identifier = {
  764. .guid = Common::UUID{params.Get("guid", "")},
  765. .port = static_cast<std::size_t>(params.Get("port", 0)),
  766. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  767. };
  768. const auto button_id = params.Get("button", 0);
  769. const auto keyboard_key = params.Get("code", 0);
  770. const auto toggle = params.Get("toggle", false) != 0;
  771. const auto inverted = params.Get("inverted", false) != 0;
  772. const auto turbo = params.Get("turbo", false) != 0;
  773. input_engine->PreSetController(identifier);
  774. input_engine->PreSetButton(identifier, button_id);
  775. input_engine->PreSetButton(identifier, keyboard_key);
  776. if (keyboard_key != 0) {
  777. return std::make_unique<InputFromButton>(identifier, keyboard_key, turbo, toggle, inverted,
  778. input_engine.get());
  779. }
  780. return std::make_unique<InputFromButton>(identifier, button_id, turbo, toggle, inverted,
  781. input_engine.get());
  782. }
  783. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateHatButtonDevice(
  784. const Common::ParamPackage& params) {
  785. const PadIdentifier identifier = {
  786. .guid = Common::UUID{params.Get("guid", "")},
  787. .port = static_cast<std::size_t>(params.Get("port", 0)),
  788. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  789. };
  790. const auto button_id = params.Get("hat", 0);
  791. const auto direction = input_engine->GetHatButtonId(params.Get("direction", ""));
  792. const auto toggle = params.Get("toggle", false) != 0;
  793. const auto inverted = params.Get("inverted", false) != 0;
  794. const auto turbo = params.Get("turbo", false) != 0;
  795. input_engine->PreSetController(identifier);
  796. input_engine->PreSetHatButton(identifier, button_id);
  797. return std::make_unique<InputFromHatButton>(identifier, button_id, direction, turbo, toggle,
  798. inverted, input_engine.get());
  799. }
  800. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateStickDevice(
  801. const Common::ParamPackage& params) {
  802. const auto deadzone = std::clamp(params.Get("deadzone", 0.15f), 0.0f, 1.0f);
  803. const auto range = std::clamp(params.Get("range", 0.95f), 0.25f, 1.50f);
  804. const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
  805. const PadIdentifier identifier = {
  806. .guid = Common::UUID{params.Get("guid", "")},
  807. .port = static_cast<std::size_t>(params.Get("port", 0)),
  808. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  809. };
  810. const auto axis_x = params.Get("axis_x", 0);
  811. const Common::Input::AnalogProperties properties_x = {
  812. .deadzone = deadzone,
  813. .range = range,
  814. .threshold = threshold,
  815. .offset = std::clamp(params.Get("offset_x", 0.0f), -1.0f, 1.0f),
  816. .inverted = params.Get("invert_x", "+") == "-",
  817. };
  818. const auto axis_y = params.Get("axis_y", 1);
  819. const Common::Input::AnalogProperties properties_y = {
  820. .deadzone = deadzone,
  821. .range = range,
  822. .threshold = threshold,
  823. .offset = std::clamp(params.Get("offset_y", 0.0f), -1.0f, 1.0f),
  824. .inverted = params.Get("invert_y", "+") != "+",
  825. };
  826. input_engine->PreSetController(identifier);
  827. input_engine->PreSetAxis(identifier, axis_x);
  828. input_engine->PreSetAxis(identifier, axis_y);
  829. return std::make_unique<InputFromStick>(identifier, axis_x, axis_y, properties_x, properties_y,
  830. input_engine.get());
  831. }
  832. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateAnalogDevice(
  833. const Common::ParamPackage& params) {
  834. const PadIdentifier identifier = {
  835. .guid = Common::UUID{params.Get("guid", "")},
  836. .port = static_cast<std::size_t>(params.Get("port", 0)),
  837. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  838. };
  839. const auto axis = params.Get("axis", 0);
  840. const Common::Input::AnalogProperties properties = {
  841. .deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f),
  842. .range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f),
  843. .threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f),
  844. .offset = std::clamp(params.Get("offset", 0.0f), -1.0f, 1.0f),
  845. .inverted = params.Get("invert", "+") == "-",
  846. .inverted_button = params.Get("inverted", false) != 0,
  847. .toggle = params.Get("toggle", false) != 0,
  848. };
  849. input_engine->PreSetController(identifier);
  850. input_engine->PreSetAxis(identifier, axis);
  851. return std::make_unique<InputFromAnalog>(identifier, axis, properties, input_engine.get());
  852. }
  853. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateTriggerDevice(
  854. const Common::ParamPackage& params) {
  855. const PadIdentifier identifier = {
  856. .guid = Common::UUID{params.Get("guid", "")},
  857. .port = static_cast<std::size_t>(params.Get("port", 0)),
  858. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  859. };
  860. const auto button = params.Get("button", 0);
  861. const auto toggle = params.Get("toggle", false) != 0;
  862. const auto inverted = params.Get("inverted", false) != 0;
  863. const auto axis = params.Get("axis", 0);
  864. const Common::Input::AnalogProperties properties = {
  865. .deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f),
  866. .range = std::clamp(params.Get("range", 1.0f), 0.25f, 2.50f),
  867. .threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f),
  868. .offset = std::clamp(params.Get("offset", 0.0f), -1.0f, 1.0f),
  869. .inverted = params.Get("invert", false) != 0,
  870. };
  871. input_engine->PreSetController(identifier);
  872. input_engine->PreSetAxis(identifier, axis);
  873. input_engine->PreSetButton(identifier, button);
  874. return std::make_unique<InputFromTrigger>(identifier, button, toggle, inverted, axis,
  875. properties, input_engine.get());
  876. }
  877. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateTouchDevice(
  878. const Common::ParamPackage& params) {
  879. const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
  880. const auto range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f);
  881. const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
  882. const PadIdentifier identifier = {
  883. .guid = Common::UUID{params.Get("guid", "")},
  884. .port = static_cast<std::size_t>(params.Get("port", 0)),
  885. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  886. };
  887. const auto button = params.Get("button", 0);
  888. const auto toggle = params.Get("toggle", false) != 0;
  889. const auto inverted = params.Get("inverted", false) != 0;
  890. const auto axis_x = params.Get("axis_x", 0);
  891. const Common::Input::AnalogProperties properties_x = {
  892. .deadzone = deadzone,
  893. .range = range,
  894. .threshold = threshold,
  895. .offset = std::clamp(params.Get("offset_x", 0.0f), -1.0f, 1.0f),
  896. .inverted = params.Get("invert_x", "+") == "-",
  897. };
  898. const auto axis_y = params.Get("axis_y", 1);
  899. const Common::Input::AnalogProperties properties_y = {
  900. .deadzone = deadzone,
  901. .range = range,
  902. .threshold = threshold,
  903. .offset = std::clamp(params.Get("offset_y", 0.0f), -1.0f, 1.0f),
  904. .inverted = params.Get("invert_y", false) != 0,
  905. };
  906. input_engine->PreSetController(identifier);
  907. input_engine->PreSetAxis(identifier, axis_x);
  908. input_engine->PreSetAxis(identifier, axis_y);
  909. input_engine->PreSetButton(identifier, button);
  910. return std::make_unique<InputFromTouch>(identifier, button, toggle, inverted, axis_x, axis_y,
  911. properties_x, properties_y, input_engine.get());
  912. }
  913. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateBatteryDevice(
  914. const Common::ParamPackage& params) {
  915. const PadIdentifier identifier = {
  916. .guid = Common::UUID{params.Get("guid", "")},
  917. .port = static_cast<std::size_t>(params.Get("port", 0)),
  918. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  919. };
  920. input_engine->PreSetController(identifier);
  921. return std::make_unique<InputFromBattery>(identifier, input_engine.get());
  922. }
  923. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateColorDevice(
  924. const Common::ParamPackage& params) {
  925. const PadIdentifier identifier = {
  926. .guid = Common::UUID{params.Get("guid", "")},
  927. .port = static_cast<std::size_t>(params.Get("port", 0)),
  928. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  929. };
  930. input_engine->PreSetController(identifier);
  931. return std::make_unique<InputFromColor>(identifier, input_engine.get());
  932. }
  933. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateMotionDevice(
  934. Common::ParamPackage params) {
  935. const PadIdentifier identifier = {
  936. .guid = Common::UUID{params.Get("guid", "")},
  937. .port = static_cast<std::size_t>(params.Get("port", 0)),
  938. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  939. };
  940. if (params.Has("motion")) {
  941. const auto motion_sensor = params.Get("motion", 0);
  942. const auto gyro_threshold = params.Get("threshold", 0.007f);
  943. input_engine->PreSetController(identifier);
  944. input_engine->PreSetMotion(identifier, motion_sensor);
  945. return std::make_unique<InputFromMotion>(identifier, motion_sensor, gyro_threshold,
  946. input_engine.get());
  947. }
  948. const auto deadzone = std::clamp(params.Get("deadzone", 0.15f), 0.0f, 1.0f);
  949. const auto range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f);
  950. const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
  951. const auto axis_x = params.Get("axis_x", 0);
  952. const Common::Input::AnalogProperties properties_x = {
  953. .deadzone = deadzone,
  954. .range = range,
  955. .threshold = threshold,
  956. .offset = std::clamp(params.Get("offset_x", 0.0f), -1.0f, 1.0f),
  957. .inverted = params.Get("invert_x", "+") == "-",
  958. };
  959. const auto axis_y = params.Get("axis_y", 1);
  960. const Common::Input::AnalogProperties properties_y = {
  961. .deadzone = deadzone,
  962. .range = range,
  963. .threshold = threshold,
  964. .offset = std::clamp(params.Get("offset_y", 0.0f), -1.0f, 1.0f),
  965. .inverted = params.Get("invert_y", "+") != "+",
  966. };
  967. const auto axis_z = params.Get("axis_z", 1);
  968. const Common::Input::AnalogProperties properties_z = {
  969. .deadzone = deadzone,
  970. .range = range,
  971. .threshold = threshold,
  972. .offset = std::clamp(params.Get("offset_z", 0.0f), -1.0f, 1.0f),
  973. .inverted = params.Get("invert_z", "+") != "+",
  974. };
  975. input_engine->PreSetController(identifier);
  976. input_engine->PreSetAxis(identifier, axis_x);
  977. input_engine->PreSetAxis(identifier, axis_y);
  978. input_engine->PreSetAxis(identifier, axis_z);
  979. return std::make_unique<InputFromAxisMotion>(identifier, axis_x, axis_y, axis_z, properties_x,
  980. properties_y, properties_z, input_engine.get());
  981. }
  982. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateCameraDevice(
  983. const Common::ParamPackage& params) {
  984. const PadIdentifier identifier = {
  985. .guid = Common::UUID{params.Get("guid", "")},
  986. .port = static_cast<std::size_t>(params.Get("port", 0)),
  987. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  988. };
  989. input_engine->PreSetController(identifier);
  990. return std::make_unique<InputFromCamera>(identifier, input_engine.get());
  991. }
  992. std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateNfcDevice(
  993. const Common::ParamPackage& params) {
  994. const PadIdentifier identifier = {
  995. .guid = Common::UUID{params.Get("guid", "")},
  996. .port = static_cast<std::size_t>(params.Get("port", 0)),
  997. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  998. };
  999. input_engine->PreSetController(identifier);
  1000. return std::make_unique<InputFromNfc>(identifier, input_engine.get());
  1001. }
  1002. InputFactory::InputFactory(std::shared_ptr<InputEngine> input_engine_)
  1003. : input_engine(std::move(input_engine_)) {}
  1004. std::unique_ptr<Common::Input::InputDevice> InputFactory::Create(
  1005. const Common::ParamPackage& params) {
  1006. if (params.Has("battery")) {
  1007. return CreateBatteryDevice(params);
  1008. }
  1009. if (params.Has("color")) {
  1010. return CreateColorDevice(params);
  1011. }
  1012. if (params.Has("camera")) {
  1013. return CreateCameraDevice(params);
  1014. }
  1015. if (params.Has("nfc")) {
  1016. return CreateNfcDevice(params);
  1017. }
  1018. if (params.Has("button") && params.Has("axis")) {
  1019. return CreateTriggerDevice(params);
  1020. }
  1021. if (params.Has("button") && params.Has("axis_x") && params.Has("axis_y")) {
  1022. return CreateTouchDevice(params);
  1023. }
  1024. if (params.Has("button") || params.Has("code")) {
  1025. return CreateButtonDevice(params);
  1026. }
  1027. if (params.Has("hat")) {
  1028. return CreateHatButtonDevice(params);
  1029. }
  1030. if (params.Has("axis_x") && params.Has("axis_y") && params.Has("axis_z")) {
  1031. return CreateMotionDevice(params);
  1032. }
  1033. if (params.Has("motion")) {
  1034. return CreateMotionDevice(params);
  1035. }
  1036. if (params.Has("axis_x") && params.Has("axis_y")) {
  1037. return CreateStickDevice(params);
  1038. }
  1039. if (params.Has("axis")) {
  1040. return CreateAnalogDevice(params);
  1041. }
  1042. LOG_ERROR(Input, "Invalid parameters given");
  1043. return std::make_unique<DummyInput>();
  1044. }
  1045. OutputFactory::OutputFactory(std::shared_ptr<InputEngine> input_engine_)
  1046. : input_engine(std::move(input_engine_)) {}
  1047. std::unique_ptr<Common::Input::OutputDevice> OutputFactory::Create(
  1048. const Common::ParamPackage& params) {
  1049. const PadIdentifier identifier = {
  1050. .guid = Common::UUID{params.Get("guid", "")},
  1051. .port = static_cast<std::size_t>(params.Get("port", 0)),
  1052. .pad = static_cast<std::size_t>(params.Get("pad", 0)),
  1053. };
  1054. input_engine->PreSetController(identifier);
  1055. return std::make_unique<OutputFromIdentifier>(identifier, input_engine.get());
  1056. }
  1057. } // namespace InputCommon