diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index abd70a3f9..c9e3b596b 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -849,7 +849,12 @@ void CL_DownloadFinished(qdownload_t *dl) cl.model_precache[i]->loadstate = MLS_NOTLOADED; cl.model_precache[i] = Mod_ForName(cl.model_name[i], MLV_WARN); if (i == 1) + { cl.worldmodel = cl.model_precache[i]; + //just in case. + if (cl.model_precache[1] && cl.model_precache[1]->loadstate == MLS_LOADED) + FS_LoadMapPackFile(cl.model_precache[1]->name, cl.model_precache[1]->archive); + } break; } } @@ -1405,6 +1410,8 @@ static int CL_LoadModels(int stage, qboolean dontactuallyload) if (cl.worldmodel && cl.worldmodel->loadstate == MLS_LOADING) return -1; + FS_LoadMapPackFile(cl.worldmodel->name, cl.worldmodel->archive); + #ifdef Q2CLIENT if (cls.protocol == CP_QUAKE2 && cl.worldmodel && cl.worldmodel->checksum != cl.q2mapchecksum) Host_EndGame("Local map version differs from server: %i != '%i'\n", cl.worldmodel->checksum, cl.q2mapchecksum); @@ -4385,6 +4392,13 @@ static void CL_ParseModellist (qboolean lots) return; } + SCR_SetLoadingFile("loading data"); + + //we need to try to load it now if we can, so any embedded archive will be loaded *before* we start looking for other content... + cl.model_precache[1] = Mod_ForName (cl.model_name[1], MLV_WARNSYNC); + if (cl.model_precache[1] && cl.model_precache[1]->loadstate == MLS_LOADED) + FS_LoadMapPackFile(cl.model_precache[1]->name, cl.model_precache[1]->archive); + Sound_CheckDownloads(); Model_CheckDownloads(); @@ -4392,7 +4406,6 @@ static void CL_ParseModellist (qboolean lots) //set the flag to load models and send prespawn cl.sendprespawn = true; - SCR_SetLoadingFile("loading data"); } #ifdef Q2CLIENT diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 4401741df..c4fd07a5d 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -2707,6 +2707,7 @@ static void QCBUILTIN PF_R_RenderScene(pubprogfuncs_t *prinst, struct globalvars { csqc_worldchanged = false; cl.worldmodel = r_worldentity.model = csqc_world.worldmodel; + FS_LoadMapPackFile(cl.worldmodel->name, cl.worldmodel->archive); Surf_NewMap(); CL_UpdateWindowTitle(); diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 851c36f47..56decc6dd 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -403,6 +403,7 @@ cvar_t gl_blendsprites = CVARD ("gl_blendsprites", "0", "Specifies how spr cvar_t r_deluxemapping_cvar = CVARAFD ("r_deluxemapping", "1", "r_glsl_deluxemapping", CVAR_ARCHIVE|CVAR_RENDERERLATCH, "Enables bumpmapping based upon precomputed light directions.\n0=off\n1=use if available\n2=auto-generate (if possible)"); cvar_t mod_loadsurfenvmaps = CVARD ("r_loadsurfenvmaps", "1", "Load local reflection environment-maps, where available. These are normally defined via env_cubemap entities dotted around the place."); +cvar_t mod_loadmappackages = CVARD ("mod_loadmappackages", "1", "Load additional content embedded within bsp files."); qboolean r_deluxemapping; cvar_t r_shaderblobs = CVARD ("r_shaderblobs", "0", "If enabled, can massively accelerate vid restarts / loading (especially with the d3d renderer). Can cause issues when upgrading engine versions, so this is disabled by default."); cvar_t gl_compress = CVARFD ("gl_compress", "0", CVAR_ARCHIVE, "Enable automatic texture compression even for textures which are not pre-compressed."); diff --git a/engine/common/fs.c b/engine/common/fs.c index 65f95391d..35adfff5f 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -2839,6 +2839,8 @@ void COM_FlushTempoaryPacks(void) //flush all temporary packages { searchpath_t *sp, **link; + COM_AssertMainThread("COM_FlushTempoaryPacks"); + COM_WorkerLock(); //make sure no workers are poking files... Sys_LockMutex(fs_thread_mutex); @@ -2851,6 +2853,7 @@ void COM_FlushTempoaryPacks(void) //flush all temporary packages FS_FlushFSHashFull(); *link = sp->next; + com_purepaths = NULL; sp->handle->ClosePath(sp->handle); Z_Free (sp); @@ -2858,16 +2861,32 @@ void COM_FlushTempoaryPacks(void) //flush all temporary packages else link = &sp->next; } - com_purepaths = NULL; Sys_UnlockMutex(fs_thread_mutex); COM_WorkerUnlock(); //workers can continue now } +static searchpath_t *FS_MapPackIsActive(searchpathfuncs_t *archive) +{ + searchpath_t *sp; + Sys_LockMutex(fs_thread_mutex); + for (sp = com_searchpaths; sp; sp = sp->next) + { + if (sp->handle == archive) + break; + } + Sys_UnlockMutex(fs_thread_mutex); + return sp; +} + static searchpath_t *FS_AddPathHandle(searchpath_t **oldpaths, const char *purepath, const char *probablepath, searchpathfuncs_t *handle, const char *prefix, unsigned int flags, unsigned int loadstuff); qboolean FS_LoadMapPackFile (const char *filename, searchpathfuncs_t *archive) { + if (!archive) + return false; if (!archive->AddReference) return false; //nope... + if (FS_MapPackIsActive(archive)) + return false; //don't do it twice. archive->AddReference(archive); if (FS_AddPathHandle(NULL, filename, filename, archive, "", SPF_TEMPORARY, 0)) return true; @@ -2877,6 +2896,8 @@ void FS_CloseMapPackFile (searchpathfuncs_t *archive) { searchpath_t *sp, **link; + COM_AssertMainThread("FS_CloseMapPackFile"); + COM_WorkerLock(); //make sure no workers are poking files... Sys_LockMutex(fs_thread_mutex); @@ -2889,6 +2910,7 @@ void FS_CloseMapPackFile (searchpathfuncs_t *archive) FS_FlushFSHashFull(); *link = sp->next; + com_purepaths = NULL; //FIXME... sp->handle->ClosePath(sp->handle); Z_Free (sp); @@ -2897,7 +2919,6 @@ void FS_CloseMapPackFile (searchpathfuncs_t *archive) else link = &sp->next; } - com_purepaths = NULL; Sys_UnlockMutex(fs_thread_mutex); COM_WorkerUnlock(); //workers can continue now diff --git a/engine/common/q1bsp.c b/engine/common/q1bsp.c index 5759870e9..5affd501c 100644 --- a/engine/common/q1bsp.c +++ b/engine/common/q1bsp.c @@ -7,6 +7,7 @@ extern cvar_t r_decal_noperpendicular; extern cvar_t mod_loadsurfenvmaps; +extern cvar_t mod_loadmappackages; /* Decal functions @@ -2281,7 +2282,7 @@ bspx_header_t *BSPX_Setup(model_t *mod, char *filebase, size_t filelen, lump_t * } } - if (offs < filelen && !mod->archive) + if (offs < filelen && !mod->archive && mod_loadmappackages.ival) { //we have some sort of trailing junk... is it a zip?... vfsfile_t *f = VFSPIPE_Open(1,true); if (f) diff --git a/engine/qclib/qcd_main.c b/engine/qclib/qcd_main.c index 29d254bc4..ea8ea0ff3 100644 --- a/engine/qclib/qcd_main.c +++ b/engine/qclib/qcd_main.c @@ -216,7 +216,7 @@ int QC_EnumerateFilesFromBlob(const void *blob, size_t blobsize, void (*cb)(cons cd = blob; cd += QC_ReadRawInt(eocd+16); cdlen = QC_ReadRawInt(eocd+12); - cdentries = QC_ReadRawInt(eocd+10); + cdentries = QC_ReadRawShort(eocd+10); if (cd+cdlen>=(const unsigned char*)blob+blobsize) return ret; diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index a108cdfcc..9473d51e9 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -1040,6 +1040,10 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents, sv.state = ss_dead; + //make sure our map's package is loaded. + if (sv.world.worldmodel) + FS_LoadMapPackFile(sv.world.worldmodel->name, sv.world.worldmodel->archive); + #ifndef SERVERONLY current_loading_size+=10; // SCR_BeginLoadingPlaque();