input_engine.h 7.2 KB

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