ref: 7d1bc4ab95db2a1199150eb91cc0d7b1a5dd1128
dir: /in.c/
#define MaxPlayers 4
#define NumCodes 128
// Stuff for the mouse
#define MReset 0
#define MButtons 3
#define MDelta 11
#define MouseInt 0x33
#define Mouse(x) _AX = x,geninterrupt(MouseInt)
typedef enum {
demo_Off,demo_Record,demo_Playback,demo_PlayDone
} Demo;
typedef enum {
ctrl_Keyboard,
ctrl_Keyboard1 = ctrl_Keyboard,ctrl_Keyboard2,
ctrl_Mouse
} ControlType;
typedef enum {
motion_Left = -1,motion_Up = -1,
motion_None = 0,
motion_Right = 1,motion_Down = 1
} Motion;
typedef enum {
dir_North,dir_NorthEast,
dir_East,dir_SouthEast,
dir_South,dir_SouthWest,
dir_West,dir_NorthWest,
dir_None
} Direction;
typedef struct {
int button0,button1,button2,button3;
s16int x,y;
Motion xaxis,yaxis;
Direction dir;
} CursorInfo;
typedef CursorInfo ControlInfo;
typedef struct {
u8int button0,button1,
upleft, up, upright,
left, right,
downleft, down, downright;
} KeyboardDef;
// Function prototypes
#define IN_KeyDown(code) (Keyboard[(code)])
#define IN_ClearKey(code) {Keyboard[code] = false;\
if (code == LastScan) LastScan = sc_None;}
int Keyboard[NumCodes];
KeyboardDef KbdDefs = {0x1d,0x38,0x47,0x48,0x49,0x4b,0x4d,0x4f,0x50,0x51};
ControlType Controls[MaxPlayers];
Demo DemoMode = demo_Off;
u8int _seg *DemoBuffer;
u16int DemoOffset,DemoSize;
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
};
void
IN_ReadControl(s16int player,ControlInfo *info)
{
int realdelta;
u8int dbyte;
u16int buttons;
s16int 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_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;
}
}
}