684 lines
17 KiB
C++
684 lines
17 KiB
C++
|
//
|
||
|
// 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 "wl_def.h"
|
||
|
|
||
|
|
||
|
/*
|
||
|
=============================================================================
|
||
|
|
||
|
GLOBAL VARIABLES
|
||
|
|
||
|
=============================================================================
|
||
|
*/
|
||
|
|
||
|
|
||
|
//
|
||
|
// configuration variables
|
||
|
//
|
||
|
boolean MousePresent;
|
||
|
boolean forcegrabmouse;
|
||
|
|
||
|
|
||
|
// Global variables
|
||
|
volatile boolean Keyboard[SDLK_LAST];
|
||
|
volatile boolean Paused;
|
||
|
volatile char LastASCII;
|
||
|
volatile ScanCode LastScan;
|
||
|
|
||
|
//KeyboardDef KbdDefs = {0x1d,0x38,0x47,0x48,0x49,0x4b,0x4d,0x4f,0x50,0x51};
|
||
|
static KeyboardDef KbdDefs = {
|
||
|
sc_Control, // button0
|
||
|
sc_Alt, // button1
|
||
|
sc_Home, // upleft
|
||
|
sc_UpArrow, // up
|
||
|
sc_PgUp, // upright
|
||
|
sc_LeftArrow, // left
|
||
|
sc_RightArrow, // right
|
||
|
sc_End, // downleft
|
||
|
sc_DownArrow, // down
|
||
|
sc_PgDn // downright
|
||
|
};
|
||
|
|
||
|
static SDL_Joystick *Joystick;
|
||
|
int JoyNumButtons;
|
||
|
static int JoyNumHats;
|
||
|
|
||
|
static bool GrabInput = false;
|
||
|
static bool NeedRestore = false;
|
||
|
|
||
|
/*
|
||
|
=============================================================================
|
||
|
|
||
|
LOCAL VARIABLES
|
||
|
|
||
|
=============================================================================
|
||
|
*/
|
||
|
byte ASCIINames[] = // Unshifted ASCII for scan codes // TODO: keypad
|
||
|
{
|
||
|
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||
|
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,8 ,9 ,0 ,0 ,0 ,13 ,0 ,0 , // 0
|
||
|
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,27 ,0 ,0 ,0 , // 1
|
||
|
' ',0 ,0 ,0 ,0 ,0 ,0 ,39 ,0 ,0 ,'*','+',',','-','.','/', // 2
|
||
|
'0','1','2','3','4','5','6','7','8','9',0 ,';',0 ,'=',0 ,0 , // 3
|
||
|
'`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', // 4
|
||
|
'p','q','r','s','t','u','v','w','x','y','z','[',92 ,']',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
|
||
|
};
|
||
|
byte ShiftNames[] = // Shifted ASCII for scan 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 ,8 ,9 ,0 ,0 ,0 ,13 ,0 ,0 , // 0
|
||
|
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,27 ,0 ,0 ,0 , // 1
|
||
|
' ',0 ,0 ,0 ,0 ,0 ,0 ,34 ,0 ,0 ,'*','+','<','_','>','?', // 2
|
||
|
')','!','@','#','$','%','^','&','*','(',0 ,':',0 ,'+',0 ,0 , // 3
|
||
|
'~','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O', // 4
|
||
|
'P','Q','R','S','T','U','V','W','X','Y','Z','{','|','}',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
|
||
|
};
|
||
|
byte 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 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
|
||
|
};
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// INL_GetMouseButtons() - Gets the status of the mouse buttons from the
|
||
|
// mouse driver
|
||
|
//
|
||
|
///////////////////////////////////////////////////////////////////////////
|
||
|
static int
|
||
|
INL_GetMouseButtons(void)
|
||
|
{
|
||
|
int buttons = SDL_GetMouseState(NULL, NULL);
|
||
|
int middlePressed = buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE);
|
||
|
int rightPressed = buttons & SDL_BUTTON(SDL_BUTTON_RIGHT);
|
||
|
buttons &= ~(SDL_BUTTON(SDL_BUTTON_MIDDLE) | SDL_BUTTON(SDL_BUTTON_RIGHT));
|
||
|
if(middlePressed) buttons |= 1 << 2;
|
||
|
if(rightPressed) buttons |= 1 << 1;
|
||
|
|
||
|
return buttons;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// IN_GetJoyDelta() - Returns the relative movement of the specified
|
||
|
// joystick (from +/-127)
|
||
|
//
|
||
|
///////////////////////////////////////////////////////////////////////////
|
||
|
void IN_GetJoyDelta(int *dx,int *dy)
|
||
|
{
|
||
|
if(!Joystick)
|
||
|
{
|
||
|
*dx = *dy = 0;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
SDL_JoystickUpdate();
|
||
|
#ifdef _arch_dreamcast
|
||
|
int x = 0;
|
||
|
int y = 0;
|
||
|
#else
|
||
|
int x = SDL_JoystickGetAxis(Joystick, 0) >> 8;
|
||
|
int y = SDL_JoystickGetAxis(Joystick, 1) >> 8;
|
||
|
#endif
|
||
|
|
||
|
if(param_joystickhat != -1)
|
||
|
{
|
||
|
uint8_t hatState = SDL_JoystickGetHat(Joystick, param_joystickhat);
|
||
|
if(hatState & SDL_HAT_RIGHT)
|
||
|
x += 127;
|
||
|
else if(hatState & SDL_HAT_LEFT)
|
||
|
x -= 127;
|
||
|
if(hatState & SDL_HAT_DOWN)
|
||
|
y += 127;
|
||
|
else if(hatState & SDL_HAT_UP)
|
||
|
y -= 127;
|
||
|
|
||
|
if(x < -128) x = -128;
|
||
|
else if(x > 127) x = 127;
|
||
|
|
||
|
if(y < -128) y = -128;
|
||
|
else if(y > 127) y = 127;
|
||
|
}
|
||
|
|
||
|
*dx = x;
|
||
|
*dy = y;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// IN_GetJoyFineDelta() - Returns the relative movement of the specified
|
||
|
// joystick without dividing the results by 256 (from +/-127)
|
||
|
//
|
||
|
///////////////////////////////////////////////////////////////////////////
|
||
|
void IN_GetJoyFineDelta(int *dx, int *dy)
|
||
|
{
|
||
|
if(!Joystick)
|
||
|
{
|
||
|
*dx = 0;
|
||
|
*dy = 0;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
SDL_JoystickUpdate();
|
||
|
int x = SDL_JoystickGetAxis(Joystick, 0);
|
||
|
int y = SDL_JoystickGetAxis(Joystick, 1);
|
||
|
|
||
|
if(x < -128) x = -128;
|
||
|
else if(x > 127) x = 127;
|
||
|
|
||
|
if(y < -128) y = -128;
|
||
|
else if(y > 127) y = 127;
|
||
|
|
||
|
*dx = x;
|
||
|
*dy = y;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===================
|
||
|
=
|
||
|
= IN_JoyButtons
|
||
|
=
|
||
|
===================
|
||
|
*/
|
||
|
|
||
|
int IN_JoyButtons()
|
||
|
{
|
||
|
if(!Joystick) return 0;
|
||
|
|
||
|
SDL_JoystickUpdate();
|
||
|
|
||
|
int res = 0;
|
||
|
for(int i = 0; i < JoyNumButtons && i < 32; i++)
|
||
|
res |= SDL_JoystickGetButton(Joystick, i) << i;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
boolean IN_JoyPresent()
|
||
|
{
|
||
|
return Joystick != NULL;
|
||
|
}
|
||
|
|
||
|
static void processEvent(SDL_Event *event)
|
||
|
{
|
||
|
switch (event->type)
|
||
|
{
|
||
|
// exit if the window is closed
|
||
|
case SDL_QUIT:
|
||
|
Quit(NULL);
|
||
|
|
||
|
// check for keypresses
|
||
|
case SDL_KEYDOWN:
|
||
|
{
|
||
|
if(event->key.keysym.sym==SDLK_SCROLLOCK || event->key.keysym.sym==SDLK_F12)
|
||
|
{
|
||
|
GrabInput = !GrabInput;
|
||
|
SDL_WM_GrabInput(GrabInput ? SDL_GRAB_ON : SDL_GRAB_OFF);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
LastScan = event->key.keysym.sym;
|
||
|
SDLMod mod = SDL_GetModState();
|
||
|
if(Keyboard[sc_Alt])
|
||
|
{
|
||
|
if(LastScan==SDLK_F4)
|
||
|
Quit(NULL);
|
||
|
}
|
||
|
|
||
|
if(LastScan == SDLK_KP_ENTER) LastScan = SDLK_RETURN;
|
||
|
else if(LastScan == SDLK_RSHIFT) LastScan = SDLK_LSHIFT;
|
||
|
else if(LastScan == SDLK_RALT) LastScan = SDLK_LALT;
|
||
|
else if(LastScan == SDLK_RCTRL) LastScan = SDLK_LCTRL;
|
||
|
else
|
||
|
{
|
||
|
if((mod & KMOD_NUM) == 0)
|
||
|
{
|
||
|
switch(LastScan)
|
||
|
{
|
||
|
case SDLK_KP2: LastScan = SDLK_DOWN; break;
|
||
|
case SDLK_KP4: LastScan = SDLK_LEFT; break;
|
||
|
case SDLK_KP6: LastScan = SDLK_RIGHT; break;
|
||
|
case SDLK_KP8: LastScan = SDLK_UP; break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int sym = LastScan;
|
||
|
if(sym >= 'a' && sym <= 'z')
|
||
|
sym -= 32; // convert to uppercase
|
||
|
|
||
|
if(mod & (KMOD_SHIFT | KMOD_CAPS))
|
||
|
{
|
||
|
if(sym < lengthof(ShiftNames) && ShiftNames[sym])
|
||
|
LastASCII = ShiftNames[sym];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(sym < lengthof(ASCIINames) && ASCIINames[sym])
|
||
|
LastASCII = ASCIINames[sym];
|
||
|
}
|
||
|
if(LastScan<SDLK_LAST)
|
||
|
Keyboard[LastScan] = 1;
|
||
|
if(LastScan == SDLK_PAUSE)
|
||
|
Paused = true;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case SDL_KEYUP:
|
||
|
{
|
||
|
int key = event->key.keysym.sym;
|
||
|
if(key == SDLK_KP_ENTER) key = SDLK_RETURN;
|
||
|
else if(key == SDLK_RSHIFT) key = SDLK_LSHIFT;
|
||
|
else if(key == SDLK_RALT) key = SDLK_LALT;
|
||
|
else if(key == SDLK_RCTRL) key = SDLK_LCTRL;
|
||
|
else
|
||
|
{
|
||
|
if((SDL_GetModState() & KMOD_NUM) == 0)
|
||
|
{
|
||
|
switch(key)
|
||
|
{
|
||
|
case SDLK_KP2: key = SDLK_DOWN; break;
|
||
|
case SDLK_KP4: key = SDLK_LEFT; break;
|
||
|
case SDLK_KP6: key = SDLK_RIGHT; break;
|
||
|
case SDLK_KP8: key = SDLK_UP; break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(key<SDLK_LAST)
|
||
|
Keyboard[key] = 0;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case SDL_ACTIVEEVENT:
|
||
|
{
|
||
|
if(fullscreen && (event->active.state & SDL_APPACTIVE) != 0)
|
||
|
{
|
||
|
if(event->active.gain)
|
||
|
{
|
||
|
if(NeedRestore)
|
||
|
{
|
||
|
FreeLatchMem();
|
||
|
LoadLatchMem();
|
||
|
}
|
||
|
|
||
|
NeedRestore = false;
|
||
|
}
|
||
|
else NeedRestore = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if defined(GP2X)
|
||
|
case SDL_JOYBUTTONDOWN:
|
||
|
GP2X_ButtonDown(event->jbutton.button);
|
||
|
break;
|
||
|
|
||
|
case SDL_JOYBUTTONUP:
|
||
|
GP2X_ButtonUp(event->jbutton.button);
|
||
|
break;
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void IN_WaitAndProcessEvents()
|
||
|
{
|
||
|
SDL_Event event;
|
||
|
if(!SDL_WaitEvent(&event)) return;
|
||
|
do
|
||
|
{
|
||
|
processEvent(&event);
|
||
|
}
|
||
|
while(SDL_PollEvent(&event));
|
||
|
}
|
||
|
|
||
|
void IN_ProcessEvents()
|
||
|
{
|
||
|
SDL_Event event;
|
||
|
|
||
|
while (SDL_PollEvent(&event))
|
||
|
{
|
||
|
processEvent(&event);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// IN_Startup() - Starts up the Input Mgr
|
||
|
//
|
||
|
///////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
IN_Startup(void)
|
||
|
{
|
||
|
if (IN_Started)
|
||
|
return;
|
||
|
|
||
|
IN_ClearKeysDown();
|
||
|
|
||
|
if(param_joystickindex >= 0 && param_joystickindex < SDL_NumJoysticks())
|
||
|
{
|
||
|
Joystick = SDL_JoystickOpen(param_joystickindex);
|
||
|
if(Joystick)
|
||
|
{
|
||
|
JoyNumButtons = SDL_JoystickNumButtons(Joystick);
|
||
|
if(JoyNumButtons > 32) JoyNumButtons = 32; // only up to 32 buttons are supported
|
||
|
JoyNumHats = SDL_JoystickNumHats(Joystick);
|
||
|
if(param_joystickhat < -1 || param_joystickhat >= JoyNumHats)
|
||
|
Quit("The joystickhat param must be between 0 and %i!", JoyNumHats - 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
|
||
|
|
||
|
if(fullscreen || forcegrabmouse)
|
||
|
{
|
||
|
GrabInput = true;
|
||
|
SDL_WM_GrabInput(SDL_GRAB_ON);
|
||
|
}
|
||
|
|
||
|
// I didn't find a way to ask libSDL whether a mouse is present, yet...
|
||
|
#if defined(GP2X)
|
||
|
MousePresent = false;
|
||
|
#elif defined(_arch_dreamcast)
|
||
|
MousePresent = DC_MousePresent();
|
||
|
#else
|
||
|
MousePresent = true;
|
||
|
#endif
|
||
|
|
||
|
IN_Started = true;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// IN_Shutdown() - Shuts down the Input Mgr
|
||
|
//
|
||
|
///////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
IN_Shutdown(void)
|
||
|
{
|
||
|
if (!IN_Started)
|
||
|
return;
|
||
|
|
||
|
if(Joystick)
|
||
|
SDL_JoystickClose(Joystick);
|
||
|
|
||
|
IN_Started = false;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// IN_ClearKeysDown() - Clears the keyboard array
|
||
|
//
|
||
|
///////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
IN_ClearKeysDown(void)
|
||
|
{
|
||
|
LastScan = sc_None;
|
||
|
LastASCII = key_None;
|
||
|
memset ((void *) 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)
|
||
|
{
|
||
|
word buttons;
|
||
|
int dx,dy;
|
||
|
Motion mx,my;
|
||
|
|
||
|
dx = dy = 0;
|
||
|
mx = my = motion_None;
|
||
|
buttons = 0;
|
||
|
|
||
|
IN_ProcessEvents();
|
||
|
|
||
|
if (Keyboard[KbdDefs.upleft])
|
||
|
mx = motion_Left,my = motion_Up;
|
||
|
else if (Keyboard[KbdDefs.upright])
|
||
|
mx = motion_Right,my = motion_Up;
|
||
|
else if (Keyboard[KbdDefs.downleft])
|
||
|
mx = motion_Left,my = motion_Down;
|
||
|
else if (Keyboard[KbdDefs.downright])
|
||
|
mx = motion_Right,my = motion_Down;
|
||
|
|
||
|
if (Keyboard[KbdDefs.up])
|
||
|
my = motion_Up;
|
||
|
else if (Keyboard[KbdDefs.down])
|
||
|
my = motion_Down;
|
||
|
|
||
|
if (Keyboard[KbdDefs.left])
|
||
|
mx = motion_Left;
|
||
|
else if (Keyboard[KbdDefs.right])
|
||
|
mx = motion_Right;
|
||
|
|
||
|
if (Keyboard[KbdDefs.button0])
|
||
|
buttons += 1 << 0;
|
||
|
if (Keyboard[KbdDefs.button1])
|
||
|
buttons += 1 << 1;
|
||
|
|
||
|
dx = mx * 127;
|
||
|
dy = my * 127;
|
||
|
|
||
|
info->x = dx;
|
||
|
info->xaxis = mx;
|
||
|
info->y = dy;
|
||
|
info->yaxis = my;
|
||
|
info->button0 = (buttons & (1 << 0)) != 0;
|
||
|
info->button1 = (buttons & (1 << 1)) != 0;
|
||
|
info->button2 = (buttons & (1 << 2)) != 0;
|
||
|
info->button3 = (buttons & (1 << 3)) != 0;
|
||
|
info->dir = DirTable[((my + 1) * 3) + (mx + 1)];
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// IN_WaitForKey() - Waits for a scan code, then clears LastScan and
|
||
|
// returns the scan code
|
||
|
//
|
||
|
///////////////////////////////////////////////////////////////////////////
|
||
|
ScanCode
|
||
|
IN_WaitForKey(void)
|
||
|
{
|
||
|
ScanCode result;
|
||
|
|
||
|
while ((result = LastScan)==0)
|
||
|
IN_WaitAndProcessEvents();
|
||
|
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)==0)
|
||
|
IN_WaitAndProcessEvents();
|
||
|
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[NUMBUTTONS];
|
||
|
|
||
|
void IN_StartAck(void)
|
||
|
{
|
||
|
IN_ProcessEvents();
|
||
|
//
|
||
|
// get initial state of everything
|
||
|
//
|
||
|
IN_ClearKeysDown();
|
||
|
memset(btnstate, 0, sizeof(btnstate));
|
||
|
|
||
|
int buttons = IN_JoyButtons() << 4;
|
||
|
|
||
|
if(MousePresent)
|
||
|
buttons |= IN_MouseButtons();
|
||
|
|
||
|
for(int i = 0; i < NUMBUTTONS; i++, buttons >>= 1)
|
||
|
if(buttons & 1)
|
||
|
btnstate[i] = true;
|
||
|
}
|
||
|
|
||
|
|
||
|
boolean IN_CheckAck (void)
|
||
|
{
|
||
|
IN_ProcessEvents();
|
||
|
//
|
||
|
// see if something has been pressed
|
||
|
//
|
||
|
if(LastScan)
|
||
|
return true;
|
||
|
|
||
|
int buttons = IN_JoyButtons() << 4;
|
||
|
|
||
|
if(MousePresent)
|
||
|
buttons |= IN_MouseButtons();
|
||
|
|
||
|
for(int i = 0; i < NUMBUTTONS; i++, buttons >>= 1)
|
||
|
{
|
||
|
if(buttons & 1)
|
||
|
{
|
||
|
if(!btnstate[i])
|
||
|
{
|
||
|
// Wait until button has been released
|
||
|
do
|
||
|
{
|
||
|
IN_WaitAndProcessEvents();
|
||
|
buttons = IN_JoyButtons() << 4;
|
||
|
|
||
|
if(MousePresent)
|
||
|
buttons |= IN_MouseButtons();
|
||
|
}
|
||
|
while(buttons & (1 << i));
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
btnstate[i] = false;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
void IN_Ack (void)
|
||
|
{
|
||
|
IN_StartAck ();
|
||
|
|
||
|
do
|
||
|
{
|
||
|
IN_WaitAndProcessEvents();
|
||
|
}
|
||
|
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 = GetTimeCount();
|
||
|
IN_StartAck ();
|
||
|
do
|
||
|
{
|
||
|
IN_ProcessEvents();
|
||
|
if (IN_CheckAck())
|
||
|
return true;
|
||
|
SDL_Delay(5);
|
||
|
} while (GetTimeCount() - lasttime < delay);
|
||
|
return(false);
|
||
|
}
|
||
|
|
||
|
//===========================================================================
|
||
|
|
||
|
/*
|
||
|
===================
|
||
|
=
|
||
|
= IN_MouseButtons
|
||
|
=
|
||
|
===================
|
||
|
*/
|
||
|
int IN_MouseButtons (void)
|
||
|
{
|
||
|
if (MousePresent)
|
||
|
return INL_GetMouseButtons();
|
||
|
else
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
bool IN_IsInputGrabbed()
|
||
|
{
|
||
|
return GrabInput;
|
||
|
}
|
||
|
|
||
|
void IN_CenterMouse()
|
||
|
{
|
||
|
SDL_WarpMouse(screenWidth / 2, screenHeight / 2);
|
||
|
}
|