1 /*
2 Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 #if PLATFORM_DOS
25 #include <conio.h>
26 #include <dos.h>
27 #include <i86.h>
28 #endif
29
30 #if USE_SDL
31 #include "SDL.h"
32 #endif
33
34 #include "rt_main.h"
35 #include "rt_spbal.h"
36 #include "rt_def.h"
37 #include "rt_in.h"
38 #include "_rt_in.h"
39 #include "isr.h"
40 #include "rt_util.h"
41 #include "rt_swift.h"
42 #include "rt_vh_a.h"
43 #include "rt_cfg.h"
44 #include "rt_msg.h"
45 #include "rt_playr.h"
46 #include "rt_net.h"
47 #include "rt_com.h"
48 #include "rt_cfg.h"
49 //MED
50 #include "memcheck.h"
51 #include "keyb.h"
52
53 #define MAXMESSAGELENGTH (COM_MAXTEXTSTRINGLENGTH-1)
54
55 //****************************************************************************
56 //
57 // GLOBALS
58 //
59 //****************************************************************************]
60
61 //
62 // Used by menu routines that need to wait for a button release.
63 // Sometimes the mouse driver misses an interrupt, so you can't wait for
64 // a button to be released. Instead, you must ignore any buttons that
65 // are pressed.
66 //
67 int IgnoreMouse = 0;
68
69 // configuration variables
70 //
71 boolean SpaceBallPresent;
72 boolean CybermanPresent;
73 boolean AssassinPresent;
74 boolean MousePresent;
75 boolean JoysPresent[MaxJoys];
76 boolean JoyPadPresent = 0;
77
78 // Global variables
79 //
80 boolean Paused;
81 char LastASCII;
82 volatile int LastScan;
83
84 byte Joy_xb,
85 Joy_yb,
86 Joy_xs,
87 Joy_ys;
88 word Joy_x,
89 Joy_y;
90
91
92 int LastLetter = 0;
93 char LetterQueue[MAXLETTERS];
94 ModemMessage MSG;
95
96
97 #if USE_SDL
98 static SDL_Joystick* sdl_joysticks[MaxJoys];
99 static int sdl_mouse_delta_x = 0;
100 static int sdl_mouse_delta_y = 0;
101 static word sdl_mouse_button_mask = 0;
102 static int sdl_total_sticks = 0;
103 static word *sdl_stick_button_state = NULL;
104 static word sdl_sticks_joybits = 0;
105 static int sdl_mouse_grabbed = 0;
106 static unsigned int scancodes[SDLK_LAST];
107 #endif
108
109
110 // 'q','w','e','r','t','y','u','i','o','p','[',']','\\', 0 ,'a','s',
111
112 const char ScanChars[128] = // Scan code names with single chars
113 {
114 0 , 0 ,'1','2','3','4','5','6','7','8','9','0','-','=', 0 , 0 ,
115 'q','w','e','r','t','y','u','i','o','p','[',']', 0 , 0 ,'a','s',
116 'd','f','g','h','j','k','l',';','\'','`', 0 ,'\\','z','x','c','v',
117 'b','n','m',',','.','/', 0 , 0 , 0 ,' ', 0 , 0 , 0 , 0 , 0 , 0 ,
118 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,'-', 0 ,'5', 0 ,'+', 0 ,
119 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
120 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
121 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
122 };
123
124 const char ShiftedScanChars[128] = // Shifted Scan code names with single chars
125 {
126 0 , 0 ,'!','@','#','$','%','^','&','*','(',')','_','+', 0 , 0 ,
127 'Q','W','E','R','T','Y','U','I','O','P','{','}', 0 , 0 ,'A','S',
128 'D','F','G','H','J','K','L',':','"','~', 0 ,'|','Z','X','C','V',
129 'B','N','M','<','>','?', 0 , 0 , 0 ,' ', 0 , 0 , 0 , 0 , 0 , 0 ,
130 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,'-', 0 ,'5', 0 ,'+', 0 ,
131 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
132 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
133 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
134 };
135
136 #if 0
137 const char ScanChars[128] = // Scan code names with single chars
138 {
139 '?','?','1','2','3','4','5','6','7','8','9','0','-','+','?','?',
140 'Q','W','E','R','T','Y','U','I','O','P','[',']','|','?','A','S',
141 'D','F','G','H','J','K','L',';','\'','?','?','?','Z','X','C','V',
142 'B','N','M',',','.','/','?','?','?',' ','?','?','?','?','?','?',
143 '?','?','?','?','?','?','?','?','?','?','-','?','5','?','+','?',
144 '?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?',
145 '?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?',
146 '?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?'
147 };
148 #endif
149
150
151
152 //****************************************************************************
153 //
154 // LOCALS
155 //
156 //****************************************************************************]
157
158 KeyboardDef KbdDefs = {0x1d,0x38,0x47,0x48,0x49,0x4b,0x4d,0x4f,0x50,0x51};
159 JoystickDef JoyDefs[MaxJoys];
160 ControlType Controls[MAXPLAYERS];
161
162
163 static boolean IN_Started;
164
165 static Direction DirTable[] = // Quick lookup for total direction
166 {
167 dir_NorthWest, dir_North, dir_NorthEast,
168 dir_West, dir_None, dir_East,
169 dir_SouthWest, dir_South, dir_SouthEast
170 };
171
172 int (far *function_ptr)();
173
174 static char *ParmStrings[] = {"nojoys","nomouse","spaceball","cyberman","assassin",NULL};
175
176
177 #if USE_SDL
178 #define sdldebug printf
179
sdl_mouse_button_filter(SDL_Event const * event)180 static int sdl_mouse_button_filter(SDL_Event const *event)
181 {
182 /*
183 * What DOS games expect:
184 * 0 left button pressed if 1
185 * 1 right button pressed if 1
186 * 2 middle button pressed if 1
187 *
188 * (That is, this is what Int 33h (AX=0x05) returns...)
189 */
190
191 Uint8 bmask = SDL_GetMouseState(NULL, NULL);
192 sdl_mouse_button_mask = 0; /* this is a static var. */
193 if (bmask & SDL_BUTTON_LMASK) sdl_mouse_button_mask |= 1;
194 if (bmask & SDL_BUTTON_RMASK) sdl_mouse_button_mask |= 2;
195 if (bmask & SDL_BUTTON_MMASK) sdl_mouse_button_mask |= 4;
196 return(0);
197 } /* sdl_mouse_up_filter */
198
199
sdl_mouse_motion_filter(SDL_Event const * event)200 static int sdl_mouse_motion_filter(SDL_Event const *event)
201 {
202 static int mouse_x = 0;
203 static int mouse_y = 0;
204 int mouse_relative_x = 0;
205 int mouse_relative_y = 0;
206
207 if (event->type == SDL_JOYBALLMOTION)
208 {
209 mouse_relative_x = event->jball.xrel/100;
210 mouse_relative_y = event->jball.yrel/100;
211 mouse_x += mouse_relative_x;
212 mouse_y += mouse_relative_y;
213 } /* if */
214 else
215 {
216 if (sdl_mouse_grabbed)
217 {
218 mouse_relative_x = event->motion.xrel;
219 mouse_relative_y = event->motion.yrel;
220 mouse_x += mouse_relative_x;
221 mouse_y += mouse_relative_y;
222 } /* if */
223 else
224 {
225 mouse_relative_x = event->motion.x - mouse_x;
226 mouse_relative_y = event->motion.y - mouse_y;
227 mouse_x = event->motion.x;
228 mouse_y = event->motion.y;
229 } /* else */
230 } /* else */
231
232 #if 0
233 if (mouse_x < 0) mouse_x = 0;
234 if (mouse_x > surface->w) mouse_x = surface->w;
235 if (mouse_y < 0) mouse_y = 0;
236 if (mouse_y > surface->h) mouse_y = surface->h;
237 #endif
238
239 /* set static vars... */
240 sdl_mouse_delta_x += mouse_relative_x;
241 sdl_mouse_delta_y += mouse_relative_y;
242
243 return(0);
244 } /* sdl_mouse_motion_filter */
245
246
247 /**
248 * Attempt to flip the video surface to fullscreen or windowed mode.
249 * Attempts to maintain the surface's state, but makes no guarantee
250 * that pointers (i.e., the surface's pixels field) will be the same
251 * after this call.
252 *
253 * Caveats: Your surface pointers will be changing; if you have any other
254 * copies laying about, they are invalidated.
255 *
256 * Do NOT call this from an SDL event filter on Windows. You can
257 * call it based on the return values from SDL_PollEvent, etc, just
258 * not during the function you passed to SDL_SetEventFilter().
259 *
260 * Thread safe? Likely not.
261 *
262 * @param surface pointer to surface ptr to toggle. May be different
263 * pointer on return. MAY BE NULL ON RETURN IF FAILURE!
264 * @param flags pointer to flags to set on surface. The value pointed
265 * to will be XOR'd with SDL_FULLSCREEN before use. Actual
266 * flags set will be filled into pointer. Contents are
267 * undefined on failure. Can be NULL, in which case the
268 * surface's current flags are used.
269 * @return non-zero on success, zero on failure.
270 */
attempt_fullscreen_toggle(SDL_Surface ** surface,Uint32 * flags)271 static int attempt_fullscreen_toggle(SDL_Surface **surface, Uint32 *flags)
272 {
273 long framesize = 0;
274 void *pixels = NULL;
275 SDL_Rect clip;
276 Uint32 tmpflags = 0;
277 int w = 0;
278 int h = 0;
279 int bpp = 0;
280 int grabmouse = (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON);
281 int showmouse = SDL_ShowCursor(-1);
282 SDL_Color *palette = NULL;
283 int ncolors = 0;
284
285 /*
286 sdldebug("attempting to toggle fullscreen flag...");
287 */
288
289 if ( (!surface) || (!(*surface)) ) /* don't try if there's no surface. */
290 {
291 /*
292 sdldebug("Null surface (?!). Not toggling fullscreen flag.");
293 */
294 return(0);
295 } /* if */
296
297 if (SDL_WM_ToggleFullScreen(*surface))
298 {
299 /*
300 sdldebug("SDL_WM_ToggleFullScreen() seems to work on this system.");
301 */
302 if (flags)
303 *flags ^= SDL_FULLSCREEN;
304 return(1);
305 } /* if */
306
307 if ( !(SDL_GetVideoInfo()->wm_available) )
308 {
309 /*
310 sdldebug("No window manager. Not toggling fullscreen flag.");
311 */
312 return(0);
313 } /* if */
314
315 /*
316 sdldebug("toggling fullscreen flag The Hard Way...");
317 */
318 tmpflags = (*surface)->flags;
319 w = (*surface)->w;
320 h = (*surface)->h;
321 bpp = (*surface)->format->BitsPerPixel;
322
323 if (flags == NULL) /* use the surface's flags. */
324 flags = &tmpflags;
325
326 SDL_GetClipRect(*surface, &clip);
327
328 /* save the contents of the screen. */
329 if ( (!(tmpflags & SDL_OPENGL)) && (!(tmpflags & SDL_OPENGLBLIT)) )
330 {
331 framesize = (w * h) * ((*surface)->format->BytesPerPixel);
332 pixels = malloc(framesize);
333 if (pixels == NULL)
334 return(0);
335 memcpy(pixels, (*surface)->pixels, framesize);
336 } /* if */
337
338 #if 1
339 STUB_FUNCTION; /* palette is broken. FIXME !!! --ryan. */
340 #else
341 if ((*surface)->format->palette != NULL)
342 {
343 ncolors = (*surface)->format->palette->ncolors;
344 palette = malloc(ncolors * sizeof (SDL_Color));
345 if (palette == NULL)
346 {
347 free(pixels);
348 return(0);
349 } /* if */
350 memcpy(palette, (*surface)->format->palette->colors,
351 ncolors * sizeof (SDL_Color));
352 } /* if */
353 #endif
354
355 if (grabmouse)
356 SDL_WM_GrabInput(SDL_GRAB_OFF);
357
358 SDL_ShowCursor(1);
359
360 *surface = SDL_SetVideoMode(w, h, bpp, (*flags) ^ SDL_FULLSCREEN);
361
362 if (*surface != NULL)
363 *flags ^= SDL_FULLSCREEN;
364
365 else /* yikes! Try to put it back as it was... */
366 {
367 *surface = SDL_SetVideoMode(w, h, bpp, tmpflags);
368 if (*surface == NULL) /* completely screwed. */
369 {
370 if (pixels != NULL)
371 free(pixels);
372 if (palette != NULL)
373 free(palette);
374 return(0);
375 } /* if */
376 } /* if */
377
378 /* Unfortunately, you lose your OpenGL image until the next frame... */
379
380 if (pixels != NULL)
381 {
382 memcpy((*surface)->pixels, pixels, framesize);
383 free(pixels);
384 } /* if */
385
386 #if 1
387 STUB_FUNCTION; /* palette is broken. FIXME !!! --ryan. */
388 #else
389 if (palette != NULL)
390 {
391 /* !!! FIXME : No idea if that flags param is right. */
392 SDL_SetPalette(*surface, SDL_LOGPAL, palette, 0, ncolors);
393 free(palette);
394 } /* if */
395 #endif
396
397 SDL_SetClipRect(*surface, &clip);
398
399 if (grabmouse)
400 SDL_WM_GrabInput(SDL_GRAB_ON);
401
402 SDL_ShowCursor(showmouse);
403
404 #if 0
405 STUB_FUNCTION; /* pull this out of buildengine/sdl_driver.c ... */
406 output_surface_info(*surface);
407 #endif
408
409 return(1);
410 } /* attempt_fullscreen_toggle */
411
412
413 /*
414 * The windib driver can't alert us to the keypad enter key, which
415 * Ken's code depends on heavily. It sends it as the same key as the
416 * regular return key. These users will have to hit SHIFT-ENTER,
417 * which we check for explicitly, and give the engine a keypad enter
418 * enter event.
419 */
handle_keypad_enter_hack(const SDL_Event * event)420 static int handle_keypad_enter_hack(const SDL_Event *event)
421 {
422 static int kp_enter_hack = 0;
423 int retval = 0;
424
425 if (event->key.keysym.sym == SDLK_RETURN)
426 {
427 if (event->key.state == SDL_PRESSED)
428 {
429 if (event->key.keysym.mod & KMOD_SHIFT)
430 {
431 kp_enter_hack = 1;
432 retval = scancodes[SDLK_KP_ENTER];
433 } /* if */
434 } /* if */
435
436 else /* key released */
437 {
438 if (kp_enter_hack)
439 {
440 kp_enter_hack = 0;
441 retval = scancodes[SDLK_KP_ENTER];
442 } /* if */
443 } /* if */
444 } /* if */
445
446 return(retval);
447 } /* handle_keypad_enter_hack */
448
449
sdl_key_filter(const SDL_Event * event)450 static int sdl_key_filter(const SDL_Event *event)
451 {
452 int k;
453 int keyon;
454 int strippedkey;
455 SDL_GrabMode grab_mode = SDL_GRAB_OFF;
456 int extended;
457
458 if ( (event->key.keysym.sym == SDLK_g) &&
459 (event->key.state == SDL_PRESSED) &&
460 (event->key.keysym.mod & KMOD_CTRL) )
461 {
462 sdl_mouse_grabbed = ((sdl_mouse_grabbed) ? 0 : 1);
463 if (sdl_mouse_grabbed)
464 grab_mode = SDL_GRAB_ON;
465 SDL_WM_GrabInput(grab_mode);
466 return(0);
467 } /* if */
468
469 else if ( ( (event->key.keysym.sym == SDLK_RETURN) ||
470 (event->key.keysym.sym == SDLK_KP_ENTER) ) &&
471 (event->key.state == SDL_PRESSED) &&
472 (event->key.keysym.mod & KMOD_ALT) )
473 {
474 SDL_Surface *surface = SDL_GetVideoSurface();
475 if (surface != NULL)
476 {
477 Uint32 sdl_flags = surface->flags;
478 attempt_fullscreen_toggle(&surface, &sdl_flags);
479 } /* if */
480 return(0);
481 } /* if */
482
483 k = handle_keypad_enter_hack(event);
484 if (!k)
485 {
486 k = scancodes[event->key.keysym.sym];
487 if (!k) /* No DOS equivalent defined. */
488 return(0);
489 } /* if */
490
491 if (event->key.state == SDL_RELEASED)
492 k += 128; /* +128 signifies that the key is released in DOS. */
493
494 if (event->key.keysym.sym == SDLK_PAUSE)
495 PausePressed = true;
496
497 else if (event->key.keysym.sym == SDLK_SCROLLOCK)
498 PanicPressed = true;
499
500 else
501 {
502 extended = ((k & 0xFF00) >> 8);
503
504 keyon = k & 0x80;
505 strippedkey = k & 0x7f;
506
507 if (extended != 0)
508 {
509 KeyboardQueue[ Keytail ] = extended;
510 Keytail = ( Keytail + 1 )&( KEYQMAX - 1 );
511 k = scancodes[event->key.keysym.sym] & 0xFF;
512 if (event->key.state == SDL_RELEASED)
513 k += 128; /* +128 signifies that the key is released in DOS. */
514 }
515
516 if (keyon) // Up event
517 Keystate[strippedkey]=0;
518 else // Down event
519 {
520 Keystate[strippedkey]=1;
521 LastScan = k;
522 }
523
524 KeyboardQueue[ Keytail ] = k;
525 Keytail = ( Keytail + 1 )&( KEYQMAX - 1 );
526 }
527
528 return(0);
529 } /* sdl_key_filter */
530
531 #ifdef DC
532 /* emulate keyboard */
sdl_joybutton_filter(const SDL_Event * event)533 int sdl_joybutton_filter(const SDL_Event *event)
534 {
535 SDL_Event ev;
536
537 /* start->esc */
538 if (event->jbutton.button != 4) return 1;
539
540 if (event->type == SDL_JOYBUTTONDOWN) {
541 ev.type = SDL_KEYDOWN;
542 } else {
543 ev.type = SDL_KEYUP;
544 }
545 ev.key.which = 0;
546 ev.key.state = event->jbutton.state;
547 ev.key.keysym.sym = SDLK_ESCAPE;
548
549 return sdl_key_filter(&ev);
550 }
551 #endif
552
553
root_sdl_event_filter(const SDL_Event * event)554 static int root_sdl_event_filter(const SDL_Event *event)
555 {
556 switch (event->type)
557 {
558 case SDL_KEYUP:
559 case SDL_KEYDOWN:
560 return(sdl_key_filter(event));
561 #ifdef DC
562 case SDL_JOYBUTTONDOWN:
563 case SDL_JOYBUTTONUP:
564 return(sdl_joybutton_filter(event));
565 #endif
566 case SDL_JOYBALLMOTION:
567 case SDL_MOUSEMOTION:
568 return(sdl_mouse_motion_filter(event));
569 case SDL_MOUSEBUTTONUP:
570 case SDL_MOUSEBUTTONDOWN:
571 return(sdl_mouse_button_filter(event));
572 case SDL_QUIT:
573 /* !!! rcg TEMP */
574 fprintf(stderr, "\n\n\nSDL_QUIT!\n\n\n");
575 SDL_Quit();
576 exit(42);
577 } /* switch */
578
579 return(1);
580 } /* root_sdl_event_filter */
581
582
sdl_handle_events(void)583 static void sdl_handle_events(void)
584 {
585 SDL_Event event;
586 while (SDL_PollEvent(&event))
587 root_sdl_event_filter(&event);
588 } /* sdl_handle_events */
589 #endif
590
591
592 //******************************************************************************
593 //
594 // IN_PumpEvents () - Let platform process an event queue.
595 //
596 //******************************************************************************
IN_PumpEvents(void)597 void IN_PumpEvents(void)
598 {
599 #if USE_SDL
600 sdl_handle_events();
601
602 #elif PLATFORM_DOS
603 /* no-op. */
604
605 #else
606 #error please define for your platform.
607 #endif
608 }
609
610
611
612 //******************************************************************************
613 //
614 // INL_GetMouseDelta () - Gets the amount that the mouse has moved from the
615 // mouse driver
616 //
617 //******************************************************************************
618
INL_GetMouseDelta(int * x,int * y)619 void INL_GetMouseDelta(int *x,int *y)
620 {
621 IN_PumpEvents();
622
623 #ifdef PLATFORM_DOS
624 union REGS inregs;
625 union REGS outregs;
626
627 if (!MousePresent)
628 *x = *y = 0;
629 else
630 {
631 inregs.w.ax = MDelta;
632 int386 (MouseInt, &inregs, &outregs);
633 *x = outregs.w.cx;
634 *y = outregs.w.dx;
635 }
636
637 #elif USE_SDL
638 #if 1
639 SDL_GetRelativeMouseState(x,y);
640 #else
641 *x = sdl_mouse_delta_x;
642 *y = sdl_mouse_delta_y;
643
644 sdl_mouse_delta_x = sdl_mouse_delta_y = 0;
645 #endif
646
647 #else
648 #error please define for your platform.
649 #endif
650 }
651
652
653
654 //******************************************************************************
655 //
656 // IN_GetMouseButtons () - Gets the status of the mouse buttons from the
657 // mouse driver
658 //
659 //******************************************************************************
660
IN_GetMouseButtons(void)661 word IN_GetMouseButtons
662 (
663 void
664 )
665
666 {
667 int buttons = 0;
668 #if USE_SDL
669 int bmask, i;
670 const static int tbl[] = {SDL_BUTTON_LEFT,SDL_BUTTON_RIGHT,SDL_BUTTON_MIDDLE,SDL_BUTTON_WHEELUP,SDL_BUTTON_WHEELDOWN};
671 #endif
672
673 IN_PumpEvents();
674
675 #if USE_SDL
676 #if 1
677 bmask = SDL_GetMouseState(NULL,NULL);
678 for(i=0;i<sizeof(tbl);i++) {
679 if (bmask & SDL_BUTTON(tbl[i])) buttons|=1<<i;
680 }
681 #else
682 buttons = sdl_mouse_button_mask;
683 #endif
684
685 #elif PLATFORM_DOS
686 union REGS inregs;
687 union REGS outregs;
688
689 if (!MousePresent || !mouseenabled)
690 return (0);
691
692 inregs.w.ax = MButtons;
693 int386 (MouseInt, &inregs, &outregs);
694
695 buttons = outregs.w.bx;
696
697 #else
698 # error please define for your platform.
699 #endif
700
701 // Used by menu routines that need to wait for a button release.
702 // Sometimes the mouse driver misses an interrupt, so you can't wait for
703 // a button to be released. Instead, you must ignore any buttons that
704 // are pressed.
705
706 IgnoreMouse &= buttons;
707 buttons &= ~IgnoreMouse;
708
709 return (buttons);
710 }
711
712
713 //******************************************************************************
714 //
715 // IN_IgnoreMouseButtons () -
716 // Tells the mouse to ignore the currently pressed buttons.
717 //
718 //******************************************************************************
719
IN_IgnoreMouseButtons(void)720 void IN_IgnoreMouseButtons
721 (
722 void
723 )
724
725 {
726 IgnoreMouse |= IN_GetMouseButtons();
727 }
728
729
730 //******************************************************************************
731 //
732 // IN_GetJoyAbs () - Reads the absolute position of the specified joystick
733 //
734 //******************************************************************************
735
IN_GetJoyAbs(word joy,word * xp,word * yp)736 void IN_GetJoyAbs (word joy, word *xp, word *yp)
737 {
738 Joy_x = Joy_y = 0;
739 Joy_xs = joy? 2 : 0; // Find shift value for x axis
740 Joy_xb = 1 << Joy_xs; // Use shift value to get x bit mask
741 Joy_ys = joy? 3 : 1; // Do the same for y axis
742 Joy_yb = 1 << Joy_ys;
743
744 #ifdef DOS
745 JoyStick_Vals ();
746 #else
747 if (joy < sdl_total_sticks)
748 {
749 /* in SDL, value return -32768<->32767 but needs 0-5000 */
750 Joy_x = SDL_JoystickGetAxis (sdl_joysticks[joy], 0)+128;
751 Joy_y = SDL_JoystickGetAxis (sdl_joysticks[joy], 1)+128;
752 } else {
753 Joy_x = 0;
754 Joy_y = 0;
755 }
756 // printf("IN_GetJoyAbs:%d %d\n",Joy_x,Joy_y);
757 #endif
758
759 *xp = Joy_x;
760 *yp = Joy_y;
761 }
762
JoyStick_Vals(void)763 void JoyStick_Vals (void)
764 {
765
766 }
767
768
769 //******************************************************************************
770 //
771 // INL_GetJoyDelta () - Returns the relative movement of the specified
772 // joystick (from +/-127)
773 //
774 //******************************************************************************
775
INL_GetJoyDelta(word joy,int * dx,int * dy)776 void INL_GetJoyDelta (word joy, int *dx, int *dy)
777 {
778 word x, y;
779 JoystickDef *def;
780 static longword lasttime;
781
782 IN_GetJoyAbs (joy, &x, &y);
783 def = JoyDefs + joy;
784
785 if (x < def->threshMinX)
786 {
787 if (x < def->joyMinX)
788 x = def->joyMinX;
789
790 x = -(x - def->threshMinX);
791 x *= def->joyMultXL;
792 x >>= JoyScaleShift;
793 *dx = (x > 127)? -127 : -x;
794 }
795 else if (x > def->threshMaxX)
796 {
797 if (x > def->joyMaxX)
798 x = def->joyMaxX;
799
800 x = x - def->threshMaxX;
801 x *= def->joyMultXH;
802 x >>= JoyScaleShift;
803 *dx = (x > 127)? 127 : x;
804 }
805 else
806 *dx = 0;
807
808 if (y < def->threshMinY)
809 {
810 if (y < def->joyMinY)
811 y = def->joyMinY;
812
813 y = -(y - def->threshMinY);
814 y *= def->joyMultYL;
815 y >>= JoyScaleShift;
816 *dy = (y > 127)? -127 : -y;
817 }
818 else if (y > def->threshMaxY)
819 {
820 if (y > def->joyMaxY)
821 y = def->joyMaxY;
822
823 y = y - def->threshMaxY;
824 y *= def->joyMultYH;
825 y >>= JoyScaleShift;
826 *dy = (y > 127)? 127 : y;
827 }
828 else
829 *dy = 0;
830
831 lasttime = GetTicCount();
832 }
833
834
835
836 //******************************************************************************
837 //
838 // INL_GetJoyButtons () - Returns the button status of the specified
839 // joystick
840 //
841 //******************************************************************************
842
INL_GetJoyButtons(word joy)843 word INL_GetJoyButtons (word joy)
844 {
845 word result = 0;
846
847 #if USE_SDL
848 if (joy < sdl_total_sticks)
849 result = sdl_stick_button_state[joy];
850
851 #elif PLATFORM_DOS
852 result = inp (0x201); // Get all the joystick buttons
853 result >>= joy? 6 : 4; // Shift into bits 0-1
854 result &= 3; // Mask off the useless bits
855 result ^= 3;
856
857 #else
858 #error please define for your platform.
859 #endif
860
861 return result;
862 }
863
864 #if 0
865 //******************************************************************************
866 //
867 // IN_GetJoyButtonsDB () - Returns the de-bounced button status of the
868 // specified joystick
869 //
870 //******************************************************************************
871
872 word IN_GetJoyButtonsDB (word joy)
873 {
874 longword lasttime;
875 word result1,result2;
876
877 do
878 {
879 result1 = INL_GetJoyButtons (joy);
880 lasttime = GetTicCount();
881 while (GetTicCount() == lasttime)
882 ;
883 result2 = INL_GetJoyButtons (joy);
884 } while (result1 != result2);
885
886 return(result1);
887 }
888 #endif
889
890 //******************************************************************************
891 //
892 // INL_StartMouse () - Detects and sets up the mouse
893 //
894 //******************************************************************************
895
INL_StartMouse(void)896 boolean INL_StartMouse (void)
897 {
898
899 boolean retval = false;
900
901 #if USE_SDL
902 /* no-op. */
903 retval = true;
904
905 #elif PLATFORM_DOS
906 union REGS inregs;
907 union REGS outregs;
908
909 inregs.w.ax = 0;
910 int386 (MouseInt, &inregs, &outregs);
911
912 retval = ((outregs.w.ax == 0xffff) ? true : false);
913
914 #else
915 #error please define your platform.
916 #endif
917
918 return (retval);
919 }
920
921
922
923 //******************************************************************************
924 //
925 // INL_SetJoyScale () - Sets up scaling values for the specified joystick
926 //
927 //******************************************************************************
928
INL_SetJoyScale(word joy)929 void INL_SetJoyScale (word joy)
930 {
931 JoystickDef *def;
932
933 def = &JoyDefs[joy];
934 def->joyMultXL = JoyScaleMax / (def->threshMinX - def->joyMinX);
935 def->joyMultXH = JoyScaleMax / (def->joyMaxX - def->threshMaxX);
936 def->joyMultYL = JoyScaleMax / (def->threshMinY - def->joyMinY);
937 def->joyMultYH = JoyScaleMax / (def->joyMaxY - def->threshMaxY);
938 }
939
940
941
942 //******************************************************************************
943 //
944 // IN_SetupJoy () - Sets up thresholding values and calls INL_SetJoyScale()
945 // to set up scaling values
946 //
947 //******************************************************************************
948
IN_SetupJoy(word joy,word minx,word maxx,word miny,word maxy)949 void IN_SetupJoy (word joy, word minx, word maxx, word miny, word maxy)
950 {
951 word d,r;
952 JoystickDef *def;
953
954 def = &JoyDefs[joy];
955
956 def->joyMinX = minx;
957 def->joyMaxX = maxx;
958 r = maxx - minx;
959 d = r / 3;
960 def->threshMinX = ((r / 2) - d) + minx;
961 def->threshMaxX = ((r / 2) + d) + minx;
962
963 def->joyMinY = miny;
964 def->joyMaxY = maxy;
965 r = maxy - miny;
966 d = r / 3;
967 def->threshMinY = ((r / 2) - d) + miny;
968 def->threshMaxY = ((r / 2) + d) + miny;
969
970 INL_SetJoyScale (joy);
971 }
972
973
974 //******************************************************************************
975 //
976 // INL_StartJoy () - Detects & auto-configures the specified joystick
977 // The auto-config assumes the joystick is centered
978 //
979 //******************************************************************************
980
981
INL_StartJoy(word joy)982 boolean INL_StartJoy (word joy)
983 {
984 word x,y;
985
986 #if USE_SDL
987 if (!SDL_WasInit(SDL_INIT_JOYSTICK))
988 {
989 SDL_Init(SDL_INIT_JOYSTICK);
990 sdl_total_sticks = SDL_NumJoysticks();
991 if (sdl_total_sticks > MaxJoys) sdl_total_sticks = MaxJoys;
992
993 if ((sdl_stick_button_state == NULL) && (sdl_total_sticks > 0))
994 {
995 sdl_stick_button_state = (word *) malloc(sizeof (word) * sdl_total_sticks);
996 if (sdl_stick_button_state == NULL)
997 SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
998 else
999 memset(sdl_stick_button_state, '\0', sizeof (word) * sdl_total_sticks);
1000 }
1001 SDL_JoystickEventState(SDL_ENABLE);
1002 }
1003
1004 if (joy >= sdl_total_sticks) return (false);
1005 sdl_joysticks[joy] = SDL_JoystickOpen (joy);
1006 if (SDL_JoystickNumAxes(sdl_joysticks[joy])<2) {
1007 SDL_JoystickClose(sdl_joysticks[joy]);
1008 return false;
1009 }
1010 #endif
1011
1012 IN_GetJoyAbs (joy, &x, &y);
1013
1014 if
1015 (
1016 ((x == 0) || (x > MaxJoyValue - 10))
1017 || ((y == 0) || (y > MaxJoyValue - 10))
1018 )
1019 return(false);
1020 else
1021 {
1022 IN_SetupJoy (joy, 0, x * 2, 0, y * 2);
1023 return (true);
1024 }
1025 }
1026
1027
1028
1029 //******************************************************************************
1030 //
1031 // INL_ShutJoy() - Cleans up the joystick stuff
1032 //
1033 //******************************************************************************
1034
INL_ShutJoy(word joy)1035 void INL_ShutJoy (word joy)
1036 {
1037 JoysPresent[joy] = false;
1038 #ifndef DOS
1039 if (joy < sdl_total_sticks) SDL_JoystickClose (sdl_joysticks[joy]);
1040 #endif
1041 }
1042
1043
1044
1045 //******************************************************************************
1046 //
1047 // IN_Startup() - Starts up the Input Mgr
1048 //
1049 //******************************************************************************
1050
1051
IN_Startup(void)1052 void IN_Startup (void)
1053 {
1054 boolean checkjoys,
1055 checkmouse,
1056 checkcyberman,
1057 checkspaceball,
1058 swiftstatus,
1059 checkassassin;
1060
1061 word i;
1062
1063 if (IN_Started==true)
1064 return;
1065
1066 #if USE_SDL
1067
1068 #if PLATFORM_WIN32
1069 // fixme: remove this.
1070 sdl_mouse_grabbed = 1;
1071 #endif
1072
1073 /*
1074 all keys are now mapped to the wolf3d-style names,
1075 except where no such name is available.
1076 */
1077 memset(scancodes, '\0', sizeof (scancodes));
1078 scancodes[SDLK_ESCAPE] = sc_Escape;
1079 scancodes[SDLK_1] = sc_1;
1080 scancodes[SDLK_2] = sc_2;
1081 scancodes[SDLK_3] = sc_3;
1082 scancodes[SDLK_4] = sc_4;
1083 scancodes[SDLK_5] = sc_5;
1084 scancodes[SDLK_6] = sc_6;
1085 scancodes[SDLK_7] = sc_7;
1086 scancodes[SDLK_8] = sc_8;
1087 scancodes[SDLK_9] = sc_9;
1088 scancodes[SDLK_0] = sc_0;
1089
1090 //scancodes[SDLK_EQUALS] = 0x4E;
1091 scancodes[SDLK_EQUALS] = sc_Equals;
1092
1093 scancodes[SDLK_BACKSPACE] = sc_BackSpace;
1094 scancodes[SDLK_TAB] = sc_Tab;
1095 scancodes[SDLK_q] = sc_Q;
1096 scancodes[SDLK_w] = sc_W;
1097 scancodes[SDLK_e] = sc_E;
1098 scancodes[SDLK_r] = sc_R;
1099 scancodes[SDLK_t] = sc_T;
1100 scancodes[SDLK_y] = sc_Y;
1101 scancodes[SDLK_u] = sc_U;
1102 scancodes[SDLK_i] = sc_I;
1103 scancodes[SDLK_o] = sc_O;
1104 scancodes[SDLK_p] = sc_P;
1105 scancodes[SDLK_LEFTBRACKET] = sc_OpenBracket;
1106 scancodes[SDLK_RIGHTBRACKET] = sc_CloseBracket;
1107 scancodes[SDLK_RETURN] = sc_Return;
1108 scancodes[SDLK_LCTRL] = sc_Control;
1109 scancodes[SDLK_a] = sc_A;
1110 scancodes[SDLK_s] = sc_S;
1111 scancodes[SDLK_d] = sc_D;
1112 scancodes[SDLK_f] = sc_F;
1113 scancodes[SDLK_g] = sc_G;
1114 scancodes[SDLK_h] = sc_H;
1115 scancodes[SDLK_j] = sc_J;
1116 scancodes[SDLK_k] = sc_K;
1117 scancodes[SDLK_l] = sc_L;
1118 scancodes[SDLK_SEMICOLON] = 0x27;
1119 scancodes[SDLK_QUOTE] = 0x28;
1120 scancodes[SDLK_BACKQUOTE] = 0x29;
1121
1122 /* left shift, but ROTT maps it to right shift in isr.c */
1123 scancodes[SDLK_LSHIFT] = sc_RShift; /* sc_LShift */
1124
1125 scancodes[SDLK_BACKSLASH] = 0x2B;
1126 scancodes[SDLK_z] = sc_Z;
1127 scancodes[SDLK_x] = sc_X;
1128 scancodes[SDLK_c] = sc_C;
1129 scancodes[SDLK_v] = sc_V;
1130 scancodes[SDLK_b] = sc_B;
1131 scancodes[SDLK_n] = sc_N;
1132 scancodes[SDLK_m] = sc_M;
1133 scancodes[SDLK_COMMA] = sc_Comma;
1134 scancodes[SDLK_PERIOD] = sc_Period;
1135 scancodes[SDLK_SLASH] = 0x35;
1136 scancodes[SDLK_RSHIFT] = sc_RShift;
1137 scancodes[SDLK_KP_DIVIDE] = 0x35;
1138
1139 /* 0x37 is printscreen */
1140 //scancodes[SDLK_KP_MULTIPLY] = 0x37;
1141
1142 scancodes[SDLK_LALT] = sc_Alt;
1143 scancodes[SDLK_RALT] = sc_Alt;
1144 scancodes[SDLK_RCTRL] = sc_Control;
1145 scancodes[SDLK_SPACE] = sc_Space;
1146 scancodes[SDLK_CAPSLOCK] = sc_CapsLock;
1147 scancodes[SDLK_F1] = sc_F1;
1148 scancodes[SDLK_F2] = sc_F2;
1149 scancodes[SDLK_F3] = sc_F3;
1150 scancodes[SDLK_F4] = sc_F4;
1151 scancodes[SDLK_F5] = sc_F5;
1152 scancodes[SDLK_F6] = sc_F6;
1153 scancodes[SDLK_F7] = sc_F7;
1154 scancodes[SDLK_F8] = sc_F8;
1155 scancodes[SDLK_F9] = sc_F9;
1156 scancodes[SDLK_F10] = sc_F10;
1157 scancodes[SDLK_F11] = sc_F11;
1158 scancodes[SDLK_F12] = sc_F12;
1159 scancodes[SDLK_NUMLOCK] = 0x45;
1160 scancodes[SDLK_SCROLLOCK] = 0x46;
1161
1162 //scancodes[SDLK_MINUS] = 0x4A;
1163 scancodes[SDLK_MINUS] = sc_Minus;
1164
1165 scancodes[SDLK_KP7] = sc_Home;
1166 scancodes[SDLK_KP8] = sc_UpArrow;
1167 scancodes[SDLK_KP9] = sc_PgUp;
1168 scancodes[SDLK_HOME] = sc_Home;
1169 scancodes[SDLK_UP] = sc_UpArrow;
1170 scancodes[SDLK_PAGEUP] = sc_PgUp;
1171 scancodes[SDLK_KP_MINUS] = 0xE04A;
1172 scancodes[SDLK_KP4] = sc_LeftArrow;
1173 scancodes[SDLK_KP5] = 0x4C;
1174 scancodes[SDLK_KP6] = sc_RightArrow;
1175 scancodes[SDLK_LEFT] = sc_LeftArrow;
1176 scancodes[SDLK_RIGHT] = sc_RightArrow;
1177
1178 //scancodes[SDLK_KP_PLUS] = 0x4E;
1179 scancodes[SDLK_KP_PLUS] = sc_Plus;
1180
1181 scancodes[SDLK_KP1] = sc_End;
1182 scancodes[SDLK_KP2] = sc_DownArrow;
1183 scancodes[SDLK_KP3] = sc_PgDn;
1184 scancodes[SDLK_END] = sc_End;
1185 scancodes[SDLK_DOWN] = sc_DownArrow;
1186 scancodes[SDLK_PAGEDOWN] = sc_PgDn;
1187 scancodes[SDLK_DELETE] = sc_Delete;
1188 scancodes[SDLK_KP0] = sc_Insert;
1189 scancodes[SDLK_INSERT] = sc_Insert;
1190 scancodes[SDLK_KP_ENTER] = sc_Return;
1191 #endif
1192
1193 checkjoys = true;
1194 checkmouse = true;
1195 checkcyberman = false;
1196 checkassassin = false;
1197 checkspaceball = false;
1198 SpaceBallPresent = false;
1199 CybermanPresent = false;
1200 AssassinPresent = false;
1201
1202 for (i = 1; i < _argc; i++)
1203 {
1204 switch (US_CheckParm (_argv[i], ParmStrings))
1205 {
1206 case 0:
1207 checkjoys = false;
1208 break;
1209
1210 case 1:
1211 checkmouse = false;
1212 break;
1213
1214 case 2:
1215 checkspaceball = true;
1216 break;
1217
1218 case 3:
1219 checkcyberman = true;
1220 checkmouse = false;
1221 break;
1222
1223 case 4:
1224 checkassassin = true;
1225 checkmouse = false;
1226 break;
1227 }
1228 }
1229
1230 MousePresent = checkmouse ? INL_StartMouse() : false;
1231
1232 if (!MousePresent)
1233 mouseenabled = false;
1234 else
1235 {
1236 if (!quiet)
1237 printf("IN_Startup: Mouse Present\n");
1238 }
1239
1240 for (i = 0;i < MaxJoys;i++)
1241 {
1242 JoysPresent[i] = checkjoys ? INL_StartJoy(i) : false;
1243 if (INL_StartJoy(i))
1244 {
1245 if (!quiet)
1246 printf("IN_Startup: Joystick Present\n");
1247 }
1248 }
1249
1250 if (checkspaceball)
1251 {
1252 OpenSpaceBall ();
1253 spaceballenabled=true;
1254 }
1255
1256 if ((checkcyberman || checkassassin) && (swiftstatus = SWIFT_Initialize ()))
1257 {
1258 int dynamic;
1259
1260 if (checkcyberman)
1261 {
1262 CybermanPresent = swiftstatus;
1263 cybermanenabled = true;
1264 }
1265 else if (checkassassin)
1266 {
1267 AssassinPresent = checkassassin & swiftstatus;
1268 assassinenabled = true;
1269 }
1270
1271 dynamic = SWIFT_GetDynamicDeviceData ();
1272
1273 SWIFT_TactileFeedback (40, 20, 20);
1274
1275 if (SWIFT_GetDynamicDeviceData () == 2)
1276 Error ("SWIFT ERROR : External Power too high!\n");
1277
1278 SWIFT_TactileFeedback (100, 10, 10);
1279 if (!quiet)
1280 printf("IN_Startup: Swift Device Present\n");
1281 }
1282
1283 IN_Started = true;
1284 }
1285
1286
1287 #if 0
1288 //******************************************************************************
1289 //
1290 // IN_Default() - Sets up default conditions for the Input Mgr
1291 //
1292 //******************************************************************************
1293
1294 void IN_Default (boolean gotit, ControlType in)
1295 {
1296 if
1297 (
1298 (!gotit)
1299 || ((in == ctrl_Joystick1) && !JoysPresent[0])
1300 || ((in == ctrl_Joystick2) && !JoysPresent[1])
1301 || ((in == ctrl_Mouse) && !MousePresent)
1302 )
1303 in = ctrl_Keyboard1;
1304 IN_SetControlType (0, in);
1305 }
1306 #endif
1307
1308 //******************************************************************************
1309 //
1310 // IN_Shutdown() - Shuts down the Input Mgr
1311 //
1312 //******************************************************************************
1313
IN_Shutdown(void)1314 void IN_Shutdown (void)
1315 {
1316 word i;
1317
1318 if (IN_Started==false)
1319 return;
1320
1321 // INL_ShutMouse();
1322
1323 for (i = 0;i < MaxJoys;i++)
1324 INL_ShutJoy(i);
1325
1326 if (CybermanPresent || AssassinPresent)
1327 SWIFT_Terminate ();
1328
1329 CloseSpaceBall ();
1330
1331 IN_Started = false;
1332 }
1333
1334
1335 //******************************************************************************
1336 //
1337 // IN_ClearKeysDown() - Clears the keyboard array
1338 //
1339 //******************************************************************************
1340
IN_ClearKeysDown(void)1341 void IN_ClearKeysDown (void)
1342 {
1343 LastScan = sc_None;
1344 memset ((void *)Keyboard, 0, sizeof (Keyboard));
1345 }
1346
1347
1348 //******************************************************************************
1349 //
1350 // IN_ReadControl() - Reads the device associated with the specified
1351 // player and fills in the control info struct
1352 //
1353 //******************************************************************************
1354
IN_ReadControl(int player,ControlInfo * info)1355 void IN_ReadControl (int player, ControlInfo *info)
1356 {
1357 boolean realdelta;
1358 word buttons;
1359 int dx,dy;
1360 Motion mx,my;
1361 ControlType type;
1362
1363 KeyboardDef *def;
1364
1365 dx = dy = 0;
1366 mx = my = motion_None;
1367 buttons = 0;
1368
1369
1370 switch (type = Controls[player])
1371 {
1372 case ctrl_Keyboard:
1373 def = &KbdDefs;
1374
1375 #if 0
1376 if (Keyboard[def->upleft])
1377 mx = motion_Left,my = motion_Up;
1378 else if (Keyboard[def->upright])
1379 mx = motion_Right,my = motion_Up;
1380 else if (Keyboard[def->downleft])
1381 mx = motion_Left,my = motion_Down;
1382 else if (Keyboard[def->downright])
1383 mx = motion_Right,my = motion_Down;
1384 #endif
1385 if (Keyboard[sc_UpArrow])
1386 my = motion_Up;
1387 else if (Keyboard[sc_DownArrow])
1388 my = motion_Down;
1389
1390 if (Keyboard[sc_LeftArrow])
1391 mx = motion_Left;
1392 else if (Keyboard[sc_RightArrow])
1393 mx = motion_Right;
1394
1395 if (Keyboard[def->button0])
1396 buttons += 1 << 0;
1397 if (Keyboard[def->button1])
1398 buttons += 1 << 1;
1399 realdelta = false;
1400 break;
1401
1402 #if 0
1403 case ctrl_Joystick1:
1404 case ctrl_Joystick2:
1405 INL_GetJoyDelta (type - ctrl_Joystick, &dx, &dy);
1406 buttons = INL_GetJoyButtons (type - ctrl_Joystick);
1407 realdelta = true;
1408 break;
1409
1410 case ctrl_Mouse:
1411 INL_GetMouseDelta (&dx,&dy);
1412 buttons = IN_GetMouseButtons ();
1413 realdelta = true;
1414 break;
1415
1416 #endif
1417 default:
1418 ;
1419 }
1420
1421 if (realdelta)
1422 {
1423 mx = (dx < 0)? motion_Left : ((dx > 0)? motion_Right : motion_None);
1424 my = (dy < 0)? motion_Up : ((dy > 0)? motion_Down : motion_None);
1425 }
1426 else
1427 {
1428 dx = mx * 127;
1429 dy = my * 127;
1430 }
1431
1432 info->x = dx;
1433 info->xaxis = mx;
1434 info->y = dy;
1435 info->yaxis = my;
1436 info->button0 = buttons & (1 << 0);
1437 info->button1 = buttons & (1 << 1);
1438 info->button2 = buttons & (1 << 2);
1439 info->button3 = buttons & (1 << 3);
1440 info->dir = DirTable[((my + 1) * 3) + (mx + 1)];
1441 }
1442
1443
1444 //******************************************************************************
1445 //
1446 // IN_WaitForKey() - Waits for a scan code, then clears LastScan and
1447 // returns the scan code
1448 //
1449 //******************************************************************************
1450
IN_WaitForKey(void)1451 ScanCode IN_WaitForKey (void)
1452 {
1453 ScanCode result;
1454
1455 while (!(result = LastScan))
1456 IN_PumpEvents();
1457 LastScan = 0;
1458 return (result);
1459 }
1460
1461
1462 //******************************************************************************
1463 //
1464 // IN_Ack() - waits for a button or key press. If a button is down, upon
1465 // calling, it must be released for it to be recognized
1466 //
1467 //******************************************************************************
1468
1469 //#define MAX_MOUSEBTN 4
1470 boolean btnstate[MAX_MOUSEBTN+MAX_JOYBTN];
1471
IN_StartAck(void)1472 void IN_StartAck (void)
1473 {
1474 unsigned i,
1475 buttons = 0;
1476
1477 //
1478 // get initial state of everything
1479 //
1480 LastScan = 0;
1481
1482 IN_ClearKeysDown ();
1483 memset (btnstate, 0, sizeof(btnstate));
1484
1485 IN_PumpEvents();
1486
1487 buttons = IN_JoyButtons () << MAX_MOUSEBTN;
1488
1489 buttons |= IN_GetMouseButtons();
1490
1491 if (SpaceBallPresent && spaceballenabled)
1492 {
1493 buttons |= GetSpaceBallButtons ();
1494 }
1495
1496 for (i=0;i<MAX_MOUSEBTN+MAX_JOYBTN;i++,buttons>>=1)
1497 if (buttons&1)
1498 btnstate[i] = true;
1499 }
1500
1501
1502
1503 //******************************************************************************
1504 //
1505 // IN_CheckAck ()
1506 //
1507 //******************************************************************************
1508
IN_CheckAck(void)1509 boolean IN_CheckAck (void)
1510 {
1511 unsigned i,
1512 buttons = 0;
1513
1514 //
1515 // see if something has been pressed
1516 //
1517 if (LastScan)
1518 return true;
1519
1520 IN_PumpEvents();
1521
1522 buttons = IN_JoyButtons () << MAX_MOUSEBTN;
1523
1524 buttons |= IN_GetMouseButtons();
1525
1526 for (i=0;i<MAX_MOUSEBTN+MAX_JOYBTN;i++,buttons>>=1)
1527 if ( buttons&1 )
1528 {
1529 if (!btnstate[i])
1530 return true;
1531 }
1532 else
1533 btnstate[i]=false;
1534
1535 return false;
1536 }
1537
1538
1539
1540 //******************************************************************************
1541 //
1542 // IN_Ack ()
1543 //
1544 //******************************************************************************
1545
IN_Ack(void)1546 void IN_Ack (void)
1547 {
1548 IN_StartAck ();
1549
1550 while (!IN_CheckAck ())
1551 ;
1552 }
1553
1554
1555
1556 //******************************************************************************
1557 //
1558 // IN_UserInput() - Waits for the specified delay time (in ticks) or the
1559 // user pressing a key or a mouse button. If the clear flag is set, it
1560 // then either clears the key or waits for the user to let the mouse
1561 // button up.
1562 //
1563 //******************************************************************************
1564
IN_UserInput(long delay)1565 boolean IN_UserInput (long delay)
1566 {
1567 long lasttime;
1568
1569 lasttime = GetTicCount();
1570
1571 IN_StartAck ();
1572 do
1573 {
1574 if (IN_CheckAck())
1575 return true;
1576 } while ((GetTicCount() - lasttime) < delay);
1577
1578 return (false);
1579 }
1580
1581 //===========================================================================
1582
1583
1584 /*
1585 ===================
1586 =
1587 = IN_JoyButtons
1588 =
1589 ===================
1590 */
1591
IN_JoyButtons(void)1592 int IN_JoyButtons (void)
1593 {
1594 unsigned joybits = 0;
1595
1596 #if USE_SDL
1597 int i,hat;
1598 #ifdef DC
1599 for(i=0;i<4;i++) {
1600 joybits |= SDL_JoystickGetButton(sdl_joysticks[0],i)<<i;
1601 }
1602
1603 hat = SDL_JoystickGetHat(sdl_joysticks[0],0);
1604 if (hat&SDL_HAT_UP ) joybits |= 1<<4;
1605 if (hat&SDL_HAT_DOWN ) joybits |= 1<<5;
1606 if (hat&SDL_HAT_LEFT ) joybits |= 1<<6;
1607 if (hat&SDL_HAT_RIGHT) joybits |= 1<<7;
1608
1609 if (SDL_JoystickGetAxis(sdl_joysticks[0],2)!=0) joybits |= 1<<9;
1610 if (SDL_JoystickGetAxis(sdl_joysticks[0],3)!=0) joybits |= 1<<8;
1611 #else
1612 for(i=0;i<MAX_JOYBTN;i++) {
1613 joybits |= SDL_JoystickGetButton(sdl_joysticks[0],i)<<i;
1614 }
1615 #endif
1616 // joybits = sdl_sticks_joybits;
1617
1618 #elif PLATFORM_DOS
1619 joybits = inp (0x201); // Get all the joystick buttons
1620 joybits >>= 4; // only the high bits are useful
1621 joybits ^= 15; // return with 1=pressed
1622
1623 #else
1624 #error define your platform.
1625 #endif
1626
1627 return joybits;
1628 }
1629
1630
1631 //******************************************************************************
1632 //
1633 // IN_UpdateKeyboard ()
1634 //
1635 //******************************************************************************
1636
1637 /* HACK HACK HACK */
1638 static int queuegotit=0;
1639
IN_UpdateKeyboard(void)1640 void IN_UpdateKeyboard (void)
1641 {
1642 int tail;
1643 int key;
1644
1645 if (!queuegotit)
1646 IN_PumpEvents();
1647
1648 queuegotit=0;
1649
1650 if (Keytail != Keyhead)
1651 {
1652 tail = Keytail;
1653
1654 while (Keyhead != tail)
1655 {
1656 if (KeyboardQueue[Keyhead] & 0x80) // Up event
1657 {
1658 key = KeyboardQueue[Keyhead] & 0x7F; // AND off high bit
1659
1660 // if (keysdown[key])
1661 // {
1662 // KeyboardQueue[Keytail] = KeyboardQueue[Keyhead];
1663 // Keytail = (Keytail+1)&(KEYQMAX-1);
1664 // }
1665 // else
1666 Keyboard[key] = 0;
1667 }
1668 else // Down event
1669 {
1670 Keyboard[KeyboardQueue[Keyhead]] = 1;
1671 // keysdown[KeyboardQueue[Keyhead]] = 1;
1672 }
1673
1674 Keyhead = (Keyhead+1)&(KEYQMAX-1);
1675
1676 } // while
1677 } // if
1678
1679 // Carry over movement keys from the last refresh
1680 // keysdown[sc_RightArrow] = Keyboard[sc_RightArrow];
1681 // keysdown[sc_LeftArrow] = Keyboard[sc_LeftArrow];
1682 // keysdown[sc_UpArrow] = Keyboard[sc_UpArrow];
1683 // keysdown[sc_DownArrow] = Keyboard[sc_DownArrow];
1684 }
1685
1686
1687
1688 //******************************************************************************
1689 //
1690 // IN_InputUpdateKeyboard ()
1691 //
1692 //******************************************************************************
1693
IN_InputUpdateKeyboard(void)1694 int IN_InputUpdateKeyboard (void)
1695 {
1696 int key;
1697 int returnval = 0;
1698 boolean done = false;
1699
1700 // _disable ();
1701
1702 if (Keytail != Keyhead)
1703 {
1704 int tail = Keytail;
1705
1706 while (!done && (Keyhead != tail))
1707 {
1708 if (KeyboardQueue[Keyhead] & 0x80) // Up event
1709 {
1710 key = KeyboardQueue[Keyhead] & 0x7F; // AND off high bit
1711
1712 Keyboard[key] = 0;
1713 }
1714 else // Down event
1715 {
1716 Keyboard[KeyboardQueue[Keyhead]] = 1;
1717 returnval = KeyboardQueue[Keyhead];
1718 done = true;
1719 }
1720
1721 Keyhead = (Keyhead+1)&(KEYQMAX-1);
1722 }
1723 } // if
1724
1725 // _enable ();
1726
1727 return (returnval);
1728 }
1729
1730
1731 //******************************************************************************
1732 //
1733 // IN_ClearKeyboardQueue ()
1734 //
1735 //******************************************************************************
1736
IN_ClearKeyboardQueue(void)1737 void IN_ClearKeyboardQueue (void)
1738 {
1739 return;
1740
1741 // IN_ClearKeysDown ();
1742
1743 // Keytail = Keyhead = 0;
1744 // memset (KeyboardQueue, 0, sizeof (KeyboardQueue));
1745 // I_SendKeyboardData(0xf6);
1746 // I_SendKeyboardData(0xf4);
1747 }
1748
1749
1750 #if 0
1751 //******************************************************************************
1752 //
1753 // IN_DumpKeyboardQueue ()
1754 //
1755 //******************************************************************************
1756
1757 void IN_DumpKeyboardQueue (void)
1758 {
1759 int head = Keyhead;
1760 int tail = Keytail;
1761 int key;
1762
1763 if (tail != head)
1764 {
1765 SoftError( "START DUMP\n");
1766
1767 while (head != tail)
1768 {
1769 if (KeyboardQueue[head] & 0x80) // Up event
1770 {
1771 key = KeyboardQueue[head] & 0x7F; // AND off high bit
1772
1773 // if (keysdown[key])
1774 // {
1775 // SoftError( "%s - was put in next refresh\n",
1776 // IN_GetScanName (key));
1777 // }
1778 // else
1779 // {
1780 if (Keyboard[key] == 0)
1781 SoftError( "%s %ld - was lost\n", IN_GetScanName (key), key);
1782 else
1783 SoftError( "%s %ld - up\n", IN_GetScanName (key), key);
1784 // }
1785 }
1786 else // Down event
1787 SoftError( "%s %ld - down\n", IN_GetScanName (KeyboardQueue[head]), KeyboardQueue[head]);
1788
1789 head = (head+1)&(KEYQMAX-1);
1790 } // while
1791
1792 SoftError( "END DUMP\n");
1793
1794 } // if
1795 }
1796 #endif
1797
1798
1799 //******************************************************************************
1800 //
1801 // QueueLetterInput ()
1802 //
1803 //******************************************************************************
1804
QueueLetterInput(void)1805 void QueueLetterInput (void)
1806 {
1807 int head = Keyhead;
1808 int tail = Keytail;
1809 char c;
1810 int scancode;
1811 boolean send = false;
1812
1813 #ifndef PLATFORM_DOS
1814 /* HACK HACK HACK */
1815 /*
1816 OK, we want the new keys NOW, and not when the update gets them.
1817 Since this called before IN_UpdateKeyboard in PollKeyboardButtons,
1818 we shall update here. The hack is there to prevent IN_UpdateKeyboard
1819 from stealing any keys... - SBF
1820 */
1821 IN_PumpEvents();
1822 head = Keyhead;
1823 tail = Keytail;
1824 queuegotit=1;
1825 /* HACK HACK HACK */
1826 #endif
1827
1828 while (head != tail)
1829 {
1830 if (!(KeyboardQueue[head] & 0x80)) // Down event
1831 {
1832 scancode = KeyboardQueue[head];
1833
1834 if (Keyboard[sc_RShift] || Keyboard[sc_LShift])
1835 {
1836 c = ShiftedScanChars[scancode];
1837 }
1838 else
1839 {
1840 c = ScanChars[scancode];
1841 }
1842
1843 // If "is printable char", queue the character
1844 if (c)
1845 {
1846 LetterQueue[LastLetter] = c;
1847 LastLetter = (LastLetter+1)&(MAXLETTERS-1);
1848
1849 // If typing a message, update the text with 'c'
1850
1851 if ( MSG.messageon )
1852 {
1853 Keystate[scancode]=0;
1854 KeyboardQueue[head] = 0;
1855 if ( MSG.inmenu )
1856 {
1857 if ( ( c == 'A' ) || ( c == 'a' ) )
1858 {
1859 MSG.towho = MSG_DIRECTED_TO_ALL;
1860 send = true;
1861 }
1862
1863 if ( ( gamestate.teamplay ) &&
1864 ( ( c == 'T' ) || ( c == 't' ) ) )
1865 {
1866 MSG.towho = MSG_DIRECTED_TO_TEAM;
1867 send = true;
1868 }
1869
1870 if ( ( c >= '0' ) && ( c <= '9' ) )
1871 {
1872 int who;
1873
1874 if ( c == '0' )
1875 {
1876 who = 10;
1877 }
1878 else
1879 {
1880 who = c - '1';
1881 }
1882
1883 // Skip over local player
1884 if ( who >= consoleplayer )
1885 {
1886 who++;
1887 }
1888
1889 if ( who < numplayers )
1890 {
1891 MSG.towho = who;
1892 send = true;
1893 }
1894 }
1895
1896 if ( send )
1897 {
1898 MSG.messageon = false;
1899 KeyboardQueue[ head ] = 0;
1900 Keyboard[ scancode ] = 0;
1901 LastScan = 0;
1902 FinishModemMessage( MSG.textnum, true );
1903 }
1904 }
1905 else if ( ( scancode >= sc_1 ) && ( scancode <= sc_0 ) &&
1906 ( Keyboard[ sc_Alt ] ) )
1907 {
1908 int msg;
1909
1910 msg = scancode - sc_1;
1911
1912 if ( CommbatMacros[ msg ].avail )
1913 {
1914 MSG.length = strlen( CommbatMacros[ msg ].macro ) + 1;
1915 strcpy( Messages[ MSG.textnum ].text,
1916 CommbatMacros[ msg ].macro );
1917
1918 MSG.messageon = false;
1919 FinishModemMessage( MSG.textnum, true );
1920 KeyboardQueue[ head ] = 0;
1921 Keyboard[ sc_Enter ] = 0;
1922 Keyboard[ sc_Escape ] = 0;
1923 LastScan = 0;
1924 }
1925 else
1926 {
1927 MSG.messageon = false;
1928 MSG.directed = false;
1929
1930 FinishModemMessage( MSG.textnum, false );
1931 AddMessage( "No macro.", MSG_MACRO );
1932 KeyboardQueue[ head ] = 0;
1933 Keyboard[ sc_Enter ] = 0;
1934 Keyboard[ sc_Escape ] = 0;
1935 LastScan = 0;
1936 }
1937 }
1938 else if ( MSG.length < MAXMESSAGELENGTH )
1939 {
1940 UpdateModemMessage (MSG.textnum, c);
1941 }
1942 }
1943 }
1944 else
1945 {
1946 // If typing a message, check for special characters
1947
1948 if ( MSG.messageon && MSG.inmenu )
1949 {
1950 if ( scancode == sc_Escape )
1951 {
1952 MSG.messageon = false;
1953 MSG.directed = false;
1954 FinishModemMessage( MSG.textnum, false );
1955 KeyboardQueue[head] = 0;
1956 Keyboard[sc_Enter] = 0;
1957 Keyboard[sc_Escape] = 0;
1958 LastScan = 0;
1959 }
1960 }
1961 else if ( MSG.messageon && !MSG.inmenu )
1962 {
1963 if ( ( scancode >= sc_F1 ) &&
1964 ( scancode <= sc_F10 ) )
1965 {
1966 MSG.remoteridicule = scancode - sc_F1;
1967 MSG.messageon = false;
1968 FinishModemMessage(MSG.textnum, true);
1969 KeyboardQueue[head] = 0;
1970 Keyboard[sc_Enter] = 0;
1971 Keyboard[sc_Escape] = 0;
1972 LastScan = 0;
1973 }
1974
1975 switch (scancode)
1976 {
1977 case sc_BackSpace:
1978 KeyboardQueue[head] = 0;
1979 if (MSG.length > 1)
1980 {
1981 ModemMessageDeleteChar (MSG.textnum);
1982 }
1983 Keystate[scancode]=0;
1984 break;
1985
1986 case sc_Enter:
1987 MSG.messageon = false;
1988 FinishModemMessage(MSG.textnum, true);
1989 KeyboardQueue[head] = 0;
1990 Keyboard[sc_Enter] = 0;
1991 Keyboard[sc_Escape] = 0;
1992 LastScan = 0;
1993 Keystate[scancode]=0;
1994 break;
1995
1996 case sc_Escape:
1997 MSG.messageon = false;
1998 MSG.directed = false;
1999 FinishModemMessage(MSG.textnum, false);
2000 KeyboardQueue[head] = 0;
2001 Keyboard[sc_Enter] = 0;
2002 Keyboard[sc_Escape] = 0;
2003 LastScan = 0;
2004 break;
2005 }
2006 }
2007 }
2008 }
2009
2010 head = (head+1)&(KEYQMAX-1);
2011 } // while
2012 }
2013