| 
									
										
										
										
											2022-04-23 04:59:50 -04:00
										 |  |  | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
 | 
					
						
							|  |  |  | // SPDX-License-Identifier: GPL-2.0-or-later
 | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "common/logging/log.h"
 | 
					
						
							|  |  |  | #include "input_common/input_engine.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace InputCommon { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputEngine::PreSetController(const PadIdentifier& identifier) { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |     std::scoped_lock lock{mutex}; | 
					
						
							| 
									
										
										
										
											2021-12-13 10:18:02 -05:00
										 |  |  |     controller_list.try_emplace(identifier); | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputEngine::PreSetButton(const PadIdentifier& identifier, int button) { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |     std::scoped_lock lock{mutex}; | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |     ControllerData& controller = controller_list.at(identifier); | 
					
						
							| 
									
										
										
										
											2021-12-13 10:18:02 -05:00
										 |  |  |     controller.buttons.try_emplace(button, false); | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputEngine::PreSetHatButton(const PadIdentifier& identifier, int button) { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |     std::scoped_lock lock{mutex}; | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |     ControllerData& controller = controller_list.at(identifier); | 
					
						
							| 
									
										
										
										
											2021-12-13 10:18:02 -05:00
										 |  |  |     controller.hat_buttons.try_emplace(button, u8{0}); | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputEngine::PreSetAxis(const PadIdentifier& identifier, int axis) { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |     std::scoped_lock lock{mutex}; | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |     ControllerData& controller = controller_list.at(identifier); | 
					
						
							| 
									
										
										
										
											2021-12-13 10:18:02 -05:00
										 |  |  |     controller.axes.try_emplace(axis, 0.0f); | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputEngine::PreSetMotion(const PadIdentifier& identifier, int motion) { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |     std::scoped_lock lock{mutex}; | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |     ControllerData& controller = controller_list.at(identifier); | 
					
						
							| 
									
										
										
										
											2021-12-13 10:18:02 -05:00
										 |  |  |     controller.motions.try_emplace(motion); | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputEngine::SetButton(const PadIdentifier& identifier, int button, bool value) { | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |         std::scoped_lock lock{mutex}; | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |         ControllerData& controller = controller_list.at(identifier); | 
					
						
							|  |  |  |         if (!configuring) { | 
					
						
							|  |  |  |             controller.buttons.insert_or_assign(button, value); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     TriggerOnButtonChange(identifier, button, value); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputEngine::SetHatButton(const PadIdentifier& identifier, int button, u8 value) { | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |         std::scoped_lock lock{mutex}; | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |         ControllerData& controller = controller_list.at(identifier); | 
					
						
							|  |  |  |         if (!configuring) { | 
					
						
							|  |  |  |             controller.hat_buttons.insert_or_assign(button, value); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     TriggerOnHatButtonChange(identifier, button, value); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputEngine::SetAxis(const PadIdentifier& identifier, int axis, f32 value) { | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |         std::scoped_lock lock{mutex}; | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |         ControllerData& controller = controller_list.at(identifier); | 
					
						
							|  |  |  |         if (!configuring) { | 
					
						
							|  |  |  |             controller.axes.insert_or_assign(axis, value); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     TriggerOnAxisChange(identifier, axis, value); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-06 18:20:12 -06:00
										 |  |  | void InputEngine::SetBattery(const PadIdentifier& identifier, Common::Input::BatteryLevel value) { | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |         std::scoped_lock lock{mutex}; | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |         ControllerData& controller = controller_list.at(identifier); | 
					
						
							|  |  |  |         if (!configuring) { | 
					
						
							|  |  |  |             controller.battery = value; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     TriggerOnBatteryChange(identifier, value); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-13 09:26:44 -05:00
										 |  |  | void InputEngine::SetMotion(const PadIdentifier& identifier, int motion, const BasicMotion& value) { | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |         std::scoped_lock lock{mutex}; | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |         ControllerData& controller = controller_list.at(identifier); | 
					
						
							|  |  |  |         if (!configuring) { | 
					
						
							|  |  |  |             controller.motions.insert_or_assign(motion, value); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     TriggerOnMotionChange(identifier, motion, value); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-18 23:32:07 -05:00
										 |  |  | void InputEngine::SetCamera(const PadIdentifier& identifier, | 
					
						
							|  |  |  |                             const Common::Input::CameraStatus& value) { | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         std::scoped_lock lock{mutex}; | 
					
						
							|  |  |  |         ControllerData& controller = controller_list.at(identifier); | 
					
						
							|  |  |  |         if (!configuring) { | 
					
						
							|  |  |  |             controller.camera = value; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     TriggerOnCameraChange(identifier, value); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-24 19:46:49 -05:00
										 |  |  | void InputEngine::SetNfc(const PadIdentifier& identifier, const Common::Input::NfcStatus& value) { | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         std::scoped_lock lock{mutex}; | 
					
						
							|  |  |  |         ControllerData& controller = controller_list.at(identifier); | 
					
						
							|  |  |  |         if (!configuring) { | 
					
						
							|  |  |  |             controller.nfc = value; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     TriggerOnNfcChange(identifier, value); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  | bool InputEngine::GetButton(const PadIdentifier& identifier, int button) const { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |     std::scoped_lock lock{mutex}; | 
					
						
							| 
									
										
										
										
											2021-12-13 09:50:48 -05:00
										 |  |  |     const auto controller_iter = controller_list.find(identifier); | 
					
						
							|  |  |  |     if (controller_iter == controller_list.cend()) { | 
					
						
							| 
									
										
										
										
											2022-02-05 00:40:28 -05:00
										 |  |  |         LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(), | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |                   identifier.pad, identifier.port); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-13 09:50:48 -05:00
										 |  |  |     const ControllerData& controller = controller_iter->second; | 
					
						
							|  |  |  |     const auto button_iter = controller.buttons.find(button); | 
					
						
							|  |  |  |     if (button_iter == controller.buttons.cend()) { | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |         LOG_ERROR(Input, "Invalid button {}", button); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-13 09:50:48 -05:00
										 |  |  |     return button_iter->second; | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool InputEngine::GetHatButton(const PadIdentifier& identifier, int button, u8 direction) const { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |     std::scoped_lock lock{mutex}; | 
					
						
							| 
									
										
										
										
											2021-12-13 09:50:48 -05:00
										 |  |  |     const auto controller_iter = controller_list.find(identifier); | 
					
						
							|  |  |  |     if (controller_iter == controller_list.cend()) { | 
					
						
							| 
									
										
										
										
											2022-02-05 00:40:28 -05:00
										 |  |  |         LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(), | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |                   identifier.pad, identifier.port); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-13 09:50:48 -05:00
										 |  |  |     const ControllerData& controller = controller_iter->second; | 
					
						
							|  |  |  |     const auto hat_iter = controller.hat_buttons.find(button); | 
					
						
							|  |  |  |     if (hat_iter == controller.hat_buttons.cend()) { | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |         LOG_ERROR(Input, "Invalid hat button {}", button); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-13 09:50:48 -05:00
										 |  |  |     return (hat_iter->second & direction) != 0; | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | f32 InputEngine::GetAxis(const PadIdentifier& identifier, int axis) const { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |     std::scoped_lock lock{mutex}; | 
					
						
							| 
									
										
										
										
											2021-12-13 09:50:48 -05:00
										 |  |  |     const auto controller_iter = controller_list.find(identifier); | 
					
						
							|  |  |  |     if (controller_iter == controller_list.cend()) { | 
					
						
							| 
									
										
										
										
											2022-02-05 00:40:28 -05:00
										 |  |  |         LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(), | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |                   identifier.pad, identifier.port); | 
					
						
							|  |  |  |         return 0.0f; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-13 09:50:48 -05:00
										 |  |  |     const ControllerData& controller = controller_iter->second; | 
					
						
							|  |  |  |     const auto axis_iter = controller.axes.find(axis); | 
					
						
							|  |  |  |     if (axis_iter == controller.axes.cend()) { | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |         LOG_ERROR(Input, "Invalid axis {}", axis); | 
					
						
							|  |  |  |         return 0.0f; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-13 09:50:48 -05:00
										 |  |  |     return axis_iter->second; | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-06 18:20:12 -06:00
										 |  |  | Common::Input::BatteryLevel InputEngine::GetBattery(const PadIdentifier& identifier) const { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |     std::scoped_lock lock{mutex}; | 
					
						
							| 
									
										
										
										
											2021-12-13 09:50:48 -05:00
										 |  |  |     const auto controller_iter = controller_list.find(identifier); | 
					
						
							|  |  |  |     if (controller_iter == controller_list.cend()) { | 
					
						
							| 
									
										
										
										
											2022-02-05 00:40:28 -05:00
										 |  |  |         LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(), | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |                   identifier.pad, identifier.port); | 
					
						
							| 
									
										
										
										
											2022-02-06 18:20:12 -06:00
										 |  |  |         return Common::Input::BatteryLevel::Charging; | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-13 09:50:48 -05:00
										 |  |  |     const ControllerData& controller = controller_iter->second; | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |     return controller.battery; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | BasicMotion InputEngine::GetMotion(const PadIdentifier& identifier, int motion) const { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |     std::scoped_lock lock{mutex}; | 
					
						
							| 
									
										
										
										
											2021-12-13 09:50:48 -05:00
										 |  |  |     const auto controller_iter = controller_list.find(identifier); | 
					
						
							|  |  |  |     if (controller_iter == controller_list.cend()) { | 
					
						
							| 
									
										
										
										
											2022-02-05 00:40:28 -05:00
										 |  |  |         LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(), | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |                   identifier.pad, identifier.port); | 
					
						
							|  |  |  |         return {}; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-13 09:50:48 -05:00
										 |  |  |     const ControllerData& controller = controller_iter->second; | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |     return controller.motions.at(motion); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-18 23:32:07 -05:00
										 |  |  | Common::Input::CameraStatus InputEngine::GetCamera(const PadIdentifier& identifier) const { | 
					
						
							|  |  |  |     std::scoped_lock lock{mutex}; | 
					
						
							|  |  |  |     const auto controller_iter = controller_list.find(identifier); | 
					
						
							|  |  |  |     if (controller_iter == controller_list.cend()) { | 
					
						
							|  |  |  |         LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(), | 
					
						
							|  |  |  |                   identifier.pad, identifier.port); | 
					
						
							|  |  |  |         return {}; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     const ControllerData& controller = controller_iter->second; | 
					
						
							|  |  |  |     return controller.camera; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-24 19:46:49 -05:00
										 |  |  | Common::Input::NfcStatus InputEngine::GetNfc(const PadIdentifier& identifier) const { | 
					
						
							|  |  |  |     std::scoped_lock lock{mutex}; | 
					
						
							|  |  |  |     const auto controller_iter = controller_list.find(identifier); | 
					
						
							|  |  |  |     if (controller_iter == controller_list.cend()) { | 
					
						
							|  |  |  |         LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(), | 
					
						
							|  |  |  |                   identifier.pad, identifier.port); | 
					
						
							|  |  |  |         return {}; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     const ControllerData& controller = controller_iter->second; | 
					
						
							|  |  |  |     return controller.nfc; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  | void InputEngine::ResetButtonState() { | 
					
						
							| 
									
										
										
										
											2021-12-13 09:32:55 -05:00
										 |  |  |     for (const auto& controller : controller_list) { | 
					
						
							|  |  |  |         for (const auto& button : controller.second.buttons) { | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |             SetButton(controller.first, button.first, false); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-12-13 09:32:55 -05:00
										 |  |  |         for (const auto& button : controller.second.hat_buttons) { | 
					
						
							| 
									
										
										
										
											2022-01-17 12:04:38 +03:00
										 |  |  |             SetHatButton(controller.first, button.first, 0); | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputEngine::ResetAnalogState() { | 
					
						
							| 
									
										
										
										
											2021-12-13 09:32:55 -05:00
										 |  |  |     for (const auto& controller : controller_list) { | 
					
						
							|  |  |  |         for (const auto& axis : controller.second.axes) { | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |             SetAxis(controller.first, axis.first, 0.0); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputEngine::TriggerOnButtonChange(const PadIdentifier& identifier, int button, bool value) { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |     std::scoped_lock lock{mutex_callback}; | 
					
						
							| 
									
										
										
										
											2021-12-13 09:32:55 -05:00
										 |  |  |     for (const auto& poller_pair : callback_list) { | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |         const InputIdentifier& poller = poller_pair.second; | 
					
						
							|  |  |  |         if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Button, button)) { | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (poller.callback.on_change) { | 
					
						
							|  |  |  |             poller.callback.on_change(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!configuring || !mapping_callback.on_data) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-10-24 11:22:20 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     PreSetButton(identifier, button); | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |     if (value == GetButton(identifier, button)) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     mapping_callback.on_data(MappingData{ | 
					
						
							|  |  |  |         .engine = GetEngineName(), | 
					
						
							|  |  |  |         .pad = identifier, | 
					
						
							|  |  |  |         .type = EngineInputType::Button, | 
					
						
							|  |  |  |         .index = button, | 
					
						
							|  |  |  |         .button_value = value, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputEngine::TriggerOnHatButtonChange(const PadIdentifier& identifier, int button, u8 value) { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |     std::scoped_lock lock{mutex_callback}; | 
					
						
							| 
									
										
										
										
											2021-12-13 09:32:55 -05:00
										 |  |  |     for (const auto& poller_pair : callback_list) { | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |         const InputIdentifier& poller = poller_pair.second; | 
					
						
							|  |  |  |         if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::HatButton, button)) { | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (poller.callback.on_change) { | 
					
						
							|  |  |  |             poller.callback.on_change(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!configuring || !mapping_callback.on_data) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     for (std::size_t index = 1; index < 0xff; index <<= 1) { | 
					
						
							|  |  |  |         bool button_value = (value & index) != 0; | 
					
						
							|  |  |  |         if (button_value == GetHatButton(identifier, button, static_cast<u8>(index))) { | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         mapping_callback.on_data(MappingData{ | 
					
						
							|  |  |  |             .engine = GetEngineName(), | 
					
						
							|  |  |  |             .pad = identifier, | 
					
						
							|  |  |  |             .type = EngineInputType::HatButton, | 
					
						
							|  |  |  |             .index = button, | 
					
						
							|  |  |  |             .hat_name = GetHatButtonName(static_cast<u8>(index)), | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputEngine::TriggerOnAxisChange(const PadIdentifier& identifier, int axis, f32 value) { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |     std::scoped_lock lock{mutex_callback}; | 
					
						
							| 
									
										
										
										
											2021-12-13 09:32:55 -05:00
										 |  |  |     for (const auto& poller_pair : callback_list) { | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |         const InputIdentifier& poller = poller_pair.second; | 
					
						
							|  |  |  |         if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Analog, axis)) { | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (poller.callback.on_change) { | 
					
						
							|  |  |  |             poller.callback.on_change(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!configuring || !mapping_callback.on_data) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (std::abs(value - GetAxis(identifier, axis)) < 0.5f) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     mapping_callback.on_data(MappingData{ | 
					
						
							|  |  |  |         .engine = GetEngineName(), | 
					
						
							|  |  |  |         .pad = identifier, | 
					
						
							|  |  |  |         .type = EngineInputType::Analog, | 
					
						
							|  |  |  |         .index = axis, | 
					
						
							|  |  |  |         .axis_value = value, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputEngine::TriggerOnBatteryChange(const PadIdentifier& identifier, | 
					
						
							| 
									
										
										
										
											2022-02-06 18:20:12 -06:00
										 |  |  |                                          [[maybe_unused]] Common::Input::BatteryLevel value) { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |     std::scoped_lock lock{mutex_callback}; | 
					
						
							| 
									
										
										
										
											2021-12-13 09:32:55 -05:00
										 |  |  |     for (const auto& poller_pair : callback_list) { | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |         const InputIdentifier& poller = poller_pair.second; | 
					
						
							|  |  |  |         if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Battery, 0)) { | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (poller.callback.on_change) { | 
					
						
							|  |  |  |             poller.callback.on_change(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputEngine::TriggerOnMotionChange(const PadIdentifier& identifier, int motion, | 
					
						
							| 
									
										
										
										
											2021-12-13 09:26:44 -05:00
										 |  |  |                                         const BasicMotion& value) { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |     std::scoped_lock lock{mutex_callback}; | 
					
						
							| 
									
										
										
										
											2021-12-13 09:32:55 -05:00
										 |  |  |     for (const auto& poller_pair : callback_list) { | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |         const InputIdentifier& poller = poller_pair.second; | 
					
						
							|  |  |  |         if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Motion, motion)) { | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (poller.callback.on_change) { | 
					
						
							|  |  |  |             poller.callback.on_change(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!configuring || !mapping_callback.on_data) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-01-06 18:06:05 -06:00
										 |  |  |     bool is_active = false; | 
					
						
							|  |  |  |     if (std::abs(value.accel_x) > 1.5f || std::abs(value.accel_y) > 1.5f || | 
					
						
							|  |  |  |         std::abs(value.accel_z) > 1.5f) { | 
					
						
							|  |  |  |         is_active = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (std::abs(value.gyro_x) > 0.6f || std::abs(value.gyro_y) > 0.6f || | 
					
						
							|  |  |  |         std::abs(value.gyro_z) > 0.6f) { | 
					
						
							|  |  |  |         is_active = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!is_active) { | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     mapping_callback.on_data(MappingData{ | 
					
						
							|  |  |  |         .engine = GetEngineName(), | 
					
						
							|  |  |  |         .pad = identifier, | 
					
						
							|  |  |  |         .type = EngineInputType::Motion, | 
					
						
							|  |  |  |         .index = motion, | 
					
						
							|  |  |  |         .motion_value = value, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-18 23:32:07 -05:00
										 |  |  | void InputEngine::TriggerOnCameraChange(const PadIdentifier& identifier, | 
					
						
							|  |  |  |                                         [[maybe_unused]] const Common::Input::CameraStatus& value) { | 
					
						
							|  |  |  |     std::scoped_lock lock{mutex_callback}; | 
					
						
							|  |  |  |     for (const auto& poller_pair : callback_list) { | 
					
						
							|  |  |  |         const InputIdentifier& poller = poller_pair.second; | 
					
						
							|  |  |  |         if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Camera, 0)) { | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (poller.callback.on_change) { | 
					
						
							|  |  |  |             poller.callback.on_change(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-24 19:46:49 -05:00
										 |  |  | void InputEngine::TriggerOnNfcChange(const PadIdentifier& identifier, | 
					
						
							|  |  |  |                                      [[maybe_unused]] const Common::Input::NfcStatus& value) { | 
					
						
							|  |  |  |     std::scoped_lock lock{mutex_callback}; | 
					
						
							|  |  |  |     for (const auto& poller_pair : callback_list) { | 
					
						
							|  |  |  |         const InputIdentifier& poller = poller_pair.second; | 
					
						
							|  |  |  |         if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Nfc, 0)) { | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (poller.callback.on_change) { | 
					
						
							|  |  |  |             poller.callback.on_change(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  | bool InputEngine::IsInputIdentifierEqual(const InputIdentifier& input_identifier, | 
					
						
							|  |  |  |                                          const PadIdentifier& identifier, EngineInputType type, | 
					
						
							| 
									
										
										
										
											2021-10-31 10:41:44 -05:00
										 |  |  |                                          int index) const { | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |     if (input_identifier.type != type) { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (input_identifier.index != index) { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (input_identifier.identifier != identifier) { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputEngine::BeginConfiguration() { | 
					
						
							|  |  |  |     configuring = true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputEngine::EndConfiguration() { | 
					
						
							|  |  |  |     configuring = false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const std::string& InputEngine::GetEngineName() const { | 
					
						
							|  |  |  |     return input_engine; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int InputEngine::SetCallback(InputIdentifier input_identifier) { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |     std::scoped_lock lock{mutex_callback}; | 
					
						
							| 
									
										
										
										
											2021-12-13 09:23:19 -05:00
										 |  |  |     callback_list.insert_or_assign(last_callback_key, std::move(input_identifier)); | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |     return last_callback_key++; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputEngine::SetMappingCallback(MappingCallback callback) { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |     std::scoped_lock lock{mutex_callback}; | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |     mapping_callback = std::move(callback); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputEngine::DeleteCallback(int key) { | 
					
						
							| 
									
										
										
										
											2022-04-07 19:32:09 +01:00
										 |  |  |     std::scoped_lock lock{mutex_callback}; | 
					
						
							| 
									
										
										
										
											2021-11-01 14:17:53 -06:00
										 |  |  |     const auto& iterator = callback_list.find(key); | 
					
						
							|  |  |  |     if (iterator == callback_list.end()) { | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  |         LOG_ERROR(Input, "Tried to delete non-existent callback {}", key); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-11-01 14:17:53 -06:00
										 |  |  |     callback_list.erase(iterator); | 
					
						
							| 
									
										
										
										
											2021-09-20 16:34:05 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace InputCommon
 |