-/* Catacomb Apocalypse Source Code\r
- * Copyright (C) 1993-2014 Flat Rock Software\r
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2017 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
*\r
- * This program is free software; you can redistribute it and/or modify\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
* it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
+ * the Free Software Foundation; either version 3 of the License, or\r
* (at your option) any later version.\r
*\r
- * This program is distributed in the hope that it will be useful,\r
+ * Project 16 is distributed in the hope that it will be useful,\r
* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
* GNU General Public License for more details.\r
*\r
- * 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"
-
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\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
+#pragma hdrstop\r
+\r
+static word far* clockw= (word far*) 0x046C; /* 18.2hz clock */\r
+\r
/*\r
=============================================================================\r
\r
GLOBAL VARIABLES\r
\r
=============================================================================\r
-*/
-struct inconfig
-{
- boolean MousePresent;\r
- boolean JoysPresent[MaxJoys];\r
- boolean JoyPadPresent[MaxPads];
+*/\r
+/*struct inconfig\r
+{\r
+ boolean MousePresent;\r
+ boolean JoysPresent[MaxJoys];\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
+} inpu;*/\r
+\r
+//gvar->in.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
-static struct instat {
- boolean IN_Started;\r
- boolean CapsLock;\r
- ScanCode CurCode,LastCode;
-} inst;
-\r
-static void (*INL_KeyHook)(void);
-static void interrupt (*OldKeyVect)(void);
-static char *ParmStringsIN[] = {"nojoys","nomouse",nil};
+*/\r
+\r
+#ifdef __cplusplus /* Function must be declared C style */\r
+extern "C" {\r
+#endif\r
+\r
+/*static struct instat {\r
+ boolean CapsLock;\r
+ ScanCode CurCode,LastCode;\r
+\r
+ boolean Keyboard[NumCodes];\r
+ boolean Paused;\r
+ char LastASCII;\r
+ ScanCode LastScan;\r
+} inst;*/\r
+\r
+//the def stuff is need fix warnings\r
+#ifndef INSTDEFED\r
+#define INSTDEFED\r
+static inst_t inst;\r
+#endif\r
\r
static byte far ASCIINames[] = // Unshifted ASCII for scan codes\r
{\r
"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
- //dir_Nortinest,\r
- dir_North,\r
- //dir_NorthEast,\r
+ /*dir_NorthWest, */dir_North,/* dir_NorthEast,*/\r
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->up])
- my = motion_Up;
- else if (inpu.Keyboard[def->down])
- my = motion_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
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-// 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;
-}
+ /*dir_SouthWest, */dir_South/*, dir_SouthEast*/\r
+ };\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+static void (*INL_KeyHook)(void);\r
+static void interrupt (*OldKeyVect)(void);\r
+static char *ParmStringsIN[] = {"nojoys","nomouse",nil};\r
+static void INL_StartKbd(void);\r
+\r
+// Internal routines\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+// INL_KeyService() - Handles a keyboard interrupt (key up/down)\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+/*static */void interrupt\r
+INL_KeyService(void)\r
+{\r
+static boolean special;\r
+ byte k,c,\r
+ temp;\r
+\r
+ k = inportb(0x60); // Get the scan code\r
+\r
+ // Tell the XT keyboard controller to clear the key\r
+ outportb(0x61,(temp = inportb(0x61)) | 0x80);\r
+ outportb(0x61,temp);\r
+\r
+ if (k == 0xe0) // Special key prefix\r
+ special = true;\r
+ else if (k == 0xe1) // Handle Pause key\r
+ inst.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
+ inst.Keyboard[k] = false;\r
+ }\r
+ else // Make code\r
+ {\r
+ inst.LastCode = inst.CurCode;\r
+ inst.CurCode = inst.LastScan = k;\r
+ inst.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 (inst.Keyboard[sc_LShift] || inst.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
+ inst.LastASCII = c;\r
+ }\r
+\r
+ special = false;\r
+ }\r
+\r
+ if (INL_KeyHook && !special)\r
+ INL_KeyHook();\r
+#ifdef __DEBUG_InputMgr__\r
+ if(dbg_testkeyin > 0) printf("%c %u [0x%x %u] %u\n", c, c, k, k, inst.Keyboard[k]);\r
+#endif\r
+ outportb(0x20,0x20);\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
+ Mouse(MDelta);\r
+ *x = _CX;\r
+ *y = _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
+ word buttons;\r
+\r
+ Mouse(MButtons);\r
+ buttons = _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
+ 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
+#ifdef __BORLANDC__\r
+ }\r
+#endif\r
+loo:\r
+#ifdef __BORLANDC__\r
+ __asm {\r
+#endif\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
+#ifdef __BORLANDC__\r
+ }\r
+#endif\r
+done:\r
+#ifdef __BORLANDC__\r
+ __asm {\r
+#endif\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)\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void INL_GetJoyDelta(word joy,int *dx,int *dy/*,boolean adaptive*/, global_game_variables_t *gvar)\r
+{\r
+ word x,y;\r
+ word TimeCount = *clockw;\r
+ JoystickDef *def;\r
+static word lasttime;\r
+\r
+ IN_GetJoyAbs(joy,&x,&y);\r
+ def = gvar->in.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
+// 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 = inportb(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
+ word TimeCount = *clockw;\r
+ word lasttime;\r
+ word result1,result2;\r
+\r
+ do\r
+ {\r
+ result1 = INL_GetJoyButtons(joy);\r
+ lasttime = TimeCount;\r
+ while(TimeCount == lasttime)\r
+ //;\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(void)\r
+{\r
+ INL_KeyHook = NULL; // Clear key hook\r
+\r
+ IN_ClearKeysDown();\r
+\r
+ OldKeyVect = getvect(KeyInt);//IN_KbdLED();\r
+ 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
+ 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
+#if 0\r
+ if (getvect(MouseInt))\r
+ {\r
+ Mouse(MReset);\r
+ if (_AX == 0xffff)\r
+ return(true);\r
+ }\r
+ return(false);\r
+#else\r
+ byte far *vector;\r
+\r
+\r
+ if ((vector=MK_FP(peek(0,0x33*4+2),peek(0,0x33*4)))==NULL)\r
+ return false;\r
+\r
+ if (*vector == 207)\r
+ return false;\r
+\r
+ Mouse(MReset);\r
+ return true;\r
+#endif\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, global_game_variables_t *gvar)\r
+{\r
+ JoystickDef *def;\r
+\r
+ def = &(gvar->in.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, global_game_variables_t *gvar)\r
+{\r
+ word d,r;\r
+ JoystickDef *def;\r
+\r
+ def = &(gvar->in.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, gvar);\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, global_game_variables_t *gvar)\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, gvar);\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, global_game_variables_t *gvar)\r
+{\r
+ gvar->in.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(global_game_variables_t *gvar)\r
+{\r
+ boolean checkjoys,checkmouse;\r
+ word i;\r
+\r
+ if (gvar->in.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
+ gvar->in.MousePresent = checkmouse? INL_StartMouse() : false;\r
+\r
+ for (i = 0;i < MaxJoys;i++)\r
+ gvar->in.JoysPresent[i] = checkjoys? INL_StartJoy(i, gvar) : false;\r
+\r
+ gvar->in.inst = &inst;\r
+\r
+ gvar->in.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, global_game_variables_t *gvar)\r
+{\r
+ int i;\r
+ if\r
+ (\r
+ (!gotit)\r
+ || ((nt == ctrl_Joystick1) && !gvar->in.JoysPresent[0])\r
+ || ((nt == ctrl_Joystick2) && !gvar->in.JoysPresent[1])\r
+ || ((nt == ctrl_Mouse) && !gvar->in.MousePresent)\r
+ )\r
+ nt = ctrl_Keyboard1;\r
+ gvar->in.KbdDefs[0].button0 = 0x1c;\r
+ gvar->in.KbdDefs[0].button1 = 0x38;\r
+ //in.KbdDefs[0].upleft = 0x47;\r
+ gvar->in.KbdDefs[0].up = 0x48;\r
+ //in.KbdDefs[0].upright = 0x49;\r
+ gvar->in.KbdDefs[0].left = 0x4b;\r
+ gvar->in.KbdDefs[0].right = 0x4d;\r
+ //in.KbdDefs[0].downleft = 0x4f;\r
+ gvar->in.KbdDefs[0].down = 0x50;\r
+ //in.KbdDefs[0].downright = 0x51;\r
+ IN_SetControlType(player,nt);\r
+ for(i=0; i>MaxPlayers;i++)\r
+ player[i].enti.d =2;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+// IN_Shutdown() - Shuts down the Input Mgr\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+IN_Shutdown(global_game_variables_t *gvar)\r
+{\r
+ word i;\r
+\r
+ if (!gvar->in.IN_Started)\r
+ return;\r
+\r
+ INL_ShutMouse();\r
+ for (i = 0;i < MaxJoys;i++)\r
+ INL_ShutJoy(i, gvar);\r
+ INL_ShutKbd();\r
+\r
+ gvar->in.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_ClearKeysDown() - Clears the keyboard array\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+IN_ClearKeysDown(void)\r
+{\r
+ //int i;\r
+\r
+ inst.LastScan = sc_None;\r
+ inst.LastASCII = key_None;\r
+ memset (inst.Keyboard,0,sizeof(inst.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, global_game_variables_t *gvar)\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 (gvar->in.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 (!gvar->in.JoysPresent[i])\r
+ continue;\r
+\r
+ buttons = INL_GetJoyButtons(i);\r
+ INL_GetJoyDelta(i,&dx,&dy/*,true*/, gvar);\r
+ dx /= 64;\r
+ dy /= 64;\r
+ INL_AdjustCursor(info,buttons,dx,dy);\r
+ }\r
+}\r
+\r
+//if else for gfxtesting and direction\r
+#define DIRECTIONIFELSE (player->info.dir == 2)\r
+//#define NDIRECTIONIFELSE (player->info.dir != 2)\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(player_t *player, global_game_variables_t *gvar)\r
+{\r
+ boolean realdelta;\r
+#if DEMO0\r
+ byte dbyte;\r
+#endif\r
+ word buttons;\r
+ int dx,dy;\r
+ Motion mx,my;\r
+ ControlType type;\r
+ sword conpee;\r
+ byte dir=DirTable[2];\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->Controls)\r
+ {\r
+ case ctrl_Keyboard:\r
+ def = &(gvar->in.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
+//TODO: make this into a function that the joystick AND keyboard can use wwww\r
+ if(DIRECTIONIFELSE)//(player->info.dir == 2)\r
+ {\r
+ if(!inst.Keyboard[def->left] && !inst.Keyboard[def->right]){\r
+ if((inst.Keyboard[def->up] && !inst.Keyboard[def->down]))\r
+ my = motion_Up;\r
+ if((inst.Keyboard[def->down] && !inst.Keyboard[def->up]))\r
+ my = motion_Down;\r
+ }else if(!inst.Keyboard[def->up] && !inst.Keyboard[def->down]){\r
+ if((inst.Keyboard[def->left] && !inst.Keyboard[def->right]))\r
+ mx = motion_Left;\r
+ if((inst.Keyboard[def->right] && !inst.Keyboard[def->left]))\r
+ mx = motion_Right;\r
+ }else{ //2 keys pressed\r
+ switch (player->pdir)\r
+ {\r
+ case 0:\r
+ case 4:\r
+ if((inst.Keyboard[def->left] && !inst.Keyboard[def->right])){ dir = DirTable[1]; }//mx = motion_Left; }\r
+ else if((inst.Keyboard[def->right] && !inst.Keyboard[def->left])){ dir = DirTable[3]; }//mx = motion_Right; }\r
+ break;\r
+ case 1:\r
+ case 3:\r
+ if((inst.Keyboard[def->up] && !inst.Keyboard[def->down])){ dir = DirTable[0]; }//my = motion_Up; }\r
+ else if((inst.Keyboard[def->down] && !inst.Keyboard[def->up])){ dir = DirTable[4]; }//my = motion_Down; }\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+#ifdef __DEBUG_InputMgr__\r
+ //if(dbg_testcontrolnoisy > 0){ printf("dir=%c ", dirchar(dir)); printf("pdir=%c ", dirchar(player->pdir)); }\r
+#endif\r
+ }\r
+ }\r
+ //input from player\r
+ if (inst.Keyboard[def->button0])\r
+ buttons += 1 << 0;\r
+ if (inst.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*/, gvar);\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
+ }\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->info.x = dx;\r
+ player->info.xaxis = mx;\r
+ player->info.y = dy;\r
+ player->info.yaxis = my;\r
+ player->info.button0 = buttons & (1 << 0);\r
+ player->info.button1 = buttons & (1 << 1);\r
+ player->info.button2 = buttons & (1 << 2);\r
+ player->info.button3 = buttons & (1 << 3);\r
+// player->info.dir = DirTable[((my + 1) * 3) + (mx + 1)];\r
+ conpee=(((my + 1) * 2) + (mx + 1))-1;\r
+ player->info.dir = DirTable[conpee];\r
+\r
+ if(DirTable[conpee]!=2) player->pdir=DirTable[conpee];\r
+ if(player->enti.q==1 &&( dir!=2 || (mx!=motion_None || my!=motion_None)))\r
+ {\r
+ if(dir==2) player->enti.d = player->info.dir;\r
+ else player->enti.d = DirTable[dir];\r
+ }\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 __DEBUG_InputMgr__\r
+if(dbg_joymousedelta)\r
+{\r
+ {\r
+static int old_dx,old_dy;\r
+static word old_buttons=0;\r
+ if(dx!=old_dx || dy!=old_dy) printf("dx,dy [%d,%d] %d,%d\n", dx, dy, mx, my);\r
+ if(dx!=old_dx) old_dx=dx;\r
+ if(dy!=old_dy) old_dy=dy;\r
+ if(old_buttons!=buttons)\r
+ {\r
+ printf(" buttons={%u,%u,%u,%u}\n", player->info.button0, player->info.button1, player->info.button2, player->info.button3);\r
+ old_buttons=buttons;\r
+ }\r
+ }\r
+}\r
+\r
+if(dbg_testcontrolnoisy > 0)\r
+if(player->info.dir!=2/*(inst.Keyboard[def->up] || inst.Keyboard[def->down] || inst.Keyboard[def->left] || inst.Keyboard[def->right])*/ || player->enti.q>1)\r
+{\r
+ //printf("b1=%u b2=%u b3=%u b4=%u ", player->info.button0, player->info.button1, player->info.button2, player->info.button3);\r
+ //printf("q=%d ", player->enti.q);\r
+ //printf("cpee=%c ", dirchar(conpee));\r
+ printf("pdir=%c d=%c dir=%c ", dirchar(player->pdir), dirchar(player->enti.d), dirchar(player->info.dir));\r
+ /*if(realdelta) */printf("dx=%d dy=%d mx=%d my=%d", player->info.x, player->info.y, player->info.xaxis, player->info.yaxis);\r
+ //else if(!realdelta) printf("%c%d %c%d %c%d %c%d", dirchar(0), inst.Keyboard[def->up], dirchar(4), inst.Keyboard[def->down], dirchar(1), inst.Keyboard[def->left], dirchar(3), inst.Keyboard[def->right]);\r
+ printf("\n");\r
+}\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(player_t *player,ControlType type)\r
+{\r
+ // DEBUG - check that requested type is present?\r
+ player->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(void)\r
+{\r
+ ScanCode result;\r
+\r
+ while (!(result = inst.LastScan))\r
+ ;\r
+ inst.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(void)\r
+{\r
+ char result;\r
+\r
+ while (!(result = inst.LastASCII))\r
+ ;\r
+ inst.LastASCII = '\0';\r
+ return(result);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+// IN_Ack() - waits for a button or key press. If a button is down, upon\r
+// calling, it must be released for it to be recognized\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+\r
+boolean btnstate[8];\r
+\r
+void IN_StartAck(global_game_variables_t *gvar)\r
+{\r
+ unsigned i,buttons;\r
+\r
+//\r
+// get initial state of everything\r
+//\r
+ IN_ClearKeysDown();\r
+ memset (btnstate,0,sizeof(btnstate));\r
+\r
+ buttons = IN_JoyButtons () << 4;\r
+ if (gvar->in.MousePresent)\r
+ buttons |= IN_MouseButtons (gvar);\r
+\r
+ for (i=0;i<8;i++,buttons>>=1)\r
+ if (buttons&1)\r
+ btnstate[i] = true;\r
+}\r
+\r
+\r
+boolean IN_CheckAck (global_game_variables_t *gvar)\r
+{\r
+ unsigned i,buttons;\r
+\r
+//\r
+// see if something has been pressed\r
+//\r
+ if(!gvar->in.IN_Started)\r
+ getch();\r
+ else\r
+ {\r
+ if (inst.LastScan)\r
+ return true;\r
+ }\r
+\r
+ buttons = IN_JoyButtons () << 4;\r
+ if (gvar->in.MousePresent)\r
+ buttons |= IN_MouseButtons (gvar);\r
+\r
+ for (i=0;i<8;i++,buttons>>=1)\r
+ if ( buttons&1 )\r
+ {\r
+ if (!btnstate[i])\r
+ return true;\r
+ }\r
+ else\r
+ btnstate[i]=false;\r
+\r
+ return false;\r
+}\r
+\r
+\r
+void IN_Ack (global_game_variables_t *gvar)\r
+{\r
+ IN_StartAck (gvar);\r
+\r
+ while (!IN_CheckAck (gvar))\r
+ ;\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(global_game_variables_t *gvar)\r
+{\r
+ boolean result;\r
+ word i;\r
+\r
+ result = inst.LastScan;\r
+\r
+ if (gvar->in.MousePresent)\r
+ if (INL_GetMouseButtons())\r
+ result = true;\r
+\r
+ for (i = 0;i < MaxJoys;i++)\r
+ if (gvar->in.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 IN_UserInput(word delay, global_game_variables_t *gvar)\r
+{\r
+ word TimeCount = *clockw;\r
+ word lasttime;\r
+\r
+ lasttime = TimeCount;\r
+ IN_StartAck (gvar);\r
+ do\r
+ {\r
+ if (IN_CheckAck(gvar))\r
+ return true;\r
+ } while (TimeCount - lasttime < delay);\r
+ return(false);\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+===================\r
+=\r
+= IN_MouseButtons\r
+=\r
+===================\r
+*/\r
+\r
+byte IN_MouseButtons (global_game_variables_t *gvar)\r
+{\r
+ if (gvar->in.MousePresent)\r
+ {\r
+ Mouse(MButtons);\r
+ return _BX;\r
+ }\r
+ else\r
+ return 0;\r
+}\r
+\r
+\r
+/*\r
+===================\r
+=\r
+= IN_JoyButtons\r
+=\r
+===================\r
+*/\r
+\r
+byte IN_JoyButtons (void)\r
+{\r
+ byte joybits;\r
+\r
+ joybits = inportb(0x201); // Get all the joystick buttons\r
+ joybits >>= 4; // only the high bits are useful\r
+ joybits ^= 15; // return with 1=pressed\r
+\r
+ return joybits;\r
+}\r
+\r
+boolean IN_KeyDown(byte code)\r
+{\r
+#ifdef __DEBUG_InputMgr__\r
+// if(inst.Keyboard[code])\r
+// printf("IN_KeyDown(%c): %u\n", code, inst.Keyboard[code]);\r
+ if(!dbg_nointest)\r
+#endif\r
+ return inst.Keyboard[code];\r
+#ifdef __DEBUG_InputMgr__\r
+ else\r
+ if(dbg_nointest && kbhit())\r
+ return 1;\r
+ else\r
+ return 0;\r
+#endif\r
+}\r
+\r
+void IN_ClearKey(byte code)\r
+{\r
+ inst.Keyboard[code] = false;\r
+ if(code == inst.LastScan)\r
+ inst.LastScan = sc_None;\r
+ }\r
+\r
+boolean IN_qb(byte kee)\r
+{\r
+#ifdef __DEBUG_InputMgr__\r
+ if(dbg_testkeyin) if(inst.Keyboard[kee]) printf("IN_qb(): %u\n", inst.Keyboard[kee]);\r
+#endif\r
+ if(inst.Keyboard[kee]==true) return 1;\r
+ else return 0;\r
+}\r
+\r
+ScanCode IN_GetLastScan()\r
+{\r
+ return inst.LastScan;\r
+}\r
+\r
+ScanCode IN_GetCurCode()\r
+{\r
+ return inst.CurCode;\r
+}\r
+\r
+void IN_KbdLED()\r
+{\r
+ byte far *lock_key;\r
+\r
+ // turn off num-lock via BIOS\r
+ lock_key = MK_FP(0x040, 0x017); // Pointing to the address of the bios shift state keys\r
+ *lock_key&=(~(16 | 32 | 64)); // toggle off the locks by changing the values of the 4th, 5th, and 6th bits of the address byte of 0040:0017\r
+ OldKeyVect(); // call BIOS keyhandler to change keyboard lights\r
+}\r