summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/wolf3d/id_in.c
diff options
context:
space:
mode:
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}