input_engine.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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 Input::LedStatus led_status) {
  100. return;
  101. }
  102. // Sets rumble to a controller
  103. virtual Input::VibrationError SetRumble([[maybe_unused]] const PadIdentifier& identifier,
  104. [[maybe_unused]] const Input::VibrationStatus vibration) {
  105. return Input::VibrationError::NotSupported;
  106. }
  107. // Sets polling mode to a controller
  108. virtual Input::PollingError SetPollingMode([[maybe_unused]] const PadIdentifier& identifier,
  109. [[maybe_unused]] const Input::PollingMode vibration) {
  110. return Input::PollingError::NotSupported;
  111. }
  112. // Returns the engine name
  113. [[nodiscard]] const std::string& GetEngineName() const;
  114. /// Used for automapping features
  115. virtual std::vector<Common::ParamPackage> GetInputDevices() const {
  116. return {};
  117. };
  118. /// Retrieves the button mappings for the given device
  119. virtual InputCommon::ButtonMapping GetButtonMappingForDevice(
  120. [[maybe_unused]] const Common::ParamPackage& params) {
  121. return {};
  122. };
  123. /// Retrieves the analog mappings for the given device
  124. virtual InputCommon::AnalogMapping GetAnalogMappingForDevice(
  125. [[maybe_unused]] const Common::ParamPackage& params) {
  126. return {};
  127. };
  128. /// Retrieves the motion mappings for the given device
  129. virtual InputCommon::MotionMapping GetMotionMappingForDevice(
  130. [[maybe_unused]] const Common::ParamPackage& params) {
  131. return {};
  132. };
  133. /// Retrieves the name of the given input.
  134. virtual std::string GetUIName([[maybe_unused]] const Common::ParamPackage& params) const {
  135. return GetEngineName();
  136. };
  137. /// Retrieves the index number of the given hat button direction
  138. virtual u8 GetHatButtonId([[maybe_unused]] const std::string direction_name) const {
  139. return 0;
  140. };
  141. void PreSetController(const PadIdentifier& identifier);
  142. void PreSetButton(const PadIdentifier& identifier, int button);
  143. void PreSetHatButton(const PadIdentifier& identifier, int button);
  144. void PreSetAxis(const PadIdentifier& identifier, int axis);
  145. void PreSetMotion(const PadIdentifier& identifier, int motion);
  146. void ResetButtonState();
  147. void ResetAnalogState();
  148. bool GetButton(const PadIdentifier& identifier, int button) const;
  149. bool GetHatButton(const PadIdentifier& identifier, int button, u8 direction) const;
  150. f32 GetAxis(const PadIdentifier& identifier, int axis) const;
  151. BatteryLevel GetBattery(const PadIdentifier& identifier) const;
  152. BasicMotion GetMotion(const PadIdentifier& identifier, int motion) const;
  153. int SetCallback(InputIdentifier input_identifier);
  154. void SetMappingCallback(MappingCallback callback);
  155. void DeleteCallback(int key);
  156. protected:
  157. void SetButton(const PadIdentifier& identifier, int button, bool value);
  158. void SetHatButton(const PadIdentifier& identifier, int button, u8 value);
  159. void SetAxis(const PadIdentifier& identifier, int axis, f32 value);
  160. void SetBattery(const PadIdentifier& identifier, BatteryLevel value);
  161. void SetMotion(const PadIdentifier& identifier, int motion, BasicMotion value);
  162. virtual std::string GetHatButtonName([[maybe_unused]] u8 direction_value) const {
  163. return "Unknown";
  164. }
  165. private:
  166. struct ControllerData {
  167. std::unordered_map<int, bool> buttons;
  168. std::unordered_map<int, u8> hat_buttons;
  169. std::unordered_map<int, float> axes;
  170. std::unordered_map<int, BasicMotion> motions;
  171. BatteryLevel battery;
  172. };
  173. void TriggerOnButtonChange(const PadIdentifier& identifier, int button, bool value);
  174. void TriggerOnHatButtonChange(const PadIdentifier& identifier, int button, u8 value);
  175. void TriggerOnAxisChange(const PadIdentifier& identifier, int button, f32 value);
  176. void TriggerOnBatteryChange(const PadIdentifier& identifier, BatteryLevel value);
  177. void TriggerOnMotionChange(const PadIdentifier& identifier, int motion, BasicMotion value);
  178. bool IsInputIdentifierEqual(const InputIdentifier& input_identifier,
  179. const PadIdentifier& identifier, EngineInputType type,
  180. std::size_t index) const;
  181. mutable std::mutex mutex;
  182. mutable std::mutex mutex_callback;
  183. bool configuring{false};
  184. bool is_callback_enabled{true};
  185. const std::string input_engine;
  186. int last_callback_key = 0;
  187. std::unordered_map<PadIdentifier, ControllerData> controller_list;
  188. std::unordered_map<int, InputIdentifier> callback_list;
  189. MappingCallback mapping_callback;
  190. };
  191. } // namespace InputCommon