]> 4ch.mooo.com Git - 16.git/commitdiff
modified: src/lib/16_in.c
authorsparky4 <sparky4@cock.li>
Mon, 29 Jun 2015 15:00:38 +0000 (10:00 -0500)
committersparky4 <sparky4@cock.li>
Mon, 29 Jun 2015 15:00:38 +0000 (10:00 -0500)
src/lib/16_in.c

index f869464c60b79501c97a16d248b0bcca7ddff0aa..b19702d088ccabb92f92e633b89ea6c3a3102f59 100644 (file)
  * You should have received a copy of the GNU General Public License along\r
  * with this program; if not, write to the Free Software Foundation, Inc.,\r
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
- */
-
-//
-//     ID Engine
-//     ID_IN.c - Input Manager
-//     v1.0d1w
-//     By Jason Blochowiak
-//     Open Watcom port by sparky4
-//
-
-//
-//     This module handles dealing with the various input devices
-//
-//     Depends on: Memory Mgr (for demo recording), Sound Mgr (for timing stuff),
-//                             User Mgr (for command line parms)
-//
-//     Globals:
-//             LastScan - The keyboard scan code of the last key pressed
-//             LastASCII - The ASCII value of the last key pressed
-//     DEBUG - there are more globals
-//
-
-#include "src/lib/16_in.h"
-
+ */\r
+\r
+//\r
+//     ID Engine\r
+//     ID_IN.c - Input Manager\r
+//     v1.0d1w\r
+//     By Jason Blochowiak\r
+//     Open Watcom port by sparky4\r
+//\r
+\r
+//\r
+//     This module handles dealing with the various input devices\r
+//\r
+//     Depends on: Memory Mgr (for demo recording), Sound Mgr (for timing stuff),\r
+//                             User Mgr (for command line parms)\r
+//\r
+//     Globals:\r
+//             LastScan - The keyboard scan code of the last key pressed\r
+//             LastASCII - The ASCII value of the last key pressed\r
+//     DEBUG - there are more globals\r
+//\r
+\r
+#include "src/lib/16_in.h"\r
+\r
 /*\r
 =============================================================================\r
 \r
                                        GLOBAL VARIABLES\r
 \r
 =============================================================================\r
-*/
-struct inconfig
-{
+*/\r
+struct inconfig\r
+{\r
        boolean                 MousePresent;\r
        boolean                 JoysPresent[MaxJoys];\r
-       boolean                 JoyPadPresent[MaxPads];
+       boolean                 JoyPadPresent[MaxPads];\r
        boolean         Keyboard[NumCodes];\r
        boolean         Paused;\r
        char            LastASCII;\r
-       ScanCode        LastScan;
-
-       KeyboardDef     KbdDefs[MaxKbds];
-       JoystickDef     JoyDefs[MaxJoys];
-       JoypadDef       JoypadDefs[MaxPads];
-} inpu;
-
-//extern inconfig inpu;
-//inpu.KbdDefs = {0x1d,0x38,/*0x47,*/0x48,/*0x49,*/0x4b,0x4d,/*0x4f,*/0x50/*,0x51*/};
-
+       ScanCode        LastScan;\r
+\r
+       KeyboardDef     KbdDefs[MaxKbds];\r
+       JoystickDef     JoyDefs[MaxJoys];\r
+       JoypadDef       JoypadDefs[MaxPads];\r
+} inpu;\r
+\r
+//extern inconfig inpu;\r
+//inpu.KbdDefs = {0x1d,0x38,/*0x47,*/0x48,/*0x49,*/0x4b,0x4d,/*0x4f,*/0x50/*,0x51*/};\r
+\r
 /*\r
 =============================================================================\r
 \r
                                        LOCAL VARIABLES\r
 \r
 =============================================================================\r
-*/
-
-#ifdef __cplusplus             /* Function must be declared C style */
-extern "C" {
-#endif
+*/\r
 \r
-static struct instat {
+#ifdef __cplusplus             /* Function must be declared C style */\r
+extern "C" {\r
+#endif\r
+\r
+static struct instat {\r
        boolean         IN_Started;\r
        boolean         CapsLock;\r
-       ScanCode        CurCode,LastCode;
-} inst;
+       ScanCode        CurCode,LastCode;\r
+} inst;\r
 \r
-static void                    (*INL_KeyHook)(void);
-static void interrupt  (*OldKeyVect)(void);
-static char                    *ParmStringsIN[] = {"nojoys","nomouse",nil};
+static void                    (*INL_KeyHook)(void);\r
+static void interrupt  (*OldKeyVect)(void);\r
+static char                    *ParmStringsIN[] = {"nojoys","nomouse",nil};\r
 \r
 static byte        far ASCIINames[] =          // Unshifted ASCII for scan codes\r
                                        {\r
@@ -145,7 +145,7 @@ static      byte        far ASCIINames[] =          // Unshifted ASCII for scan codes
        "F5","F6","F7","F8","F9","F10","F11","F12","ScrlLk","Enter","RShft",\r
        "PrtSc","Alt","Home","PgUp","End","PgDn","Ins","Del","NumLk","Up",\r
        "Down","Left","Right",""\r
-                                       };
+                                       };\r
 \r
 static Direction       DirTable[] =            // Quick lookup for total direction\r
                                        {\r
@@ -155,1048 +155,1048 @@ static        Direction       DirTable[] =            // Quick lookup for total direction
                                                dir_West,               dir_None,       dir_East,\r
                                                //dir_Soutinest,\r
                                                dir_South//,dir_SouthEast\r
-                                       };
-#ifdef __cplusplus
-}
-#endif
-
-//     Internal routines
-///////////////////////////////////////////////////////////////////////////
-//
-//     INL_KeyService() - Handles a keyboard interrupt (key up/down)
-//
-///////////////////////////////////////////////////////////////////////////
-void interrupt
-INL_KeyService()
-{
-static boolean special;
-               byte    k,c;
-               register byte temp;
-
-       k = inp(0x60);  // Get the scan code
-
-       // Tell the XT keyboard controller to clear the key
-       outp(0x61,(temp = inp(0x61)) | 0x80);
-       outp(0x61,temp);
-
-       if (k == 0xe0)          // Special key prefix
-               special = true;
-       else if (k == 0xe1)     // Handle Pause key
-               inpu.Paused = true;
-       else
-       {
-               if (k & 0x80)   // Break code
-               {
-                       k &= 0x7f;
-
-// DEBUG - handle special keys: ctl-alt-delete, print scrn
-
-                       inpu.Keyboard[k] = false;
-               }
-               else                    // Make code
-               {
-                       inst.LastCode = inst.CurCode;
-                       inst.CurCode = inpu.LastScan = k;
-                       inpu.Keyboard[k] = true;
-
-                       if (special)
-                               c = SpecialNames[k];
-                       else
-                       {
-                               if (k == sc_CapsLock)
-                               {
-                                       inst.CapsLock ^= true;
-                                       // DEBUG - make caps lock light work
-                               }
-
-                               if (inpu.Keyboard[sc_LShift] || inpu.Keyboard[sc_RShift])       // If shifted
-                               {
-                                       c = ShiftNames[k];
-                                       if ((c >= 'A') && (c <= 'Z') && inst.CapsLock)
-                                               c += 'a' - 'A';
-                               }
-                               else
-                               {
-                                       c = ASCIINames[k];
-                                       if ((c >= 'a') && (c <= 'z') && inst.CapsLock)
-                                               c -= 'a' - 'A';
-                               }
-                       }
-                       if (c)
-                               inpu.LastASCII = c;
-               }
-
-               special = false;
-       }
-
-       if (INL_KeyHook && !special)
-               INL_KeyHook();
-       #ifdef TESTKEYIN
-       printf("%c %x %u\n", c, k, inpu.Keyboard[k]);
-       #endif
-       outp(0x20,0x20);
-}
-
-void
-Mouse(int x)
-{
-       union REGS CPURegs;
-       x = CPURegs.x.ax;
-       int86(MouseInt,&CPURegs,&CPURegs);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     INL_GetMouseDelta() - Gets the amount that the mouse has moved from the
-//             mouse driver
-//
-///////////////////////////////////////////////////////////////////////////
-static void
-INL_GetMouseDelta(int *x,int *y)
-{
-       union REGS CPURegs;
-       Mouse(MDelta);
-       *x = CPURegs.x.cx;
-       *y = CPURegs.x.dx;
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     INL_GetMouseButtons() - Gets the status of the mouse buttons from the
-//             mouse driver
-//
-///////////////////////////////////////////////////////////////////////////
-static word
-INL_GetMouseButtons(void)
-{
-       union REGS CPURegs;
-       word    buttons;
-
-       Mouse(MButtons);
-       buttons = CPURegs.x.bx;
-       return(buttons);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_GetJoyAbs() - Reads the absolute position of the specified joystick
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_GetJoyAbs(word joy,word *xp,word *yp)
-{
-       byte    xb,yb,
-                       xs,ys;
-       word    x,y;
-
-       x = y = 0;
-       xs = joy? 2 : 0;                // Find shift value for x axis
-       xb = 1 << xs;                   // Use shift value to get x bit mask
-       ys = joy? 3 : 1;                // Do the same for y axis
-       yb = 1 << ys;
-
-// Read the absolute joystick values
-       __asm
-       {
-               pushf                           // Save some registers
-               push    si
-               push    di
-               cli                                     // Make sure an interrupt doesn't screw the timings
-
-
-               mov             dx,0x201
-               in              al,dx
-               out             dx,al           // Clear the resistors
-
-               mov             ah,[xb]         // Get masks into registers
-               mov             ch,[yb]
-
-               xor             si,si           // Clear count registers
-               xor             di,di
-               xor             bh,bh           // Clear high byte of bx for later
-
-               push    bp                      // Don't mess up stack frame
-               mov             bp,MaxJoyValue
-
-loo:
-               in              al,dx           // Get bits indicating whether all are finished
-
-               dec             bp                      // Check bounding register
-               jz              done            // We have a silly value - abort
-
-               mov             bl,al           // Duplicate the bits
-               and             bl,ah           // Mask off useless bits (in [xb])
-               add             si,bx           // Possibly increment count register
-               mov             cl,bl           // Save for testing later
-
-               mov             bl,al
-               and             bl,ch           // [yb]
-               add             di,bx
-
-               add             cl,bl
-               jnz             loo             // If both bits were 0, drop out
-
-done:
-               pop             bp
-
-               mov             cl,[xs]         // Get the number of bits to shift
-               shr             si,cl           //  and shift the count that many times
-
-               mov             cl,[ys]
-               shr             di,cl
-
-               mov             [x],si          // Store the values into the variables
-               mov             [y],di
-
-               pop             di
-               pop             si
-               popf                            // Restore the registers
-       }
-
-       *xp = x;
-       *yp = y;
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     INL_GetJoyDelta() - Returns the relative movement of the specified
-//             joystick (from +/-127, scaled adaptively)
-//
-///////////////////////////////////////////////////////////////////////////
-static void
-INL_GetJoyDelta(word joy,int *dx,int *dy,boolean adaptive)
-{
-       word            x,y;
-       dword   time;
-       dword TimeCount = *clockdw;
-       JoystickDef     *def;
-static dword   lasttime;
-
-       IN_GetJoyAbs(joy,&x,&y);
-       def = inpu.JoyDefs + joy;
-
-       if (x < def->threshMinX)
-       {
-               if (x < def->joyMinX)
-                       x = def->joyMinX;
-
-               x = -(x - def->threshMinX);
-               x *= def->joyMultXL;
-               x >>= JoyScaleShift;
-               *dx = (x > 127)? -127 : -x;
-       }
-       else if (x > def->threshMaxX)
-       {
-               if (x > def->joyMaxX)
-                       x = def->joyMaxX;
-
-               x = x - def->threshMaxX;
-               x *= def->joyMultXH;
-               x >>= JoyScaleShift;
-               *dx = (x > 127)? 127 : x;
-       }
-       else
-               *dx = 0;
-
-       if (y < def->threshMinY)
-       {
-               if (y < def->joyMinY)
-                       y = def->joyMinY;
-
-               y = -(y - def->threshMinY);
-               y *= def->joyMultYL;
-               y >>= JoyScaleShift;
-               *dy = (y > 127)? -127 : -y;
-       }
-       else if (y > def->threshMaxY)
-       {
-               if (y > def->joyMaxY)
-                       y = def->joyMaxY;
-
-               y = y - def->threshMaxY;
-               y *= def->joyMultYH;
-               y >>= JoyScaleShift;
-               *dy = (y > 127)? 127 : y;
-       }
-       else
-               *dy = 0;
-
-       if (adaptive)
-       {
-               time = (TimeCount - lasttime) / 2;
-               if (time)
-               {
-                       if (time > 8)
-                               time = 8;
-                       *dx *= time;
-                       *dy *= time;
-               }
-       }
-       lasttime = TimeCount;
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     INL_GetJoyButtons() - Returns the button status of the specified
-//             joystick
-//
-///////////////////////////////////////////////////////////////////////////
-static word
-INL_GetJoyButtons(word joy)
-{
-register       word    result;
-
-       result = inp(0x201);    // Get all the joystick buttons
-       result >>= joy? 6 : 4;  // Shift into bits 0-1
-       result &= 3;                            // Mask off the useless bits
-       result ^= 3;
-       return(result);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_GetJoyButtonsDB() - Returns the de-bounced button status of the
-//             specified joystick
-//
-///////////////////////////////////////////////////////////////////////////
-word
-IN_GetJoyButtonsDB(word joy)
-{
-       dword TimeCount = *clockdw;
-       dword   lasttime;
-       word            result1,result2;
-
-       do
-       {
-               result1 = INL_GetJoyButtons(joy);
-               lasttime = TimeCount;
-               while(TimeCount == lasttime)
-               result2 = INL_GetJoyButtons(joy);
-       } while(result1 != result2);
-       return(result1);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     INL_StartKbd() - Sets up my keyboard stuff for use
-//
-///////////////////////////////////////////////////////////////////////////
-static void
-INL_StartKbd()
-{
-       INL_KeyHook = 0;        // Clear key hook
-
-       IN_ClearKeysDown();
-
-       OldKeyVect = _dos_getvect(KeyInt);
-       _dos_setvect(KeyInt,INL_KeyService);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     INL_ShutKbd() - Restores keyboard control to the BIOS
-//
-///////////////////////////////////////////////////////////////////////////
-static void
-INL_ShutKbd(void)
-{
-       pokeb(0x40,0x17,peekb(0x40,0x17) & 0xfaf0);     // Clear ctrl/alt/shift flags
-
-       _dos_setvect(KeyInt,OldKeyVect);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     INL_StartMouse() - Detects and sets up the mouse
-//
-///////////////////////////////////////////////////////////////////////////
-static boolean
-INL_StartMouse(void)
-{
-       union REGS CPURegs;
-       if(_dos_getvect(MouseInt))
-       {
-               Mouse(MReset);
-               if(CPURegs.x.ax == 0xffff)
-                       return(true);
-       }
-       return(false);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     INL_ShutMouse() - Cleans up after the mouse
-//
-///////////////////////////////////////////////////////////////////////////
-static void
-INL_ShutMouse(void)
-{
-}
-
-//
-//     INL_SetJoyScale() - Sets up scaling values for the specified joystick
-//
-static void
-INL_SetJoyScale(word joy)
-{
-       JoystickDef     *def;
-
-       def = &(inpu.JoyDefs[joy]);
-       def->joyMultXL = JoyScaleMax / (def->threshMinX - def->joyMinX);
-       def->joyMultXH = JoyScaleMax / (def->joyMaxX - def->threshMaxX);
-       def->joyMultYL = JoyScaleMax / (def->threshMinY - def->joyMinY);
-       def->joyMultYH = JoyScaleMax / (def->joyMaxY - def->threshMaxY);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_SetupJoy() - Sets up thresholding values and calls INL_SetJoyScale()
-//             to set up scaling values
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_SetupJoy(word joy,word minx,word maxx,word miny,word maxy)
-{
-       word            d,r;
-       JoystickDef     *def;
-
-       def = &(inpu.JoyDefs[joy]);
-
-       def->joyMinX = minx;
-       def->joyMaxX = maxx;
-       r = maxx - minx;
-       d = r / 3;
-       def->threshMinX = ((r / 2) - d) + minx;
-       def->threshMaxX = ((r / 2) + d) + minx;
-
-       def->joyMinY = miny;
-       def->joyMaxY = maxy;
-       r = maxy - miny;
-       d = r / 3;
-       def->threshMinY = ((r / 2) - d) + miny;
-       def->threshMaxY = ((r / 2) + d) + miny;
-
-       INL_SetJoyScale(joy);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     INL_StartJoy() - Detects & auto-configures the specified joystick
-//                                     The auto-config assumes the joystick is centered
-//
-///////////////////////////////////////////////////////////////////////////
-static boolean
-INL_StartJoy(word joy)
-{
-       word            x,y;
-
-       IN_GetJoyAbs(joy,&x,&y);
-
-       if
-       (
-               ((x == 0) || (x > MaxJoyValue - 10))
-       ||      ((y == 0) || (y > MaxJoyValue - 10))
-       )
-               return(false);
-       else
-       {
-               IN_SetupJoy(joy,0,x * 2,0,y * 2);
-               return(true);
-       }
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     INL_ShutJoy() - Cleans up the joystick stuff
-//
-///////////////////////////////////////////////////////////////////////////
-static void
-INL_ShutJoy(word joy)
-{
-       inpu.JoysPresent[joy] = false;
-}
-
-//     Public routines
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_Startup() - Starts up the Input Mgr
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_Startup()
-{
-       boolean checkjoys,checkmouse;
-       word    i;
-
-       if (inst.IN_Started)
-               return;
-
-       checkjoys = true;
-       checkmouse = true;
-       for (i = 1;i < __argc;i++)
-       {
-               switch (US_CheckParm(__argv[i],ParmStringsIN))
-               {
-               case 0:
-                       checkjoys = false;
-                       break;
-               case 1:
-                       checkmouse = false;
-                       break;
-               }
-       }
-
-       INL_StartKbd();
-       inpu.MousePresent = checkmouse? INL_StartMouse() : false;
-
-       for (i = 0;i < MaxJoys;i++)
-               inpu.JoysPresent[i] = checkjoys? INL_StartJoy(i) : false;
-
-       inst.IN_Started = true;
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_Default() - Sets up default conditions for the Input Mgr
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_Default(boolean gotit,player_t *player,ControlType nt)
-{
-       if
-       (
-               (!gotit)
-       ||      ((nt == ctrl_Joystick1) && !inpu.JoysPresent[0])
-       ||      ((nt == ctrl_Joystick2) && !inpu.JoysPresent[1])
-       ||      ((nt == ctrl_Mouse) && !inpu.MousePresent)
-       ||      ((nt == ctrl_Joypad1) && !inpu.JoyPadPresent[0])
-       ||      ((nt == ctrl_Joypad2) && !inpu.JoyPadPresent[1])
-       )
-               nt = ctrl_Keyboard1;
-       inpu.KbdDefs[0].button0 = 0x1d;
-       inpu.KbdDefs[0].button1 = 0x38;
-       //in.KbdDefs[0].upleft = 0x47;
-       inpu.KbdDefs[0].up = 0x48;
-       //in.KbdDefs[0].upright = 0x49;
-       inpu.KbdDefs[0].left = 0x4b;
-       inpu.KbdDefs[0].right = 0x4d;
-       //in.KbdDefs[0].downleft = 0x4f;
-       inpu.KbdDefs[0].down = 0x50;
-       //in.KbdDefs[0].downright = 0x51;
-       IN_SetControlType(0,player,nt);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_Shutdown() - Shuts down the Input Mgr
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_Shutdown()
-{
-       word    i;
-
-       if (!inst.IN_Started)
-               return;
-
-       INL_ShutMouse();
-       for (i = 0;i < MaxJoys;i++)
-               INL_ShutJoy(i);
-       INL_ShutKbd();
-
-       inst.IN_Started = false;
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_SetKeyHook() - Sets the routine that gets called by INL_KeyService()
-//                     everytime a real make/break code gets hit
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_SetKeyHook(void (*hook)())
-{
-       INL_KeyHook = hook;
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_ClearKeyDown() - Clears the keyboard array
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_ClearKeysDown()
-{
-       int     i;
-
-       inpu.LastScan = sc_None;
-       inpu.LastASCII = key_None;
-       memset (inpu.Keyboard,0,sizeof(inpu.Keyboard));
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     INL_AdjustCursor() - Internal routine of common code from IN_ReadCursor()
-//
-///////////////////////////////////////////////////////////////////////////
-static void
-INL_AdjustCursor(CursorInfo *info,word buttons,int dx,int dy)
-{
-       if (buttons & (1 << 0))
-               info->button0 = true;
-       if (buttons & (1 << 1))
-               info->button1 = true;
-
-       info->x += dx;
-       info->y += dy;
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_ReadCursor() - Reads the input devices and fills in the cursor info
-//             struct
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_ReadCursor(CursorInfo *info)
-{
-       word    i,
-                       buttons;
-       int             dx,dy;
-
-       info->x = info->y = 0;
-       info->button0 = info->button1 = false;
-
-       if (inpu.MousePresent)
-       {
-               buttons = INL_GetMouseButtons();
-               INL_GetMouseDelta(&dx,&dy);
-               INL_AdjustCursor(info,buttons,dx,dy);
-       }
-
-       for (i = 0;i < MaxJoys;i++)
-       {
-               if (!inpu.JoysPresent[i])
-                       continue;
-
-               buttons = INL_GetJoyButtons(i);
-               INL_GetJoyDelta(i,&dx,&dy,true);
-               dx /= 64;
-               dy /= 64;
-               INL_AdjustCursor(info,buttons,dx,dy);
-       }
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_ReadControl() - Reads the device associated with the specified
-//             player and fills in the control info struct
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_ReadControl(int playnum,player_t *player)
-{
-                       boolean         realdelta;
-                       byte            dbyte;
-                       word            buttons;
-                       int                     dx,dy;
-                       Motion          mx,my;
-                       ControlType     type;
-register       KeyboardDef     *def;
-
-       dx = dy = 0;
-       mx = my = motion_None;
-       buttons = 0;
-
-#if DEMO0
-       if (DemoMode == demo_Playback)
-       {
-               dbyte = DemoBuffer[DemoOffset + 1];
-               my = (dbyte & 3) - 1;
-               mx = ((dbyte >> 2) & 3) - 1;
-               buttons = (dbyte >> 4) & 3;
-
-               if (!(--DemoBuffer[DemoOffset]))
-               {
-                       DemoOffset += 2;
-                       if (DemoOffset >= DemoSize)
-                               DemoMode = demo_PlayDone;
-               }
-
-               realdelta = false;
-       }
-       else if (DemoMode == demo_PlayDone)
-               Quit("Demo playback exceeded");
-       else
-       {
-#endif
-               switch (type = player[playnum].Controls)
-               {
-               case ctrl_Keyboard1:
-               case ctrl_Keyboard2:
-                       def = &(inpu.KbdDefs[type - ctrl_Keyboard]);
-
-/*                     if (Keyboard[def->upleft])
-                               mx = motion_Left,my = motion_Up;
-                       else if (Keyboard[def->upright])
-                               mx = motion_Right,my = motion_Up;
-                       else if (Keyboard[def->downleft])
-                               mx = motion_Left,my = motion_Down;
-                       else if (Keyboard[def->downright])
-                               mx = motion_Right,my = motion_Down;*/
-
-                       if(!inpu.Keyboard[def->left] && !inpu.Keyboard[def->right]){
-                       if (inpu.Keyboard[def->up])
-                               my = motion_Up;
-                       else if (inpu.Keyboard[def->down])
-                               my = motion_Down;
-
-                       }else//if(!inpu.Keyboard[def->up] && !inpu.Keyboard[def->down])
-                       if (inpu.Keyboard[def->left])
-                               mx = motion_Left;
-                       else if (inpu.Keyboard[def->right])
-                               mx = motion_Right;
-
-                       if (inpu.Keyboard[def->button0])
-                               buttons += 1 << 0;
-                       if (inpu.Keyboard[def->button1])
-                               buttons += 1 << 1;
-                       realdelta = false;
-                       break;
-               case ctrl_Joystick1:
-               case ctrl_Joystick2:
-                       INL_GetJoyDelta(type - ctrl_Joystick,&dx,&dy,false);
-                       buttons = INL_GetJoyButtons(type - ctrl_Joystick);
-                       realdelta = true;
-                       break;
-               case ctrl_Mouse:
-                       INL_GetMouseDelta(&dx,&dy);
-                       buttons = INL_GetMouseButtons();
-                       realdelta = true;
-                       break;
-               case ctrl_Joypad1:
-               case ctrl_Joypad2:
-                       printf("wwww");
-                       break;
-               }
-#ifdef DEMO0
-       }
-#endif
-
-       if (realdelta)
-       {
-               mx = (dx < 0)? motion_Left : ((dx > 0)? motion_Right : motion_None);
-               my = (dy < 0)? motion_Up : ((dy > 0)? motion_Down : motion_None);
-       }
-       else
-       {
-               dx = mx * 127;
-               dy = my * 127;
-       }
-
-       player[playnum].info.x = dx;
-       player[playnum].info.xaxis = mx;
-       player[playnum].info.y = dy;
-       player[playnum].info.yaxis = my;
-       player[playnum].info.button0 = buttons & (1 << 0);
-       player[playnum].info.button1 = buttons & (1 << 1);
-       player[playnum].info.button2 = buttons & (1 << 2);
-       player[playnum].info.button3 = buttons & (1 << 3);
-       player[playnum].info.dir = DirTable[((my + 1) * 3) + (mx + 1)];
-
-#if DEMO0
-       if (DemoMode == demo_Record)
-       {
-               // Pack the control info into a byte
-               dbyte = (buttons << 4) | ((mx + 1) << 2) | (my + 1);
-
-               if
-               (
-                       (DemoBuffer[DemoOffset + 1] == dbyte)
-               &&      (DemoBuffer[DemoOffset] < 255)
-               )
-                       (DemoBuffer[DemoOffset])++;
-               else
-               {
-                       if (DemoOffset || DemoBuffer[DemoOffset])
-                               DemoOffset += 2;
-
-                       if (DemoOffset >= DemoSize)
-                               Quit("Demo buffer overflow");
-
-                       DemoBuffer[DemoOffset] = 1;
-                       DemoBuffer[DemoOffset + 1] = dbyte;
-               }
-       }
-#endif
-#ifdef TESTCONTROLNOISY
-printf("dir=%d\n", player[playnum].info.dir);
-#endif
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_SetControlType() - Sets the control type to be used by the specified
-//             player
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_SetControlType(word playnum,player_t *player,ControlType type)
-{
-       // DEBUG - check that requested type is present?
-       player[playnum].Controls = type;
-}
-
-#if DEMO0
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_StartDemoRecord() - Starts the demo recording, using a buffer the
-//             size passed. Returns if the buffer allocation was successful
-//
-///////////////////////////////////////////////////////////////////////////
-boolean
-IN_StartDemoRecord(word bufsize)
-{
-       if (!bufsize)
-               return(false);
-
-       MM_GetPtr((memptr *)&DemoBuffer,bufsize);
-       DemoMode = demo_Record;
-       DemoSize = bufsize & ~1;
-       DemoOffset = 0;
-       DemoBuffer[0] = DemoBuffer[1] = 0;
-
-       return(true);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_StartDemoPlayback() - Plays back the demo pointed to of the given size
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_StartDemoPlayback(byte /*__segment*/ *buffer,word bufsize)
-{
-       DemoBuffer = buffer;
-       DemoMode = demo_Playback;
-       DemoSize = bufsize & ~1;
-       DemoOffset = 0;
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_StopDemo() - Turns off demo mode
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_StopDemo(void)
-{
-       if ((DemoMode == demo_Record) && DemoOffset)
-               DemoOffset += 2;
-
-       DemoMode = demo_Off;
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_FreeDemoBuffer() - Frees the demo buffer, if it's been allocated
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_FreeDemoBuffer(void)
-{
-       if (DemoBuffer)
-               MM_FreePtr((memptr *)&DemoBuffer);
-}
-#endif
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_GetScanName() - Returns a string containing the name of the
-//             specified scan code
-//
-///////////////////////////////////////////////////////////////////////////
-byte *
-IN_GetScanName(ScanCode scan)
-{
-       byte            **p;
-       ScanCode        far *s;
-
-       for (s = ExtScanCodes,p = ExtScanNames;*s;p++,s++)
-               if (*s == scan)
-                       return(*p);
-
-       return(ScanNames[scan]);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_WaitForKey() - Waits for a scan code, then clears LastScan and
-//             returns the scan code
-//
-///////////////////////////////////////////////////////////////////////////
-ScanCode
-IN_WaitForKey()
-{
-       ScanCode        result;
-
-       while (!(result = inpu.LastScan))
-               ;
-       inpu.LastScan = 0;
-       return(result);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_WaitForASCII() - Waits for an ASCII char, then clears LastASCII and
-//             returns the ASCII value
-//
-///////////////////////////////////////////////////////////////////////////
-char
-IN_WaitForASCII()
-{
-       char            result;
-
-       while (!(result = inpu.LastASCII))
-               ;
-       inpu.LastASCII = '\0';
-       return(result);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_AckBack() - Waits for either an ASCII keypress or a button press
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_AckBack()
-{
-       word    i;
-
-       while (!inpu.LastScan)
-       {
-               if (inpu.MousePresent)
-               {
-                       if (INL_GetMouseButtons())
-                       {
-                               while (INL_GetMouseButtons())
-                                       ;
-                               return;
-                       }
-               }
-
-               for (i = 0;i < MaxJoys;i++)
-               {
-                       if (inpu.JoysPresent[i])
-                       {
-                               if (IN_GetJoyButtonsDB(i))
-                               {
-                                       while (IN_GetJoyButtonsDB(i))
-                                               ;
-                                       return;
-                               }
-                       }
-               }
-       }
-
-       IN_ClearKey(inpu.LastScan);
-       inpu.LastScan = sc_None;
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_Ack() - Clears user input & then calls IN_AckBack()
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_Ack()
-{
-       word    i;
-
-       IN_ClearKey(inpu.LastScan);
-       inpu.LastScan = sc_None;
-
-       if (inpu.MousePresent)
-               while (INL_GetMouseButtons())
-                                       ;
-       for (i = 0;i < MaxJoys;i++)
-               if (inpu.JoysPresent[i])
-                       while (IN_GetJoyButtonsDB(i))
-                               ;
-
-       IN_AckBack();
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_IsUserInput() - Returns true if a key has been pressed or a button
-//             is down
-//
-///////////////////////////////////////////////////////////////////////////
-boolean
-IN_IsUserInput()
-{
-       boolean result;
-       word    i;
-
-       result = inpu.LastScan;
-
-       if (inpu.MousePresent)
-               if (INL_GetMouseButtons())
-                       result = true;
-
-       for (i = 0;i < MaxJoys;i++)
-               if (inpu.JoysPresent[i])
-                       if (INL_GetJoyButtons(i))
-                               result = true;
-
-       return(result);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-//     IN_UserInput() - Waits for the specified delay time (in ticks) or the
-//             user pressing a key or a mouse button. If the clear flag is set, it
-//             then either clears the key or waits for the user to let the mouse
-//             button up.
-//
-///////////////////////////////////////////////////////////////////////////
-boolean
-IN_UserInput(dword delay,boolean clear)
-{
-       dword TimeCount = *clockdw;
-       dword   lasttime;
-
-       lasttime = TimeCount;
-       do
-       {
-               if (IN_IsUserInput())
-               {
-                       if (clear)
-                               IN_AckBack();
-                       return(true);
-               }
-       } while (TimeCount - lasttime < delay);
-       return(false);
-}
-
-boolean IN_KeyDown(byte code)
-{
-       return inpu.Keyboard[code];
-}
-\r
-void IN_ClearKey(byte code)
-{
-       inpu.Keyboard[code] = false;
-       if(code == inpu.LastScan)
-               inpu.LastScan = sc_None;
-       }
-
-boolean IN_qb(byte kee)
-{
-       printf("%u\n", inpu.Keyboard[kee]);
-       if(inpu.Keyboard[kee]==true) return 1;
-       else return 0;
-}
+                                       };\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+//     Internal routines\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     INL_KeyService() - Handles a keyboard interrupt (key up/down)\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void interrupt\r
+INL_KeyService()\r
+{\r
+static boolean special;\r
+               byte    k,c;\r
+               register byte temp;\r
+\r
+       k = inp(0x60);  // Get the scan code\r
+\r
+       // Tell the XT keyboard controller to clear the key\r
+       outp(0x61,(temp = inp(0x61)) | 0x80);\r
+       outp(0x61,temp);\r
+\r
+       if (k == 0xe0)          // Special key prefix\r
+               special = true;\r
+       else if (k == 0xe1)     // Handle Pause key\r
+               inpu.Paused = true;\r
+       else\r
+       {\r
+               if (k & 0x80)   // Break code\r
+               {\r
+                       k &= 0x7f;\r
+\r
+// DEBUG - handle special keys: ctl-alt-delete, print scrn\r
+\r
+                       inpu.Keyboard[k] = false;\r
+               }\r
+               else                    // Make code\r
+               {\r
+                       inst.LastCode = inst.CurCode;\r
+                       inst.CurCode = inpu.LastScan = k;\r
+                       inpu.Keyboard[k] = true;\r
+\r
+                       if (special)\r
+                               c = SpecialNames[k];\r
+                       else\r
+                       {\r
+                               if (k == sc_CapsLock)\r
+                               {\r
+                                       inst.CapsLock ^= true;\r
+                                       // DEBUG - make caps lock light work\r
+                               }\r
+\r
+                               if (inpu.Keyboard[sc_LShift] || inpu.Keyboard[sc_RShift])       // If shifted\r
+                               {\r
+                                       c = ShiftNames[k];\r
+                                       if ((c >= 'A') && (c <= 'Z') && inst.CapsLock)\r
+                                               c += 'a' - 'A';\r
+                               }\r
+                               else\r
+                               {\r
+                                       c = ASCIINames[k];\r
+                                       if ((c >= 'a') && (c <= 'z') && inst.CapsLock)\r
+                                               c -= 'a' - 'A';\r
+                               }\r
+                       }\r
+                       if (c)\r
+                               inpu.LastASCII = c;\r
+               }\r
+\r
+               special = false;\r
+       }\r
+\r
+       if (INL_KeyHook && !special)\r
+               INL_KeyHook();\r
+       #ifdef TESTKEYIN\r
+       printf("%c %x %u\n", c, k, inpu.Keyboard[k]);\r
+       #endif\r
+       outp(0x20,0x20);\r
+}\r
+\r
+void\r
+Mouse(int x)\r
+{\r
+       union REGS CPURegs;\r
+       x = CPURegs.x.ax;\r
+       int86(MouseInt,&CPURegs,&CPURegs);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     INL_GetMouseDelta() - Gets the amount that the mouse has moved from the\r
+//             mouse driver\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static void\r
+INL_GetMouseDelta(int *x,int *y)\r
+{\r
+       union REGS CPURegs;\r
+       Mouse(MDelta);\r
+       *x = CPURegs.x.cx;\r
+       *y = CPURegs.x.dx;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     INL_GetMouseButtons() - Gets the status of the mouse buttons from the\r
+//             mouse driver\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static word\r
+INL_GetMouseButtons(void)\r
+{\r
+       union REGS CPURegs;\r
+       word    buttons;\r
+\r
+       Mouse(MButtons);\r
+       buttons = CPURegs.x.bx;\r
+       return(buttons);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_GetJoyAbs() - Reads the absolute position of the specified joystick\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+IN_GetJoyAbs(word joy,word *xp,word *yp)\r
+{\r
+       byte    xb,yb,\r
+                       xs,ys;\r
+       word    x,y;\r
+\r
+       x = y = 0;\r
+       xs = joy? 2 : 0;                // Find shift value for x axis\r
+       xb = 1 << xs;                   // Use shift value to get x bit mask\r
+       ys = joy? 3 : 1;                // Do the same for y axis\r
+       yb = 1 << ys;\r
+\r
+// Read the absolute joystick values\r
+       __asm\r
+       {\r
+               pushf                           // Save some registers\r
+               push    si\r
+               push    di\r
+               cli                                     // Make sure an interrupt doesn't screw the timings\r
+\r
+\r
+               mov             dx,0x201\r
+               in              al,dx\r
+               out             dx,al           // Clear the resistors\r
+\r
+               mov             ah,[xb]         // Get masks into registers\r
+               mov             ch,[yb]\r
+\r
+               xor             si,si           // Clear count registers\r
+               xor             di,di\r
+               xor             bh,bh           // Clear high byte of bx for later\r
+\r
+               push    bp                      // Don't mess up stack frame\r
+               mov             bp,MaxJoyValue\r
+\r
+loo:\r
+               in              al,dx           // Get bits indicating whether all are finished\r
+\r
+               dec             bp                      // Check bounding register\r
+               jz              done            // We have a silly value - abort\r
+\r
+               mov             bl,al           // Duplicate the bits\r
+               and             bl,ah           // Mask off useless bits (in [xb])\r
+               add             si,bx           // Possibly increment count register\r
+               mov             cl,bl           // Save for testing later\r
+\r
+               mov             bl,al\r
+               and             bl,ch           // [yb]\r
+               add             di,bx\r
+\r
+               add             cl,bl\r
+               jnz             loo             // If both bits were 0, drop out\r
+\r
+done:\r
+               pop             bp\r
+\r
+               mov             cl,[xs]         // Get the number of bits to shift\r
+               shr             si,cl           //  and shift the count that many times\r
+\r
+               mov             cl,[ys]\r
+               shr             di,cl\r
+\r
+               mov             [x],si          // Store the values into the variables\r
+               mov             [y],di\r
+\r
+               pop             di\r
+               pop             si\r
+               popf                            // Restore the registers\r
+       }\r
+\r
+       *xp = x;\r
+       *yp = y;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     INL_GetJoyDelta() - Returns the relative movement of the specified\r
+//             joystick (from +/-127, scaled adaptively)\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static void\r
+INL_GetJoyDelta(word joy,int *dx,int *dy,boolean adaptive)\r
+{\r
+       word            x,y;\r
+       dword   time;\r
+       dword TimeCount = *clockdw;\r
+       JoystickDef     *def;\r
+static dword   lasttime;\r
+\r
+       IN_GetJoyAbs(joy,&x,&y);\r
+       def = inpu.JoyDefs + joy;\r
+\r
+       if (x < def->threshMinX)\r
+       {\r
+               if (x < def->joyMinX)\r
+                       x = def->joyMinX;\r
+\r
+               x = -(x - def->threshMinX);\r
+               x *= def->joyMultXL;\r
+               x >>= JoyScaleShift;\r
+               *dx = (x > 127)? -127 : -x;\r
+       }\r
+       else if (x > def->threshMaxX)\r
+       {\r
+               if (x > def->joyMaxX)\r
+                       x = def->joyMaxX;\r
+\r
+               x = x - def->threshMaxX;\r
+               x *= def->joyMultXH;\r
+               x >>= JoyScaleShift;\r
+               *dx = (x > 127)? 127 : x;\r
+       }\r
+       else\r
+               *dx = 0;\r
+\r
+       if (y < def->threshMinY)\r
+       {\r
+               if (y < def->joyMinY)\r
+                       y = def->joyMinY;\r
+\r
+               y = -(y - def->threshMinY);\r
+               y *= def->joyMultYL;\r
+               y >>= JoyScaleShift;\r
+               *dy = (y > 127)? -127 : -y;\r
+       }\r
+       else if (y > def->threshMaxY)\r
+       {\r
+               if (y > def->joyMaxY)\r
+                       y = def->joyMaxY;\r
+\r
+               y = y - def->threshMaxY;\r
+               y *= def->joyMultYH;\r
+               y >>= JoyScaleShift;\r
+               *dy = (y > 127)? 127 : y;\r
+       }\r
+       else\r
+               *dy = 0;\r
+\r
+       if (adaptive)\r
+       {\r
+               time = (TimeCount - lasttime) / 2;\r
+               if (time)\r
+               {\r
+                       if (time > 8)\r
+                               time = 8;\r
+                       *dx *= time;\r
+                       *dy *= time;\r
+               }\r
+       }\r
+       lasttime = TimeCount;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     INL_GetJoyButtons() - Returns the button status of the specified\r
+//             joystick\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static word\r
+INL_GetJoyButtons(word joy)\r
+{\r
+register       word    result;\r
+\r
+       result = inp(0x201);    // Get all the joystick buttons\r
+       result >>= joy? 6 : 4;  // Shift into bits 0-1\r
+       result &= 3;                            // Mask off the useless bits\r
+       result ^= 3;\r
+       return(result);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_GetJoyButtonsDB() - Returns the de-bounced button status of the\r
+//             specified joystick\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+word\r
+IN_GetJoyButtonsDB(word joy)\r
+{\r
+       dword TimeCount = *clockdw;\r
+       dword   lasttime;\r
+       word            result1,result2;\r
+\r
+       do\r
+       {\r
+               result1 = INL_GetJoyButtons(joy);\r
+               lasttime = TimeCount;\r
+               while(TimeCount == lasttime)\r
+               result2 = INL_GetJoyButtons(joy);\r
+       } while(result1 != result2);\r
+       return(result1);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     INL_StartKbd() - Sets up my keyboard stuff for use\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static void\r
+INL_StartKbd()\r
+{\r
+       INL_KeyHook = 0;        // Clear key hook\r
+\r
+       IN_ClearKeysDown();\r
+\r
+       OldKeyVect = _dos_getvect(KeyInt);\r
+       _dos_setvect(KeyInt,INL_KeyService);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     INL_ShutKbd() - Restores keyboard control to the BIOS\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static void\r
+INL_ShutKbd(void)\r
+{\r
+       pokeb(0x40,0x17,peekb(0x40,0x17) & 0xfaf0);     // Clear ctrl/alt/shift flags\r
+\r
+       _dos_setvect(KeyInt,OldKeyVect);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     INL_StartMouse() - Detects and sets up the mouse\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static boolean\r
+INL_StartMouse(void)\r
+{\r
+       union REGS CPURegs;\r
+       if(_dos_getvect(MouseInt))\r
+       {\r
+               Mouse(MReset);\r
+               if(CPURegs.x.ax == 0xffff)\r
+                       return(true);\r
+       }\r
+       return(false);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     INL_ShutMouse() - Cleans up after the mouse\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static void\r
+INL_ShutMouse(void)\r
+{\r
+}\r
+\r
+//\r
+//     INL_SetJoyScale() - Sets up scaling values for the specified joystick\r
+//\r
+static void\r
+INL_SetJoyScale(word joy)\r
+{\r
+       JoystickDef     *def;\r
+\r
+       def = &(inpu.JoyDefs[joy]);\r
+       def->joyMultXL = JoyScaleMax / (def->threshMinX - def->joyMinX);\r
+       def->joyMultXH = JoyScaleMax / (def->joyMaxX - def->threshMaxX);\r
+       def->joyMultYL = JoyScaleMax / (def->threshMinY - def->joyMinY);\r
+       def->joyMultYH = JoyScaleMax / (def->joyMaxY - def->threshMaxY);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_SetupJoy() - Sets up thresholding values and calls INL_SetJoyScale()\r
+//             to set up scaling values\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+IN_SetupJoy(word joy,word minx,word maxx,word miny,word maxy)\r
+{\r
+       word            d,r;\r
+       JoystickDef     *def;\r
+\r
+       def = &(inpu.JoyDefs[joy]);\r
+\r
+       def->joyMinX = minx;\r
+       def->joyMaxX = maxx;\r
+       r = maxx - minx;\r
+       d = r / 3;\r
+       def->threshMinX = ((r / 2) - d) + minx;\r
+       def->threshMaxX = ((r / 2) + d) + minx;\r
+\r
+       def->joyMinY = miny;\r
+       def->joyMaxY = maxy;\r
+       r = maxy - miny;\r
+       d = r / 3;\r
+       def->threshMinY = ((r / 2) - d) + miny;\r
+       def->threshMaxY = ((r / 2) + d) + miny;\r
+\r
+       INL_SetJoyScale(joy);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     INL_StartJoy() - Detects & auto-configures the specified joystick\r
+//                                     The auto-config assumes the joystick is centered\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static boolean\r
+INL_StartJoy(word joy)\r
+{\r
+       word            x,y;\r
+\r
+       IN_GetJoyAbs(joy,&x,&y);\r
+\r
+       if\r
+       (\r
+               ((x == 0) || (x > MaxJoyValue - 10))\r
+       ||      ((y == 0) || (y > MaxJoyValue - 10))\r
+       )\r
+               return(false);\r
+       else\r
+       {\r
+               IN_SetupJoy(joy,0,x * 2,0,y * 2);\r
+               return(true);\r
+       }\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     INL_ShutJoy() - Cleans up the joystick stuff\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static void\r
+INL_ShutJoy(word joy)\r
+{\r
+       inpu.JoysPresent[joy] = false;\r
+}\r
+\r
+//     Public routines\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_Startup() - Starts up the Input Mgr\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+IN_Startup()\r
+{\r
+       boolean checkjoys,checkmouse;\r
+       word    i;\r
+\r
+       if (inst.IN_Started)\r
+               return;\r
+\r
+       checkjoys = true;\r
+       checkmouse = true;\r
+       for (i = 1;i < __argc;i++)\r
+       {\r
+               switch (US_CheckParm(__argv[i],ParmStringsIN))\r
+               {\r
+               case 0:\r
+                       checkjoys = false;\r
+                       break;\r
+               case 1:\r
+                       checkmouse = false;\r
+                       break;\r
+               }\r
+       }\r
+\r
+       INL_StartKbd();\r
+       inpu.MousePresent = checkmouse? INL_StartMouse() : false;\r
+\r
+       for (i = 0;i < MaxJoys;i++)\r
+               inpu.JoysPresent[i] = checkjoys? INL_StartJoy(i) : false;\r
+\r
+       inst.IN_Started = true;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_Default() - Sets up default conditions for the Input Mgr\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+IN_Default(boolean gotit,player_t *player,ControlType nt)\r
+{\r
+       if\r
+       (\r
+               (!gotit)\r
+       ||      ((nt == ctrl_Joystick1) && !inpu.JoysPresent[0])\r
+       ||      ((nt == ctrl_Joystick2) && !inpu.JoysPresent[1])\r
+       ||      ((nt == ctrl_Mouse) && !inpu.MousePresent)\r
+       ||      ((nt == ctrl_Joypad1) && !inpu.JoyPadPresent[0])\r
+       ||      ((nt == ctrl_Joypad2) && !inpu.JoyPadPresent[1])\r
+       )\r
+               nt = ctrl_Keyboard1;\r
+       inpu.KbdDefs[0].button0 = 0x1d;\r
+       inpu.KbdDefs[0].button1 = 0x38;\r
+       //in.KbdDefs[0].upleft = 0x47;\r
+       inpu.KbdDefs[0].up = 0x48;\r
+       //in.KbdDefs[0].upright = 0x49;\r
+       inpu.KbdDefs[0].left = 0x4b;\r
+       inpu.KbdDefs[0].right = 0x4d;\r
+       //in.KbdDefs[0].downleft = 0x4f;\r
+       inpu.KbdDefs[0].down = 0x50;\r
+       //in.KbdDefs[0].downright = 0x51;\r
+       IN_SetControlType(0,player,nt);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_Shutdown() - Shuts down the Input Mgr\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+IN_Shutdown()\r
+{\r
+       word    i;\r
+\r
+       if (!inst.IN_Started)\r
+               return;\r
+\r
+       INL_ShutMouse();\r
+       for (i = 0;i < MaxJoys;i++)\r
+               INL_ShutJoy(i);\r
+       INL_ShutKbd();\r
+\r
+       inst.IN_Started = false;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_SetKeyHook() - Sets the routine that gets called by INL_KeyService()\r
+//                     everytime a real make/break code gets hit\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+IN_SetKeyHook(void (*hook)())\r
+{\r
+       INL_KeyHook = hook;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_ClearKeyDown() - Clears the keyboard array\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+IN_ClearKeysDown()\r
+{\r
+       int     i;\r
+\r
+       inpu.LastScan = sc_None;\r
+       inpu.LastASCII = key_None;\r
+       memset (inpu.Keyboard,0,sizeof(inpu.Keyboard));\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     INL_AdjustCursor() - Internal routine of common code from IN_ReadCursor()\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static void\r
+INL_AdjustCursor(CursorInfo *info,word buttons,int dx,int dy)\r
+{\r
+       if (buttons & (1 << 0))\r
+               info->button0 = true;\r
+       if (buttons & (1 << 1))\r
+               info->button1 = true;\r
+\r
+       info->x += dx;\r
+       info->y += dy;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_ReadCursor() - Reads the input devices and fills in the cursor info\r
+//             struct\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+IN_ReadCursor(CursorInfo *info)\r
+{\r
+       word    i,\r
+                       buttons;\r
+       int             dx,dy;\r
+\r
+       info->x = info->y = 0;\r
+       info->button0 = info->button1 = false;\r
+\r
+       if (inpu.MousePresent)\r
+       {\r
+               buttons = INL_GetMouseButtons();\r
+               INL_GetMouseDelta(&dx,&dy);\r
+               INL_AdjustCursor(info,buttons,dx,dy);\r
+       }\r
+\r
+       for (i = 0;i < MaxJoys;i++)\r
+       {\r
+               if (!inpu.JoysPresent[i])\r
+                       continue;\r
+\r
+               buttons = INL_GetJoyButtons(i);\r
+               INL_GetJoyDelta(i,&dx,&dy,true);\r
+               dx /= 64;\r
+               dy /= 64;\r
+               INL_AdjustCursor(info,buttons,dx,dy);\r
+       }\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_ReadControl() - Reads the device associated with the specified\r
+//             player and fills in the control info struct\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+IN_ReadControl(int playnum,player_t *player)\r
+{\r
+                       boolean         realdelta;\r
+                       byte            dbyte;\r
+                       word            buttons;\r
+                       int                     dx,dy;\r
+                       Motion          mx,my;\r
+                       ControlType     type;\r
+register       KeyboardDef     *def;\r
+\r
+       dx = dy = 0;\r
+       mx = my = motion_None;\r
+       buttons = 0;\r
+\r
+#if DEMO0\r
+       if (DemoMode == demo_Playback)\r
+       {\r
+               dbyte = DemoBuffer[DemoOffset + 1];\r
+               my = (dbyte & 3) - 1;\r
+               mx = ((dbyte >> 2) & 3) - 1;\r
+               buttons = (dbyte >> 4) & 3;\r
+\r
+               if (!(--DemoBuffer[DemoOffset]))\r
+               {\r
+                       DemoOffset += 2;\r
+                       if (DemoOffset >= DemoSize)\r
+                               DemoMode = demo_PlayDone;\r
+               }\r
+\r
+               realdelta = false;\r
+       }\r
+       else if (DemoMode == demo_PlayDone)\r
+               Quit("Demo playback exceeded");\r
+       else\r
+       {\r
+#endif\r
+               switch (type = player[playnum].Controls)\r
+               {\r
+               case ctrl_Keyboard1:\r
+               case ctrl_Keyboard2:\r
+                       def = &(inpu.KbdDefs[type - ctrl_Keyboard]);\r
+\r
+/*                     if (Keyboard[def->upleft])\r
+                               mx = motion_Left,my = motion_Up;\r
+                       else if (Keyboard[def->upright])\r
+                               mx = motion_Right,my = motion_Up;\r
+                       else if (Keyboard[def->downleft])\r
+                               mx = motion_Left,my = motion_Down;\r
+                       else if (Keyboard[def->downright])\r
+                               mx = motion_Right,my = motion_Down;*/\r
+\r
+                       if(!inpu.Keyboard[def->left] && !inpu.Keyboard[def->right]){\r
+                       if (inpu.Keyboard[def->up])\r
+                               my = motion_Up;\r
+                       else if (inpu.Keyboard[def->down])\r
+                               my = motion_Down;\r
+\r
+                       }else if(!inpu.Keyboard[def->up] && !inpu.Keyboard[def->down]){\r
+                       if (inpu.Keyboard[def->left])\r
+                               mx = motion_Left;\r
+                       else if (inpu.Keyboard[def->right])\r
+                               mx = motion_Right;\r
+                       }\r
+                       if (inpu.Keyboard[def->button0])\r
+                               buttons += 1 << 0;\r
+                       if (inpu.Keyboard[def->button1])\r
+                               buttons += 1 << 1;\r
+                       realdelta = false;\r
+                       break;\r
+               case ctrl_Joystick1:\r
+               case ctrl_Joystick2:\r
+                       INL_GetJoyDelta(type - ctrl_Joystick,&dx,&dy,false);\r
+                       buttons = INL_GetJoyButtons(type - ctrl_Joystick);\r
+                       realdelta = true;\r
+                       break;\r
+               case ctrl_Mouse:\r
+                       INL_GetMouseDelta(&dx,&dy);\r
+                       buttons = INL_GetMouseButtons();\r
+                       realdelta = true;\r
+                       break;\r
+               case ctrl_Joypad1:\r
+               case ctrl_Joypad2:\r
+                       printf("wwww");\r
+                       break;\r
+               }\r
+#ifdef DEMO0\r
+       }\r
+#endif\r
+\r
+       if (realdelta)\r
+       {\r
+               mx = (dx < 0)? motion_Left : ((dx > 0)? motion_Right : motion_None);\r
+               my = (dy < 0)? motion_Up : ((dy > 0)? motion_Down : motion_None);\r
+       }\r
+       else\r
+       {\r
+               dx = mx * 127;\r
+               dy = my * 127;\r
+       }\r
+\r
+       player[playnum].info.x = dx;\r
+       player[playnum].info.xaxis = mx;\r
+       player[playnum].info.y = dy;\r
+       player[playnum].info.yaxis = my;\r
+       player[playnum].info.button0 = buttons & (1 << 0);\r
+       player[playnum].info.button1 = buttons & (1 << 1);\r
+       player[playnum].info.button2 = buttons & (1 << 2);\r
+       player[playnum].info.button3 = buttons & (1 << 3);\r
+       player[playnum].info.dir = DirTable[((my + 1) * 3) + (mx + 1)];\r
+\r
+#if DEMO0\r
+       if (DemoMode == demo_Record)\r
+       {\r
+               // Pack the control info into a byte\r
+               dbyte = (buttons << 4) | ((mx + 1) << 2) | (my + 1);\r
+\r
+               if\r
+               (\r
+                       (DemoBuffer[DemoOffset + 1] == dbyte)\r
+               &&      (DemoBuffer[DemoOffset] < 255)\r
+               )\r
+                       (DemoBuffer[DemoOffset])++;\r
+               else\r
+               {\r
+                       if (DemoOffset || DemoBuffer[DemoOffset])\r
+                               DemoOffset += 2;\r
+\r
+                       if (DemoOffset >= DemoSize)\r
+                               Quit("Demo buffer overflow");\r
+\r
+                       DemoBuffer[DemoOffset] = 1;\r
+                       DemoBuffer[DemoOffset + 1] = dbyte;\r
+               }\r
+       }\r
+#endif\r
+#ifdef TESTCONTROLNOISY\r
+printf("dir=%d\n", player[playnum].info.dir);\r
+#endif\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_SetControlType() - Sets the control type to be used by the specified\r
+//             player\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+IN_SetControlType(word playnum,player_t *player,ControlType type)\r
+{\r
+       // DEBUG - check that requested type is present?\r
+       player[playnum].Controls = type;\r
+}\r
+\r
+#if DEMO0\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_StartDemoRecord() - Starts the demo recording, using a buffer the\r
+//             size passed. Returns if the buffer allocation was successful\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+boolean\r
+IN_StartDemoRecord(word bufsize)\r
+{\r
+       if (!bufsize)\r
+               return(false);\r
+\r
+       MM_GetPtr((memptr *)&DemoBuffer,bufsize);\r
+       DemoMode = demo_Record;\r
+       DemoSize = bufsize & ~1;\r
+       DemoOffset = 0;\r
+       DemoBuffer[0] = DemoBuffer[1] = 0;\r
+\r
+       return(true);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_StartDemoPlayback() - Plays back the demo pointed to of the given size\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+IN_StartDemoPlayback(byte /*__segment*/ *buffer,word bufsize)\r
+{\r
+       DemoBuffer = buffer;\r
+       DemoMode = demo_Playback;\r
+       DemoSize = bufsize & ~1;\r
+       DemoOffset = 0;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_StopDemo() - Turns off demo mode\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+IN_StopDemo(void)\r
+{\r
+       if ((DemoMode == demo_Record) && DemoOffset)\r
+               DemoOffset += 2;\r
+\r
+       DemoMode = demo_Off;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_FreeDemoBuffer() - Frees the demo buffer, if it's been allocated\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+IN_FreeDemoBuffer(void)\r
+{\r
+       if (DemoBuffer)\r
+               MM_FreePtr((memptr *)&DemoBuffer);\r
+}\r
+#endif\r
+\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_GetScanName() - Returns a string containing the name of the\r
+//             specified scan code\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+byte *\r
+IN_GetScanName(ScanCode scan)\r
+{\r
+       byte            **p;\r
+       ScanCode        far *s;\r
+\r
+       for (s = ExtScanCodes,p = ExtScanNames;*s;p++,s++)\r
+               if (*s == scan)\r
+                       return(*p);\r
+\r
+       return(ScanNames[scan]);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_WaitForKey() - Waits for a scan code, then clears LastScan and\r
+//             returns the scan code\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+ScanCode\r
+IN_WaitForKey()\r
+{\r
+       ScanCode        result;\r
+\r
+       while (!(result = inpu.LastScan))\r
+               ;\r
+       inpu.LastScan = 0;\r
+       return(result);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_WaitForASCII() - Waits for an ASCII char, then clears LastASCII and\r
+//             returns the ASCII value\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+char\r
+IN_WaitForASCII()\r
+{\r
+       char            result;\r
+\r
+       while (!(result = inpu.LastASCII))\r
+               ;\r
+       inpu.LastASCII = '\0';\r
+       return(result);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_AckBack() - Waits for either an ASCII keypress or a button press\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+IN_AckBack()\r
+{\r
+       word    i;\r
+\r
+       while (!inpu.LastScan)\r
+       {\r
+               if (inpu.MousePresent)\r
+               {\r
+                       if (INL_GetMouseButtons())\r
+                       {\r
+                               while (INL_GetMouseButtons())\r
+                                       ;\r
+                               return;\r
+                       }\r
+               }\r
+\r
+               for (i = 0;i < MaxJoys;i++)\r
+               {\r
+                       if (inpu.JoysPresent[i])\r
+                       {\r
+                               if (IN_GetJoyButtonsDB(i))\r
+                               {\r
+                                       while (IN_GetJoyButtonsDB(i))\r
+                                               ;\r
+                                       return;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       IN_ClearKey(inpu.LastScan);\r
+       inpu.LastScan = sc_None;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_Ack() - Clears user input & then calls IN_AckBack()\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+IN_Ack()\r
+{\r
+       word    i;\r
+\r
+       IN_ClearKey(inpu.LastScan);\r
+       inpu.LastScan = sc_None;\r
+\r
+       if (inpu.MousePresent)\r
+               while (INL_GetMouseButtons())\r
+                                       ;\r
+       for (i = 0;i < MaxJoys;i++)\r
+               if (inpu.JoysPresent[i])\r
+                       while (IN_GetJoyButtonsDB(i))\r
+                               ;\r
+\r
+       IN_AckBack();\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_IsUserInput() - Returns true if a key has been pressed or a button\r
+//             is down\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+boolean\r
+IN_IsUserInput()\r
+{\r
+       boolean result;\r
+       word    i;\r
+\r
+       result = inpu.LastScan;\r
+\r
+       if (inpu.MousePresent)\r
+               if (INL_GetMouseButtons())\r
+                       result = true;\r
+\r
+       for (i = 0;i < MaxJoys;i++)\r
+               if (inpu.JoysPresent[i])\r
+                       if (INL_GetJoyButtons(i))\r
+                               result = true;\r
+\r
+       return(result);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     IN_UserInput() - Waits for the specified delay time (in ticks) or the\r
+//             user pressing a key or a mouse button. If the clear flag is set, it\r
+//             then either clears the key or waits for the user to let the mouse\r
+//             button up.\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+boolean\r
+IN_UserInput(dword delay,boolean clear)\r
+{\r
+       dword TimeCount = *clockdw;\r
+       dword   lasttime;\r
+\r
+       lasttime = TimeCount;\r
+       do\r
+       {\r
+               if (IN_IsUserInput())\r
+               {\r
+                       if (clear)\r
+                               IN_AckBack();\r
+                       return(true);\r
+               }\r
+       } while (TimeCount - lasttime < delay);\r
+       return(false);\r
+}\r
+\r
+boolean IN_KeyDown(byte code)\r
+{\r
+       return inpu.Keyboard[code];\r
+}\r
+\r
+void IN_ClearKey(byte code)\r
+{\r
+       inpu.Keyboard[code] = false;\r
+       if(code == inpu.LastScan)\r
+               inpu.LastScan = sc_None;\r
+       }\r
+\r
+boolean IN_qb(byte kee)\r
+{\r
+       printf("%u\n", inpu.Keyboard[kee]);\r
+       if(inpu.Keyboard[kee]==true) return 1;\r
+       else return 0;\r
+}\r