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.
32 void Mod_SpriteInit (void)
36 void Mod_Sprite_StripExtension(char *in, char *out)
39 end = in + strlen(in);
41 if (strcmp(end - 6, ".spr32") == 0)
44 if (strcmp(end - 4, ".spr") == 0)
56 void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum, int bytesperpixel)
58 dspriteframe_t *pinframe;
59 mspriteframe_t *pspriteframe;
60 int i, width, height, size, origin[2];
61 char name[256], tempname[256];
62 byte *pixbuf, *pixel, *inpixel;
64 pinframe = (dspriteframe_t *)pin;
66 width = LittleLong (pinframe->width);
67 height = LittleLong (pinframe->height);
68 size = width * height * bytesperpixel;
70 pspriteframe = Hunk_AllocName (sizeof (mspriteframe_t), va("%s frames", loadname));
72 memset (pspriteframe, 0, sizeof (mspriteframe_t));
74 *ppframe = pspriteframe;
76 pspriteframe->width = width;
77 pspriteframe->height = height;
78 origin[0] = LittleLong (pinframe->origin[0]);
79 origin[1] = LittleLong (pinframe->origin[1]);
81 pspriteframe->up = origin[1];
82 pspriteframe->down = origin[1] - height;
83 pspriteframe->left = origin[0];
84 pspriteframe->right = width + origin[0];
86 Mod_Sprite_StripExtension(loadmodel->name, tempname);
87 sprintf (name, "%s_%i", tempname, framenum);
88 pspriteframe->gl_texturenum = loadtextureimagewithmask(name, 0, 0, false, true);
89 pspriteframe->gl_fogtexturenum = image_masktexnum;
90 if (pspriteframe->gl_texturenum == 0)
92 pspriteframe->gl_texturenum = GL_LoadTexture (name, width, height, (byte *)(pinframe + 1), true, true, bytesperpixel);
93 // make fog version (just alpha)
94 pixbuf = pixel = qmalloc(width*height*4);
95 inpixel = (byte *)(pinframe + 1);
96 if (bytesperpixel == 1)
98 for (i = 0;i < width*height;i++)
103 if (*inpixel++ != 255)
112 for (i = 0;i < width*height;i++)
121 sprintf (name, "%s_%ifog", loadmodel->name, framenum);
122 pspriteframe->gl_fogtexturenum = GL_LoadTexture (name, width, height, pixbuf, true, true, 4);
126 return (void *)((byte *)pinframe + sizeof (dspriteframe_t) + size);
135 void * Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum, int bytesperpixel)
137 dspritegroup_t *pingroup;
138 mspritegroup_t *pspritegroup;
140 dspriteinterval_t *pin_intervals;
141 float *poutintervals;
144 pingroup = (dspritegroup_t *)pin;
146 numframes = LittleLong (pingroup->numframes);
148 pspritegroup = Hunk_AllocName (sizeof (mspritegroup_t) + (numframes - 1) * sizeof (pspritegroup->frames[0]), va("%s frames", loadname));
150 pspritegroup->numframes = numframes;
152 *ppframe = (mspriteframe_t *)pspritegroup;
154 pin_intervals = (dspriteinterval_t *)(pingroup + 1);
156 poutintervals = Hunk_AllocName (numframes * sizeof (float), va("%s frames", loadname));
158 pspritegroup->intervals = poutintervals;
160 for (i=0 ; i<numframes ; i++)
162 *poutintervals = LittleFloat (pin_intervals->interval);
163 if (*poutintervals <= 0.0)
164 Host_Error ("Mod_LoadSpriteGroup: interval<=0");
170 ptemp = (void *)pin_intervals;
172 for (i=0 ; i<numframes ; i++)
173 ptemp = Mod_LoadSpriteFrame (ptemp, &pspritegroup->frames[i], framenum * 100 + i, bytesperpixel);
184 void Mod_LoadSpriteModel (model_t *mod, void *buffer)
192 dspriteframetype_t *pframetype;
193 // LordHavoc: 32bit textures
196 mod->flags = EF_FULLBRIGHT;
197 // LordHavoc: hack to allow sprites to be non-fullbright
198 for (i = 0;i < MAX_QPATH && mod->name[i];i++)
200 if (mod->name[i] == '!')
202 mod->flags &= ~EF_FULLBRIGHT;
207 pin = (dsprite_t *)buffer;
209 version = LittleLong (pin->version);
213 Con_Printf("warning: %s is a version 2 sprite (RGBA), supported for now, please hex edit to version 32 incase HalfLife sprites might be supported at some point.\n", mod->name);
215 // LordHavoc: 32bit textures
216 if (version != SPRITE_VERSION && version != SPRITE32_VERSION)
217 Host_Error ("%s has wrong version number "
218 "(%i should be %i or %i)", mod->name, version, SPRITE_VERSION, SPRITE32_VERSION);
220 if (version == SPRITE32_VERSION)
223 numframes = LittleLong (pin->numframes);
225 size = sizeof (msprite_t) + (numframes - 1) * sizeof (psprite->frames);
227 psprite = Hunk_AllocName (size, va("%s info", loadname));
229 mod->cache.data = psprite;
231 psprite->type = LittleLong (pin->type);
232 psprite->maxwidth = LittleLong (pin->width);
233 psprite->maxheight = LittleLong (pin->height);
234 psprite->beamlength = LittleFloat (pin->beamlength);
235 mod->synctype = LittleLong (pin->synctype);
236 psprite->numframes = numframes;
238 mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2;
239 mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2;
240 mod->mins[2] = -psprite->maxheight/2;
241 mod->maxs[2] = psprite->maxheight/2;
247 Host_Error ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes);
249 mod->numframes = numframes;
251 pframetype = (dspriteframetype_t *)(pin + 1);
253 for (i=0 ; i<numframes ; i++)
255 spriteframetype_t frametype;
257 frametype = LittleLong (pframetype->type);
258 psprite->frames[i].type = frametype;
260 if (frametype == SPR_SINGLE)
261 pframetype = (dspriteframetype_t *) Mod_LoadSpriteFrame (pframetype + 1, &psprite->frames[i].frameptr, i, bytesperpixel);
263 pframetype = (dspriteframetype_t *) Mod_LoadSpriteGroup (pframetype + 1, &psprite->frames[i].frameptr, i, bytesperpixel);
266 mod->type = mod_sprite;