duke3d/keyboard.c

462 lines
12 KiB
C
Executable File

//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------
#include "duke3d.h"
#include "keyboard.h"
/* this should be a proper prototype included from a header file */
extern int stricmp(const char *x, const char *y);
/*
=============================================================================
GLOBAL VARIABLES
=============================================================================
*/
volatile byte KB_KeyDown[ MAXKEYBOARDSCAN ]; // Keyboard state array
volatile kb_scancode KB_LastScan;
static volatile boolean keyIsWaiting = 0;
static char scancodeToASCII[ MAXKEYBOARDSCAN ];
static char shiftedScancodeToASCII[ MAXKEYBOARDSCAN ];
static char extscanToSC[ MAXKEYBOARDSCAN ];
/*
=============================================================================
FUNCTIONS
=============================================================================
*/
void keyhandler(void)
{
static boolean gotextended = false;
int rawkey = _readlastkeyhit();
int lastkey = rawkey & 0x7f;
// 128 bit means key was released.
int pressed = !(rawkey & 0x80);
if (rawkey == 0xe0 && !gotextended)
{
gotextended = true;
return;
}
if (rawkey == 0xe1)
{
/* SBF - build doesn't actually generate this for Pause/Break */
STUBBED("Another extended key!");
return;
}
if (gotextended)
{
gotextended = false;
/* remap extended key to Duke3D equivalent */
lastkey = extscanToSC[lastkey];
}
if (lastkey >= MAXKEYBOARDSCAN)
{
STUBBED("Scancode out of range!");
return;
}
if (pressed)
{
KB_LastScan = lastkey;
}
KB_KeyDown[lastkey] = pressed;
keyIsWaiting = ((keyIsWaiting) || (KB_KeyDown[lastkey]));
CONTROL_UpdateKeyboardState(lastkey, pressed);
}
void KB_KeyEvent( int scancode, boolean keypressed )
{
STUBBED("KB_KeyEvent");
}
boolean KB_KeyWaiting( void )
{
_handle_events();
return keyIsWaiting;
}
char KB_Getch( void )
{
int shifted;
while (!keyIsWaiting) { _idle(); /* pull the pud. */ }
keyIsWaiting = false;
if (KB_LastScan >= MAXKEYBOARDSCAN)
return(0xFF);
if (KB_KeyDown[sc_LeftShift] || KB_KeyDown[sc_RightShift])
return shiftedScancodeToASCII[KB_LastScan];
return scancodeToASCII[KB_LastScan];
}
void KB_Addch( char ch )
{
STUBBED("KB_Addch");
}
void KB_FlushKeyboardQueue( void )
{
_handle_events();
keyIsWaiting = false;
}
void KB_ClearKeysDown( void )
{
memset((void *) KB_KeyDown, '\0', sizeof (KB_KeyDown));
keyIsWaiting = false;
}
static struct {
char* name;
int code;
} keyname2scancode[] = {
{ "Comma", sc_Comma },
{ "Period", sc_Period },
{ "Enter", sc_Return },
{ "Escape", sc_Escape },
{ "Space", sc_Space },
{ "BakSpc", sc_BackSpace },
{ "Tab", sc_Tab },
{ "LAlt", sc_LeftAlt },
{ "LCtrl", sc_LeftControl },
{ "CapLck", sc_CapsLock },
{ "LShift", sc_LeftShift },
{ "RShift", sc_RightShift },
{ "F1", sc_F1 },
{ "F2", sc_F2 },
{ "F3", sc_F3 },
{ "F4", sc_F4 },
{ "F5", sc_F5 },
{ "F6", sc_F6 },
{ "F7", sc_F7 },
{ "F8", sc_F8 },
{ "F9", sc_F9 },
{ "F10", sc_F10 },
{ "F11", sc_F11 },
{ "F12", sc_F12 },
{ "KStar", sc_Kpad_Star },
{ "Pause", sc_Pause },
{ "ScrLck", sc_ScrollLock },
{ "NumLck", sc_NumLock },
{ "Slash", sc_Slash },
{ "Semi", sc_SemiColon },
{ "Quote", sc_Quote },
{ "Tilde", sc_Tilde },
{ "BkSlash", sc_BackSlash },
{ "LBrack", sc_OpenBracket },
{ "RBrack", sc_CloseBracket },
{ "1", sc_1 },
{ "2", sc_2 },
{ "3", sc_3 },
{ "4", sc_4 },
{ "5", sc_5 },
{ "6", sc_6 },
{ "7", sc_7 },
{ "8", sc_8 },
{ "9", sc_9 },
{ "0", sc_0 },
{ "Minus", sc_Minus },
{ "Equals", sc_Equals },
{ "Plus", sc_Plus },
{ "Kpad1", sc_kpad_1 },
{ "Kpad2", sc_kpad_2 },
{ "Kpad3", sc_kpad_3 },
{ "Kpad4", sc_kpad_4 },
{ "Kpad5", sc_kpad_5 },
{ "Kpad6", sc_kpad_6 },
{ "Kpad7", sc_kpad_7 },
{ "Kpad8", sc_kpad_8 },
{ "Kpad9", sc_kpad_9 },
{ "Kpad0", sc_kpad_0 },
{ "KMinus", sc_kpad_Minus },
{ "KPlus", sc_kpad_Plus },
{ "KPeriod", sc_kpad_Period },
{ "A", sc_A },
{ "B", sc_B },
{ "C", sc_C },
{ "D", sc_D },
{ "E", sc_E },
{ "F", sc_F },
{ "G", sc_G },
{ "H", sc_H },
{ "I", sc_I },
{ "J", sc_J },
{ "K", sc_K },
{ "L", sc_L },
{ "M", sc_M },
{ "N", sc_N },
{ "O", sc_O },
{ "P", sc_P },
{ "Q", sc_Q },
{ "R", sc_R },
{ "S", sc_S },
{ "T", sc_T },
{ "U", sc_U },
{ "V", sc_V },
{ "W", sc_W },
{ "X", sc_X },
{ "Y", sc_Y },
{ "Z", sc_Z },
{ "Up", sc_UpArrow },
{ "Down", sc_DownArrow },
{ "Left", sc_LeftArrow },
{ "Right", sc_RightArrow },
{ "Insert", sc_Insert },
{ "Delete", sc_Delete },
{ "Home", sc_Home },
{ "End", sc_End },
{ "PgUp", sc_PgUp },
{ "PgDn", sc_PgDn },
{ "RAlt", sc_RightAlt },
{ "RCtrl", sc_RightControl },
{ "KpdSl", sc_kpad_Slash },
{ "KpdEnt", sc_kpad_Enter },
{ "PrtScn", sc_PrintScreen },
// AZERTY hacks...
{ "INTL1", sc_INTL1 },
{ "INTL2", sc_INTL2 },
{ "INTL3", sc_INTL3 },
{ "INTL4", sc_INTL4 },
{ "INTL5", sc_INTL5 },
{ "INTL6", sc_INTL6 },
{ "INTL7", sc_INTL7 },
{ "INTL8", sc_INTL8 },
{ "INTL9", sc_INTL9 },
{ "INTL10", sc_INTL10 },
{ "INTL11", sc_INTL11 },
{ "INTL12", sc_INTL12 },
{ "INTL13", sc_INTL13 },
{ "INTL14", sc_INTL14 },
{ "INTL15", sc_INTL15 },
{ NULL, 0 }
};
char *KB_ScanCodeToString( kb_scancode scancode )
{
int i;
for(i = 0; keyname2scancode[i].name != NULL; i++)
{
if (keyname2scancode[i].code == scancode)
return keyname2scancode[i].name;
}
return NULL;
}
kb_scancode KB_StringToScanCode( char * string )
{
char* name = NULL;
int32 i=0;
name = keyname2scancode[i].name;
for(;name;++i, name=keyname2scancode[i].name)
{
if(!stricmp(name,string))
break;
}
return keyname2scancode[i].code;
}
void KB_TurnKeypadOn( void )
{
STUBBED("KB_TurnKeypadOn");
}
void KB_TurnKeypadOff( void )
{
STUBBED("KB_TurnKeypadOff");
}
boolean KB_KeypadActive( void )
{
STUBBED("KB_KeypadActive");
return false;
}
void KB_Startup( void )
{
memset(scancodeToASCII, 0xFF, sizeof (scancodeToASCII));
// !!! FIXME: incomplete?
scancodeToASCII[sc_A] = 'a';
scancodeToASCII[sc_B] = 'b';
scancodeToASCII[sc_C] = 'c';
scancodeToASCII[sc_D] = 'd';
scancodeToASCII[sc_E] = 'e';
scancodeToASCII[sc_F] = 'f';
scancodeToASCII[sc_G] = 'g';
scancodeToASCII[sc_H] = 'h';
scancodeToASCII[sc_I] = 'i';
scancodeToASCII[sc_J] = 'j';
scancodeToASCII[sc_K] = 'k';
scancodeToASCII[sc_L] = 'l';
scancodeToASCII[sc_M] = 'm';
scancodeToASCII[sc_N] = 'n';
scancodeToASCII[sc_O] = 'o';
scancodeToASCII[sc_P] = 'p';
scancodeToASCII[sc_Q] = 'q';
scancodeToASCII[sc_R] = 'r';
scancodeToASCII[sc_S] = 's';
scancodeToASCII[sc_T] = 't';
scancodeToASCII[sc_U] = 'u';
scancodeToASCII[sc_V] = 'v';
scancodeToASCII[sc_W] = 'w';
scancodeToASCII[sc_X] = 'x';
scancodeToASCII[sc_Y] = 'y';
scancodeToASCII[sc_Z] = 'z';
scancodeToASCII[sc_0] = '0';
scancodeToASCII[sc_1] = '1';
scancodeToASCII[sc_2] = '2';
scancodeToASCII[sc_3] = '3';
scancodeToASCII[sc_4] = '4';
scancodeToASCII[sc_5] = '5';
scancodeToASCII[sc_6] = '6';
scancodeToASCII[sc_7] = '7';
scancodeToASCII[sc_8] = '8';
scancodeToASCII[sc_9] = '9';
scancodeToASCII[sc_Escape] = asc_Escape;
scancodeToASCII[sc_Tab] = asc_Tab;
scancodeToASCII[sc_Space] = asc_Space;
scancodeToASCII[sc_Enter] = asc_Enter;
scancodeToASCII[sc_BackSpace] = asc_BackSpace;
scancodeToASCII[sc_Comma] = ',';
scancodeToASCII[sc_Period] = '.';
scancodeToASCII[sc_Kpad_Star] = '*';
scancodeToASCII[sc_Slash] = '/';
scancodeToASCII[sc_SemiColon] = ';';
scancodeToASCII[sc_Quote] = '\'';
scancodeToASCII[sc_Tilde] = '`';
scancodeToASCII[sc_BackSlash] = '\\';
scancodeToASCII[sc_OpenBracket] = '[';
scancodeToASCII[sc_CloseBracket] = ']';
scancodeToASCII[sc_Minus] = '-';
scancodeToASCII[sc_Equals] = '=';
scancodeToASCII[sc_Plus] = '+';
scancodeToASCII[sc_kpad_Minus] = '-';
scancodeToASCII[sc_kpad_Period] = '.';
scancodeToASCII[sc_kpad_Plus] = '+';
// !!! FIXME: incomplete?
memset(shiftedScancodeToASCII, 0xFF, sizeof (shiftedScancodeToASCII));
shiftedScancodeToASCII[sc_A] = 'A';
shiftedScancodeToASCII[sc_B] = 'B';
shiftedScancodeToASCII[sc_C] = 'C';
shiftedScancodeToASCII[sc_D] = 'D';
shiftedScancodeToASCII[sc_E] = 'E';
shiftedScancodeToASCII[sc_F] = 'F';
shiftedScancodeToASCII[sc_G] = 'G';
shiftedScancodeToASCII[sc_H] = 'H';
shiftedScancodeToASCII[sc_I] = 'I';
shiftedScancodeToASCII[sc_J] = 'J';
shiftedScancodeToASCII[sc_K] = 'K';
shiftedScancodeToASCII[sc_L] = 'L';
shiftedScancodeToASCII[sc_M] = 'M';
shiftedScancodeToASCII[sc_N] = 'N';
shiftedScancodeToASCII[sc_O] = 'O';
shiftedScancodeToASCII[sc_P] = 'P';
shiftedScancodeToASCII[sc_Q] = 'Q';
shiftedScancodeToASCII[sc_R] = 'R';
shiftedScancodeToASCII[sc_S] = 'S';
shiftedScancodeToASCII[sc_T] = 'T';
shiftedScancodeToASCII[sc_U] = 'U';
shiftedScancodeToASCII[sc_V] = 'V';
shiftedScancodeToASCII[sc_W] = 'W';
shiftedScancodeToASCII[sc_X] = 'X';
shiftedScancodeToASCII[sc_Y] = 'Y';
shiftedScancodeToASCII[sc_Z] = 'Z';
shiftedScancodeToASCII[sc_0] = ')';
shiftedScancodeToASCII[sc_1] = '!';
shiftedScancodeToASCII[sc_2] = '@';
shiftedScancodeToASCII[sc_3] = '#';
shiftedScancodeToASCII[sc_4] = '$';
shiftedScancodeToASCII[sc_5] = '%';
shiftedScancodeToASCII[sc_6] = '^';
shiftedScancodeToASCII[sc_7] = '&';
shiftedScancodeToASCII[sc_8] = '*';
shiftedScancodeToASCII[sc_9] = '(';
shiftedScancodeToASCII[sc_Comma] = '<';
shiftedScancodeToASCII[sc_Period] = '>';
shiftedScancodeToASCII[sc_Kpad_Star] = '*';
shiftedScancodeToASCII[sc_Slash] = '?';
shiftedScancodeToASCII[sc_SemiColon] = ':';
shiftedScancodeToASCII[sc_Quote] = '\"';
shiftedScancodeToASCII[sc_Tilde] = '~';
shiftedScancodeToASCII[sc_BackSlash] = '|';
shiftedScancodeToASCII[sc_OpenBracket] = '{';
shiftedScancodeToASCII[sc_CloseBracket] = '}';
shiftedScancodeToASCII[sc_Minus] = '_';
shiftedScancodeToASCII[sc_Equals] = '+';
shiftedScancodeToASCII[sc_Plus] = '+';
shiftedScancodeToASCII[sc_kpad_Minus] = '-';
shiftedScancodeToASCII[sc_kpad_Period] = '.';
shiftedScancodeToASCII[sc_kpad_Plus] = '+';
memset(extscanToSC, '\0', sizeof (extscanToSC));
/* map extended keys to their Duke3D equivalents */
extscanToSC[0x1C] = sc_kpad_Enter;
extscanToSC[0x1D] = sc_RightControl;
extscanToSC[0x35] = sc_kpad_Slash;
extscanToSC[0x37] = sc_PrintScreen;
extscanToSC[0x38] = sc_RightAlt;
extscanToSC[0x47] = sc_Home;
extscanToSC[0x48] = sc_UpArrow;
extscanToSC[0x49] = sc_PgUp;
extscanToSC[0x4B] = sc_LeftArrow;
extscanToSC[0x4D] = sc_RightArrow;
extscanToSC[0x4F] = sc_End;
extscanToSC[0x50] = sc_DownArrow;
extscanToSC[0x51] = sc_PgDn;
extscanToSC[0x52] = sc_Insert;
extscanToSC[0x53] = sc_Delete;
KB_ClearKeysDown();
}
void KB_Shutdown( void )
{
KB_ClearKeysDown();
}