summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/input_common/CMakeLists.txt6
-rw-r--r--src/input_common/input_mapping.cpp171
-rw-r--r--src/input_common/input_mapping.h76
-rw-r--r--src/input_common/input_poller.cpp860
-rw-r--r--src/input_common/input_poller.h189
-rw-r--r--src/input_common/main.h3
6 files changed, 1305 insertions, 0 deletions
diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt
index dd13d948f..72f1e0f4a 100644
--- a/src/input_common/CMakeLists.txt
+++ b/src/input_common/CMakeLists.txt
@@ -3,6 +3,12 @@ add_library(input_common STATIC
3 analog_from_button.h 3 analog_from_button.h
4 keyboard.cpp 4 keyboard.cpp
5 keyboard.h 5 keyboard.h
6 input_engine.cpp
7 input_engine.h
8 input_mapping.cpp
9 input_mapping.h
10 input_poller.cpp
11 input_poller.h
6 main.cpp 12 main.cpp
7 main.h 13 main.h
8 motion_from_button.cpp 14 motion_from_button.cpp
diff --git a/src/input_common/input_mapping.cpp b/src/input_common/input_mapping.cpp
new file mode 100644
index 000000000..0ffc71028
--- /dev/null
+++ b/src/input_common/input_mapping.cpp
@@ -0,0 +1,171 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included
4
5#include "common/common_types.h"
6#include "input_common/input_engine.h"
7#include "input_common/input_mapping.h"
8
9namespace InputCommon {
10
11MappingFactory::MappingFactory() {}
12
13void MappingFactory::BeginMapping(Polling::InputType type) {
14 is_enabled = true;
15 input_type = type;
16 input_queue.Clear();
17 first_axis = -1;
18 second_axis = -1;
19}
20
21[[nodiscard]] const Common::ParamPackage MappingFactory::GetNextInput() {
22 Common::ParamPackage input;
23 input_queue.Pop(input);
24 return input;
25}
26
27void MappingFactory::RegisterInput(const MappingData& data) {
28 if (!is_enabled) {
29 return;
30 }
31 switch (input_type) {
32 case Polling::InputType::Button:
33 RegisterButton(data);
34 return;
35 case Polling::InputType::Stick:
36 RegisterStick(data);
37 return;
38 case Polling::InputType::Motion:
39 RegisterMotion(data);
40 return;
41 default:
42 return;
43 }
44}
45
46void MappingFactory::StopMapping() {
47 is_enabled = false;
48 input_type = Polling::InputType::None;
49 input_queue.Clear();
50}
51
52void MappingFactory::RegisterButton(const MappingData& data) {
53 Common::ParamPackage new_input;
54 new_input.Set("engine", data.engine);
55 if (data.pad.guid != Common::UUID{}) {
56 new_input.Set("guid", data.pad.guid.Format());
57 }
58 new_input.Set("port", static_cast<int>(data.pad.port));
59 new_input.Set("pad", static_cast<int>(data.pad.pad));
60 switch (data.type) {
61 case EngineInputType::Button:
62 // Workaround for old compatibility
63 if (data.engine == "keyboard") {
64 new_input.Set("code", data.index);
65 break;
66 }
67 new_input.Set("button", data.index);
68 break;
69 case EngineInputType::HatButton:
70 new_input.Set("hat", data.index);
71 new_input.Set("direction", data.hat_name);
72 break;
73 case EngineInputType::Analog:
74 new_input.Set("axis", data.index);
75 new_input.Set("threshold", 0.5f);
76 break;
77 default:
78 return;
79 }
80 input_queue.Push(new_input);
81}
82
83void MappingFactory::RegisterStick(const MappingData& data) {
84 Common::ParamPackage new_input;
85 new_input.Set("engine", data.engine);
86 if (data.pad.guid != Common::UUID{}) {
87 new_input.Set("guid", data.pad.guid.Format());
88 }
89 new_input.Set("port", static_cast<int>(data.pad.port));
90 new_input.Set("pad", static_cast<int>(data.pad.pad));
91
92 // If engine is mouse map the mouse position as a joystick
93 if (data.engine == "mouse") {
94 new_input.Set("axis_x", 0);
95 new_input.Set("axis_y", 1);
96 new_input.Set("threshold", 0.5f);
97 new_input.Set("range", 1.0f);
98 new_input.Set("deadzone", 0.0f);
99 input_queue.Push(new_input);
100 return;
101 }
102
103 switch (data.type) {
104 case EngineInputType::Button:
105 case EngineInputType::HatButton:
106 RegisterButton(data);
107 return;
108 case EngineInputType::Analog:
109 if (first_axis == data.index) {
110 return;
111 }
112 if (first_axis == -1) {
113 first_axis = data.index;
114 return;
115 }
116 new_input.Set("axis_x", first_axis);
117 new_input.Set("axis_y", data.index);
118 new_input.Set("threshold", 0.5f);
119 new_input.Set("range", 0.95f);
120 new_input.Set("deadzone", 0.15f);
121 break;
122 default:
123 return;
124 }
125 input_queue.Push(new_input);
126}
127
128void MappingFactory::RegisterMotion(const MappingData& data) {
129 Common::ParamPackage new_input;
130 new_input.Set("engine", data.engine);
131 if (data.pad.guid != Common::UUID{}) {
132 new_input.Set("guid", data.pad.guid.Format());
133 }
134 new_input.Set("port", static_cast<int>(data.pad.port));
135 new_input.Set("pad", static_cast<int>(data.pad.pad));
136 switch (data.type) {
137 case EngineInputType::Button:
138 case EngineInputType::HatButton:
139 RegisterButton(data);
140 return;
141 case EngineInputType::Analog:
142 if (first_axis == data.index) {
143 return;
144 }
145 if (second_axis == data.index) {
146 return;
147 }
148 if (first_axis == -1) {
149 first_axis = data.index;
150 return;
151 }
152 if (second_axis == -1) {
153 second_axis = data.index;
154 return;
155 }
156 new_input.Set("axis_x", first_axis);
157 new_input.Set("axis_y", second_axis);
158 new_input.Set("axis_z", data.index);
159 new_input.Set("range", 1.0f);
160 new_input.Set("deadzone", 0.20f);
161 break;
162 case EngineInputType::Motion:
163 new_input.Set("motion", data.index);
164 break;
165 default:
166 return;
167 }
168 input_queue.Push(new_input);
169}
170
171} // namespace InputCommon
diff --git a/src/input_common/input_mapping.h b/src/input_common/input_mapping.h
new file mode 100644
index 000000000..2622dba70
--- /dev/null
+++ b/src/input_common/input_mapping.h
@@ -0,0 +1,76 @@
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#include "common/threadsafe_queue.h"
7
8namespace InputCommon {
9class InputEngine;
10struct MappingData;
11
12class MappingFactory {
13public:
14 MappingFactory();
15
16 /**
17 * Resets all varables to beggin the mapping process
18 * @param "type": type of input desired to be returned
19 */
20 void BeginMapping(Polling::InputType type);
21
22 /// Returns an input event with mapping information from the input_queue
23 [[nodiscard]] const Common::ParamPackage GetNextInput();
24
25 /**
26 * Registers mapping input data from the driver
27 * @param "data": An struct containing all the information needed to create a proper
28 * ParamPackage
29 */
30 void RegisterInput(const MappingData& data);
31
32 /// Stop polling from all backends
33 void StopMapping();
34
35private:
36 /**
37 * If provided data satisfies the requeriments it will push an element to the input_queue
38 * Supported input:
39 * - Button: Creates a basic button ParamPackage
40 * - HatButton: Creates a basic hat button ParamPackage
41 * - Analog: Creates a basic analog ParamPackage
42 * @param "data": An struct containing all the information needed to create a proper
43 * ParamPackage
44 */
45 void RegisterButton(const MappingData& data);
46
47 /**
48 * If provided data satisfies the requeriments it will push an element to the input_queue
49 * Supported input:
50 * - Button, HatButton: Pass the data to RegisterButton
51 * - Analog: Stores the first axis and on the second axis creates a basic stick ParamPackage
52 * @param "data": An struct containing all the information needed to create a proper
53 * ParamPackage
54 */
55 void RegisterStick(const MappingData& data);
56
57 /**
58 * If provided data satisfies the requeriments it will push an element to the input_queue
59 * Supported input:
60 * - Button, HatButton: Pass the data to RegisterButton
61 * - Analog: Stores the first two axis and on the third axis creates a basic Motion
62 * ParamPackage
63 * - Motion: Creates a basic Motion ParamPackage
64 * @param "data": An struct containing all the information needed to create a proper
65 * ParamPackage
66 */
67 void RegisterMotion(const MappingData& data);
68
69 Common::SPSCQueue<Common::ParamPackage> input_queue;
70 Polling::InputType input_type{Polling::InputType::None};
71 bool is_enabled{};
72 int first_axis = -1;
73 int second_axis = -1;
74};
75
76} // namespace InputCommon
diff --git a/src/input_common/input_poller.cpp b/src/input_common/input_poller.cpp
new file mode 100644
index 000000000..46a7dd276
--- /dev/null
+++ b/src/input_common/input_poller.cpp
@@ -0,0 +1,860 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included
4
5#include "common/common_types.h"
6#include "common/input.h"
7
8#include "input_common/input_engine.h"
9#include "input_common/input_poller.h"
10
11namespace InputCommon {
12
13class DummyInput final : public Input::InputDevice {
14public:
15 explicit DummyInput() {}
16 ~DummyInput() {}
17};
18
19class InputFromButton final : public Input::InputDevice {
20public:
21 explicit InputFromButton(PadIdentifier identifier_, u32 button_, bool toggle_, bool inverted_,
22 InputEngine* input_engine_)
23 : identifier(identifier_), button(button_), toggle(toggle_), inverted(inverted_),
24 input_engine(input_engine_) {
25 UpdateCallback engine_callback{[this]() { OnChange(); }};
26 const InputIdentifier input_identifier{
27 .identifier = identifier,
28 .type = EngineInputType::Button,
29 .index = button,
30 .callback = engine_callback,
31 };
32 last_button_value = false;
33 callback_key = input_engine->SetCallback(input_identifier);
34 }
35
36 ~InputFromButton() {
37 input_engine->DeleteCallback(callback_key);
38 }
39
40 Input::ButtonStatus GetStatus() const {
41 return {
42 .value = input_engine->GetButton(identifier, button),
43 .inverted = inverted,
44 .toggle = toggle,
45 };
46 }
47
48 void OnChange() {
49 const Input::CallbackStatus status{
50 .type = Input::InputType::Button,
51 .button_status = GetStatus(),
52 };
53
54 if (status.button_status.value != last_button_value) {
55 last_button_value = status.button_status.value;
56 TriggerOnChange(status);
57 }
58 }
59
60private:
61 const PadIdentifier identifier;
62 const u32 button;
63 const bool toggle;
64 const bool inverted;
65 int callback_key;
66 bool last_button_value;
67 InputEngine* input_engine;
68};
69
70class InputFromHatButton final : public Input::InputDevice {
71public:
72 explicit InputFromHatButton(PadIdentifier identifier_, u32 button_, u8 direction_, bool toggle_,
73 bool inverted_, InputEngine* input_engine_)
74 : identifier(identifier_), button(button_), direction(direction_), toggle(toggle_),
75 inverted(inverted_), input_engine(input_engine_) {
76 UpdateCallback engine_callback{[this]() { OnChange(); }};
77 const InputIdentifier input_identifier{
78 .identifier = identifier,
79 .type = EngineInputType::HatButton,
80 .index = button,
81 .callback = engine_callback,
82 };
83 last_button_value = false;
84 callback_key = input_engine->SetCallback(input_identifier);
85 }
86
87 ~InputFromHatButton() {
88 input_engine->DeleteCallback(callback_key);
89 }
90
91 Input::ButtonStatus GetStatus() const {
92 return {
93 .value = input_engine->GetHatButton(identifier, button, direction),
94 .inverted = inverted,
95 .toggle = toggle,
96 };
97 }
98
99 void OnChange() {
100 const Input::CallbackStatus status{
101 .type = Input::InputType::Button,
102 .button_status = GetStatus(),
103 };
104
105 if (status.button_status.value != last_button_value) {
106 last_button_value = status.button_status.value;
107 TriggerOnChange(status);
108 }
109 }
110
111private:
112 const PadIdentifier identifier;
113 const u32 button;
114 const u8 direction;
115 const bool toggle;
116 const bool inverted;
117 int callback_key;
118 bool last_button_value;
119 InputEngine* input_engine;
120};
121
122class InputFromStick final : public Input::InputDevice {
123public:
124 explicit InputFromStick(PadIdentifier identifier_, u32 axis_x_, u32 axis_y_,
125 Input::AnalogProperties properties_x_,
126 Input::AnalogProperties properties_y_, InputEngine* input_engine_)
127 : identifier(identifier_), axis_x(axis_x_), axis_y(axis_y_), properties_x(properties_x_),
128 properties_y(properties_y_), input_engine(input_engine_) {
129 UpdateCallback engine_callback{[this]() { OnChange(); }};
130 const InputIdentifier x_input_identifier{
131 .identifier = identifier,
132 .type = EngineInputType::Analog,
133 .index = axis_x,
134 .callback = engine_callback,
135 };
136 const InputIdentifier y_input_identifier{
137 .identifier = identifier,
138 .type = EngineInputType::Analog,
139 .index = axis_y,
140 .callback = engine_callback,
141 };
142 last_axis_x_value = 0.0f;
143 last_axis_y_value = 0.0f;
144 callback_key_x = input_engine->SetCallback(x_input_identifier);
145 callback_key_y = input_engine->SetCallback(y_input_identifier);
146 }
147
148 ~InputFromStick() {
149 input_engine->DeleteCallback(callback_key_x);
150 input_engine->DeleteCallback(callback_key_y);
151 }
152
153 Input::StickStatus GetStatus() const {
154 Input::StickStatus status;
155 status.x = {
156 .raw_value = input_engine->GetAxis(identifier, axis_x),
157 .properties = properties_x,
158 };
159 status.y = {
160 .raw_value = input_engine->GetAxis(identifier, axis_y),
161 .properties = properties_y,
162 };
163 return status;
164 }
165
166 void OnChange() {
167 const Input::CallbackStatus status{
168 .type = Input::InputType::Stick,
169 .stick_status = GetStatus(),
170 };
171
172 if (status.stick_status.x.raw_value != last_axis_x_value ||
173 status.stick_status.y.raw_value != last_axis_y_value) {
174 last_axis_x_value = status.stick_status.x.raw_value;
175 last_axis_y_value = status.stick_status.y.raw_value;
176 TriggerOnChange(status);
177 }
178 }
179
180private:
181 const PadIdentifier identifier;
182 const u32 axis_x;
183 const u32 axis_y;
184 const Input::AnalogProperties properties_x;
185 const Input::AnalogProperties properties_y;
186 int callback_key_x;
187 int callback_key_y;
188 float last_axis_x_value;
189 float last_axis_y_value;
190 InputEngine* input_engine;
191};
192
193class InputFromTouch final : public Input::InputDevice {
194public:
195 explicit InputFromTouch(PadIdentifier identifier_, u32 touch_id_, u32 button_, bool toggle_,
196 bool inverted_, u32 axis_x_, u32 axis_y_,
197 Input::AnalogProperties properties_x_,
198 Input::AnalogProperties properties_y_, InputEngine* input_engine_)
199 : identifier(identifier_), touch_id(touch_id_), button(button_), toggle(toggle_),
200 inverted(inverted_), axis_x(axis_x_), axis_y(axis_y_), properties_x(properties_x_),
201 properties_y(properties_y_), input_engine(input_engine_) {
202 UpdateCallback engine_callback{[this]() { OnChange(); }};
203 const InputIdentifier button_input_identifier{
204 .identifier = identifier,
205 .type = EngineInputType::Button,
206 .index = button,
207 .callback = engine_callback,
208 };
209 const InputIdentifier x_input_identifier{
210 .identifier = identifier,
211 .type = EngineInputType::Analog,
212 .index = axis_x,
213 .callback = engine_callback,
214 };
215 const InputIdentifier y_input_identifier{
216 .identifier = identifier,
217 .type = EngineInputType::Analog,
218 .index = axis_y,
219 .callback = engine_callback,
220 };
221 last_axis_x_value = 0.0f;
222 last_axis_y_value = 0.0f;
223 last_button_value = false;
224 callback_key_button = input_engine->SetCallback(button_input_identifier);
225 callback_key_x = input_engine->SetCallback(x_input_identifier);
226 callback_key_y = input_engine->SetCallback(y_input_identifier);
227 }
228
229 ~InputFromTouch() {
230 input_engine->DeleteCallback(callback_key_button);
231 input_engine->DeleteCallback(callback_key_x);
232 input_engine->DeleteCallback(callback_key_y);
233 }
234
235 Input::TouchStatus GetStatus() const {
236 Input::TouchStatus status;
237 status.id = touch_id;
238 status.pressed = {
239 .value = input_engine->GetButton(identifier, button),
240 .inverted = inverted,
241 .toggle = toggle,
242 };
243 status.x = {
244 .raw_value = input_engine->GetAxis(identifier, axis_x),
245 .properties = properties_x,
246 };
247 status.y = {
248 .raw_value = input_engine->GetAxis(identifier, axis_y),
249 .properties = properties_y,
250 };
251 return status;
252 }
253
254 void OnChange() {
255 const Input::CallbackStatus status{
256 .type = Input::InputType::Touch,
257 .touch_status = GetStatus(),
258 };
259
260 if (status.touch_status.x.raw_value != last_axis_x_value ||
261 status.touch_status.y.raw_value != last_axis_y_value ||
262 status.touch_status.pressed.value != last_button_value) {
263 last_axis_x_value = status.touch_status.x.raw_value;
264 last_axis_y_value = status.touch_status.y.raw_value;
265 last_button_value = status.touch_status.pressed.value;
266 TriggerOnChange(status);
267 }
268 }
269
270private:
271 const PadIdentifier identifier;
272 const u32 touch_id;
273 const u32 button;
274 const bool toggle;
275 const bool inverted;
276 const u32 axis_x;
277 const u32 axis_y;
278 const Input::AnalogProperties properties_x;
279 const Input::AnalogProperties properties_y;
280 int callback_key_button;
281 int callback_key_x;
282 int callback_key_y;
283 bool last_button_value;
284 float last_axis_x_value;
285 float last_axis_y_value;
286 InputEngine* input_engine;
287};
288
289class InputFromTrigger final : public Input::InputDevice {
290public:
291 explicit InputFromTrigger(PadIdentifier identifier_, u32 button_, bool toggle_, bool inverted_,
292 u32 axis_, Input::AnalogProperties properties_,
293 InputEngine* input_engine_)
294 : identifier(identifier_), button(button_), toggle(toggle_), inverted(inverted_),
295 axis(axis_), properties(properties_), input_engine(input_engine_) {
296 UpdateCallback engine_callback{[this]() { OnChange(); }};
297 const InputIdentifier button_input_identifier{
298 .identifier = identifier,
299 .type = EngineInputType::Button,
300 .index = button,
301 .callback = engine_callback,
302 };
303 const InputIdentifier axis_input_identifier{
304 .identifier = identifier,
305 .type = EngineInputType::Analog,
306 .index = axis,
307 .callback = engine_callback,
308 };
309 last_axis_value = 0.0f;
310 last_button_value = false;
311 callback_key_button = input_engine->SetCallback(button_input_identifier);
312 axis_callback_key = input_engine->SetCallback(axis_input_identifier);
313 }
314
315 ~InputFromTrigger() {
316 input_engine->DeleteCallback(callback_key_button);
317 input_engine->DeleteCallback(axis_callback_key);
318 }
319
320 Input::TriggerStatus GetStatus() const {
321 const Input::AnalogStatus analog_status{
322 .raw_value = input_engine->GetAxis(identifier, axis),
323 .properties = properties,
324 };
325 return {
326 .analog = analog_status,
327 .pressed = input_engine->GetButton(identifier, button),
328 };
329 }
330
331 void OnChange() {
332 const Input::CallbackStatus status{
333 .type = Input::InputType::Trigger,
334 .trigger_status = GetStatus(),
335 };
336
337 if (status.trigger_status.analog.raw_value != last_axis_value ||
338 status.trigger_status.pressed != last_button_value) {
339 last_axis_value = status.trigger_status.analog.raw_value;
340 last_button_value = status.trigger_status.pressed;
341 TriggerOnChange(status);
342 }
343 }
344
345private:
346 const PadIdentifier identifier;
347 const u32 button;
348 const bool toggle;
349 const bool inverted;
350 const u32 axis;
351 const Input::AnalogProperties properties;
352 int callback_key_button;
353 int axis_callback_key;
354 bool last_button_value;
355 float last_axis_value;
356 InputEngine* input_engine;
357};
358
359class InputFromAnalog final : public Input::InputDevice {
360public:
361 explicit InputFromAnalog(PadIdentifier identifier_, u32 axis_,
362 Input::AnalogProperties properties_, InputEngine* input_engine_)
363 : identifier(identifier_), axis(axis_), properties(properties_),
364 input_engine(input_engine_) {
365 UpdateCallback engine_callback{[this]() { OnChange(); }};
366 const InputIdentifier input_identifier{
367 .identifier = identifier,
368 .type = EngineInputType::Analog,
369 .index = axis,
370 .callback = engine_callback,
371 };
372 last_axis_value = 0.0f;
373 callback_key = input_engine->SetCallback(input_identifier);
374 }
375
376 ~InputFromAnalog() {
377 input_engine->DeleteCallback(callback_key);
378 }
379
380 Input::AnalogStatus GetStatus() const {
381 return {
382 .raw_value = input_engine->GetAxis(identifier, axis),
383 .properties = properties,
384 };
385 }
386
387 void OnChange() {
388 const Input::CallbackStatus status{
389 .type = Input::InputType::Analog,
390 .analog_status = GetStatus(),
391 };
392
393 if (status.analog_status.raw_value != last_axis_value) {
394 last_axis_value = status.analog_status.raw_value;
395 TriggerOnChange(status);
396 }
397 }
398
399private:
400 const PadIdentifier identifier;
401 const u32 axis;
402 const Input::AnalogProperties properties;
403 int callback_key;
404 float last_axis_value;
405 InputEngine* input_engine;
406};
407
408class InputFromBattery final : public Input::InputDevice {
409public:
410 explicit InputFromBattery(PadIdentifier identifier_, InputEngine* input_engine_)
411 : identifier(identifier_), input_engine(input_engine_) {
412 UpdateCallback engine_callback{[this]() { OnChange(); }};
413 const InputIdentifier input_identifier{
414 .identifier = identifier,
415 .type = EngineInputType::Battery,
416 .index = 0,
417 .callback = engine_callback,
418 };
419 last_battery_value = Input::BatteryStatus::Charging;
420 callback_key = input_engine->SetCallback(input_identifier);
421 }
422
423 ~InputFromBattery() {
424 input_engine->DeleteCallback(callback_key);
425 }
426
427 Input::BatteryStatus GetStatus() const {
428 return static_cast<Input::BatteryLevel>(input_engine->GetBattery(identifier));
429 }
430
431 void OnChange() {
432 const Input::CallbackStatus status{
433 .type = Input::InputType::Battery,
434 .battery_status = GetStatus(),
435 };
436
437 if (status.battery_status != last_battery_value) {
438 last_battery_value = status.battery_status;
439 TriggerOnChange(status);
440 }
441 }
442
443private:
444 const PadIdentifier identifier;
445 int callback_key;
446 Input::BatteryStatus last_battery_value;
447 InputEngine* input_engine;
448};
449
450class InputFromMotion final : public Input::InputDevice {
451public:
452 explicit InputFromMotion(PadIdentifier identifier_, u32 motion_sensor_,
453 InputEngine* input_engine_)
454 : identifier(identifier_), motion_sensor(motion_sensor_), input_engine(input_engine_) {
455 UpdateCallback engine_callback{[this]() { OnChange(); }};
456 const InputIdentifier input_identifier{
457 .identifier = identifier,
458 .type = EngineInputType::Motion,
459 .index = motion_sensor,
460 .callback = engine_callback,
461 };
462 callback_key = input_engine->SetCallback(input_identifier);
463 }
464
465 ~InputFromMotion() {
466 input_engine->DeleteCallback(callback_key);
467 }
468
469 Input::MotionStatus GetStatus() const {
470 const auto basic_motion = input_engine->GetMotion(identifier, motion_sensor);
471 Input::MotionStatus status{};
472 const Input::AnalogProperties properties = {
473 .deadzone = 0.001f,
474 .range = 1.0f,
475 .offset = 0.0f,
476 };
477 status.accel.x = {.raw_value = basic_motion.accel_x, .properties = properties};
478 status.accel.y = {.raw_value = basic_motion.accel_y, .properties = properties};
479 status.accel.z = {.raw_value = basic_motion.accel_z, .properties = properties};
480 status.gyro.x = {.raw_value = basic_motion.gyro_x, .properties = properties};
481 status.gyro.y = {.raw_value = basic_motion.gyro_y, .properties = properties};
482 status.gyro.z = {.raw_value = basic_motion.gyro_z, .properties = properties};
483 status.delta_timestamp = basic_motion.delta_timestamp;
484 return status;
485 }
486
487 void OnChange() {
488 const Input::CallbackStatus status{
489 .type = Input::InputType::Motion,
490 .motion_status = GetStatus(),
491 };
492
493 TriggerOnChange(status);
494 }
495
496private:
497 const PadIdentifier identifier;
498 const u32 motion_sensor;
499 int callback_key;
500 InputEngine* input_engine;
501};
502
503class InputFromAxisMotion final : public Input::InputDevice {
504public:
505 explicit InputFromAxisMotion(PadIdentifier identifier_, u32 axis_x_, u32 axis_y_, u32 axis_z_,
506 Input::AnalogProperties properties_x_,
507 Input::AnalogProperties properties_y_,
508 Input::AnalogProperties properties_z_, InputEngine* input_engine_)
509 : identifier(identifier_), axis_x(axis_x_), axis_y(axis_y_), axis_z(axis_z_),
510 properties_x(properties_x_), properties_y(properties_y_), properties_z(properties_z_),
511 input_engine(input_engine_) {
512 UpdateCallback engine_callback{[this]() { OnChange(); }};
513 const InputIdentifier x_input_identifier{
514 .identifier = identifier,
515 .type = EngineInputType::Analog,
516 .index = axis_x,
517 .callback = engine_callback,
518 };
519 const InputIdentifier y_input_identifier{
520 .identifier = identifier,
521 .type = EngineInputType::Analog,
522 .index = axis_y,
523 .callback = engine_callback,
524 };
525 const InputIdentifier z_input_identifier{
526 .identifier = identifier,
527 .type = EngineInputType::Analog,
528 .index = axis_z,
529 .callback = engine_callback,
530 };
531 last_axis_x_value = 0.0f;
532 last_axis_y_value = 0.0f;
533 last_axis_z_value = 0.0f;
534 callback_key_x = input_engine->SetCallback(x_input_identifier);
535 callback_key_y = input_engine->SetCallback(y_input_identifier);
536 callback_key_z = input_engine->SetCallback(z_input_identifier);
537 }
538
539 ~InputFromAxisMotion() {
540 input_engine->DeleteCallback(callback_key_x);
541 input_engine->DeleteCallback(callback_key_y);
542 input_engine->DeleteCallback(callback_key_z);
543 }
544
545 Input::MotionStatus GetStatus() const {
546 Input::MotionStatus status{};
547 status.gyro.x = {
548 .raw_value = input_engine->GetAxis(identifier, axis_x),
549 .properties = properties_x,
550 };
551 status.gyro.y = {
552 .raw_value = input_engine->GetAxis(identifier, axis_y),
553 .properties = properties_y,
554 };
555 status.gyro.z = {
556 .raw_value = input_engine->GetAxis(identifier, axis_z),
557 .properties = properties_z,
558 };
559 return status;
560 }
561
562 void OnChange() {
563 const Input::CallbackStatus status{
564 .type = Input::InputType::Motion,
565 .motion_status = GetStatus(),
566 };
567
568 if (status.motion_status.gyro.x.raw_value != last_axis_x_value ||
569 status.motion_status.gyro.y.raw_value != last_axis_y_value ||
570 status.motion_status.gyro.z.raw_value != last_axis_z_value) {
571 last_axis_x_value = status.motion_status.gyro.x.raw_value;
572 last_axis_y_value = status.motion_status.gyro.y.raw_value;
573 last_axis_z_value = status.motion_status.gyro.z.raw_value;
574 TriggerOnChange(status);
575 }
576 }
577
578private:
579 const PadIdentifier identifier;
580 const u32 axis_x;
581 const u32 axis_y;
582 const u32 axis_z;
583 const Input::AnalogProperties properties_x;
584 const Input::AnalogProperties properties_y;
585 const Input::AnalogProperties properties_z;
586 int callback_key_x;
587 int callback_key_y;
588 int callback_key_z;
589 float last_axis_x_value;
590 float last_axis_y_value;
591 float last_axis_z_value;
592 InputEngine* input_engine;
593};
594
595std::unique_ptr<Input::InputDevice> InputFactory::CreateButtonDevice(
596 const Common::ParamPackage& params) {
597 const PadIdentifier identifier = {
598 .guid = Common::UUID{params.Get("guid", "")},
599 .port = static_cast<std::size_t>(params.Get("port", 0)),
600 .pad = static_cast<std::size_t>(params.Get("pad", 0)),
601 };
602
603 const auto button_id = static_cast<u32>(params.Get("button", 0));
604 const auto keyboard_key = static_cast<u32>(params.Get("code", 0));
605 const auto toggle = params.Get("toggle", false);
606 const auto inverted = params.Get("inverted", false);
607 input_engine->PreSetController(identifier);
608 input_engine->PreSetButton(identifier, button_id);
609 input_engine->PreSetButton(identifier, keyboard_key);
610 if (keyboard_key != 0) {
611 return std::make_unique<InputFromButton>(identifier, keyboard_key, toggle, inverted,
612 input_engine.get());
613 }
614 return std::make_unique<InputFromButton>(identifier, button_id, toggle, inverted,
615 input_engine.get());
616}
617
618std::unique_ptr<Input::InputDevice> InputFactory::CreateHatButtonDevice(
619 const Common::ParamPackage& params) {
620 const PadIdentifier identifier = {
621 .guid = Common::UUID{params.Get("guid", "")},
622 .port = static_cast<std::size_t>(params.Get("port", 0)),
623 .pad = static_cast<std::size_t>(params.Get("pad", 0)),
624 };
625
626 const auto button_id = static_cast<u32>(params.Get("hat", 0));
627 const auto direction = input_engine->GetHatButtonId(params.Get("direction", ""));
628 const auto toggle = params.Get("toggle", false);
629 const auto inverted = params.Get("inverted", false);
630
631 input_engine->PreSetController(identifier);
632 input_engine->PreSetHatButton(identifier, button_id);
633 return std::make_unique<InputFromHatButton>(identifier, button_id, direction, toggle, inverted,
634 input_engine.get());
635}
636
637std::unique_ptr<Input::InputDevice> InputFactory::CreateStickDevice(
638 const Common::ParamPackage& params) {
639 const auto deadzone = std::clamp(params.Get("deadzone", 0.15f), 0.0f, 1.0f);
640 const auto range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f);
641 const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
642 const PadIdentifier identifier = {
643 .guid = Common::UUID{params.Get("guid", "")},
644 .port = static_cast<std::size_t>(params.Get("port", 0)),
645 .pad = static_cast<std::size_t>(params.Get("pad", 0)),
646 };
647
648 const auto axis_x = static_cast<u32>(params.Get("axis_x", 0));
649 const Input::AnalogProperties properties_x = {
650 .deadzone = deadzone,
651 .range = range,
652 .threshold = threshold,
653 .offset = std::clamp(params.Get("offset_x", 0.0f), -1.0f, 1.0f),
654 .inverted = params.Get("invert_x", "+") == "-",
655 };
656
657 const auto axis_y = static_cast<u32>(params.Get("axis_y", 1));
658 const Input::AnalogProperties properties_y = {
659 .deadzone = deadzone,
660 .range = range,
661 .threshold = threshold,
662 .offset = std::clamp(params.Get("offset_y", 0.0f), -1.0f, 1.0f),
663 .inverted = params.Get("invert_y", "+") != "+",
664 };
665 input_engine->PreSetController(identifier);
666 input_engine->PreSetAxis(identifier, axis_x);
667 input_engine->PreSetAxis(identifier, axis_y);
668 return std::make_unique<InputFromStick>(identifier, axis_x, axis_y, properties_x, properties_y,
669 input_engine.get());
670}
671
672std::unique_ptr<Input::InputDevice> InputFactory::CreateAnalogDevice(
673 const Common::ParamPackage& params) {
674 const PadIdentifier identifier = {
675 .guid = Common::UUID{params.Get("guid", "")},
676 .port = static_cast<std::size_t>(params.Get("port", 0)),
677 .pad = static_cast<std::size_t>(params.Get("pad", 0)),
678 };
679
680 const auto axis = static_cast<u32>(params.Get("axis", 0));
681 const Input::AnalogProperties properties = {
682 .deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f),
683 .range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f),
684 .threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f),
685 .offset = std::clamp(params.Get("offset", 0.0f), -1.0f, 1.0f),
686 .inverted = params.Get("invert", "+") == "-",
687 };
688 input_engine->PreSetController(identifier);
689 input_engine->PreSetAxis(identifier, axis);
690 return std::make_unique<InputFromAnalog>(identifier, axis, properties, input_engine.get());
691}
692
693std::unique_ptr<Input::InputDevice> InputFactory::CreateTriggerDevice(
694 const Common::ParamPackage& params) {
695 const PadIdentifier identifier = {
696 .guid = Common::UUID{params.Get("guid", "")},
697 .port = static_cast<std::size_t>(params.Get("port", 0)),
698 .pad = static_cast<std::size_t>(params.Get("pad", 0)),
699 };
700
701 const auto button = static_cast<u32>(params.Get("button", 0));
702 const auto toggle = params.Get("toggle", false);
703 const auto inverted = params.Get("inverted", false);
704
705 const auto axis = static_cast<u32>(params.Get("axis", 0));
706 const Input::AnalogProperties properties = {
707 .deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f),
708 .range = std::clamp(params.Get("range", 1.0f), 0.25f, 2.50f),
709 .threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f),
710 .offset = std::clamp(params.Get("offset", 0.0f), -1.0f, 1.0f),
711 .inverted = params.Get("invert", false) != 0,
712 };
713 input_engine->PreSetController(identifier);
714 input_engine->PreSetAxis(identifier, axis);
715 input_engine->PreSetButton(identifier, button);
716 return std::make_unique<InputFromTrigger>(identifier, button, toggle, inverted, axis,
717 properties, input_engine.get());
718}
719
720std::unique_ptr<Input::InputDevice> InputFactory::CreateTouchDevice(
721 const Common::ParamPackage& params) {
722 const auto touch_id = params.Get("touch_id", 0);
723 const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
724 const auto range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f);
725 const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
726 const PadIdentifier identifier = {
727 .guid = Common::UUID{params.Get("guid", "")},
728 .port = static_cast<std::size_t>(params.Get("port", 0)),
729 .pad = static_cast<std::size_t>(params.Get("pad", 0)),
730 };
731
732 const auto button = static_cast<u32>(params.Get("button", 0));
733 const auto toggle = params.Get("toggle", false);
734 const auto inverted = params.Get("inverted", false);
735
736 const auto axis_x = static_cast<u32>(params.Get("axis_x", 0));
737 const Input::AnalogProperties properties_x = {
738 .deadzone = deadzone,
739 .range = range,
740 .threshold = threshold,
741 .offset = std::clamp(params.Get("offset_x", 0.0f), -1.0f, 1.0f),
742 .inverted = params.Get("invert_x", "+") == "-",
743 };
744
745 const auto axis_y = static_cast<u32>(params.Get("axis_y", 1));
746 const Input::AnalogProperties properties_y = {
747 .deadzone = deadzone,
748 .range = range,
749 .threshold = threshold,
750 .offset = std::clamp(params.Get("offset_y", 0.0f), -1.0f, 1.0f),
751 .inverted = params.Get("invert_y", false) != 0,
752 };
753 input_engine->PreSetController(identifier);
754 input_engine->PreSetAxis(identifier, axis_x);
755 input_engine->PreSetAxis(identifier, axis_y);
756 input_engine->PreSetButton(identifier, button);
757 return std::make_unique<InputFromTouch>(identifier, touch_id, button, toggle, inverted, axis_x,
758 axis_y, properties_x, properties_y, input_engine.get());
759}
760
761std::unique_ptr<Input::InputDevice> InputFactory::CreateBatteryDevice(
762 const Common::ParamPackage& params) {
763 const PadIdentifier identifier = {
764 .guid = Common::UUID{params.Get("guid", "")},
765 .port = static_cast<std::size_t>(params.Get("port", 0)),
766 .pad = static_cast<std::size_t>(params.Get("pad", 0)),
767 };
768
769 input_engine->PreSetController(identifier);
770 return std::make_unique<InputFromBattery>(identifier, input_engine.get());
771}
772
773std::unique_ptr<Input::InputDevice> InputFactory::CreateMotionDevice(Common::ParamPackage params) {
774 const PadIdentifier identifier = {
775 .guid = Common::UUID{params.Get("guid", "")},
776 .port = static_cast<std::size_t>(params.Get("port", 0)),
777 .pad = static_cast<std::size_t>(params.Get("pad", 0)),
778 };
779
780 if (params.Has("motion")) {
781 const auto motion_sensor = params.Get("motion", 0);
782 input_engine->PreSetController(identifier);
783 input_engine->PreSetMotion(identifier, motion_sensor);
784 return std::make_unique<InputFromMotion>(identifier, motion_sensor, input_engine.get());
785 }
786
787 const auto deadzone = std::clamp(params.Get("deadzone", 0.15f), 0.0f, 1.0f);
788 const auto range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f);
789 const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
790
791 const auto axis_x = static_cast<u32>(params.Get("axis_x", 0));
792 const Input::AnalogProperties properties_x = {
793 .deadzone = deadzone,
794 .range = range,
795 .threshold = threshold,
796 .offset = std::clamp(params.Get("offset_x", 0.0f), -1.0f, 1.0f),
797 .inverted = params.Get("invert_x", "+") == "-",
798 };
799
800 const auto axis_y = static_cast<u32>(params.Get("axis_y", 1));
801 const Input::AnalogProperties properties_y = {
802 .deadzone = deadzone,
803 .range = range,
804 .threshold = threshold,
805 .offset = std::clamp(params.Get("offset_y", 0.0f), -1.0f, 1.0f),
806 .inverted = params.Get("invert_y", "+") != "+",
807 };
808
809 const auto axis_z = static_cast<u32>(params.Get("axis_z", 1));
810 const Input::AnalogProperties properties_z = {
811 .deadzone = deadzone,
812 .range = range,
813 .threshold = threshold,
814 .offset = std::clamp(params.Get("offset_z", 0.0f), -1.0f, 1.0f),
815 .inverted = params.Get("invert_z", "+") != "+",
816 };
817 input_engine->PreSetController(identifier);
818 input_engine->PreSetAxis(identifier, axis_x);
819 input_engine->PreSetAxis(identifier, axis_y);
820 input_engine->PreSetAxis(identifier, axis_z);
821 return std::make_unique<InputFromAxisMotion>(identifier, axis_x, axis_y, axis_z, properties_x,
822 properties_y, properties_z, input_engine.get());
823}
824
825InputFactory::InputFactory(std::shared_ptr<InputEngine> input_engine_)
826 : input_engine(std::move(input_engine_)) {}
827
828std::unique_ptr<Input::InputDevice> InputFactory::Create(const Common::ParamPackage& params) {
829 if (params.Has("button") && params.Has("axis")) {
830 return CreateTriggerDevice(params);
831 }
832 if (params.Has("button") && params.Has("axis_x") && params.Has("axis_y")) {
833 return CreateTouchDevice(params);
834 }
835 if (params.Has("button") || params.Has("code")) {
836 return CreateButtonDevice(params);
837 }
838 if (params.Has("hat")) {
839 return CreateHatButtonDevice(params);
840 }
841 if (params.Has("axis_x") && params.Has("axis_y") && params.Has("axis_z")) {
842 return CreateMotionDevice(params);
843 }
844 if (params.Has("motion")) {
845 return CreateMotionDevice(params);
846 }
847 if (params.Has("axis_x") && params.Has("axis_y")) {
848 return CreateStickDevice(params);
849 }
850 if (params.Has("axis")) {
851 return CreateAnalogDevice(params);
852 }
853 if (params.Has("battery")) {
854 return CreateBatteryDevice(params);
855 }
856 LOG_ERROR(Input, "Invalid parameters given");
857 return std::make_unique<DummyInput>();
858}
859
860} // namespace InputCommon
diff --git a/src/input_common/input_poller.h b/src/input_common/input_poller.h
new file mode 100644
index 000000000..3c1e5b541
--- /dev/null
+++ b/src/input_common/input_poller.h
@@ -0,0 +1,189 @@
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
7namespace Input {
8class InputDevice;
9
10template <typename InputDevice>
11class Factory;
12}; // namespace Input
13
14namespace InputCommon {
15class InputEngine;
16/**
17 * An Input factory. It receives input events and forward them to all input devices it created.
18 */
19class InputFactory final : public Input::Factory<Input::InputDevice> {
20public:
21 explicit InputFactory(std::shared_ptr<InputEngine> input_engine_);
22
23 /**
24 * Creates a input device from the parameters given. Identifies the type of input to be returned
25 * if it contains the following parameters:
26 * - button: Contains "button" or "code"
27 * - hat_button: Contains "hat"
28 * - analog: Contains "axis"
29 * - trigger: Contains "button" and "axis"
30 * - stick: Contains "axis_x" and "axis_y"
31 * - motion: Contains "axis_x", "axis_y" and "axis_z"
32 * - motion: Contains "motion"
33 * - touch: Contains "button", "axis_x" and "axis_y"
34 * - battery: Contains "battery"
35 * @param params contains parameters for creating the device:
36 * @param - "code": the code of the keyboard key to bind with the input
37 * @param - "button": same as "code" but for controller buttons
38 * @param - "hat": similar as "button" but it's a group of hat buttons from SDL
39 * @param - "axis": the axis number of the axis to bind with the input
40 * @param - "motion": the motion number of the motion to bind with the input
41 * @param - "axis_x": same as axis but specifing horizontal direction
42 * @param - "axis_y": same as axis but specifing vertical direction
43 * @param - "axis_z": same as axis but specifing forward direction
44 * @param - "battery": Only used as a placeholder to set the input type
45 * @return an unique input device with the parameters specified
46 */
47 std::unique_ptr<Input::InputDevice> Create(const Common::ParamPackage& params) override;
48
49private:
50 /**
51 * Creates a button device from the parameters given.
52 * @param params contains parameters for creating the device:
53 * @param - "code": the code of the keyboard key to bind with the input
54 * @param - "button": same as "code" but for controller buttons
55 * @param - "toggle": press once to enable, press again to disable
56 * @param - "inverted": inverts the output of the button
57 * @param - "guid": text string for identifing controllers
58 * @param - "port": port of the connected device
59 * @param - "pad": slot of the connected controller
60 * @return an unique input device with the parameters specified
61 */
62 std::unique_ptr<Input::InputDevice> CreateButtonDevice(const Common::ParamPackage& params);
63
64 /**
65 * Creates a hat button device from the parameters given.
66 * @param params contains parameters for creating the device:
67 * @param - "button": the controller hat id to bind with the input
68 * @param - "direction": the direction id to be detected
69 * @param - "toggle": press once to enable, press again to disable
70 * @param - "inverted": inverts the output of the button
71 * @param - "guid": text string for identifing controllers
72 * @param - "port": port of the connected device
73 * @param - "pad": slot of the connected controller
74 * @return an unique input device with the parameters specified
75 */
76 std::unique_ptr<Input::InputDevice> CreateHatButtonDevice(const Common::ParamPackage& params);
77
78 /**
79 * Creates a stick device from the parameters given.
80 * @param params contains parameters for creating the device:
81 * @param - "axis_x": the controller horizontal axis id to bind with the input
82 * @param - "axis_y": the controller vertical axis id to bind with the input
83 * @param - "deadzone": the mimimum required value to be detected
84 * @param - "range": the maximum value required to reach 100%
85 * @param - "threshold": the mimimum required value to considered pressed
86 * @param - "offset_x": the amount of offset in the x axis
87 * @param - "offset_y": the amount of offset in the y axis
88 * @param - "invert_x": inverts the sign of the horizontal axis
89 * @param - "invert_y": inverts the sign of the vertical axis
90 * @param - "guid": text string for identifing controllers
91 * @param - "port": port of the connected device
92 * @param - "pad": slot of the connected controller
93 * @return an unique input device with the parameters specified
94 */
95 std::unique_ptr<Input::InputDevice> CreateStickDevice(const Common::ParamPackage& params);
96
97 /**
98 * Creates an analog device from the parameters given.
99 * @param params contains parameters for creating the device:
100 * @param - "axis": the controller axis id to bind with the input
101 * @param - "deadzone": the mimimum required value to be detected
102 * @param - "range": the maximum value required to reach 100%
103 * @param - "threshold": the mimimum required value to considered pressed
104 * @param - "offset": the amount of offset in the axis
105 * @param - "invert": inverts the sign of the axis
106 * @param - "guid": text string for identifing controllers
107 * @param - "port": port of the connected device
108 * @param - "pad": slot of the connected controller
109 * @return an unique input device with the parameters specified
110 */
111 std::unique_ptr<Input::InputDevice> CreateAnalogDevice(const Common::ParamPackage& params);
112
113 /**
114 * Creates a trigger device from the parameters given.
115 * @param params contains parameters for creating the device:
116 * @param - "button": the controller hat id to bind with the input
117 * @param - "direction": the direction id to be detected
118 * @param - "toggle": press once to enable, press again to disable
119 * @param - "inverted": inverts the output of the button
120 * @param - "axis": the controller axis id to bind with the input
121 * @param - "deadzone": the mimimum required value to be detected
122 * @param - "range": the maximum value required to reach 100%
123 * @param - "threshold": the mimimum required value to considered pressed
124 * @param - "offset": the amount of offset in the axis
125 * @param - "invert": inverts the sign of the axis
126 * @param - "guid": text string for identifing controllers
127 * @param - "port": port of the connected device
128 * @param - "pad": slot of the connected controller
129 * @return an unique input device with the parameters specified
130 */
131 std::unique_ptr<Input::InputDevice> CreateTriggerDevice(const Common::ParamPackage& params);
132
133 /**
134 * Creates a touch device from the parameters given.
135 * @param params contains parameters for creating the device:
136 * @param - "button": the controller hat id to bind with the input
137 * @param - "direction": the direction id to be detected
138 * @param - "toggle": press once to enable, press again to disable
139 * @param - "inverted": inverts the output of the button
140 * @param - "axis_x": the controller horizontal axis id to bind with the input
141 * @param - "axis_y": the controller vertical axis id to bind with the input
142 * @param - "deadzone": the mimimum required value to be detected
143 * @param - "range": the maximum value required to reach 100%
144 * @param - "threshold": the mimimum required value to considered pressed
145 * @param - "offset_x": the amount of offset in the x axis
146 * @param - "offset_y": the amount of offset in the y axis
147 * @param - "invert_x": inverts the sign of the horizontal axis
148 * @param - "invert_y": inverts the sign of the vertical axis
149 * @param - "guid": text string for identifing controllers
150 * @param - "port": port of the connected device
151 * @param - "pad": slot of the connected controller
152 * @return an unique input device with the parameters specified
153 */
154 std::unique_ptr<Input::InputDevice> CreateTouchDevice(const Common::ParamPackage& params);
155
156 /**
157 * Creates a battery device from the parameters given.
158 * @param params contains parameters for creating the device:
159 * @param - "guid": text string for identifing controllers
160 * @param - "port": port of the connected device
161 * @param - "pad": slot of the connected controller
162 * @return an unique input device with the parameters specified
163 */
164 std::unique_ptr<Input::InputDevice> CreateBatteryDevice(const Common::ParamPackage& params);
165
166 /**
167 * Creates a motion device from the parameters given.
168 * @param params contains parameters for creating the device:
169 * @param - "axis_x": the controller horizontal axis id to bind with the input
170 * @param - "axis_y": the controller vertical axis id to bind with the input
171 * @param - "axis_z": the controller fordward axis id to bind with the input
172 * @param - "deadzone": the mimimum required value to be detected
173 * @param - "range": the maximum value required to reach 100%
174 * @param - "offset_x": the amount of offset in the x axis
175 * @param - "offset_y": the amount of offset in the y axis
176 * @param - "offset_z": the amount of offset in the z axis
177 * @param - "invert_x": inverts the sign of the horizontal axis
178 * @param - "invert_y": inverts the sign of the vertical axis
179 * @param - "invert_z": inverts the sign of the fordward axis
180 * @param - "guid": text string for identifing controllers
181 * @param - "port": port of the connected device
182 * @param - "pad": slot of the connected controller
183 * @return an unique input device with the parameters specified
184 */
185 std::unique_ptr<Input::InputDevice> CreateMotionDevice(Common::ParamPackage params);
186
187 std::shared_ptr<InputEngine> input_engine;
188};
189} // namespace InputCommon
diff --git a/src/input_common/main.h b/src/input_common/main.h
index 6390d3f09..eb247e164 100644
--- a/src/input_common/main.h
+++ b/src/input_common/main.h
@@ -38,6 +38,9 @@ namespace Polling {
38 38
39enum class DeviceType { Button, AnalogPreferred, Motion }; 39enum class DeviceType { Button, AnalogPreferred, Motion };
40 40
41/// Type of input desired for mapping purposes
42enum class InputType { None, Button, Stick, Motion, Touch };
43
41/** 44/**
42 * A class that can be used to get inputs from an input device like controllers without having to 45 * A class that can be used to get inputs from an input device like controllers without having to
43 * poll the device's status yourself 46 * poll the device's status yourself