X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=keys.c;h=199d311f99a902e41d3c70662967b2b23c705af5;hp=968cae63a7217b88c258009ca041d0849536fd64;hb=700595596cc73b077db70faab83ae761bdd2e36c;hpb=8dcce44300385b12c46d494c06aadcfa35a8bc14 diff --git a/keys.c b/keys.c index 968cae63..199d311f 100644 --- a/keys.c +++ b/keys.c @@ -8,7 +8,7 @@ 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. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -26,30 +26,32 @@ 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; +#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) -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 +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[] = @@ -67,7 +69,7 @@ keyname_t keynames[] = {"ALT", K_ALT}, {"CTRL", K_CTRL}, {"SHIFT", K_SHIFT}, - + {"F1", K_F1}, {"F2", K_F2}, {"F3", K_F3}, @@ -158,46 +160,90 @@ Interactive line editing and console scrollback */ void Key_Console (int key) { - char *cmd; - if (key == K_ENTER) { - Cbuf_AddText (key_lines[edit_line]+1); // skip the > + Cbuf_AddText (key_lines[edit_line]+1); // skip the ] Cbuf_AddText ("\n"); Con_Printf ("%s\n",key_lines[edit_line]); edit_line = (edit_line + 1) & 31; history_line = edit_line; key_lines[edit_line][0] = ']'; + key_lines[edit_line][1] = 0; // EvilTypeGuy: null terminate key_linepos = 1; + // force an update, because the command may take some time if (cls.state == ca_disconnected) - SCR_UpdateScreen (); // force an update, because the command - // may take some time + { + CL_UpdateScreen (); + CL_UpdateScreen (); + } return; } if (key == K_TAB) - { // command completion - cmd = Cmd_CompleteCommand (key_lines[edit_line]+1); - if (!cmd) - cmd = Cvar_CompleteVariable (key_lines[edit_line]+1); - if (cmd) + { + // Enhanced command completion + // by EvilTypeGuy eviltypeguy@qeradiant.com + // Thanks to Fett, Taniwha + Con_CompleteCommandLine(); + } + + // Advanced Console Editing by Radix radix@planetquake.com + // Added/Modified by EvilTypeGuy eviltypeguy@qeradiant.com + + // left arrow will just move left one without erasing, backspace will + // actually erase charcter + if (key == K_LEFTARROW) + { + if (key_linepos > 1) + key_linepos--; + return; + } + + if (key == K_BACKSPACE) // delete char before cursor + { + if (key_linepos > 1) { - strcpy (key_lines[edit_line]+1, cmd); - key_linepos = strlen(cmd)+1; - key_lines[edit_line][key_linepos] = ' '; + strcpy(key_lines[edit_line] + key_linepos - 1, key_lines[edit_line] + key_linepos); + key_linepos--; + } + return; + } + + if (key == K_DEL) // delete char on cursor + { + if (key_linepos < strlen(key_lines[edit_line])) + strcpy(key_lines[edit_line] + key_linepos, key_lines[edit_line] + key_linepos + 1); + return; + } + + + // if we're at the end, get one character from previous line, + // otherwise just go right one + if (key == K_RIGHTARROW) + { + if (strlen(key_lines[edit_line]) == key_linepos) + { + if (strlen(key_lines[(edit_line + 31) & 31]) <= key_linepos) + return; // no character to get + + key_lines[edit_line][key_linepos] = key_lines[(edit_line + 31) & 31][key_linepos]; key_linepos++; key_lines[edit_line][key_linepos] = 0; - return; } + else + key_linepos++; + + return; } - - if (key == K_BACKSPACE || key == K_LEFTARROW) + + if (key == K_INS) // toggle insert mode { - if (key_linepos > 1) - key_linepos--; + key_insert ^= 1; return; } + // End Advanced Console Editing + if (key == K_UPARROW) { do @@ -236,15 +282,15 @@ void Key_Console (int key) if (key == K_PGUP || key==K_MWHEELUP) { - con_backscroll += 2; - if (con_backscroll > con_totallines - (vid.height>>3) - 1) - con_backscroll = con_totallines - (vid.height>>3) - 1; + 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) { - con_backscroll -= 2; + con_backscroll -= ((int) scr_conlines >> 4); if (con_backscroll < 0) con_backscroll = 0; return; @@ -252,7 +298,7 @@ void Key_Console (int key) if (key == K_HOME) { - con_backscroll = con_totallines - (vid.height>>3) - 1; + con_backscroll = con_totallines - (vid.conheight>>3) - 1; return; } @@ -261,17 +307,36 @@ void Key_Console (int key) con_backscroll = 0; return; } - + if (key < 32 || key > 127) return; // non printable - + + + if (key_linepos < MAXCMDLINE-1) { + int i; + + if (key_insert) // check insert mode + { + // can't do strcpy to move string to right + i = strlen(key_lines[edit_line]) - 1; + + if (i == 254) + i--; + + for (; i >= key_linepos; i--) + key_lines[edit_line][i + 1] = key_lines[edit_line][i]; + } + + // only null terminate if at the end + i = key_lines[edit_line][key_linepos]; key_lines[edit_line][key_linepos] = key; key_linepos++; - key_lines[edit_line][key_linepos] = 0; - } + if (!i) + key_lines[edit_line][key_linepos] = 0; + } } //============================================================================ @@ -321,7 +386,7 @@ void Key_Message (int key) } // LordHavoc: increased messagemode length (was 31) - if (chat_bufferlen == 255) + if (chat_bufferlen == 240) return; // all full chat_buffer[chat_bufferlen++] = key; @@ -343,7 +408,7 @@ the K_* names are matched up. int Key_StringToKeynum (char *str) { keyname_t *kn; - + if (!str || !str[0]) return -1; if (!str[1]) @@ -368,9 +433,9 @@ FIXME: handle quote special (general escape sequence?) */ char *Key_KeynumToString (int keynum) { - keyname_t *kn; + keyname_t *kn; static char tinystr[2]; - + if (keynum == -1) return ""; if (keynum > 32 && keynum < 127) @@ -430,7 +495,7 @@ void Key_Unbind_f (void) Con_Printf ("unbind : remove commands from a key\n"); return; } - + b = Key_StringToKeynum (Cmd_Argv(1)); if (b==-1) { @@ -444,7 +509,7 @@ void Key_Unbind_f (void) void Key_Unbindall_f (void) { int i; - + for (i=0 ; i<256 ; i++) if (keybindings[i]) Key_SetBinding (i, ""); @@ -460,7 +525,7 @@ void Key_Bind_f (void) { int i, c, b; char cmd[1024]; - + c = Cmd_Argc(); if (c != 2 && c != 3) @@ -483,7 +548,7 @@ void Key_Bind_f (void) Con_Printf ("\"%s\" is not bound\n", Cmd_Argv(1) ); return; } - + // copy the rest of the command line cmd[0] = 0; // start out with a null string for (i=2 ; i< c ; i++) @@ -503,14 +568,14 @@ Key_WriteBindings Writes lines containing "bind key value" ============ */ -void Key_WriteBindings (FILE *f) +void Key_WriteBindings (QFile *f) { int i; for (i=0 ; i<256 ; i++) if (keybindings[i]) if (*keybindings[i]) - fprintf (f, "bind \"%s\" \"%s\"\n", Key_KeynumToString(i), keybindings[i]); + Qprintf (f, "bind \"%s\" \"%s\"\n", Key_KeynumToString(i), keybindings[i]); } @@ -523,13 +588,17 @@ void Key_Init (void) { 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++) { key_lines[i][0] = ']'; key_lines[i][1] = 0; } key_linepos = 1; - + // // init ascii characters in console mode // @@ -542,6 +611,8 @@ void Key_Init (void) consolekeys[K_UPARROW] = true; consolekeys[K_DOWNARROW] = true; consolekeys[K_BACKSPACE] = true; + consolekeys[K_DEL] = true; + consolekeys[K_INS] = true; consolekeys[K_PGUP] = true; consolekeys[K_PGDN] = true; consolekeys[K_SHIFT] = true; @@ -586,8 +657,6 @@ void Key_Init (void) Cmd_AddCommand ("bind",Key_Bind_f); Cmd_AddCommand ("unbind",Key_Unbind_f); Cmd_AddCommand ("unbindall",Key_Unbindall_f); - - } /* @@ -611,19 +680,15 @@ void Key_Event (int key, qboolean down) key_lastpress = key; key_count++; if (key_count <= 0) - { return; // just catching keys for Con_NotifyBox - } // update auto-repeat status if (down) { key_repeats[key]++; if (key != K_BACKSPACE && key != K_PAUSE && 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) ); } @@ -647,7 +712,6 @@ void Key_Event (int key, qboolean down) M_Keydown (key); break; case key_game: - case key_console: M_ToggleMenu_f (); break; default: @@ -656,89 +720,116 @@ 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 kenum as a parameter, so multiple -// downs can be matched with ups -// - if (!down) + // LordHavoc: hack to make toggleconsole always work + 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; - } + // + // 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) + // + // if not a consolekey, send to the interpreter no matter what mode is + // + //if ((key_dest == key_console && !consolekeys[key]) + 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"); + } } } @@ -750,9 +841,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;