mirror of
https://github.com/id-Software/wolf3d.git
synced 2026-03-19 16:39:29 +01:00
The Wolfenstein 3D source as originally released.
This commit is contained in:
990
WOLFSRC/ID_IN.C
Normal file
990
WOLFSRC/ID_IN.C
Normal file
@@ -0,0 +1,990 @@
|
||||
//
|
||||
// ID Engine
|
||||
// ID_IN.c - Input Manager
|
||||
// v1.0d1
|
||||
// By Jason Blochowiak
|
||||
//
|
||||
|
||||
//
|
||||
// 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 "ID_HEADS.H"
|
||||
#pragma hdrstop
|
||||
|
||||
#define KeyInt 9 // The keyboard ISR number
|
||||
|
||||
//
|
||||
// mouse constants
|
||||
//
|
||||
#define MReset 0
|
||||
#define MButtons 3
|
||||
#define MDelta 11
|
||||
|
||||
#define MouseInt 0x33
|
||||
#define Mouse(x) _AX = x,geninterrupt(MouseInt)
|
||||
|
||||
//
|
||||
// joystick constants
|
||||
//
|
||||
#define JoyScaleMax 32768
|
||||
#define JoyScaleShift 8
|
||||
#define MaxJoyValue 5000
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
GLOBAL VARIABLES
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
//
|
||||
// configuration variables
|
||||
//
|
||||
boolean MousePresent;
|
||||
boolean JoysPresent[MaxJoys];
|
||||
boolean JoyPadPresent;
|
||||
|
||||
|
||||
// Global variables
|
||||
boolean Keyboard[NumCodes];
|
||||
boolean Paused;
|
||||
char LastASCII;
|
||||
ScanCode LastScan;
|
||||
|
||||
KeyboardDef KbdDefs = {0x1d,0x38,0x47,0x48,0x49,0x4b,0x4d,0x4f,0x50,0x51};
|
||||
JoystickDef JoyDefs[MaxJoys];
|
||||
ControlType Controls[MaxPlayers];
|
||||
|
||||
longword MouseDownCount;
|
||||
|
||||
Demo DemoMode = demo_Off;
|
||||
byte _seg *DemoBuffer;
|
||||
word DemoOffset,DemoSize;
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
LOCAL VARIABLES
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
static byte far ASCIINames[] = // Unshifted ASCII for scan codes
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
0 ,27 ,'1','2','3','4','5','6','7','8','9','0','-','=',8 ,9 , // 0
|
||||
'q','w','e','r','t','y','u','i','o','p','[',']',13 ,0 ,'a','s', // 1
|
||||
'd','f','g','h','j','k','l',';',39 ,'`',0 ,92 ,'z','x','c','v', // 2
|
||||
'b','n','m',',','.','/',0 ,'*',0 ,' ',0 ,0 ,0 ,0 ,0 ,0 , // 3
|
||||
0 ,0 ,0 ,0 ,0 ,0 ,0 ,'7','8','9','-','4','5','6','+','1', // 4
|
||||
'2','3','0',127,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 5
|
||||
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6
|
||||
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7
|
||||
},
|
||||
far ShiftNames[] = // Shifted ASCII for scan codes
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
0 ,27 ,'!','@','#','$','%','^','&','*','(',')','_','+',8 ,9 , // 0
|
||||
'Q','W','E','R','T','Y','U','I','O','P','{','}',13 ,0 ,'A','S', // 1
|
||||
'D','F','G','H','J','K','L',':',34 ,'~',0 ,'|','Z','X','C','V', // 2
|
||||
'B','N','M','<','>','?',0 ,'*',0 ,' ',0 ,0 ,0 ,0 ,0 ,0 , // 3
|
||||
0 ,0 ,0 ,0 ,0 ,0 ,0 ,'7','8','9','-','4','5','6','+','1', // 4
|
||||
'2','3','0',127,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 5
|
||||
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6
|
||||
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7
|
||||
},
|
||||
far SpecialNames[] = // ASCII for 0xe0 prefixed codes
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 0
|
||||
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,13 ,0 ,0 ,0 , // 1
|
||||
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 2
|
||||
0 ,0 ,0 ,0 ,0 ,'/',0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 3
|
||||
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 4
|
||||
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 5
|
||||
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6
|
||||
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7
|
||||
};
|
||||
|
||||
|
||||
static boolean IN_Started;
|
||||
static boolean CapsLock;
|
||||
static ScanCode CurCode,LastCode;
|
||||
|
||||
static Direction DirTable[] = // Quick lookup for total direction
|
||||
{
|
||||
dir_NorthWest, dir_North, dir_NorthEast,
|
||||
dir_West, dir_None, dir_East,
|
||||
dir_SouthWest, dir_South, dir_SouthEast
|
||||
};
|
||||
|
||||
static void (*INL_KeyHook)(void);
|
||||
static void interrupt (*OldKeyVect)(void);
|
||||
|
||||
static char *ParmStrings[] = {"nojoys","nomouse",nil};
|
||||
|
||||
// Internal routines
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// INL_KeyService() - Handles a keyboard interrupt (key up/down)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
static void interrupt
|
||||
INL_KeyService(void)
|
||||
{
|
||||
static boolean special;
|
||||
byte k,c,
|
||||
temp;
|
||||
int i;
|
||||
|
||||
k = inportb(0x60); // Get the scan code
|
||||
|
||||
// Tell the XT keyboard controller to clear the key
|
||||
outportb(0x61,(temp = inportb(0x61)) | 0x80);
|
||||
outportb(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();
|
||||
outportb(0x20,0x20);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// INL_GetMouseDelta() - Gets the amount that the mouse has moved from the
|
||||
// mouse driver
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
static void
|
||||
INL_GetMouseDelta(int *x,int *y)
|
||||
{
|
||||
Mouse(MDelta);
|
||||
*x = _CX;
|
||||
*y = _DX;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// INL_GetMouseButtons() - Gets the status of the mouse buttons from the
|
||||
// mouse driver
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
static word
|
||||
INL_GetMouseButtons(void)
|
||||
{
|
||||
word buttons;
|
||||
|
||||
Mouse(MButtons);
|
||||
buttons = _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
|
||||
asm push si
|
||||
asm push di
|
||||
asm cli // Make sure an interrupt doesn't screw the timings
|
||||
|
||||
|
||||
asm mov dx,0x201
|
||||
asm in al,dx
|
||||
asm out dx,al // Clear the resistors
|
||||
|
||||
asm mov ah,[xb] // Get masks into registers
|
||||
asm mov ch,[yb]
|
||||
|
||||
asm xor si,si // Clear count registers
|
||||
asm xor di,di
|
||||
asm xor bh,bh // Clear high byte of bx for later
|
||||
|
||||
asm push bp // Don't mess up stack frame
|
||||
asm mov bp,MaxJoyValue
|
||||
|
||||
loop:
|
||||
asm in al,dx // Get bits indicating whether all are finished
|
||||
|
||||
asm dec bp // Check bounding register
|
||||
asm jz done // We have a silly value - abort
|
||||
|
||||
asm mov bl,al // Duplicate the bits
|
||||
asm and bl,ah // Mask off useless bits (in [xb])
|
||||
asm add si,bx // Possibly increment count register
|
||||
asm mov cl,bl // Save for testing later
|
||||
|
||||
asm mov bl,al
|
||||
asm and bl,ch // [yb]
|
||||
asm add di,bx
|
||||
|
||||
asm add cl,bl
|
||||
asm jnz loop // If both bits were 0, drop out
|
||||
|
||||
done:
|
||||
asm pop bp
|
||||
|
||||
asm mov cl,[xs] // Get the number of bits to shift
|
||||
asm shr si,cl // and shift the count that many times
|
||||
|
||||
asm mov cl,[ys]
|
||||
asm shr di,cl
|
||||
|
||||
asm mov [x],si // Store the values into the variables
|
||||
asm mov [y],di
|
||||
|
||||
asm pop di
|
||||
asm pop si
|
||||
asm popf // Restore the registers
|
||||
|
||||
*xp = x;
|
||||
*yp = y;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// INL_GetJoyDelta() - Returns the relative movement of the specified
|
||||
// joystick (from +/-127)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
void INL_GetJoyDelta(word joy,int *dx,int *dy)
|
||||
{
|
||||
word x,y;
|
||||
longword time;
|
||||
JoystickDef *def;
|
||||
static longword 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;
|
||||
|
||||
lasttime = TimeCount;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// INL_GetJoyButtons() - Returns the button status of the specified
|
||||
// joystick
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
static word
|
||||
INL_GetJoyButtons(word joy)
|
||||
{
|
||||
register word result;
|
||||
|
||||
result = inportb(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)
|
||||
{
|
||||
longword 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 = NULL; // no key hook routine
|
||||
|
||||
IN_ClearKeysDown();
|
||||
|
||||
OldKeyVect = getvect(KeyInt);
|
||||
setvect(KeyInt,INL_KeyService);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// INL_ShutKbd() - Restores keyboard control to the BIOS
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
static void
|
||||
INL_ShutKbd(void)
|
||||
{
|
||||
poke(0x40,0x17,peek(0x40,0x17) & 0xfaf0); // Clear ctrl/alt/shift flags
|
||||
|
||||
setvect(KeyInt,OldKeyVect);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// INL_StartMouse() - Detects and sets up the mouse
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
static boolean
|
||||
INL_StartMouse(void)
|
||||
{
|
||||
#if 0
|
||||
if (getvect(MouseInt))
|
||||
{
|
||||
Mouse(MReset);
|
||||
if (_AX == 0xffff)
|
||||
return(true);
|
||||
}
|
||||
return(false);
|
||||
#endif
|
||||
union REGS regs;
|
||||
unsigned char far *vector;
|
||||
|
||||
|
||||
if ((vector=MK_FP(peek(0,0x33*4+2),peek(0,0x33*4)))==NULL)
|
||||
return false;
|
||||
|
||||
if (*vector == 207)
|
||||
return false;
|
||||
|
||||
Mouse(MReset);
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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],ParmStrings))
|
||||
{
|
||||
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_ClearKeysDown() - Clears the keyboard array
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
IN_ClearKeysDown(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
LastScan = sc_None;
|
||||
LastASCII = key_None;
|
||||
memset (Keyboard,0,sizeof(Keyboard));
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 (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
|
||||
{
|
||||
switch (type = Controls[player])
|
||||
{
|
||||
case ctrl_Keyboard:
|
||||
def = &KbdDefs;
|
||||
|
||||
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);
|
||||
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->button2 = buttons & (1 << 2);
|
||||
info->button3 = buttons & (1 << 3);
|
||||
info->dir = DirTable[((my + 1) * 3) + (mx + 1)];
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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_Ack() - waits for a button or key press. If a button is down, upon
|
||||
// calling, it must be released for it to be recognized
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
boolean btnstate[8];
|
||||
|
||||
void IN_StartAck(void)
|
||||
{
|
||||
unsigned i,buttons;
|
||||
|
||||
//
|
||||
// get initial state of everything
|
||||
//
|
||||
IN_ClearKeysDown();
|
||||
memset (btnstate,0,sizeof(btnstate));
|
||||
|
||||
buttons = IN_JoyButtons () << 4;
|
||||
if (MousePresent)
|
||||
buttons |= IN_MouseButtons ();
|
||||
|
||||
for (i=0;i<8;i++,buttons>>=1)
|
||||
if (buttons&1)
|
||||
btnstate[i] = true;
|
||||
}
|
||||
|
||||
|
||||
boolean IN_CheckAck (void)
|
||||
{
|
||||
unsigned i,buttons;
|
||||
|
||||
//
|
||||
// see if something has been pressed
|
||||
//
|
||||
if (LastScan)
|
||||
return true;
|
||||
|
||||
buttons = IN_JoyButtons () << 4;
|
||||
if (MousePresent)
|
||||
buttons |= IN_MouseButtons ();
|
||||
|
||||
for (i=0;i<8;i++,buttons>>=1)
|
||||
if ( buttons&1 )
|
||||
{
|
||||
if (!btnstate[i])
|
||||
return true;
|
||||
}
|
||||
else
|
||||
btnstate[i]=false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void IN_Ack (void)
|
||||
{
|
||||
IN_StartAck ();
|
||||
|
||||
while (!IN_CheckAck ())
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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(longword delay)
|
||||
{
|
||||
longword lasttime;
|
||||
|
||||
lasttime = TimeCount;
|
||||
IN_StartAck ();
|
||||
do
|
||||
{
|
||||
if (IN_CheckAck())
|
||||
return true;
|
||||
} while (TimeCount - lasttime < delay);
|
||||
return(false);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
/*
|
||||
===================
|
||||
=
|
||||
= IN_MouseButtons
|
||||
=
|
||||
===================
|
||||
*/
|
||||
|
||||
byte IN_MouseButtons (void)
|
||||
{
|
||||
if (MousePresent)
|
||||
{
|
||||
Mouse(MButtons);
|
||||
return _BX;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
=
|
||||
= IN_JoyButtons
|
||||
=
|
||||
===================
|
||||
*/
|
||||
|
||||
byte IN_JoyButtons (void)
|
||||
{
|
||||
unsigned joybits;
|
||||
|
||||
joybits = inportb(0x201); // Get all the joystick buttons
|
||||
joybits >>= 4; // only the high bits are useful
|
||||
joybits ^= 15; // return with 1=pressed
|
||||
|
||||
return joybits;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user