]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
progs: Implement new extension DP_QC_FS_SEARCH_PACKFILE
authorcloudwalk <cloudwalk@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 15 Jul 2020 14:59:11 +0000 (14:59 +0000)
committercloudwalk <cloudwalk@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 15 Jul 2020 14:59:11 +0000 (14:59 +0000)
Adds an optional parameter to the search_begin builtin function that
allows specifying a package file to look in, skipping any results that
aren't inside the package. Useful for mods aiming to provide
compatibility with Quake 3's .arena files, as they don't match the .bsp
filename.

Patch from Mario: https://gitlab.com/xonotic/darkplaces/-/merge_requests/100

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12826 d7cf8633-e32d-0410-b094-e92efae38249

cmd.c
console.c
dpdefs/csprogsdefs.qc
dpdefs/dpextensions.qc
dpdefs/menudefs.qc
fs.c
fs.h
image.c
model_shared.c
prvm_cmds.c
svvm_cmds.c

diff --git a/cmd.c b/cmd.c
index ff7c138f2c9f1e7d836aa592ab0e5bba148e1dcf..b7baf77eb78c42112ffe1e100e4277db76ccfce1 100644 (file)
--- a/cmd.c
+++ b/cmd.c
@@ -737,7 +737,7 @@ static void Cmd_Exec_f (cmd_state_t *cmd)
                return;
        }
 
-       s = FS_Search(Cmd_Argv(cmd, 1), true, true);
+       s = FS_Search(Cmd_Argv(cmd, 1), true, true, NULL);
        if(!s || !s->numfilenames)
        {
                Con_Printf("couldn't exec %s\n",Cmd_Argv(cmd, 1));
index 6bf28ec7d87d26e5d197606f1769ba064a170703..1a4b19148005e0ee16131a601241969d07db6f79 100644 (file)
--- a/console.c
+++ b/console.c
@@ -2125,7 +2125,7 @@ qboolean GetMapList (const char *s, char *completedname, int completednamebuffer
        unsigned char buf[1024];
 
        dpsnprintf(message, sizeof(message), "maps/%s*.bsp", s);
-       t = FS_Search(message, 1, true);
+       t = FS_Search(message, 1, true, NULL);
        if(!t)
                return false;
        if (t->numfilenames > 1)
@@ -2843,7 +2843,7 @@ int Con_CompleteCommandLine(cmd_state_t *cmd, qboolean is_console)
                                        fssearch_t *search;
                                        if(strchr(com_token, '/'))
                                        {
-                                               search = FS_Search(com_token, true, true);
+                                               search = FS_Search(com_token, true, true, NULL);
                                        }
                                        else
                                        {
@@ -2852,10 +2852,10 @@ int Con_CompleteCommandLine(cmd_state_t *cmd, qboolean is_console)
                                                {
                                                        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);
+                                                       search = FS_Search(t, true, true, NULL);
                                                }
                                                else
-                                                       search = FS_Search(com_token, true, true);
+                                                       search = FS_Search(com_token, true, true, NULL);
                                        }
                                        if(search)
                                        {
@@ -2875,10 +2875,10 @@ int Con_CompleteCommandLine(cmd_state_t *cmd, qboolean is_console)
                                        {
                                                strlcpy(t, s, min(sizeof(t), (unsigned int)(slash - s + 2))); // + 2, because I want to include the slash
                                                strlcat(t, "*", sizeof(t));
-                                               search = FS_Search(t, true, true);
+                                               search = FS_Search(t, true, true, NULL);
                                        }
                                        else
-                                               search = FS_Search("*", true, true);
+                                               search = FS_Search("*", true, true, NULL);
                                        if(search)
                                        {
                                                for(i = 0; i < search->numfilenames; ++i)
index 00245b98ba9839b2356ba066061ad7601efcf413..ce31fad481e36f99187d7b7edb2dc28fb440bc7f 100644 (file)
@@ -1435,6 +1435,15 @@ void(entity e, string s) parseentitydata = #608;
 //function definitions:
 void coverage() = #642;  // Reports a coverage event. The engine counts for each of the calls to this builtin whether it has been called.
 
+//DP_QC_FS_SEARCH_PACKFILE
+//idea: Mario
+//darkplaces implementation: Mario
+//builtin definitions:
+float(string pattern, float caseinsensitive, float quiet, string packfile) search_packfile_begin = #444;
+//description:
+//extension to search_begin (DP_QC_FS_SEARCH), performs a filename search with the specified pattern (for example "maps/*.bsp") and stores the results in a search slot (minimum of 128 supported by any engine with this extension), the other functions take this returned search slot number, be sure to search_free when done (they are also freed on progs reload).
+//only searches for files within the specified packfile, which is expected to match the results of whichpack().
+
 // assorted builtins
 const float            STAT_MOVEVARS_TICRATE           = 240;
 const float            STAT_MOVEVARS_TIMESCALE         = 241;
index 05812846742975bf25bdcc7c6d22e15c8e9fc109..43dd56cb6a929736f055c4ed000f850d72846f6e 100644 (file)
@@ -2623,3 +2623,12 @@ float MOVETYPE_USER_LAST = 191;
 string __fullspawndata;
 //description:
 // http://icculus.org/finger/marco?date=2019-01-25&time=05-38-02
+
+//DP_QC_FS_SEARCH_PACKFILE
+//idea: Mario
+//darkplaces implementation: Mario
+//builtin definitions:
+float(string pattern, float caseinsensitive, float quiet, string packfile) search_packfile_begin = #444;
+//description:
+//extension to search_begin (DP_QC_FS_SEARCH), performs a filename search with the specified pattern (for example "maps/*.bsp") and stores the results in a search slot (minimum of 128 supported by any engine with this extension), the other functions take this returned search slot number, be sure to search_free when done (they are also freed on progs reload).
+//only searches for files within the specified packfile, which is expected to match the results of whichpack().
index 1890a4b027c88c8dd5a5184080611794c46dfef0..36cedec4f2fdfd1b96e935f1f5f91b84b230fd53 100644 (file)
@@ -538,6 +538,15 @@ float FIELD_FUNCTION = 6;
 //function definitions:
 void coverage() = #642;  // Reports a coverage event. The engine counts for each of the calls to this builtin whether it has been called.
 
+//DP_QC_FS_SEARCH_PACKFILE
+//idea: Mario
+//darkplaces implementation: Mario
+//builtin definitions:
+float(string pattern, float caseinsensitive, float quiet, string packfile) search_packfile_begin = #444;
+//description:
+//extension to search_begin (DP_QC_FS_SEARCH), performs a filename search with the specified pattern (for example "maps/*.bsp") and stores the results in a search slot (minimum of 128 supported by any engine with this extension), the other functions take this returned search slot number, be sure to search_free when done (they are also freed on progs reload).
+//only searches for files within the specified packfile, which is expected to match the results of whichpack().
+
 // assorted undocumented extensions
 string(string, float) netaddress_resolve = #625;
 string(string search, string replace, string subject) strreplace = #484;
diff --git a/fs.c b/fs.c
index 4b98e32ea4b96d4e4158d333b5270a949380e667..5a06538a108d3eca4df1d0f79c13405370dc93fd 100644 (file)
--- a/fs.c
+++ b/fs.c
@@ -3570,7 +3570,7 @@ FS_Search
 Allocate and fill a search structure with information on matching filenames.
 ===========
 */
-fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet)
+fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet, const char *packfile)
 {
        fssearch_t *search;
        searchpath_t *searchpath;
@@ -3612,6 +3612,11 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet)
                {
                        // look through all the pak file elements
                        pak = searchpath->pack;
+                       if(packfile)
+                       {
+                               if(strcmp(packfile, pak->shortname))
+                                       continue;
+                       }
                        for (i = 0;i < pak->numfiles;i++)
                        {
                                char temp[MAX_OSPATH];
@@ -3648,6 +3653,8 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet)
                }
                else
                {
+                       if(packfile)
+                               continue;
                        stringlist_t matchedSet, foundSet;
                        const char *start = pattern;
 
@@ -3786,7 +3793,7 @@ static int FS_ListDirectory(const char *pattern, int oneperline)
        const char *name;
        char linebuf[MAX_INPUTLINE];
        fssearch_t *search;
-       search = FS_Search(pattern, true, true);
+       search = FS_Search(pattern, true, true, NULL);
        if (!search)
                return 0;
        numfiles = search->numfilenames;
diff --git a/fs.h b/fs.h
index d824680b901133f11245f9f08c1ac0185e66a15e..e466d9908850c7ff5b0eee5941f13c1a066cdd8f 100644 (file)
--- a/fs.h
+++ b/fs.h
@@ -107,7 +107,7 @@ typedef struct fssearch_s
 }
 fssearch_t;
 
-fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet);
+fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet, const char *packfile);
 void FS_FreeSearch(fssearch_t *search);
 
 unsigned char *FS_LoadFile (const char *path, mempool_t *pool, qboolean quiet, fs_offset_t *filesizepointer);
diff --git a/image.c b/image.c
index a072df248dd460dd7195013a8061a791331c77ae..a4e97d14e0d4749917a0ae5bb01db17514cf8cf2 100644 (file)
--- a/image.c
+++ b/image.c
@@ -1421,7 +1421,7 @@ void Image_FixTransparentPixels_f(cmd_state_t *cmd)
                return;
        }
        filename_pattern = Cmd_Argv(cmd, 1);
-       search = FS_Search(filename_pattern, true, true);
+       search = FS_Search(filename_pattern, true, true, NULL);
        if(!search)
                return;
        for(i = 0; i < search->numfilenames; ++i)
index c4d89707556af87a3413c82318e1d0e7d757f498..65a4e155495087c24f649f3071ed9e03c95683bc 100644 (file)
@@ -1517,7 +1517,7 @@ void Mod_LoadQ3Shaders(void)
        }
 
        // parse shaders
-       search = FS_Search("scripts/*.shader", true, false);
+       search = FS_Search("scripts/*.shader", true, false, NULL);
        if (!search)
                return;
        for (fileindex = 0;fileindex < search->numfilenames;fileindex++)
index 6833080ec04a9f33c1508e4bae5be7a16328d079..5216d3f785f1767f8028108e8e9348928c8acbc2 100644 (file)
@@ -3088,16 +3088,16 @@ static void VM_Search_Reset(prvm_prog_t *prog)
 =========
 VM_search_begin
 
-float search_begin(string pattern, float caseinsensitive, float quiet)
+float search_begin(string pattern, float caseinsensitive, float quiet[, string packfile])
 =========
 */
 void VM_search_begin(prvm_prog_t *prog)
 {
        int handle;
-       const char *pattern;
+       const char *packfile = NULL, *pattern;
        int caseinsens, quiet;
 
-       VM_SAFEPARMCOUNT(3, VM_search_begin);
+       VM_SAFEPARMCOUNTRANGE(3, 4, VM_search_begin);
 
        pattern = PRVM_G_STRING(OFS_PARM0);
 
@@ -3106,6 +3106,10 @@ void VM_search_begin(prvm_prog_t *prog)
        caseinsens = (int)PRVM_G_FLOAT(OFS_PARM1);
        quiet = (int)PRVM_G_FLOAT(OFS_PARM2);
 
+       // optional packfile parameter (DP_QC_FS_SEARCH_PACKFILE)
+       if(prog->argc >= 4)
+               packfile = PRVM_G_STRING(OFS_PARM3);
+
        for(handle = 0; handle < PRVM_MAX_OPENSEARCHES; handle++)
                if(!prog->opensearches[handle])
                        break;
@@ -3117,7 +3121,7 @@ void VM_search_begin(prvm_prog_t *prog)
                return;
        }
 
-       if(!(prog->opensearches[handle] = FS_Search(pattern,caseinsens, quiet)))
+       if(!(prog->opensearches[handle] = FS_Search(pattern,caseinsens, quiet, packfile)))
                PRVM_G_FLOAT(OFS_RETURN) = -1;
        else
        {
index 54776d5653b78ed7aed89053b3e953aeb1d987af..871e738633f388f1c6bcd5c373a27ddd2f373e9a 100644 (file)
@@ -228,6 +228,7 @@ const char *vm_sv_extensions[] = {
 "TW_SV_STEPCONTROL",
 "ZQ_PAUSE",
 "DP_RM_CLIPGROUP",
+"DP_QC_FS_SEARCH_PACKFILE",
 NULL
 //"EXT_CSQC" // not ready yet
 };