summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/wolf3d/id_in.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2019-07-07 22:00:20 -0400
committerFranklin Wei <git@fwei.tk>2019-07-09 11:20:55 -0400
commit3f59fc8b771625aca9c3aefe03cf1038d8461963 (patch)
treee0623a323613baa0b0993411b38bcaed144b27ed /apps/plugins/sdl/progs/wolf3d/id_in.c
parent439a0d1d91fa040d261fc39b87278bc9f5391dcc (diff)
downloadrockbox-3f59fc8b771625aca9c3aefe03cf1038d8461963.tar.gz
rockbox-3f59fc8b771625aca9c3aefe03cf1038d8461963.zip
Wolfenstein 3-D!
This is a port of Wolf4SDL, which is derived from the original id software source release. The port runs on top of the SDL plugin runtime and is loaded as an overlay. Licensing of the game code is not an issue, as discussed below (essentially, the Debian project treats Wolf4SDL as GPLv2, with an email from John Carmack backing it up): http://forums.rockbox.org/index.php?topic=52872 Included is a copy of MAME's Yamaha OPL sound chip emulator (fmopl_gpl.c). This file was not part of the original Wolf4SDL source (which includes a non-GPL'd version), but was rather rebased from from a later MAME source which had been relicensed to GPLv2. Change-Id: I64c2ba035e0be7e2f49252f40640641416613439
Diffstat (limited to 'apps/plugins/sdl/progs/wolf3d/id_in.c')
-rw-r--r--apps/plugins/sdl/progs/wolf3d/id_in.c667
1 files changed, 667 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/wolf3d/id_in.c b/apps/plugins/sdl/progs/wolf3d/id_in.c
new file mode 100644
index 0000000000..62eec2f24d
--- /dev/null
+++ b/apps/plugins/sdl/progs/wolf3d/id_in.c
@@ -0,0 +1,667 @@
1//
2// ID Engine
3// ID_IN.c - Input Manager
4// v1.0d1
5// By Jason Blochowiak
6//
7
8//
9// This module handles dealing with the various input devices
10//
11// Depends on: Memory Mgr (for demo recording), Sound Mgr (for timing stuff),
12// User Mgr (for command line parms)
13//
14// Globals:
15// LastScan - The keyboard scan code of the last key pressed
16// LastASCII - The ASCII value of the last key pressed
17// DEBUG - there are more globals
18//
19
20#include "wl_def.h"
21
22
23/*
24=============================================================================
25
26 GLOBAL VARIABLES
27
28=============================================================================
29*/
30
31
32//
33// configuration variables
34//
35boolean MousePresent;
36boolean forcegrabmouse;
37
38
39// Global variables
40volatile boolean Keyboard[SDLK_LAST];
41volatile boolean Paused;
42volatile char LastASCII;
43volatile ScanCode LastScan;
44
45//KeyboardDef KbdDefs = {0x1d,0x38,0x47,0x48,0x49,0x4b,0x4d,0x4f,0x50,0x51};
46static KeyboardDef KbdDefs = {
47 sc_Return, // button0
48 sc_Alt, // button1
49 sc_Home, // upleft
50 sc_UpArrow, // up
51 sc_PgUp, // upright
52 sc_LeftArrow, // left
53 sc_RightArrow, // right
54 sc_End, // downleft
55 sc_DownArrow, // down
56 sc_PgDn // downright
57};
58
59static SDL_Joystick *Joystick;
60int JoyNumButtons;
61static int JoyNumHats;
62
63static bool GrabInput = false;
64
65/*
66=============================================================================
67
68 LOCAL VARIABLES
69
70=============================================================================
71*/
72byte ASCIINames[] = // Unshifted ASCII for scan codes // TODO: keypad
73{
74// 0 1 2 3 4 5 6 7 8 9 A B C D E F
75 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,8 ,9 ,0 ,0 ,0 ,13 ,0 ,0 , // 0
76 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,27 ,0 ,0 ,0 , // 1
77 ' ',0 ,0 ,0 ,0 ,0 ,0 ,39 ,0 ,0 ,'*','+',',','-','.','/', // 2
78 '0','1','2','3','4','5','6','7','8','9',0 ,';',0 ,'=',0 ,0 , // 3
79 '`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', // 4
80 'p','q','r','s','t','u','v','w','x','y','z','[',92 ,']',0 ,0 , // 5
81 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6
82 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7
83};
84byte ShiftNames[] = // Shifted ASCII for scan codes
85{
86// 0 1 2 3 4 5 6 7 8 9 A B C D E F
87 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,8 ,9 ,0 ,0 ,0 ,13 ,0 ,0 , // 0
88 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,27 ,0 ,0 ,0 , // 1
89 ' ',0 ,0 ,0 ,0 ,0 ,0 ,34 ,0 ,0 ,'*','+','<','_','>','?', // 2
90 ')','!','@','#','$','%','^','&','*','(',0 ,':',0 ,'+',0 ,0 , // 3
91 '~','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O', // 4
92 'P','Q','R','S','T','U','V','W','X','Y','Z','{','|','}',0 ,0 , // 5
93 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6
94 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7
95};
96byte SpecialNames[] = // ASCII for 0xe0 prefixed codes
97{
98// 0 1 2 3 4 5 6 7 8 9 A B C D E F
99 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 0
100 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,13 ,0 ,0 ,0 , // 1
101 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 2
102 0 ,0 ,0 ,0 ,0 ,'/',0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 3
103 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 4
104 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 5
105 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6
106 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7
107};
108
109
110static boolean IN_Started;
111
112static Direction DirTable[] = // Quick lookup for total direction
113{
114 dir_NorthWest, dir_North, dir_NorthEast,
115 dir_West, dir_None, dir_East,
116 dir_SouthWest, dir_South, dir_SouthEast
117};
118
119
120///////////////////////////////////////////////////////////////////////////
121//
122// INL_GetMouseButtons() - Gets the status of the mouse buttons from the
123// mouse driver
124//
125///////////////////////////////////////////////////////////////////////////
126static int
127INL_GetMouseButtons(void)
128{
129 int buttons = SDL_GetMouseState(NULL, NULL);
130 int middlePressed = buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE);
131 int rightPressed = buttons & SDL_BUTTON(SDL_BUTTON_RIGHT);
132 buttons &= ~(SDL_BUTTON(SDL_BUTTON_MIDDLE) | SDL_BUTTON(SDL_BUTTON_RIGHT));
133 if(middlePressed) buttons |= 1 << 2;
134 if(rightPressed) buttons |= 1 << 1;
135
136 return buttons;
137}
138
139///////////////////////////////////////////////////////////////////////////
140//
141// IN_GetJoyDelta() - Returns the relative movement of the specified
142// joystick (from +/-127)
143//
144///////////////////////////////////////////////////////////////////////////
145void IN_GetJoyDelta(int *dx,int *dy)
146{
147 if(!Joystick)
148 {
149 *dx = *dy = 0;
150 return;
151 }
152
153 SDL_JoystickUpdate();
154#ifdef _arch_dreamcast
155 int x = 0;
156 int y = 0;
157#else
158 int x = SDL_JoystickGetAxis(Joystick, 0) >> 8;
159 int y = SDL_JoystickGetAxis(Joystick, 1) >> 8;
160#endif
161
162 if(param_joystickhat != -1)
163 {
164 uint8_t hatState = SDL_JoystickGetHat(Joystick, param_joystickhat);
165 if(hatState & SDL_HAT_RIGHT)
166 x += 127;
167 else if(hatState & SDL_HAT_LEFT)
168 x -= 127;
169 if(hatState & SDL_HAT_DOWN)
170 y += 127;
171 else if(hatState & SDL_HAT_UP)
172 y -= 127;
173
174 if(x < -128) x = -128;
175 else if(x > 127) x = 127;
176
177 if(y < -128) y = -128;
178 else if(y > 127) y = 127;
179 }
180
181 *dx = x;
182 *dy = y;
183}
184
185///////////////////////////////////////////////////////////////////////////
186//
187// IN_GetJoyFineDelta() - Returns the relative movement of the specified
188// joystick without dividing the results by 256 (from +/-127)
189//
190///////////////////////////////////////////////////////////////////////////
191void IN_GetJoyFineDelta(int *dx, int *dy)
192{
193 if(!Joystick)
194 {
195 *dx = 0;
196 *dy = 0;
197 return;
198 }
199
200 SDL_JoystickUpdate();
201 int x = SDL_JoystickGetAxis(Joystick, 0);
202 int y = SDL_JoystickGetAxis(Joystick, 1);
203
204 if(x < -128) x = -128;
205 else if(x > 127) x = 127;
206
207 if(y < -128) y = -128;
208 else if(y > 127) y = 127;
209
210 *dx = x;
211 *dy = y;
212}
213
214/*
215===================
216=
217= IN_JoyButtons
218=
219===================
220*/
221
222int IN_JoyButtons()
223{
224 if(!Joystick) return 0;
225
226 SDL_JoystickUpdate();
227
228 int res = 0;
229 for(int i = 0; i < JoyNumButtons && i < 32; i++)
230 res |= SDL_JoystickGetButton(Joystick, i) << i;
231 return res;
232}
233
234boolean IN_JoyPresent()
235{
236 return Joystick != NULL;
237}
238
239static void processEvent(SDL_Event *event)
240{
241 switch (event->type)
242 {
243 // exit if the window is closed
244 case SDL_QUIT:
245 Quit(NULL);
246
247 // check for keypresses
248 case SDL_KEYDOWN:
249 {
250 if(event->key.keysym.sym==SDLK_SCROLLOCK || event->key.keysym.sym==SDLK_F12)
251 {
252 GrabInput = !GrabInput;
253 SDL_WM_GrabInput(GrabInput ? SDL_GRAB_ON : SDL_GRAB_OFF);
254 return;
255 }
256
257 LastScan = event->key.keysym.sym;
258 SDLMod mod = SDL_GetModState();
259 if(Keyboard[sc_Alt])
260 {
261 if(LastScan==SDLK_F4)
262 Quit(NULL);
263 }
264
265 if(LastScan == SDLK_KP_ENTER) LastScan = SDLK_RETURN;
266 else if(LastScan == SDLK_RSHIFT) LastScan = SDLK_LSHIFT;
267 else if(LastScan == SDLK_RALT) LastScan = SDLK_LALT;
268 else if(LastScan == SDLK_RCTRL) LastScan = SDLK_LCTRL;
269 else
270 {
271 if((mod & KMOD_NUM) == 0)
272 {
273 switch(LastScan)
274 {
275 case SDLK_KP2: LastScan = SDLK_DOWN; break;
276 case SDLK_KP4: LastScan = SDLK_LEFT; break;
277 case SDLK_KP6: LastScan = SDLK_RIGHT; break;
278 case SDLK_KP8: LastScan = SDLK_UP; break;
279 }
280 }
281 }
282
283 int sym = LastScan;
284 if(sym >= 'a' && sym <= 'z')
285 sym -= 32; // convert to uppercase
286
287 if(mod & (KMOD_SHIFT | KMOD_CAPS))
288 {
289 if(sym < lengthof(ShiftNames) && ShiftNames[sym])
290 LastASCII = ShiftNames[sym];
291 }
292 else
293 {
294 if(sym < lengthof(ASCIINames) && ASCIINames[sym])
295 LastASCII = ASCIINames[sym];
296 }
297 if(LastScan<SDLK_LAST)
298 {
299 LOGF("setting key %d", LastScan);
300 Keyboard[LastScan] = 1;
301 }
302 if(LastScan == SDLK_PAUSE)
303 Paused = true;
304 break;
305 }
306
307 case SDL_KEYUP:
308 {
309 int key = event->key.keysym.sym;
310 if(key == SDLK_KP_ENTER) key = SDLK_RETURN;
311 else if(key == SDLK_RSHIFT) key = SDLK_LSHIFT;
312 else if(key == SDLK_RALT) key = SDLK_LALT;
313 else if(key == SDLK_RCTRL) key = SDLK_LCTRL;
314 else
315 {
316 if((SDL_GetModState() & KMOD_NUM) == 0)
317 {
318 switch(key)
319 {
320 case SDLK_KP2: key = SDLK_DOWN; break;
321 case SDLK_KP4: key = SDLK_LEFT; break;
322 case SDLK_KP6: key = SDLK_RIGHT; break;
323 case SDLK_KP8: key = SDLK_UP; break;
324 }
325 }
326 }
327
328 if(key<SDLK_LAST)
329 Keyboard[key] = 0;
330 break;
331 }
332
333#if defined(GP2X)
334 case SDL_JOYBUTTONDOWN:
335 GP2X_ButtonDown(event->jbutton.button);
336 break;
337
338 case SDL_JOYBUTTONUP:
339 GP2X_ButtonUp(event->jbutton.button);
340 break;
341#endif
342 }
343}
344
345void IN_WaitAndProcessEvents()
346{
347 SDL_Event event;
348 if(!SDL_WaitEvent(&event)) return;
349 do
350 {
351 processEvent(&event);
352 }
353 while(SDL_PollEvent(&event));
354}
355
356void IN_ProcessEvents()
357{
358 SDL_Event event;
359
360 while (SDL_PollEvent(&event))
361 {
362 processEvent(&event);
363 }
364}
365
366
367///////////////////////////////////////////////////////////////////////////
368//
369// IN_Startup() - Starts up the Input Mgr
370//
371///////////////////////////////////////////////////////////////////////////
372void
373IN_Startup(void)
374{
375 if (IN_Started)
376 return;
377
378 IN_ClearKeysDown();
379
380 if(param_joystickindex >= 0 && param_joystickindex < SDL_NumJoysticks())
381 {
382 Joystick = SDL_JoystickOpen(param_joystickindex);
383 if(Joystick)
384 {
385 JoyNumButtons = SDL_JoystickNumButtons(Joystick);
386 if(JoyNumButtons > 32) JoyNumButtons = 32; // only up to 32 buttons are supported
387 JoyNumHats = SDL_JoystickNumHats(Joystick);
388 if(param_joystickhat < -1 || param_joystickhat >= JoyNumHats)
389 Quit("The joystickhat param must be between 0 and %i!", JoyNumHats - 1);
390 }
391 }
392
393 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
394
395 if(fullscreen || forcegrabmouse)
396 {
397 GrabInput = true;
398 SDL_WM_GrabInput(SDL_GRAB_ON);
399 }
400
401 // I didn't find a way to ask libSDL whether a mouse is present, yet...
402#if defined(GP2X)
403 MousePresent = false;
404#elif defined(_arch_dreamcast)
405 MousePresent = DC_MousePresent();
406#else
407 MousePresent = true;
408#endif
409
410 IN_Started = true;
411}
412
413///////////////////////////////////////////////////////////////////////////
414//
415// IN_Shutdown() - Shuts down the Input Mgr
416//
417///////////////////////////////////////////////////////////////////////////
418void
419IN_Shutdown(void)
420{
421 if (!IN_Started)
422 return;
423
424 if(Joystick)
425 SDL_JoystickClose(Joystick);
426
427 IN_Started = false;
428}
429
430///////////////////////////////////////////////////////////////////////////
431//
432// IN_ClearKeysDown() - Clears the keyboard array
433//
434///////////////////////////////////////////////////////////////////////////
435void
436IN_ClearKeysDown(void)
437{
438 LastScan = sc_None;
439 LastASCII = key_None;
440 memset ((void *) Keyboard,0,sizeof(Keyboard));
441}
442
443
444///////////////////////////////////////////////////////////////////////////
445//
446// IN_ReadControl() - Reads the device associated with the specified
447// player and fills in the control info struct
448//
449///////////////////////////////////////////////////////////////////////////
450void
451IN_ReadControl(int player,ControlInfo *info)
452{
453 word buttons;
454 int dx,dy;
455 Motion mx,my;
456
457 dx = dy = 0;
458 mx = my = motion_None;
459 buttons = 0;
460
461 IN_ProcessEvents();
462
463 if (Keyboard[KbdDefs.upleft])
464 mx = motion_Left,my = motion_Up;
465 else if (Keyboard[KbdDefs.upright])
466 mx = motion_Right,my = motion_Up;
467 else if (Keyboard[KbdDefs.downleft])
468 mx = motion_Left,my = motion_Down;
469 else if (Keyboard[KbdDefs.downright])
470 mx = motion_Right,my = motion_Down;
471
472 if (Keyboard[KbdDefs.up])
473 my = motion_Up;
474 else if (Keyboard[KbdDefs.down])
475 my = motion_Down;
476
477 if (Keyboard[KbdDefs.left])
478 mx = motion_Left;
479 else if (Keyboard[KbdDefs.right])
480 mx = motion_Right;
481
482 if (Keyboard[KbdDefs.button0])
483 buttons += 1 << 0;
484 if (Keyboard[KbdDefs.button1])
485 buttons += 1 << 1;
486
487 dx = mx * 127;
488 dy = my * 127;
489
490 info->x = dx;
491 info->xaxis = mx;
492 info->y = dy;
493 info->yaxis = my;
494 info->button0 = (buttons & (1 << 0)) != 0;
495 info->button1 = (buttons & (1 << 1)) != 0;
496 info->button2 = (buttons & (1 << 2)) != 0;
497 info->button3 = (buttons & (1 << 3)) != 0;
498 info->dir = DirTable[((my + 1) * 3) + (mx + 1)];
499}
500
501///////////////////////////////////////////////////////////////////////////
502//
503// IN_WaitForKey() - Waits for a scan code, then clears LastScan and
504// returns the scan code
505//
506///////////////////////////////////////////////////////////////////////////
507ScanCode
508IN_WaitForKey(void)
509{
510 ScanCode result;
511
512 while ((result = LastScan)==0)
513 IN_WaitAndProcessEvents();
514 LastScan = 0;
515 return(result);
516}
517
518///////////////////////////////////////////////////////////////////////////
519//
520// IN_WaitForASCII() - Waits for an ASCII char, then clears LastASCII and
521// returns the ASCII value
522//
523///////////////////////////////////////////////////////////////////////////
524char
525IN_WaitForASCII(void)
526{
527 char result;
528
529 while ((result = LastASCII)==0)
530 IN_WaitAndProcessEvents();
531 LastASCII = '\0';
532 return(result);
533}
534
535///////////////////////////////////////////////////////////////////////////
536//
537// IN_Ack() - waits for a button or key press. If a button is down, upon
538// calling, it must be released for it to be recognized
539//
540///////////////////////////////////////////////////////////////////////////
541
542boolean btnstate[NUMBUTTONS];
543
544void IN_StartAck(void)
545{
546 IN_ProcessEvents();
547//
548// get initial state of everything
549//
550 IN_ClearKeysDown();
551 memset(btnstate, 0, sizeof(btnstate));
552
553 int buttons = IN_JoyButtons() << 4;
554
555 if(MousePresent)
556 buttons |= IN_MouseButtons();
557
558 for(int i = 0; i < NUMBUTTONS; i++, buttons >>= 1)
559 if(buttons & 1)
560 btnstate[i] = true;
561}
562
563
564boolean IN_CheckAck (void)
565{
566 IN_ProcessEvents();
567//
568// see if something has been pressed
569//
570 if(LastScan)
571 return true;
572
573 int buttons = IN_JoyButtons() << 4;
574
575 if(MousePresent)
576 buttons |= IN_MouseButtons();
577
578 for(int i = 0; i < NUMBUTTONS; i++, buttons >>= 1)
579 {
580 if(buttons & 1)
581 {
582 if(!btnstate[i])
583 {
584 // Wait until button has been released
585 do
586 {
587 IN_WaitAndProcessEvents();
588 buttons = IN_JoyButtons() << 4;
589
590 if(MousePresent)
591 buttons |= IN_MouseButtons();
592 }
593 while(buttons & (1 << i));
594
595 return true;
596 }
597 }
598 else
599 btnstate[i] = false;
600 }
601
602 return false;
603}
604
605
606void IN_Ack (void)
607{
608 IN_StartAck ();
609
610 do
611 {
612 IN_WaitAndProcessEvents();
613 }
614 while(!IN_CheckAck ());
615}
616
617
618///////////////////////////////////////////////////////////////////////////
619//
620// IN_UserInput() - Waits for the specified delay time (in ticks) or the
621// user pressing a key or a mouse button. If the clear flag is set, it
622// then either clears the key or waits for the user to let the mouse
623// button up.
624//
625///////////////////////////////////////////////////////////////////////////
626boolean IN_UserInput(longword delay)
627{
628 longword lasttime;
629
630 lasttime = GetTimeCount();
631 IN_StartAck ();
632 do
633 {
634 IN_ProcessEvents();
635 if (IN_CheckAck())
636 return true;
637 SDL_Delay(5);
638 } while (GetTimeCount() - lasttime < delay);
639 return(false);
640}
641
642//===========================================================================
643
644/*
645===================
646=
647= IN_MouseButtons
648=
649===================
650*/
651int IN_MouseButtons (void)
652{
653 if (MousePresent)
654 return INL_GetMouseButtons();
655 else
656 return 0;
657}
658
659bool IN_IsInputGrabbed()
660{
661 return GrabInput;
662}
663
664void IN_CenterMouse()
665{
666 SDL_WarpMouse(screenWidth / 2, screenHeight / 2);
667}