X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=keys.c;h=e89ff178b453c22aa65aedf39cb3a096c795695d;hb=af0b7a1fa11c2ceedeb9f66ca950f6c0bff8ad8f;hp=f44a4681a5236221b5160ed540615805cc037ac0;hpb=ea7c24e1fb41f3b1df984ac0eed6881c9fde16f5;p=xonotic%2Fdarkplaces.git diff --git a/keys.c b/keys.c index f44a4681..e89ff178 100644 --- a/keys.c +++ b/keys.c @@ -26,31 +26,29 @@ key up events are sent even if in console mode */ -#define MAXCMDLINE 256 -char key_lines[32][MAXCMDLINE]; -int key_linepos; -int shift_down = false; -int key_lastpress; -int key_insert; // insert key toggle (for editing) +#define MAXCMDLINE 256 +char key_lines[32][MAXCMDLINE]; +int key_linepos; +int shift_down = false; +int key_insert; // insert key toggle (for editing) -int edit_line = 0; -int history_line = 0; +int edit_line = 0; +int history_line = 0; -keydest_t key_dest; +int key_consoleactive; +keydest_t key_dest; -int key_count; // incremented every key event - -char *keybindings[256]; -qboolean consolekeys[256]; // if true, can't be rebound while in console -qboolean menubound[256]; // if true, can't be rebound while in menu -int keyshift[256]; // key to map to if shift held down in console -int key_repeats[256]; // if > 1, it is autorepeating -qboolean keydown[256]; +char *keybindings[256]; +qboolean consolekeys[256]; // if true, can't be rebound while in console +qboolean menubound[256]; // if true, can't be rebound while in menu +int keyshift[256]; // key to map to if shift held down in console +int key_repeats[256]; // if > 1, it is autorepeating +qboolean keydown[256]; typedef struct { - char *name; - int keynum; + char *name; + int keynum; } keyname_t; keyname_t keynames[] = @@ -92,6 +90,17 @@ keyname_t keynames[] = {"MOUSE1", K_MOUSE1}, {"MOUSE2", K_MOUSE2}, {"MOUSE3", K_MOUSE3}, + // LordHavoc: thanks to backslash for this MOUSE4 and MOUSE5 code + /* backslash :: imouse explorer buttons */ + {"MOUSE4", K_MOUSE4}, + {"MOUSE5", K_MOUSE5}, + /* :: backslash */ + // LordHavoc: added more for completeness + {"MOUSE6", K_MOUSE6}, + {"MOUSE7", K_MOUSE7}, + {"MOUSE8", K_MOUSE8}, + {"MOUSE9", K_MOUSE9}, + {"MOUSE10", K_MOUSE10}, {"JOY1", K_JOY1}, {"JOY2", K_JOY2}, @@ -131,10 +140,26 @@ keyname_t keynames[] = {"AUX31", K_AUX31}, {"AUX32", K_AUX32}, - {"PAUSE", K_PAUSE}, + {"KP_HOME", K_KP_HOME }, + {"KP_UPARROW", K_KP_UPARROW }, + {"KP_PGUP", K_KP_PGUP }, + {"KP_LEFTARROW", K_KP_LEFTARROW }, + {"KP_5", K_KP_5 }, + {"KP_RIGHTARROW", K_KP_RIGHTARROW }, + {"KP_END", K_KP_END }, + {"KP_DOWNARROW", K_KP_DOWNARROW }, + {"KP_PGDN", K_KP_PGDN }, + {"KP_ENTER", K_KP_ENTER }, + {"KP_INS", K_KP_INS }, + {"KP_DEL", K_KP_DEL }, + {"KP_SLASH", K_KP_SLASH }, + {"KP_MINUS", K_KP_MINUS }, + {"KP_PLUS", K_KP_PLUS }, + + {"MWHEELUP", K_MWHEELUP }, + {"MWHEELDOWN", K_MWHEELDOWN }, - {"MWHEELUP", K_MWHEELUP}, - {"MWHEELDOWN", K_MWHEELDOWN}, + {"PAUSE", K_PAUSE}, {"SEMICOLON", ';'}, // because a raw semicolon seperates commands @@ -159,7 +184,87 @@ Interactive line editing and console scrollback */ void Key_Console (int key) { - if (key == K_ENTER) + // LordHavoc: copied most of this from Q2 to improve keyboard handling + switch (key) + { + case K_KP_SLASH: + key = '/'; + break; + case K_KP_MINUS: + key = '-'; + break; + case K_KP_PLUS: + key = '+'; + break; + case K_KP_HOME: + key = '7'; + break; + case K_KP_UPARROW: + key = '8'; + break; + case K_KP_PGUP: + key = '9'; + break; + case K_KP_LEFTARROW: + key = '4'; + break; + case K_KP_5: + key = '5'; + break; + case K_KP_RIGHTARROW: + key = '6'; + break; + case K_KP_END: + key = '1'; + break; + case K_KP_DOWNARROW: + key = '2'; + break; + case K_KP_PGDN: + key = '3'; + break; + case K_KP_INS: + key = '0'; + break; + case K_KP_DEL: + key = '.'; + break; + } + + // LordHavoc: FIXME: implement this sometime + #if 0 + if ((toupper(key) == 'V' && keydown[K_CTRL]) || ((key == K_INS || key == K_KP_INS) && keydown[K_SHIFT])) + { + char *cbd; + if ((cbd = Sys_GetClipboardData()) != 0) + { + int i; + strtok(cbd, "\n\r\b"); + i = strlen(cbd); + if (i + key_linepos >= MAXCMDLINE) + i= MAXCMDLINE - key_linepos; + if (i > 0) + { + cbd[i]=0; + strcat(key_lines[edit_line], cbd); + key_linepos += i; + } + free(cbd); + } + return; + } + #endif + + if (key == 'l') + { + if (keydown[K_CTRL]) + { + Cbuf_AddText ("clear\n"); + return; + } + } + + if (key == K_ENTER || key == K_KP_ENTER) { Cbuf_AddText (key_lines[edit_line]+1); // skip the ] Cbuf_AddText ("\n"); @@ -184,6 +289,7 @@ void Key_Console (int key) // by EvilTypeGuy eviltypeguy@qeradiant.com // Thanks to Fett, Taniwha Con_CompleteCommandLine(); + return; } // Advanced Console Editing by Radix radix@planetquake.com @@ -191,14 +297,15 @@ void Key_Console (int key) // left arrow will just move left one without erasing, backspace will // actually erase charcter - if (key == K_LEFTARROW) + if (key == K_LEFTARROW || key == K_KP_LEFTARROW) { if (key_linepos > 1) key_linepos--; return; } - if (key == K_BACKSPACE) // delete char before cursor + // delete char before cursor + if (key == K_BACKSPACE || (key == 'h' && keydown[K_CTRL])) { if (key_linepos > 1) { @@ -208,9 +315,10 @@ void Key_Console (int key) return; } - if (key == K_DEL) // delete char on cursor + // delete char on cursor + if (key == K_DEL || key == K_KP_DEL) { - if (key_linepos < strlen(key_lines[edit_line])) + if ((size_t)key_linepos < strlen(key_lines[edit_line])) strcpy(key_lines[edit_line] + key_linepos, key_lines[edit_line] + key_linepos + 1); return; } @@ -218,11 +326,11 @@ void Key_Console (int key) // if we're at the end, get one character from previous line, // otherwise just go right one - if (key == K_RIGHTARROW) + if (key == K_RIGHTARROW || key == K_KP_RIGHTARROW) { - if (strlen(key_lines[edit_line]) == key_linepos) + if (strlen(key_lines[edit_line]) == (size_t)key_linepos) { - if (strlen(key_lines[(edit_line + 31) & 31]) <= key_linepos) + if (strlen(key_lines[(edit_line + 31) & 31]) <= (size_t)key_linepos) return; // no character to get key_lines[edit_line][key_linepos] = key_lines[(edit_line + 31) & 31][key_linepos]; @@ -235,7 +343,7 @@ void Key_Console (int key) return; } - if (key == K_INS) // toggle insert mode + if (key == K_INS || key == K_KP_INS) // toggle insert mode { key_insert ^= 1; return; @@ -243,7 +351,7 @@ void Key_Console (int key) // End Advanced Console Editing - if (key == K_UPARROW) + if (key == K_UPARROW || key == K_KP_UPARROW || (key == 'p' && keydown[K_CTRL])) { do { @@ -257,7 +365,7 @@ void Key_Console (int key) return; } - if (key == K_DOWNARROW) + if (key == K_DOWNARROW || key == K_KP_DOWNARROW || (key == 'n' && keydown[K_CTRL])) { if (history_line == edit_line) return; do @@ -279,38 +387,37 @@ void Key_Console (int key) return; } - if (key == K_PGUP || key==K_MWHEELUP) + if (key == K_PGUP || key == K_KP_PGUP || key == K_MWHEELUP) { - con_backscroll += 2; + con_backscroll += ((int) scr_conlines >> 4); if (con_backscroll > con_totallines - (vid.conheight>>3) - 1) con_backscroll = con_totallines - (vid.conheight>>3) - 1; return; } - if (key == K_PGDN || key==K_MWHEELDOWN) + if (key == K_PGDN || key == K_KP_PGDN || key == K_MWHEELDOWN) { - con_backscroll -= 2; + con_backscroll -= ((int) scr_conlines >> 4); if (con_backscroll < 0) con_backscroll = 0; return; } - if (key == K_HOME) + if (key == K_HOME || key == K_KP_HOME) { con_backscroll = con_totallines - (vid.conheight>>3) - 1; return; } - if (key == K_END) + if (key == K_END || key == K_KP_END) { con_backscroll = 0; return; } - - if (key < 32 || key > 127) - return; // non printable - + // non printable + if (key < 32 || key > 127) + return; if (key_linepos < MAXCMDLINE-1) { @@ -341,16 +448,15 @@ void Key_Console (int key) //============================================================================ // LordHavoc: increased messagemode length (was 32) +qboolean chat_team = false; char chat_buffer[256]; -qboolean team_message = false; +int chat_bufferlen = 0; void Key_Message (int key) { - static int chat_bufferlen = 0; - - if (key == K_ENTER) + if (key == K_ENTER || key == K_KP_ENTER) { - if (team_message) + if (chat_team) Cbuf_AddText ("say_team \""); else Cbuf_AddText ("say \""); @@ -371,8 +477,9 @@ void Key_Message (int key) return; } + // non printable if (key < 32 || key > 127) - return; // non printable + return; if (key == K_BACKSPACE) { @@ -384,8 +491,7 @@ void Key_Message (int key) return; } - // LordHavoc: increased messagemode length (was 31) - if (chat_bufferlen == 240) + if (chat_bufferlen == sizeof(chat_buffer) - 1) return; // all full chat_buffer[chat_bufferlen++] = key; @@ -404,9 +510,9 @@ the given string. Single ascii characters return themselves, while the K_* names are matched up. =================== */ -int Key_StringToKeynum (char *str) +int Key_StringToKeynum (const char *str) { - keyname_t *kn; + keyname_t *kn; if (!str || !str[0]) return -1; @@ -414,10 +520,8 @@ int Key_StringToKeynum (char *str) return str[0]; for (kn=keynames ; kn->name ; kn++) - { - if (!Q_strcasecmp(str,kn->name)) + if (!strcasecmp(str,kn->name)) return kn->keynum; - } return -1; } @@ -432,8 +536,8 @@ FIXME: handle quote special (general escape sequence?) */ char *Key_KeynumToString (int keynum) { - keyname_t *kn; - static char tinystr[2]; + keyname_t *kn; + static char tinystr[2]; if (keynum == -1) return ""; @@ -443,7 +547,7 @@ char *Key_KeynumToString (int keynum) tinystr[1] = 0; return tinystr; } - + for (kn=keynames ; kn->name ; kn++) if (keynum == kn->keynum) return kn->name; @@ -459,10 +563,10 @@ Key_SetBinding */ void Key_SetBinding (int keynum, char *binding) { - char *new; - int l; - - if (keynum == -1) + char *new; + int l; + + if (keynum < 0 || keynum >= 256) return; // free old bindings @@ -471,13 +575,13 @@ void Key_SetBinding (int keynum, char *binding) Z_Free (keybindings[keynum]); keybindings[keynum] = NULL; } - + // allocate memory for new binding - l = strlen (binding); + l = strlen (binding); new = Z_Malloc (l+1); strcpy (new, binding); new[l] = 0; - keybindings[keynum] = new; + keybindings[keynum] = new; } /* @@ -487,7 +591,7 @@ Key_Unbind_f */ void Key_Unbind_f (void) { - int b; + int b; if (Cmd_Argc() != 2) { @@ -496,7 +600,7 @@ void Key_Unbind_f (void) } b = Key_StringToKeynum (Cmd_Argv(1)); - if (b==-1) + if (b == -1) { Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(1)); return; @@ -507,9 +611,9 @@ void Key_Unbind_f (void) void Key_Unbindall_f (void) { - int i; + int i; - for (i=0 ; i<256 ; i++) + for (i = 0;i < 256;i++) if (keybindings[i]) Key_SetBinding (i, ""); } @@ -522,8 +626,8 @@ Key_Bind_f */ void Key_Bind_f (void) { - int i, c, b; - char cmd[1024]; + int i, c, b; + char cmd[1024]; c = Cmd_Argc(); @@ -533,7 +637,7 @@ void Key_Bind_f (void) return; } b = Key_StringToKeynum (Cmd_Argv(1)); - if (b==-1) + if (b == -1) { Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(1)); return; @@ -549,7 +653,8 @@ void Key_Bind_f (void) } // copy the rest of the command line - cmd[0] = 0; // start out with a null string + // start out with a null string + cmd[0] = 0; for (i=2 ; i< c ; i++) { if (i > 2) @@ -567,14 +672,29 @@ Key_WriteBindings Writes lines containing "bind key value" ============ */ -void Key_WriteBindings (QFile *f) +void Key_WriteBindings (qfile_t *f) { - int i; + int i; - for (i=0 ; i<256 ; i++) - if (keybindings[i]) - if (*keybindings[i]) - Qprintf (f, "bind \"%s\" \"%s\"\n", Key_KeynumToString(i), keybindings[i]); + for (i = 0;i < 256;i++) + if (keybindings[i] && *keybindings[i]) + FS_Printf (f, "bind \"%s\" \"%s\"\n", Key_KeynumToString(i), keybindings[i]); +} + + +/* +============ +Key_Bindlist_f + +============ +*/ +void Key_Bindlist_f (void) +{ + int i; + + for (i = 0;i < 256;i++) + if (keybindings[i] && keybindings[i][0]) + Con_Printf ("%s \"%s\"\n", Key_KeynumToString(i), keybindings[i]); } @@ -585,13 +705,13 @@ Key_Init */ void Key_Init (void) { - int i; + int i; // LordHavoc: clear keybindings array so bounds checking won't freak for (i = 0;i < 256;i++) keybindings[i] = NULL; - for (i=0 ; i<32 ; i++) + for (i = 0;i < 32;i++) { key_lines[i][0] = ']'; key_lines[i][1] = 0; @@ -601,28 +721,35 @@ void Key_Init (void) // // init ascii characters in console mode // - for (i=32 ; i<128 ; i++) + for (i = 32;i < 128;i++) consolekeys[i] = true; - consolekeys[K_ENTER] = true; + consolekeys[K_ENTER] = true;consolekeys[K_KP_ENTER] = true; consolekeys[K_TAB] = true; - consolekeys[K_LEFTARROW] = true; - consolekeys[K_RIGHTARROW] = true; - consolekeys[K_UPARROW] = true; - consolekeys[K_DOWNARROW] = true; + consolekeys[K_LEFTARROW] = true;consolekeys[K_KP_LEFTARROW] = true; + consolekeys[K_RIGHTARROW] = true;consolekeys[K_KP_RIGHTARROW] = true; + consolekeys[K_UPARROW] = true;consolekeys[K_KP_UPARROW] = true; + consolekeys[K_DOWNARROW] = true;consolekeys[K_KP_DOWNARROW] = true; consolekeys[K_BACKSPACE] = true; - consolekeys[K_DEL] = true; - consolekeys[K_INS] = true; - consolekeys[K_PGUP] = true; - consolekeys[K_PGDN] = true; + consolekeys[K_HOME] = true;consolekeys[K_KP_HOME] = true; + consolekeys[K_END] = true;consolekeys[K_KP_END] = true; + consolekeys[K_PGUP] = true;consolekeys[K_KP_PGUP] = true; + consolekeys[K_PGDN] = true;consolekeys[K_KP_PGDN] = true; consolekeys[K_SHIFT] = true; + consolekeys[K_INS] = true;consolekeys[K_KP_INS] = true; + consolekeys[K_DEL] = true;consolekeys[K_KP_DEL] = true; + consolekeys[K_KP_SLASH] = true; + consolekeys[K_KP_PLUS] = true; + consolekeys[K_KP_MINUS] = true; + consolekeys[K_KP_5] = true; consolekeys[K_MWHEELUP] = true; consolekeys[K_MWHEELDOWN] = true; + consolekeys['`'] = false; consolekeys['~'] = false; - for (i=0 ; i<256 ; i++) + for (i = 0;i < 256;i++) keyshift[i] = i; - for (i='a' ; i<='z' ; i++) + for (i = 'a';i <= 'z';i++) keyshift[i] = i - 'a' + 'A'; keyshift['1'] = '!'; keyshift['2'] = '@'; @@ -656,6 +783,7 @@ void Key_Init (void) Cmd_AddCommand ("bind",Key_Bind_f); Cmd_AddCommand ("unbind",Key_Unbind_f); Cmd_AddCommand ("unbindall",Key_Unbindall_f); + Cmd_AddCommand ("bindlist",Key_Bindlist_f); } /* @@ -673,24 +801,24 @@ void Key_Event (int key, qboolean down) keydown[key] = down; - if (!down) - key_repeats[key] = 0; - - key_lastpress = key; - key_count++; - if (key_count <= 0) - return; // just catching keys for Con_NotifyBox - -// update auto-repeat status + // update auto-repeat status if (down) { key_repeats[key]++; - if (key != K_BACKSPACE && key != K_PAUSE && key_repeats[key] > 1) + if (key != K_BACKSPACE + && key != K_PAUSE + && key != K_PGUP + && key != K_KP_PGUP + && key != K_PGDN + && key != K_KP_PGDN + && key_repeats[key] > 1) return; // ignore most autorepeats - + if (key >= 200 && !keybindings[key]) - Con_Printf ("%s is unbound, hit F4 to set.\n", Key_KeynumToString (key) ); + Con_Printf ("%s is unbound, hit F4 to set.\n", Key_KeynumToString (key)); } + else + key_repeats[key] = 0; if (key == K_SHIFT) shift_down = down; @@ -711,7 +839,6 @@ void Key_Event (int key, qboolean down) M_Keydown (key); break; case key_game: - case key_console: M_ToggleMenu_f (); break; default: @@ -720,89 +847,120 @@ void Key_Event (int key, qboolean down) return; } -// -// key up events only generate commands if the game key binding is -// a button command (leading + sign). These will occur even in console mode, -// to keep the character from continuing an action started before a console -// switch. Button commands include the keynum as a parameter, so multiple -// downs can be matched with ups -// - if (!down) + // console key is hardcoded, so the user can never unbind it + if (key == '`' || key == '~') + { + if (down) + Con_ToggleConsole_f (); + return; + } + + if (down) { kb = keybindings[key]; - if (kb && kb[0] == '+') + if (kb && !strncmp(kb, "toggleconsole", strlen("toggleconsole"))) { - sprintf (cmd, "-%s %i\n", kb+1, key); - Cbuf_AddText (cmd); + Cbuf_AddText (kb); + Cbuf_AddText ("\n"); + return; } - if (keyshift[key] != key) + } + + if (key_consoleactive && consolekeys[key]) + { + // console only wants key down events + if (!down) + return; + + // FIXME: this does not support non-QWERTY keyboards + if (shift_down) + key = keyshift[key]; + + Key_Console (key); + } + else + { + // + // key up events only generate commands if the game key binding is + // a button command (leading + sign). These will occur even in console mode, + // to keep the character from continuing an action started before a console + // switch. Button commands include the keynum as a parameter, so multiple + // downs can be matched with ups + // + if (!down) { - kb = keybindings[keyshift[key]]; + kb = keybindings[key]; if (kb && kb[0] == '+') { sprintf (cmd, "-%s %i\n", kb+1, key); Cbuf_AddText (cmd); } + if (keyshift[key] != key) + { + kb = keybindings[keyshift[key]]; + if (kb && kb[0] == '+') + { + sprintf (cmd, "-%s %i\n", kb+1, key); + Cbuf_AddText (cmd); + } + } + return; } - return; - } - -// -// during demo playback, most keys bring up the main menu -// - if (cls.demoplayback && down && consolekeys[key] && key_dest == key_game) - { - M_ToggleMenu_f (); - return; - } -// -// if not a consolekey, send to the interpreter no matter what mode is -// - if ( (key_dest == key_menu && menubound[key]) - || (key_dest == key_console && !consolekeys[key]) - || (key_dest == key_game && ( !con_forcedup || !consolekeys[key] ) ) ) - { - kb = keybindings[key]; - if (kb) + // + // during demo playback, most keys bring up the main menu + // + if (cls.demoplayback && down && consolekeys[key] && key_dest == key_game) + key = K_ESCAPE; + + // + // if not a consolekey, send to the interpreter no matter what mode is + // + if ((key_consoleactive && !consolekeys[key]) + || (key_dest == key_menu && menubound[key]) + || key_dest == key_game) { - if (kb[0] == '+') - { // button commands add keynum as a parm - sprintf (cmd, "%s %i\n", kb, key); - Cbuf_AddText (cmd); - } - else + kb = keybindings[key]; + if (kb) { - Cbuf_AddText (kb); - Cbuf_AddText ("\n"); + if (kb[0] == '+') + { + // button commands add keynum as a parm + sprintf (cmd, "%s %i\n", kb, key); + Cbuf_AddText (cmd); + } + else + { + Cbuf_AddText (kb); + Cbuf_AddText ("\n"); + } } + return; } - return; - } - if (!down) - return; // other systems only care about key down events + if (!down) + return; // other systems only care about key down events - if (shift_down) - { - key = keyshift[key]; - } + // FIXME: this does not support non-QWERTY keyboards + if (shift_down) + key = keyshift[key]; - switch (key_dest) - { - case key_message: - Key_Message (key); - break; - case key_menu: - M_Keydown (key); - break; + switch (key_dest) + { + case key_message: + Key_Message (key); + break; + case key_menu: + M_Keydown (key); + break; - case key_game: - case key_console: - Key_Console (key); - break; - default: - Sys_Error ("Bad key_dest"); + case key_game: + //case key_console: + Key_Console (key); + break; + default: + Sys_Error ("Bad key_dest"); + } } } @@ -814,9 +972,9 @@ Key_ClearStates */ void Key_ClearStates (void) { - int i; + int i; - for (i=0 ; i<256 ; i++) + for (i = 0;i < 256;i++) { keydown[i] = false; key_repeats[i] = 0;