2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 // models.c -- model loading and caching
22 // models are the only shared resource between a client and server running
23 // on the same machine.
29 // LordHavoc: increased from 512 to 2048
30 #define MAX_MOD_KNOWN 2048
31 static model_t mod_known[MAX_MOD_KNOWN];
33 static void mod_start(void)
36 for (i = 0;i < MAX_MOD_KNOWN;i++)
37 if (mod_known[i].name[0])
38 Mod_UnloadModel(&mod_known[i]);
41 static void mod_shutdown(void)
44 for (i = 0;i < MAX_MOD_KNOWN;i++)
45 if (mod_known[i].name[0])
46 Mod_UnloadModel(&mod_known[i]);
49 static void mod_newmap(void)
58 static void Mod_Print (void);
59 static void Mod_Flush (void);
66 Cmd_AddCommand ("modellist", Mod_Print);
67 Cmd_AddCommand ("modelflush", Mod_Flush);
70 void Mod_RenderInit(void)
72 R_RegisterModule("Models", mod_start, mod_shutdown, mod_newmap);
75 void Mod_FreeModel (model_t *mod)
77 R_FreeTexturePool(&mod->texturepool);
78 Mem_FreePool(&mod->mempool);
80 // clear the struct to make it available
81 memset(mod, 0, sizeof(model_t));
84 void Mod_UnloadModel (model_t *mod)
87 qboolean isworldmodel;
88 strcpy(name, mod->name);
89 isworldmodel = mod->isworldmodel;
91 strcpy(mod->name, name);
92 mod->isworldmodel = isworldmodel;
103 static model_t *Mod_LoadModel (model_t *mod, qboolean crash, qboolean checkdisk, qboolean isworldmodel)
110 if (mod->name[0] == '*') // submodel
119 buf = COM_LoadFile (mod->name, false);
123 Host_Error ("Mod_LoadModel: %s not found", mod->name); // LordHavoc: Sys_Error was *ANNOYING*
127 crc = CRC_Block(buf, com_filesize);
132 if (mod->crc == crc && mod->isworldmodel == isworldmodel)
136 return mod; // already loaded
140 Con_DPrintf("loading model %s\n", mod->name);
144 buf = COM_LoadFile (mod->name, false);
148 Host_Error ("Mod_LoadModel: %s not found", mod->name);
151 crc = CRC_Block(buf, com_filesize);
154 // make sure nothing got trashed
155 //Mem_CheckSentinelsGlobal();
157 // allocate a new model
160 // LordHavoc: unload the existing model in this slot (if there is one)
161 Mod_UnloadModel(mod);
162 mod->isworldmodel = isworldmodel;
163 mod->needload = false;
167 // all models use memory, so allocate a memory pool
168 mod->mempool = Mem_AllocPool(mod->name);
169 // all models load textures, so allocate a texture pool
170 if (cls.state != ca_dedicated)
171 mod->texturepool = R_AllocTexturePool();
173 // call the apropriate loader
174 if (!memcmp(buf, "IDPO" , 4)) Mod_LoadAliasModel (mod, buf);
175 else if (!memcmp(buf, "IDP2" , 4)) Mod_LoadQ2AliasModel(mod, buf);
176 else if (!memcmp(buf, "ZYMOTIC" , 7)) Mod_LoadZymoticModel(mod, buf);
177 else if (!memcmp(buf, "IDSP" , 4)) Mod_LoadSpriteModel (mod, buf);
178 else Mod_LoadBrushModel (mod, buf);
182 // make sure nothing got trashed
183 //Mem_CheckSentinelsGlobal();
188 void Mod_CheckLoaded (model_t *mod)
193 Mod_LoadModel(mod, true, true, mod->isworldmodel);
196 if (mod->type == mod_invalid)
197 Host_Error("Mod_CheckLoaded: invalid model\n");
209 void Mod_ClearAll (void)
215 for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++)
222 void Mod_ClearUsed(void)
227 for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++)
232 void Mod_PurgeUnused(void)
237 for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++)
249 model_t *Mod_FindName (char *name)
252 model_t *mod, *freemod;
255 Host_Error ("Mod_ForName: NULL name");
257 // search the currently loaded models
259 for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++)
263 if (!strcmp (mod->name, name))
269 else if (freemod == NULL)
276 strcpy (mod->name, name);
277 mod->needload = true;
282 Host_Error ("Mod_FindName: ran out of models\n");
292 void Mod_TouchModel (char *name)
296 mod = Mod_FindName (name);
304 Loads in a model for the given name
307 model_t *Mod_ForName (char *name, qboolean crash, qboolean checkdisk, qboolean isworldmodel)
309 return Mod_LoadModel (Mod_FindName (name), crash, checkdisk, isworldmodel);
320 float RadiusFromBounds (vec3_t mins, vec3_t maxs)
325 for (i=0 ; i<3 ; i++)
326 corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]);
328 return Length (corner);
332 //=============================================================================
339 static void Mod_Print (void)
344 Con_Printf ("Loaded models:\n");
345 for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++)
347 Con_Printf ("%4iK %s\n", mod->mempool ? (mod->mempool->totalsize + 1023) / 1024 : 0, mod->name);
350 static void Mod_Flush (void)
354 Con_Printf ("Unloading models\n");
355 for (i = 0;i < MAX_MOD_KNOWN;i++)
356 if (mod_known[i].name[0])
357 Mod_UnloadModel(&mod_known[i]);