diff options
Diffstat (limited to 'src/core/hid/emulated_controller.h')
| -rw-r--r-- | src/core/hid/emulated_controller.h | 392 |
1 files changed, 392 insertions, 0 deletions
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h new file mode 100644 index 000000000..2c5d51bc8 --- /dev/null +++ b/src/core/hid/emulated_controller.h | |||
| @@ -0,0 +1,392 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <array> | ||
| 8 | #include <functional> | ||
| 9 | #include <memory> | ||
| 10 | #include <mutex> | ||
| 11 | #include <unordered_map> | ||
| 12 | |||
| 13 | #include "common/common_types.h" | ||
| 14 | #include "common/input.h" | ||
| 15 | #include "common/param_package.h" | ||
| 16 | #include "common/point.h" | ||
| 17 | #include "common/quaternion.h" | ||
| 18 | #include "common/settings.h" | ||
| 19 | #include "common/vector_math.h" | ||
| 20 | #include "core/hid/hid_types.h" | ||
| 21 | #include "core/hid/motion_input.h" | ||
| 22 | |||
| 23 | namespace Core::HID { | ||
| 24 | const std::size_t max_emulated_controllers = 2; | ||
| 25 | struct ControllerMotionInfo { | ||
| 26 | Common::Input::MotionStatus raw_status{}; | ||
| 27 | MotionInput emulated{}; | ||
| 28 | }; | ||
| 29 | |||
| 30 | using ButtonDevices = | ||
| 31 | std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeButton::NumButtons>; | ||
| 32 | using StickDevices = | ||
| 33 | std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeAnalog::NumAnalogs>; | ||
| 34 | using ControllerMotionDevices = | ||
| 35 | std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeMotion::NumMotions>; | ||
| 36 | using TriggerDevices = | ||
| 37 | std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeTrigger::NumTriggers>; | ||
| 38 | using BatteryDevices = | ||
| 39 | std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>; | ||
| 40 | using OutputDevices = | ||
| 41 | std::array<std::unique_ptr<Common::Input::OutputDevice>, max_emulated_controllers>; | ||
| 42 | |||
| 43 | using ButtonParams = std::array<Common::ParamPackage, Settings::NativeButton::NumButtons>; | ||
| 44 | using StickParams = std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs>; | ||
| 45 | using ControllerMotionParams = std::array<Common::ParamPackage, Settings::NativeMotion::NumMotions>; | ||
| 46 | using TriggerParams = std::array<Common::ParamPackage, Settings::NativeTrigger::NumTriggers>; | ||
| 47 | using BatteryParams = std::array<Common::ParamPackage, max_emulated_controllers>; | ||
| 48 | using OutputParams = std::array<Common::ParamPackage, max_emulated_controllers>; | ||
| 49 | |||
| 50 | using ButtonValues = std::array<Common::Input::ButtonStatus, Settings::NativeButton::NumButtons>; | ||
| 51 | using SticksValues = std::array<Common::Input::StickStatus, Settings::NativeAnalog::NumAnalogs>; | ||
| 52 | using TriggerValues = | ||
| 53 | std::array<Common::Input::TriggerStatus, Settings::NativeTrigger::NumTriggers>; | ||
| 54 | using ControllerMotionValues = std::array<ControllerMotionInfo, Settings::NativeMotion::NumMotions>; | ||
| 55 | using ColorValues = std::array<Common::Input::BodyColorStatus, max_emulated_controllers>; | ||
| 56 | using BatteryValues = std::array<Common::Input::BatteryStatus, max_emulated_controllers>; | ||
| 57 | using VibrationValues = std::array<Common::Input::VibrationStatus, max_emulated_controllers>; | ||
| 58 | |||
| 59 | struct AnalogSticks { | ||
| 60 | AnalogStickState left{}; | ||
| 61 | AnalogStickState right{}; | ||
| 62 | }; | ||
| 63 | |||
| 64 | struct ControllerColors { | ||
| 65 | NpadControllerColor fullkey{}; | ||
| 66 | NpadControllerColor left{}; | ||
| 67 | NpadControllerColor right{}; | ||
| 68 | }; | ||
| 69 | |||
| 70 | struct BatteryLevelState { | ||
| 71 | NpadPowerInfo dual{}; | ||
| 72 | NpadPowerInfo left{}; | ||
| 73 | NpadPowerInfo right{}; | ||
| 74 | }; | ||
| 75 | |||
| 76 | struct ControllerMotion { | ||
| 77 | Common::Vec3f accel{}; | ||
| 78 | Common::Vec3f gyro{}; | ||
| 79 | Common::Vec3f rotation{}; | ||
| 80 | std::array<Common::Vec3f, 3> orientation{}; | ||
| 81 | bool is_at_rest{}; | ||
| 82 | }; | ||
| 83 | |||
| 84 | enum EmulatedDeviceIndex : u8 { | ||
| 85 | LeftIndex, | ||
| 86 | RightIndex, | ||
| 87 | DualIndex, | ||
| 88 | AllDevices, | ||
| 89 | }; | ||
| 90 | |||
| 91 | using MotionState = std::array<ControllerMotion, 2>; | ||
| 92 | |||
| 93 | struct ControllerStatus { | ||
| 94 | // Data from input_common | ||
| 95 | ButtonValues button_values{}; | ||
| 96 | SticksValues stick_values{}; | ||
| 97 | ControllerMotionValues motion_values{}; | ||
| 98 | TriggerValues trigger_values{}; | ||
| 99 | ColorValues color_values{}; | ||
| 100 | BatteryValues battery_values{}; | ||
| 101 | VibrationValues vibration_values{}; | ||
| 102 | |||
| 103 | // Data for HID serices | ||
| 104 | NpadButtonState npad_button_state{}; | ||
| 105 | DebugPadButton debug_pad_button_state{}; | ||
| 106 | AnalogSticks analog_stick_state{}; | ||
| 107 | MotionState motion_state{}; | ||
| 108 | NpadGcTriggerState gc_trigger_state{}; | ||
| 109 | ControllerColors colors_state{}; | ||
| 110 | BatteryLevelState battery_state{}; | ||
| 111 | }; | ||
| 112 | |||
| 113 | enum class ControllerTriggerType { | ||
| 114 | Button, | ||
| 115 | Stick, | ||
| 116 | Trigger, | ||
| 117 | Motion, | ||
| 118 | Color, | ||
| 119 | Battery, | ||
| 120 | Vibration, | ||
| 121 | Connected, | ||
| 122 | Disconnected, | ||
| 123 | Type, | ||
| 124 | All, | ||
| 125 | }; | ||
| 126 | |||
| 127 | struct ControllerUpdateCallback { | ||
| 128 | std::function<void(ControllerTriggerType)> on_change; | ||
| 129 | bool is_npad_service; | ||
| 130 | }; | ||
| 131 | |||
| 132 | class EmulatedController { | ||
| 133 | public: | ||
| 134 | /** | ||
| 135 | * Contains all input data related to this controller. Like buttons, joysticks, motion. | ||
| 136 | * @param Npad id type for this specific controller | ||
| 137 | */ | ||
| 138 | explicit EmulatedController(NpadIdType npad_id_type_); | ||
| 139 | ~EmulatedController(); | ||
| 140 | |||
| 141 | YUZU_NON_COPYABLE(EmulatedController); | ||
| 142 | YUZU_NON_MOVEABLE(EmulatedController); | ||
| 143 | |||
| 144 | /// Converts the controller type from settings to npad type | ||
| 145 | static NpadStyleIndex MapSettingsTypeToNPad(Settings::ControllerType type); | ||
| 146 | |||
| 147 | /// Converts npad type to the equivalent of controller type from settings | ||
| 148 | static Settings::ControllerType MapNPadToSettingsType(NpadStyleIndex type); | ||
| 149 | |||
| 150 | /// Gets the NpadIdType for this controller | ||
| 151 | NpadIdType GetNpadIdType() const; | ||
| 152 | |||
| 153 | /// Sets the NpadStyleIndex for this controller | ||
| 154 | void SetNpadStyleIndex(NpadStyleIndex npad_type_); | ||
| 155 | |||
| 156 | /** | ||
| 157 | * Gets the NpadStyleIndex for this controller | ||
| 158 | * @param If true tmp_npad_type will be returned | ||
| 159 | * @return NpadStyleIndex set on the controller | ||
| 160 | */ | ||
| 161 | NpadStyleIndex GetNpadStyleIndex(bool get_temporary_value = false) const; | ||
| 162 | |||
| 163 | /// Sets the connected status to true | ||
| 164 | void Connect(); | ||
| 165 | |||
| 166 | /// Sets the connected status to false | ||
| 167 | void Disconnect(); | ||
| 168 | |||
| 169 | /** | ||
| 170 | * Is the emulated connected | ||
| 171 | * @param If true tmp_is_connected will be returned | ||
| 172 | * @return true if the controller has the connected status | ||
| 173 | */ | ||
| 174 | bool IsConnected(bool get_temporary_value = false) const; | ||
| 175 | |||
| 176 | /// Returns true if vibration is enabled | ||
| 177 | bool IsVibrationEnabled() const; | ||
| 178 | |||
| 179 | /// Removes all callbacks created from input devices | ||
| 180 | void UnloadInput(); | ||
| 181 | |||
| 182 | /// Sets the emulated console into configuring mode. Locking all HID service events from being | ||
| 183 | /// moddified | ||
| 184 | void EnableConfiguration(); | ||
| 185 | |||
| 186 | /// Returns the emulated console to the normal behaivour | ||
| 187 | void DisableConfiguration(); | ||
| 188 | |||
| 189 | /// Returns true if the emulated device is on configuring mode | ||
| 190 | bool IsConfiguring() const; | ||
| 191 | |||
| 192 | /// Reload all input devices | ||
| 193 | void ReloadInput(); | ||
| 194 | |||
| 195 | /// Overrides current mapped devices with the stored configuration and reloads all input devices | ||
| 196 | void ReloadFromSettings(); | ||
| 197 | |||
| 198 | /// Saves the current mapped configuration | ||
| 199 | void SaveCurrentConfig(); | ||
| 200 | |||
| 201 | /// Reverts any mapped changes made that weren't saved | ||
| 202 | void RestoreConfig(); | ||
| 203 | |||
| 204 | /// Returns a vector of mapped devices from the mapped button and stick parameters | ||
| 205 | std::vector<Common::ParamPackage> GetMappedDevices(EmulatedDeviceIndex device_index) const; | ||
| 206 | |||
| 207 | // Returns the current mapped button device | ||
| 208 | Common::ParamPackage GetButtonParam(std::size_t index) const; | ||
| 209 | |||
| 210 | // Returns the current mapped stick device | ||
| 211 | Common::ParamPackage GetStickParam(std::size_t index) const; | ||
| 212 | |||
| 213 | // Returns the current mapped motion device | ||
| 214 | Common::ParamPackage GetMotionParam(std::size_t index) const; | ||
| 215 | |||
| 216 | /** | ||
| 217 | * Updates the current mapped button device | ||
| 218 | * @param ParamPackage with controller data to be mapped | ||
| 219 | */ | ||
| 220 | void SetButtonParam(std::size_t index, Common::ParamPackage param); | ||
| 221 | |||
| 222 | /** | ||
| 223 | * Updates the current mapped stick device | ||
| 224 | * @param ParamPackage with controller data to be mapped | ||
| 225 | */ | ||
| 226 | void SetStickParam(std::size_t index, Common::ParamPackage param); | ||
| 227 | |||
| 228 | /** | ||
| 229 | * Updates the current mapped motion device | ||
| 230 | * @param ParamPackage with controller data to be mapped | ||
| 231 | */ | ||
| 232 | void SetMotionParam(std::size_t index, Common::ParamPackage param); | ||
| 233 | |||
| 234 | /// Returns the latest button status from the controller with parameters | ||
| 235 | ButtonValues GetButtonsValues() const; | ||
| 236 | |||
| 237 | /// Returns the latest analog stick status from the controller with parameters | ||
| 238 | SticksValues GetSticksValues() const; | ||
| 239 | |||
| 240 | /// Returns the latest trigger status from the controller with parameters | ||
| 241 | TriggerValues GetTriggersValues() const; | ||
| 242 | |||
| 243 | /// Returns the latest motion status from the controller with parameters | ||
| 244 | ControllerMotionValues GetMotionValues() const; | ||
| 245 | |||
| 246 | /// Returns the latest color status from the controller with parameters | ||
| 247 | ColorValues GetColorsValues() const; | ||
| 248 | |||
| 249 | /// Returns the latest battery status from the controller with parameters | ||
| 250 | BatteryValues GetBatteryValues() const; | ||
| 251 | |||
| 252 | /// Returns the latest status of button input for the npad service | ||
| 253 | NpadButtonState GetNpadButtons() const; | ||
| 254 | |||
| 255 | /// Returns the latest status of button input for the debug pad service | ||
| 256 | DebugPadButton GetDebugPadButtons() const; | ||
| 257 | |||
| 258 | /// Returns the latest status of stick input from the mouse | ||
| 259 | AnalogSticks GetSticks() const; | ||
| 260 | |||
| 261 | /// Returns the latest status of trigger input from the mouse | ||
| 262 | NpadGcTriggerState GetTriggers() const; | ||
| 263 | |||
| 264 | /// Returns the latest status of motion input from the mouse | ||
| 265 | MotionState GetMotions() const; | ||
| 266 | |||
| 267 | /// Returns the latest color value from the controller | ||
| 268 | ControllerColors GetColors() const; | ||
| 269 | |||
| 270 | /// Returns the latest battery status from the controller | ||
| 271 | BatteryLevelState GetBattery() const; | ||
| 272 | |||
| 273 | /* | ||
| 274 | * Sends a specific vibration to the output device | ||
| 275 | * @return returns true if vibration had no errors | ||
| 276 | */ | ||
| 277 | bool SetVibration(std::size_t device_index, VibrationValue vibration); | ||
| 278 | |||
| 279 | /* | ||
| 280 | * Sends a small vibration to the output device | ||
| 281 | * @return returns true if SetVibration was successfull | ||
| 282 | */ | ||
| 283 | bool TestVibration(std::size_t device_index); | ||
| 284 | |||
| 285 | /// Returns the led pattern corresponding to this emulated controller | ||
| 286 | LedPattern GetLedPattern() const; | ||
| 287 | |||
| 288 | /// Asks the output device to change the player led pattern | ||
| 289 | void SetLedPattern(); | ||
| 290 | |||
| 291 | /** | ||
| 292 | * Adds a callback to the list of events | ||
| 293 | * @param ConsoleUpdateCallback that will be triggered | ||
| 294 | * @return an unique key corresponding to the callback index in the list | ||
| 295 | */ | ||
| 296 | int SetCallback(ControllerUpdateCallback update_callback); | ||
| 297 | |||
| 298 | /** | ||
| 299 | * Removes a callback from the list stopping any future events to this object | ||
| 300 | * @param Key corresponding to the callback index in the list | ||
| 301 | */ | ||
| 302 | void DeleteCallback(int key); | ||
| 303 | |||
| 304 | private: | ||
| 305 | /// creates input devices from params | ||
| 306 | void LoadDevices(); | ||
| 307 | |||
| 308 | /// Set the params for TAS devices | ||
| 309 | void LoadTASParams(); | ||
| 310 | |||
| 311 | /** | ||
| 312 | * Updates the button status of the controller | ||
| 313 | * @param callback: A CallbackStatus containing the button status | ||
| 314 | * @param index: Button ID of the to be updated | ||
| 315 | */ | ||
| 316 | void SetButton(Common::Input::CallbackStatus callback, std::size_t index, Common::UUID uuid); | ||
| 317 | |||
| 318 | /** | ||
| 319 | * Updates the analog stick status of the controller | ||
| 320 | * @param callback: A CallbackStatus containing the analog stick status | ||
| 321 | * @param index: stick ID of the to be updated | ||
| 322 | */ | ||
| 323 | void SetStick(Common::Input::CallbackStatus callback, std::size_t index, Common::UUID uuid); | ||
| 324 | |||
| 325 | /** | ||
| 326 | * Updates the trigger status of the controller | ||
| 327 | * @param callback: A CallbackStatus containing the trigger status | ||
| 328 | * @param index: trigger ID of the to be updated | ||
| 329 | */ | ||
| 330 | void SetTrigger(Common::Input::CallbackStatus callback, std::size_t index, Common::UUID uuid); | ||
| 331 | |||
| 332 | /** | ||
| 333 | * Updates the motion status of the controller | ||
| 334 | * @param callback: A CallbackStatus containing gyro and accelerometer data | ||
| 335 | * @param index: motion ID of the to be updated | ||
| 336 | */ | ||
| 337 | void SetMotion(Common::Input::CallbackStatus callback, std::size_t index); | ||
| 338 | |||
| 339 | /** | ||
| 340 | * Updates the battery status of the controller | ||
| 341 | * @param callback: A CallbackStatus containing the battery status | ||
| 342 | * @param index: Button ID of the to be updated | ||
| 343 | */ | ||
| 344 | void SetBattery(Common::Input::CallbackStatus callback, std::size_t index); | ||
| 345 | |||
| 346 | /** | ||
| 347 | * Triggers a callback that something has changed on the controller status | ||
| 348 | * @param type: Input type of the event to trigger | ||
| 349 | * @param is_service_update: indicates if this event should be sended to only services | ||
| 350 | */ | ||
| 351 | void TriggerOnChange(ControllerTriggerType type, bool is_service_update); | ||
| 352 | |||
| 353 | NpadIdType npad_id_type; | ||
| 354 | NpadStyleIndex npad_type{NpadStyleIndex::None}; | ||
| 355 | bool is_connected{false}; | ||
| 356 | bool is_configuring{false}; | ||
| 357 | f32 motion_sensitivity{0.01f}; | ||
| 358 | bool force_update_motion{false}; | ||
| 359 | |||
| 360 | // Temporary values to avoid doing changes while the controller is on configuration mode | ||
| 361 | NpadStyleIndex tmp_npad_type{NpadStyleIndex::None}; | ||
| 362 | bool tmp_is_connected{false}; | ||
| 363 | |||
| 364 | ButtonParams button_params; | ||
| 365 | StickParams stick_params; | ||
| 366 | ControllerMotionParams motion_params; | ||
| 367 | TriggerParams trigger_params; | ||
| 368 | BatteryParams battery_params; | ||
| 369 | OutputParams output_params; | ||
| 370 | |||
| 371 | ButtonDevices button_devices; | ||
| 372 | StickDevices stick_devices; | ||
| 373 | ControllerMotionDevices motion_devices; | ||
| 374 | TriggerDevices trigger_devices; | ||
| 375 | BatteryDevices battery_devices; | ||
| 376 | OutputDevices output_devices; | ||
| 377 | |||
| 378 | // TAS related variables | ||
| 379 | ButtonParams tas_button_params; | ||
| 380 | StickParams tas_stick_params; | ||
| 381 | ButtonDevices tas_button_devices; | ||
| 382 | StickDevices tas_stick_devices; | ||
| 383 | |||
| 384 | mutable std::mutex mutex; | ||
| 385 | std::unordered_map<int, ControllerUpdateCallback> callback_list; | ||
| 386 | int last_callback_key = 0; | ||
| 387 | |||
| 388 | // Stores the current status of all controller input | ||
| 389 | ControllerStatus controller; | ||
| 390 | }; | ||
| 391 | |||
| 392 | } // namespace Core::HID | ||