Etterna 0.74.4
Loading...
Searching...
No Matches
RageInputDevice.h
1/* RageInputDevice - User input types. */
2#ifndef RAGE_INPUT_DEVICE_H
3#define RAGE_INPUT_DEVICE_H
4
5#include "Etterna/Models/Misc/EnumHelper.h"
6#include <chrono>
7#include <utility>
8
9const int NUM_JOYSTICKS = 32;
10const int NUM_PUMPS = 2;
11
12enum InputDevice
13{
14 DEVICE_KEYBOARD = 0,
15 DEVICE_JOY1,
16 DEVICE_JOY2,
17 DEVICE_JOY3,
18 DEVICE_JOY4,
19 DEVICE_JOY5,
20 DEVICE_JOY6,
21 DEVICE_JOY7,
22 DEVICE_JOY8,
23 DEVICE_JOY9,
24 DEVICE_JOY10,
25 DEVICE_JOY11,
26 DEVICE_JOY12,
27 DEVICE_JOY13,
28 DEVICE_JOY14,
29 DEVICE_JOY15,
30 DEVICE_JOY16,
31 DEVICE_JOY17,
32 DEVICE_JOY18,
33 DEVICE_JOY19,
34 DEVICE_JOY20,
35 DEVICE_JOY21,
36 DEVICE_JOY22,
37 DEVICE_JOY23,
38 DEVICE_JOY24,
39 DEVICE_JOY25,
40 DEVICE_JOY26,
41 DEVICE_JOY27,
42 DEVICE_JOY28,
43 DEVICE_JOY29,
44 DEVICE_JOY30,
45 DEVICE_JOY31,
46 DEVICE_JOY32,
47 DEVICE_PUMP1,
48 DEVICE_PUMP2,
49 DEVICE_MIDI,
50 DEVICE_MOUSE,
51 DEVICE_PIUIO,
52 NUM_InputDevice, // leave this at the end
53 InputDevice_Invalid // means this is NULL
54};
56#define FOREACH_InputDevice(i) FOREACH_ENUM(InputDevice, i)
57auto
58InputDeviceToString(InputDevice i) -> const std::string&;
59auto
60StringToInputDevice(const std::string& s) -> InputDevice;
61inline auto
62IsJoystick(InputDevice id) -> bool
63{
64 return DEVICE_JOY1 <= id && id < DEVICE_JOY1 + NUM_JOYSTICKS;
65}
66inline auto
67IsPump(InputDevice id) -> bool
68{
69 return DEVICE_PUMP1 <= id && id < DEVICE_PUMP1 + NUM_PUMPS;
70}
71inline auto
72IsMouse(InputDevice id) -> bool
73{
74 return id == DEVICE_MOUSE;
75}
76
78{
79 InputDeviceInfo(InputDevice id_, std::string sDesc_)
80 : id(id_)
81 , sDesc(std::move(sDesc_))
82 {
83 }
84
85 InputDevice id;
86 std::string sDesc;
87};
88
89inline auto
90operator==(InputDeviceInfo const& lhs, InputDeviceInfo const& rhs) -> bool
91{
92 return lhs.id == rhs.id && lhs.sDesc == rhs.sDesc;
93}
94
95inline auto
96operator!=(InputDeviceInfo const& lhs, InputDeviceInfo const& rhs) -> bool
97{
98 return !operator==(lhs, rhs);
99}
100
101enum InputDeviceState
102{
103 InputDeviceState_Connected, // has an InputHandler and controller is plugged
104 // in
105 InputDeviceState_Unplugged, // has an InputHandler but controller is
106 // unplugged or lost wireless link
107 InputDeviceState_NeedsMultitap, // has an InputHandler but needs a multitap
108 // to function
109 InputDeviceState_NoInputHandler, // there is no InputHandler that implements
110 // this InputDevice
111 NUM_InputDeviceState,
112 InputDeviceState_Invalid
113};
114auto
115InputDeviceStateToString(InputDeviceState ids) -> const std::string&;
116
117/* Only raw, unshifted keys go in this table; this doesn't include
118 * internationalized keyboards, only keys that we might actually want to test
119 * for programmatically. Any other keys are mapped to KEY_OTHER_0 and up. (If we
120 * want to support real international input, stick a wchar_t in DeviceInput.) */
121
122enum DeviceButton
123{
124 KEY_SPACE = 32,
125 KEY_EXCL = 33,
126 KEY_QUOTE = 34,
127 KEY_HASH = 35,
128 KEY_DOLLAR = 36,
129 KEY_PERCENT = 37,
130 KEY_AMPER = 38,
131 KEY_SQUOTE = 39,
132 KEY_LPAREN = 40,
133 KEY_RPAREN = 41,
134 KEY_ASTERISK = 42,
135 KEY_PLUS = 43,
136 KEY_COMMA = 44,
137 KEY_HYPHEN = 45,
138 KEY_PERIOD = 46,
139 KEY_SLASH = 47,
140 KEY_C0 = 48,
141 KEY_C1 = 49,
142 KEY_C2 = 50,
143 KEY_C3 = 51,
144 KEY_C4 = 52,
145 KEY_C5 = 53,
146 KEY_C6 = 54,
147 KEY_C7 = 55,
148 KEY_C8 = 56,
149 KEY_C9 = 57,
150 KEY_COLON = 58,
151 KEY_SEMICOLON = 59,
152 KEY_LANGLE = 60,
153 KEY_EQUAL = 61,
154 KEY_RANGLE = 62,
155 KEY_QUESTION = 63,
156 KEY_AT = 64,
157 KEY_CA = 65,
158 KEY_CB = 66,
159 KEY_CC = 67,
160 KEY_CD = 68,
161 KEY_CE = 69,
162 KEY_CF = 70,
163 KEY_CG = 71,
164 KEY_CH = 72,
165 KEY_CI = 73,
166 KEY_CJ = 74,
167 KEY_CK = 75,
168 KEY_CL = 76,
169 KEY_CM = 77,
170 KEY_CN = 78,
171 KEY_CO = 79,
172 KEY_CP = 80,
173 KEY_CQ = 81,
174 KEY_CR = 82,
175 KEY_CS = 83,
176 KEY_CT = 84,
177 KEY_CU = 85,
178 KEY_CV = 86,
179 KEY_CW = 87,
180 KEY_CX = 88,
181 KEY_CY = 89,
182 KEY_CZ = 90,
183 KEY_LBRACKET = 91,
184 KEY_BACKSLASH = 92,
185 KEY_RBRACKET = 93,
186 KEY_CARAT = 94,
187 KEY_UNDERSCORE = 95,
188 KEY_ACCENT = 96,
189 KEY_Ca = 97,
190 KEY_Cb = 98,
191 KEY_Cc = 99,
192 KEY_Cd = 100,
193 KEY_Ce = 101,
194 KEY_Cf = 102,
195 KEY_Cg = 103,
196 KEY_Ch = 104,
197 KEY_Ci = 105,
198 KEY_Cj = 106,
199 KEY_Ck = 107,
200 KEY_Cl = 108,
201 KEY_Cm = 109,
202 KEY_Cn = 110,
203 KEY_Co = 111,
204 KEY_Cp = 112,
205 KEY_Cq = 113,
206 KEY_Cr = 114,
207 KEY_Cs = 115,
208 KEY_Ct = 116,
209 KEY_Cu = 117,
210 KEY_Cv = 118,
211 KEY_Cw = 119,
212 KEY_Cx = 120,
213 KEY_Cy = 121,
214 KEY_Cz = 122,
215 KEY_LBRACE = 123,
216 KEY_PIPE = 124,
217 KEY_RBRACE = 125,
218 KEY_DEL = 127,
219
220 KEY_BACK,
221 KEY_TAB,
222 KEY_ENTER,
223 KEY_PAUSE,
224 KEY_ESC,
225
226 KEY_F1,
227 KEY_F2,
228 KEY_F3,
229 KEY_F4,
230 KEY_F5,
231 KEY_F6,
232 KEY_F7,
233 KEY_F8,
234 KEY_F9,
235 KEY_F10,
236 KEY_F11,
237 KEY_F12,
238 KEY_F13,
239 KEY_F14,
240 KEY_F15,
241 KEY_F16,
242
243 KEY_LCTRL,
244 KEY_RCTRL,
245 KEY_LSHIFT,
246 KEY_RSHIFT,
247 KEY_LALT,
248 KEY_RALT,
249 KEY_LMETA,
250 KEY_RMETA,
251 KEY_LSUPER,
252 KEY_RSUPER,
253 KEY_MENU,
254
255 KEY_FN, // Laptop function keys.
256
257 KEY_NUMLOCK,
258 KEY_SCRLLOCK,
259 KEY_CAPSLOCK,
260 KEY_PRTSC,
261
262 KEY_UP,
263 KEY_DOWN,
264 KEY_LEFT,
265 KEY_RIGHT,
266
267 KEY_INSERT,
268 KEY_HOME,
269 KEY_END,
270 KEY_PGUP,
271 KEY_PGDN,
272
273 KEY_KP_C0,
274 KEY_KP_C1,
275 KEY_KP_C2,
276 KEY_KP_C3,
277 KEY_KP_C4,
278 KEY_KP_C5,
279 KEY_KP_C6,
280 KEY_KP_C7,
281 KEY_KP_C8,
282 KEY_KP_C9,
283 KEY_KP_SLASH,
284 KEY_KP_ASTERISK,
285 KEY_KP_HYPHEN,
286 KEY_KP_PLUS,
287 KEY_KP_PERIOD,
288 KEY_KP_EQUAL,
289 KEY_KP_ENTER,
290
291 KEY_OTHER_0,
292 // ...
293 KEY_LAST_OTHER = 511,
294
295 /* Joystick inputs. We try to have enough input names so any input on a
296 * reasonable joystick has an obvious mapping, but keep it generic and don't
297 * try to handle odd special cases. For example, many controllers have two
298 * sticks, so the JOY_LEFT_2, etc. pairs are useful for many types of
299 * sticks. */
300 // Standard axis:
301 JOY_LEFT,
302 JOY_RIGHT,
303 JOY_UP,
304 JOY_DOWN,
305
306 // Secondary sticks:
307 JOY_LEFT_2,
308 JOY_RIGHT_2,
309 JOY_UP_2,
310 JOY_DOWN_2,
311
312 JOY_Z_UP,
313 JOY_Z_DOWN,
314 JOY_ROT_UP,
315 JOY_ROT_DOWN,
316 JOY_ROT_LEFT,
317 JOY_ROT_RIGHT,
318 JOY_ROT_Z_UP,
319 JOY_ROT_Z_DOWN,
320 JOY_HAT_LEFT,
321 JOY_HAT_RIGHT,
322 JOY_HAT_UP,
323 JOY_HAT_DOWN,
324 JOY_AUX_1,
325 JOY_AUX_2,
326 JOY_AUX_3,
327 JOY_AUX_4,
328
329 // Buttons:
330 JOY_BUTTON_1,
331 JOY_BUTTON_2,
332 JOY_BUTTON_3,
333 JOY_BUTTON_4,
334 JOY_BUTTON_5,
335 JOY_BUTTON_6,
336 JOY_BUTTON_7,
337 JOY_BUTTON_8,
338 JOY_BUTTON_9,
339 JOY_BUTTON_10,
340 JOY_BUTTON_11,
341 JOY_BUTTON_12,
342 JOY_BUTTON_13,
343 JOY_BUTTON_14,
344 JOY_BUTTON_15,
345 JOY_BUTTON_16,
346 JOY_BUTTON_17,
347 JOY_BUTTON_18,
348 JOY_BUTTON_19,
349 JOY_BUTTON_20,
350 JOY_BUTTON_21,
351 JOY_BUTTON_22,
352 JOY_BUTTON_23,
353 JOY_BUTTON_24,
354 JOY_BUTTON_25,
355 JOY_BUTTON_26,
356 JOY_BUTTON_27,
357 JOY_BUTTON_28,
358 JOY_BUTTON_29,
359 JOY_BUTTON_30,
360 JOY_BUTTON_31,
361 JOY_BUTTON_32,
362
363 MIDI_FIRST = 600,
364 MIDI_LAST = 699,
365
366 // Mouse buttons
367 MOUSE_LEFT = 700,
368 MOUSE_RIGHT,
369 MOUSE_MIDDLE,
370 // todo: button4/5
371 // axis
372 MOUSE_X_LEFT,
373 MOUSE_X_RIGHT,
374 MOUSE_Y_UP,
375 MOUSE_Y_DOWN,
376 // Mouse wheel (z axis)
377 MOUSE_WHEELUP,
378 MOUSE_WHEELDOWN,
379
380 NUM_DeviceButton,
381 DeviceButton_Invalid
382};
383
384auto
385DeviceButtonToString(DeviceButton i) -> std::string;
386auto
387StringToDeviceButton(const std::string& s) -> DeviceButton;
388
390{
391 public:
392 InputDevice device{ InputDevice_Invalid };
393 DeviceButton button{ DeviceButton_Invalid };
394
395 /* This is usually 0 or 1. Analog joystick inputs can set this to a
396 * percentage (0..1). This should be 0 for analog axes within the dead zone.
397 */
398 float level{ 0 };
399
400 // Mouse coordinates
401 // unsigned x;
402 // unsigned y;
403 int z{ 0 }; // mousewheel
404
405 /* Whether this button is pressed. This is level with a threshold and
406 * debouncing applied. */
407 bool bDown{ false };
408
409 std::chrono::steady_clock::time_point ts;
410
412 : ts(std::chrono::microseconds{ 0 })
413 {
414 }
415 DeviceInput(InputDevice d, DeviceButton b, float l = 0)
416 : device(d)
417 , button(b)
418 , level(l)
419 , bDown(l > 0.5F)
420 , ts(std::chrono::microseconds{ 0 })
421 {
422 }
423 DeviceInput(InputDevice d,
424 DeviceButton b,
425 float l,
426 const std::chrono::steady_clock::time_point& t)
427 : device(d)
428 , button(b)
429 , level(l)
430 , bDown(level > 0.5F)
431 , ts(t)
432 {
433 }
434 DeviceInput(InputDevice d,
435 DeviceButton b,
436 const std::chrono::steady_clock::time_point& t,
437 int zVal = 0)
438 : device(d)
439 , button(b)
440 , z(zVal)
441 , ts(t)
442 {
443 }
444
445 [[nodiscard]] auto ToString() const -> std::string;
446 auto FromString(const std::string& s) -> bool;
447
448 [[nodiscard]] auto IsValid() const -> bool
449 {
450 return device != InputDevice_Invalid;
451 };
452 void MakeInvalid() { device = InputDevice_Invalid; };
453
454 [[nodiscard]] auto IsJoystick() const -> bool
455 {
456 return ::IsJoystick(device);
457 }
458 [[nodiscard]] auto IsMouse() const -> bool { return ::IsMouse(device); }
459};
460
461inline auto
462operator==(DeviceInput const& lhs, DeviceInput const& rhs) -> bool
463{
464 /* Return true if we represent the same button on the same device.
465 * Don't compare level or ts. */
466 return lhs.device == rhs.device && lhs.button == rhs.button;
467}
468inline auto
469operator!=(DeviceInput const& lhs, DeviceInput const& rhs) -> bool
470{
471 return !operator==(lhs, rhs);
472}
473
474inline auto
475operator<(DeviceInput const& lhs, DeviceInput const& rhs) -> bool
476{
477 /* Only the devices and buttons matter here. */
478 if (lhs.device != rhs.device) {
479 return lhs.device < rhs.device;
480 }
481 return lhs.button < rhs.button;
482}
483inline auto
484operator>(DeviceInput const& lhs, DeviceInput const& rhs) -> bool
485{
486 return operator<(rhs, lhs);
487}
488inline auto
489operator<=(DeviceInput const& lhs, DeviceInput const& rhs) -> bool
490{
491 return !operator<(rhs, lhs);
492}
493inline auto
494operator>=(DeviceInput const& lhs, DeviceInput const& rhs) -> bool
495{
496 return !operator<(lhs, rhs);
497}
498
499typedef std::vector<DeviceInput> DeviceInputList;
500
501#endif
Definition RageInputDevice.h:390
Definition RageInputDevice.h:78