summaryrefslogtreecommitdiff
path: root/src/core/hid/emulated_controller.h
diff options
context:
space:
mode:
authorGravatar Feng Chen2021-12-18 13:57:14 +0800
committerGravatar GitHub2021-12-18 13:57:14 +0800
commite49184e6069a9d791d2df3c1958f5c4b1187e124 (patch)
treeb776caf722e0be0e680f67b0ad0842628162ef1c /src/core/hid/emulated_controller.h
parentImplement convert legacy to generic (diff)
parentMerge pull request #7570 from ameerj/favorites-expanded (diff)
downloadyuzu-e49184e6069a9d791d2df3c1958f5c4b1187e124.tar.gz
yuzu-e49184e6069a9d791d2df3c1958f5c4b1187e124.tar.xz
yuzu-e49184e6069a9d791d2df3c1958f5c4b1187e124.zip
Merge branch 'yuzu-emu:master' into convert_legacy
Diffstat (limited to 'src/core/hid/emulated_controller.h')
-rw-r--r--src/core/hid/emulated_controller.h411
1 files changed, 411 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..e42aafebc
--- /dev/null
+++ b/src/core/hid/emulated_controller.h
@@ -0,0 +1,411 @@
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
23namespace Core::HID {
24const std::size_t max_emulated_controllers = 2;
25struct ControllerMotionInfo {
26 Common::Input::MotionStatus raw_status{};
27 MotionInput emulated{};
28};
29
30using ButtonDevices =
31 std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeButton::NumButtons>;
32using StickDevices =
33 std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeAnalog::NumAnalogs>;
34using ControllerMotionDevices =
35 std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeMotion::NumMotions>;
36using TriggerDevices =
37 std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeTrigger::NumTriggers>;
38using BatteryDevices =
39 std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
40using OutputDevices =
41 std::array<std::unique_ptr<Common::Input::OutputDevice>, max_emulated_controllers>;
42
43using ButtonParams = std::array<Common::ParamPackage, Settings::NativeButton::NumButtons>;
44using StickParams = std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs>;
45using ControllerMotionParams = std::array<Common::ParamPackage, Settings::NativeMotion::NumMotions>;
46using TriggerParams = std::array<Common::ParamPackage, Settings::NativeTrigger::NumTriggers>;
47using BatteryParams = std::array<Common::ParamPackage, max_emulated_controllers>;
48using OutputParams = std::array<Common::ParamPackage, max_emulated_controllers>;
49
50using ButtonValues = std::array<Common::Input::ButtonStatus, Settings::NativeButton::NumButtons>;
51using SticksValues = std::array<Common::Input::StickStatus, Settings::NativeAnalog::NumAnalogs>;
52using TriggerValues =
53 std::array<Common::Input::TriggerStatus, Settings::NativeTrigger::NumTriggers>;
54using ControllerMotionValues = std::array<ControllerMotionInfo, Settings::NativeMotion::NumMotions>;
55using ColorValues = std::array<Common::Input::BodyColorStatus, max_emulated_controllers>;
56using BatteryValues = std::array<Common::Input::BatteryStatus, max_emulated_controllers>;
57using VibrationValues = std::array<Common::Input::VibrationStatus, max_emulated_controllers>;
58
59struct AnalogSticks {
60 AnalogStickState left{};
61 AnalogStickState right{};
62};
63
64struct ControllerColors {
65 NpadControllerColor fullkey{};
66 NpadControllerColor left{};
67 NpadControllerColor right{};
68};
69
70struct BatteryLevelState {
71 NpadPowerInfo dual{};
72 NpadPowerInfo left{};
73 NpadPowerInfo right{};
74};
75
76struct 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
84enum EmulatedDeviceIndex : u8 {
85 LeftIndex,
86 RightIndex,
87 DualIndex,
88 AllDevices,
89};
90
91using MotionState = std::array<ControllerMotion, 2>;
92
93struct 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
113enum 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
127struct ControllerUpdateCallback {
128 std::function<void(ControllerTriggerType)> on_change;
129 bool is_npad_service;
130};
131
132class EmulatedController {
133public:
134 /**
135 * Contains all input data (buttons, joysticks, vibration, and motion) within this controller.
136 * @param npad_id_type 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 get_temporary_value 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 /**
164 * Sets the supported controller types. Disconnects the controller if current type is not
165 * supported
166 * @param supported_styles bitflag with supported types
167 */
168 void SetSupportedNpadStyleTag(NpadStyleTag supported_styles);
169
170 /// Sets the connected status to true
171 void Connect();
172
173 /// Sets the connected status to false
174 void Disconnect();
175
176 /**
177 * Is the emulated connected
178 * @param get_temporary_value If true tmp_is_connected will be returned
179 * @return true if the controller has the connected status
180 */
181 bool IsConnected(bool get_temporary_value = false) const;
182
183 /// Returns true if vibration is enabled
184 bool IsVibrationEnabled() const;
185
186 /// Removes all callbacks created from input devices
187 void UnloadInput();
188
189 /**
190 * Sets the emulated controller into configuring mode
191 * This prevents the modification of the HID state of the emulated controller by input commands
192 */
193 void EnableConfiguration();
194
195 /// Returns the emulated controller into normal mode, allowing the modification of the HID state
196 void DisableConfiguration();
197
198 /// Returns true if the emulated controller is in configuring mode
199 bool IsConfiguring() const;
200
201 /// Reload all input devices
202 void ReloadInput();
203
204 /// Overrides current mapped devices with the stored configuration and reloads all input devices
205 void ReloadFromSettings();
206
207 /// Saves the current mapped configuration
208 void SaveCurrentConfig();
209
210 /// Reverts any mapped changes made that weren't saved
211 void RestoreConfig();
212
213 /// Returns a vector of mapped devices from the mapped button and stick parameters
214 std::vector<Common::ParamPackage> GetMappedDevices(EmulatedDeviceIndex device_index) const;
215
216 // Returns the current mapped button device
217 Common::ParamPackage GetButtonParam(std::size_t index) const;
218
219 // Returns the current mapped stick device
220 Common::ParamPackage GetStickParam(std::size_t index) const;
221
222 // Returns the current mapped motion device
223 Common::ParamPackage GetMotionParam(std::size_t index) const;
224
225 /**
226 * Updates the current mapped button device
227 * @param param ParamPackage with controller data to be mapped
228 */
229 void SetButtonParam(std::size_t index, Common::ParamPackage param);
230
231 /**
232 * Updates the current mapped stick device
233 * @param param ParamPackage with controller data to be mapped
234 */
235 void SetStickParam(std::size_t index, Common::ParamPackage param);
236
237 /**
238 * Updates the current mapped motion device
239 * @param param ParamPackage with controller data to be mapped
240 */
241 void SetMotionParam(std::size_t index, Common::ParamPackage param);
242
243 /// Returns the latest button status from the controller with parameters
244 ButtonValues GetButtonsValues() const;
245
246 /// Returns the latest analog stick status from the controller with parameters
247 SticksValues GetSticksValues() const;
248
249 /// Returns the latest trigger status from the controller with parameters
250 TriggerValues GetTriggersValues() const;
251
252 /// Returns the latest motion status from the controller with parameters
253 ControllerMotionValues GetMotionValues() const;
254
255 /// Returns the latest color status from the controller with parameters
256 ColorValues GetColorsValues() const;
257
258 /// Returns the latest battery status from the controller with parameters
259 BatteryValues GetBatteryValues() const;
260
261 /// Returns the latest status of button input for the npad service
262 NpadButtonState GetNpadButtons() const;
263
264 /// Returns the latest status of button input for the debug pad service
265 DebugPadButton GetDebugPadButtons() const;
266
267 /// Returns the latest status of stick input from the mouse
268 AnalogSticks GetSticks() const;
269
270 /// Returns the latest status of trigger input from the mouse
271 NpadGcTriggerState GetTriggers() const;
272
273 /// Returns the latest status of motion input from the mouse
274 MotionState GetMotions() const;
275
276 /// Returns the latest color value from the controller
277 ControllerColors GetColors() const;
278
279 /// Returns the latest battery status from the controller
280 BatteryLevelState GetBattery() const;
281
282 /**
283 * Sends a specific vibration to the output device
284 * @return returns true if vibration had no errors
285 */
286 bool SetVibration(std::size_t device_index, VibrationValue vibration);
287
288 /**
289 * Sends a small vibration to the output device
290 * @return returns true if SetVibration was successfull
291 */
292 bool TestVibration(std::size_t device_index);
293
294 /// Returns the led pattern corresponding to this emulated controller
295 LedPattern GetLedPattern() const;
296
297 /// Asks the output device to change the player led pattern
298 void SetLedPattern();
299
300 /**
301 * Adds a callback to the list of events
302 * @param update_callback A ConsoleUpdateCallback that will be triggered
303 * @return an unique key corresponding to the callback index in the list
304 */
305 int SetCallback(ControllerUpdateCallback update_callback);
306
307 /**
308 * Removes a callback from the list stopping any future events to this object
309 * @param key Key corresponding to the callback index in the list
310 */
311 void DeleteCallback(int key);
312
313private:
314 /// creates input devices from params
315 void LoadDevices();
316
317 /// Set the params for TAS devices
318 void LoadTASParams();
319
320 /**
321 * Checks the current controller type against the supported_style_tag
322 * @return true if the controller is supported
323 */
324 bool IsControllerSupported() const;
325
326 /**
327 * Updates the button status of the controller
328 * @param callback A CallbackStatus containing the button status
329 * @param index Button ID of the to be updated
330 */
331 void SetButton(const Common::Input::CallbackStatus& callback, std::size_t index,
332 Common::UUID uuid);
333
334 /**
335 * Updates the analog stick status of the controller
336 * @param callback A CallbackStatus containing the analog stick status
337 * @param index stick ID of the to be updated
338 */
339 void SetStick(const Common::Input::CallbackStatus& callback, std::size_t index,
340 Common::UUID uuid);
341
342 /**
343 * Updates the trigger status of the controller
344 * @param callback A CallbackStatus containing the trigger status
345 * @param index trigger ID of the to be updated
346 */
347 void SetTrigger(const Common::Input::CallbackStatus& callback, std::size_t index,
348 Common::UUID uuid);
349
350 /**
351 * Updates the motion status of the controller
352 * @param callback A CallbackStatus containing gyro and accelerometer data
353 * @param index motion ID of the to be updated
354 */
355 void SetMotion(const Common::Input::CallbackStatus& callback, std::size_t index);
356
357 /**
358 * Updates the battery status of the controller
359 * @param callback A CallbackStatus containing the battery status
360 * @param index Button ID of the to be updated
361 */
362 void SetBattery(const Common::Input::CallbackStatus& callback, std::size_t index);
363
364 /**
365 * Triggers a callback that something has changed on the controller status
366 * @param type Input type of the event to trigger
367 * @param is_service_update indicates if this event should only be sent to HID services
368 */
369 void TriggerOnChange(ControllerTriggerType type, bool is_service_update);
370
371 NpadIdType npad_id_type;
372 NpadStyleIndex npad_type{NpadStyleIndex::None};
373 NpadStyleTag supported_style_tag{NpadStyleSet::All};
374 bool is_connected{false};
375 bool is_configuring{false};
376 f32 motion_sensitivity{0.01f};
377 bool force_update_motion{false};
378
379 // Temporary values to avoid doing changes while the controller is in configuring mode
380 NpadStyleIndex tmp_npad_type{NpadStyleIndex::None};
381 bool tmp_is_connected{false};
382
383 ButtonParams button_params;
384 StickParams stick_params;
385 ControllerMotionParams motion_params;
386 TriggerParams trigger_params;
387 BatteryParams battery_params;
388 OutputParams output_params;
389
390 ButtonDevices button_devices;
391 StickDevices stick_devices;
392 ControllerMotionDevices motion_devices;
393 TriggerDevices trigger_devices;
394 BatteryDevices battery_devices;
395 OutputDevices output_devices;
396
397 // TAS related variables
398 ButtonParams tas_button_params;
399 StickParams tas_stick_params;
400 ButtonDevices tas_button_devices;
401 StickDevices tas_stick_devices;
402
403 mutable std::mutex mutex;
404 std::unordered_map<int, ControllerUpdateCallback> callback_list;
405 int last_callback_key = 0;
406
407 // Stores the current status of all controller input
408 ControllerStatus controller;
409};
410
411} // namespace Core::HID