]> icculus.org git repositories - divverent/darkplaces.git/blob - model_shared.c
improved TraceLine in chase.c to be more generally useful (should move it to another...
[divverent/darkplaces.git] / model_shared.c
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
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.
8
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.  
12
13 See the GNU General Public License for more details.
14
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.
18
19 */
20 // models.c -- model loading and caching
21
22 // models are the only shared resource between a client and server running
23 // on the same machine.
24
25 #include "quakedef.h"
26
27 model_t *loadmodel;
28 char    loadname[32];   // for hunk tags
29
30 extern void Mod_LoadSpriteModel (model_t *mod, void *buffer);
31 extern void Mod_LoadBrushModel (model_t *mod, void *buffer);
32 extern void Mod_LoadAliasModel (model_t *mod, void *buffer);
33 extern void Mod_LoadQ2AliasModel (model_t *mod, void *buffer);
34 extern void Mod_LoadZymoticModel (model_t *mod, void *buffer);
35 model_t *Mod_LoadModel (model_t *mod, qboolean crash);
36
37 #define MAX_MOD_KNOWN   512
38 model_t mod_known[MAX_MOD_KNOWN];
39 int             mod_numknown;
40
41 extern void Mod_BrushInit();
42 extern void Mod_AliasInit();
43 extern void Mod_SpriteInit();
44
45 /*
46 ===============
47 Mod_Init
48 ===============
49 */
50 void Mod_Init (void)
51 {
52         Mod_BrushInit();
53         Mod_AliasInit();
54         Mod_SpriteInit();
55 }
56
57 /*
58 ===============
59 Mod_Init
60
61 Caches the data if needed
62 ===============
63 */
64 void *Mod_Extradata (model_t *mod)
65 {
66         void    *r;
67         
68         r = Cache_Check (&mod->cache);
69         if (r)
70                 return r;
71
72         Mod_LoadModel (mod, true);
73         
74         if (!mod->cache.data)
75                 Host_Error ("Mod_Extradata: caching failed");
76         return mod->cache.data;
77 }
78
79 /*
80 ===================
81 Mod_ClearAll
82 ===================
83 */
84 void Mod_ClearAll (void)
85 {
86         int             i;
87         model_t *mod;
88         
89         for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
90                 if (mod->type != mod_alias)
91                         mod->needload = true;
92 }
93
94 /*
95 ==================
96 Mod_FindName
97
98 ==================
99 */
100 model_t *Mod_FindName (char *name)
101 {
102         int             i;
103         model_t *mod;
104         
105         if (!name[0])
106                 Host_Error ("Mod_ForName: NULL name");
107                 
108 //
109 // search the currently loaded models
110 //
111         for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
112                 if (!strcmp (mod->name, name) )
113                         break;
114                         
115         if (i == mod_numknown)
116         {
117                 if (mod_numknown == MAX_MOD_KNOWN)
118                         Host_Error ("mod_numknown == MAX_MOD_KNOWN");
119                 strcpy (mod->name, name);
120                 mod->needload = true;
121                 mod_numknown++;
122         }
123
124         return mod;
125 }
126
127 /*
128 ==================
129 Mod_TouchModel
130
131 ==================
132 */
133 void Mod_TouchModel (char *name)
134 {
135         model_t *mod;
136         
137         mod = Mod_FindName (name);
138         
139         if (!mod->needload)
140         {
141                 if (mod->type == mod_alias)
142                         Cache_Check (&mod->cache);
143         }
144 }
145
146 /*
147 ==================
148 Mod_LoadModel
149
150 Loads a model into the cache
151 ==================
152 */
153 model_t *Mod_LoadModel (model_t *mod, qboolean crash)
154 {
155         void    *d;
156         unsigned *buf;
157
158         if (!mod->needload)
159         {
160                 if (mod->type == mod_alias)
161                 {
162                         d = Cache_Check (&mod->cache);
163                         if (d)
164                                 return mod;
165                 }
166                 else
167                         return mod;             // not cached at all
168         }
169
170         Con_DPrintf("loading model %s\n", mod->name);
171
172 // load the file
173         buf = (unsigned *)COM_LoadMallocFile (mod->name, false);
174         if (!buf)
175         {
176                 if (crash)
177                         Host_Error ("Mod_NumForName: %s not found", mod->name); // LordHavoc: Sys_Error was *ANNOYING*
178                 return NULL;
179         }
180         
181 // allocate a new model
182         COM_FileBase (mod->name, loadname);
183         
184         loadmodel = mod;
185
186 // call the apropriate loader
187         mod->needload = false;
188         
189         switch (LittleLong(*(unsigned *)buf))
190         {
191         case IDPOLYHEADER:
192                 Mod_LoadAliasModel (mod, buf);
193                 break;
194
195         case MD2IDALIASHEADER: // LordHavoc: added Quake2 model support
196                 Mod_LoadQ2AliasModel (mod, buf);
197                 break;
198
199         case (('O'<<24)+('M'<<16)+('Y'<<8)+'Z'):
200                 Mod_LoadZymoticModel(mod, buf);
201                 break;
202                 
203         case IDSPRITEHEADER:
204                 Mod_LoadSpriteModel (mod, buf);
205                 break;
206         
207         default:
208                 Mod_LoadBrushModel (mod, buf);
209                 break;
210         }
211         qfree(buf);
212
213         return mod;
214 }
215
216 /*
217 ==================
218 Mod_ForName
219
220 Loads in a model for the given name
221 ==================
222 */
223 model_t *Mod_ForName (char *name, qboolean crash)
224 {
225         model_t *mod;
226         
227         mod = Mod_FindName (name);
228         
229         return Mod_LoadModel (mod, crash);
230 }
231
232 byte    *mod_base;
233
234 /*
235 =================
236 RadiusFromBounds
237 =================
238 */
239 float RadiusFromBounds (vec3_t mins, vec3_t maxs)
240 {
241         int             i;
242         vec3_t  corner;
243
244         for (i=0 ; i<3 ; i++)
245                 corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]);
246
247         return Length (corner);
248 }
249
250 //=============================================================================
251
252 /*
253 ================
254 Mod_Print
255 ================
256 */
257 void Mod_Print (void)
258 {
259         int             i;
260         model_t *mod;
261
262         Con_Printf ("Cached models:\n");
263         for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++)
264         {
265                 Con_Printf ("%8p : %s\n",mod->cache.data, mod->name);
266         }
267 }
268
269