input_engine.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. // Copyright 2021 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included
  4. #pragma once
  5. #include <functional>
  6. #include <mutex>
  7. #include <unordered_map>
  8. #include "common/common_types.h"
  9. #include "common/input.h"
  10. #include "common/param_package.h"
  11. #include "common/uuid.h"
  12. #include "input_common/main.h"
  13. // Pad Identifier of data source
  14. struct PadIdentifier {
  15. Common::UUID guid{};
  16. std::size_t port{};
  17. std::size_t pad{};
  18. friend constexpr bool operator==(const PadIdentifier&, const PadIdentifier&) = default;
  19. };
  20. // Basic motion data containing data from the sensors and a timestamp in microsecons
  21. struct BasicMotion {
  22. float gyro_x;
  23. float gyro_y;
  24. float gyro_z;
  25. float accel_x;
  26. float accel_y;
  27. float accel_z;
  28. u64 delta_timestamp;
  29. };
  30. // Stages of a battery charge
  31. enum class BatteryLevel {
  32. Empty,
  33. Critical,
  34. Low,
  35. Medium,
  36. Full,
  37. Charging,
  38. };
  39. // Types of input that are stored in the engine
  40. enum class EngineInputType {
  41. None,
  42. Button,
  43. HatButton,
  44. Analog,
  45. Motion,
  46. Battery,
  47. };
  48. namespace std {
  49. // Hash used to create lists from PadIdentifier data
  50. template <>
  51. struct hash<PadIdentifier> {
  52. size_t operator()(const PadIdentifier& pad_id) const noexcept {
  53. u64 hash_value = pad_id.guid.uuid[1] ^ pad_id.guid.uuid[0];
  54. hash_value ^= (static_cast<u64>(pad_id.port) << 32);
  55. hash_value ^= static_cast<u64>(pad_id.pad);
  56. return static_cast<size_t>(hash_value);
  57. }
  58. };
  59. } // namespace std
  60. namespace InputCommon {
  61. // Data from the engine and device needed for creating a ParamPackage
  62. struct MappingData {
  63. std::string engine{};
  64. PadIdentifier pad{};
  65. EngineInputType type{};
  66. int index{};
  67. bool button_value{};
  68. std::string hat_name{};
  69. f32 axis_value{};
  70. BasicMotion motion_value{};
  71. };
  72. // Triggered if data changed on the controller
  73. struct UpdateCallback {
  74. std::function<void()> on_change;
  75. };
  76. // Triggered if data changed on the controller and the engine is on configuring mode
  77. struct MappingCallback {
  78. std::function<void(MappingData)> on_data;
  79. };
  80. // Input Identifier of data source
  81. struct InputIdentifier {
  82. PadIdentifier identifier;
  83. EngineInputType type;
  84. std::size_t index;
  85. UpdateCallback callback;
  86. };
  87. class InputEngine {
  88. public:
  89. explicit InputEngine(const std::string& input_engine_) : input_engine(input_engine_) {
  90. callback_list.clear();
  91. }
  92. virtual ~InputEngine() = default;
  93. // Enable configuring mode for mapping
  94. void BeginConfiguration();
  95. // Disable configuring mode for mapping
  96. void EndConfiguration();
  97. // Sets a led pattern for a controller
  98. virtual void SetLeds([[maybe_unused]] const PadIdentifier& identifier,
  99. [[maybe_unused]] const Common::Input::LedStatus led_status) {
  100. return;
  101. }
  102. // Sets rumble to a controller
  103. virtual Common::Input::VibrationError SetRumble(
  104. [[maybe_unused]] const PadIdentifier& identifier,
  105. [[maybe_unused]] const Common::Input::VibrationStatus vibration) {
  106. return Common::Input::VibrationError::NotSupported;
  107. }
  108. // Sets polling mode to a controller
  109. virtual Common::Input::PollingError SetPollingMode(
  110. [[maybe_unused]] const PadIdentifier& identifier,
  111. [[maybe_unused]] const Common::Input::PollingMode vibration) {
  112. return Common::Input::PollingError::NotSupported;
  113. }
  114. // Returns the engine name
  115. [[nodiscard]] const std::string& GetEngineName() const;
  116. /// Used for automapping features
  117. virtual std::vector<Common::ParamPackage> GetInputDevices() const {
  118. return {};
  119. };
  120. /// Retrieves the button mappings for the given device
  121. virtual InputCommon::ButtonMapping GetButtonMappingForDevice(
  122. [[maybe_unused]] const Common::ParamPackage& params) {
  123. return {};
  124. };
  125. /// Retrieves the analog mappings for the given device
  126. virtual InputCommon::AnalogMapping GetAnalogMappingForDevice(
  127. [[maybe_unused]] const Common::ParamPackage& params) {
  128. return {};
  129. };
  130. /// Retrieves the motion mappings for the given device
  131. virtual InputCommon::MotionMapping GetMotionMappingForDevice(
  132. [[maybe_unused]] const Common::ParamPackage& params) {
  133. return {};
  134. };
  135. /// Retrieves the name of the given input.
  136. virtual std::string GetUIName([[maybe_unused]] const Common::ParamPackage& params) const {
  137. return GetEngineName();
  138. };
  139. /// Retrieves the index number of the given hat button direction
  140. virtual u8 GetHatButtonId([[maybe_unused]] const std::string direction_name) const {
  141. return 0;
  142. };
  143. void PreSetController(const PadIdentifier& identifier);
  144. void PreSetButton(const PadIdentifier& identifier, int button);
  145. void PreSetHatButton(const PadIdentifier& identifier, int button);
  146. void PreSetAxis(const PadIdentifier& identifier, int axis);
  147. void PreSetMotion(const PadIdentifier& identifier, int motion);
  148. void ResetButtonState();
  149. void ResetAnalogState();
  150. bool GetButton(const PadIdentifier& identifier, int button) const;
  151. bool GetHatButton(const PadIdentifier& identifier, int button, u8 direction) const;
  152. f32 GetAxis(const PadIdentifier& identifier, int axis) const;
  153. BatteryLevel GetBattery(const PadIdentifier& identifier) const;
  154. BasicMotion GetMotion(const PadIdentifier& identifier, int motion) const;
  155. int SetCallback(InputIdentifier input_identifier);
  156. void SetMappingCallback(MappingCallback callback);
  157. void DeleteCallback(int key);
  158. protected:
  159. void SetButton(const PadIdentifier& identifier, int button, bool value);
  160. void SetHatButton(const PadIdentifier& identifier, int button, u8 value);
  161. void SetAxis(const PadIdentifier& identifier, int axis, f32 value);
  162. void SetBattery(const PadIdentifier& identifier, BatteryLevel value);
  163. void SetMotion(const PadIdentifier& identifier, int motion, BasicMotion value);
  164. virtual std::string GetHatButtonName([[maybe_unused]] u8 direction_value) const {
  165. return "Unknown";
  166. }
  167. private:
  168. struct ControllerData {
  169. std::unordered_map<int, bool> buttons;
  170. std::unordered_map<int, u8> hat_buttons;
  171. std::unordered_map<int, float> axes;
  172. std::unordered_map<int, BasicMotion> motions;
  173. BatteryLevel battery;
  174. };
  175. void TriggerOnButtonChange(const PadIdentifier& identifier, int button, bool value);
  176. void TriggerOnHatButtonChange(const PadIdentifier& identifier, int button, u8 value);
  177. void TriggerOnAxisChange(const PadIdentifier& identifier, int button, f32 value);
  178. void TriggerOnBatteryChange(const PadIdentifier& identifier, BatteryLevel value);
  179. void TriggerOnMotionChange(const PadIdentifier& identifier, int motion, BasicMotion value);
  180. bool IsInputIdentifierEqual(const InputIdentifier& input_identifier,
  181. const PadIdentifier& identifier, EngineInputType type,
  182. std::size_t index) const;
  183. mutable std::mutex mutex;
  184. mutable std::mutex mutex_callback;
  185. bool configuring{false};
  186. bool is_callback_enabled{true};
  187. const std::string input_engine;
  188. int last_callback_key = 0;
  189. std::unordered_map<PadIdentifier, ControllerData> controller_list;
  190. std::unordered_map<int, InputIdentifier> callback_list;
  191. MappingCallback mapping_callback;
  192. };
  193. } // namespace InputCommon