input_engine.h 11 KB

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