-/* Catacomb Armageddon Source Code
- * Copyright (C) 1993-2014 Flat Rock Software
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-//
-// 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"
-
+/* Catacomb Apocalypse Source Code\r
+ * Copyright (C) 1993-2014 Flat Rock Software\r
+ *\r
+ * This program 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
+ * (at your option) any later version.\r
+ *\r
+ * This program 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
+ */\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
+boolean testkeyin=0,testcontrolnoisy=0,testctrltype=0;\r
+\r
/*\r
=============================================================================\r
\r
\r
=============================================================================\r
*/\r
-// Global variables
- boolean JoystickCalibrated=false; // MDM (GAMERS EDGE) - added\r
- ControlType ControlTypeUsed; // MDM (GAMERS EDGE) - added\r
- boolean Keyboard[NumCodes];\r
- boolean Paused;\r
- char LastASCII;\r
- ScanCode LastScan;\r
-\r
- //KeyboardDef KbdDefs = {0x1d,0x38,0x47,0x48,0x49,0x4b,0x4d,0x4f,0x50,0x51};\r
- JoystickDef JoyDefs[MaxJoys];\r
- ControlType Controls[MaxPlayers];\r
-\r
- dword MouseDownCount;
-
-// Internal routines
-///////////////////////////////////////////////////////////////////////////
-//
-// INL_KeyService() - Handles a keyboard interrupt (key up/down)
-//
-///////////////////////////////////////////////////////////////////////////
-void interrupt
-INL_KeyService(void)
-{
-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
- Paused = true;
- else
- {
- if (k & 0x80) // Break code
- {
- k &= 0x7f;
-
-// DEBUG - handle special keys: ctl-alt-delete, print scrn
-
- Keyboard[k] = false;
- }
- else // Make code
- {
- LastCode = CurCode;
- CurCode = LastScan = k;
- Keyboard[k] = true;
-
- if (special)
- c = SpecialNames[k];
- else
- {
- if (k == sc_CapsLock)
- {
- CapsLock ^= true;
- // DEBUG - make caps lock light work
- }
-
- if (Keyboard[sc_LShift] || Keyboard[sc_RShift]) // If shifted
- {
- c = ShiftNames[k];
- if ((c >= 'A') && (c <= 'Z') && CapsLock)
- c += 'a' - 'A';
- }
- else
- {
- c = ASCIINames[k];
- if ((c >= 'a') && (c <= 'z') && CapsLock)
- c -= 'a' - 'A';
- }
- }
- if (c)
- LastASCII = c;
- }
-
- special = false;
- }
-
- if (INL_KeyHook && !special)
- INL_KeyHook();
- #ifdef TESTKEYIN
- printf("%c %x %u\n", c, k, 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 = 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(void)
-{
- 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 = &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 = &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)
-{
- JoysPresent[joy] = false;
-}
-
-// Public routines
-
-///////////////////////////////////////////////////////////////////////////
-//
-// IN_Startup() - Starts up the Input Mgr
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_Startup(void)
-{
- boolean checkjoys,checkmouse;
- word i;
-
- if (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();
- MousePresent = checkmouse? INL_StartMouse() : false;
-
- for (i = 0;i < MaxJoys;i++)
- JoysPresent[i] = checkjoys? INL_StartJoy(i) : false;
-
- IN_Started = true;
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-// IN_Default() - Sets up default conditions for the Input Mgr
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_Default(boolean gotit,ControlType in)
-{
- if
- (
- (!gotit)
- || ((in == ctrl_Joystick1) && !JoysPresent[0])
- || ((in == ctrl_Joystick2) && !JoysPresent[1])
- || ((in == ctrl_Mouse) && !MousePresent)
- )
- in = ctrl_Keyboard1;
- IN_SetControlType(0,in);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-// IN_Shutdown() - Shuts down the Input Mgr
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_Shutdown(void)
-{
- word i;
-
- if (!IN_Started)
- return;
-
- INL_ShutMouse();
- for (i = 0;i < MaxJoys;i++)
- INL_ShutJoy(i);
- INL_ShutKbd();
-
- 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(void)
-{
- int i;
-
- LastScan = sc_None;
- LastASCII = key_None;
- memset (Keyboard,0,sizeof(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 (MousePresent)
- {
- buttons = INL_GetMouseButtons();
- INL_GetMouseDelta(&dx,&dy);
- INL_AdjustCursor(info,buttons,dx,dy);
- }
-
- for (i = 0;i < MaxJoys;i++)
- {
- if (!JoysPresent[i])
- continue;
-
- buttons = INL_GetJoyButtons(i);
- INL_GetJoyDelta(i,&dx,&dy,true);
- dx /= 64;
- dy /= 64;
- INL_AdjustCursor(info,buttons,dx,dy);
- }
-}
-
-#ifndef DUMU
-///////////////////////////////////////////////////////////////////////////
-//
-// IN_ReadControl() - Reads the device associated with the specified
-// player and fills in the control info struct
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_ReadControl(int player,ControlInfo *info)
-{
- boolean realdelta=false; // MDM (GAMERS EDGE)
- 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
- {
- // MDM begin (GAMERS EDGE) - added this block
- ControlTypeUsed = ctrl_None;
-
- // Handle mouse input...
- //
- if ((MousePresent) && (ControlTypeUsed == ctrl_None))
- {
- INL_GetMouseDelta(&dx,&dy);
- buttons = INL_GetMouseButtons();
- realdelta = true;
- if (dx || dy || buttons)
- ControlTypeUsed = ctrl_Mouse;
- }
-
- // Handle joystick input...
- //
- if ((JoystickCalibrated) && (ControlTypeUsed == ctrl_None))
- {
- type = ctrl_Joystick1;
- INL_GetJoyDelta(type - ctrl_Joystick,&dx,&dy,false);
- buttons = INL_GetJoyButtons(type - ctrl_Joystick);
- realdelta = true;
- if (dx || dy || buttons)
- ControlTypeUsed = ctrl_Joystick;
- }
-
- // Handle keyboard input...
- //
- if (ControlTypeUsed == ctrl_None)
- {
- type = ctrl_Keyboard1;
- def = &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 (Keyboard[def->up])
- my = motion_Up;
- else if (Keyboard[def->down])
- my = motion_Down;
-
- if (Keyboard[def->left])
- mx = motion_Left;
- else if (Keyboard[def->right])
- mx = motion_Right;
-
- if (Keyboard[def->button0])
- buttons += 1 << 0;
- if (Keyboard[def->button1])
- buttons += 1 << 1;
- realdelta = false;
- if (mx || my || buttons)
- ControlTypeUsed = ctrl_Keyboard;
- } // MDM end (GAMERS EDGE)
- }
-
- 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;
- }
-
- info->x = dx;
- info->xaxis = mx;
- info->y = dy;
- info->yaxis = my;
- info->button0 = buttons & (1 << 0);
- info->button1 = buttons & (1 << 1);
- 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
-}
-
-#else
-///////////////////////////////////////////////////////////////////////////
-//
-// IN_ReadControl() - Reads the device associated with the specified
-// player and fills in the control info struct
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_ReadControl(int player,ControlInfo *info)
-{
- 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 = Controls[player])
- {
- case ctrl_Keyboard1:
- case ctrl_Keyboard2:
- def = &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 (Keyboard[def->up])
- my = motion_Up;
- else if (Keyboard[def->down])
- my = motion_Down;
-
- if (Keyboard[def->left])
- mx = motion_Left;
- else if (Keyboard[def->right])
- mx = motion_Right;
-
- if (Keyboard[def->button0])
- buttons += 1 << 0;
- if (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;
- }
- }
-
- 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;
- }
-
- info->x = dx;
- info->xaxis = mx;
- info->y = dy;
- info->yaxis = my;
- info->button0 = buttons & (1 << 0);
- info->button1 = buttons & (1 << 1);
- 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
-}
-#endif
-
-///////////////////////////////////////////////////////////////////////////
-//
-// IN_SetControlType() - Sets the control type to be used by the specified
-// player
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_SetControlType(int player,ControlType type)
-{
- // DEBUG - check that requested type is present?
- Controls[player] = 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(void)
-{
- ScanCode result;
-
- while (!(result = LastScan))
- ;
- LastScan = 0;
- return(result);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-// IN_WaitForASCII() - Waits for an ASCII char, then clears LastASCII and
-// returns the ASCII value
-//
-///////////////////////////////////////////////////////////////////////////
-char
-IN_WaitForASCII(void)
-{
- char result;
-
- while (!(result = LastASCII))
- ;
- LastASCII = '\0';
- return(result);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-// IN_AckBack() - Waits for either an ASCII keypress or a button press
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_AckBack(void)
-{
- word i;
-
- while (!LastScan)
- {
- if (MousePresent)
- {
- if (INL_GetMouseButtons())
- {
- while (INL_GetMouseButtons())
- ;
- return;
- }
- }
-
- for (i = 0;i < MaxJoys;i++)
- {
- if (JoysPresent[i])
- {
- if (IN_GetJoyButtonsDB(i))
- {
- while (IN_GetJoyButtonsDB(i))
- ;
- return;
- }
- }
- }
- }
-
- IN_ClearKey(LastScan);
- LastScan = sc_None;
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-// IN_Ack() - Clears user input & then calls IN_AckBack()
-//
-///////////////////////////////////////////////////////////////////////////
-void
-IN_Ack(void)
-{
- word i;
-
- IN_ClearKey(LastScan);
- LastScan = sc_None;
-
- if (MousePresent)
- while (INL_GetMouseButtons())
- ;
- for (i = 0;i < MaxJoys;i++)
- if (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(void)
-{
- boolean result;
- word i;
-
- result = LastScan;
-
- if (MousePresent)
- if (INL_GetMouseButtons())
- result = true;
-
- for (i = 0;i < MaxJoys;i++)
- if (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_qb(byte kee)
-{
- if(Keyboard[kee]==true) return 1;
- else return 0;
-}
+struct inconfig\r
+{\r
+ boolean MousePresent;\r
+ boolean JoysPresent[MaxJoys];\r
+ boolean Keyboard[NumCodes];\r
+ boolean Paused;\r
+ char LastASCII;\r
+ ScanCode LastScan;\r
+\r
+ KeyboardDef KbdDefs[MaxKbds];\r
+ JoystickDef JoyDefs[MaxJoys];\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
+*/\r
+\r
+#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;\r
+} inst;\r
+\r
+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
+// 0 1 2 3 4 5 6 7 8 9 A B C D E F\r
+ 0 ,27 ,'1','2','3','4','5','6','7','8','9','0','-','=',8 ,9 , // 0\r
+ 'q','w','e','r','t','y','u','i','o','p','[',']',13 ,0 ,'a','s', // 1\r
+ 'd','f','g','h','j','k','l',';',39 ,'`',0 ,92 ,'z','x','c','v', // 2\r
+ 'b','n','m',',','.','/',0 ,'*',0 ,' ',0 ,0 ,0 ,0 ,0 ,0 , // 3\r
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,'7','8','9','-','4','5','6','+','1', // 4\r
+ '2','3','0',127,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 5\r
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6\r
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7\r
+ },\r
+ far ShiftNames[] = // Shifted ASCII for scan codes\r
+ {\r
+// 0 1 2 3 4 5 6 7 8 9 A B C D E F\r
+ 0 ,27 ,'!','@','#','$','%','^','&','*','(',')','_','+',8 ,9 , // 0\r
+ 'Q','W','E','R','T','Y','U','I','O','P','{','}',13 ,0 ,'A','S', // 1\r
+ 'D','F','G','H','J','K','L',':',34 ,'~',0 ,'|','Z','X','C','V', // 2\r
+ 'B','N','M','<','>','?',0 ,'*',0 ,' ',0 ,0 ,0 ,0 ,0 ,0 , // 3\r
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,'7','8','9','-','4','5','6','+','1', // 4\r
+ '2','3','0',127,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 5\r
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6\r
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7\r
+ },\r
+ far SpecialNames[] = // ASCII for 0xe0 prefixed codes\r
+ {\r
+// 0 1 2 3 4 5 6 7 8 9 A B C D E F\r
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 0\r
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,13 ,0 ,0 ,0 , // 1\r
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 2\r
+ 0 ,0 ,0 ,0 ,0 ,'/',0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 3\r
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 4\r
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 5\r
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6\r
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7\r
+ },\r
+ *ScanNames[] = // Scan code names with single chars\r
+ {\r
+ "?","?","1","2","3","4","5","6","7","8","9","0","-","+","?","?",\r
+ "Q","W","E","R","T","Y","U","I","O","P","[","]","|","?","A","S",\r
+ "D","F","G","H","J","K","L",";","\"","?","?","?","Z","X","C","V",\r
+ "B","N","M",",",".","/","?","?","?","?","?","?","?","?","?","?",\r
+ "?","?","?","?","?","?","?","?","\xf","?","-","\x15","5","\x11","+","?",\r
+ "\x13","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",\r
+ "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",\r
+ "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?"\r
+ }, // DEBUG - consolidate these\r
+ far ExtScanCodes[] = // Scan codes with >1 char names\r
+ {\r
+ 1,0xe,0xf,0x1d,0x2a,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,\r
+ 0x3f,0x40,0x41,0x42,0x43,0x44,0x57,0x59,0x46,0x1c,0x36,\r
+ 0x37,0x38,0x47,0x49,0x4f,0x51,0x52,0x53,0x45,0x48,\r
+ 0x50,0x4b,0x4d,0x00\r
+ },\r
+ *ExtScanNames[] = // Names corresponding to ExtScanCodes\r
+ {\r
+ "Esc","BkSp","Tab","Ctrl","LShft","Space","CapsLk","F1","F2","F3","F4",\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_West,\r
+ dir_None,\r
+ dir_East,\r
+ dir_South\r
+ //dir_NorthEast,\r
+ //dir_Soutinest,\r
+ //,dir_SouthEast\r
+ };\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
+ if(testkeyin > 0) printf("%c %u [0x%x %u] %u\n", c, c, k, 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
+ word time;\r
+ word TimeCount = *clockw;\r
+ JoystickDef *def;\r
+static word lasttime;\r
+\r
+ IN_GetJoyAbs(joy,&x,&y);\r
+ def = inpu.JoyDefs + joy;\r
+\r
+ //TODO: inject p16 input controls!\r
+ //which is this\r
+ /* if(DIRECTIONIFELSE)\r
+ {\r
+ if(!inpu.Keyboard[def->left] && !inpu.Keyboard[def->right]){\r
+ if((inpu.Keyboard[def->up] && !inpu.Keyboard[def->down]))\r
+ my = motion_Up;\r
+ if((inpu.Keyboard[def->down] && !inpu.Keyboard[def->up]))\r
+ my = motion_Down;\r
+ }else if(!inpu.Keyboard[def->up] && !inpu.Keyboard[def->down]){\r
+ if((inpu.Keyboard[def->left] && !inpu.Keyboard[def->right]))\r
+ mx = motion_Left;\r
+ if((inpu.Keyboard[def->right] && !inpu.Keyboard[def->left]))// || player[pn].pdir != 1)\r
+ mx = motion_Right;\r
+ }else\r
+ //if(mx+my!=1 && mx+my!=-1 && mx!=my!=0)\r
+ { //2 keys pressed\r
+ switch (player[pn].pdir)\r
+ {\r
+ case 0:\r
+ case 4:\r
+ if((inpu.Keyboard[def->left] && !inpu.Keyboard[def->right])) dir = DirTable[1];\r
+ else if((inpu.Keyboard[def->right] && !inpu.Keyboard[def->left])) dir = DirTable[3];\r
+ break;\r
+ case 1:\r
+ case 3:\r
+ if((inpu.Keyboard[def->up] && !inpu.Keyboard[def->down])) dir = DirTable[0];\r
+ else if((inpu.Keyboard[def->down] && !inpu.Keyboard[def->up])) dir = DirTable[4];\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ if(testcontrolnoisy > 0){ printf("dir=%c ", dirchar(dir)); printf("pdir=%c ", dirchar(player[pn].pdir)); }\r
+ }//else printf(" ");\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
+ 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
+ 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
+//\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
+ int i;\r
+ if(testctrltype==0)\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
+ )\r
+ nt = ctrl_Keyboard1;\r
+ inpu.KbdDefs[0].button0 = 0x1c;\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
+ for(i=0; i>MaxPlayers;i++)\r
+ player[i].d=2;\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 near\r
+IN_ReadControl(int pn,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
+ 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
+ if(testctrltype>0) printf("player[pn].Controls=%c\n", player[pn].Controls);\r
+ switch (type = player[pn].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
+ if(DIRECTIONIFELSE)\r
+ {\r
+ if(!inpu.Keyboard[def->left] && !inpu.Keyboard[def->right]){\r
+ if((inpu.Keyboard[def->up] && !inpu.Keyboard[def->down]))\r
+ my = motion_Up;\r
+ if((inpu.Keyboard[def->down] && !inpu.Keyboard[def->up]))\r
+ my = motion_Down;\r
+ }else if(!inpu.Keyboard[def->up] && !inpu.Keyboard[def->down]){\r
+ if((inpu.Keyboard[def->left] && !inpu.Keyboard[def->right]))\r
+ mx = motion_Left;\r
+ if((inpu.Keyboard[def->right] && !inpu.Keyboard[def->left]))// || player[pn].pdir != 1)\r
+ mx = motion_Right;\r
+ }else\r
+ //if(mx+my!=1 && mx+my!=-1 && mx!=my!=0)\r
+ { //2 keys pressed\r
+ switch (player[pn].pdir)\r
+ {\r
+ case 0:\r
+ case 4:\r
+ if((inpu.Keyboard[def->left] && !inpu.Keyboard[def->right])) dir = DirTable[1];\r
+ else if((inpu.Keyboard[def->right] && !inpu.Keyboard[def->left])) dir = DirTable[3];\r
+ break;\r
+ case 1:\r
+ case 3:\r
+ if((inpu.Keyboard[def->up] && !inpu.Keyboard[def->down])) dir = DirTable[0];\r
+ else if((inpu.Keyboard[def->down] && !inpu.Keyboard[def->up])) dir = DirTable[4];\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ if(testcontrolnoisy > 0){ printf("dir=%c ", dirchar(dir)); printf("pdir=%c ", dirchar(player[pn].pdir)); }\r
+ }//else printf(" ");\r
+ }\r
+ //input from player\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
+ }\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[pn].info.x = dx;\r
+ player[pn].info.xaxis = mx;\r
+ player[pn].info.y = dy;\r
+ player[pn].info.yaxis = my;\r
+ player[pn].info.button0 = buttons & (1 << 0);\r
+ player[pn].info.button1 = buttons & (1 << 1);\r
+ player[pn].info.button2 = buttons & (1 << 2);\r
+ player[pn].info.button3 = buttons & (1 << 3);\r
+// player[pn].info.dir = DirTable[((my + 1) * 3) + (mx + 1)];\r
+ conpee=(((my + 1) * 2) + (mx + 1))-1;\r
+ player[pn].info.dir = DirTable[conpee];\r
+\r
+ if(DirTable[conpee]!=2) player[pn].pdir=DirTable[conpee];\r
+ if(player[pn].q==1 &&( dir!=2 || (mx!=motion_None || my!=motion_None)))\r
+ {\r
+ if(dir==2) player[pn].d = player[pn].info.dir;\r
+ else player[pn].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 TESTCONTROLNOISY\r
+if(testcontrolnoisy > 0)\r
+if((inpu.Keyboard[def->up] || inpu.Keyboard[def->down] || inpu.Keyboard[def->left] || inpu.Keyboard[def->right]) || player[pn].q>1)\r
+{\r
+ printf("q=%d ", player[pn].q);\r
+ printf("cpee=%c ", dirchar(conpee));\r
+ //printf("(mx)=%d ", mx);\r
+ //printf("(my)=%d ", my);\r
+ //printf("[%d] ", mx+my);\r
+ printf("pdir=%c d=%c dir=%c ", dirchar(player[pn].pdir), dirchar(player[pn].d), dirchar(player[pn].info.dir));\r
+ printf("%c%d %c%d %c%d %c%d\n", dirchar(0), inpu.Keyboard[def->up], dirchar(4), inpu.Keyboard[def->down], dirchar(1), inpu.Keyboard[def->left], dirchar(3), inpu.Keyboard[def->right]);\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(word pn,player_t *player,ControlType type)\r
+{\r
+ // DEBUG - check that requested type is present?\r
+ player[pn].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
+ word TimeCount = *clockw;\r
+ word 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
+//#ifdef TESTKEYIN\r
+// if(testkeyin > 0) printf("%u\n", inpu.Keyboard[kee]);\r
+//#endif\r
+ if(inpu.Keyboard[kee]==true) return 1;\r
+ else return 0;\r
+}\r
+\r
+//init player!\r
+void IN_initplayer(player_t *player, word pn)\r
+{\r
+ player[pn].x = player[pn].tx*TILEWH;\r
+ player[pn].y = player[pn].ty*TILEWH;\r
+ player[pn].triggerx = player[pn].tx;\r
+ player[pn].triggery = player[pn].ty+1;\r
+/* player[0].info.x = player[0].tx;\r
+ player[0].info.xaxis = player[0].tx*TILEWH;\r
+ player[0].info.y = player[0].ty;\r
+ player[0].info.yaxis = player[0].ty*TILEWH;*/\r
+ player[pn].q=1;\r
+ player[pn].d=2;\r
+ player[pn].hp=4;\r
+ player[pn].speed=4;\r
+ player[pn].persist_aniframe=0;\r
+ player[pn].spt=(TILEWH/(player[pn].speed)); //speed per tile wwww\r
+}\r