Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/nall/input.hpp
2 views
1
#ifndef NALL_INPUT_HPP
2
#define NALL_INPUT_HPP
3
4
#include <stdio.h>
5
#include <stdlib.h>
6
#include <string.h>
7
8
#include <nall/stdint.hpp>
9
#include <nall/string.hpp>
10
11
namespace nall {
12
13
struct Keyboard;
14
Keyboard& keyboard(unsigned = 0);
15
16
static const char KeyboardScancodeName[][64] = {
17
"Escape", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12",
18
"PrintScreen", "ScrollLock", "Pause", "Tilde",
19
"Num1", "Num2", "Num3", "Num4", "Num5", "Num6", "Num7", "Num8", "Num9", "Num0",
20
"Dash", "Equal", "Backspace",
21
"Insert", "Delete", "Home", "End", "PageUp", "PageDown",
22
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
23
"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
24
"LeftBracket", "RightBracket", "Backslash", "Semicolon", "Apostrophe", "Comma", "Period", "Slash",
25
"Keypad1", "Keypad2", "Keypad3", "Keypad4", "Keypad5", "Keypad6", "Keypad7", "Keypad8", "Keypad9", "Keypad0",
26
"Point", "Enter", "Add", "Subtract", "Multiply", "Divide",
27
"NumLock", "CapsLock",
28
"Up", "Down", "Left", "Right",
29
"Tab", "Return", "Spacebar", "Menu",
30
"Shift", "Control", "Alt", "Super",
31
};
32
33
struct Keyboard {
34
const unsigned ID;
35
enum { Base = 1 };
36
enum { Count = 8, Size = 128 };
37
38
enum Scancode {
39
Escape, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
40
PrintScreen, ScrollLock, Pause, Tilde,
41
Num1, Num2, Num3, Num4, Num5, Num6, Num7, Num8, Num9, Num0,
42
Dash, Equal, Backspace,
43
Insert, Delete, Home, End, PageUp, PageDown,
44
A, B, C, D, E, F, G, H, I, J, K, L, M,
45
N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
46
LeftBracket, RightBracket, Backslash, Semicolon, Apostrophe, Comma, Period, Slash,
47
Keypad1, Keypad2, Keypad3, Keypad4, Keypad5, Keypad6, Keypad7, Keypad8, Keypad9, Keypad0,
48
Point, Enter, Add, Subtract, Multiply, Divide,
49
NumLock, CapsLock,
50
Up, Down, Left, Right,
51
Tab, Return, Spacebar, Menu,
52
Shift, Control, Alt, Super,
53
Limit,
54
};
55
56
static signed numberDecode(uint16_t scancode) {
57
for(unsigned i = 0; i < Count; i++) {
58
if(keyboard(i).belongsTo(scancode)) return i;
59
}
60
return -1;
61
}
62
63
static signed keyDecode(uint16_t scancode) {
64
for(unsigned i = 0; i < Count; i++) {
65
if(keyboard(i).isKey(scancode)) return scancode - keyboard(i).key(Escape);
66
}
67
return -1;
68
}
69
70
static signed modifierDecode(uint16_t scancode) {
71
for(unsigned i = 0; i < Count; i++) {
72
if(keyboard(i).isModifier(scancode)) return scancode - keyboard(i).key(Shift);
73
}
74
return -1;
75
}
76
77
static bool isAnyKey(uint16_t scancode) {
78
for(unsigned i = 0; i < Count; i++) {
79
if(keyboard(i).isKey(scancode)) return true;
80
}
81
return false;
82
}
83
84
static bool isAnyModifier(uint16_t scancode) {
85
for(unsigned i = 0; i < Count; i++) {
86
if(keyboard(i).isModifier(scancode)) return true;
87
}
88
return false;
89
}
90
91
static uint16_t decode(const char *name) {
92
string s(name);
93
if(!strbegin(name, "KB")) return 0;
94
s.ltrim("KB");
95
unsigned id = decimal(s);
96
auto pos = strpos(s, "::");
97
if(!pos) return 0;
98
s = substr(s, pos() + 2);
99
for(unsigned i = 0; i < Limit; i++) {
100
if(s == KeyboardScancodeName[i]) return Base + Size * id + i;
101
}
102
return 0;
103
}
104
105
string encode(uint16_t code) const {
106
unsigned index = 0;
107
for(unsigned i = 0; i < Count; i++) {
108
if(code >= Base + Size * i && code < Base + Size * (i + 1)) {
109
index = code - (Base + Size * i);
110
break;
111
}
112
}
113
return { "KB", ID, "::", KeyboardScancodeName[index] };
114
}
115
116
uint16_t operator[](Scancode code) const { return Base + ID * Size + code; }
117
uint16_t key(unsigned id) const { return Base + Size * ID + id; }
118
bool isKey(unsigned id) const { return id >= key(Escape) && id <= key(Menu); }
119
bool isModifier(unsigned id) const { return id >= key(Shift) && id <= key(Super); }
120
bool belongsTo(uint16_t scancode) const { return isKey(scancode) || isModifier(scancode); }
121
122
Keyboard(unsigned ID_) : ID(ID_) {}
123
};
124
125
inline Keyboard& keyboard(unsigned id) {
126
static Keyboard kb0(0), kb1(1), kb2(2), kb3(3), kb4(4), kb5(5), kb6(6), kb7(7);
127
switch(id) { default:
128
case 0: return kb0; case 1: return kb1; case 2: return kb2; case 3: return kb3;
129
case 4: return kb4; case 5: return kb5; case 6: return kb6; case 7: return kb7;
130
}
131
}
132
133
static const char MouseScancodeName[][64] = {
134
"Xaxis", "Yaxis", "Zaxis",
135
"Button0", "Button1", "Button2", "Button3", "Button4", "Button5", "Button6", "Button7",
136
};
137
138
struct Mouse;
139
Mouse& mouse(unsigned = 0);
140
141
struct Mouse {
142
const unsigned ID;
143
enum { Base = Keyboard::Base + Keyboard::Size * Keyboard::Count };
144
enum { Count = 8, Size = 16 };
145
enum { Axes = 3, Buttons = 8 };
146
147
enum Scancode {
148
Xaxis, Yaxis, Zaxis,
149
Button0, Button1, Button2, Button3, Button4, Button5, Button6, Button7,
150
Limit,
151
};
152
153
static signed numberDecode(uint16_t scancode) {
154
for(unsigned i = 0; i < Count; i++) {
155
if(mouse(i).belongsTo(scancode)) return i;
156
}
157
return -1;
158
}
159
160
static signed axisDecode(uint16_t scancode) {
161
for(unsigned i = 0; i < Count; i++) {
162
if(mouse(i).isAxis(scancode)) return scancode - mouse(i).axis(0);
163
}
164
return -1;
165
}
166
167
static signed buttonDecode(uint16_t scancode) {
168
for(unsigned i = 0; i < Count; i++) {
169
if(mouse(i).isButton(scancode)) return scancode - mouse(i).button(0);
170
}
171
return -1;
172
}
173
174
static bool isAnyAxis(uint16_t scancode) {
175
for(unsigned i = 0; i < Count; i++) {
176
if(mouse(i).isAxis(scancode)) return true;
177
}
178
return false;
179
}
180
181
static bool isAnyButton(uint16_t scancode) {
182
for(unsigned i = 0; i < Count; i++) {
183
if(mouse(i).isButton(scancode)) return true;
184
}
185
return false;
186
}
187
188
static uint16_t decode(const char *name) {
189
string s(name);
190
if(!strbegin(name, "MS")) return 0;
191
s.ltrim("MS");
192
unsigned id = decimal(s);
193
auto pos = strpos(s, "::");
194
if(!pos) return 0;
195
s = substr(s, pos() + 2);
196
for(unsigned i = 0; i < Limit; i++) {
197
if(s == MouseScancodeName[i]) return Base + Size * id + i;
198
}
199
return 0;
200
}
201
202
string encode(uint16_t code) const {
203
unsigned index = 0;
204
for(unsigned i = 0; i < Count; i++) {
205
if(code >= Base + Size * i && code < Base + Size * (i + 1)) {
206
index = code - (Base + Size * i);
207
break;
208
}
209
}
210
return { "MS", ID, "::", MouseScancodeName[index] };
211
}
212
213
uint16_t operator[](Scancode code) const { return Base + ID * Size + code; }
214
uint16_t axis(unsigned id) const { return Base + Size * ID + Xaxis + id; }
215
uint16_t button(unsigned id) const { return Base + Size * ID + Button0 + id; }
216
bool isAxis(unsigned id) const { return id >= axis(0) && id <= axis(2); }
217
bool isButton(unsigned id) const { return id >= button(0) && id <= button(7); }
218
bool belongsTo(uint16_t scancode) const { return isAxis(scancode) || isButton(scancode); }
219
220
Mouse(unsigned ID_) : ID(ID_) {}
221
};
222
223
inline Mouse& mouse(unsigned id) {
224
static Mouse ms0(0), ms1(1), ms2(2), ms3(3), ms4(4), ms5(5), ms6(6), ms7(7);
225
switch(id) { default:
226
case 0: return ms0; case 1: return ms1; case 2: return ms2; case 3: return ms3;
227
case 4: return ms4; case 5: return ms5; case 6: return ms6; case 7: return ms7;
228
}
229
}
230
231
static const char JoypadScancodeName[][64] = {
232
"Hat0", "Hat1", "Hat2", "Hat3", "Hat4", "Hat5", "Hat6", "Hat7",
233
"Axis0", "Axis1", "Axis2", "Axis3", "Axis4", "Axis5", "Axis6", "Axis7",
234
"Axis8", "Axis9", "Axis10", "Axis11", "Axis12", "Axis13", "Axis14", "Axis15",
235
"Button0", "Button1", "Button2", "Button3", "Button4", "Button5", "Button6", "Button7",
236
"Button8", "Button9", "Button10", "Button11", "Button12", "Button13", "Button14", "Button15",
237
"Button16", "Button17", "Button18", "Button19", "Button20", "Button21", "Button22", "Button23",
238
"Button24", "Button25", "Button26", "Button27", "Button28", "Button29", "Button30", "Button31",
239
};
240
241
struct Joypad;
242
Joypad& joypad(unsigned = 0);
243
244
struct Joypad {
245
const unsigned ID;
246
enum { Base = Mouse::Base + Mouse::Size * Mouse::Count };
247
enum { Count = 8, Size = 64 };
248
enum { Hats = 8, Axes = 16, Buttons = 32 };
249
250
enum Scancode {
251
Hat0, Hat1, Hat2, Hat3, Hat4, Hat5, Hat6, Hat7,
252
Axis0, Axis1, Axis2, Axis3, Axis4, Axis5, Axis6, Axis7,
253
Axis8, Axis9, Axis10, Axis11, Axis12, Axis13, Axis14, Axis15,
254
Button0, Button1, Button2, Button3, Button4, Button5, Button6, Button7,
255
Button8, Button9, Button10, Button11, Button12, Button13, Button14, Button15,
256
Button16, Button17, Button18, Button19, Button20, Button21, Button22, Button23,
257
Button24, Button25, Button26, Button27, Button28, Button29, Button30, Button31,
258
Limit,
259
};
260
261
enum Hat { HatCenter = 0, HatUp = 1, HatRight = 2, HatDown = 4, HatLeft = 8 };
262
263
static signed numberDecode(uint16_t scancode) {
264
for(unsigned i = 0; i < Count; i++) {
265
if(joypad(i).belongsTo(scancode)) return i;
266
}
267
return -1;
268
}
269
270
static signed hatDecode(uint16_t scancode) {
271
for(unsigned i = 0; i < Count; i++) {
272
if(joypad(i).isHat(scancode)) return scancode - joypad(i).hat(0);
273
}
274
return -1;
275
}
276
277
static signed axisDecode(uint16_t scancode) {
278
for(unsigned i = 0; i < Count; i++) {
279
if(joypad(i).isAxis(scancode)) return scancode - joypad(i).axis(0);
280
}
281
return -1;
282
}
283
284
static signed buttonDecode(uint16_t scancode) {
285
for(unsigned i = 0; i < Count; i++) {
286
if(joypad(i).isButton(scancode)) return scancode - joypad(i).button(0);
287
}
288
return -1;
289
}
290
291
static bool isAnyHat(uint16_t scancode) {
292
for(unsigned i = 0; i < Count; i++) {
293
if(joypad(i).isHat(scancode)) return true;
294
}
295
return false;
296
}
297
298
static bool isAnyAxis(uint16_t scancode) {
299
for(unsigned i = 0; i < Count; i++) {
300
if(joypad(i).isAxis(scancode)) return true;
301
}
302
return false;
303
}
304
305
static bool isAnyButton(uint16_t scancode) {
306
for(unsigned i = 0; i < Count; i++) {
307
if(joypad(i).isButton(scancode)) return true;
308
}
309
return false;
310
}
311
312
static uint16_t decode(const char *name) {
313
string s(name);
314
if(!strbegin(name, "JP")) return 0;
315
s.ltrim("JP");
316
unsigned id = decimal(s);
317
auto pos = strpos(s, "::");
318
if(!pos) return 0;
319
s = substr(s, pos() + 2);
320
for(unsigned i = 0; i < Limit; i++) {
321
if(s == JoypadScancodeName[i]) return Base + Size * id + i;
322
}
323
return 0;
324
}
325
326
string encode(uint16_t code) const {
327
unsigned index = 0;
328
for(unsigned i = 0; i < Count; i++) {
329
if(code >= Base + Size * i && code < Base + Size * (i + 1)) {
330
index = code - (Base + Size * i);
331
}
332
}
333
return { "JP", ID, "::", JoypadScancodeName[index] };
334
}
335
336
uint16_t operator[](Scancode code) const { return Base + ID * Size + code; }
337
uint16_t hat(unsigned id) const { return Base + Size * ID + Hat0 + id; }
338
uint16_t axis(unsigned id) const { return Base + Size * ID + Axis0 + id; }
339
uint16_t button(unsigned id) const { return Base + Size * ID + Button0 + id; }
340
bool isHat(unsigned id) const { return id >= hat(0) && id <= hat(7); }
341
bool isAxis(unsigned id) const { return id >= axis(0) && id <= axis(15); }
342
bool isButton(unsigned id) const { return id >= button(0) && id <= button(31); }
343
bool belongsTo(uint16_t scancode) const { return isHat(scancode) || isAxis(scancode) || isButton(scancode); }
344
345
Joypad(unsigned ID_) : ID(ID_) {}
346
};
347
348
inline Joypad& joypad(unsigned id) {
349
static Joypad jp0(0), jp1(1), jp2(2), jp3(3), jp4(4), jp5(5), jp6(6), jp7(7);
350
switch(id) { default:
351
case 0: return jp0; case 1: return jp1; case 2: return jp2; case 3: return jp3;
352
case 4: return jp4; case 5: return jp5; case 6: return jp6; case 7: return jp7;
353
}
354
}
355
356
struct Scancode {
357
enum { None = 0, Limit = Joypad::Base + Joypad::Size * Joypad::Count };
358
359
static uint16_t decode(const char *name) {
360
uint16_t code;
361
code = Keyboard::decode(name);
362
if(code) return code;
363
code = Mouse::decode(name);
364
if(code) return code;
365
code = Joypad::decode(name);
366
if(code) return code;
367
return None;
368
}
369
370
static string encode(uint16_t code) {
371
for(unsigned i = 0; i < Keyboard::Count; i++) {
372
if(keyboard(i).belongsTo(code)) return keyboard(i).encode(code);
373
}
374
for(unsigned i = 0; i < Mouse::Count; i++) {
375
if(mouse(i).belongsTo(code)) return mouse(i).encode(code);
376
}
377
for(unsigned i = 0; i < Joypad::Count; i++) {
378
if(joypad(i).belongsTo(code)) return joypad(i).encode(code);
379
}
380
return "None";
381
}
382
};
383
384
}
385
386
#endif
387
388