//------------------------------------------------------------------------- /* 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(); }