1
2 #include "input.h"
3
4 #include "Utils/Logger.h"
5 #include "console.h"
6 #include "game.h"
7 #include "nx.h"
8 #include "settings.h"
9 #include "sound/SoundManager.h"
10
11 #include <array>
12
13 in_action mappings[INPUT_COUNT];
14
15 bool inputs[INPUT_COUNT];
16 bool lastinputs[INPUT_COUNT];
17 in_action last_sdl_action;
18 SDL_Joystick *joy;
19
20 int ACCEPT_BUTTON = JUMPKEY;
21 int DECLINE_BUTTON = FIREKEY;
22
23
input_init(void)24 bool input_init(void)
25 {
26 memset(inputs, 0, sizeof(inputs));
27 memset(lastinputs, 0, sizeof(lastinputs));
28 memset(mappings, -1, sizeof(mappings));
29 for (int i = 0; i < INPUT_COUNT; i++)
30 {
31 mappings[i].key = -1;
32 mappings[i].jbut = -1;
33 mappings[i].jhat = -1;
34 mappings[i].jaxis = -1;
35 }
36
37 // default mappings
38 mappings[LEFTKEY].key = SDLK_LEFT;
39 mappings[RIGHTKEY].key = SDLK_RIGHT;
40 mappings[UPKEY].key = SDLK_UP;
41 mappings[DOWNKEY].key = SDLK_DOWN;
42 mappings[JUMPKEY].key = SDLK_z;
43 mappings[FIREKEY].key = SDLK_x;
44 mappings[STRAFEKEY].key = SDLK_c;
45 mappings[PREVWPNKEY].key = SDLK_a;
46 mappings[NEXTWPNKEY].key = SDLK_s;
47 mappings[INVENTORYKEY].key = SDLK_q;
48 mappings[MAPSYSTEMKEY].key = SDLK_w;
49
50 mappings[ESCKEY].key = SDLK_ESCAPE;
51
52 #if defined(__VITA__)
53 mappings[MAPSYSTEMKEY].jbut = 0; // Triangle
54 mappings[FIREKEY].jbut = 1; // Circle
55 mappings[JUMPKEY].jbut = 2; // Cross
56 mappings[INVENTORYKEY].jbut = 3; // Square
57 mappings[PREVWPNKEY].jbut = 4; // LTrig
58 mappings[NEXTWPNKEY].jbut = 5; // Rtrig
59
60 mappings[DOWNKEY].jbut = 6;
61 mappings[LEFTKEY].jbut = 7;
62 mappings[UPKEY].jbut = 8;
63 mappings[RIGHTKEY].jbut = 9;
64 mappings[ESCKEY].jbut = 11;
65 #endif
66
67 #if defined(__SWITCH__)
68 mappings[LEFTKEY].jbut = 16;
69 mappings[UPKEY].jbut = 17;
70 mappings[RIGHTKEY].jbut = 18;
71 mappings[DOWNKEY].jbut = 19;
72
73 mappings[FIREKEY].jbut = 1; // A
74 mappings[JUMPKEY].jbut = 0; // B
75 mappings[MAPSYSTEMKEY].jbut = 3; // X
76 mappings[INVENTORYKEY].jbut = 2; // Y
77
78 mappings[PREVWPNKEY].jbut = 6; // L
79 mappings[NEXTWPNKEY].jbut = 7; // R
80
81 mappings[ENTERKEY].jbut = 10; // +
82 mappings[ESCKEY].jbut = 11; // -
83 #endif
84
85 mappings[F1KEY].key = SDLK_F1;
86 mappings[F2KEY].key = SDLK_F2;
87 mappings[F3KEY].key = SDLK_F3;
88 mappings[F4KEY].key = SDLK_F4;
89 mappings[F5KEY].key = SDLK_F5;
90 mappings[F6KEY].key = SDLK_F6;
91 mappings[F7KEY].key = SDLK_F7;
92 mappings[F8KEY].key = SDLK_F8;
93 mappings[F9KEY].key = SDLK_F9;
94 mappings[F10KEY].key = SDLK_F10;
95 mappings[F11KEY].key = SDLK_F11;
96 mappings[F12KEY].key = SDLK_F12;
97 #if defined(DEBUG)
98 mappings[FREEZE_FRAME_KEY].key = SDLK_SPACE;
99 mappings[FRAME_ADVANCE_KEY].key = SDLK_b;
100 mappings[DEBUG_FLY_KEY].key = SDLK_v;
101 #else
102 mappings[FREEZE_FRAME_KEY].key = 0;
103 mappings[FRAME_ADVANCE_KEY].key = 0;
104 mappings[DEBUG_FLY_KEY].key = 0;
105 #endif
106 mappings[ENTERKEY].key = SDLK_RETURN;
107
108 SDL_InitSubSystem(SDL_INIT_JOYSTICK);
109 if (SDL_NumJoysticks() > 0)
110 {
111 // Open joystick
112 joy = SDL_JoystickOpen(0);
113
114 if (joy)
115 {
116 LOG_INFO("Opened Joystick 0");
117 LOG_INFO("Name: {}", SDL_JoystickNameForIndex(0));
118 LOG_INFO("Number of Axes: {}", SDL_JoystickNumAxes(joy));
119 LOG_INFO("Number of Buttons: {}", SDL_JoystickNumButtons(joy));
120 LOG_INFO("Number of Balls: {}", SDL_JoystickNumBalls(joy));
121 }
122 else
123 {
124 LOG_WARN("Couldn't open Joystick 0");
125 }
126 }
127 return 0;
128 }
129
rumble(float str,uint32_t len)130 void rumble(float str, uint32_t len)
131 {
132 if (settings->rumble)
133 SDL_JoystickRumble(joy, 0xFFFF * str, 0xFFFF * str, len);
134 }
135
136 // set the SDL key that triggers an input
input_remap(int keyindex,in_action sdl_key)137 void input_remap(int keyindex, in_action sdl_key)
138 {
139 LOG_DEBUG("input_remap(%d => %d)", keyindex, sdl_key.key);
140 // in_action old_mapping = input_get_mapping(keyindex);
141 // if (old_mapping != -1)
142 // mappings[old_mapping] = 0xff;
143
144 mappings[keyindex] = sdl_key;
145 }
146
147 // get which SDL key triggers a given input
input_get_mapping(int keyindex)148 in_action input_get_mapping(int keyindex)
149 {
150 return mappings[keyindex];
151 }
152
input_get_action(int32_t sdlkey)153 int input_get_action(int32_t sdlkey)
154 {
155 for (int i = 0; i < INPUT_COUNT; i++)
156 {
157 if (mappings[i].key == sdlkey)
158 {
159 return i;
160 }
161 }
162 return -1;
163 }
164
input_get_action_but(int32_t jbut)165 int input_get_action_but(int32_t jbut)
166 {
167 for (int i = 0; i < INPUT_COUNT; i++)
168 {
169 if (mappings[i].jbut == jbut)
170 {
171 return i;
172 }
173 }
174 return -1;
175 }
176
input_get_action_hat(int32_t jhat,int32_t jvalue)177 int input_get_action_hat(int32_t jhat, int32_t jvalue)
178 {
179 for (int i = 0; i < INPUT_COUNT; i++)
180 {
181 if ((mappings[i].jhat == jhat) && (jvalue & mappings[i].jhat_value))
182 {
183 return i;
184 }
185 }
186 return -1;
187 }
188
input_get_action_axis(int32_t jaxis,int32_t jvalue)189 int input_get_action_axis(int32_t jaxis, int32_t jvalue)
190 {
191 for (int i = 0; i < INPUT_COUNT; i++)
192 {
193 if ((mappings[i].jaxis == jaxis)
194 && ((jvalue > 0 && mappings[i].jaxis_value > 0) || (jvalue < 0 && mappings[i].jaxis_value < 0)))
195 {
196 return i;
197 }
198 }
199 return -1;
200 }
201
input_get_name(int index)202 const std::string input_get_name(int index)
203 {
204 static std::array<std::string, 28> input_names = {"Left", "Right",
205 "Up", "Down",
206 "Jump", "Fire",
207 "Strafe", "Wpn Prev",
208 "Wpn Next", "Inventory",
209 "Map", "Pause",
210 "f1", "f2",
211 "f3", "f4",
212 "f5", "f6",
213 "f7", "f8",
214 "f9", "f10",
215 "f11", "f12",
216 "freeze frame", "frame advance",
217 "debug fly", "Enter"};
218
219 if (index < 0 || index >= INPUT_COUNT)
220 return "invalid";
221
222 return input_names[index];
223 }
224
input_set_mappings(in_action * array)225 void input_set_mappings(in_action *array)
226 {
227 memset(mappings, 0xff, sizeof(mappings));
228 for (int i = 0; i < INPUT_COUNT; i++)
229 mappings[i] = array[i];
230 }
231
232 /*
233 void c------------------------------() {}
234 */
235
236 // keys that we don't want to send to the console
237 // even if the console is up.
IsNonConsoleKey(int key)238 static int IsNonConsoleKey(int key)
239 {
240 static const int nosend[] = {SDLK_LEFT, SDLK_RIGHT, 0};
241
242 for (int i = 0; nosend[i]; i++)
243 if (key == nosend[i])
244 return true;
245
246 return false;
247 }
248
input_poll(void)249 void input_poll(void)
250 {
251 SDL_Event evt;
252 int32_t key;
253 int ino; //, key;
254
255 while (SDL_PollEvent(&evt))
256 {
257 switch (evt.type)
258 {
259 case SDL_KEYDOWN:
260 case SDL_KEYUP:
261 {
262 key = evt.key.keysym.sym;
263
264 static uint8_t shiftstates = 0;
265
266 if (console.IsVisible() && !IsNonConsoleKey(key))
267 {
268 if (key == SDLK_LSHIFT)
269 {
270 if (evt.type == SDL_KEYDOWN)
271 shiftstates |= LEFTMASK;
272 else
273 shiftstates &= ~LEFTMASK;
274 }
275 else if (key == SDLK_RSHIFT)
276 {
277 if (evt.type == SDL_KEYDOWN)
278 shiftstates |= RIGHTMASK;
279 else
280 shiftstates &= ~RIGHTMASK;
281 }
282 else
283 {
284 int ch = key;
285 if (shiftstates != 0)
286 {
287 ch = toupper(ch);
288 if (ch == '.')
289 ch = '>';
290 if (ch == '-')
291 ch = '_';
292 if (ch == '/')
293 ch = '?';
294 if (ch == '1')
295 ch = '!';
296 }
297
298 if (evt.type == SDL_KEYDOWN)
299 console.HandleKey(ch);
300 else
301 console.HandleKeyRelease(ch);
302 }
303 }
304 else
305 {
306 ino = input_get_action(key); // mappings[key];
307
308 if (ino != -1)
309 inputs[ino] = (evt.type == SDL_KEYDOWN);
310
311 if (evt.type == SDL_KEYDOWN)
312 {
313 if (key == '`') // bring up console
314 {
315 #if defined(DEBUG)
316 extern bool freezeframe;
317 if (!freezeframe)
318 {
319 NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_SWITCH_WEAPON);
320 console.SetVisible(true);
321 }
322 #endif
323 }
324 else
325 {
326 last_sdl_action.key = key;
327 }
328 }
329 }
330 }
331 break;
332
333 case SDL_QUIT:
334 {
335 inputs[ESCKEY] = true;
336 game.running = false;
337 }
338 break;
339
340 case SDL_JOYBUTTONDOWN:
341 {
342 Uint8 but = evt.jbutton.button;
343 last_sdl_action.jbut = but;
344 ino = input_get_action_but(but); // mappings[key];
345 if (ino != -1)
346 inputs[ino] = (evt.jbutton.state == SDL_PRESSED);
347 }
348 break;
349
350 case SDL_JOYBUTTONUP:
351 {
352 Uint8 but = evt.jbutton.button;
353 ino = input_get_action_but(but); // mappings[key];
354 if (ino != -1)
355 inputs[ino] = (evt.jbutton.state == SDL_PRESSED);
356 }
357 break;
358
359 case SDL_JOYHATMOTION:
360 {
361 if (evt.jhat.value != SDL_HAT_CENTERED)
362 {
363 last_sdl_action.jhat = evt.jhat.hat;
364 last_sdl_action.jhat_value = evt.jhat.value;
365 }
366 ino = input_get_action_hat(evt.jhat.hat, evt.jhat.value); // mappings[key];
367 // cleanup all hat-binded states
368 for (int i = 0; i < INPUT_COUNT; i++)
369 {
370 if (mappings[i].jhat != -1)
371 inputs[i] = false;
372 }
373
374 if (ino != -1)
375 inputs[ino] = true;
376 }
377 break;
378
379 case SDL_JOYAXISMOTION:
380 {
381 // this only used for control remapping.
382 // for actual in-game handling see below.
383 if (evt.jaxis.value > 20000 || evt.jaxis.value < -20000) // dead zone
384 {
385 last_sdl_action.jaxis = evt.jaxis.axis;
386 last_sdl_action.jaxis_value = evt.jaxis.value;
387 }
388 }
389 break;
390 }
391 }
392
393 // handle gamepad sticks
394
395 for (int i = 0; i < INPUT_COUNT; i++)
396 {
397 if (mappings[i].jaxis >= 0) // reset all mapped axises
398 {
399 inputs[i] = false;
400 }
401 }
402
403 // now get current values of all axises
404 for (int ax = 0; ax < SDL_JoystickNumAxes(joy); ax++)
405 {
406 int value = SDL_JoystickGetAxis(joy, ax);
407 ino = input_get_action_axis(ax, value); // this returns actual mapping for axis direction
408
409 if (ino != -1 && (value > 20000 || value < -20000))
410 inputs[ino] = true;
411 }
412 }
413
input_close(void)414 void input_close(void)
415 {
416 // Close if opened
417 if (SDL_JoystickGetAttached(joy))
418 {
419 SDL_JoystickClose(joy);
420 }
421 }
422
423 /*
424 void c------------------------------() {}
425 */
426
427 static const int buttons[] = {JUMPKEY, FIREKEY, STRAFEKEY, ACCEPT_BUTTON, DECLINE_BUTTON, 0};
428
buttondown(void)429 bool buttondown(void)
430 {
431 for (int i = 0; buttons[i]; i++)
432 {
433 if (inputs[buttons[i]])
434 return 1;
435 }
436
437 return 0;
438 }
439
buttonjustpushed(void)440 bool buttonjustpushed(void)
441 {
442 for (int i = 0; buttons[i]; i++)
443 {
444 if (inputs[buttons[i]] && !lastinputs[buttons[i]])
445 return 1;
446 }
447
448 return 0;
449 }
450
justpushed(int k)451 bool justpushed(int k)
452 {
453 return (inputs[k] && !lastinputs[k]);
454 }
455