]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - keys.c
Fix CL_VM_InputeEvent prototype in keys.c
[xonotic/darkplaces.git] / keys.c
diff --git a/keys.c b/keys.c
index 7ef45f1dedabeaeaae1063530e5830693afcf385..bc20e8be121f73d820b4382da4256fd5fba5f0ba 100644 (file)
--- a/keys.c
+++ b/keys.c
@@ -23,7 +23,7 @@
 #include "quakedef.h"
 #include "cl_video.h"
 
-cvar_t con_closeontoggleconsole = {CVAR_SAVE, "con_closeontoggleconsole","0", "allows toggleconsole binds to close the console as well"};
+cvar_t con_closeontoggleconsole = {CVAR_SAVE, "con_closeontoggleconsole","1", "allows toggleconsole binds to close the console as well"};
 
 /*
 key up events are sent even if in console mode
@@ -53,6 +53,9 @@ static const keyname_t   keynames[] = {
        {"ENTER", K_ENTER},
        {"ESCAPE", K_ESCAPE},
        {"SPACE", K_SPACE},
+
+       // spacer so it lines up with keys.h
+
        {"BACKSPACE", K_BACKSPACE},
        {"UPARROW", K_UPARROW},
        {"DOWNARROW", K_DOWNARROW},
@@ -85,53 +88,32 @@ static const keyname_t   keynames[] = {
 
        {"PAUSE", K_PAUSE},
 
-       {"MWHEELUP", K_MWHEELUP},
-       {"MWHEELDOWN", K_MWHEELDOWN},
-
-       {"MOUSE1", K_MOUSE1},
-       {"MOUSE2", K_MOUSE2},
-       {"MOUSE3", K_MOUSE3},
-       {"MOUSE4", K_MOUSE4},
-       {"MOUSE5", K_MOUSE5},
-       {"MOUSE6", K_MOUSE6},
-       {"MOUSE7", K_MOUSE7},
-       {"MOUSE8", K_MOUSE8},
-       {"MOUSE9", K_MOUSE9},
-       {"MOUSE10", K_MOUSE10},
-       {"MOUSE11", K_MOUSE11},
-       {"MOUSE12", K_MOUSE12},
-       {"MOUSE13", K_MOUSE13},
-       {"MOUSE14", K_MOUSE14},
-       {"MOUSE15", K_MOUSE15},
-       {"MOUSE16", K_MOUSE16},
-
        {"NUMLOCK", K_NUMLOCK},
        {"CAPSLOCK", K_CAPSLOCK},
        {"SCROLLOCK", K_SCROLLOCK},
 
-       {"KP_HOME",                     K_KP_HOME },
-       {"KP_UPARROW",          K_KP_UPARROW },
-       {"KP_PGUP",                     K_KP_PGUP },
-       {"KP_LEFTARROW",        K_KP_LEFTARROW },
-       {"KP_RIGHTARROW",       K_KP_RIGHTARROW },
-       {"KP_END",                      K_KP_END },
-       {"KP_DOWNARROW",        K_KP_DOWNARROW },
-       {"KP_PGDN",                     K_KP_PGDN },
        {"KP_INS",                      K_KP_INS },
-       {"KP_DEL",                      K_KP_DEL },
-       {"KP_SLASH",            K_KP_SLASH },
-
        {"KP_0", K_KP_0},
+       {"KP_END",                      K_KP_END },
        {"KP_1", K_KP_1},
+       {"KP_DOWNARROW",        K_KP_DOWNARROW },
        {"KP_2", K_KP_2},
+       {"KP_PGDN",                     K_KP_PGDN },
        {"KP_3", K_KP_3},
+       {"KP_LEFTARROW",        K_KP_LEFTARROW },
        {"KP_4", K_KP_4},
        {"KP_5", K_KP_5},
+       {"KP_RIGHTARROW",       K_KP_RIGHTARROW },
        {"KP_6", K_KP_6},
+       {"KP_HOME",                     K_KP_HOME },
        {"KP_7", K_KP_7},
+       {"KP_UPARROW",          K_KP_UPARROW },
        {"KP_8", K_KP_8},
+       {"KP_PGUP",                     K_KP_PGUP },
        {"KP_9", K_KP_9},
+       {"KP_DEL",                      K_KP_DEL },
        {"KP_PERIOD", K_KP_PERIOD},
+       {"KP_SLASH",            K_KP_SLASH },
        {"KP_DIVIDE", K_KP_DIVIDE},
        {"KP_MULTIPLY", K_KP_MULTIPLY},
        {"KP_MINUS", K_KP_MINUS},
@@ -139,6 +121,31 @@ static const keyname_t   keynames[] = {
        {"KP_ENTER", K_KP_ENTER},
        {"KP_EQUALS", K_KP_EQUALS},
 
+
+
+       {"MOUSE1", K_MOUSE1},
+
+       {"MOUSE2", K_MOUSE2},
+       {"MOUSE3", K_MOUSE3},
+       {"MWHEELUP", K_MWHEELUP},
+       {"MWHEELDOWN", K_MWHEELDOWN},
+       {"MOUSE4", K_MOUSE4},
+       {"MOUSE5", K_MOUSE5},
+       {"MOUSE6", K_MOUSE6},
+       {"MOUSE7", K_MOUSE7},
+       {"MOUSE8", K_MOUSE8},
+       {"MOUSE9", K_MOUSE9},
+       {"MOUSE10", K_MOUSE10},
+       {"MOUSE11", K_MOUSE11},
+       {"MOUSE12", K_MOUSE12},
+       {"MOUSE13", K_MOUSE13},
+       {"MOUSE14", K_MOUSE14},
+       {"MOUSE15", K_MOUSE15},
+       {"MOUSE16", K_MOUSE16},
+
+
+
+
        {"JOY1",  K_JOY1},
        {"JOY2",  K_JOY2},
        {"JOY3",  K_JOY3},
@@ -156,6 +163,11 @@ static const keyname_t   keynames[] = {
        {"JOY15", K_JOY15},
        {"JOY16", K_JOY16},
 
+
+
+
+
+
        {"AUX1", K_AUX1},
        {"AUX2", K_AUX2},
        {"AUX3", K_AUX3},
@@ -189,11 +201,12 @@ static const keyname_t   keynames[] = {
        {"AUX31", K_AUX31},
        {"AUX32", K_AUX32},
 
-       {"SEMICOLON", ';'},                     // because a raw semicolon seperates commands
+       {"SEMICOLON", ';'},                     // because a raw semicolon separates commands
        {"TILDE", '~'},
        {"BACKQUOTE", '`'},
        {"QUOTE", '"'},
        {"APOSTROPHE", '\''},
+       {"BACKSLASH", '\\'},            // because a raw backslash is used for special characters
 
        {NULL, 0}
 };
@@ -448,23 +461,19 @@ Key_Console (int key, char ascii)
        if (key == K_PGUP || key == K_KP_PGUP || key == K_MWHEELUP)
        {
                con_backscroll += ((int) vid_conheight.integer >> 5);
-               if (con_backscroll > con_totallines - (vid_conheight.integer>>3) - 1)
-                       con_backscroll = con_totallines - (vid_conheight.integer>>3) - 1;
                return;
        }
 
        if (key == K_PGDN || key == K_KP_PGDN || key == K_MWHEELDOWN)
        {
                con_backscroll -= ((int) vid_conheight.integer >> 5);
-               if (con_backscroll < 0)
-                       con_backscroll = 0;
                return;
        }
 
        if (key == K_HOME || key == K_KP_HOME)
        {
                if (keydown[K_CTRL])
-                       con_backscroll = con_totallines - (vid_conheight.integer>>3) - 1;
+                       con_backscroll = INT_MAX;
                else
                        key_linepos = 1;
                return;
@@ -505,11 +514,13 @@ qboolean  chat_team;
 char           chat_buffer[MAX_INPUTLINE];
 unsigned int   chat_bufferlen = 0;
 
+extern int Nicks_CompleteChatLine(char *buffer, size_t size, unsigned int pos);
+
 static void
 Key_Message (int key, char ascii)
 {
 
-       if (key == K_ENTER)
+       if (key == K_ENTER || ascii == 10 || ascii == 13)
        {
                Cmd_ForwardStringToServer(va("%s %s", chat_team ? "say_team" : "say ", chat_buffer));
 
@@ -534,6 +545,11 @@ Key_Message (int key, char ascii)
                return;
        }
 
+       if(key == K_TAB) {
+               chat_bufferlen = Nicks_CompleteChatLine(chat_buffer, sizeof(chat_buffer), chat_bufferlen);
+               return;
+       }
+
        if (chat_bufferlen == sizeof (chat_buffer) - 1)
                return;                                                 // all full
 
@@ -584,18 +600,24 @@ Key_KeynumToString (int keynum)
        const keyname_t  *kn;
        static char tinystr[2];
 
-       if (keynum == -1)
+       // -1 is an invalid code
+       if (keynum < 0)
                return "<KEY NOT FOUND>";
-       if (keynum > 32 && keynum < 127) {      // printable ascii
-               tinystr[0] = keynum;
-               tinystr[1] = 0;
-               return tinystr;
-       }
 
+       // search overrides first, because some characters are special
        for (kn = keynames; kn->name; kn++)
                if (keynum == kn->keynum)
                        return kn->name;
 
+       // if it is printable, output it as a single character
+       if (keynum > 32 && keynum < 256)
+       {
+               tinystr[0] = keynum;
+               tinystr[1] = 0;
+               return tinystr;
+       }
+
+       // if it is not overridden and not printable, we don't know what to do with it
        return "<UNKNOWN KEYNUM>";
 }
 
@@ -614,6 +636,8 @@ Key_SetBinding (int keynum, int bindmap, const char *binding)
                Z_Free (keybindings[bindmap][keynum]);
                keybindings[bindmap][keynum] = NULL;
        }
+       if(!binding[0]) // make "" binds be removed --blub
+               return;
 // allocate memory for new binding
        l = strlen (binding);
        newbinding = (char *)Z_Malloc (l + 1);
@@ -794,16 +818,24 @@ void
 Key_WriteBindings (qfile_t *f)
 {
        int         i, j;
+       char bindbuf[MAX_INPUTLINE];
+       const char *p;
 
-       for (i = 0; i < (int)(sizeof(keybindings[0])/sizeof(keybindings[0][0])); i++)
-               if (keybindings[0][i])
-                       FS_Printf(f, "bind \"%s\" \"%s\"\n",
-                                       Key_KeynumToString (i), keybindings[0][i]);
-       for (j = 1; j < 8; j++)
+       for (j = 0; j < MAX_BINDMAPS; j++)
+       {
                for (i = 0; i < (int)(sizeof(keybindings[0])/sizeof(keybindings[0][0])); i++)
-                       if (keybindings[j][i])
-                               FS_Printf(f, "in_bind %d \"%s\" \"%s\"\n",
-                                               j, Key_KeynumToString (i), keybindings[j][i]);
+               {
+                       p = keybindings[j][i];
+                       if (p)
+                       {
+                               Cmd_QuoteString(bindbuf, sizeof(bindbuf), p, "\"\\");
+                               if (j == 0)
+                                       FS_Printf(f, "bind %s \"%s\"\n", Key_KeynumToString (i), bindbuf);
+                               else
+                                       FS_Printf(f, "in_bind %d %s \"%s\"\n", j, Key_KeynumToString (i), bindbuf);
+                       }
+               }
+       }
 }
 
 
@@ -843,7 +875,7 @@ const char *Key_GetBind (int key)
        return bind;
 }
 
-qboolean CL_VM_InputEvent (qboolean pressed, int key);
+qboolean CL_VM_InputEvent (qboolean down, int key, int ascii);
 
 /*
 ===================
@@ -865,9 +897,13 @@ Key_Event (int key, char ascii, qboolean down)
        if (!bind)
                bind = keybindings[key_bmap2][key];
 
+       if (developer.integer >= 1000)
+               Con_Printf("Key_Event(%i, '%c', %s) keydown %i bind \"%s\"\n", key, ascii, down ? "down" : "up", keydown[key], bind ? bind : "");
+
+#if 0
        if(key_dest == key_game)
        {
-               q = CL_VM_InputEvent(!down, key);
+               q = CL_VM_InputEvent(down, key);
                if(q)
                {
                        if (down)
@@ -877,6 +913,7 @@ Key_Event (int key, char ascii, qboolean down)
                        return;
                }
        }
+#endif
 
        if (down)
        {
@@ -888,13 +925,6 @@ Key_Event (int key, char ascii, qboolean down)
        {
                // clear repeat count now that the key is released
                keydown[key] = 0;
-               // 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 (bind && bind[0] == '+')
-                       Cbuf_AddText(va("-%s %i\n", bind + 1, key));
        }
 
        // key_consoleactive is a flag not a key_dest because the console is a
@@ -931,10 +961,13 @@ Key_Event (int key, char ascii, qboolean down)
                                        Key_Message (key, ascii);
                                break;
                        case key_menu:
+                       case key_menu_grabbed:
                                MR_KeyEvent (key, ascii, down);
                                break;
                        case key_game:
-                               if (down)
+                               // csqc has priority over toggle menu if it wants to (e.g. handling escape for UI stuff in-game.. :sick:)
+                               q = CL_VM_InputEvent(down, key, ascii);
+                               if (!q && down)
                                        MR_ToggleMenu_f ();
                                break;
                        default:
@@ -943,7 +976,8 @@ Key_Event (int key, char ascii, qboolean down)
                return;
        }
 
-       // send function keydowns to interpreter no matter what mode is
+       // send function keydowns to interpreter no matter what mode is (unless the menu has specifically grabbed the keyboard, for rebinding keys)
+       if (key_dest != key_menu_grabbed)
        if (key >= K_F1 && key <= K_F12 && down)
        {
                // ignore key repeats on F1-F12 binds
@@ -976,6 +1010,17 @@ Key_Event (int key, char ascii, qboolean down)
                return;
        }
 
+
+       // FIXME: actually the up-bind should only be called if the button was actually pressed while key_dest == key_game [12/17/2007 Black]
+       //                       especially CL_VM_InputEvent should be able to prevent it from being called (to intercept the binds)
+       // 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 && bind && bind[0] == '+')
+               Cbuf_AddText(va("-%s %i\n", bind + 1, key));
+
        // ignore binds while a video is played, let the video system handle the key event
        if (cl_videoplaying)
        {
@@ -991,11 +1036,13 @@ Key_Event (int key, char ascii, qboolean down)
                                Key_Message (key, ascii);
                        break;
                case key_menu:
+               case key_menu_grabbed:
                        MR_KeyEvent (key, ascii, down);
                        break;
                case key_game:
-                       // ignore key repeats on binds
-                       if (bind && keydown[key] == 1 && down)
+                       q = CL_VM_InputEvent(down, key, ascii);
+                       // ignore key repeats on binds and only send the bind if the event hasnt been already processed by csqc
+                       if (!q && bind && keydown[key] == 1 && down)
                        {
                                // button commands add keynum as a parm
                                if (bind[0] == '+')