input_engine.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "common/logging/log.h"
  4. #include "input_common/input_engine.h"
  5. namespace InputCommon {
  6. void InputEngine::PreSetController(const PadIdentifier& identifier) {
  7. std::scoped_lock lock{mutex};
  8. controller_list.try_emplace(identifier);
  9. }
  10. void InputEngine::PreSetButton(const PadIdentifier& identifier, int button) {
  11. std::scoped_lock lock{mutex};
  12. ControllerData& controller = controller_list.at(identifier);
  13. controller.buttons.try_emplace(button, false);
  14. }
  15. void InputEngine::PreSetHatButton(const PadIdentifier& identifier, int button) {
  16. std::scoped_lock lock{mutex};
  17. ControllerData& controller = controller_list.at(identifier);
  18. controller.hat_buttons.try_emplace(button, u8{0});
  19. }
  20. void InputEngine::PreSetAxis(const PadIdentifier& identifier, int axis) {
  21. std::scoped_lock lock{mutex};
  22. ControllerData& controller = controller_list.at(identifier);
  23. controller.axes.try_emplace(axis, 0.0f);
  24. }
  25. void InputEngine::PreSetMotion(const PadIdentifier& identifier, int motion) {
  26. std::scoped_lock lock{mutex};
  27. ControllerData& controller = controller_list.at(identifier);
  28. controller.motions.try_emplace(motion);
  29. }
  30. void InputEngine::SetButton(const PadIdentifier& identifier, int button, bool value) {
  31. {
  32. std::scoped_lock lock{mutex};
  33. ControllerData& controller = controller_list.at(identifier);
  34. if (!configuring) {
  35. controller.buttons.insert_or_assign(button, value);
  36. }
  37. }
  38. TriggerOnButtonChange(identifier, button, value);
  39. }
  40. void InputEngine::SetHatButton(const PadIdentifier& identifier, int button, u8 value) {
  41. {
  42. std::scoped_lock lock{mutex};
  43. ControllerData& controller = controller_list.at(identifier);
  44. if (!configuring) {
  45. controller.hat_buttons.insert_or_assign(button, value);
  46. }
  47. }
  48. TriggerOnHatButtonChange(identifier, button, value);
  49. }
  50. void InputEngine::SetAxis(const PadIdentifier& identifier, int axis, f32 value) {
  51. {
  52. std::scoped_lock lock{mutex};
  53. ControllerData& controller = controller_list.at(identifier);
  54. if (!configuring) {
  55. controller.axes.insert_or_assign(axis, value);
  56. }
  57. }
  58. TriggerOnAxisChange(identifier, axis, value);
  59. }
  60. void InputEngine::SetBattery(const PadIdentifier& identifier, Common::Input::BatteryLevel value) {
  61. {
  62. std::scoped_lock lock{mutex};
  63. ControllerData& controller = controller_list.at(identifier);
  64. if (!configuring) {
  65. controller.battery = value;
  66. }
  67. }
  68. TriggerOnBatteryChange(identifier, value);
  69. }
  70. void InputEngine::SetMotion(const PadIdentifier& identifier, int motion, const BasicMotion& value) {
  71. {
  72. std::scoped_lock lock{mutex};
  73. ControllerData& controller = controller_list.at(identifier);
  74. if (!configuring) {
  75. controller.motions.insert_or_assign(motion, value);
  76. }
  77. }
  78. TriggerOnMotionChange(identifier, motion, value);
  79. }
  80. void InputEngine::SetCamera(const PadIdentifier& identifier,
  81. const Common::Input::CameraStatus& value) {
  82. {
  83. std::scoped_lock lock{mutex};
  84. ControllerData& controller = controller_list.at(identifier);
  85. if (!configuring) {
  86. controller.camera = value;
  87. }
  88. }
  89. TriggerOnCameraChange(identifier, value);
  90. }
  91. void InputEngine::SetNfc(const PadIdentifier& identifier, const Common::Input::NfcStatus& value) {
  92. {
  93. std::scoped_lock lock{mutex};
  94. ControllerData& controller = controller_list.at(identifier);
  95. if (!configuring) {
  96. controller.nfc = value;
  97. }
  98. }
  99. TriggerOnNfcChange(identifier, value);
  100. }
  101. bool InputEngine::GetButton(const PadIdentifier& identifier, int button) const {
  102. std::scoped_lock lock{mutex};
  103. const auto controller_iter = controller_list.find(identifier);
  104. if (controller_iter == controller_list.cend()) {
  105. LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(),
  106. identifier.pad, identifier.port);
  107. return false;
  108. }
  109. const ControllerData& controller = controller_iter->second;
  110. const auto button_iter = controller.buttons.find(button);
  111. if (button_iter == controller.buttons.cend()) {
  112. LOG_ERROR(Input, "Invalid button {}", button);
  113. return false;
  114. }
  115. return button_iter->second;
  116. }
  117. bool InputEngine::GetHatButton(const PadIdentifier& identifier, int button, u8 direction) const {
  118. std::scoped_lock lock{mutex};
  119. const auto controller_iter = controller_list.find(identifier);
  120. if (controller_iter == controller_list.cend()) {
  121. LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(),
  122. identifier.pad, identifier.port);
  123. return false;
  124. }
  125. const ControllerData& controller = controller_iter->second;
  126. const auto hat_iter = controller.hat_buttons.find(button);
  127. if (hat_iter == controller.hat_buttons.cend()) {
  128. LOG_ERROR(Input, "Invalid hat button {}", button);
  129. return false;
  130. }
  131. return (hat_iter->second & direction) != 0;
  132. }
  133. f32 InputEngine::GetAxis(const PadIdentifier& identifier, int axis) const {
  134. std::scoped_lock lock{mutex};
  135. const auto controller_iter = controller_list.find(identifier);
  136. if (controller_iter == controller_list.cend()) {
  137. LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(),
  138. identifier.pad, identifier.port);
  139. return 0.0f;
  140. }
  141. const ControllerData& controller = controller_iter->second;
  142. const auto axis_iter = controller.axes.find(axis);
  143. if (axis_iter == controller.axes.cend()) {
  144. LOG_ERROR(Input, "Invalid axis {}", axis);
  145. return 0.0f;
  146. }
  147. return axis_iter->second;
  148. }
  149. Common::Input::BatteryLevel InputEngine::GetBattery(const PadIdentifier& identifier) const {
  150. std::scoped_lock lock{mutex};
  151. const auto controller_iter = controller_list.find(identifier);
  152. if (controller_iter == controller_list.cend()) {
  153. LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(),
  154. identifier.pad, identifier.port);
  155. return Common::Input::BatteryLevel::Charging;
  156. }
  157. const ControllerData& controller = controller_iter->second;
  158. return controller.battery;
  159. }
  160. BasicMotion InputEngine::GetMotion(const PadIdentifier& identifier, int motion) const {
  161. std::scoped_lock lock{mutex};
  162. const auto controller_iter = controller_list.find(identifier);
  163. if (controller_iter == controller_list.cend()) {
  164. LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(),
  165. identifier.pad, identifier.port);
  166. return {};
  167. }
  168. const ControllerData& controller = controller_iter->second;
  169. return controller.motions.at(motion);
  170. }
  171. Common::Input::CameraStatus InputEngine::GetCamera(const PadIdentifier& identifier) const {
  172. std::scoped_lock lock{mutex};
  173. const auto controller_iter = controller_list.find(identifier);
  174. if (controller_iter == controller_list.cend()) {
  175. LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(),
  176. identifier.pad, identifier.port);
  177. return {};
  178. }
  179. const ControllerData& controller = controller_iter->second;
  180. return controller.camera;
  181. }
  182. Common::Input::NfcStatus InputEngine::GetNfc(const PadIdentifier& identifier) const {
  183. std::scoped_lock lock{mutex};
  184. const auto controller_iter = controller_list.find(identifier);
  185. if (controller_iter == controller_list.cend()) {
  186. LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(),
  187. identifier.pad, identifier.port);
  188. return {};
  189. }
  190. const ControllerData& controller = controller_iter->second;
  191. return controller.nfc;
  192. }
  193. void InputEngine::ResetButtonState() {
  194. for (const auto& controller : controller_list) {
  195. for (const auto& button : controller.second.buttons) {
  196. SetButton(controller.first, button.first, false);
  197. }
  198. for (const auto& button : controller.second.hat_buttons) {
  199. SetHatButton(controller.first, button.first, 0);
  200. }
  201. }
  202. }
  203. void InputEngine::ResetAnalogState() {
  204. for (const auto& controller : controller_list) {
  205. for (const auto& axis : controller.second.axes) {
  206. SetAxis(controller.first, axis.first, 0.0);
  207. }
  208. }
  209. }
  210. void InputEngine::TriggerOnButtonChange(const PadIdentifier& identifier, int button, bool value) {
  211. std::scoped_lock lock{mutex_callback};
  212. for (const auto& poller_pair : callback_list) {
  213. const InputIdentifier& poller = poller_pair.second;
  214. if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Button, button)) {
  215. continue;
  216. }
  217. if (poller.callback.on_change) {
  218. poller.callback.on_change();
  219. }
  220. }
  221. if (!configuring || !mapping_callback.on_data) {
  222. return;
  223. }
  224. PreSetButton(identifier, button);
  225. if (value == GetButton(identifier, button)) {
  226. return;
  227. }
  228. mapping_callback.on_data(MappingData{
  229. .engine = GetEngineName(),
  230. .pad = identifier,
  231. .type = EngineInputType::Button,
  232. .index = button,
  233. .button_value = value,
  234. });
  235. }
  236. void InputEngine::TriggerOnHatButtonChange(const PadIdentifier& identifier, int button, u8 value) {
  237. std::scoped_lock lock{mutex_callback};
  238. for (const auto& poller_pair : callback_list) {
  239. const InputIdentifier& poller = poller_pair.second;
  240. if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::HatButton, button)) {
  241. continue;
  242. }
  243. if (poller.callback.on_change) {
  244. poller.callback.on_change();
  245. }
  246. }
  247. if (!configuring || !mapping_callback.on_data) {
  248. return;
  249. }
  250. for (std::size_t index = 1; index < 0xff; index <<= 1) {
  251. bool button_value = (value & index) != 0;
  252. if (button_value == GetHatButton(identifier, button, static_cast<u8>(index))) {
  253. continue;
  254. }
  255. mapping_callback.on_data(MappingData{
  256. .engine = GetEngineName(),
  257. .pad = identifier,
  258. .type = EngineInputType::HatButton,
  259. .index = button,
  260. .hat_name = GetHatButtonName(static_cast<u8>(index)),
  261. });
  262. }
  263. }
  264. void InputEngine::TriggerOnAxisChange(const PadIdentifier& identifier, int axis, f32 value) {
  265. std::scoped_lock lock{mutex_callback};
  266. for (const auto& poller_pair : callback_list) {
  267. const InputIdentifier& poller = poller_pair.second;
  268. if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Analog, axis)) {
  269. continue;
  270. }
  271. if (poller.callback.on_change) {
  272. poller.callback.on_change();
  273. }
  274. }
  275. if (!configuring || !mapping_callback.on_data) {
  276. return;
  277. }
  278. if (std::abs(value - GetAxis(identifier, axis)) < 0.5f) {
  279. return;
  280. }
  281. mapping_callback.on_data(MappingData{
  282. .engine = GetEngineName(),
  283. .pad = identifier,
  284. .type = EngineInputType::Analog,
  285. .index = axis,
  286. .axis_value = value,
  287. });
  288. }
  289. void InputEngine::TriggerOnBatteryChange(const PadIdentifier& identifier,
  290. [[maybe_unused]] Common::Input::BatteryLevel value) {
  291. std::scoped_lock lock{mutex_callback};
  292. for (const auto& poller_pair : callback_list) {
  293. const InputIdentifier& poller = poller_pair.second;
  294. if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Battery, 0)) {
  295. continue;
  296. }
  297. if (poller.callback.on_change) {
  298. poller.callback.on_change();
  299. }
  300. }
  301. }
  302. void InputEngine::TriggerOnMotionChange(const PadIdentifier& identifier, int motion,
  303. const BasicMotion& value) {
  304. std::scoped_lock lock{mutex_callback};
  305. for (const auto& poller_pair : callback_list) {
  306. const InputIdentifier& poller = poller_pair.second;
  307. if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Motion, motion)) {
  308. continue;
  309. }
  310. if (poller.callback.on_change) {
  311. poller.callback.on_change();
  312. }
  313. }
  314. if (!configuring || !mapping_callback.on_data) {
  315. return;
  316. }
  317. bool is_active = false;
  318. if (std::abs(value.accel_x) > 1.5f || std::abs(value.accel_y) > 1.5f ||
  319. std::abs(value.accel_z) > 1.5f) {
  320. is_active = true;
  321. }
  322. if (std::abs(value.gyro_x) > 0.6f || std::abs(value.gyro_y) > 0.6f ||
  323. std::abs(value.gyro_z) > 0.6f) {
  324. is_active = true;
  325. }
  326. if (!is_active) {
  327. return;
  328. }
  329. mapping_callback.on_data(MappingData{
  330. .engine = GetEngineName(),
  331. .pad = identifier,
  332. .type = EngineInputType::Motion,
  333. .index = motion,
  334. .motion_value = value,
  335. });
  336. }
  337. void InputEngine::TriggerOnCameraChange(const PadIdentifier& identifier,
  338. [[maybe_unused]] const Common::Input::CameraStatus& value) {
  339. std::scoped_lock lock{mutex_callback};
  340. for (const auto& poller_pair : callback_list) {
  341. const InputIdentifier& poller = poller_pair.second;
  342. if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Camera, 0)) {
  343. continue;
  344. }
  345. if (poller.callback.on_change) {
  346. poller.callback.on_change();
  347. }
  348. }
  349. }
  350. void InputEngine::TriggerOnNfcChange(const PadIdentifier& identifier,
  351. [[maybe_unused]] const Common::Input::NfcStatus& value) {
  352. std::scoped_lock lock{mutex_callback};
  353. for (const auto& poller_pair : callback_list) {
  354. const InputIdentifier& poller = poller_pair.second;
  355. if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Nfc, 0)) {
  356. continue;
  357. }
  358. if (poller.callback.on_change) {
  359. poller.callback.on_change();
  360. }
  361. }
  362. }
  363. bool InputEngine::IsInputIdentifierEqual(const InputIdentifier& input_identifier,
  364. const PadIdentifier& identifier, EngineInputType type,
  365. int index) const {
  366. if (input_identifier.type != type) {
  367. return false;
  368. }
  369. if (input_identifier.index != index) {
  370. return false;
  371. }
  372. if (input_identifier.identifier != identifier) {
  373. return false;
  374. }
  375. return true;
  376. }
  377. void InputEngine::BeginConfiguration() {
  378. configuring = true;
  379. }
  380. void InputEngine::EndConfiguration() {
  381. configuring = false;
  382. }
  383. const std::string& InputEngine::GetEngineName() const {
  384. return input_engine;
  385. }
  386. int InputEngine::SetCallback(InputIdentifier input_identifier) {
  387. std::scoped_lock lock{mutex_callback};
  388. callback_list.insert_or_assign(last_callback_key, std::move(input_identifier));
  389. return last_callback_key++;
  390. }
  391. void InputEngine::SetMappingCallback(MappingCallback callback) {
  392. std::scoped_lock lock{mutex_callback};
  393. mapping_callback = std::move(callback);
  394. }
  395. void InputEngine::DeleteCallback(int key) {
  396. std::scoped_lock lock{mutex_callback};
  397. const auto& iterator = callback_list.find(key);
  398. if (iterator == callback_list.end()) {
  399. LOG_ERROR(Input, "Tried to delete non-existent callback {}", key);
  400. return;
  401. }
  402. callback_list.erase(iterator);
  403. }
  404. } // namespace InputCommon