summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorGravatar Fernando S2021-11-27 11:52:08 +0100
committerGravatar GitHub2021-11-27 11:52:08 +0100
commit564f10527745f870621c08bbb5d16badee0ed861 (patch)
treee8ac8dee60086facf1837393882865f5df18c95e /src/common
parentMerge pull request #7431 from liushuyu/fix-linux-decoding (diff)
parentconfig: Remove vibration configuration (diff)
downloadyuzu-564f10527745f870621c08bbb5d16badee0ed861.tar.gz
yuzu-564f10527745f870621c08bbb5d16badee0ed861.tar.xz
yuzu-564f10527745f870621c08bbb5d16badee0ed861.zip
Merge pull request #7255 from german77/kraken
Project Kraken: Input rewrite
Diffstat (limited to 'src/common')
-rw-r--r--src/common/CMakeLists.txt1
-rw-r--r--src/common/input.h372
-rw-r--r--src/common/settings.h12
-rw-r--r--src/common/settings_input.h65
4 files changed, 420 insertions, 30 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 23d43a394..919da4a53 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -73,6 +73,7 @@ add_library(common STATIC
73 hex_util.h 73 hex_util.h
74 host_memory.cpp 74 host_memory.cpp
75 host_memory.h 75 host_memory.h
76 input.h
76 intrusive_red_black_tree.h 77 intrusive_red_black_tree.h
77 literals.h 78 literals.h
78 logging/backend.cpp 79 logging/backend.cpp
diff --git a/src/common/input.h b/src/common/input.h
new file mode 100644
index 000000000..eaee0bdea
--- /dev/null
+++ b/src/common/input.h
@@ -0,0 +1,372 @@
1// Copyright 2017 Citra 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 <functional>
8#include <memory>
9#include <string>
10#include <unordered_map>
11#include <utility>
12#include "common/logging/log.h"
13#include "common/param_package.h"
14#include "common/uuid.h"
15
16namespace Common::Input {
17
18// Type of data that is expected to recieve or send
19enum class InputType {
20 None,
21 Battery,
22 Button,
23 Stick,
24 Analog,
25 Trigger,
26 Motion,
27 Touch,
28 Color,
29 Vibration,
30 Nfc,
31 Ir,
32};
33
34// Internal battery charge level
35enum class BatteryLevel : u32 {
36 None,
37 Empty,
38 Critical,
39 Low,
40 Medium,
41 Full,
42 Charging,
43};
44
45enum class PollingMode {
46 // Constant polling of buttons, analogs and motion data
47 Active,
48 // Only update on button change, digital analogs
49 Pasive,
50 // Enable near field communication polling
51 NFC,
52 // Enable infrared camera polling
53 IR,
54};
55
56// Vibration reply from the controller
57enum class VibrationError {
58 None,
59 NotSupported,
60 Disabled,
61 Unknown,
62};
63
64// Polling mode reply from the controller
65enum class PollingError {
66 None,
67 NotSupported,
68 Unknown,
69};
70
71// Hint for amplification curve to be used
72enum class VibrationAmplificationType {
73 Linear,
74 Exponential,
75};
76
77// Analog properties for calibration
78struct AnalogProperties {
79 // Anything below this value will be detected as zero
80 float deadzone{};
81 // Anyting above this values will be detected as one
82 float range{1.0f};
83 // Minimum value to be detected as active
84 float threshold{0.5f};
85 // Drift correction applied to the raw data
86 float offset{};
87 // Invert direction of the sensor data
88 bool inverted{};
89};
90
91// Single analog sensor data
92struct AnalogStatus {
93 float value{};
94 float raw_value{};
95 AnalogProperties properties{};
96};
97
98// Button data
99struct ButtonStatus {
100 Common::UUID uuid{};
101 bool value{};
102 bool inverted{};
103 bool toggle{};
104 bool locked{};
105};
106
107// Internal battery data
108using BatteryStatus = BatteryLevel;
109
110// Analog and digital joystick data
111struct StickStatus {
112 Common::UUID uuid{};
113 AnalogStatus x{};
114 AnalogStatus y{};
115 bool left{};
116 bool right{};
117 bool up{};
118 bool down{};
119};
120
121// Analog and digital trigger data
122struct TriggerStatus {
123 Common::UUID uuid{};
124 AnalogStatus analog{};
125 ButtonStatus pressed{};
126};
127
128// 3D vector representing motion input
129struct MotionSensor {
130 AnalogStatus x{};
131 AnalogStatus y{};
132 AnalogStatus z{};
133};
134
135// Motion data used to calculate controller orientation
136struct MotionStatus {
137 // Gyroscope vector measurement in radians/s.
138 MotionSensor gyro{};
139 // Acceleration vector measurement in G force
140 MotionSensor accel{};
141 // Time since last measurement in microseconds
142 u64 delta_timestamp{};
143 // Request to update after reading the value
144 bool force_update{};
145};
146
147// Data of a single point on a touch screen
148struct TouchStatus {
149 ButtonStatus pressed{};
150 AnalogStatus x{};
151 AnalogStatus y{};
152 int id{};
153};
154
155// Physical controller color in RGB format
156struct BodyColorStatus {
157 u32 body{};
158 u32 buttons{};
159};
160
161// HD rumble data
162struct VibrationStatus {
163 f32 low_amplitude{};
164 f32 low_frequency{};
165 f32 high_amplitude{};
166 f32 high_frequency{};
167 VibrationAmplificationType type;
168};
169
170// Physical controller LED pattern
171struct LedStatus {
172 bool led_1{};
173 bool led_2{};
174 bool led_3{};
175 bool led_4{};
176};
177
178// List of buttons to be passed to Qt that can be translated
179enum class ButtonNames {
180 Undefined,
181 Invalid,
182 // This will display the engine name instead of the button name
183 Engine,
184 // This will display the button by value instead of the button name
185 Value,
186 ButtonLeft,
187 ButtonRight,
188 ButtonDown,
189 ButtonUp,
190 TriggerZ,
191 TriggerR,
192 TriggerL,
193 ButtonA,
194 ButtonB,
195 ButtonX,
196 ButtonY,
197 ButtonStart,
198
199 // DS4 button names
200 L1,
201 L2,
202 L3,
203 R1,
204 R2,
205 R3,
206 Circle,
207 Cross,
208 Square,
209 Triangle,
210 Share,
211 Options,
212};
213
214// Callback data consisting of an input type and the equivalent data status
215struct CallbackStatus {
216 InputType type{InputType::None};
217 ButtonStatus button_status{};
218 StickStatus stick_status{};
219 AnalogStatus analog_status{};
220 TriggerStatus trigger_status{};
221 MotionStatus motion_status{};
222 TouchStatus touch_status{};
223 BodyColorStatus color_status{};
224 BatteryStatus battery_status{};
225 VibrationStatus vibration_status{};
226};
227
228// Triggered once every input change
229struct InputCallback {
230 std::function<void(CallbackStatus)> on_change;
231};
232
233/// An abstract class template for an input device (a button, an analog input, etc.).
234class InputDevice {
235public:
236 virtual ~InputDevice() = default;
237
238 // Request input device to update if necessary
239 virtual void SoftUpdate() {
240 return;
241 }
242
243 // Force input device to update data regardless of the current state
244 virtual void ForceUpdate() {
245 return;
246 }
247
248 // Sets the function to be triggered when input changes
249 void SetCallback(InputCallback callback_) {
250 callback = std::move(callback_);
251 }
252
253 // Triggers the function set in the callback
254 void TriggerOnChange(CallbackStatus status) {
255 if (callback.on_change) {
256 callback.on_change(status);
257 }
258 }
259
260private:
261 InputCallback callback;
262};
263
264/// An abstract class template for an output device (rumble, LED pattern, polling mode).
265class OutputDevice {
266public:
267 virtual ~OutputDevice() = default;
268
269 virtual void SetLED([[maybe_unused]] LedStatus led_status) {
270 return;
271 }
272
273 virtual VibrationError SetVibration([[maybe_unused]] VibrationStatus vibration_status) {
274 return VibrationError::NotSupported;
275 }
276
277 virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) {
278 return PollingError::NotSupported;
279 }
280};
281
282/// An abstract class template for a factory that can create input devices.
283template <typename InputDeviceType>
284class Factory {
285public:
286 virtual ~Factory() = default;
287 virtual std::unique_ptr<InputDeviceType> Create(const Common::ParamPackage&) = 0;
288};
289
290namespace Impl {
291
292template <typename InputDeviceType>
293using FactoryListType = std::unordered_map<std::string, std::shared_ptr<Factory<InputDeviceType>>>;
294
295template <typename InputDeviceType>
296struct FactoryList {
297 static FactoryListType<InputDeviceType> list;
298};
299
300template <typename InputDeviceType>
301FactoryListType<InputDeviceType> FactoryList<InputDeviceType>::list;
302
303} // namespace Impl
304
305/**
306 * Registers an input device factory.
307 * @tparam InputDeviceType the type of input devices the factory can create
308 * @param name the name of the factory. Will be used to match the "engine" parameter when creating
309 * a device
310 * @param factory the factory object to register
311 */
312template <typename InputDeviceType>
313void RegisterFactory(const std::string& name, std::shared_ptr<Factory<InputDeviceType>> factory) {
314 auto pair = std::make_pair(name, std::move(factory));
315 if (!Impl::FactoryList<InputDeviceType>::list.insert(std::move(pair)).second) {
316 LOG_ERROR(Input, "Factory '{}' already registered", name);
317 }
318}
319
320/**
321 * Unregisters an input device factory.
322 * @tparam InputDeviceType the type of input devices the factory can create
323 * @param name the name of the factory to unregister
324 */
325template <typename InputDeviceType>
326void UnregisterFactory(const std::string& name) {
327 if (Impl::FactoryList<InputDeviceType>::list.erase(name) == 0) {
328 LOG_ERROR(Input, "Factory '{}' not registered", name);
329 }
330}
331
332/**
333 * Create an input device from given paramters.
334 * @tparam InputDeviceType the type of input devices to create
335 * @param params a serialized ParamPackage string that contains all parameters for creating the
336 * device
337 */
338template <typename InputDeviceType>
339std::unique_ptr<InputDeviceType> CreateDeviceFromString(const std::string& params) {
340 const Common::ParamPackage package(params);
341 const std::string engine = package.Get("engine", "null");
342 const auto& factory_list = Impl::FactoryList<InputDeviceType>::list;
343 const auto pair = factory_list.find(engine);
344 if (pair == factory_list.end()) {
345 if (engine != "null") {
346 LOG_ERROR(Input, "Unknown engine name: {}", engine);
347 }
348 return std::make_unique<InputDeviceType>();
349 }
350 return pair->second->Create(package);
351}
352
353/**
354 * Create an input device from given paramters.
355 * @tparam InputDeviceType the type of input devices to create
356 * @param A ParamPackage that contains all parameters for creating the device
357 */
358template <typename InputDeviceType>
359std::unique_ptr<InputDeviceType> CreateDevice(const Common::ParamPackage package) {
360 const std::string engine = package.Get("engine", "null");
361 const auto& factory_list = Impl::FactoryList<InputDeviceType>::list;
362 const auto pair = factory_list.find(engine);
363 if (pair == factory_list.end()) {
364 if (engine != "null") {
365 LOG_ERROR(Input, "Unknown engine name: {}", engine);
366 }
367 return std::make_unique<InputDeviceType>();
368 }
369 return pair->second->Create(package);
370}
371
372} // namespace Common::Input
diff --git a/src/common/settings.h b/src/common/settings.h
index fa4aa8747..e4e049f67 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -6,7 +6,6 @@
6 6
7#include <algorithm> 7#include <algorithm>
8#include <array> 8#include <array>
9#include <atomic>
10#include <map> 9#include <map>
11#include <optional> 10#include <optional>
12#include <string> 11#include <string>
@@ -560,25 +559,19 @@ struct Values {
560 Setting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"}; 559 Setting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"};
561 560
562 Setting<bool> motion_enabled{true, "motion_enabled"}; 561 Setting<bool> motion_enabled{true, "motion_enabled"};
563 BasicSetting<std::string> motion_device{"engine:motion_emu,update_period:100,sensitivity:0.01",
564 "motion_device"};
565 BasicSetting<std::string> udp_input_servers{"127.0.0.1:26760", "udp_input_servers"}; 562 BasicSetting<std::string> udp_input_servers{"127.0.0.1:26760", "udp_input_servers"};
563 BasicSetting<bool> enable_udp_controller{false, "enable_udp_controller"};
566 564
567 BasicSetting<bool> pause_tas_on_load{true, "pause_tas_on_load"}; 565 BasicSetting<bool> pause_tas_on_load{true, "pause_tas_on_load"};
568 BasicSetting<bool> tas_enable{false, "tas_enable"}; 566 BasicSetting<bool> tas_enable{false, "tas_enable"};
569 BasicSetting<bool> tas_loop{false, "tas_loop"}; 567 BasicSetting<bool> tas_loop{false, "tas_loop"};
570 BasicSetting<bool> tas_swap_controllers{true, "tas_swap_controllers"};
571 568
572 BasicSetting<bool> mouse_panning{false, "mouse_panning"}; 569 BasicSetting<bool> mouse_panning{false, "mouse_panning"};
573 BasicRangedSetting<u8> mouse_panning_sensitivity{10, 1, 100, "mouse_panning_sensitivity"}; 570 BasicRangedSetting<u8> mouse_panning_sensitivity{10, 1, 100, "mouse_panning_sensitivity"};
574 BasicSetting<bool> mouse_enabled{false, "mouse_enabled"}; 571 BasicSetting<bool> mouse_enabled{false, "mouse_enabled"};
575 std::string mouse_device;
576 MouseButtonsRaw mouse_buttons;
577 572
578 BasicSetting<bool> emulate_analog_keyboard{false, "emulate_analog_keyboard"}; 573 BasicSetting<bool> emulate_analog_keyboard{false, "emulate_analog_keyboard"};
579 BasicSetting<bool> keyboard_enabled{false, "keyboard_enabled"}; 574 BasicSetting<bool> keyboard_enabled{false, "keyboard_enabled"};
580 KeyboardKeysRaw keyboard_keys;
581 KeyboardModsRaw keyboard_mods;
582 575
583 BasicSetting<bool> debug_pad_enabled{false, "debug_pad_enabled"}; 576 BasicSetting<bool> debug_pad_enabled{false, "debug_pad_enabled"};
584 ButtonsRaw debug_pad_buttons; 577 ButtonsRaw debug_pad_buttons;
@@ -586,14 +579,11 @@ struct Values {
586 579
587 TouchscreenInput touchscreen; 580 TouchscreenInput touchscreen;
588 581
589 BasicSetting<bool> use_touch_from_button{false, "use_touch_from_button"};
590 BasicSetting<std::string> touch_device{"min_x:100,min_y:50,max_x:1800,max_y:850", 582 BasicSetting<std::string> touch_device{"min_x:100,min_y:50,max_x:1800,max_y:850",
591 "touch_device"}; 583 "touch_device"};
592 BasicSetting<int> touch_from_button_map_index{0, "touch_from_button_map"}; 584 BasicSetting<int> touch_from_button_map_index{0, "touch_from_button_map"};
593 std::vector<TouchFromButtonMap> touch_from_button_maps; 585 std::vector<TouchFromButtonMap> touch_from_button_maps;
594 586
595 std::atomic_bool is_device_reload_pending{true};
596
597 // Data Storage 587 // Data Storage
598 BasicSetting<bool> use_virtual_sd{true, "use_virtual_sd"}; 588 BasicSetting<bool> use_virtual_sd{true, "use_virtual_sd"};
599 BasicSetting<bool> gamecard_inserted{false, "gamecard_inserted"}; 589 BasicSetting<bool> gamecard_inserted{false, "gamecard_inserted"};
diff --git a/src/common/settings_input.h b/src/common/settings_input.h
index 609600582..9e3df7376 100644
--- a/src/common/settings_input.h
+++ b/src/common/settings_input.h
@@ -62,11 +62,22 @@ enum Values : int {
62 62
63constexpr int STICK_HID_BEGIN = LStick; 63constexpr int STICK_HID_BEGIN = LStick;
64constexpr int STICK_HID_END = NumAnalogs; 64constexpr int STICK_HID_END = NumAnalogs;
65constexpr int NUM_STICKS_HID = NumAnalogs;
66 65
67extern const std::array<const char*, NumAnalogs> mapping; 66extern const std::array<const char*, NumAnalogs> mapping;
68} // namespace NativeAnalog 67} // namespace NativeAnalog
69 68
69namespace NativeTrigger {
70enum Values : int {
71 LTrigger,
72 RTrigger,
73
74 NumTriggers,
75};
76
77constexpr int TRIGGER_HID_BEGIN = LTrigger;
78constexpr int TRIGGER_HID_END = NumTriggers;
79} // namespace NativeTrigger
80
70namespace NativeVibration { 81namespace NativeVibration {
71enum Values : int { 82enum Values : int {
72 LeftVibrationDevice, 83 LeftVibrationDevice,
@@ -115,10 +126,20 @@ constexpr int NUM_MOUSE_HID = NumMouseButtons;
115extern const std::array<const char*, NumMouseButtons> mapping; 126extern const std::array<const char*, NumMouseButtons> mapping;
116} // namespace NativeMouseButton 127} // namespace NativeMouseButton
117 128
129namespace NativeMouseWheel {
130enum Values {
131 X,
132 Y,
133
134 NumMouseWheels,
135};
136
137extern const std::array<const char*, NumMouseWheels> mapping;
138} // namespace NativeMouseWheel
139
118namespace NativeKeyboard { 140namespace NativeKeyboard {
119enum Keys { 141enum Keys {
120 None, 142 None,
121 Error,
122 143
123 A = 4, 144 A = 4,
124 B, 145 B,
@@ -156,22 +177,22 @@ enum Keys {
156 N8, 177 N8,
157 N9, 178 N9,
158 N0, 179 N0,
159 Enter, 180 Return,
160 Escape, 181 Escape,
161 Backspace, 182 Backspace,
162 Tab, 183 Tab,
163 Space, 184 Space,
164 Minus, 185 Minus,
165 Equal, 186 Plus,
166 LeftBrace, 187 OpenBracket,
167 RightBrace, 188 CloseBracket,
168 Backslash, 189 Pipe,
169 Tilde, 190 Tilde,
170 Semicolon, 191 Semicolon,
171 Apostrophe, 192 Quote,
172 Grave, 193 Backquote,
173 Comma, 194 Comma,
174 Dot, 195 Period,
175 Slash, 196 Slash,
176 CapsLockKey, 197 CapsLockKey,
177 198
@@ -188,7 +209,7 @@ enum Keys {
188 F11, 209 F11,
189 F12, 210 F12,
190 211
191 SystemRequest, 212 PrintScreen,
192 ScrollLockKey, 213 ScrollLockKey,
193 Pause, 214 Pause,
194 Insert, 215 Insert,
@@ -257,8 +278,18 @@ enum Keys {
257 ScrollLockActive, 278 ScrollLockActive,
258 KPComma, 279 KPComma,
259 280
260 KPLeftParenthesis, 281 Ro = 0x87,
261 KPRightParenthesis, 282 KatakanaHiragana,
283 Yen,
284 Henkan,
285 Muhenkan,
286 NumPadCommaPc98,
287
288 HangulEnglish = 0x90,
289 Hanja,
290 KatakanaKey,
291 HiraganaKey,
292 ZenkakuHankaku,
262 293
263 LeftControlKey = 0xE0, 294 LeftControlKey = 0xE0,
264 LeftShiftKey, 295 LeftShiftKey,
@@ -307,6 +338,8 @@ enum Modifiers {
307 CapsLock, 338 CapsLock,
308 ScrollLock, 339 ScrollLock,
309 NumLock, 340 NumLock,
341 Katakana,
342 Hiragana,
310 343
311 NumKeyboardMods, 344 NumKeyboardMods,
312}; 345};
@@ -324,11 +357,6 @@ constexpr int NUM_KEYBOARD_MODS_HID = NumKeyboardMods;
324using AnalogsRaw = std::array<std::string, NativeAnalog::NumAnalogs>; 357using AnalogsRaw = std::array<std::string, NativeAnalog::NumAnalogs>;
325using ButtonsRaw = std::array<std::string, NativeButton::NumButtons>; 358using ButtonsRaw = std::array<std::string, NativeButton::NumButtons>;
326using MotionsRaw = std::array<std::string, NativeMotion::NumMotions>; 359using MotionsRaw = std::array<std::string, NativeMotion::NumMotions>;
327using VibrationsRaw = std::array<std::string, NativeVibration::NumVibrations>;
328
329using MouseButtonsRaw = std::array<std::string, NativeMouseButton::NumMouseButtons>;
330using KeyboardKeysRaw = std::array<std::string, NativeKeyboard::NumKeyboardKeys>;
331using KeyboardModsRaw = std::array<std::string, NativeKeyboard::NumKeyboardMods>;
332 360
333constexpr u32 JOYCON_BODY_NEON_RED = 0xFF3C28; 361constexpr u32 JOYCON_BODY_NEON_RED = 0xFF3C28;
334constexpr u32 JOYCON_BUTTONS_NEON_RED = 0x1E0A0A; 362constexpr u32 JOYCON_BUTTONS_NEON_RED = 0x1E0A0A;
@@ -349,7 +377,6 @@ struct PlayerInput {
349 ControllerType controller_type; 377 ControllerType controller_type;
350 ButtonsRaw buttons; 378 ButtonsRaw buttons;
351 AnalogsRaw analogs; 379 AnalogsRaw analogs;
352 VibrationsRaw vibrations;
353 MotionsRaw motions; 380 MotionsRaw motions;
354 381
355 bool vibration_enabled; 382 bool vibration_enabled;