diff --git a/engine/client/m_options.c b/engine/client/m_options.c index 72d7643a2..41837c941 100644 --- a/engine/client/m_options.c +++ b/engine/client/m_options.c @@ -218,7 +218,6 @@ void M_Menu_Audio_Speakers_f (void) info->card = sndcardinfo; - menu->selecteditem = NULL; } @@ -362,29 +361,28 @@ typedef struct { } presetinfo_t; presetinfo_t preset[] = { - {"r_presetname", {"286", "fast", "default", "nice", "realtime"}}, - {"gl_texturemode", {"nn", "ln", "ln", "ll", "ll"}}, - {"r_particlesdesc", {"none", "highfps", "spikeset", "spikeset", "spikeset"}}, - {"r_stains", {"0", "0", "0.75", "0.75", "0.75"}}, - {"r_drawflat", {"1", "0", "0", "0", "0"}}, - {"r_nolerp", {"1", "1", "0", "0", "0"}}, - {"r_nolightdir", {"1", "0", "0", "0", "0"}}, - {"r_dynamic", {"0", "0", "1", "1", "1"}}, - {"r_bloom", {"0", "0", "0", "0", "1"}}, - {"gl_flashblend", {"0", "1", "0", "1", "2"}}, - {"gl_bump", {"0", "0", "0", "1", "1"}}, - {"gl_specular", {"0", "0", "0", "1", "1"}}, - {"r_loadlit", {"0", "1", "1", "2", "2"}}, - {"r_fastsky", {"1", "1", "0", "0", "0"}}, - {"r_waterlayers", {"0", "2", "3", "4", "4"}}, - {"r_shadows", {"0", "0", "0", "1", "1"}}, - {"r_shadow_realtime_world",{"0", "0", "0", "0", "1"}}, - {"gl_detail", {"0", "0", "0", "1", "1"}}, - {"gl_load24bit", {"0", "0", "1", "1", "1"}}, - {"gl_loadmd2", {"0", "0", "1", "1", "1"}}, - {"gl_loadmd3", {"0", "0", "0", "1", "1"}}, - {"r_waterwarp", {"0", "-1", "1", "1", "1"}}, - {"r_lightstylesmooth", {"0", "0", "0", "1", "1"}}, + {"r_presetname", {"286", "fast", "default", "nice", "realtime"}}, + {"gl_texturemode", {"nn", "ln", "ln", "ll", "ll"}}, + {"r_particlesdesc", {"none", "highfps", "spikeset tsshaft", "spikeset tsshaft", "spikeset tsshaft"}}, + {"r_stains", {"0", "0", "0.75", "0.75", "0.75"}}, + {"r_drawflat", {"1", "0", "0", "0", "0"}}, + {"r_nolerp", {"1", "1", "0", "0", "0"}}, + {"r_nolightdir", {"1", "0", "0", "0", "0"}}, + {"r_dynamic", {"0", "0", "1", "1", "1"}}, + {"r_bloom", {"0", "0", "0", "0", "1"}}, + {"gl_flashblend", {"0", "1", "0", "1", "2"}}, + {"gl_bump", {"0", "0", "0", "1", "1"}}, + {"gl_specular", {"0", "0", "0", "1", "1"}}, + {"r_loadlit", {"0", "1", "1", "2", "2"}}, + {"r_fastsky", {"1", "1", "0", "0", "0"}}, + {"r_waterlayers", {"0", "2", "3", "4", "4"}}, + {"r_shadows", {"0", "0", "0", "1", "1"}}, + {"r_shadow_realtime_world",{"0", "0", "0", "0", "1"}}, + {"gl_detail", {"0", "0", "0", "1", "1"}}, + {"gl_load24bit", {"0", "0", "1", "1", "1"}}, + {"r_replacemodels", {"", "", "md3 md2", "md3 md2", "md3 md2"}}, + {"r_waterwarp", {"0", "-1", "1", "1", "1"}}, + {"r_lightstylesmooth", {"0", "0", "0", "1", "1"}}, {NULL} }; static void ApplyPreset (int presetnum) diff --git a/engine/client/r_part.c b/engine/client/r_part.c index 23f4935a3..73e1af5f7 100644 --- a/engine/client/r_part.c +++ b/engine/client/r_part.c @@ -129,7 +129,7 @@ void R_ParticlesDesc_Callback(struct cvar_s *var, char *oldvalue); void R_Rockettrail_Callback(struct cvar_s *var, char *oldvalue); void R_Grenadetrail_Callback(struct cvar_s *var, char *oldvalue); -cvar_t r_particlesdesc = SCVARFC("r_particlesdesc", "spikeset;tsshaft", CVAR_SEMICHEAT, R_ParticlesDesc_Callback); +cvar_t r_particlesdesc = SCVARFC("r_particlesdesc", "spikeset tsshaft", CVAR_SEMICHEAT, R_ParticlesDesc_Callback); cvar_t r_part_rain_quantity = SCVAR("r_part_rain_quantity", "1"); @@ -728,6 +728,12 @@ void P_ParticleEffect_f(void) else ptype->spawnmode = SM_BOX; + if (Cmd_Argc()>2) + { + if (Cmd_Argc()>3) + ptype->spawnparam2 = atof(Cmd_Argv(3)); + ptype->spawnparam1 = atof(Cmd_Argv(2)); + } } else if (!strcmp(var, "type")) { @@ -1538,9 +1544,11 @@ void R_ParticlesDesc_Callback(struct cvar_s *var, char *oldvalue) { extern model_t mod_known[]; extern int mod_numknown; + qboolean first; model_t *mod; int i; + char *c; if (cls.state == ca_disconnected) return; // don't bother parsing while disconnected @@ -1566,28 +1574,11 @@ void R_ParticlesDesc_Callback(struct cvar_s *var, char *oldvalue) f_modified_particles = false; + first = true; + for (c = COM_ParseStringSet(var->string); com_token[0]; c = COM_ParseStringSet(c)) { - char name[32]; - int len; - qboolean first = true; - - char *oldsemi; - char *semi; - oldsemi = r_particlesdesc.string; - semi = strchr(oldsemi, ';'); - while (semi) - { - len = (int)(semi - oldsemi) + 1; - if (len > sizeof(name)) - len = sizeof(name); - Q_strncpyz(name, oldsemi, len); - P_LoadParticleSet(name, first); - first = false; - oldsemi = semi + 1; - semi = strchr(oldsemi, ';'); - } - Q_strncpyz(name, oldsemi, sizeof(name)); - P_LoadParticleSet(name, first); + P_LoadParticleSet(com_token, first); + first = false; } } diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 8b8cc54d1..ec52e9493 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -133,6 +133,9 @@ cvar_t r_wateralpha = SCVAR ("r_wateralpha", "1"); cvar_t r_waterwarp = SCVARF ("r_waterwarp", "1", CVAR_ARCHIVE); +cvar_t r_replacemodels = SCVARF ("r_replacemodels", "md3 md2", + CVAR_ARCHIVE); + //otherwise it would defeat the point. cvar_t scr_allowsnap = SCVARF ("scr_allowsnap", "1", CVAR_NOTFROMSERVER); @@ -276,16 +279,6 @@ cvar_t gl_lightmap_shift = SCVARF ("gl_lightmap_shift", "0", cvar_t gl_load24bit = SCVARF ("gl_load24bit", "1", CVAR_ARCHIVE); -#ifdef MD2MODELS -cvar_t gl_loadmd2 = SCVARF ("gl_loadmd2","1", - CVAR_ARCHIVE | CVAR_RENDERERLATCH); -#endif - -#ifdef MD3MODELS -cvar_t gl_loadmd3 = SCVARF ("gl_loadmd3","1", - CVAR_ARCHIVE | CVAR_RENDERERLATCH); -#endif - cvar_t gl_max_size = SCVAR ("gl_max_size", "1024"); cvar_t gl_maxshadowlights = SCVARF ("gl_maxshadowlights", "2", CVAR_ARCHIVE); @@ -457,12 +450,6 @@ void GLRenderer_Init(void) Cvar_Register (&gl_overbright_all, GRAPHICALNICETIES); Cvar_Register (&gl_dither, GRAPHICALNICETIES); Cvar_Register (&r_fb_bmodels, GRAPHICALNICETIES); -#ifdef MD2MODELS - Cvar_Register (&gl_loadmd2, GRAPHICALNICETIES); -#endif -#ifdef MD3MODELS - Cvar_Register (&gl_loadmd3, GRAPHICALNICETIES); -#endif Cvar_Register (&gl_ati_truform, GRAPHICALNICETIES); Cvar_Register (&gl_ati_truform_type, GRAPHICALNICETIES); @@ -684,6 +671,8 @@ void Renderer_Init(void) Cvar_Register (&r_fb_models, GRAPHICALNICETIES); + Cvar_Register (&r_replacemodels, GRAPHICALNICETIES); + //bulletens Cvar_Register(&bul_nowater, BULLETENVARS); Cvar_Register(&bul_rippleamount, BULLETENVARS); diff --git a/engine/common/common.c b/engine/common/common.c index 471892008..46c3a0566 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -1928,6 +1928,42 @@ skipwhite: return data; } +char *COM_ParseStringSet (char *data) +{ + int c; + int len; + + len = 0; + com_token[0] = 0; + + if (!data) + return NULL; + +// skip whitespace and semicolons + while ( (c = *data) <= ' ' || c == ';' ) + { + if (c == 0) + return NULL; // end of file; + data++; + } + +// parse a regular word + do + { + if (len >= TOKENSIZE-1) + return data; + + com_token[len] = c; + data++; + len++; + c = *data; + } while (c>32 && c != ';'); + + com_token[len] = 0; + return data; +} + + char *COM_ParseOut (char *data, char *out, int outlen) { int c; diff --git a/engine/common/common.h b/engine/common/common.h index 09cdad07c..0f6c1c1db 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -235,6 +235,7 @@ extern com_tokentype_t com_tokentype; extern qboolean com_eof; char *COM_Parse (char *data); +char *COM_ParseStringSet (char *data); char *COM_ParseCString (char *data); char *COM_StringParse (char *data, qboolean expandmacros, qboolean qctokenize); char *COM_ParseToken (const char *data, const char *punctuation); diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index dc49a7fc4..bb2e1563f 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -40,18 +40,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif extern cvar_t r_shadow_bumpscale_basetexture; +extern cvar_t r_replacemodels; + extern int gl_bumpmappingpossible; qboolean isnotmap = true; //used to not warp ammo models. -#if defined(RGLQUAKE) || defined(D3DQUAKE) -#ifdef MD2MODELS -extern cvar_t gl_loadmd2; -#endif -#ifdef MD3MODELS -extern cvar_t gl_loadmd3; -#endif -#endif - #ifndef SWQUAKE model_t *loadmodel; char loadname[32]; // for hunk tags @@ -435,6 +428,10 @@ model_t *GLMod_LoadModel (model_t *mod, qboolean crash) void *d; unsigned *buf = NULL; qbyte stackbuf[1024]; // avoid dirtying the cache heap + char mdlbase[MAX_QPATH]; + qboolean lastload = false; + char *replstr; + qboolean doomsprite = false; char *ext; @@ -468,66 +465,6 @@ model_t *GLMod_LoadModel (model_t *mod, qboolean crash) // // load the file // - //look for a replacement, but not for q1 sprites - ext = COM_FileExtension(mod->name); - if (gl_load24bit.value && Q_strcasecmp(ext, "spr") && Q_strcasecmp(ext, "sp2")) - { - char mdlbase[MAX_QPATH]; - COM_StripExtension(mod->name, mdlbase, sizeof(mdlbase)); -#ifdef MD3MODELS - if (gl_loadmd3.value && !buf) - buf = (unsigned *)COM_LoadStackFile (va("%s.md3", mdlbase), stackbuf, sizeof(stackbuf)); -#endif -#ifdef MD2MODELS - if (gl_loadmd2.value && !buf) - buf = (unsigned *)COM_LoadStackFile (va("%s.md2", mdlbase), stackbuf, sizeof(stackbuf)); -#endif - } - if (!buf) - { - buf = (unsigned *)COM_LoadStackFile (mod->name, stackbuf, sizeof(stackbuf)); - if (!buf) - { - ext = COM_FileExtension(mod->name); -#ifdef DOOMWADS - if (!stricmp(ext, "dsp")) - { - mod->needload = false; - GLMod_LoadDoomSprite(mod); - P_DefaultTrail(mod); - return mod; - } -#endif - -couldntload: - - if (crash) - Host_EndGame ("Mod_NumForName: %s not found or couldn't load", mod->name); - - mod->type = mod_dummy; - mod->mins[0] = -16; - mod->mins[1] = -16; - mod->mins[2] = -16; - mod->maxs[0] = 16; - mod->maxs[1] = 16; - mod->maxs[2] = 16; - mod->needload = true; - P_DefaultTrail(mod); - return mod; - return NULL; - } - } - -// -// allocate a new model -// - COM_FileBase (mod->name, loadname, sizeof(loadname)); - Validation_IncludeFile(mod->name, (char *)buf, com_filesize); - -// -// fill it in -// - // set necessary engine flags for loading purposes if (!strcmp(mod->name, "progs/player.mdl")) mod->engineflags |= MDLF_PLAYER | MDLF_DOCRC; @@ -545,121 +482,193 @@ couldntload: else if (!strcmp(mod->name, "progs/eyes.mdl")) mod->engineflags |= MDLF_DOCRC; -// call the apropriate loader + // call the apropriate loader mod->needload = false; - - switch (LittleLong(*(unsigned *)buf)) + + // get string used for replacement tokens + ext = COM_FileExtension(mod->name); + if (!Q_strcasecmp(ext, "spr") || !Q_strcasecmp(ext, "sp2")) + replstr = NULL; // sprite + else if (!Q_strcasecmp(ext, "dsp")) // doom sprite { -//The binary 3d mesh model formats - case IDPOLYHEADER: - if (!Mod_LoadQ1Model(mod, buf)) - goto couldntload; - break; + replstr = NULL; + doomsprite = true; + } + else // assume models + replstr = r_replacemodels.string; + + // gl_load24bit 0 disables all replacements + if (gl_load24bit.value) + replstr = NULL; + + COM_StripExtension(mod->name, mdlbase, sizeof(mdlbase)); + + while (1) + { + for (replstr = COM_ParseStringSet(replstr); com_token[0] && !buf; replstr = COM_ParseStringSet(replstr)) + buf = (unsigned *)COM_LoadStackFile (va("%s.%s", mdlbase, com_token), stackbuf, sizeof(stackbuf)); + + if (!buf) + { + if (lastload) // only load unreplaced file once + break; + lastload = true; + buf = (unsigned *)COM_LoadStackFile (mod->name, stackbuf, sizeof(stackbuf)); + if (!buf) + { +#ifdef DOOMWADS + if (doomsprite) // special case needed for doom sprites + { + mod->needload = false; + GLMod_LoadDoomSprite(mod); + P_DefaultTrail(mod); + return mod; + } +#endif + break; // failed to load unreplaced file and nothing left + } + } +// +// allocate a new model +// + COM_FileBase (mod->name, loadname, sizeof(loadname)); + +// +// fill it in +// + + switch (LittleLong(*(unsigned *)buf)) + { +//The binary 3d mesh model formats + case IDPOLYHEADER: + if (!Mod_LoadQ1Model(mod, buf)) + continue; + break; + #ifdef MD2MODELS - case MD2IDALIASHEADER: - if (!Mod_LoadQ2Model(mod, buf)) - goto couldntload; - break; + case MD2IDALIASHEADER: + if (!Mod_LoadQ2Model(mod, buf)) + continue; + break; #endif #ifdef MD3MODELS - case MD3_IDENT: - if (!Mod_LoadQ3Model (mod, buf)) - goto couldntload; - break; + case MD3_IDENT: + if (!Mod_LoadQ3Model (mod, buf)) + continue; + break; #endif #ifdef HALFLIFEMODELS - case (('T'<<24)+('S'<<16)+('D'<<8)+'I'): - if (!Mod_LoadHLModel (mod, buf)) - goto couldntload; - break; + case (('T'<<24)+('S'<<16)+('D'<<8)+'I'): + if (!Mod_LoadHLModel (mod, buf)) + continue; + break; #endif //Binary skeletal model formats #ifdef ZYMOTICMODELS - case (('O'<<24)+('M'<<16)+('Y'<<8)+'Z'): - if (!Mod_LoadZymoticModel(mod, buf)) - goto couldntload; - break; - case (('K'<<24)+('R'<<16)+('A'<<8)+'D'): - if (!Mod_LoadDarkPlacesModel(mod, buf)) - goto couldntload; - break; + case (('O'<<24)+('M'<<16)+('Y'<<8)+'Z'): + if (!Mod_LoadZymoticModel(mod, buf)) + continue; + break; + case (('K'<<24)+('R'<<16)+('A'<<8)+'D'): + if (!Mod_LoadDarkPlacesModel(mod, buf)) + continue; + break; #endif //Binary Sprites #ifdef SP2MODELS - case IDSPRITE2HEADER: - if (!GLMod_LoadSprite2Model (mod, buf)) - goto couldntload; - break; + case IDSPRITE2HEADER: + if (!GLMod_LoadSprite2Model (mod, buf)) + continue; + break; #endif - case IDSPRITEHEADER: - if (!GLMod_LoadSpriteModel (mod, buf)) - goto couldntload; - break; + case IDSPRITEHEADER: + if (!GLMod_LoadSpriteModel (mod, buf)) + continue; + break; -//Binary Map formats + //Binary Map formats #ifdef Q2BSPS - case ('R'<<0)+('B'<<8)+('S'<<16)+('P'<<24): - case IDBSPHEADER: //looks like id switched to have proper ids - if (!Mod_LoadQ2BrushModel (mod, buf)) - goto couldntload; - break; + case ('R'<<0)+('B'<<8)+('S'<<16)+('P'<<24): + case IDBSPHEADER: //looks like id switched to have proper ids + if (!Mod_LoadQ2BrushModel (mod, buf)) + continue; + break; #endif #ifdef DOOMWADS - case (('D'<<24)+('A'<<16)+('W'<<8)+'I'): //the id is hacked by the FS .wad loader (main wad). - case (('D'<<24)+('A'<<16)+('W'<<8)+'P'): //the id is hacked by the FS .wad loader (patch wad). - if (!Mod_LoadDoomLevel (mod)) - goto couldntload; - break; + case (('D'<<24)+('A'<<16)+('W'<<8)+'I'): //the id is hacked by the FS .wad loader (main wad). + case (('D'<<24)+('A'<<16)+('W'<<8)+'P'): //the id is hacked by the FS .wad loader (patch wad). + if (!Mod_LoadDoomLevel (mod)) + continue; + break; #endif - case 30: //hl - case 29: //q1 - case 28: //prerel - if (!GLMod_LoadBrushModel (mod, buf)) - goto couldntload; - break; + case 30: //hl + case 29: //q1 + case 28: //prerel + if (!GLMod_LoadBrushModel (mod, buf)) + continue; + break; -//Text based misc types. - default: - //check for text based headers - COM_Parse((char*)buf); + //Text based misc types. + default: + //check for text based headers + COM_Parse((char*)buf); #ifdef MD5MODELS - if (!strcmp(com_token, "MD5Version")) //doom3 format, text based, skeletal - { - if (!Mod_LoadMD5MeshModel (mod, buf)) - goto couldntload; - break; - } - if (!strcmp(com_token, "EXTERNALANIM")) //custom format, text based, specifies skeletal models to load and which md5anim files to use. - { - if (!Mod_LoadCompositeAnim (mod, buf)) - goto couldntload; - break; - } + if (!strcmp(com_token, "MD5Version")) //doom3 format, text based, skeletal + { + if (!Mod_LoadMD5MeshModel (mod, buf)) + continue; + break; + } + if (!strcmp(com_token, "EXTERNALANIM")) //custom format, text based, specifies skeletal models to load and which md5anim files to use. + { + if (!Mod_LoadCompositeAnim (mod, buf)) + continue; + break; + } #endif #ifdef TERRAIN - if (!strcmp(com_token, "terrain")) //custom format, text based. - { - if (!GL_LoadHeightmapModel(mod, buf)) - goto couldntload; - break; - } + if (!strcmp(com_token, "terrain")) //custom format, text based. + { + if (!GL_LoadHeightmapModel(mod, buf)) + continue; + break; + } #endif - Con_Printf(S_ERROR "Unrecognised model format %i loading %s\n", LittleLong(*(unsigned *)buf), mod->name); - goto couldntload; + Con_Printf(S_WARNING "Unrecognised model format %i\n", LittleLong(*(unsigned *)buf)); + continue; + } + + P_DefaultTrail(mod); + Validation_IncludeFile(mod->name, (char *)buf, com_filesize); + + return mod; } - P_DefaultTrail(mod); +couldntload: + if (crash) + Host_EndGame ("Mod_NumForName: %s not found or couldn't load", mod->name); + Con_Printf(S_ERROR "Unable to load or replace %s\n", mod->name); + mod->type = mod_dummy; + mod->mins[0] = -16; + mod->mins[1] = -16; + mod->mins[2] = -16; + mod->maxs[0] = 16; + mod->maxs[1] = 16; + mod->maxs[2] = 16; + mod->needload = true; + mod->engineflags = 0; + P_DefaultTrail(mod); return mod; } diff --git a/engine/sw/sw_model.c b/engine/sw/sw_model.c index 0cae034fb..bd2b753b4 100644 --- a/engine/sw/sw_model.c +++ b/engine/sw/sw_model.c @@ -274,9 +274,16 @@ Loads a model into the cache */ model_t *SWMod_LoadModel (model_t *mod, qboolean crash) { + extern cvar_t r_replacemodels; + void *d; unsigned *buf = NULL; qbyte stackbuf[1024]; // avoid dirtying the cache heap + char mdlbase[MAX_QPATH]; + qboolean lastload = false; + char *replstr; +// qboolean doomsprite = false; + char *ext; if (!mod->needload) @@ -305,59 +312,6 @@ model_t *SWMod_LoadModel (model_t *mod, qboolean crash) // // because the world is so huge, load it one piece at a time // - - //look for a replacement - ext = COM_FileExtension(mod->name); -#ifndef CLIENTONLY - if (!isDedicated && (!Q_strcasecmp(ext, "mdl") || !Q_strcasecmp(ext, "bsp"))) - { - char mdlbase[MAX_QPATH]; - COM_StripExtension(mod->name, mdlbase, sizeof(mdlbase)); - - if (!buf) - buf = (unsigned *)COM_LoadStackFile (va("%s.md3", mdlbase), stackbuf, sizeof(stackbuf)); - if (!buf) - buf = (unsigned *)COM_LoadStackFile (va("%s.md2", mdlbase), stackbuf, sizeof(stackbuf)); - } -#endif - if (!buf) - { -// -// load the file -// - buf = (unsigned *)COM_LoadStackFile (mod->name, stackbuf, sizeof(stackbuf)); - if (!buf) - { - if (crash) - Host_EndGame ("Mod_NumForName: %s not found or couldn't load", mod->name); - - mod->type = mod_dummy; - mod->mins[0] = -16; - mod->mins[1] = -16; - mod->mins[2] = -16; - mod->maxs[0] = 16; - mod->maxs[1] = 16; - mod->maxs[2] = 16; - mod->needload = true; - P_DefaultTrail(mod); - return mod; - } - } - -// -// allocate a new model -// - COM_FileBase (mod->name, loadname, sizeof(loadname)); - - loadmodel = mod; -#ifndef SERVERONLY - if (cl.model_precache[1]) //not the world. - Validation_IncludeFile(mod->name, (char *)buf, com_filesize); -#endif -// -// fill it in -// - // set necessary engine flags for loading purposes if (!strcmp(mod->name, "progs/player.mdl")) { @@ -377,73 +331,119 @@ model_t *SWMod_LoadModel (model_t *mod, qboolean crash) else if (!strcmp(mod->name, "progs/eyes.mdl")) mod->engineflags |= MDLF_DOCRC; - -// call the apropriate loader + // call the apropriate loader mod->needload = false; - - switch (LittleLong(*(unsigned *)buf)) + + // get string used for replacement tokens + ext = COM_FileExtension(mod->name); + if (isDedicated) + replstr = NULL; + else if (!Q_strcasecmp(ext, "spr") || !Q_strcasecmp(ext, "sp2")) + replstr = NULL; // sprite + else if (!Q_strcasecmp(ext, "dsp")) // doom sprite + replstr = NULL; + else // assume models + replstr = r_replacemodels.string; + + COM_StripExtension(mod->name, mdlbase, sizeof(mdlbase)); + + while (1) { -#ifndef SERVERONLY - case IDPOLYHEADER: - if (!SWMod_LoadAliasModel (mod, buf)) - goto couldntload; - break; + for (replstr = COM_ParseStringSet(replstr); com_token[0] && !buf; replstr = COM_ParseStringSet(replstr)) + buf = (unsigned *)COM_LoadStackFile (va("%s.%s", mdlbase, com_token), stackbuf, sizeof(stackbuf)); - case MD2IDALIASHEADER: - if (!SWMod_LoadAlias2Model (mod, buf)) - goto couldntload; - break; - - case MD3_IDENT: - if (!SWMod_LoadAlias3Model (mod, buf)) - goto couldntload; - break; - - case IDSPRITEHEADER: - if (!SWMod_LoadSpriteModel (mod, buf)) - goto couldntload; - break; + if (!buf) + { + if (lastload) // only load unreplaced file once + break; + lastload = true; + buf = (unsigned *)COM_LoadStackFile (mod->name, stackbuf, sizeof(stackbuf)); + if (!buf) // we would attempt Doom sprites here, but SW doesn't support them + break; // failed to load unreplaced file and nothing left + } - case IDSPRITE2HEADER: - if (!SWMod_LoadSprite2Model (mod, buf)) - goto couldntload; - break; +// +// allocate a new model +// + COM_FileBase (mod->name, loadname, sizeof(loadname)); + + loadmodel = mod; +// +// fill it in +// + + switch (LittleLong(*(unsigned *)buf)) + { +#ifndef SERVERONLY + case IDPOLYHEADER: + if (!SWMod_LoadAliasModel (mod, buf)) + continue; + break; + + case MD2IDALIASHEADER: + if (!SWMod_LoadAlias2Model (mod, buf)) + continue; + break; + + case MD3_IDENT: + if (!SWMod_LoadAlias3Model (mod, buf)) + continue; + break; + + case IDSPRITEHEADER: + if (!SWMod_LoadSpriteModel (mod, buf)) + continue; + break; + + case IDSPRITE2HEADER: + if (!SWMod_LoadSprite2Model (mod, buf)) + continue; + break; #endif #ifdef Q2BSPS - case IDBSPHEADER: //looks like id switched to have proper ids - if (!Mod_LoadQ2BrushModel (mod, buf)) - goto couldntload; - break; + case IDBSPHEADER: //looks like id switched to have proper ids + if (!Mod_LoadQ2BrushModel (mod, buf)) + continue; + break; #endif - case BSPVERSIONHL: - case BSPVERSION: //hmm. - case BSPVERSIONPREREL: - if (!SWMod_LoadBrushModel (mod, buf)) - goto couldntload; - break; + case BSPVERSIONHL: + case BSPVERSION: //hmm. + case BSPVERSIONPREREL: + if (!SWMod_LoadBrushModel (mod, buf)) + continue; + break; - default: //some telejano mods can do this - Con_Printf(S_ERROR "model %s, unrecognized format %i\n", mod->name, LittleLong(*(unsigned *)buf)); -couldntload: + default: //some telejano mods can do this + Con_Printf(S_WARNING "Unrecognized format %i\n", LittleLong(*(unsigned *)buf)); + continue; + } - if (crash) - Host_EndGame ("Mod_NumForName: %s not found or couldn't load", mod->name); - - mod->type = mod_dummy; - mod->mins[0] = -16; - mod->mins[1] = -16; - mod->mins[2] = -16; - mod->maxs[0] = 16; - mod->maxs[1] = 16; - mod->maxs[2] = 16; - mod->needload = true; P_DefaultTrail(mod); + +#ifndef SERVERONLY + if (cl.model_precache[1]) //not the world. + Validation_IncludeFile(mod->name, (char *)buf, com_filesize); +#endif + return mod; } - P_DefaultTrail(mod); +couldntload: + if (crash) + Host_EndGame ("Mod_NumForName: %s not found or couldn't load", mod->name); + Con_Printf(S_ERROR "Unable to load or replace %s\n", mod->name); + mod->type = mod_dummy; + mod->mins[0] = -16; + mod->mins[1] = -16; + mod->mins[2] = -16; + mod->maxs[0] = 16; + mod->maxs[1] = 16; + mod->maxs[2] = 16; + mod->needload = true; + mod->engineflags = 0; + P_DefaultTrail(mod); return mod; }