]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - console.c
implemented threaded audio mixing for SDL client (required some
[xonotic/darkplaces.git] / console.c
index d7084e394a450d73dd146dd2dd3fd751bd4ef4d8..d101cea996c57bad254423317dbceca40138c86c 100644 (file)
--- a/console.c
+++ b/console.c
@@ -553,7 +553,7 @@ void Con_Init (void)
        Cmd_AddCommand ("condump", Con_ConDump_f, "output console history to a file (see also log_file)");
 
        con_initialized = true;
-       Con_Print("Console initialized.\n");
+       Con_DPrint("Console initialized.\n");
 }
 
 
@@ -1509,7 +1509,7 @@ void Con_DrawConsole (int lines)
        con_vislines = lines;
 
 // draw the background
-       DrawQ_Pic(0, lines - vid_conheight.integer, scr_conbrightness.value >= 0.01f ? Draw_CachePic("gfx/conback", true) : NULL, vid_conwidth.integer, vid_conheight.integer, scr_conbrightness.value, scr_conbrightness.value, scr_conbrightness.value, cls.signon == SIGNONS ? scr_conalpha.value : 1.0, 0); // always full alpha when not in game
+       DrawQ_Pic(0, lines - vid_conheight.integer, scr_conbrightness.value >= 0.01f ? Draw_CachePic ("gfx/conback") : NULL, vid_conwidth.integer, vid_conheight.integer, scr_conbrightness.value, scr_conbrightness.value, scr_conbrightness.value, cls.signon == SIGNONS ? scr_conalpha.value : 1.0, 0); // always full alpha when not in game
        DrawQ_String_Font(vid_conwidth.integer - DrawQ_TextWidth_Font(engineversion, 0, false, FONT_CONSOLE) * con_textsize.value, lines - con_textsize.value, engineversion, 0, con_textsize.value, con_textsize.value, 1, 0, 0, 1, 0, NULL, true, FONT_CONSOLE);
 
 // draw the text
@@ -1771,7 +1771,6 @@ void SanitizeString(char *in, char *out)
        }
        *out = 0;
 }
-int Sbar_GetPlayer (int index); // <- safety?
 
 // Now it becomes TRICKY :D --blub
 static char Nicks_list[MAX_SCOREBOARD][MAX_SCOREBOARDNAME];    // contains the nicks with colors and all that
@@ -1816,15 +1815,15 @@ int Nicks_strncasecmp(char *a, char *b, unsigned int a_len)
                        return Nicks_strncasecmp_nospaces(a, b, a_len);
                return strncasecmp(a, b, a_len);
        }
-       
+
        space_char = (con_nickcompletion_flags.integer & NICKS_NO_SPACES) ? 'a' : ' ';
-       
+
        // ignore non alphanumerics of B
        // if A contains a non-alphanumeric, B must contain it as well though!
        while(a_len)
        {
                qboolean alnum_a, alnum_b;
-               
+
                if(tolower(*a) == tolower(*b))
                {
                        if(*a == 0) // end of both strings, they're equal
@@ -1861,33 +1860,30 @@ int Nicks_CompleteCountPossible(char *line, int pos, char *s, qboolean isCon)
        int match;
        int spos;
        int count = 0;
-       
+
        if(!con_nickcompletion.integer)
                return 0;
 
        // changed that to 1
        if(!line[0])// || !line[1]) // we want at least... 2 written characters
                return 0;
-       
+
        for(i = 0; i < cl.maxclients; ++i)
        {
-               /*p = Sbar_GetPlayer(i);
-               if(p < 0)
-               break;*/
                p = i;
                if(!cl.scores[p].name[0])
                        continue;
 
                SanitizeString(cl.scores[p].name, name);
                //Con_Printf("Sanitized: %s^7 -> %s", cl.scores[p].name, name);
-               
+
                if(!name[0])
                        continue;
-               
+
                length = strlen(name);
                match = -1;
                spos = pos - 1; // no need for a minimum of characters :)
-               
+
                while(spos >= 0 && (spos - pos) < length) // search-string-length < name length
                {
                        if(spos > 0 && line[spos-1] != ' ' && line[spos-1] != ';' && line[spos-1] != '\"' && line[spos-1] != '\'')
@@ -1916,7 +1912,7 @@ int Nicks_CompleteCountPossible(char *line, int pos, char *s, qboolean isCon)
                {
                        Nicks_matchpos = match;
                }
-               
+
                Nicks_offset[count] = s - (&line[match]);
                //Con_Printf("offset for %s: %i\n", name, Nicks_offset[count]);
 
@@ -1943,7 +1939,7 @@ void Nicks_CutMatchesNormal(int count)
                l = strlen(Nicks_sanlist[i]) - 1;
                if(l < c)
                        c = l;
-               
+
                for(l = 0; l <= c; ++l)
                        if(tolower(Nicks_sanlist[0][l]) != tolower(Nicks_sanlist[i][l]))
                        {
@@ -1978,7 +1974,7 @@ void Nicks_CutMatchesAlphaNumeric(int count)
        char tempstr[sizeof(Nicks_sanlist[0])];
        char *a, *b;
        char space_char = (con_nickcompletion_flags.integer & NICKS_NO_SPACES) ? 'a' : ' '; // yes this is correct, we want NO spaces when no spaces
-       
+
        c = strlen(Nicks_sanlist[0]);
        for(i = 0, l = 0; i < (int)c; ++i)
        {
@@ -1990,7 +1986,7 @@ void Nicks_CutMatchesAlphaNumeric(int count)
                }
        }
        tempstr[l] = 0;
-       
+
        for(i = 1; i < count; ++i)
        {
                a = tempstr;
@@ -2036,7 +2032,7 @@ void Nicks_CutMatchesNoSpaces(int count)
        unsigned int c, l;
        char tempstr[sizeof(Nicks_sanlist[0])];
        char *a, *b;
-       
+
        c = strlen(Nicks_sanlist[0]);
        for(i = 0, l = 0; i < (int)c; ++i)
        {
@@ -2046,7 +2042,7 @@ void Nicks_CutMatchesNoSpaces(int count)
                }
        }
        tempstr[l] = 0;
-       
+
        for(i = 1; i < count; ++i)
        {
                a = tempstr;
@@ -2106,7 +2102,7 @@ const char **Nicks_CompleteBuildList(int count)
                buf[bpos] = Nicks_sanlist[bpos] + Nicks_offset[bpos];
 
        Nicks_CutMatches(count);
-       
+
        buf[bpos] = NULL;
        return buf;
 }
@@ -2116,14 +2112,14 @@ int Nicks_AddLastColor(char *buffer, int pos)
        qboolean quote_added = false;
        int match;
        char color = '7';
-       
+
        if(con_nickcompletion_flags.integer & NICKS_ADD_QUOTE && buffer[Nicks_matchpos-1] == '\"')
        {
                // we'll have to add a quote :)
                buffer[pos++] = '\"';
                quote_added = true;
        }
-       
+
        if((!quote_added && con_nickcompletion_flags.integer & NICKS_ADD_COLOR) || con_nickcompletion_flags.integer & NICKS_FORCE_COLOR)
        {
                // add color when no quote was added, or when flags &4?
@@ -2154,7 +2150,7 @@ int Nicks_CompleteChatLine(char *buffer, size_t size, unsigned int pos)
        {
                size_t len;
                char *msg;
-               
+
                msg = Nicks_list[0];
                len = min(size - Nicks_matchpos - 3, strlen(msg));
                memcpy(&buffer[Nicks_matchpos], msg, len);
@@ -2202,8 +2198,8 @@ void Con_CompleteCommandLine (void)
        char command[512];
        int c, v, a, i, cmd_len, pos, k;
        int n; // nicks --blub
-       const char *space;
-       
+       const char *space, *patterns;
+
        //find what we want to complete
        pos = key_linepos;
        while(--pos)
@@ -2222,7 +2218,12 @@ void Con_CompleteCommandLine (void)
        if(space && pos == (space - key_lines[edit_line]) + 1)
        {
                strlcpy(command, key_lines[edit_line] + 1, min(sizeof(command), (unsigned int)(space - key_lines[edit_line])));
-               if(!strcmp(command, "map") || !strcmp(command, "changelevel"))
+
+               patterns = Cvar_VariableString(va("con_completion_%s", command)); // TODO maybe use a better place for this?
+               if(patterns && !*patterns)
+                       patterns = NULL; // get rid of the empty string
+
+               if(!strcmp(command, "map") || !strcmp(command, "changelevel") || (patterns && !strcmp(patterns, "map")))
                {
                        //maps search
                        char t[MAX_QPATH];
@@ -2244,96 +2245,147 @@ void Con_CompleteCommandLine (void)
                }
                else
                {
-                       const char *patterns = Cvar_VariableString(va("con_completion_%s", command)); // TODO maybe use a better place for this?
-                       char t[MAX_QPATH];
-                       stringlist_t resultbuf;
-
-                       // Usage:
-                       //   // store completion patterns (space separated) for command foo in con_completion_foo
-                       //   set con_completion_foo "foodata/*.foodefault *.foo"
-                       //   foo <TAB>
-                       //
-                       // Note: patterns with slash are always treated as absolute
-                       // patterns; patterns without slash search in the innermost
-                       // directory the user specified. There is no way to "complete into"
-                       // a directory as of now, as directories seem to be unknown to the
-                       // FS subsystem.
-                       //
-                       // Examples:
-                       //   set con_completion_playermodel "models/player/*.zym models/player/*.md3 models/player/*.psk models/player/*.dpm"
-                       //   set con_completion_playdemo "*.dem"
-                       //   set con_completion_play "*.wav *.ogg"
-                       //
-                       // TODO somehow add support for directories; these shall complete
-                       // to their name + an appended slash.
-
-                       stringlistinit(&resultbuf);
-                       while(COM_ParseToken_Simple(&patterns, false, false))
+                       if(patterns)
                        {
-                               fssearch_t *search;
-                               if(strchr(com_token, '/'))
+                               char t[MAX_QPATH];
+                               stringlist_t resultbuf, dirbuf;
+
+                               // Usage:
+                               //   // store completion patterns (space separated) for command foo in con_completion_foo
+                               //   set con_completion_foo "foodata/*.foodefault *.foo"
+                               //   foo <TAB>
+                               //
+                               // Note: patterns with slash are always treated as absolute
+                               // patterns; patterns without slash search in the innermost
+                               // directory the user specified. There is no way to "complete into"
+                               // a directory as of now, as directories seem to be unknown to the
+                               // FS subsystem.
+                               //
+                               // Examples:
+                               //   set con_completion_playermodel "models/player/*.zym models/player/*.md3 models/player/*.psk models/player/*.dpm"
+                               //   set con_completion_playdemo "*.dem"
+                               //   set con_completion_play "*.wav *.ogg"
+                               //
+                               // TODO somehow add support for directories; these shall complete
+                               // to their name + an appended slash.
+
+                               stringlistinit(&resultbuf);
+                               stringlistinit(&dirbuf);
+                               while(COM_ParseToken_Simple(&patterns, false, false))
                                {
-                                       search = FS_Search(com_token, true, true);
+                                       fssearch_t *search;
+                                       if(strchr(com_token, '/'))
+                                       {
+                                               search = FS_Search(com_token, true, true);
+                                       }
+                                       else
+                                       {
+                                               const char *slash = strrchr(s, '/');
+                                               if(slash)
+                                               {
+                                                       strlcpy(t, s, min(sizeof(t), (unsigned int)(slash - s + 2))); // + 2, because I want to include the slash
+                                                       strlcat(t, com_token, sizeof(t));
+                                                       search = FS_Search(t, true, true);
+                                               }
+                                               else
+                                                       search = FS_Search(com_token, true, true);
+                                       }
+                                       if(search)
+                                       {
+                                               for(i = 0; i < search->numfilenames; ++i)
+                                                       if(!strncmp(search->filenames[i], s, strlen(s)))
+                                                               if(FS_FileType(search->filenames[i]) == FS_FILETYPE_FILE)
+                                                                       stringlistappend(&resultbuf, search->filenames[i]);
+                                               FS_FreeSearch(search);
+                                       }
                                }
-                               else
+
+                               // In any case, add directory names
                                {
+                                       fssearch_t *search;
                                        const char *slash = strrchr(s, '/');
                                        if(slash)
                                        {
                                                strlcpy(t, s, min(sizeof(t), (unsigned int)(slash - s + 2))); // + 2, because I want to include the slash
-                                               strlcat(t, com_token, sizeof(t));
+                                               strlcat(t, "*", sizeof(t));
                                                search = FS_Search(t, true, true);
                                        }
                                        else
-                                               search = FS_Search(com_token, true, true);
-                               }
-                               if(search)
-                               {
-                                       for(i = 0; i < search->numfilenames; ++i)
-                                               if(!strncmp(search->filenames[i], s, strlen(s)))
-                                                       stringlistappend(&resultbuf, search->filenames[i]);
-                                       FS_FreeSearch(search);
-                               }
-                       }
-                       
-                       if(resultbuf.numstrings > 0)
-                       {
-                               const char *p, *q;
-                               if(resultbuf.numstrings == 1)
-                               {
-                                       dpsnprintf(t, sizeof(t), "%s ", resultbuf.strings[0]);
+                                               search = FS_Search("*", true, true);
+                                       if(search)
+                                       {
+                                               for(i = 0; i < search->numfilenames; ++i)
+                                                       if(!strncmp(search->filenames[i], s, strlen(s)))
+                                                               if(FS_FileType(search->filenames[i]) == FS_FILETYPE_DIRECTORY)
+                                                                       stringlistappend(&dirbuf, search->filenames[i]);
+                                               FS_FreeSearch(search);
+                                       }
                                }
-                               else
+
+                               if(resultbuf.numstrings > 0 || dirbuf.numstrings > 0)
                                {
-                                       stringlistsort(&resultbuf);
-                                       Con_Printf("\n%i possible filenames\n", resultbuf.numstrings);
-                                       for(i = 0; i < resultbuf.numstrings; ++i)
+                                       const char *p, *q;
+                                       unsigned int matchchars;
+                                       if(resultbuf.numstrings == 0 && dirbuf.numstrings == 1)
                                        {
-                                               Con_Printf("%s\n", resultbuf.strings[i]);
+                                               dpsnprintf(t, sizeof(t), "%s/", dirbuf.strings[0]);
+                                       }
+                                       else
+                                       if(resultbuf.numstrings == 1 && dirbuf.numstrings == 0)
+                                       {
+                                               dpsnprintf(t, sizeof(t), "%s ", resultbuf.strings[0]);
+                                       }
+                                       else
+                                       {
+                                               stringlistsort(&resultbuf); // dirbuf is already sorted
+                                               Con_Printf("\n%i possible filenames\n", resultbuf.numstrings + dirbuf.numstrings);
+                                               for(i = 0; i < dirbuf.numstrings; ++i)
+                                               {
+                                                       Con_Printf("%s/\n", dirbuf.strings[i]);
+                                               }
+                                               for(i = 0; i < resultbuf.numstrings; ++i)
+                                               {
+                                                       Con_Printf("%s\n", resultbuf.strings[i]);
+                                               }
+                                               matchchars = sizeof(t) - 1;
+                                               if(resultbuf.numstrings > 0)
+                                               {
+                                                       p = resultbuf.strings[0];
+                                                       q = resultbuf.strings[resultbuf.numstrings - 1];
+                                                       for(; *p && *p == *q; ++p, ++q);
+                                                       matchchars = (unsigned int)(p - resultbuf.strings[0]);
+                                               }
+                                               if(dirbuf.numstrings > 0)
+                                               {
+                                                       p = dirbuf.strings[0];
+                                                       q = dirbuf.strings[dirbuf.numstrings - 1];
+                                                       for(; *p && *p == *q; ++p, ++q);
+                                                       matchchars = min(matchchars, (unsigned int)(p - dirbuf.strings[0]));
+                                               }
+                                               // now p points to the first non-equal character, or to the end
+                                               // of resultbuf.strings[0]. We want to append the characters
+                                               // from resultbuf.strings[0] to (not including) p as these are
+                                               // the unique prefix
+                                               strlcpy(t, (resultbuf.numstrings > 0 ? resultbuf : dirbuf).strings[0], min(matchchars + 1, sizeof(t)));
                                        }
-                                       p = resultbuf.strings[0];
-                                       q = resultbuf.strings[resultbuf.numstrings - 1];
-                                       for(; *p && *p == *q; ++p, ++q);
-                                       // now p points to the first non-equal character, or to the end
-                                       // of resultbuf.strings[0]. We want to append the characters
-                                       // from resultbuf.strings[0] to (not including) p as these are
-                                       // the unique prefix
-                                       strlcpy(t, resultbuf.strings[0], min((unsigned int)(p - resultbuf.strings[0] + 1), sizeof(t)));
-                               }
 
-                               // first move the cursor
-                               key_linepos += (int)strlen(t) - (int)strlen(s);
+                                       // first move the cursor
+                                       key_linepos += (int)strlen(t) - (int)strlen(s);
 
-                               // and now do the actual work
-                               *s = 0;
-                               strlcat(key_lines[edit_line], t, MAX_INPUTLINE);
-                               strlcat(key_lines[edit_line], s2, MAX_INPUTLINE); //add back chars after cursor
+                                       // and now do the actual work
+                                       *s = 0;
+                                       strlcat(key_lines[edit_line], t, MAX_INPUTLINE);
+                                       strlcat(key_lines[edit_line], s2, MAX_INPUTLINE); //add back chars after cursor
 
-                               // and fix the cursor
-                               if(key_linepos > (int) strlen(key_lines[edit_line]))
-                                       key_linepos = (int) strlen(key_lines[edit_line]);
+                                       // and fix the cursor
+                                       if(key_linepos > (int) strlen(key_lines[edit_line]))
+                                               key_linepos = (int) strlen(key_lines[edit_line]);
+                               }
+                               stringlistfreecontents(&resultbuf);
+                               stringlistfreecontents(&dirbuf);
+
+                               return; // bail out, when we complete for a command that wants a file name
                        }
-                       stringlistfreecontents(&resultbuf);
                }
        }
 
@@ -2364,7 +2416,7 @@ void Con_CompleteCommandLine (void)
        }
 
        if (!(c + v + a + n))   // No possible matches
-       {               
+       {
                if(s2[0])
                        strlcpy(&key_lines[edit_line][key_linepos], s2, sizeof(key_lines[edit_line]) - key_linepos);
                return;
@@ -2378,7 +2430,7 @@ void Con_CompleteCommandLine (void)
                cmd = *(list[2] = Cmd_CompleteAliasBuildList(s));
        if (n)
                cmd = *(list[3] = Nicks_CompleteBuildList(n));
-       
+
        for (cmd_len = (int)strlen(s);;cmd_len++)
        {
                const char **l;