input_engine.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <functional>
  5. #include <mutex>
  6. #include <unordered_map>
  7. #include "common/common_types.h"
  8. #include "common/input.h"
  9. #include "common/param_package.h"
  10. #include "common/uuid.h"
  11. #include "input_common/main.h"
  12. // Pad Identifier of data source
  13. struct PadIdentifier {
  14. Common::UUID guid{};
  15. std::size_t port{};
  16. std::size_t pad{};
  17. friend constexpr bool operator==(const PadIdentifier&, const PadIdentifier&) = default;
  18. };
  19. // Basic motion data containing data from the sensors and a timestamp in microseconds
  20. struct BasicMotion {
  21. float gyro_x{};
  22. float gyro_y{};
  23. float gyro_z{};
  24. float accel_x{};
  25. float accel_y{};
  26. float accel_z{};
  27. u64 delta_timestamp{};
  28. };
  29. // Types of input that are stored in the engine
  30. enum class EngineInputType {
  31. None,
  32. Analog,
  33. Battery,
  34. Button,
  35. Camera,
  36. Color,
  37. HatButton,
  38. Motion,
  39. Nfc,
  40. };
  41. struct VibrationRequest {
  42. PadIdentifier identifier;
  43. Common::Input::VibrationStatus vibration;
  44. };
  45. namespace std {
  46. // Hash used to create lists from PadIdentifier data
  47. template <>
  48. struct hash<PadIdentifier> {
  49. size_t operator()(const PadIdentifier& pad_id) const noexcept {
  50. u64 hash_value = pad_id.guid.Hash();
  51. hash_value ^= (static_cast<u64>(pad_id.port) << 32);
  52. hash_value ^= static_cast<u64>(pad_id.pad);
  53. return static_cast<size_t>(hash_value);
  54. }
  55. };
  56. } // namespace std
  57. namespace InputCommon {
  58. // Data from the engine and device needed for creating a ParamPackage
  59. struct MappingData {
  60. std::string engine{};
  61. PadIdentifier pad{};
  62. EngineInputType type{};
  63. int index{};
  64. bool button_value{};
  65. std::string hat_name{};
  66. f32 axis_value{};
  67. BasicMotion motion_value{};
  68. };
  69. // Triggered if data changed on the controller
  70. struct UpdateCallback {
  71. std::function<void()> on_change;
  72. };
  73. // Triggered if data changed on the controller and the engine is on configuring mode
  74. struct MappingCallback {
  75. std::function<void(const MappingData&)> on_data;
  76. };
  77. // Input Identifier of data source
  78. struct InputIdentifier {
  79. PadIdentifier identifier;
  80. EngineInputType type;
  81. int index;
  82. UpdateCallback callback;
  83. };
  84. class InputEngine {
  85. public:
  86. explicit InputEngine(std::string input_engine_) : input_engine{std::move(input_engine_)} {}
  87. virtual ~InputEngine() = default;
  88. // Enable configuring mode for mapping
  89. void BeginConfiguration();
  90. // Disable configuring mode for mapping
  91. void EndConfiguration();
  92. // Sets a led pattern for a controller
  93. virtual Common::Input::DriverResult SetLeds(
  94. [[maybe_unused]] const PadIdentifier& identifier,
  95. [[maybe_unused]] const Common::Input::LedStatus& led_status) {
  96. return Common::Input::DriverResult::NotSupported;
  97. }
  98. // Sets rumble to a controller
  99. virtual Common::Input::DriverResult SetVibration(
  100. [[maybe_unused]] const PadIdentifier& identifier,
  101. [[maybe_unused]] const Common::Input::VibrationStatus& vibration) {
  102. return Common::Input::DriverResult::NotSupported;
  103. }
  104. // Returns true if device supports vibrations
  105. virtual bool IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) {
  106. return false;
  107. }
  108. // Sets polling mode to a controller
  109. virtual Common::Input::DriverResult SetPollingMode(
  110. [[maybe_unused]] const PadIdentifier& identifier,
  111. [[maybe_unused]] const Common::Input::PollingMode polling_mode) {
  112. return Common::Input::DriverResult::NotSupported;
  113. }
  114. // Sets camera format to a controller
  115. virtual Common::Input::DriverResult SetCameraFormat(
  116. [[maybe_unused]] const PadIdentifier& identifier,
  117. [[maybe_unused]] Common::Input::CameraFormat camera_format) {
  118. return Common::Input::DriverResult::NotSupported;
  119. }
  120. // Returns success if nfc is supported
  121. virtual Common::Input::NfcState SupportsNfc(
  122. [[maybe_unused]] const PadIdentifier& identifier) const {
  123. return Common::Input::NfcState::NotSupported;
  124. }
  125. // Start scanning for nfc tags
  126. virtual Common::Input::NfcState StartNfcPolling(
  127. [[maybe_unused]] const PadIdentifier& identifier_) {
  128. return Common::Input::NfcState::NotSupported;
  129. }
  130. // Start scanning for nfc tags
  131. virtual Common::Input::NfcState StopNfcPolling(
  132. [[maybe_unused]] const PadIdentifier& identifier_) {
  133. return Common::Input::NfcState::NotSupported;
  134. }
  135. // Reads data from amiibo tag
  136. virtual Common::Input::NfcState ReadAmiiboData(
  137. [[maybe_unused]] const PadIdentifier& identifier_,
  138. [[maybe_unused]] std::vector<u8>& out_data) {
  139. return Common::Input::NfcState::NotSupported;
  140. }
  141. // Writes data to an nfc tag
  142. virtual Common::Input::NfcState WriteNfcData([[maybe_unused]] const PadIdentifier& identifier,
  143. [[maybe_unused]] const std::vector<u8>& data) {
  144. return Common::Input::NfcState::NotSupported;
  145. }
  146. // Reads data from mifare tag
  147. virtual Common::Input::NfcState ReadMifareData(
  148. [[maybe_unused]] const PadIdentifier& identifier_,
  149. [[maybe_unused]] const Common::Input::MifareRequest& request,
  150. [[maybe_unused]] Common::Input::MifareRequest& out_data) {
  151. return Common::Input::NfcState::NotSupported;
  152. }
  153. // Write data to mifare tag
  154. virtual Common::Input::NfcState WriteMifareData(
  155. [[maybe_unused]] const PadIdentifier& identifier_,
  156. [[maybe_unused]] const Common::Input::MifareRequest& request) {
  157. return Common::Input::NfcState::NotSupported;
  158. }
  159. // Returns the engine name
  160. [[nodiscard]] const std::string& GetEngineName() const;
  161. /// Used for automapping features
  162. virtual std::vector<Common::ParamPackage> GetInputDevices() const {
  163. return {};
  164. }
  165. /// Retrieves the button mappings for the given device
  166. virtual ButtonMapping GetButtonMappingForDevice(
  167. [[maybe_unused]] const Common::ParamPackage& params) {
  168. return {};
  169. }
  170. /// Retrieves the analog mappings for the given device
  171. virtual AnalogMapping GetAnalogMappingForDevice(
  172. [[maybe_unused]] const Common::ParamPackage& params) {
  173. return {};
  174. }
  175. /// Retrieves the motion mappings for the given device
  176. virtual MotionMapping GetMotionMappingForDevice(
  177. [[maybe_unused]] const Common::ParamPackage& params) {
  178. return {};
  179. }
  180. /// Retrieves the name of the given input.
  181. virtual Common::Input::ButtonNames GetUIName(
  182. [[maybe_unused]] const Common::ParamPackage& params) const {
  183. return Common::Input::ButtonNames::Engine;
  184. }
  185. /// Retrieves the index number of the given hat button direction
  186. virtual u8 GetHatButtonId([[maybe_unused]] const std::string& direction_name) const {
  187. return 0;
  188. }
  189. /// Returns true if axis of a stick aren't mapped in the correct direction
  190. virtual bool IsStickInverted([[maybe_unused]] const Common::ParamPackage& params) {
  191. return false;
  192. }
  193. void PreSetController(const PadIdentifier& identifier);
  194. void PreSetButton(const PadIdentifier& identifier, int button);
  195. void PreSetHatButton(const PadIdentifier& identifier, int button);
  196. void PreSetAxis(const PadIdentifier& identifier, int axis);
  197. void PreSetMotion(const PadIdentifier& identifier, int motion);
  198. void ResetButtonState();
  199. void ResetAnalogState();
  200. bool GetButton(const PadIdentifier& identifier, int button) const;
  201. bool GetHatButton(const PadIdentifier& identifier, int button, u8 direction) const;
  202. f32 GetAxis(const PadIdentifier& identifier, int axis) const;
  203. Common::Input::BatteryLevel GetBattery(const PadIdentifier& identifier) const;
  204. Common::Input::BodyColorStatus GetColor(const PadIdentifier& identifier) const;
  205. BasicMotion GetMotion(const PadIdentifier& identifier, int motion) const;
  206. Common::Input::CameraStatus GetCamera(const PadIdentifier& identifier) const;
  207. Common::Input::NfcStatus GetNfc(const PadIdentifier& identifier) const;
  208. int SetCallback(InputIdentifier input_identifier);
  209. void SetMappingCallback(MappingCallback callback);
  210. void DeleteCallback(int key);
  211. protected:
  212. void SetButton(const PadIdentifier& identifier, int button, bool value);
  213. void SetHatButton(const PadIdentifier& identifier, int button, u8 value);
  214. void SetAxis(const PadIdentifier& identifier, int axis, f32 value);
  215. void SetBattery(const PadIdentifier& identifier, Common::Input::BatteryLevel value);
  216. void SetColor(const PadIdentifier& identifier, Common::Input::BodyColorStatus value);
  217. void SetMotion(const PadIdentifier& identifier, int motion, const BasicMotion& value);
  218. void SetCamera(const PadIdentifier& identifier, const Common::Input::CameraStatus& value);
  219. void SetNfc(const PadIdentifier& identifier, const Common::Input::NfcStatus& value);
  220. virtual std::string GetHatButtonName([[maybe_unused]] u8 direction_value) const {
  221. return "Unknown";
  222. }
  223. private:
  224. struct ControllerData {
  225. std::unordered_map<int, bool> buttons;
  226. std::unordered_map<int, u8> hat_buttons;
  227. std::unordered_map<int, float> axes;
  228. std::unordered_map<int, BasicMotion> motions;
  229. Common::Input::BatteryLevel battery{};
  230. Common::Input::BodyColorStatus color{};
  231. Common::Input::CameraStatus camera{};
  232. Common::Input::NfcStatus nfc{};
  233. };
  234. void TriggerOnButtonChange(const PadIdentifier& identifier, int button, bool value);
  235. void TriggerOnHatButtonChange(const PadIdentifier& identifier, int button, u8 value);
  236. void TriggerOnAxisChange(const PadIdentifier& identifier, int axis, f32 value);
  237. void TriggerOnBatteryChange(const PadIdentifier& identifier, Common::Input::BatteryLevel value);
  238. void TriggerOnColorChange(const PadIdentifier& identifier,
  239. Common::Input::BodyColorStatus value);
  240. void TriggerOnMotionChange(const PadIdentifier& identifier, int motion,
  241. const BasicMotion& value);
  242. void TriggerOnCameraChange(const PadIdentifier& identifier,
  243. const Common::Input::CameraStatus& value);
  244. void TriggerOnNfcChange(const PadIdentifier& identifier, const Common::Input::NfcStatus& value);
  245. bool IsInputIdentifierEqual(const InputIdentifier& input_identifier,
  246. const PadIdentifier& identifier, EngineInputType type,
  247. int index) const;
  248. mutable std::mutex mutex;
  249. mutable std::mutex mutex_callback;
  250. bool configuring{false};
  251. const std::string input_engine;
  252. int last_callback_key = 0;
  253. std::unordered_map<PadIdentifier, ControllerData> controller_list;
  254. std::unordered_map<int, InputIdentifier> callback_list;
  255. MappingCallback mapping_callback;
  256. };
  257. } // namespace InputCommon