]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - keys.c
recalc the 2D view if changing view parameters with R_SetView
[xonotic/darkplaces.git] / keys.c
diff --git a/keys.c b/keys.c
index f01ee9f0d01d49c590bef6a8364542d7a115e529..18765a167e2c0c6c050dd6e915502c858ac1d654 100644 (file)
--- a/keys.c
+++ b/keys.c
@@ -22,6 +22,7 @@
 
 #include "quakedef.h"
 #include "cl_video.h"
+#include "utf8lib.h"
 
 cvar_t con_closeontoggleconsole = {CVAR_SAVE, "con_closeontoggleconsole","1", "allows toggleconsole binds to close the console as well"};
 
@@ -475,7 +476,7 @@ Interactive line editing and console scrollback
 ====================
 */
 static void
-Key_Console (int key, int ascii)
+Key_Console (int key, int unicode)
 {
        // LordHavoc: copied most of this from Q2 to improve keyboard handling
        switch (key)
@@ -552,6 +553,7 @@ Key_Console (int key, int ascii)
                        if (i > 0)
                        {
                                // terencehill: insert the clipboard text between the characters of the line
+                               /*
                                char *temp = (char *) Z_Malloc(MAX_INPUTLINE);
                                cbd[i]=0;
                                temp[0]=0;
@@ -563,6 +565,12 @@ Key_Console (int key, int ascii)
                                        strlcat(key_line, temp, sizeof(key_line));
                                Z_Free(temp);
                                key_linepos += i;
+                               */
+                               // blub: I'm changing this to use memmove() like the rest of the code does.
+                               cbd[i] = 0;
+                               memmove(key_line + key_linepos + i, key_line + key_linepos, sizeof(key_line) - key_linepos - i);
+                               memcpy(key_line + key_linepos, cbd, i);
+                               key_linepos += i;
                        }
                        Z_Free(cbd);
                }
@@ -704,7 +712,8 @@ Key_Console (int key, int ascii)
                else if(keydown[K_SHIFT]) // move cursor to the previous character ignoring colors
                {
                        int             pos;
-                       pos = key_linepos-1;
+                       size_t          inchar = 0;
+                       pos = u8_prevbyte(key_line, key_linepos);
                        while (pos)
                                if(pos-1 > 0 && key_line[pos-1] == STRING_COLOR_TAG && isdigit(key_line[pos]))
                                        pos-=2;
@@ -718,10 +727,14 @@ Key_Console (int key, int ascii)
                                        pos--;
                                        break;
                                }
-                       key_linepos = pos + 1;
+                       // we need to move to the beginning of the character when in a wide character:
+                       u8_charidx(key_line, pos + 1, &inchar);
+                       key_linepos = pos + 1 - inchar;
                }
                else
-                       key_linepos--;
+               {
+                       key_linepos = u8_prevbyte(key_line, key_linepos);
+               }
                return;
        }
 
@@ -730,8 +743,9 @@ Key_Console (int key, int ascii)
        {
                if (key_linepos > 1)
                {
-                       strlcpy(key_line + key_linepos - 1, key_line + key_linepos, sizeof(key_line) + 1 - key_linepos);
-                       key_linepos--;
+                       int newpos = u8_prevbyte(key_line, key_linepos);
+                       strlcpy(key_line + newpos, key_line + key_linepos, sizeof(key_line) + 1 - key_linepos);
+                       key_linepos = newpos;
                }
                return;
        }
@@ -742,7 +756,7 @@ Key_Console (int key, int ascii)
                size_t linelen;
                linelen = strlen(key_line);
                if (key_linepos < (int)linelen)
-                       memmove(key_line + key_linepos, key_line + key_linepos + 1, linelen - key_linepos);
+                       memmove(key_line + key_linepos, key_line + key_linepos + u8_bytelen(key_line + key_linepos, 1), linelen - key_linepos);
                return;
        }
 
@@ -796,7 +810,7 @@ Key_Console (int key, int ascii)
                        // skip the char
                        if (key_line[pos] == STRING_COLOR_TAG && key_line[pos+1] == STRING_COLOR_TAG) // consider ^^ as a character
                                pos++;
-                       pos++;
+                       pos += u8_bytelen(key_line + pos, 1);
                        
                        // now go beyond all next consecutive color tags, if any
                        if(pos < len)
@@ -812,7 +826,7 @@ Key_Console (int key, int ascii)
                        key_linepos = pos;
                }
                else
-                       key_linepos++;
+                       key_linepos += u8_bytelen(key_line + key_linepos, 1);
                return;
        }
 
@@ -907,7 +921,7 @@ Key_Console (int key, int ascii)
        if (key == K_HOME || key == K_KP_HOME)
        {
                if (keydown[K_CTRL])
-                       con_backscroll = INT_MAX;
+                       con_backscroll = CON_TEXTSIZE;
                else
                        key_linepos = 1;
                return;
@@ -923,22 +937,31 @@ Key_Console (int key, int ascii)
        }
 
        // non printable
-       if (ascii < 32)
+       if (unicode < 32)
                return;
 
        if (key_linepos < MAX_INPUTLINE-1)
        {
+               char buf[16];
                int len;
+               int blen;
+               blen = u8_fromchar(unicode, buf, sizeof(buf));
+               if (!blen)
+                       return;
                len = (int)strlen(&key_line[key_linepos]);
                // check insert mode, or always insert if at end of line
                if (key_insert || len == 0)
                {
                        // can't use strcpy to move string to right
                        len++;
-                       memmove(&key_line[key_linepos + 1], &key_line[key_linepos], len);
+                       //memmove(&key_line[key_linepos + u8_bytelen(key_line + key_linepos, 1)], &key_line[key_linepos], len);
+                       memmove(&key_line[key_linepos + blen], &key_line[key_linepos], len);
                }
-               key_line[key_linepos] = ascii;
-               key_linepos++;
+               memcpy(key_line + key_linepos, buf, blen);
+               key_linepos += blen;
+               //key_linepos += u8_fromchar(unicode, key_line + key_linepos, sizeof(key_line) - key_linepos - 1);
+               //key_line[key_linepos] = ascii;
+               //key_linepos++;
        }
 }
 
@@ -953,7 +976,6 @@ extern int Nicks_CompleteChatLine(char *buffer, size_t size, unsigned int pos);
 static void
 Key_Message (int key, int ascii)
 {
-
        if (key == K_ENTER || ascii == 10 || ascii == 13)
        {
                if(chat_mode < 0)
@@ -978,7 +1000,7 @@ Key_Message (int key, int ascii)
 
        if (key == K_BACKSPACE) {
                if (chat_bufferlen) {
-                       chat_bufferlen--;
+                       chat_bufferlen = u8_prevbyte(chat_buffer, chat_bufferlen);
                        chat_buffer[chat_bufferlen] = 0;
                }
                return;
@@ -995,8 +1017,10 @@ Key_Message (int key, int ascii)
        if (!ascii)
                return;                                                 // non printable
 
-       chat_buffer[chat_bufferlen++] = ascii;
-       chat_buffer[chat_bufferlen] = 0;
+       chat_bufferlen += u8_fromchar(ascii, chat_buffer+chat_bufferlen, sizeof(chat_buffer) - chat_bufferlen - 1);
+
+       //chat_buffer[chat_bufferlen++] = ascii;
+       //chat_buffer[chat_bufferlen] = 0;
 }
 
 //============================================================================
@@ -1061,14 +1085,16 @@ Key_KeynumToString (int keynum)
 }
 
 
-void
+qboolean
 Key_SetBinding (int keynum, int bindmap, const char *binding)
 {
        char *newbinding;
        size_t l;
 
        if (keynum == -1 || keynum >= MAX_KEYS)
-               return;
+               return false;
+       if ((bindmap < 0) || (bindmap >= MAX_BINDMAPS))
+               return false;
 
 // free old bindings
        if (keybindings[bindmap][keynum]) {
@@ -1076,13 +1102,35 @@ Key_SetBinding (int keynum, int bindmap, const char *binding)
                keybindings[bindmap][keynum] = NULL;
        }
        if(!binding[0]) // make "" binds be removed --blub
-               return;
+               return true;
 // allocate memory for new binding
        l = strlen (binding);
        newbinding = (char *)Z_Malloc (l + 1);
        memcpy (newbinding, binding, l + 1);
        newbinding[l] = 0;
        keybindings[bindmap][keynum] = newbinding;
+       return true;
+}
+
+void Key_GetBindMap(int *fg, int *bg)
+{
+       if(fg)
+               *fg = key_bmap;
+       if(bg)
+               *bg = key_bmap2;
+}
+
+qboolean Key_SetBindMap(int fg, int bg)
+{
+       if(fg >= MAX_BINDMAPS)
+               return false;
+       if(bg >= MAX_BINDMAPS)
+               return false;
+       if(fg >= 0)
+               key_bmap = fg;
+       if(bg >= 0)
+               key_bmap2 = bg;
+       return true;
 }
 
 static void
@@ -1097,7 +1145,7 @@ Key_In_Unbind_f (void)
        }
 
        m = strtol(Cmd_Argv (1), &errchar, 0);
-       if ((m < 0) || (m >= 8) || (errchar && *errchar)) {
+       if ((m < 0) || (m >= MAX_BINDMAPS) || (errchar && *errchar)) {
                Con_Printf("%s isn't a valid bindmap\n", Cmd_Argv(1));
                return;
        }
@@ -1108,7 +1156,8 @@ Key_In_Unbind_f (void)
                return;
        }
 
-       Key_SetBinding (b, m, "");
+       if(!Key_SetBinding (b, m, ""))
+               Con_Printf("Key_SetBinding failed for unknown reason\n");
 }
 
 static void
@@ -1126,7 +1175,7 @@ Key_In_Bind_f (void)
        }
 
        m = strtol(Cmd_Argv (1), &errchar, 0);
-       if ((m < 0) || (m >= 8) || (errchar && *errchar)) {
+       if ((m < 0) || (m >= MAX_BINDMAPS) || (errchar && *errchar)) {
                Con_Printf("%s isn't a valid bindmap\n", Cmd_Argv(1));
                return;
        }
@@ -1152,7 +1201,8 @@ Key_In_Bind_f (void)
                        strlcat (cmd, " ", sizeof (cmd));
        }
 
-       Key_SetBinding (b, m, cmd);
+       if(!Key_SetBinding (b, m, cmd))
+               Con_Printf("Key_SetBinding failed for unknown reason\n");
 }
 
 static void
@@ -1169,13 +1219,13 @@ Key_In_Bindmap_f (void)
        }
 
        m1 = strtol(Cmd_Argv (1), &errchar, 0);
-       if ((m1 < 0) || (m1 >= 8) || (errchar && *errchar)) {
+       if ((m1 < 0) || (m1 >= MAX_BINDMAPS) || (errchar && *errchar)) {
                Con_Printf("%s isn't a valid bindmap\n", Cmd_Argv(1));
                return;
        }
 
        m2 = strtol(Cmd_Argv (2), &errchar, 0);
-       if ((m2 < 0) || (m2 >= 8) || (errchar && *errchar)) {
+       if ((m2 < 0) || (m2 >= MAX_BINDMAPS) || (errchar && *errchar)) {
                Con_Printf("%s isn't a valid bindmap\n", Cmd_Argv(2));
                return;
        }
@@ -1200,7 +1250,8 @@ Key_Unbind_f (void)
                return;
        }
 
-       Key_SetBinding (b, 0, "");
+       if(!Key_SetBinding (b, 0, ""))
+               Con_Printf("Key_SetBinding failed for unknown reason\n");
 }
 
 static void
@@ -1208,7 +1259,7 @@ Key_Unbindall_f (void)
 {
        int         i, j;
 
-       for (j = 0; 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])
                                Key_SetBinding (i, j, "");
@@ -1244,7 +1295,7 @@ Key_In_BindList_f (void)
        if(Cmd_Argc() >= 2)
        {
                m = strtol(Cmd_Argv(1), &errchar, 0);
-               if ((m < 0) || (m >= 8) || (errchar && *errchar)) {
+               if ((m < 0) || (m >= MAX_BINDMAPS) || (errchar && *errchar)) {
                        Con_Printf("%s isn't a valid bindmap\n", Cmd_Argv(1));
                        return;
                }
@@ -1296,7 +1347,8 @@ Key_Bind_f (void)
                        strlcat (cmd, " ", sizeof (cmd));
        }
 
-       Key_SetBinding (b, 0, cmd);
+       if(!Key_SetBinding (b, 0, cmd))
+               Con_Printf("Key_SetBinding failed for unknown reason\n");
 }
 
 /*
@@ -1359,17 +1411,54 @@ Key_Shutdown (void)
        Key_History_Shutdown();
 }
 
-const char *Key_GetBind (int key)
+const char *Key_GetBind (int key, int bindmap)
 {
        const char *bind;
        if (key < 0 || key >= MAX_KEYS)
                return NULL;
-       bind = keybindings[key_bmap][key];
-       if (!bind)
-               bind = keybindings[key_bmap2][key];
+       if(bindmap >= MAX_BINDMAPS)
+               return NULL;
+       if(bindmap >= 0)
+       {
+               bind = keybindings[bindmap][key];
+       }
+       else
+       {
+               bind = keybindings[key_bmap][key];
+               if (!bind)
+                       bind = keybindings[key_bmap2][key];
+       }
        return bind;
 }
 
+void Key_FindKeysForCommand (const char *command, int *keys, int numkeys, int bindmap)
+{
+       int             count;
+       int             j;
+       const char      *b;
+
+       for (j = 0;j < numkeys;j++)
+               keys[j] = -1;
+
+       if(bindmap >= MAX_BINDMAPS)
+               return;
+
+       count = 0;
+
+       for (j = 0; j < MAX_KEYS; ++j)
+       {
+               b = Key_GetBind(j, bindmap);
+               if (!b)
+                       continue;
+               if (!strcmp (b, command) )
+               {
+                       keys[count++] = j;
+                       if (count == numkeys)
+                               break;
+               }
+       }
+}
+
 qboolean CL_VM_InputEvent (qboolean down, int key, int ascii);
 
 /*
@@ -1381,6 +1470,44 @@ Should NOT be called during an interrupt!
 static char tbl_keyascii[MAX_KEYS];
 static keydest_t tbl_keydest[MAX_KEYS];
 
+typedef struct eventqueueitem_s
+{
+       int key;
+       int ascii;
+       qboolean down;
+}
+eventqueueitem_t;
+static int events_blocked = 0;
+static eventqueueitem_t eventqueue[32];
+static unsigned eventqueue_idx = 0;
+
+static void Key_EventQueue_Add(int key, int ascii, qboolean down)
+{
+       if(eventqueue_idx < sizeof(eventqueue) / sizeof(*eventqueue))
+       {
+               eventqueue[eventqueue_idx].key = key;
+               eventqueue[eventqueue_idx].ascii = ascii;
+               eventqueue[eventqueue_idx].down = down;
+               ++eventqueue_idx;
+       }
+}
+
+void Key_EventQueue_Block(void)
+{
+       // block key events until call to Unblock
+       events_blocked = true;
+}
+
+void Key_EventQueue_Unblock(void)
+{
+       // unblocks key events again
+       unsigned i;
+       events_blocked = false;
+       for(i = 0; i < eventqueue_idx; ++i)
+               Key_Event(eventqueue[i].key, eventqueue[i].ascii, eventqueue[i].down);
+       eventqueue_idx = 0;
+}
+
 void
 Key_Event (int key, int ascii, qboolean down)
 {
@@ -1391,13 +1518,19 @@ Key_Event (int key, int ascii, qboolean down)
        if (key < 0 || key >= MAX_KEYS)
                return;
 
+       if(events_blocked)
+       {
+               Key_EventQueue_Add(key, ascii, down);
+               return;
+       }
+
        // get key binding
        bind = keybindings[key_bmap][key];
        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 (developer_insane.integer)
+               Con_DPrintf("Key_Event(%i, '%c', %s) keydown %i bind \"%s\"\n", key, ascii ? ascii : '?', down ? "down" : "up", keydown[key], bind ? bind : "");
 
        if(key_consoleactive)
                keydest = key_console;
@@ -1468,7 +1601,7 @@ Key_Event (int key, int ascii, qboolean down)
                                        if(key_consoleactive & KEY_CONSOLEACTIVE_FORCED)
                                        {
                                                key_consoleactive &= ~KEY_CONSOLEACTIVE_USER;
-                                               MR_ToggleMenu_f ();
+                                               MR_ToggleMenu(1);
                                        }
                                        else
                                                Con_ToggleConsole_f();
@@ -1489,7 +1622,7 @@ Key_Event (int key, int ascii, qboolean 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 ();
+                                       MR_ToggleMenu(1);
                                break;
 
                        default:
@@ -1499,8 +1632,9 @@ Key_Event (int key, int ascii, qboolean down)
        }
 
        // send function keydowns to interpreter no matter what mode is (unless the menu has specifically grabbed the keyboard, for rebinding keys)
+       // VorteX: Omnicide does bind F* keys
        if (keydest != key_menu_grabbed)
-       if (key >= K_F1 && key <= K_F12)
+       if (key >= K_F1 && key <= K_F12 && gamemode != GAME_BLOODOMNICIDE)
        {
                if (bind)
                {