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