462 lines
12 KiB
C
462 lines
12 KiB
C
|
//-------------------------------------------------------------------------
|
||
|
/*
|
||
|
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();
|
||
|
}
|
||
|
|