From 73bbf90a419c7b19c0b6f1cb11f05813a1658199 Mon Sep 17 00:00:00 2001 From: cloudwalk Date: Wed, 15 Jul 2020 14:59:11 +0000 Subject: [PATCH] progs: Implement new extension DP_QC_FS_SEARCH_PACKFILE 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 | 2 +- console.c | 12 ++++++------ dpdefs/csprogsdefs.qc | 9 +++++++++ dpdefs/dpextensions.qc | 9 +++++++++ dpdefs/menudefs.qc | 9 +++++++++ fs.c | 11 +++++++++-- fs.h | 2 +- image.c | 2 +- model_shared.c | 2 +- prvm_cmds.c | 12 ++++++++---- svvm_cmds.c | 1 + 11 files changed, 55 insertions(+), 16 deletions(-) diff --git a/cmd.c b/cmd.c index ff7c138f..b7baf77e 100644 --- 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)); diff --git a/console.c b/console.c index 6bf28ec7..1a4b1914 100644 --- 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) diff --git a/dpdefs/csprogsdefs.qc b/dpdefs/csprogsdefs.qc index 00245b98..ce31fad4 100644 --- a/dpdefs/csprogsdefs.qc +++ b/dpdefs/csprogsdefs.qc @@ -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; diff --git a/dpdefs/dpextensions.qc b/dpdefs/dpextensions.qc index 05812846..43dd56cb 100644 --- a/dpdefs/dpextensions.qc +++ b/dpdefs/dpextensions.qc @@ -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(). diff --git a/dpdefs/menudefs.qc b/dpdefs/menudefs.qc index 1890a4b0..36cedec4 100644 --- a/dpdefs/menudefs.qc +++ b/dpdefs/menudefs.qc @@ -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 4b98e32e..5a06538a 100644 --- 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 d824680b..e466d990 100644 --- 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 a072df24..a4e97d14 100644 --- 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) diff --git a/model_shared.c b/model_shared.c index c4d89707..65a4e155 100644 --- a/model_shared.c +++ b/model_shared.c @@ -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++) diff --git a/prvm_cmds.c b/prvm_cmds.c index 6833080e..5216d3f7 100644 --- a/prvm_cmds.c +++ b/prvm_cmds.c @@ -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 { diff --git a/svvm_cmds.c b/svvm_cmds.c index 54776d56..871e7386 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -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 }; -- 2.39.2