From c7d8fb37737a36d73453bc3bc1d22b55ba03c965 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 1 Sep 2000 04:43:56 +0000 Subject: [PATCH 1/9] preliminary work on really cleaning up *model.c. atm, just split out the model type specific code into the appropriate files (which will later be merged as much as possible) and remove all model type specific code from model.c. gl_model.c is no more as it ended up being an exact copy of model.c minus a header include and a prototype, neither of which were needed. --- source/gl_model_alias.c | 495 +++++++ source/{gl_model.c => gl_model_brush.c} | 870 +----------- source/gl_model_sprite.c | 210 +++ source/model.c | 1616 +---------------------- source/sw_model_alias.c | 477 +++++++ source/sw_model_brush.c | 1019 ++++++++++++++ source/sw_model_sprite.c | 223 ++++ 7 files changed, 2428 insertions(+), 2482 deletions(-) create mode 100644 source/gl_model_alias.c rename source/{gl_model.c => gl_model_brush.c} (54%) create mode 100644 source/gl_model_sprite.c create mode 100644 source/sw_model_alias.c create mode 100644 source/sw_model_brush.c create mode 100644 source/sw_model_sprite.c diff --git a/source/gl_model_alias.c b/source/gl_model_alias.c new file mode 100644 index 0000000..4d773ab --- /dev/null +++ b/source/gl_model_alias.c @@ -0,0 +1,495 @@ +/* + gl_model.c + + model loading and caching + + Copyright (C) 1996-1997 Id Software, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + + $Id$ +*/ + +// models are the only shared resource between a client and server running +// on the same machine. + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +/* +============================================================================== + +ALIAS MODELS + +============================================================================== +*/ + +aliashdr_t *pheader; + +stvert_t stverts[MAXALIASVERTS]; +mtriangle_t triangles[MAXALIASTRIS]; + +// a pose is a single set of vertexes. a frame may be +// an animating sequence of poses +trivertx_t *poseverts[MAXALIASFRAMES]; +int posenum; + +byte player_8bit_texels[320*200]; + +/* +================= +Mod_LoadAliasFrame +================= +*/ +void * Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame) +{ + trivertx_t *pinframe; + int i; + daliasframe_t *pdaliasframe; + + pdaliasframe = (daliasframe_t *)pin; + + strcpy (frame->name, pdaliasframe->name); + frame->firstpose = posenum; + frame->numposes = 1; + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about + // endianness + frame->bboxmin.v[i] = pdaliasframe->bboxmin.v[i]; + frame->bboxmin.v[i] = pdaliasframe->bboxmax.v[i]; + } + + pinframe = (trivertx_t *)(pdaliasframe + 1); + + poseverts[posenum] = pinframe; + posenum++; + + pinframe += pheader->numverts; + + return (void *)pinframe; +} + + +/* +================= +Mod_LoadAliasGroup +================= +*/ +void *Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame) +{ + daliasgroup_t *pingroup; + int i, numframes; + daliasinterval_t *pin_intervals; + void *ptemp; + + pingroup = (daliasgroup_t *)pin; + + numframes = LittleLong (pingroup->numframes); + + frame->firstpose = posenum; + frame->numposes = numframes; + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about endianness + frame->bboxmin.v[i] = pingroup->bboxmin.v[i]; + frame->bboxmin.v[i] = pingroup->bboxmax.v[i]; + } + + pin_intervals = (daliasinterval_t *)(pingroup + 1); + + frame->interval = LittleFloat (pin_intervals->interval); + + pin_intervals += numframes; + + ptemp = (void *)pin_intervals; + + for (i=0 ; inumverts; + } + + return ptemp; +} + +//========================================================= + +/* +================= +Mod_FloodFillSkin + +Fill background pixels so mipmapping doesn't have haloes - Ed +================= +*/ + +typedef struct +{ + short x, y; +} floodfill_t; + +extern unsigned d_8to24table[]; + +// must be a power of 2 +#define FLOODFILL_FIFO_SIZE 0x1000 +#define FLOODFILL_FIFO_MASK (FLOODFILL_FIFO_SIZE - 1) + +#define FLOODFILL_STEP( off, dx, dy ) \ +{ \ + if (pos[off] == fillcolor) \ + { \ + pos[off] = 255; \ + fifo[inpt].x = x + (dx), fifo[inpt].y = y + (dy); \ + inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; \ + } \ + else if (pos[off] != 255) fdc = pos[off]; \ +} + +void Mod_FloodFillSkin( byte *skin, int skinwidth, int skinheight ) +{ + byte fillcolor = *skin; // assume this is the pixel to fill + floodfill_t fifo[FLOODFILL_FIFO_SIZE]; + int inpt = 0, outpt = 0; + int filledcolor = -1; + int i; + + if (filledcolor == -1) + { + filledcolor = 0; + // attempt to find opaque black + for (i = 0; i < 256; ++i) + if (d_8to24table[i] == (255 << 0)) // alpha 1.0 + { + filledcolor = i; + break; + } + } + + // can't fill to filled color or to transparent color (used as visited marker) + if ((fillcolor == filledcolor) || (fillcolor == 255)) + { + //printf( "not filling skin from %d to %d\n", fillcolor, filledcolor ); + return; + } + + fifo[inpt].x = 0, fifo[inpt].y = 0; + inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; + + while (outpt != inpt) + { + int x = fifo[outpt].x, y = fifo[outpt].y; + int fdc = filledcolor; + byte *pos = &skin[x + skinwidth * y]; + + outpt = (outpt + 1) & FLOODFILL_FIFO_MASK; + + if (x > 0) FLOODFILL_STEP( -1, -1, 0 ); + if (x < skinwidth - 1) FLOODFILL_STEP( 1, 1, 0 ); + if (y > 0) FLOODFILL_STEP( -skinwidth, 0, -1 ); + if (y < skinheight - 1) FLOODFILL_STEP( skinwidth, 0, 1 ); + skin[x + skinwidth * y] = fdc; + } +} + +/* +=============== +Mod_LoadAllSkins +=============== +*/ +void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype) +{ + int i, j, k; + char name[32]; + int s; + byte *skin; + daliasskingroup_t *pinskingroup; + int groupskins; + daliasskininterval_t *pinskinintervals; + + skin = (byte *)(pskintype + 1); + + if (numskins < 1 || numskins > MAX_SKINS) + Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins); + + s = pheader->skinwidth * pheader->skinheight; + + for (i=0 ; itype == ALIAS_SKIN_SINGLE) { + Mod_FloodFillSkin( skin, pheader->skinwidth, pheader->skinheight ); + + // save 8 bit texels for the player model to remap + if (!strcmp(loadmodel->name,"progs/player.mdl")) + { + if (s > sizeof(player_8bit_texels)) + Sys_Error ("Player skin too large"); + memcpy (player_8bit_texels, (byte *)(pskintype + 1), s); + } + + // This block is GL fullbright support for objects... + { + int pixels; + byte *ptexel; + + // Check for fullbright pixels.. + pixels = pheader->skinwidth * pheader->skinheight; + ptexel = (byte *)(pskintype + 1); + + for (j=0 ; j= 256-32) { + loadmodel->hasfullbrights = true; + break; + } + } + + if (loadmodel->hasfullbrights) { + byte *ptexels; + + //ptexels = Hunk_Alloc(s); + ptexels = malloc(pixels); + + snprintf(name, sizeof(name), "fb_%s_%i", loadmodel->name,i); + Con_DPrintf("FB Model ID: '%s'\n", name); + for (j=0 ; j= 256-32) { + ptexels[j] = ptexel[j]; + } else { + ptexels[j] = 255; + } + } + pheader->gl_fb_texturenum[i][0] = + pheader->gl_fb_texturenum[i][1] = + pheader->gl_fb_texturenum[i][2] = + pheader->gl_fb_texturenum[i][3] = + GL_LoadTexture (name, pheader->skinwidth, + pheader->skinheight, ptexels, true, true, 1); + + free(ptexels); + } + } + + + snprintf (name, sizeof(name), "%s_%i", loadmodel->name, i); + pheader->gl_texturenum[i][0] = + pheader->gl_texturenum[i][1] = + pheader->gl_texturenum[i][2] = + pheader->gl_texturenum[i][3] = + GL_LoadTexture (name, pheader->skinwidth, + pheader->skinheight, (byte *)(pskintype + 1), true, true, 1); + pskintype = (daliasskintype_t *)((byte *)(pskintype+1) + s); + } else { + // animating skin group. yuck. + Con_Printf("Animating Skin Group, if you get this message please notify warp@debian.org\n"); + pskintype++; + pinskingroup = (daliasskingroup_t *)pskintype; + groupskins = LittleLong (pinskingroup->numskins); + pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1); + + pskintype = (void *)(pinskinintervals + groupskins); + + for (j=0 ; jskinwidth, pheader->skinheight ); + snprintf (name, sizeof(name), "%s_%i_%i", loadmodel->name, i,j); + pheader->gl_texturenum[i][j&3] = + GL_LoadTexture (name, pheader->skinwidth, + pheader->skinheight, (byte *)(pskintype), true, false, 1); + pskintype = (daliasskintype_t *)((byte *)(pskintype) + s); + } + k = j; + for (/* */; j < 4; j++) + pheader->gl_texturenum[i][j&3] = + pheader->gl_texturenum[i][j - k]; + } + } + + return (void *)pskintype; +} + + +//========================================================================= + +/* +================= +Mod_LoadAliasModel +================= +*/ +void Mod_LoadAliasModel (model_t *mod, void *buffer) +{ + int i, j; + mdl_t *pinmodel; + stvert_t *pinstverts; + dtriangle_t *pintriangles; + int version, numframes; + int size; + daliasframetype_t *pframetype; + daliasskintype_t *pskintype; + int start, end, total; + + start = Hunk_LowMark (); + + pinmodel = (mdl_t *)buffer; + + version = LittleLong (pinmodel->version); + if (version != ALIAS_VERSION) + Sys_Error ("%s has wrong version number (%i should be %i)", + mod->name, version, ALIAS_VERSION); + +// +// allocate space for a working header, plus all the data except the frames, +// skin and group info +// + size = sizeof (aliashdr_t) + + (LittleLong (pinmodel->numframes) - 1) * + sizeof (pheader->frames[0]); + pheader = Hunk_AllocName (size, loadname); + + mod->flags = LittleLong (pinmodel->flags); + +// +// endian-adjust and copy the data, starting with the alias model header +// + pheader->boundingradius = LittleFloat (pinmodel->boundingradius); + pheader->numskins = LittleLong (pinmodel->numskins); + pheader->skinwidth = LittleLong (pinmodel->skinwidth); + pheader->skinheight = LittleLong (pinmodel->skinheight); + + if (pheader->skinheight > MAX_LBM_HEIGHT) + Sys_Error ("model %s has a skin taller than %d", mod->name, + MAX_LBM_HEIGHT); + + pheader->numverts = LittleLong (pinmodel->numverts); + + if (pheader->numverts <= 0) + Sys_Error ("model %s has no vertices", mod->name); + + if (pheader->numverts > MAXALIASVERTS) + Sys_Error ("model %s has too many vertices", mod->name); + + pheader->numtris = LittleLong (pinmodel->numtris); + + if (pheader->numtris <= 0) + Sys_Error ("model %s has no triangles", mod->name); + + pheader->numframes = LittleLong (pinmodel->numframes); + numframes = pheader->numframes; + if (numframes < 1) + Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); + + pheader->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; + mod->synctype = LittleLong (pinmodel->synctype); + mod->numframes = pheader->numframes; + + for (i=0 ; i<3 ; i++) + { + pheader->scale[i] = LittleFloat (pinmodel->scale[i]); + pheader->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]); + pheader->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]); + } + + +// +// load the skins +// + pskintype = (daliasskintype_t *)&pinmodel[1]; + pskintype = Mod_LoadAllSkins (pheader->numskins, pskintype); + +// +// load base s and t vertices +// + pinstverts = (stvert_t *)pskintype; + + for (i=0 ; inumverts ; i++) + { + stverts[i].onseam = LittleLong (pinstverts[i].onseam); + stverts[i].s = LittleLong (pinstverts[i].s); + stverts[i].t = LittleLong (pinstverts[i].t); + } + +// +// load triangle lists +// + pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts]; + + for (i=0 ; inumtris ; i++) + { + triangles[i].facesfront = LittleLong (pintriangles[i].facesfront); + + for (j=0 ; j<3 ; j++) + { + triangles[i].vertindex[j] = + LittleLong (pintriangles[i].vertindex[j]); + } + } + +// +// load the frames +// + posenum = 0; + pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris]; + + for (i=0 ; itype); + + if (frametype == ALIAS_SINGLE) + { + pframetype = (daliasframetype_t *) + Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]); + } + else + { + pframetype = (daliasframetype_t *) + Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i]); + } + } + + pheader->numposes = posenum; + + mod->type = mod_alias; + +// FIXME: do this right + mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; + mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; + + // + // build the draw lists + // + GL_MakeAliasModelDisplayLists (mod, pheader); + +// +// move the complete, relocatable alias model to the cache +// + end = Hunk_LowMark (); + total = end - start; + + Cache_Alloc (&mod->cache, total, loadname); + if (!mod->cache.data) + return; + memcpy (mod->cache.data, pheader, total); + + Hunk_FreeToLowMark (start); +} diff --git a/source/gl_model.c b/source/gl_model_brush.c similarity index 54% rename from source/gl_model.c rename to source/gl_model_brush.c index 251bdca..a3a907c 100644 --- a/source/gl_model.c +++ b/source/gl_model_brush.c @@ -40,36 +40,6 @@ #include "checksum.h" #include "glquake.h" -model_t *loadmodel; -char loadname[32]; // for hunk tags - -void Mod_LoadSpriteModel (model_t *mod, void *buffer); -void Mod_LoadBrushModel (model_t *mod, void *buffer); -void Mod_LoadAliasModel (model_t *mod, void *buffer); -model_t *Mod_LoadModel (model_t *mod, qboolean crash); -void Mod_LoadMMNearest(miptex_t *mx, texture_t *tx); - -byte mod_novis[MAX_MAP_LEAFS/8]; - -#define MAX_MOD_KNOWN 512 -model_t mod_known[MAX_MOD_KNOWN]; -int mod_numknown; - -unsigned *model_checksum; -texture_t *r_notexture_mip; -cvar_t *gl_subdivide_size; - -/* -=============== -Mod_Init -=============== -*/ -void Mod_Init (void) -{ - gl_subdivide_size = Cvar_Get("gl_subdivide_size", "128", CVAR_ARCHIVE, "None"); - memset (mod_novis, 0xff, sizeof(mod_novis)); -} - /* =============== Mod_PointInLeaf @@ -90,7 +60,7 @@ mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model) if (node->contents < 0) return (mleaf_t *)node; plane = node->plane; - d = DotProduct (p,plane->normal) - plane->dist; + d = DotProduct (p, plane->normal) - plane->dist; if (d > 0) node = node->children[0]; else @@ -153,140 +123,6 @@ byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model) return Mod_DecompressVis (leaf->compressed_vis, model); } -/* -=================== -Mod_ClearAll -=================== -*/ -void Mod_ClearAll (void) -{ - int i; - model_t *mod; - - for (i=0 , mod=mod_known ; itype != mod_alias) - mod->needload = true; -} - -/* -================== -Mod_FindName - -================== -*/ -model_t *Mod_FindName (char *name) -{ - int i; - model_t *mod; - - if (!name[0]) - Sys_Error ("Mod_ForName: NULL name"); - -// -// search the currently loaded models -// - for (i=0 , mod=mod_known ; iname, name) ) - break; - - if (i == mod_numknown) - { - if (mod_numknown == MAX_MOD_KNOWN) - Sys_Error ("mod_numknown == MAX_MOD_KNOWN"); - strcpy (mod->name, name); - mod->needload = true; - mod_numknown++; - } - - return mod; -} - -/* -================== -Mod_LoadModel - -Loads a model into the cache -================== -*/ -model_t *Mod_LoadModel (model_t *mod, qboolean crash) -{ - void *d; - unsigned *buf; - byte stackbuf[1024]; // avoid dirtying the cache heap - - if (!mod->needload) - { - if (mod->type == mod_alias) - { - d = Cache_Check (&mod->cache); - if (d) - return mod; - } - else - return mod; // not cached at all - } - -// -// load the file -// - buf = (unsigned *)COM_LoadStackFile (mod->name, stackbuf, sizeof(stackbuf)); - if (!buf) - { - if (crash) - Sys_Error ("Mod_NumForName: %s not found", mod->name); - return NULL; - } - -// -// allocate a new model -// - COM_FileBase (mod->name, loadname); - - loadmodel = mod; - -// -// fill it in -// - -// call the apropriate loader - mod->needload = false; - mod->hasfullbrights = false; - - switch (LittleLong(*(unsigned *)buf)) - { - case IDPOLYHEADER: - Mod_LoadAliasModel (mod, buf); - break; - - case IDSPRITEHEADER: - Mod_LoadSpriteModel (mod, buf); - break; - - default: - Mod_LoadBrushModel (mod, buf); - break; - } - - return mod; -} - -/* -================== -Mod_ForName - -Loads in a model for the given name -================== -*/ -model_t *Mod_ForName (char *name, qboolean crash) -{ - model_t *mod; - - mod = Mod_FindName (name); - - return Mod_LoadModel (mod, crash); -} - - /* =============================================================================== @@ -1229,57 +1065,6 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) } } -extern char loadname[]; // for hunk tags -extern model_t *loadmodel; -extern model_t mod_known[]; -extern int mod_numknown; - -void Mod_LoadSpriteModel (model_t *mod, void *buffer); -void Mod_LoadAliasModel (model_t *mod, void *buffer); -model_t *Mod_LoadModel (model_t *mod, qboolean crash); -model_t *Mod_FindName (char *name); - -/* -=============== -Mod_Extradata - -Caches the data if needed -=============== -*/ -void *Mod_Extradata (model_t *mod) -{ - void *r; - - r = Cache_Check (&mod->cache); - if (r) - return r; - - Mod_LoadModel (mod, true); - - if (!mod->cache.data) - Sys_Error ("Mod_Extradata: caching failed"); - return mod->cache.data; -} - -/* -================== -Mod_TouchModel - -================== -*/ -void Mod_TouchModel (char *name) -{ - model_t *mod; - - mod = Mod_FindName (name); - - if (!mod->needload) - { - if (mod->type == mod_alias) - Cache_Check (&mod->cache); - } -} - void Mod_LoadMMNearest(miptex_t *mt, texture_t *tx) { @@ -1287,656 +1072,3 @@ Mod_LoadMMNearest(miptex_t *mt, texture_t *tx) tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false, 1); texture_mode = GL_LINEAR; } - -/* -============================================================================== - -ALIAS MODELS - -============================================================================== -*/ - -aliashdr_t *pheader; - -stvert_t stverts[MAXALIASVERTS]; -mtriangle_t triangles[MAXALIASTRIS]; - -// a pose is a single set of vertexes. a frame may be -// an animating sequence of poses -trivertx_t *poseverts[MAXALIASFRAMES]; -int posenum; - -byte player_8bit_texels[320*200]; - -/* -================= -Mod_LoadAliasFrame -================= -*/ -void * Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame) -{ - trivertx_t *pinframe; - int i; - daliasframe_t *pdaliasframe; - - pdaliasframe = (daliasframe_t *)pin; - - strcpy (frame->name, pdaliasframe->name); - frame->firstpose = posenum; - frame->numposes = 1; - - for (i=0 ; i<3 ; i++) - { - // these are byte values, so we don't have to worry about - // endianness - frame->bboxmin.v[i] = pdaliasframe->bboxmin.v[i]; - frame->bboxmin.v[i] = pdaliasframe->bboxmax.v[i]; - } - - pinframe = (trivertx_t *)(pdaliasframe + 1); - - poseverts[posenum] = pinframe; - posenum++; - - pinframe += pheader->numverts; - - return (void *)pinframe; -} - - -/* -================= -Mod_LoadAliasGroup -================= -*/ -void *Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame) -{ - daliasgroup_t *pingroup; - int i, numframes; - daliasinterval_t *pin_intervals; - void *ptemp; - - pingroup = (daliasgroup_t *)pin; - - numframes = LittleLong (pingroup->numframes); - - frame->firstpose = posenum; - frame->numposes = numframes; - - for (i=0 ; i<3 ; i++) - { - // these are byte values, so we don't have to worry about endianness - frame->bboxmin.v[i] = pingroup->bboxmin.v[i]; - frame->bboxmin.v[i] = pingroup->bboxmax.v[i]; - } - - pin_intervals = (daliasinterval_t *)(pingroup + 1); - - frame->interval = LittleFloat (pin_intervals->interval); - - pin_intervals += numframes; - - ptemp = (void *)pin_intervals; - - for (i=0 ; inumverts; - } - - return ptemp; -} - -//========================================================= - -/* -================= -Mod_FloodFillSkin - -Fill background pixels so mipmapping doesn't have haloes - Ed -================= -*/ - -typedef struct -{ - short x, y; -} floodfill_t; - -extern unsigned d_8to24table[]; - -// must be a power of 2 -#define FLOODFILL_FIFO_SIZE 0x1000 -#define FLOODFILL_FIFO_MASK (FLOODFILL_FIFO_SIZE - 1) - -#define FLOODFILL_STEP( off, dx, dy ) \ -{ \ - if (pos[off] == fillcolor) \ - { \ - pos[off] = 255; \ - fifo[inpt].x = x + (dx), fifo[inpt].y = y + (dy); \ - inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; \ - } \ - else if (pos[off] != 255) fdc = pos[off]; \ -} - -void Mod_FloodFillSkin( byte *skin, int skinwidth, int skinheight ) -{ - byte fillcolor = *skin; // assume this is the pixel to fill - floodfill_t fifo[FLOODFILL_FIFO_SIZE]; - int inpt = 0, outpt = 0; - int filledcolor = -1; - int i; - - if (filledcolor == -1) - { - filledcolor = 0; - // attempt to find opaque black - for (i = 0; i < 256; ++i) - if (d_8to24table[i] == (255 << 0)) // alpha 1.0 - { - filledcolor = i; - break; - } - } - - // can't fill to filled color or to transparent color (used as visited marker) - if ((fillcolor == filledcolor) || (fillcolor == 255)) - { - //printf( "not filling skin from %d to %d\n", fillcolor, filledcolor ); - return; - } - - fifo[inpt].x = 0, fifo[inpt].y = 0; - inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; - - while (outpt != inpt) - { - int x = fifo[outpt].x, y = fifo[outpt].y; - int fdc = filledcolor; - byte *pos = &skin[x + skinwidth * y]; - - outpt = (outpt + 1) & FLOODFILL_FIFO_MASK; - - if (x > 0) FLOODFILL_STEP( -1, -1, 0 ); - if (x < skinwidth - 1) FLOODFILL_STEP( 1, 1, 0 ); - if (y > 0) FLOODFILL_STEP( -skinwidth, 0, -1 ); - if (y < skinheight - 1) FLOODFILL_STEP( skinwidth, 0, 1 ); - skin[x + skinwidth * y] = fdc; - } -} - -/* -=============== -Mod_LoadAllSkins -=============== -*/ -void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype) -{ - int i, j, k; - char name[32]; - int s; - byte *skin; - daliasskingroup_t *pinskingroup; - int groupskins; - daliasskininterval_t *pinskinintervals; - - skin = (byte *)(pskintype + 1); - - if (numskins < 1 || numskins > MAX_SKINS) - Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins); - - s = pheader->skinwidth * pheader->skinheight; - - for (i=0 ; itype == ALIAS_SKIN_SINGLE) { - Mod_FloodFillSkin( skin, pheader->skinwidth, pheader->skinheight ); - - // save 8 bit texels for the player model to remap - if (!strcmp(loadmodel->name,"progs/player.mdl")) - { - if (s > sizeof(player_8bit_texels)) - Sys_Error ("Player skin too large"); - memcpy (player_8bit_texels, (byte *)(pskintype + 1), s); - } - - // This block is GL fullbright support for objects... - { - int pixels; - byte *ptexel; - - // Check for fullbright pixels.. - pixels = pheader->skinwidth * pheader->skinheight; - ptexel = (byte *)(pskintype + 1); - - for (j=0 ; j= 256-32) { - loadmodel->hasfullbrights = true; - break; - } - } - - if (loadmodel->hasfullbrights) { - byte *ptexels; - - //ptexels = Hunk_Alloc(s); - ptexels = malloc(pixels); - - snprintf(name, sizeof(name), "fb_%s_%i", loadmodel->name,i); - Con_DPrintf("FB Model ID: '%s'\n", name); - for (j=0 ; j= 256-32) { - ptexels[j] = ptexel[j]; - } else { - ptexels[j] = 255; - } - } - pheader->gl_fb_texturenum[i][0] = - pheader->gl_fb_texturenum[i][1] = - pheader->gl_fb_texturenum[i][2] = - pheader->gl_fb_texturenum[i][3] = - GL_LoadTexture (name, pheader->skinwidth, - pheader->skinheight, ptexels, true, true, 1); - - free(ptexels); - } - } - - - snprintf (name, sizeof(name), "%s_%i", loadmodel->name, i); - pheader->gl_texturenum[i][0] = - pheader->gl_texturenum[i][1] = - pheader->gl_texturenum[i][2] = - pheader->gl_texturenum[i][3] = - GL_LoadTexture (name, pheader->skinwidth, - pheader->skinheight, (byte *)(pskintype + 1), true, true, 1); - pskintype = (daliasskintype_t *)((byte *)(pskintype+1) + s); - } else { - // animating skin group. yuck. - Con_Printf("Animating Skin Group, if you get this message please notify warp@debian.org\n"); - pskintype++; - pinskingroup = (daliasskingroup_t *)pskintype; - groupskins = LittleLong (pinskingroup->numskins); - pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1); - - pskintype = (void *)(pinskinintervals + groupskins); - - for (j=0 ; jskinwidth, pheader->skinheight ); - snprintf (name, sizeof(name), "%s_%i_%i", loadmodel->name, i,j); - pheader->gl_texturenum[i][j&3] = - GL_LoadTexture (name, pheader->skinwidth, - pheader->skinheight, (byte *)(pskintype), true, false, 1); - pskintype = (daliasskintype_t *)((byte *)(pskintype) + s); - } - k = j; - for (/* */; j < 4; j++) - pheader->gl_texturenum[i][j&3] = - pheader->gl_texturenum[i][j - k]; - } - } - - return (void *)pskintype; -} - - -//========================================================================= - -/* -================= -Mod_LoadAliasModel -================= -*/ -void Mod_LoadAliasModel (model_t *mod, void *buffer) -{ - int i, j; - mdl_t *pinmodel; - stvert_t *pinstverts; - dtriangle_t *pintriangles; - int version, numframes; - int size; - daliasframetype_t *pframetype; - daliasskintype_t *pskintype; - int start, end, total; - - start = Hunk_LowMark (); - - pinmodel = (mdl_t *)buffer; - - version = LittleLong (pinmodel->version); - if (version != ALIAS_VERSION) - Sys_Error ("%s has wrong version number (%i should be %i)", - mod->name, version, ALIAS_VERSION); - -// -// allocate space for a working header, plus all the data except the frames, -// skin and group info -// - size = sizeof (aliashdr_t) - + (LittleLong (pinmodel->numframes) - 1) * - sizeof (pheader->frames[0]); - pheader = Hunk_AllocName (size, loadname); - - mod->flags = LittleLong (pinmodel->flags); - -// -// endian-adjust and copy the data, starting with the alias model header -// - pheader->boundingradius = LittleFloat (pinmodel->boundingradius); - pheader->numskins = LittleLong (pinmodel->numskins); - pheader->skinwidth = LittleLong (pinmodel->skinwidth); - pheader->skinheight = LittleLong (pinmodel->skinheight); - - if (pheader->skinheight > MAX_LBM_HEIGHT) - Sys_Error ("model %s has a skin taller than %d", mod->name, - MAX_LBM_HEIGHT); - - pheader->numverts = LittleLong (pinmodel->numverts); - - if (pheader->numverts <= 0) - Sys_Error ("model %s has no vertices", mod->name); - - if (pheader->numverts > MAXALIASVERTS) - Sys_Error ("model %s has too many vertices", mod->name); - - pheader->numtris = LittleLong (pinmodel->numtris); - - if (pheader->numtris <= 0) - Sys_Error ("model %s has no triangles", mod->name); - - pheader->numframes = LittleLong (pinmodel->numframes); - numframes = pheader->numframes; - if (numframes < 1) - Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); - - pheader->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; - mod->synctype = LittleLong (pinmodel->synctype); - mod->numframes = pheader->numframes; - - for (i=0 ; i<3 ; i++) - { - pheader->scale[i] = LittleFloat (pinmodel->scale[i]); - pheader->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]); - pheader->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]); - } - - -// -// load the skins -// - pskintype = (daliasskintype_t *)&pinmodel[1]; - pskintype = Mod_LoadAllSkins (pheader->numskins, pskintype); - -// -// load base s and t vertices -// - pinstverts = (stvert_t *)pskintype; - - for (i=0 ; inumverts ; i++) - { - stverts[i].onseam = LittleLong (pinstverts[i].onseam); - stverts[i].s = LittleLong (pinstverts[i].s); - stverts[i].t = LittleLong (pinstverts[i].t); - } - -// -// load triangle lists -// - pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts]; - - for (i=0 ; inumtris ; i++) - { - triangles[i].facesfront = LittleLong (pintriangles[i].facesfront); - - for (j=0 ; j<3 ; j++) - { - triangles[i].vertindex[j] = - LittleLong (pintriangles[i].vertindex[j]); - } - } - -// -// load the frames -// - posenum = 0; - pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris]; - - for (i=0 ; itype); - - if (frametype == ALIAS_SINGLE) - { - pframetype = (daliasframetype_t *) - Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]); - } - else - { - pframetype = (daliasframetype_t *) - Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i]); - } - } - - pheader->numposes = posenum; - - mod->type = mod_alias; - -// FIXME: do this right - mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; - mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; - - // - // build the draw lists - // - GL_MakeAliasModelDisplayLists (mod, pheader); - -// -// move the complete, relocatable alias model to the cache -// - end = Hunk_LowMark (); - total = end - start; - - Cache_Alloc (&mod->cache, total, loadname); - if (!mod->cache.data) - return; - memcpy (mod->cache.data, pheader, total); - - Hunk_FreeToLowMark (start); -} - -//============================================================================= - -/* -================= -Mod_LoadSpriteFrame -================= -*/ -void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum) -{ - dspriteframe_t *pinframe; - mspriteframe_t *pspriteframe; - int width, height, size, origin[2]; - char name[64]; - - pinframe = (dspriteframe_t *)pin; - - width = LittleLong (pinframe->width); - height = LittleLong (pinframe->height); - size = width * height; - - pspriteframe = Hunk_AllocName (sizeof (mspriteframe_t),loadname); - - memset (pspriteframe, 0, sizeof (mspriteframe_t)); - - *ppframe = pspriteframe; - - pspriteframe->width = width; - pspriteframe->height = height; - origin[0] = LittleLong (pinframe->origin[0]); - origin[1] = LittleLong (pinframe->origin[1]); - - pspriteframe->up = origin[1]; - pspriteframe->down = origin[1] - height; - pspriteframe->left = origin[0]; - pspriteframe->right = width + origin[0]; - - snprintf (name, sizeof(name), "%s_%i", loadmodel->name, framenum); - pspriteframe->gl_texturenum = GL_LoadTexture (name, width, height, (byte *)(pinframe + 1), true, true, 1); - - return (void *)((byte *)pinframe + sizeof (dspriteframe_t) + size); -} - - -/* -================= -Mod_LoadSpriteGroup -================= -*/ -void * Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum) -{ - dspritegroup_t *pingroup; - mspritegroup_t *pspritegroup; - int i, numframes; - dspriteinterval_t *pin_intervals; - float *poutintervals; - void *ptemp; - - pingroup = (dspritegroup_t *)pin; - - numframes = LittleLong (pingroup->numframes); - - pspritegroup = Hunk_AllocName (sizeof (mspritegroup_t) + - (numframes - 1) * sizeof (pspritegroup->frames[0]), loadname); - - pspritegroup->numframes = numframes; - - *ppframe = (mspriteframe_t *)pspritegroup; - - pin_intervals = (dspriteinterval_t *)(pingroup + 1); - - poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname); - - pspritegroup->intervals = poutintervals; - - for (i=0 ; iinterval); - if (*poutintervals <= 0.0) - Sys_Error ("Mod_LoadSpriteGroup: interval<=0"); - - poutintervals++; - pin_intervals++; - } - - ptemp = (void *)pin_intervals; - - for (i=0 ; iframes[i], framenum * 100 + i); - } - - return ptemp; -} - - -/* -================= -Mod_LoadSpriteModel -================= -*/ -void Mod_LoadSpriteModel (model_t *mod, void *buffer) -{ - int i; - int version; - dsprite_t *pin; - msprite_t *psprite; - int numframes; - int size; - dspriteframetype_t *pframetype; - - pin = (dsprite_t *)buffer; - - version = LittleLong (pin->version); - if (version != SPRITE_VERSION) - Sys_Error ("%s has wrong version number " - "(%i should be %i)", mod->name, version, SPRITE_VERSION); - - numframes = LittleLong (pin->numframes); - - size = sizeof (msprite_t) + (numframes - 1) * sizeof (psprite->frames); - - psprite = Hunk_AllocName (size, loadname); - - mod->cache.data = psprite; - - psprite->type = LittleLong (pin->type); - psprite->maxwidth = LittleLong (pin->width); - psprite->maxheight = LittleLong (pin->height); - psprite->beamlength = LittleFloat (pin->beamlength); - mod->synctype = LittleLong (pin->synctype); - psprite->numframes = numframes; - - mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2; - mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2; - mod->mins[2] = -psprite->maxheight/2; - mod->maxs[2] = psprite->maxheight/2; - -// -// load the frames -// - if (numframes < 1) - Sys_Error ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes); - - mod->numframes = numframes; - - pframetype = (dspriteframetype_t *)(pin + 1); - - for (i=0 ; itype); - psprite->frames[i].type = frametype; - - if (frametype == SPR_SINGLE) - { - pframetype = (dspriteframetype_t *) - Mod_LoadSpriteFrame (pframetype + 1, - &psprite->frames[i].frameptr, i); - } - else - { - pframetype = (dspriteframetype_t *) - Mod_LoadSpriteGroup (pframetype + 1, - &psprite->frames[i].frameptr, i); - } - } - - mod->type = mod_sprite; -} - -//============================================================================= - -/* -================ -Mod_Print -================ -*/ -void Mod_Print (void) -{ - int i; - model_t *mod; - - Con_Printf ("Cached models:\n"); - for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++) - { - Con_Printf ("%8p : %s\n",mod->cache.data, mod->name); - } -} - - diff --git a/source/gl_model_sprite.c b/source/gl_model_sprite.c new file mode 100644 index 0000000..5f8aad2 --- /dev/null +++ b/source/gl_model_sprite.c @@ -0,0 +1,210 @@ +/* + gl_model.c + + model loading and caching + + Copyright (C) 1996-1997 Id Software, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + + $Id$ +*/ + +// models are the only shared resource between a client and server running +// on the same machine. + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "r_local.h" +#include "sys.h" +#include "console.h" +#include "qendian.h" +#include "checksum.h" +#include "glquake.h" + +/* +================= +Mod_LoadSpriteFrame +================= +*/ +void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum) +{ + dspriteframe_t *pinframe; + mspriteframe_t *pspriteframe; + int width, height, size, origin[2]; + char name[64]; + + pinframe = (dspriteframe_t *)pin; + + width = LittleLong (pinframe->width); + height = LittleLong (pinframe->height); + size = width * height; + + pspriteframe = Hunk_AllocName (sizeof (mspriteframe_t),loadname); + + memset (pspriteframe, 0, sizeof (mspriteframe_t)); + + *ppframe = pspriteframe; + + pspriteframe->width = width; + pspriteframe->height = height; + origin[0] = LittleLong (pinframe->origin[0]); + origin[1] = LittleLong (pinframe->origin[1]); + + pspriteframe->up = origin[1]; + pspriteframe->down = origin[1] - height; + pspriteframe->left = origin[0]; + pspriteframe->right = width + origin[0]; + + snprintf (name, sizeof(name), "%s_%i", loadmodel->name, framenum); + pspriteframe->gl_texturenum = GL_LoadTexture (name, width, height, (byte *)(pinframe + 1), true, true, 1); + + return (void *)((byte *)pinframe + sizeof (dspriteframe_t) + size); +} + + +/* +================= +Mod_LoadSpriteGroup +================= +*/ +void * Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum) +{ + dspritegroup_t *pingroup; + mspritegroup_t *pspritegroup; + int i, numframes; + dspriteinterval_t *pin_intervals; + float *poutintervals; + void *ptemp; + + pingroup = (dspritegroup_t *)pin; + + numframes = LittleLong (pingroup->numframes); + + pspritegroup = Hunk_AllocName (sizeof (mspritegroup_t) + + (numframes - 1) * sizeof (pspritegroup->frames[0]), loadname); + + pspritegroup->numframes = numframes; + + *ppframe = (mspriteframe_t *)pspritegroup; + + pin_intervals = (dspriteinterval_t *)(pingroup + 1); + + poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname); + + pspritegroup->intervals = poutintervals; + + for (i=0 ; iinterval); + if (*poutintervals <= 0.0) + Sys_Error ("Mod_LoadSpriteGroup: interval<=0"); + + poutintervals++; + pin_intervals++; + } + + ptemp = (void *)pin_intervals; + + for (i=0 ; iframes[i], framenum * 100 + i); + } + + return ptemp; +} + + +/* +================= +Mod_LoadSpriteModel +================= +*/ +void Mod_LoadSpriteModel (model_t *mod, void *buffer) +{ + int i; + int version; + dsprite_t *pin; + msprite_t *psprite; + int numframes; + int size; + dspriteframetype_t *pframetype; + + pin = (dsprite_t *)buffer; + + version = LittleLong (pin->version); + if (version != SPRITE_VERSION) + Sys_Error ("%s has wrong version number " + "(%i should be %i)", mod->name, version, SPRITE_VERSION); + + numframes = LittleLong (pin->numframes); + + size = sizeof (msprite_t) + (numframes - 1) * sizeof (psprite->frames); + + psprite = Hunk_AllocName (size, loadname); + + mod->cache.data = psprite; + + psprite->type = LittleLong (pin->type); + psprite->maxwidth = LittleLong (pin->width); + psprite->maxheight = LittleLong (pin->height); + psprite->beamlength = LittleFloat (pin->beamlength); + mod->synctype = LittleLong (pin->synctype); + psprite->numframes = numframes; + + mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2; + mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2; + mod->mins[2] = -psprite->maxheight/2; + mod->maxs[2] = psprite->maxheight/2; + +// +// load the frames +// + if (numframes < 1) + Sys_Error ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes); + + mod->numframes = numframes; + + pframetype = (dspriteframetype_t *)(pin + 1); + + for (i=0 ; itype); + psprite->frames[i].type = frametype; + + if (frametype == SPR_SINGLE) + { + pframetype = (dspriteframetype_t *) + Mod_LoadSpriteFrame (pframetype + 1, + &psprite->frames[i].frameptr, i); + } + else + { + pframetype = (dspriteframetype_t *) + Mod_LoadSpriteGroup (pframetype + 1, + &psprite->frames[i].frameptr, i); + } + } + + mod->type = mod_sprite; +} diff --git a/source/model.c b/source/model.c index c3960d4..af48d14 100644 --- a/source/model.c +++ b/source/model.c @@ -26,6 +26,9 @@ $Id$ */ +// models are the only shared resource between a client and server running +// on the same machine. + #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -65,89 +68,6 @@ void Mod_Init (void) memset (mod_novis, 0xff, sizeof(mod_novis)); } -/* -=============== -Mod_PointInLeaf -=============== -*/ -mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model) -{ - mnode_t *node; - float d; - mplane_t *plane; - - if (!model || !model->nodes) - Sys_Error ("Mod_PointInLeaf: bad model"); - - node = model->nodes; - while (1) - { - if (node->contents < 0) - return (mleaf_t *)node; - plane = node->plane; - d = DotProduct (p, plane->normal) - plane->dist; - if (d > 0) - node = node->children[0]; - else - node = node->children[1]; - } - - return NULL; // never reached -} - - -/* -=================== -Mod_DecompressVis -=================== -*/ -byte *Mod_DecompressVis (byte *in, model_t *model) -{ - static byte decompressed[MAX_MAP_LEAFS/8]; - int c; - byte *out; - int row; - - row = (model->numleafs+7)>>3; - out = decompressed; - - if (!in) - { // no vis info, so make all visible - while (row) - { - *out++ = 0xff; - row--; - } - return decompressed; - } - - do - { - if (*in) - { - *out++ = *in++; - continue; - } - - c = in[1]; - in += 2; - while (c) - { - *out++ = 0; - c--; - } - } while (out - decompressed < row); - - return decompressed; -} - -byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model) -{ - if (leaf == model->leafs) - return mod_novis; - return Mod_DecompressVis (leaf->compressed_vis, model); -} - /* =================== Mod_ClearAll @@ -281,906 +201,6 @@ model_t *Mod_ForName (char *name, qboolean crash) return Mod_LoadModel (mod, crash); } - -/* -=============================================================================== - - BRUSHMODEL LOADING - -=============================================================================== -*/ - -byte *mod_base; - - -/* -================= -Mod_LoadTextures -================= -*/ -void Mod_LoadTextures (lump_t *l) -{ - int i, j, pixels, num, max, altmax; - miptex_t *mt; - texture_t *tx, *tx2; - texture_t *anims[10]; - texture_t *altanims[10]; - dmiptexlump_t *m; - - if (!l->filelen) - { - loadmodel->textures = NULL; - return; - } - m = (dmiptexlump_t *)(mod_base + l->fileofs); - - m->nummiptex = LittleLong (m->nummiptex); - - loadmodel->numtextures = m->nummiptex; - loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname); - - for (i=0 ; inummiptex ; i++) - { - m->dataofs[i] = LittleLong(m->dataofs[i]); - if (m->dataofs[i] == -1) - continue; - mt = (miptex_t *)((byte *)m + m->dataofs[i]); - mt->width = LittleLong (mt->width); - mt->height = LittleLong (mt->height); - for (j=0 ; joffsets[j] = LittleLong (mt->offsets[j]); - - if ( (mt->width & 15) || (mt->height & 15) ) - Sys_Error ("Texture %s is not 16 aligned", mt->name); - pixels = mt->width*mt->height/64*85; - tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname ); - loadmodel->textures[i] = tx; - - memcpy (tx->name, mt->name, sizeof(tx->name)); - tx->width = mt->width; - tx->height = mt->height; - for (j=0 ; joffsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t); - // the pixels immediately follow the structures - memcpy ( tx+1, mt+1, pixels); - - if (!strncmp(mt->name,"sky",3)) - R_InitSky (tx); - } - -// -// sequence the animations -// - for (i=0 ; inummiptex ; i++) - { - tx = loadmodel->textures[i]; - if (!tx || tx->name[0] != '+') - continue; - if (tx->anim_next) - continue; // allready sequenced - - // find the number of frames in the animation - memset (anims, 0, sizeof(anims)); - memset (altanims, 0, sizeof(altanims)); - - max = tx->name[1]; - altmax = 0; - if (max >= 'a' && max <= 'z') - max -= 'a' - 'A'; - if (max >= '0' && max <= '9') - { - max -= '0'; - altmax = 0; - anims[max] = tx; - max++; - } - else if (max >= 'A' && max <= 'J') - { - altmax = max - 'A'; - max = 0; - altanims[altmax] = tx; - altmax++; - } - else - Sys_Error ("Bad animating texture %s", tx->name); - - for (j=i+1 ; jnummiptex ; j++) - { - tx2 = loadmodel->textures[j]; - if (!tx2 || tx2->name[0] != '+') - continue; - if (strcmp (tx2->name+2, tx->name+2)) - continue; - - num = tx2->name[1]; - if (num >= 'a' && num <= 'z') - num -= 'a' - 'A'; - if (num >= '0' && num <= '9') - { - num -= '0'; - anims[num] = tx2; - if (num+1 > max) - max = num + 1; - } - else if (num >= 'A' && num <= 'J') - { - num = num - 'A'; - altanims[num] = tx2; - if (num+1 > altmax) - altmax = num+1; - } - else - Sys_Error ("Bad animating texture %s", tx->name); - } - -#define ANIM_CYCLE 2 - // link them all together - for (j=0 ; jname); - tx2->anim_total = max * ANIM_CYCLE; - tx2->anim_min = j * ANIM_CYCLE; - tx2->anim_max = (j+1) * ANIM_CYCLE; - tx2->anim_next = anims[ (j+1)%max ]; - if (altmax) - tx2->alternate_anims = altanims[0]; - } - for (j=0 ; jname); - tx2->anim_total = altmax * ANIM_CYCLE; - tx2->anim_min = j * ANIM_CYCLE; - tx2->anim_max = (j+1) * ANIM_CYCLE; - tx2->anim_next = altanims[ (j+1)%altmax ]; - if (max) - tx2->alternate_anims = anims[0]; - } - } -} - -/* -================= -Mod_LoadLighting -================= -*/ -void Mod_LoadLighting (lump_t *l) -{ - if (!l->filelen) - { - loadmodel->lightdata = NULL; - return; - } - loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname); - memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen); -} - - -/* -================= -Mod_LoadVisibility -================= -*/ -void Mod_LoadVisibility (lump_t *l) -{ - if (!l->filelen) - { - loadmodel->visdata = NULL; - return; - } - loadmodel->visdata = Hunk_AllocName ( l->filelen, loadname); - memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen); -} - - -/* -================= -Mod_LoadEntities -================= -*/ -void Mod_LoadEntities (lump_t *l) -{ - if (!l->filelen) - { - loadmodel->entities = NULL; - return; - } - loadmodel->entities = Hunk_AllocName ( l->filelen, loadname); - memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen); -} - - -/* -================= -Mod_LoadVertexes -================= -*/ -void Mod_LoadVertexes (lump_t *l) -{ - dvertex_t *in; - mvertex_t *out; - int i, count; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->vertexes = out; - loadmodel->numvertexes = count; - - for ( i=0 ; iposition[0] = LittleFloat (in->point[0]); - out->position[1] = LittleFloat (in->point[1]); - out->position[2] = LittleFloat (in->point[2]); - } -} - -/* -================= -Mod_LoadSubmodels -================= -*/ -void Mod_LoadSubmodels (lump_t *l) -{ - dmodel_t *in; - dmodel_t *out; - int i, j, count; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->submodels = out; - loadmodel->numsubmodels = count; - - for ( i=0 ; imins[j] = LittleFloat (in->mins[j]) - 1; - out->maxs[j] = LittleFloat (in->maxs[j]) + 1; - out->origin[j] = LittleFloat (in->origin[j]); - } - for (j=0 ; jheadnode[j] = LittleLong (in->headnode[j]); - out->visleafs = LittleLong (in->visleafs); - out->firstface = LittleLong (in->firstface); - out->numfaces = LittleLong (in->numfaces); - } -} - -/* -================= -Mod_LoadEdges -================= -*/ -void Mod_LoadEdges (lump_t *l) -{ - dedge_t *in; - medge_t *out; - int i, count; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( (count + 1) * sizeof(*out), loadname); - - loadmodel->edges = out; - loadmodel->numedges = count; - - for ( i=0 ; iv[0] = (unsigned short)LittleShort(in->v[0]); - out->v[1] = (unsigned short)LittleShort(in->v[1]); - } -} - -/* -================= -Mod_LoadTexinfo -================= -*/ -void Mod_LoadTexinfo (lump_t *l) -{ - texinfo_t *in; - mtexinfo_t *out; - int i, j, count; - int miptex; - float len1, len2; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->texinfo = out; - loadmodel->numtexinfo = count; - - for ( i=0 ; ivecs[0][j] = LittleFloat (in->vecs[0][j]); - out->vecs[1][j] = LittleFloat (in->vecs[1][j]); - } - len1 = Length (out->vecs[0]); - len2 = Length (out->vecs[1]); - - len1 = (len1 + len2)/2; - if (len1 < 0.32) - out->mipadjust = 4; - else if (len1 < 0.49) - out->mipadjust = 3; - else if (len1 < 0.99) - out->mipadjust = 2; - else - out->mipadjust = 1; - - miptex = LittleLong (in->miptex); - out->flags = LittleLong (in->flags); - - if (!loadmodel->textures) - { - out->texture = r_notexture_mip; // checkerboard texture - out->flags = 0; - } - else - { - if (miptex >= loadmodel->numtextures) - Sys_Error ("miptex >= loadmodel->numtextures"); - out->texture = loadmodel->textures[miptex]; - if (!out->texture) - { - out->texture = r_notexture_mip; // texture not found - out->flags = 0; - } - } - } -} - -/* -================ -CalcSurfaceExtents - -Fills in s->texturemins[] and s->extents[] -================ -*/ -void CalcSurfaceExtents (msurface_t *s) -{ - float mins[2], maxs[2], val; - int i,j, e; - mvertex_t *v; - mtexinfo_t *tex; - int bmins[2], bmaxs[2]; - - mins[0] = mins[1] = 999999; - maxs[0] = maxs[1] = -99999; - - tex = s->texinfo; - - for (i=0 ; inumedges ; i++) - { - e = loadmodel->surfedges[s->firstedge+i]; - if (e >= 0) - v = &loadmodel->vertexes[loadmodel->edges[e].v[0]]; - else - v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]]; - - for (j=0 ; j<2 ; j++) - { - val = v->position[0] * tex->vecs[j][0] + - v->position[1] * tex->vecs[j][1] + - v->position[2] * tex->vecs[j][2] + - tex->vecs[j][3]; - if (val < mins[j]) - mins[j] = val; - if (val > maxs[j]) - maxs[j] = val; - } - } - - for (i=0 ; i<2 ; i++) - { - bmins[i] = floor(mins[i]/16); - bmaxs[i] = ceil(maxs[i]/16); - - s->texturemins[i] = bmins[i] * 16; - s->extents[i] = (bmaxs[i] - bmins[i]) * 16; - if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 512 /* 256 */ ) - Sys_Error ("Bad surface extents"); - } -} - - -/* -================= -Mod_LoadFaces -================= -*/ -void Mod_LoadFaces (lump_t *l) -{ - dface_t *in; - msurface_t *out; - int i, count, surfnum; - int planenum, side; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->surfaces = out; - loadmodel->numsurfaces = count; - - for ( surfnum=0 ; surfnumfirstedge = LittleLong(in->firstedge); - out->numedges = LittleShort(in->numedges); - out->flags = 0; - - planenum = LittleShort(in->planenum); - side = LittleShort(in->side); - if (side) - out->flags |= SURF_PLANEBACK; - - out->plane = loadmodel->planes + planenum; - - out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo); - - CalcSurfaceExtents (out); - - // lighting info - - for (i=0 ; istyles[i] = in->styles[i]; - i = LittleLong(in->lightofs); - if (i == -1) - out->samples = NULL; - else - out->samples = loadmodel->lightdata + i; - - // set the drawing flags flag - - if (!strncmp(out->texinfo->texture->name,"sky",3)) // sky - { - out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED); - continue; - } - - if (!strncmp(out->texinfo->texture->name,"*",1)) // turbulent - { - out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED); - for (i=0 ; i<2 ; i++) - { - out->extents[i] = 16384; - out->texturemins[i] = -8192; - } - continue; - } - } -} - - -/* -================= -Mod_SetParent -================= -*/ -void Mod_SetParent (mnode_t *node, mnode_t *parent) -{ - node->parent = parent; - if (node->contents < 0) - return; - Mod_SetParent (node->children[0], node); - Mod_SetParent (node->children[1], node); -} - -/* -================= -Mod_LoadNodes -================= -*/ -void Mod_LoadNodes (lump_t *l) -{ - int i, j, count, p; - dnode_t *in; - mnode_t *out; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->nodes = out; - loadmodel->numnodes = count; - - for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); - out->minmaxs[3+j] = LittleShort (in->maxs[j]); - } - - p = LittleLong(in->planenum); - out->plane = loadmodel->planes + p; - - out->firstsurface = LittleShort (in->firstface); - out->numsurfaces = LittleShort (in->numfaces); - - for (j=0 ; j<2 ; j++) - { - p = LittleShort (in->children[j]); - if (p >= 0) - out->children[j] = loadmodel->nodes + p; - else - out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p)); - } - } - - Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs -} - -/* -================= -Mod_LoadLeafs -================= -*/ -void Mod_LoadLeafs (lump_t *l) -{ - dleaf_t *in; - mleaf_t *out; - int i, j, count, p; - qboolean isnotmap = true; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->leafs = out; - loadmodel->numleafs = count; - if (!strncmp("maps/", loadmodel->name,5)) - isnotmap = false; - for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); - out->minmaxs[3+j] = LittleShort (in->maxs[j]); - } - - p = LittleLong(in->contents); - out->contents = p; - - out->firstmarksurface = loadmodel->marksurfaces + - LittleShort(in->firstmarksurface); - out->nummarksurfaces = LittleShort(in->nummarksurfaces); - - p = LittleLong(in->visofs); - if (p == -1) - out->compressed_vis = NULL; - else - out->compressed_vis = loadmodel->visdata + p; - out->efrags = NULL; - - for (j=0 ; j<4 ; j++) - out->ambient_sound_level[j] = in->ambient_level[j]; - } -} - -/* -================= -Mod_LoadClipnodes -================= -*/ -void Mod_LoadClipnodes (lump_t *l) -{ - dclipnode_t *in, *out; - int i, count; - hull_t *hull; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->clipnodes = out; - loadmodel->numclipnodes = count; - - hull = &loadmodel->hulls[1]; - hull->clipnodes = out; - hull->firstclipnode = 0; - hull->lastclipnode = count-1; - hull->planes = loadmodel->planes; - hull->clip_mins[0] = -16; - hull->clip_mins[1] = -16; - hull->clip_mins[2] = -24; - hull->clip_maxs[0] = 16; - hull->clip_maxs[1] = 16; - hull->clip_maxs[2] = 32; - - hull = &loadmodel->hulls[2]; - hull->clipnodes = out; - hull->firstclipnode = 0; - hull->lastclipnode = count-1; - hull->planes = loadmodel->planes; - hull->clip_mins[0] = -32; - hull->clip_mins[1] = -32; - hull->clip_mins[2] = -24; - hull->clip_maxs[0] = 32; - hull->clip_maxs[1] = 32; - hull->clip_maxs[2] = 64; - - for (i=0 ; iplanenum = LittleLong(in->planenum); - out->children[0] = LittleShort(in->children[0]); - out->children[1] = LittleShort(in->children[1]); - } -} - -/* -================= -Mod_MakeHull0 - -Deplicate the drawing hull structure as a clipping hull -================= -*/ -void Mod_MakeHull0 (void) -{ - mnode_t *in, *child; - dclipnode_t *out; - int i, j, count; - hull_t *hull; - - hull = &loadmodel->hulls[0]; - - in = loadmodel->nodes; - count = loadmodel->numnodes; - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - hull->clipnodes = out; - hull->firstclipnode = 0; - hull->lastclipnode = count-1; - hull->planes = loadmodel->planes; - - for (i=0 ; iplanenum = in->plane - loadmodel->planes; - for (j=0 ; j<2 ; j++) - { - child = in->children[j]; - if (child->contents < 0) - out->children[j] = child->contents; - else - out->children[j] = child - loadmodel->nodes; - } - } -} - -/* -================= -Mod_LoadMarksurfaces -================= -*/ -void Mod_LoadMarksurfaces (lump_t *l) -{ - int i, j, count; - short *in; - msurface_t **out; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->marksurfaces = out; - loadmodel->nummarksurfaces = count; - - for ( i=0 ; i= loadmodel->numsurfaces) - Sys_Error ("Mod_ParseMarksurfaces: bad surface number"); - out[i] = loadmodel->surfaces + j; - } -} - -/* -================= -Mod_LoadSurfedges -================= -*/ -void Mod_LoadSurfedges (lump_t *l) -{ - int i, count; - int *in, *out; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->surfedges = out; - loadmodel->numsurfedges = count; - - for ( i=0 ; ifileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*2*sizeof(*out), loadname); - - loadmodel->planes = out; - loadmodel->numplanes = count; - - for ( i=0 ; inormal[j] = LittleFloat (in->normal[j]); - if (out->normal[j] < 0) - bits |= 1<dist = LittleFloat (in->dist); - out->type = LittleLong (in->type); - out->signbits = bits; - } -} - -/* -================= -RadiusFromBounds -================= -*/ -float RadiusFromBounds (vec3_t mins, vec3_t maxs) -{ - int i; - vec3_t corner; - - for (i=0 ; i<3 ; i++) - { - corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]); - } - - return Length (corner); -} - -/* -================= -Mod_LoadBrushModel -================= -*/ -void Mod_LoadBrushModel (model_t *mod, void *buffer) -{ - int i, j; - dheader_t *header; - dmodel_t *bm; - - loadmodel->type = mod_brush; - - header = (dheader_t *)buffer; - - i = LittleLong (header->version); - if (i != BSPVERSION) - Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION); - -// swap all the lumps - mod_base = (byte *)header; - - for (i=0 ; ichecksum = 0; - mod->checksum2 = 0; - - for (i = 0; i < HEADER_LUMPS; i++) { - if (i == LUMP_ENTITIES) - continue; - mod->checksum ^= LittleLong(Com_BlockChecksum(mod_base + header->lumps[i].fileofs, - header->lumps[i].filelen)); - - if (i == LUMP_VISIBILITY || i == LUMP_LEAFS || i == LUMP_NODES) - continue; - mod->checksum2 ^= LittleLong(Com_BlockChecksum(mod_base + header->lumps[i].fileofs, - header->lumps[i].filelen)); - } - -// load into heap - - Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]); - Mod_LoadEdges (&header->lumps[LUMP_EDGES]); - Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]); - Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]); - Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); - Mod_LoadPlanes (&header->lumps[LUMP_PLANES]); - Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); - Mod_LoadFaces (&header->lumps[LUMP_FACES]); - Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]); - Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); - Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]); - Mod_LoadNodes (&header->lumps[LUMP_NODES]); - Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]); - Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]); - Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]); - - Mod_MakeHull0 (); - - mod->numframes = 2; // regular and alternate animation - mod->flags = 0; - -// -// set up the submodels (FIXME: this is confusing) -// - for (i=0 ; inumsubmodels ; i++) - { - bm = &mod->submodels[i]; - - mod->hulls[0].firstclipnode = bm->headnode[0]; - for (j=1 ; jhulls[j].firstclipnode = bm->headnode[j]; - mod->hulls[j].lastclipnode = mod->numclipnodes-1; - } - - mod->firstmodelsurface = bm->firstface; - mod->nummodelsurfaces = bm->numfaces; - - VectorCopy (bm->maxs, mod->maxs); - VectorCopy (bm->mins, mod->mins); - - mod->radius = RadiusFromBounds (mod->mins, mod->maxs); - - mod->numleafs = bm->visleafs; - - if (i < mod->numsubmodels-1) - { // duplicate the basic information - char name[10]; - - snprintf (name, sizeof(name), "*%i", i+1); - loadmodel = Mod_FindName (name); - *loadmodel = *mod; - strcpy (loadmodel->name, name); - mod = loadmodel; - } - } -} - /* =============== Mod_Extradata @@ -1222,636 +242,6 @@ void Mod_TouchModel (char *name) } } -/* -============================================================================== - -ALIAS MODELS - -============================================================================== -*/ - -/* -================= -Mod_LoadAliasFrame -================= -*/ -void * Mod_LoadAliasFrame (void * pin, int *pframeindex, int numv, - trivertx_t *pbboxmin, trivertx_t *pbboxmax, aliashdr_t *pheader, char *name) -{ - trivertx_t *pframe, *pinframe; - int i, j; - daliasframe_t *pdaliasframe; - - pdaliasframe = (daliasframe_t *)pin; - - strcpy (name, pdaliasframe->name); - - for (i=0 ; i<3 ; i++) - { - // these are byte values, so we don't have to worry about - // endianness - pbboxmin->v[i] = pdaliasframe->bboxmin.v[i]; - pbboxmax->v[i] = pdaliasframe->bboxmax.v[i]; - } - - pinframe = (trivertx_t *)(pdaliasframe + 1); - pframe = Hunk_AllocName (numv * sizeof(*pframe), loadname); - - *pframeindex = (byte *)pframe - (byte *)pheader; - - for (j=0 ; jnumframes); - - paliasgroup = Hunk_AllocName (sizeof (maliasgroup_t) + - (numframes - 1) * sizeof (paliasgroup->frames[0]), loadname); - - paliasgroup->numframes = numframes; - - for (i=0 ; i<3 ; i++) - { - // these are byte values, so we don't have to worry about endianness - pbboxmin->v[i] = pingroup->bboxmin.v[i]; - pbboxmax->v[i] = pingroup->bboxmax.v[i]; - } - - *pframeindex = (byte *)paliasgroup - (byte *)pheader; - - pin_intervals = (daliasinterval_t *)(pingroup + 1); - - poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname); - - paliasgroup->intervals = (byte *)poutintervals - (byte *)pheader; - - for (i=0 ; iinterval); - if (*poutintervals <= 0.0) - Sys_Error ("Mod_LoadAliasGroup: interval<=0"); - - poutintervals++; - pin_intervals++; - } - - ptemp = (void *)pin_intervals; - - for (i=0 ; iframes[i].frame, - numv, - &paliasgroup->frames[i].bboxmin, - &paliasgroup->frames[i].bboxmax, - pheader, name); - } - - return ptemp; -} - - -/* -================= -Mod_LoadAliasSkin -================= -*/ -void * Mod_LoadAliasSkin (void * pin, int *pskinindex, int skinsize, - aliashdr_t *pheader) -{ - int i; - byte *pskin, *pinskin; - unsigned short *pusskin; - - pskin = Hunk_AllocName (skinsize * r_pixbytes, loadname); - pinskin = (byte *)pin; - *pskinindex = (byte *)pskin - (byte *)pheader; - - if (r_pixbytes == 1) - { - memcpy (pskin, pinskin, skinsize); - } - else if (r_pixbytes == 2) - { - pusskin = (unsigned short *)pskin; - - for (i=0 ; inumskins); - - paliasskingroup = Hunk_AllocName (sizeof (maliasskingroup_t) + - (numskins - 1) * sizeof (paliasskingroup->skindescs[0]), - loadname); - - paliasskingroup->numskins = numskins; - - *pskinindex = (byte *)paliasskingroup - (byte *)pheader; - - pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1); - - poutskinintervals = Hunk_AllocName (numskins * sizeof (float),loadname); - - paliasskingroup->intervals = (byte *)poutskinintervals - (byte *)pheader; - - for (i=0 ; iinterval); - if (*poutskinintervals <= 0) - Sys_Error ("Mod_LoadAliasSkinGroup: interval<=0"); - - poutskinintervals++; - pinskinintervals++; - } - - ptemp = (void *)pinskinintervals; - - for (i=0 ; iskindescs[i].skin, skinsize, pheader); - } - - return ptemp; -} - - -/* -================= -Mod_LoadAliasModel -================= -*/ -void Mod_LoadAliasModel (model_t *mod, void *buffer) -{ - int i; - mdl_t *pmodel, *pinmodel; - stvert_t *pstverts, *pinstverts; - aliashdr_t *pheader; - mtriangle_t *ptri; - dtriangle_t *pintriangles; - int version, numframes, numskins; - int size; - daliasframetype_t *pframetype; - daliasskintype_t *pskintype; - maliasskindesc_t *pskindesc; - int skinsize; - int start, end, total; - - start = Hunk_LowMark (); - - pinmodel = (mdl_t *)buffer; - - version = LittleLong (pinmodel->version); - if (version != ALIAS_VERSION) - Sys_Error ("%s has wrong version number (%i should be %i)", - mod->name, version, ALIAS_VERSION); - -// -// allocate space for a working header, plus all the data except the frames, -// skin and group info -// - size = sizeof (aliashdr_t) + (LittleLong (pinmodel->numframes) - 1) * - sizeof (pheader->frames[0]) + - sizeof (mdl_t) + - LittleLong (pinmodel->numverts) * sizeof (stvert_t) + - LittleLong (pinmodel->numtris) * sizeof (mtriangle_t); - - pheader = Hunk_AllocName (size, loadname); - pmodel = (mdl_t *) ((byte *)&pheader[1] + - (LittleLong (pinmodel->numframes) - 1) * - sizeof (pheader->frames[0])); - -// mod->cache.data = pheader; - mod->flags = LittleLong (pinmodel->flags); - -// -// endian-adjust and copy the data, starting with the alias model header -// - pmodel->boundingradius = LittleFloat (pinmodel->boundingradius); - pmodel->numskins = LittleLong (pinmodel->numskins); - pmodel->skinwidth = LittleLong (pinmodel->skinwidth); - pmodel->skinheight = LittleLong (pinmodel->skinheight); - - if (pmodel->skinheight > MAX_LBM_HEIGHT) - Sys_Error ("model %s has a skin taller than %d", mod->name, - MAX_LBM_HEIGHT); - - pmodel->numverts = LittleLong (pinmodel->numverts); - - if (pmodel->numverts <= 0) - Sys_Error ("model %s has no vertices", mod->name); - - if (pmodel->numverts > MAXALIASVERTS) - Sys_Error ("model %s has too many vertices", mod->name); - - pmodel->numtris = LittleLong (pinmodel->numtris); - - if (pmodel->numtris <= 0) - Sys_Error ("model %s has no triangles", mod->name); - - pmodel->numframes = LittleLong (pinmodel->numframes); - pmodel->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; - mod->synctype = LittleLong (pinmodel->synctype); - mod->numframes = pmodel->numframes; - - for (i=0 ; i<3 ; i++) - { - pmodel->scale[i] = LittleFloat (pinmodel->scale[i]); - pmodel->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]); - pmodel->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]); - } - - numskins = pmodel->numskins; - numframes = pmodel->numframes; - - if (pmodel->skinwidth & 0x03) - Sys_Error ("Mod_LoadAliasModel: skinwidth not multiple of 4"); - - pheader->model = (byte *)pmodel - (byte *)pheader; - -// -// load the skins -// - skinsize = pmodel->skinheight * pmodel->skinwidth; - - if (numskins < 1) - Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins); - - pskintype = (daliasskintype_t *)&pinmodel[1]; - - pskindesc = Hunk_AllocName (numskins * sizeof (maliasskindesc_t), - loadname); - - pheader->skindesc = (byte *)pskindesc - (byte *)pheader; - - for (i=0 ; itype); - pskindesc[i].type = skintype; - - if (skintype == ALIAS_SKIN_SINGLE) - { - pskintype = (daliasskintype_t *) - Mod_LoadAliasSkin (pskintype + 1, - &pskindesc[i].skin, - skinsize, pheader); - } - else - { - pskintype = (daliasskintype_t *) - Mod_LoadAliasSkinGroup (pskintype + 1, - &pskindesc[i].skin, - skinsize, pheader); - } - } - -// -// set base s and t vertices -// - pstverts = (stvert_t *)&pmodel[1]; - pinstverts = (stvert_t *)pskintype; - - pheader->stverts = (byte *)pstverts - (byte *)pheader; - - for (i=0 ; inumverts ; i++) - { - pstverts[i].onseam = LittleLong (pinstverts[i].onseam); - // put s and t in 16.16 format - pstverts[i].s = LittleLong (pinstverts[i].s) << 16; - pstverts[i].t = LittleLong (pinstverts[i].t) << 16; - } - -// -// set up the triangles -// - ptri = (mtriangle_t *)&pstverts[pmodel->numverts]; - pintriangles = (dtriangle_t *)&pinstverts[pmodel->numverts]; - - pheader->triangles = (byte *)ptri - (byte *)pheader; - - for (i=0 ; inumtris ; i++) - { - int j; - - ptri[i].facesfront = LittleLong (pintriangles[i].facesfront); - - for (j=0 ; j<3 ; j++) - { - ptri[i].vertindex[j] = - LittleLong (pintriangles[i].vertindex[j]); - } - } - -// -// load the frames -// - if (numframes < 1) - Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); - - pframetype = (daliasframetype_t *)&pintriangles[pmodel->numtris]; - - for (i=0 ; itype); - pheader->frames[i].type = frametype; - - if (frametype == ALIAS_SINGLE) - { - pframetype = (daliasframetype_t *) - Mod_LoadAliasFrame (pframetype + 1, - &pheader->frames[i].frame, - pmodel->numverts, - &pheader->frames[i].bboxmin, - &pheader->frames[i].bboxmax, - pheader, pheader->frames[i].name); - } - else - { - pframetype = (daliasframetype_t *) - Mod_LoadAliasGroup (pframetype + 1, - &pheader->frames[i].frame, - pmodel->numverts, - &pheader->frames[i].bboxmin, - &pheader->frames[i].bboxmax, - pheader, pheader->frames[i].name); - } - } - - mod->type = mod_alias; - -// FIXME: do this right - mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; - mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; - -// -// move the complete, relocatable alias model to the cache -// - end = Hunk_LowMark (); - total = end - start; - - Cache_Alloc (&mod->cache, total, loadname); - if (!mod->cache.data) - return; - memcpy (mod->cache.data, pheader, total); - - Hunk_FreeToLowMark (start); -} - -//============================================================================= - -/* -================= -Mod_LoadSpriteFrame -================= -*/ -void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe) -{ - dspriteframe_t *pinframe; - mspriteframe_t *pspriteframe; - int i, width, height, size, origin[2]; - unsigned short *ppixout; - byte *ppixin; - - pinframe = (dspriteframe_t *)pin; - - width = LittleLong (pinframe->width); - height = LittleLong (pinframe->height); - size = width * height; - - pspriteframe = Hunk_AllocName (sizeof (mspriteframe_t) + size*r_pixbytes, - loadname); - - memset (pspriteframe, 0, sizeof (mspriteframe_t) + size); - *ppframe = pspriteframe; - - pspriteframe->width = width; - pspriteframe->height = height; - origin[0] = LittleLong (pinframe->origin[0]); - origin[1] = LittleLong (pinframe->origin[1]); - - pspriteframe->up = origin[1]; - pspriteframe->down = origin[1] - height; - pspriteframe->left = origin[0]; - pspriteframe->right = width + origin[0]; - - if (r_pixbytes == 1) - { - memcpy (&pspriteframe->pixels[0], (byte *)(pinframe + 1), size); - } - else if (r_pixbytes == 2) - { - ppixin = (byte *)(pinframe + 1); - ppixout = (unsigned short *)&pspriteframe->pixels[0]; - - for (i=0 ; inumframes); - - pspritegroup = Hunk_AllocName (sizeof (mspritegroup_t) + - (numframes - 1) * sizeof (pspritegroup->frames[0]), loadname); - - pspritegroup->numframes = numframes; - - *ppframe = (mspriteframe_t *)pspritegroup; - - pin_intervals = (dspriteinterval_t *)(pingroup + 1); - - poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname); - - pspritegroup->intervals = poutintervals; - - for (i=0 ; iinterval); - if (*poutintervals <= 0.0) - Sys_Error ("Mod_LoadSpriteGroup: interval<=0"); - - poutintervals++; - pin_intervals++; - } - - ptemp = (void *)pin_intervals; - - for (i=0 ; iframes[i]); - } - - return ptemp; -} - - -/* -================= -Mod_LoadSpriteModel -================= -*/ -void Mod_LoadSpriteModel (model_t *mod, void *buffer) -{ - int i; - int version; - dsprite_t *pin; - msprite_t *psprite; - int numframes; - int size; - dspriteframetype_t *pframetype; - - pin = (dsprite_t *)buffer; - - version = LittleLong (pin->version); - if (version != SPRITE_VERSION) - Sys_Error ("%s has wrong version number " - "(%i should be %i)", mod->name, version, SPRITE_VERSION); - - numframes = LittleLong (pin->numframes); - - size = sizeof (msprite_t) + (numframes - 1) * sizeof (psprite->frames); - - psprite = Hunk_AllocName (size, loadname); - - mod->cache.data = psprite; - - psprite->type = LittleLong (pin->type); - psprite->maxwidth = LittleLong (pin->width); - psprite->maxheight = LittleLong (pin->height); - psprite->beamlength = LittleFloat (pin->beamlength); - mod->synctype = LittleLong (pin->synctype); - psprite->numframes = numframes; - - mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2; - mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2; - mod->mins[2] = -psprite->maxheight/2; - mod->maxs[2] = psprite->maxheight/2; - -// -// load the frames -// - if (numframes < 1) - Sys_Error ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes); - - mod->numframes = numframes; - mod->flags = 0; - - pframetype = (dspriteframetype_t *)(pin + 1); - - for (i=0 ; itype); - psprite->frames[i].type = frametype; - - if (frametype == SPR_SINGLE) - { - pframetype = (dspriteframetype_t *) - Mod_LoadSpriteFrame (pframetype + 1, - &psprite->frames[i].frameptr); - } - else - { - pframetype = (dspriteframetype_t *) - Mod_LoadSpriteGroup (pframetype + 1, - &psprite->frames[i].frameptr); - } - } - - mod->type = mod_sprite; -} - -//============================================================================= - /* ================ Mod_Print diff --git a/source/sw_model_alias.c b/source/sw_model_alias.c new file mode 100644 index 0000000..78a97ca --- /dev/null +++ b/source/sw_model_alias.c @@ -0,0 +1,477 @@ +/* + model.c + + model loading and caching + + Copyright (C) 1996-1997 Id Software, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + + $Id$ +*/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "r_local.h" +#include "sys.h" +#include "console.h" +#include "qendian.h" +#include "checksum.h" + +/* +============================================================================== + +ALIAS MODELS + +============================================================================== +*/ + +/* +================= +Mod_LoadAliasFrame +================= +*/ +void * Mod_LoadAliasFrame (void * pin, int *pframeindex, int numv, + trivertx_t *pbboxmin, trivertx_t *pbboxmax, aliashdr_t *pheader, char *name) +{ + trivertx_t *pframe, *pinframe; + int i, j; + daliasframe_t *pdaliasframe; + + pdaliasframe = (daliasframe_t *)pin; + + strcpy (name, pdaliasframe->name); + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about + // endianness + pbboxmin->v[i] = pdaliasframe->bboxmin.v[i]; + pbboxmax->v[i] = pdaliasframe->bboxmax.v[i]; + } + + pinframe = (trivertx_t *)(pdaliasframe + 1); + pframe = Hunk_AllocName (numv * sizeof(*pframe), loadname); + + *pframeindex = (byte *)pframe - (byte *)pheader; + + for (j=0 ; jnumframes); + + paliasgroup = Hunk_AllocName (sizeof (maliasgroup_t) + + (numframes - 1) * sizeof (paliasgroup->frames[0]), loadname); + + paliasgroup->numframes = numframes; + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about endianness + pbboxmin->v[i] = pingroup->bboxmin.v[i]; + pbboxmax->v[i] = pingroup->bboxmax.v[i]; + } + + *pframeindex = (byte *)paliasgroup - (byte *)pheader; + + pin_intervals = (daliasinterval_t *)(pingroup + 1); + + poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname); + + paliasgroup->intervals = (byte *)poutintervals - (byte *)pheader; + + for (i=0 ; iinterval); + if (*poutintervals <= 0.0) + Sys_Error ("Mod_LoadAliasGroup: interval<=0"); + + poutintervals++; + pin_intervals++; + } + + ptemp = (void *)pin_intervals; + + for (i=0 ; iframes[i].frame, + numv, + &paliasgroup->frames[i].bboxmin, + &paliasgroup->frames[i].bboxmax, + pheader, name); + } + + return ptemp; +} + + +/* +================= +Mod_LoadAliasSkin +================= +*/ +void * Mod_LoadAliasSkin (void * pin, int *pskinindex, int skinsize, + aliashdr_t *pheader) +{ + int i; + byte *pskin, *pinskin; + unsigned short *pusskin; + + pskin = Hunk_AllocName (skinsize * r_pixbytes, loadname); + pinskin = (byte *)pin; + *pskinindex = (byte *)pskin - (byte *)pheader; + + if (r_pixbytes == 1) + { + memcpy (pskin, pinskin, skinsize); + } + else if (r_pixbytes == 2) + { + pusskin = (unsigned short *)pskin; + + for (i=0 ; inumskins); + + paliasskingroup = Hunk_AllocName (sizeof (maliasskingroup_t) + + (numskins - 1) * sizeof (paliasskingroup->skindescs[0]), + loadname); + + paliasskingroup->numskins = numskins; + + *pskinindex = (byte *)paliasskingroup - (byte *)pheader; + + pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1); + + poutskinintervals = Hunk_AllocName (numskins * sizeof (float),loadname); + + paliasskingroup->intervals = (byte *)poutskinintervals - (byte *)pheader; + + for (i=0 ; iinterval); + if (*poutskinintervals <= 0) + Sys_Error ("Mod_LoadAliasSkinGroup: interval<=0"); + + poutskinintervals++; + pinskinintervals++; + } + + ptemp = (void *)pinskinintervals; + + for (i=0 ; iskindescs[i].skin, skinsize, pheader); + } + + return ptemp; +} + + +/* +================= +Mod_LoadAliasModel +================= +*/ +void Mod_LoadAliasModel (model_t *mod, void *buffer) +{ + int i; + mdl_t *pmodel, *pinmodel; + stvert_t *pstverts, *pinstverts; + aliashdr_t *pheader; + mtriangle_t *ptri; + dtriangle_t *pintriangles; + int version, numframes, numskins; + int size; + daliasframetype_t *pframetype; + daliasskintype_t *pskintype; + maliasskindesc_t *pskindesc; + int skinsize; + int start, end, total; + + start = Hunk_LowMark (); + + pinmodel = (mdl_t *)buffer; + + version = LittleLong (pinmodel->version); + if (version != ALIAS_VERSION) + Sys_Error ("%s has wrong version number (%i should be %i)", + mod->name, version, ALIAS_VERSION); + +// +// allocate space for a working header, plus all the data except the frames, +// skin and group info +// + size = sizeof (aliashdr_t) + (LittleLong (pinmodel->numframes) - 1) * + sizeof (pheader->frames[0]) + + sizeof (mdl_t) + + LittleLong (pinmodel->numverts) * sizeof (stvert_t) + + LittleLong (pinmodel->numtris) * sizeof (mtriangle_t); + + pheader = Hunk_AllocName (size, loadname); + pmodel = (mdl_t *) ((byte *)&pheader[1] + + (LittleLong (pinmodel->numframes) - 1) * + sizeof (pheader->frames[0])); + +// mod->cache.data = pheader; + mod->flags = LittleLong (pinmodel->flags); + +// +// endian-adjust and copy the data, starting with the alias model header +// + pmodel->boundingradius = LittleFloat (pinmodel->boundingradius); + pmodel->numskins = LittleLong (pinmodel->numskins); + pmodel->skinwidth = LittleLong (pinmodel->skinwidth); + pmodel->skinheight = LittleLong (pinmodel->skinheight); + + if (pmodel->skinheight > MAX_LBM_HEIGHT) + Sys_Error ("model %s has a skin taller than %d", mod->name, + MAX_LBM_HEIGHT); + + pmodel->numverts = LittleLong (pinmodel->numverts); + + if (pmodel->numverts <= 0) + Sys_Error ("model %s has no vertices", mod->name); + + if (pmodel->numverts > MAXALIASVERTS) + Sys_Error ("model %s has too many vertices", mod->name); + + pmodel->numtris = LittleLong (pinmodel->numtris); + + if (pmodel->numtris <= 0) + Sys_Error ("model %s has no triangles", mod->name); + + pmodel->numframes = LittleLong (pinmodel->numframes); + pmodel->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; + mod->synctype = LittleLong (pinmodel->synctype); + mod->numframes = pmodel->numframes; + + for (i=0 ; i<3 ; i++) + { + pmodel->scale[i] = LittleFloat (pinmodel->scale[i]); + pmodel->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]); + pmodel->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]); + } + + numskins = pmodel->numskins; + numframes = pmodel->numframes; + + if (pmodel->skinwidth & 0x03) + Sys_Error ("Mod_LoadAliasModel: skinwidth not multiple of 4"); + + pheader->model = (byte *)pmodel - (byte *)pheader; + +// +// load the skins +// + skinsize = pmodel->skinheight * pmodel->skinwidth; + + if (numskins < 1) + Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins); + + pskintype = (daliasskintype_t *)&pinmodel[1]; + + pskindesc = Hunk_AllocName (numskins * sizeof (maliasskindesc_t), + loadname); + + pheader->skindesc = (byte *)pskindesc - (byte *)pheader; + + for (i=0 ; itype); + pskindesc[i].type = skintype; + + if (skintype == ALIAS_SKIN_SINGLE) + { + pskintype = (daliasskintype_t *) + Mod_LoadAliasSkin (pskintype + 1, + &pskindesc[i].skin, + skinsize, pheader); + } + else + { + pskintype = (daliasskintype_t *) + Mod_LoadAliasSkinGroup (pskintype + 1, + &pskindesc[i].skin, + skinsize, pheader); + } + } + +// +// set base s and t vertices +// + pstverts = (stvert_t *)&pmodel[1]; + pinstverts = (stvert_t *)pskintype; + + pheader->stverts = (byte *)pstverts - (byte *)pheader; + + for (i=0 ; inumverts ; i++) + { + pstverts[i].onseam = LittleLong (pinstverts[i].onseam); + // put s and t in 16.16 format + pstverts[i].s = LittleLong (pinstverts[i].s) << 16; + pstverts[i].t = LittleLong (pinstverts[i].t) << 16; + } + +// +// set up the triangles +// + ptri = (mtriangle_t *)&pstverts[pmodel->numverts]; + pintriangles = (dtriangle_t *)&pinstverts[pmodel->numverts]; + + pheader->triangles = (byte *)ptri - (byte *)pheader; + + for (i=0 ; inumtris ; i++) + { + int j; + + ptri[i].facesfront = LittleLong (pintriangles[i].facesfront); + + for (j=0 ; j<3 ; j++) + { + ptri[i].vertindex[j] = + LittleLong (pintriangles[i].vertindex[j]); + } + } + +// +// load the frames +// + if (numframes < 1) + Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); + + pframetype = (daliasframetype_t *)&pintriangles[pmodel->numtris]; + + for (i=0 ; itype); + pheader->frames[i].type = frametype; + + if (frametype == ALIAS_SINGLE) + { + pframetype = (daliasframetype_t *) + Mod_LoadAliasFrame (pframetype + 1, + &pheader->frames[i].frame, + pmodel->numverts, + &pheader->frames[i].bboxmin, + &pheader->frames[i].bboxmax, + pheader, pheader->frames[i].name); + } + else + { + pframetype = (daliasframetype_t *) + Mod_LoadAliasGroup (pframetype + 1, + &pheader->frames[i].frame, + pmodel->numverts, + &pheader->frames[i].bboxmin, + &pheader->frames[i].bboxmax, + pheader, pheader->frames[i].name); + } + } + + mod->type = mod_alias; + +// FIXME: do this right + mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; + mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; + +// +// move the complete, relocatable alias model to the cache +// + end = Hunk_LowMark (); + total = end - start; + + Cache_Alloc (&mod->cache, total, loadname); + if (!mod->cache.data) + return; + memcpy (mod->cache.data, pheader, total); + + Hunk_FreeToLowMark (start); +} diff --git a/source/sw_model_brush.c b/source/sw_model_brush.c new file mode 100644 index 0000000..0175175 --- /dev/null +++ b/source/sw_model_brush.c @@ -0,0 +1,1019 @@ +/* + model.c + + model loading and caching + + Copyright (C) 1996-1997 Id Software, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + + $Id$ +*/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "r_local.h" +#include "sys.h" +#include "console.h" +#include "qendian.h" +#include "checksum.h" + +/* +=============== +Mod_PointInLeaf +=============== +*/ +mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model) +{ + mnode_t *node; + float d; + mplane_t *plane; + + if (!model || !model->nodes) + Sys_Error ("Mod_PointInLeaf: bad model"); + + node = model->nodes; + while (1) + { + if (node->contents < 0) + return (mleaf_t *)node; + plane = node->plane; + d = DotProduct (p, plane->normal) - plane->dist; + if (d > 0) + node = node->children[0]; + else + node = node->children[1]; + } + + return NULL; // never reached +} + + +/* +=================== +Mod_DecompressVis +=================== +*/ +byte *Mod_DecompressVis (byte *in, model_t *model) +{ + static byte decompressed[MAX_MAP_LEAFS/8]; + int c; + byte *out; + int row; + + row = (model->numleafs+7)>>3; + out = decompressed; + + if (!in) + { // no vis info, so make all visible + while (row) + { + *out++ = 0xff; + row--; + } + return decompressed; + } + + do + { + if (*in) + { + *out++ = *in++; + continue; + } + + c = in[1]; + in += 2; + while (c) + { + *out++ = 0; + c--; + } + } while (out - decompressed < row); + + return decompressed; +} + +byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model) +{ + if (leaf == model->leafs) + return mod_novis; + return Mod_DecompressVis (leaf->compressed_vis, model); +} + +/* +=============================================================================== + + BRUSHMODEL LOADING + +=============================================================================== +*/ + +byte *mod_base; + + +/* +================= +Mod_LoadTextures +================= +*/ +void Mod_LoadTextures (lump_t *l) +{ + int i, j, pixels, num, max, altmax; + miptex_t *mt; + texture_t *tx, *tx2; + texture_t *anims[10]; + texture_t *altanims[10]; + dmiptexlump_t *m; + + if (!l->filelen) + { + loadmodel->textures = NULL; + return; + } + m = (dmiptexlump_t *)(mod_base + l->fileofs); + + m->nummiptex = LittleLong (m->nummiptex); + + loadmodel->numtextures = m->nummiptex; + loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname); + + for (i=0 ; inummiptex ; i++) + { + m->dataofs[i] = LittleLong(m->dataofs[i]); + if (m->dataofs[i] == -1) + continue; + mt = (miptex_t *)((byte *)m + m->dataofs[i]); + mt->width = LittleLong (mt->width); + mt->height = LittleLong (mt->height); + for (j=0 ; joffsets[j] = LittleLong (mt->offsets[j]); + + if ( (mt->width & 15) || (mt->height & 15) ) + Sys_Error ("Texture %s is not 16 aligned", mt->name); + pixels = mt->width*mt->height/64*85; + tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname ); + loadmodel->textures[i] = tx; + + memcpy (tx->name, mt->name, sizeof(tx->name)); + tx->width = mt->width; + tx->height = mt->height; + for (j=0 ; joffsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t); + // the pixels immediately follow the structures + memcpy ( tx+1, mt+1, pixels); + + if (!strncmp(mt->name,"sky",3)) + R_InitSky (tx); + } + +// +// sequence the animations +// + for (i=0 ; inummiptex ; i++) + { + tx = loadmodel->textures[i]; + if (!tx || tx->name[0] != '+') + continue; + if (tx->anim_next) + continue; // allready sequenced + + // find the number of frames in the animation + memset (anims, 0, sizeof(anims)); + memset (altanims, 0, sizeof(altanims)); + + max = tx->name[1]; + altmax = 0; + if (max >= 'a' && max <= 'z') + max -= 'a' - 'A'; + if (max >= '0' && max <= '9') + { + max -= '0'; + altmax = 0; + anims[max] = tx; + max++; + } + else if (max >= 'A' && max <= 'J') + { + altmax = max - 'A'; + max = 0; + altanims[altmax] = tx; + altmax++; + } + else + Sys_Error ("Bad animating texture %s", tx->name); + + for (j=i+1 ; jnummiptex ; j++) + { + tx2 = loadmodel->textures[j]; + if (!tx2 || tx2->name[0] != '+') + continue; + if (strcmp (tx2->name+2, tx->name+2)) + continue; + + num = tx2->name[1]; + if (num >= 'a' && num <= 'z') + num -= 'a' - 'A'; + if (num >= '0' && num <= '9') + { + num -= '0'; + anims[num] = tx2; + if (num+1 > max) + max = num + 1; + } + else if (num >= 'A' && num <= 'J') + { + num = num - 'A'; + altanims[num] = tx2; + if (num+1 > altmax) + altmax = num+1; + } + else + Sys_Error ("Bad animating texture %s", tx->name); + } + +#define ANIM_CYCLE 2 + // link them all together + for (j=0 ; jname); + tx2->anim_total = max * ANIM_CYCLE; + tx2->anim_min = j * ANIM_CYCLE; + tx2->anim_max = (j+1) * ANIM_CYCLE; + tx2->anim_next = anims[ (j+1)%max ]; + if (altmax) + tx2->alternate_anims = altanims[0]; + } + for (j=0 ; jname); + tx2->anim_total = altmax * ANIM_CYCLE; + tx2->anim_min = j * ANIM_CYCLE; + tx2->anim_max = (j+1) * ANIM_CYCLE; + tx2->anim_next = altanims[ (j+1)%altmax ]; + if (max) + tx2->alternate_anims = anims[0]; + } + } +} + +/* +================= +Mod_LoadLighting +================= +*/ +void Mod_LoadLighting (lump_t *l) +{ + if (!l->filelen) + { + loadmodel->lightdata = NULL; + return; + } + loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname); + memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen); +} + + +/* +================= +Mod_LoadVisibility +================= +*/ +void Mod_LoadVisibility (lump_t *l) +{ + if (!l->filelen) + { + loadmodel->visdata = NULL; + return; + } + loadmodel->visdata = Hunk_AllocName ( l->filelen, loadname); + memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen); +} + + +/* +================= +Mod_LoadEntities +================= +*/ +void Mod_LoadEntities (lump_t *l) +{ + if (!l->filelen) + { + loadmodel->entities = NULL; + return; + } + loadmodel->entities = Hunk_AllocName ( l->filelen, loadname); + memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen); +} + + +/* +================= +Mod_LoadVertexes +================= +*/ +void Mod_LoadVertexes (lump_t *l) +{ + dvertex_t *in; + mvertex_t *out; + int i, count; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->vertexes = out; + loadmodel->numvertexes = count; + + for ( i=0 ; iposition[0] = LittleFloat (in->point[0]); + out->position[1] = LittleFloat (in->point[1]); + out->position[2] = LittleFloat (in->point[2]); + } +} + +/* +================= +Mod_LoadSubmodels +================= +*/ +void Mod_LoadSubmodels (lump_t *l) +{ + dmodel_t *in; + dmodel_t *out; + int i, j, count; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->submodels = out; + loadmodel->numsubmodels = count; + + for ( i=0 ; imins[j] = LittleFloat (in->mins[j]) - 1; + out->maxs[j] = LittleFloat (in->maxs[j]) + 1; + out->origin[j] = LittleFloat (in->origin[j]); + } + for (j=0 ; jheadnode[j] = LittleLong (in->headnode[j]); + out->visleafs = LittleLong (in->visleafs); + out->firstface = LittleLong (in->firstface); + out->numfaces = LittleLong (in->numfaces); + } +} + +/* +================= +Mod_LoadEdges +================= +*/ +void Mod_LoadEdges (lump_t *l) +{ + dedge_t *in; + medge_t *out; + int i, count; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( (count + 1) * sizeof(*out), loadname); + + loadmodel->edges = out; + loadmodel->numedges = count; + + for ( i=0 ; iv[0] = (unsigned short)LittleShort(in->v[0]); + out->v[1] = (unsigned short)LittleShort(in->v[1]); + } +} + +/* +================= +Mod_LoadTexinfo +================= +*/ +void Mod_LoadTexinfo (lump_t *l) +{ + texinfo_t *in; + mtexinfo_t *out; + int i, j, count; + int miptex; + float len1, len2; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->texinfo = out; + loadmodel->numtexinfo = count; + + for ( i=0 ; ivecs[0][j] = LittleFloat (in->vecs[0][j]); + out->vecs[1][j] = LittleFloat (in->vecs[1][j]); + } + len1 = Length (out->vecs[0]); + len2 = Length (out->vecs[1]); + + len1 = (len1 + len2)/2; + if (len1 < 0.32) + out->mipadjust = 4; + else if (len1 < 0.49) + out->mipadjust = 3; + else if (len1 < 0.99) + out->mipadjust = 2; + else + out->mipadjust = 1; + + miptex = LittleLong (in->miptex); + out->flags = LittleLong (in->flags); + + if (!loadmodel->textures) + { + out->texture = r_notexture_mip; // checkerboard texture + out->flags = 0; + } + else + { + if (miptex >= loadmodel->numtextures) + Sys_Error ("miptex >= loadmodel->numtextures"); + out->texture = loadmodel->textures[miptex]; + if (!out->texture) + { + out->texture = r_notexture_mip; // texture not found + out->flags = 0; + } + } + } +} + +/* +================ +CalcSurfaceExtents + +Fills in s->texturemins[] and s->extents[] +================ +*/ +void CalcSurfaceExtents (msurface_t *s) +{ + float mins[2], maxs[2], val; + int i,j, e; + mvertex_t *v; + mtexinfo_t *tex; + int bmins[2], bmaxs[2]; + + mins[0] = mins[1] = 999999; + maxs[0] = maxs[1] = -99999; + + tex = s->texinfo; + + for (i=0 ; inumedges ; i++) + { + e = loadmodel->surfedges[s->firstedge+i]; + if (e >= 0) + v = &loadmodel->vertexes[loadmodel->edges[e].v[0]]; + else + v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]]; + + for (j=0 ; j<2 ; j++) + { + val = v->position[0] * tex->vecs[j][0] + + v->position[1] * tex->vecs[j][1] + + v->position[2] * tex->vecs[j][2] + + tex->vecs[j][3]; + if (val < mins[j]) + mins[j] = val; + if (val > maxs[j]) + maxs[j] = val; + } + } + + for (i=0 ; i<2 ; i++) + { + bmins[i] = floor(mins[i]/16); + bmaxs[i] = ceil(maxs[i]/16); + + s->texturemins[i] = bmins[i] * 16; + s->extents[i] = (bmaxs[i] - bmins[i]) * 16; + if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 512 /* 256 */ ) + Sys_Error ("Bad surface extents"); + } +} + + +/* +================= +Mod_LoadFaces +================= +*/ +void Mod_LoadFaces (lump_t *l) +{ + dface_t *in; + msurface_t *out; + int i, count, surfnum; + int planenum, side; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->surfaces = out; + loadmodel->numsurfaces = count; + + for ( surfnum=0 ; surfnumfirstedge = LittleLong(in->firstedge); + out->numedges = LittleShort(in->numedges); + out->flags = 0; + + planenum = LittleShort(in->planenum); + side = LittleShort(in->side); + if (side) + out->flags |= SURF_PLANEBACK; + + out->plane = loadmodel->planes + planenum; + + out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo); + + CalcSurfaceExtents (out); + + // lighting info + + for (i=0 ; istyles[i] = in->styles[i]; + i = LittleLong(in->lightofs); + if (i == -1) + out->samples = NULL; + else + out->samples = loadmodel->lightdata + i; + + // set the drawing flags flag + + if (!strncmp(out->texinfo->texture->name,"sky",3)) // sky + { + out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED); + continue; + } + + if (!strncmp(out->texinfo->texture->name,"*",1)) // turbulent + { + out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED); + for (i=0 ; i<2 ; i++) + { + out->extents[i] = 16384; + out->texturemins[i] = -8192; + } + continue; + } + } +} + + +/* +================= +Mod_SetParent +================= +*/ +void Mod_SetParent (mnode_t *node, mnode_t *parent) +{ + node->parent = parent; + if (node->contents < 0) + return; + Mod_SetParent (node->children[0], node); + Mod_SetParent (node->children[1], node); +} + +/* +================= +Mod_LoadNodes +================= +*/ +void Mod_LoadNodes (lump_t *l) +{ + int i, j, count, p; + dnode_t *in; + mnode_t *out; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->nodes = out; + loadmodel->numnodes = count; + + for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); + out->minmaxs[3+j] = LittleShort (in->maxs[j]); + } + + p = LittleLong(in->planenum); + out->plane = loadmodel->planes + p; + + out->firstsurface = LittleShort (in->firstface); + out->numsurfaces = LittleShort (in->numfaces); + + for (j=0 ; j<2 ; j++) + { + p = LittleShort (in->children[j]); + if (p >= 0) + out->children[j] = loadmodel->nodes + p; + else + out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p)); + } + } + + Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs +} + +/* +================= +Mod_LoadLeafs +================= +*/ +void Mod_LoadLeafs (lump_t *l) +{ + dleaf_t *in; + mleaf_t *out; + int i, j, count, p; + qboolean isnotmap = true; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->leafs = out; + loadmodel->numleafs = count; + if (!strncmp("maps/", loadmodel->name,5)) + isnotmap = false; + for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); + out->minmaxs[3+j] = LittleShort (in->maxs[j]); + } + + p = LittleLong(in->contents); + out->contents = p; + + out->firstmarksurface = loadmodel->marksurfaces + + LittleShort(in->firstmarksurface); + out->nummarksurfaces = LittleShort(in->nummarksurfaces); + + p = LittleLong(in->visofs); + if (p == -1) + out->compressed_vis = NULL; + else + out->compressed_vis = loadmodel->visdata + p; + out->efrags = NULL; + + for (j=0 ; j<4 ; j++) + out->ambient_sound_level[j] = in->ambient_level[j]; + } +} + +/* +================= +Mod_LoadClipnodes +================= +*/ +void Mod_LoadClipnodes (lump_t *l) +{ + dclipnode_t *in, *out; + int i, count; + hull_t *hull; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->clipnodes = out; + loadmodel->numclipnodes = count; + + hull = &loadmodel->hulls[1]; + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + hull->clip_mins[0] = -16; + hull->clip_mins[1] = -16; + hull->clip_mins[2] = -24; + hull->clip_maxs[0] = 16; + hull->clip_maxs[1] = 16; + hull->clip_maxs[2] = 32; + + hull = &loadmodel->hulls[2]; + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + hull->clip_mins[0] = -32; + hull->clip_mins[1] = -32; + hull->clip_mins[2] = -24; + hull->clip_maxs[0] = 32; + hull->clip_maxs[1] = 32; + hull->clip_maxs[2] = 64; + + for (i=0 ; iplanenum = LittleLong(in->planenum); + out->children[0] = LittleShort(in->children[0]); + out->children[1] = LittleShort(in->children[1]); + } +} + +/* +================= +Mod_MakeHull0 + +Deplicate the drawing hull structure as a clipping hull +================= +*/ +void Mod_MakeHull0 (void) +{ + mnode_t *in, *child; + dclipnode_t *out; + int i, j, count; + hull_t *hull; + + hull = &loadmodel->hulls[0]; + + in = loadmodel->nodes; + count = loadmodel->numnodes; + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + + for (i=0 ; iplanenum = in->plane - loadmodel->planes; + for (j=0 ; j<2 ; j++) + { + child = in->children[j]; + if (child->contents < 0) + out->children[j] = child->contents; + else + out->children[j] = child - loadmodel->nodes; + } + } +} + +/* +================= +Mod_LoadMarksurfaces +================= +*/ +void Mod_LoadMarksurfaces (lump_t *l) +{ + int i, j, count; + short *in; + msurface_t **out; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->marksurfaces = out; + loadmodel->nummarksurfaces = count; + + for ( i=0 ; i= loadmodel->numsurfaces) + Sys_Error ("Mod_ParseMarksurfaces: bad surface number"); + out[i] = loadmodel->surfaces + j; + } +} + +/* +================= +Mod_LoadSurfedges +================= +*/ +void Mod_LoadSurfedges (lump_t *l) +{ + int i, count; + int *in, *out; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->surfedges = out; + loadmodel->numsurfedges = count; + + for ( i=0 ; ifileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*2*sizeof(*out), loadname); + + loadmodel->planes = out; + loadmodel->numplanes = count; + + for ( i=0 ; inormal[j] = LittleFloat (in->normal[j]); + if (out->normal[j] < 0) + bits |= 1<dist = LittleFloat (in->dist); + out->type = LittleLong (in->type); + out->signbits = bits; + } +} + +/* +================= +RadiusFromBounds +================= +*/ +float RadiusFromBounds (vec3_t mins, vec3_t maxs) +{ + int i; + vec3_t corner; + + for (i=0 ; i<3 ; i++) + { + corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]); + } + + return Length (corner); +} + +/* +================= +Mod_LoadBrushModel +================= +*/ +void Mod_LoadBrushModel (model_t *mod, void *buffer) +{ + int i, j; + dheader_t *header; + dmodel_t *bm; + + loadmodel->type = mod_brush; + + header = (dheader_t *)buffer; + + i = LittleLong (header->version); + if (i != BSPVERSION) + Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION); + +// swap all the lumps + mod_base = (byte *)header; + + for (i=0 ; ichecksum = 0; + mod->checksum2 = 0; + + for (i = 0; i < HEADER_LUMPS; i++) { + if (i == LUMP_ENTITIES) + continue; + mod->checksum ^= LittleLong(Com_BlockChecksum(mod_base + header->lumps[i].fileofs, + header->lumps[i].filelen)); + + if (i == LUMP_VISIBILITY || i == LUMP_LEAFS || i == LUMP_NODES) + continue; + mod->checksum2 ^= LittleLong(Com_BlockChecksum(mod_base + header->lumps[i].fileofs, + header->lumps[i].filelen)); + } + +// load into heap + + Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]); + Mod_LoadEdges (&header->lumps[LUMP_EDGES]); + Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]); + Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]); + Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); + Mod_LoadPlanes (&header->lumps[LUMP_PLANES]); + Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); + Mod_LoadFaces (&header->lumps[LUMP_FACES]); + Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]); + Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); + Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]); + Mod_LoadNodes (&header->lumps[LUMP_NODES]); + Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]); + Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]); + Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]); + + Mod_MakeHull0 (); + + mod->numframes = 2; // regular and alternate animation + mod->flags = 0; + +// +// set up the submodels (FIXME: this is confusing) +// + for (i=0 ; inumsubmodels ; i++) + { + bm = &mod->submodels[i]; + + mod->hulls[0].firstclipnode = bm->headnode[0]; + for (j=1 ; jhulls[j].firstclipnode = bm->headnode[j]; + mod->hulls[j].lastclipnode = mod->numclipnodes-1; + } + + mod->firstmodelsurface = bm->firstface; + mod->nummodelsurfaces = bm->numfaces; + + VectorCopy (bm->maxs, mod->maxs); + VectorCopy (bm->mins, mod->mins); + + mod->radius = RadiusFromBounds (mod->mins, mod->maxs); + + mod->numleafs = bm->visleafs; + + if (i < mod->numsubmodels-1) + { // duplicate the basic information + char name[10]; + + snprintf (name, sizeof(name), "*%i", i+1); + loadmodel = Mod_FindName (name); + *loadmodel = *mod; + strcpy (loadmodel->name, name); + mod = loadmodel; + } + } +} diff --git a/source/sw_model_sprite.c b/source/sw_model_sprite.c new file mode 100644 index 0000000..e99913b --- /dev/null +++ b/source/sw_model_sprite.c @@ -0,0 +1,223 @@ +/* + model.c + + model loading and caching + + Copyright (C) 1996-1997 Id Software, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + + $Id$ +*/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "r_local.h" +#include "sys.h" +#include "console.h" +#include "qendian.h" +#include "checksum.h" + +/* +================= +Mod_LoadSpriteFrame +================= +*/ +void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe) +{ + dspriteframe_t *pinframe; + mspriteframe_t *pspriteframe; + int i, width, height, size, origin[2]; + unsigned short *ppixout; + byte *ppixin; + + pinframe = (dspriteframe_t *)pin; + + width = LittleLong (pinframe->width); + height = LittleLong (pinframe->height); + size = width * height; + + pspriteframe = Hunk_AllocName (sizeof (mspriteframe_t) + size*r_pixbytes, + loadname); + + memset (pspriteframe, 0, sizeof (mspriteframe_t) + size); + *ppframe = pspriteframe; + + pspriteframe->width = width; + pspriteframe->height = height; + origin[0] = LittleLong (pinframe->origin[0]); + origin[1] = LittleLong (pinframe->origin[1]); + + pspriteframe->up = origin[1]; + pspriteframe->down = origin[1] - height; + pspriteframe->left = origin[0]; + pspriteframe->right = width + origin[0]; + + if (r_pixbytes == 1) + { + memcpy (&pspriteframe->pixels[0], (byte *)(pinframe + 1), size); + } + else if (r_pixbytes == 2) + { + ppixin = (byte *)(pinframe + 1); + ppixout = (unsigned short *)&pspriteframe->pixels[0]; + + for (i=0 ; inumframes); + + pspritegroup = Hunk_AllocName (sizeof (mspritegroup_t) + + (numframes - 1) * sizeof (pspritegroup->frames[0]), loadname); + + pspritegroup->numframes = numframes; + + *ppframe = (mspriteframe_t *)pspritegroup; + + pin_intervals = (dspriteinterval_t *)(pingroup + 1); + + poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname); + + pspritegroup->intervals = poutintervals; + + for (i=0 ; iinterval); + if (*poutintervals <= 0.0) + Sys_Error ("Mod_LoadSpriteGroup: interval<=0"); + + poutintervals++; + pin_intervals++; + } + + ptemp = (void *)pin_intervals; + + for (i=0 ; iframes[i]); + } + + return ptemp; +} + + +/* +================= +Mod_LoadSpriteModel +================= +*/ +void Mod_LoadSpriteModel (model_t *mod, void *buffer) +{ + int i; + int version; + dsprite_t *pin; + msprite_t *psprite; + int numframes; + int size; + dspriteframetype_t *pframetype; + + pin = (dsprite_t *)buffer; + + version = LittleLong (pin->version); + if (version != SPRITE_VERSION) + Sys_Error ("%s has wrong version number " + "(%i should be %i)", mod->name, version, SPRITE_VERSION); + + numframes = LittleLong (pin->numframes); + + size = sizeof (msprite_t) + (numframes - 1) * sizeof (psprite->frames); + + psprite = Hunk_AllocName (size, loadname); + + mod->cache.data = psprite; + + psprite->type = LittleLong (pin->type); + psprite->maxwidth = LittleLong (pin->width); + psprite->maxheight = LittleLong (pin->height); + psprite->beamlength = LittleFloat (pin->beamlength); + mod->synctype = LittleLong (pin->synctype); + psprite->numframes = numframes; + + mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2; + mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2; + mod->mins[2] = -psprite->maxheight/2; + mod->maxs[2] = psprite->maxheight/2; + +// +// load the frames +// + if (numframes < 1) + Sys_Error ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes); + + mod->numframes = numframes; + mod->flags = 0; + + pframetype = (dspriteframetype_t *)(pin + 1); + + for (i=0 ; itype); + psprite->frames[i].type = frametype; + + if (frametype == SPR_SINGLE) + { + pframetype = (dspriteframetype_t *) + Mod_LoadSpriteFrame (pframetype + 1, + &psprite->frames[i].frameptr); + } + else + { + pframetype = (dspriteframetype_t *) + Mod_LoadSpriteGroup (pframetype + 1, + &psprite->frames[i].frameptr); + } + } + + mod->type = mod_sprite; +} From 50bd641616b02491e4b885a96f093deba56c326c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 1 Sep 2000 17:07:28 +0000 Subject: [PATCH 2/9] ok, the chopped up model files compile and sw seems to work just fine. Don't know about gl yet (probably won't until either monday or tuesday; hence the branch) --- include/model.h | 2 ++ source/Makefile.am | 7 ++++--- source/gl_model_alias.c | 10 ++++++++++ source/gl_model_brush.c | 20 ++++++++++++-------- source/gl_model_sprite.c | 3 +++ source/sw_model_alias.c | 2 ++ source/sw_model_brush.c | 4 ++++ source/sw_model_sprite.c | 2 ++ 8 files changed, 39 insertions(+), 11 deletions(-) diff --git a/include/model.h b/include/model.h index 9b8b64d..8f09317 100644 --- a/include/model.h +++ b/include/model.h @@ -465,4 +465,6 @@ void Mod_TouchModel (char *name); mleaf_t *Mod_PointInLeaf (float *p, model_t *model); byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model); +model_t *Mod_FindName (char *name); + #endif // _MODEL_H diff --git a/source/Makefile.am b/source/Makefile.am index 82e3280..d4a9f77 100644 --- a/source/Makefile.am +++ b/source/Makefile.am @@ -48,7 +48,7 @@ sound_ASM= snd_mixa.S common_ASM= sys_ia32.S worlda.S $(math_ASM) #endif -common_SOURCES= crc.c cvar.c cmd.c mathlib.c wad.c world.c \ +common_SOURCES= crc.c cvar.c cmd.c mathlib.c wad.c world.c model.c \ msg.c r_part.c sizebuf.c qendian.c qargs.c quakefs.c \ va.c quakeio.c link.c com.c \ zone.c $(common_ASM) @@ -133,7 +133,8 @@ soft_SOURCES= d_edge.c d_fill.c d_init.c d_modech.c d_part.c d_polyse.c \ d_scan.c d_sky.c d_sprite.c d_surf.c d_vars.c d_zpoint.c \ draw.c r_aclip.c r_alias.c r_bsp.c r_draw.c r_edge.c r_efrag.c \ r_light.c r_main.c r_misc.c sw_part.c r_sky.c r_sprite.c \ - r_surf.c r_vars.c screen.c model.c sw_view.c $(soft_ASM) + r_surf.c r_vars.c screen.c sw_model_alias.c sw_model_brush.c \ + sw_model_sprite.c sw_view.c $(soft_ASM) # # ... GGI @@ -188,7 +189,7 @@ nuq_x11_DEPENDENCIES=libqfsys.a libqfsnd.a libqfcd.a libqfnet.a # ogl_SOURCES= gl_draw.c gl_mesh.c gl_part.c gl_refrag.c gl_rlight.c \ gl_rmain.c gl_rmisc.c gl_rsurf.c gl_screen.c gl_view.c \ - gl_warp.c gl_model.c + gl_warp.c gl_model_alias.c gl_model_brush.c gl_model_sprite.c # # ... 3Dfx Voodoo 1 and 2 SVGAlib-based console GL diff --git a/source/gl_model_alias.c b/source/gl_model_alias.c index 4d773ab..4187b3b 100644 --- a/source/gl_model_alias.c +++ b/source/gl_model_alias.c @@ -33,6 +33,16 @@ # include "config.h" #endif +#include "r_local.h" +#include "sys.h" +#include "console.h" +#include "qendian.h" +#include "checksum.h" +#include "glquake.h" + +extern char loadname[]; +extern model_t *loadmodel; + /* ============================================================================== diff --git a/source/gl_model_brush.c b/source/gl_model_brush.c index a3a907c..a413445 100644 --- a/source/gl_model_brush.c +++ b/source/gl_model_brush.c @@ -40,6 +40,18 @@ #include "checksum.h" #include "glquake.h" +extern char loadname[]; +extern model_t *loadmodel; +extern byte mod_novis[]; + +void +Mod_LoadMMNearest(miptex_t *mt, texture_t *tx) +{ + texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; + tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false, 1); + texture_mode = GL_LINEAR; +} + /* =============== Mod_PointInLeaf @@ -1064,11 +1076,3 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) } } } - -void -Mod_LoadMMNearest(miptex_t *mt, texture_t *tx) -{ - texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; - tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false, 1); - texture_mode = GL_LINEAR; -} diff --git a/source/gl_model_sprite.c b/source/gl_model_sprite.c index 5f8aad2..7e3a357 100644 --- a/source/gl_model_sprite.c +++ b/source/gl_model_sprite.c @@ -40,6 +40,9 @@ #include "checksum.h" #include "glquake.h" +extern char loadname[]; +extern model_t *loadmodel; + /* ================= Mod_LoadSpriteFrame diff --git a/source/sw_model_alias.c b/source/sw_model_alias.c index 78a97ca..f2b54c0 100644 --- a/source/sw_model_alias.c +++ b/source/sw_model_alias.c @@ -36,6 +36,8 @@ #include "qendian.h" #include "checksum.h" +extern char loadname[]; + /* ============================================================================== diff --git a/source/sw_model_brush.c b/source/sw_model_brush.c index 0175175..2b1baf2 100644 --- a/source/sw_model_brush.c +++ b/source/sw_model_brush.c @@ -36,6 +36,10 @@ #include "qendian.h" #include "checksum.h" +extern char loadname[]; +model_t *loadmodel; +extern byte mod_novis[]; + /* =============== Mod_PointInLeaf diff --git a/source/sw_model_sprite.c b/source/sw_model_sprite.c index e99913b..eaf5c88 100644 --- a/source/sw_model_sprite.c +++ b/source/sw_model_sprite.c @@ -36,6 +36,8 @@ #include "qendian.h" #include "checksum.h" +extern char loadname[]; + /* ================= Mod_LoadSpriteFrame From 1ab1dd2683658bb1913ca93929cb34a18d15c77e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 1 Sep 2000 17:32:42 +0000 Subject: [PATCH 3/9] bah, forgot to save this one :/ --- source/sw_model_brush.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/sw_model_brush.c b/source/sw_model_brush.c index 2b1baf2..9f9dee9 100644 --- a/source/sw_model_brush.c +++ b/source/sw_model_brush.c @@ -37,7 +37,7 @@ #include "checksum.h" extern char loadname[]; -model_t *loadmodel; +extern model_t *loadmodel; extern byte mod_novis[]; /* From 69706f997ebfc8d296a24372adfa61007237d0d8 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 5 Sep 2000 17:59:11 +0000 Subject: [PATCH 4/9] sprite model code merge done. model_sprite.c is the common code while gl_model_sprite.c and sw_model_sprite are just the gl/sw specific code (Mod_LoadSpriteFrame). --- source/Makefile.am | 3 +- source/gl_model_sprite.c | 134 +----------------------------- source/model_sprite.c | 175 +++++++++++++++++++++++++++++++++++++++ source/sw_model_sprite.c | 134 +----------------------------- 4 files changed, 180 insertions(+), 266 deletions(-) create mode 100644 source/model_sprite.c diff --git a/source/Makefile.am b/source/Makefile.am index d4a9f77..d279810 100644 --- a/source/Makefile.am +++ b/source/Makefile.am @@ -48,7 +48,8 @@ sound_ASM= snd_mixa.S common_ASM= sys_ia32.S worlda.S $(math_ASM) #endif -common_SOURCES= crc.c cvar.c cmd.c mathlib.c wad.c world.c model.c \ +common_SOURCES= crc.c cvar.c cmd.c mathlib.c wad.c world.c \ + model.c model_sprite.c \ msg.c r_part.c sizebuf.c qendian.c qargs.c quakefs.c \ va.c quakeio.c link.c com.c \ zone.c $(common_ASM) diff --git a/source/gl_model_sprite.c b/source/gl_model_sprite.c index 7e3a357..81d9a18 100644 --- a/source/gl_model_sprite.c +++ b/source/gl_model_sprite.c @@ -1,5 +1,5 @@ /* - gl_model.c + gl_model_sprite.c model loading and caching @@ -26,9 +26,6 @@ $Id$ */ -// models are the only shared resource between a client and server running -// on the same machine. - #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -82,132 +79,3 @@ void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum) return (void *)((byte *)pinframe + sizeof (dspriteframe_t) + size); } - - -/* -================= -Mod_LoadSpriteGroup -================= -*/ -void * Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum) -{ - dspritegroup_t *pingroup; - mspritegroup_t *pspritegroup; - int i, numframes; - dspriteinterval_t *pin_intervals; - float *poutintervals; - void *ptemp; - - pingroup = (dspritegroup_t *)pin; - - numframes = LittleLong (pingroup->numframes); - - pspritegroup = Hunk_AllocName (sizeof (mspritegroup_t) + - (numframes - 1) * sizeof (pspritegroup->frames[0]), loadname); - - pspritegroup->numframes = numframes; - - *ppframe = (mspriteframe_t *)pspritegroup; - - pin_intervals = (dspriteinterval_t *)(pingroup + 1); - - poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname); - - pspritegroup->intervals = poutintervals; - - for (i=0 ; iinterval); - if (*poutintervals <= 0.0) - Sys_Error ("Mod_LoadSpriteGroup: interval<=0"); - - poutintervals++; - pin_intervals++; - } - - ptemp = (void *)pin_intervals; - - for (i=0 ; iframes[i], framenum * 100 + i); - } - - return ptemp; -} - - -/* -================= -Mod_LoadSpriteModel -================= -*/ -void Mod_LoadSpriteModel (model_t *mod, void *buffer) -{ - int i; - int version; - dsprite_t *pin; - msprite_t *psprite; - int numframes; - int size; - dspriteframetype_t *pframetype; - - pin = (dsprite_t *)buffer; - - version = LittleLong (pin->version); - if (version != SPRITE_VERSION) - Sys_Error ("%s has wrong version number " - "(%i should be %i)", mod->name, version, SPRITE_VERSION); - - numframes = LittleLong (pin->numframes); - - size = sizeof (msprite_t) + (numframes - 1) * sizeof (psprite->frames); - - psprite = Hunk_AllocName (size, loadname); - - mod->cache.data = psprite; - - psprite->type = LittleLong (pin->type); - psprite->maxwidth = LittleLong (pin->width); - psprite->maxheight = LittleLong (pin->height); - psprite->beamlength = LittleFloat (pin->beamlength); - mod->synctype = LittleLong (pin->synctype); - psprite->numframes = numframes; - - mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2; - mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2; - mod->mins[2] = -psprite->maxheight/2; - mod->maxs[2] = psprite->maxheight/2; - -// -// load the frames -// - if (numframes < 1) - Sys_Error ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes); - - mod->numframes = numframes; - - pframetype = (dspriteframetype_t *)(pin + 1); - - for (i=0 ; itype); - psprite->frames[i].type = frametype; - - if (frametype == SPR_SINGLE) - { - pframetype = (dspriteframetype_t *) - Mod_LoadSpriteFrame (pframetype + 1, - &psprite->frames[i].frameptr, i); - } - else - { - pframetype = (dspriteframetype_t *) - Mod_LoadSpriteGroup (pframetype + 1, - &psprite->frames[i].frameptr, i); - } - } - - mod->type = mod_sprite; -} diff --git a/source/model_sprite.c b/source/model_sprite.c new file mode 100644 index 0000000..b3a579f --- /dev/null +++ b/source/model_sprite.c @@ -0,0 +1,175 @@ +/* + model_sprite.c + + sprite model loading and caching + + Copyright (C) 1996-1997 Id Software, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + + $Id$ +*/ + +// models are the only shared resource between a client and server running +// on the same machine. + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "r_local.h" +#include "sys.h" +#include "console.h" +#include "qendian.h" +#include "checksum.h" +#include "glquake.h" + +extern char loadname[]; +extern model_t *loadmodel; + +void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum); + +/* +================= +Mod_LoadSpriteGroup +================= +*/ +void * Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum) +{ + dspritegroup_t *pingroup; + mspritegroup_t *pspritegroup; + int i, numframes; + dspriteinterval_t *pin_intervals; + float *poutintervals; + void *ptemp; + + pingroup = (dspritegroup_t *)pin; + + numframes = LittleLong (pingroup->numframes); + + pspritegroup = Hunk_AllocName (sizeof (mspritegroup_t) + + (numframes - 1) * sizeof (pspritegroup->frames[0]), loadname); + + pspritegroup->numframes = numframes; + + *ppframe = (mspriteframe_t *)pspritegroup; + + pin_intervals = (dspriteinterval_t *)(pingroup + 1); + + poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname); + + pspritegroup->intervals = poutintervals; + + for (i=0 ; iinterval); + if (*poutintervals <= 0.0) + Sys_Error ("Mod_LoadSpriteGroup: interval<=0"); + + poutintervals++; + pin_intervals++; + } + + ptemp = (void *)pin_intervals; + + for (i=0 ; iframes[i], framenum * 100 + i); + } + + return ptemp; +} + + +/* +================= +Mod_LoadSpriteModel +================= +*/ +void Mod_LoadSpriteModel (model_t *mod, void *buffer) +{ + int i; + int version; + dsprite_t *pin; + msprite_t *psprite; + int numframes; + int size; + dspriteframetype_t *pframetype; + + pin = (dsprite_t *)buffer; + + version = LittleLong (pin->version); + if (version != SPRITE_VERSION) + Sys_Error ("%s has wrong version number " + "(%i should be %i)", mod->name, version, SPRITE_VERSION); + + numframes = LittleLong (pin->numframes); + + size = sizeof (msprite_t) + (numframes - 1) * sizeof (psprite->frames); + + psprite = Hunk_AllocName (size, loadname); + + mod->cache.data = psprite; + + psprite->type = LittleLong (pin->type); + psprite->maxwidth = LittleLong (pin->width); + psprite->maxheight = LittleLong (pin->height); + psprite->beamlength = LittleFloat (pin->beamlength); + mod->synctype = LittleLong (pin->synctype); + psprite->numframes = numframes; + + mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2; + mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2; + mod->mins[2] = -psprite->maxheight/2; + mod->maxs[2] = psprite->maxheight/2; + +// +// load the frames +// + if (numframes < 1) + Sys_Error ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes); + + mod->numframes = numframes; + mod->flags = 0; + + pframetype = (dspriteframetype_t *)(pin + 1); + + for (i=0 ; itype); + psprite->frames[i].type = frametype; + + if (frametype == SPR_SINGLE) + { + pframetype = (dspriteframetype_t *) + Mod_LoadSpriteFrame (pframetype + 1, + &psprite->frames[i].frameptr, i); + } + else + { + pframetype = (dspriteframetype_t *) + Mod_LoadSpriteGroup (pframetype + 1, + &psprite->frames[i].frameptr, i); + } + } + + mod->type = mod_sprite; +} diff --git a/source/sw_model_sprite.c b/source/sw_model_sprite.c index eaf5c88..ca6ca4d 100644 --- a/source/sw_model_sprite.c +++ b/source/sw_model_sprite.c @@ -1,5 +1,5 @@ /* - model.c + sw_model_sprite.c model loading and caching @@ -43,7 +43,7 @@ extern char loadname[]; Mod_LoadSpriteFrame ================= */ -void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe) +void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum) { dspriteframe_t *pinframe; mspriteframe_t *pspriteframe; @@ -93,133 +93,3 @@ void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe) return (void *)((byte *)pinframe + sizeof (dspriteframe_t) + size); } - - -/* -================= -Mod_LoadSpriteGroup -================= -*/ -void * Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe) -{ - dspritegroup_t *pingroup; - mspritegroup_t *pspritegroup; - int i, numframes; - dspriteinterval_t *pin_intervals; - float *poutintervals; - void *ptemp; - - pingroup = (dspritegroup_t *)pin; - - numframes = LittleLong (pingroup->numframes); - - pspritegroup = Hunk_AllocName (sizeof (mspritegroup_t) + - (numframes - 1) * sizeof (pspritegroup->frames[0]), loadname); - - pspritegroup->numframes = numframes; - - *ppframe = (mspriteframe_t *)pspritegroup; - - pin_intervals = (dspriteinterval_t *)(pingroup + 1); - - poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname); - - pspritegroup->intervals = poutintervals; - - for (i=0 ; iinterval); - if (*poutintervals <= 0.0) - Sys_Error ("Mod_LoadSpriteGroup: interval<=0"); - - poutintervals++; - pin_intervals++; - } - - ptemp = (void *)pin_intervals; - - for (i=0 ; iframes[i]); - } - - return ptemp; -} - - -/* -================= -Mod_LoadSpriteModel -================= -*/ -void Mod_LoadSpriteModel (model_t *mod, void *buffer) -{ - int i; - int version; - dsprite_t *pin; - msprite_t *psprite; - int numframes; - int size; - dspriteframetype_t *pframetype; - - pin = (dsprite_t *)buffer; - - version = LittleLong (pin->version); - if (version != SPRITE_VERSION) - Sys_Error ("%s has wrong version number " - "(%i should be %i)", mod->name, version, SPRITE_VERSION); - - numframes = LittleLong (pin->numframes); - - size = sizeof (msprite_t) + (numframes - 1) * sizeof (psprite->frames); - - psprite = Hunk_AllocName (size, loadname); - - mod->cache.data = psprite; - - psprite->type = LittleLong (pin->type); - psprite->maxwidth = LittleLong (pin->width); - psprite->maxheight = LittleLong (pin->height); - psprite->beamlength = LittleFloat (pin->beamlength); - mod->synctype = LittleLong (pin->synctype); - psprite->numframes = numframes; - - mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2; - mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2; - mod->mins[2] = -psprite->maxheight/2; - mod->maxs[2] = psprite->maxheight/2; - -// -// load the frames -// - if (numframes < 1) - Sys_Error ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes); - - mod->numframes = numframes; - mod->flags = 0; - - pframetype = (dspriteframetype_t *)(pin + 1); - - for (i=0 ; itype); - psprite->frames[i].type = frametype; - - if (frametype == SPR_SINGLE) - { - pframetype = (dspriteframetype_t *) - Mod_LoadSpriteFrame (pframetype + 1, - &psprite->frames[i].frameptr); - } - else - { - pframetype = (dspriteframetype_t *) - Mod_LoadSpriteGroup (pframetype + 1, - &psprite->frames[i].frameptr); - } - } - - mod->type = mod_sprite; -} From ff69e3f2f395085a6d997c76e5de4e0dc6829402 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 5 Sep 2000 19:58:08 +0000 Subject: [PATCH 5/9] brush model code has now been merged. common stuff in model_brush.c, gl and sw specific stuff in gl_model_brush.c and sw_model_brush.c respectively. --- source/Makefile.am | 2 +- source/gl_model_brush.c | 991 +------------------------------------ source/model_brush.c | 1027 +++++++++++++++++++++++++++++++++++++++ source/sw_model_brush.c | 969 +----------------------------------- 4 files changed, 1040 insertions(+), 1949 deletions(-) create mode 100644 source/model_brush.c diff --git a/source/Makefile.am b/source/Makefile.am index d279810..27b57c1 100644 --- a/source/Makefile.am +++ b/source/Makefile.am @@ -49,7 +49,7 @@ common_ASM= sys_ia32.S worlda.S $(math_ASM) #endif common_SOURCES= crc.c cvar.c cmd.c mathlib.c wad.c world.c \ - model.c model_sprite.c \ + model.c model_brush.c model_sprite.c \ msg.c r_part.c sizebuf.c qendian.c qargs.c quakefs.c \ va.c quakeio.c link.c com.c \ zone.c $(common_ASM) diff --git a/source/gl_model_brush.c b/source/gl_model_brush.c index a413445..50cecf8 100644 --- a/source/gl_model_brush.c +++ b/source/gl_model_brush.c @@ -1,5 +1,5 @@ /* - gl_model.c + gl_model_brush.c model loading and caching @@ -43,6 +43,9 @@ extern char loadname[]; extern model_t *loadmodel; extern byte mod_novis[]; +extern byte *mod_base; + +const int mod_lightmap_bytes = 3; void Mod_LoadMMNearest(miptex_t *mt, texture_t *tx) @@ -52,253 +55,6 @@ Mod_LoadMMNearest(miptex_t *mt, texture_t *tx) texture_mode = GL_LINEAR; } -/* -=============== -Mod_PointInLeaf -=============== -*/ -mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model) -{ - mnode_t *node; - float d; - mplane_t *plane; - - if (!model || !model->nodes) - Sys_Error ("Mod_PointInLeaf: bad model"); - - node = model->nodes; - while (1) - { - if (node->contents < 0) - return (mleaf_t *)node; - plane = node->plane; - d = DotProduct (p, plane->normal) - plane->dist; - if (d > 0) - node = node->children[0]; - else - node = node->children[1]; - } - - return NULL; // never reached -} - - -/* -=================== -Mod_DecompressVis -=================== -*/ -byte *Mod_DecompressVis (byte *in, model_t *model) -{ - static byte decompressed[MAX_MAP_LEAFS/8]; - int c; - byte *out; - int row; - - row = (model->numleafs+7)>>3; - out = decompressed; - - if (!in) - { // no vis info, so make all visible - while (row) - { - *out++ = 0xff; - row--; - } - return decompressed; - } - - do - { - if (*in) - { - *out++ = *in++; - continue; - } - - c = in[1]; - in += 2; - while (c) - { - *out++ = 0; - c--; - } - } while (out - decompressed < row); - - return decompressed; -} - -byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model) -{ - if (leaf == model->leafs) - return mod_novis; - return Mod_DecompressVis (leaf->compressed_vis, model); -} - -/* -=============================================================================== - - BRUSHMODEL LOADING - -=============================================================================== -*/ - -byte *mod_base; - - -/* -================= -Mod_LoadTextures -================= -*/ -void Mod_LoadTextures (lump_t *l) -{ - int i, j, pixels, num, max, altmax; - miptex_t *mt; - texture_t *tx, *tx2; - texture_t *anims[10]; - texture_t *altanims[10]; - dmiptexlump_t *m; - - if (!l->filelen) - { - loadmodel->textures = NULL; - return; - } - m = (dmiptexlump_t *)(mod_base + l->fileofs); - - m->nummiptex = LittleLong (m->nummiptex); - - loadmodel->numtextures = m->nummiptex; - loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname); - - for (i=0 ; inummiptex ; i++) - { - m->dataofs[i] = LittleLong(m->dataofs[i]); - if (m->dataofs[i] == -1) - continue; - mt = (miptex_t *)((byte *)m + m->dataofs[i]); - mt->width = LittleLong (mt->width); - mt->height = LittleLong (mt->height); - for (j=0 ; joffsets[j] = LittleLong (mt->offsets[j]); - - if ( (mt->width & 15) || (mt->height & 15) ) - Sys_Error ("Texture %s is not 16 aligned", mt->name); - pixels = mt->width*mt->height/64*85; - tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname ); - loadmodel->textures[i] = tx; - - memcpy (tx->name, mt->name, sizeof(tx->name)); - tx->width = mt->width; - tx->height = mt->height; - for (j=0 ; joffsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t); - // the pixels immediately follow the structures - memcpy ( tx+1, mt+1, pixels); - - if (!strncmp(mt->name,"sky",3)) - R_InitSky (tx); - else - { - Mod_LoadMMNearest(mt, tx); - } - } - -// -// sequence the animations -// - for (i=0 ; inummiptex ; i++) - { - tx = loadmodel->textures[i]; - if (!tx || tx->name[0] != '+') - continue; - if (tx->anim_next) - continue; // allready sequenced - - // find the number of frames in the animation - memset (anims, 0, sizeof(anims)); - memset (altanims, 0, sizeof(altanims)); - - max = tx->name[1]; - altmax = 0; - if (max >= 'a' && max <= 'z') - max -= 'a' - 'A'; - if (max >= '0' && max <= '9') - { - max -= '0'; - altmax = 0; - anims[max] = tx; - max++; - } - else if (max >= 'A' && max <= 'J') - { - altmax = max - 'A'; - max = 0; - altanims[altmax] = tx; - altmax++; - } - else - Sys_Error ("Bad animating texture %s", tx->name); - - for (j=i+1 ; jnummiptex ; j++) - { - tx2 = loadmodel->textures[j]; - if (!tx2 || tx2->name[0] != '+') - continue; - if (strcmp (tx2->name+2, tx->name+2)) - continue; - - num = tx2->name[1]; - if (num >= 'a' && num <= 'z') - num -= 'a' - 'A'; - if (num >= '0' && num <= '9') - { - num -= '0'; - anims[num] = tx2; - if (num+1 > max) - max = num + 1; - } - else if (num >= 'A' && num <= 'J') - { - num = num - 'A'; - altanims[num] = tx2; - if (num+1 > altmax) - altmax = num+1; - } - else - Sys_Error ("Bad animating texture %s", tx->name); - } - -#define ANIM_CYCLE 2 - // link them all together - for (j=0 ; jname); - tx2->anim_total = max * ANIM_CYCLE; - tx2->anim_min = j * ANIM_CYCLE; - tx2->anim_max = (j+1) * ANIM_CYCLE; - tx2->anim_next = anims[ (j+1)%max ]; - if (altmax) - tx2->alternate_anims = altanims[0]; - } - for (j=0 ; jname); - tx2->anim_total = altmax * ANIM_CYCLE; - tx2->anim_min = j * ANIM_CYCLE; - tx2->anim_max = (j+1) * ANIM_CYCLE; - tx2->anim_next = altanims[ (j+1)%altmax ]; - if (max) - tx2->alternate_anims = anims[0]; - } - } -} - /* ================= Mod_LoadLighting @@ -337,742 +93,3 @@ void Mod_LoadLighting (lump_t *l) } } } - - -/* -================= -Mod_LoadVisibility -================= -*/ -void Mod_LoadVisibility (lump_t *l) -{ - if (!l->filelen) - { - loadmodel->visdata = NULL; - return; - } - loadmodel->visdata = Hunk_AllocName ( l->filelen, loadname); - memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen); -} - - -/* -================= -Mod_LoadEntities -================= -*/ -void Mod_LoadEntities (lump_t *l) -{ - if (!l->filelen) - { - loadmodel->entities = NULL; - return; - } - loadmodel->entities = Hunk_AllocName ( l->filelen, loadname); - memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen); -} - - -/* -================= -Mod_LoadVertexes -================= -*/ -void Mod_LoadVertexes (lump_t *l) -{ - dvertex_t *in; - mvertex_t *out; - int i, count; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->vertexes = out; - loadmodel->numvertexes = count; - - for ( i=0 ; iposition[0] = LittleFloat (in->point[0]); - out->position[1] = LittleFloat (in->point[1]); - out->position[2] = LittleFloat (in->point[2]); - } -} - -/* -================= -Mod_LoadSubmodels -================= -*/ -void Mod_LoadSubmodels (lump_t *l) -{ - dmodel_t *in; - dmodel_t *out; - int i, j, count; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->submodels = out; - loadmodel->numsubmodels = count; - - for ( i=0 ; imins[j] = LittleFloat (in->mins[j]) - 1; - out->maxs[j] = LittleFloat (in->maxs[j]) + 1; - out->origin[j] = LittleFloat (in->origin[j]); - } - for (j=0 ; jheadnode[j] = LittleLong (in->headnode[j]); - out->visleafs = LittleLong (in->visleafs); - out->firstface = LittleLong (in->firstface); - out->numfaces = LittleLong (in->numfaces); - } -} - -/* -================= -Mod_LoadEdges -================= -*/ -void Mod_LoadEdges (lump_t *l) -{ - dedge_t *in; - medge_t *out; - int i, count; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( (count + 1) * sizeof(*out), loadname); - - loadmodel->edges = out; - loadmodel->numedges = count; - - for ( i=0 ; iv[0] = (unsigned short)LittleShort(in->v[0]); - out->v[1] = (unsigned short)LittleShort(in->v[1]); - } -} - -/* -================= -Mod_LoadTexinfo -================= -*/ -void Mod_LoadTexinfo (lump_t *l) -{ - texinfo_t *in; - mtexinfo_t *out; - int i, j, count; - int miptex; - float len1, len2; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->texinfo = out; - loadmodel->numtexinfo = count; - - for ( i=0 ; ivecs[0][j] = LittleFloat (in->vecs[0][j]); - out->vecs[1][j] = LittleFloat (in->vecs[1][j]); - } - len1 = Length (out->vecs[0]); - len2 = Length (out->vecs[1]); - - len1 = (len1 + len2)/2; - if (len1 < 0.32) - out->mipadjust = 4; - else if (len1 < 0.49) - out->mipadjust = 3; - else if (len1 < 0.99) - out->mipadjust = 2; - else - out->mipadjust = 1; - - miptex = LittleLong (in->miptex); - out->flags = LittleLong (in->flags); - - if (!loadmodel->textures) - { - out->texture = r_notexture_mip; // checkerboard texture - out->flags = 0; - } - else - { - if (miptex >= loadmodel->numtextures) - Sys_Error ("miptex >= loadmodel->numtextures"); - out->texture = loadmodel->textures[miptex]; - if (!out->texture) - { - out->texture = r_notexture_mip; // texture not found - out->flags = 0; - } - } - } -} - -/* -================ -CalcSurfaceExtents - -Fills in s->texturemins[] and s->extents[] -================ -*/ -void CalcSurfaceExtents (msurface_t *s) -{ - float mins[2], maxs[2], val; - int i,j, e; - mvertex_t *v; - mtexinfo_t *tex; - int bmins[2], bmaxs[2]; - - mins[0] = mins[1] = 999999; - maxs[0] = maxs[1] = -99999; - - tex = s->texinfo; - - for (i=0 ; inumedges ; i++) - { - e = loadmodel->surfedges[s->firstedge+i]; - if (e >= 0) - v = &loadmodel->vertexes[loadmodel->edges[e].v[0]]; - else - v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]]; - - for (j=0 ; j<2 ; j++) - { - val = v->position[0] * tex->vecs[j][0] + - v->position[1] * tex->vecs[j][1] + - v->position[2] * tex->vecs[j][2] + - tex->vecs[j][3]; - if (val < mins[j]) - mins[j] = val; - if (val > maxs[j]) - maxs[j] = val; - } - } - - for (i=0 ; i<2 ; i++) - { - bmins[i] = floor(mins[i]/16); - bmaxs[i] = ceil(maxs[i]/16); - - s->texturemins[i] = bmins[i] * 16; - s->extents[i] = (bmaxs[i] - bmins[i]) * 16; - if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 512 /* 256 */ ) - Sys_Error ("Bad surface extents"); - } -} - - -/* -================= -Mod_LoadFaces -================= -*/ -void Mod_LoadFaces (lump_t *l) -{ - dface_t *in; - msurface_t *out; - int i, count, surfnum; - int planenum, side; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->surfaces = out; - loadmodel->numsurfaces = count; - - for ( surfnum=0 ; surfnumfirstedge = LittleLong(in->firstedge); - out->numedges = LittleShort(in->numedges); - out->flags = 0; - - planenum = LittleShort(in->planenum); - side = LittleShort(in->side); - if (side) - out->flags |= SURF_PLANEBACK; - - out->plane = loadmodel->planes + planenum; - - out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo); - - CalcSurfaceExtents (out); - - // lighting info - - for (i=0 ; istyles[i] = in->styles[i]; - i = LittleLong(in->lightofs); - if (i == -1) - out->samples = NULL; - else - out->samples = loadmodel->lightdata + (i * 3); - - // set the drawing flags flag - - if (!strncmp(out->texinfo->texture->name,"sky",3)) // sky - { - out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED); -#ifndef QUAKE2 - GL_SubdivideSurface (out); // cut up polygon for warps -#endif - continue; - } - - if (!strncmp(out->texinfo->texture->name,"*",1)) // turbulent - { - out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED); - for (i=0 ; i<2 ; i++) - { - out->extents[i] = 16384; - out->texturemins[i] = -8192; - } - GL_SubdivideSurface (out); // cut up polygon for warps - continue; - } - } -} - - -/* -================= -Mod_SetParent -================= -*/ -void Mod_SetParent (mnode_t *node, mnode_t *parent) -{ - node->parent = parent; - if (node->contents < 0) - return; - Mod_SetParent (node->children[0], node); - Mod_SetParent (node->children[1], node); -} - -/* -================= -Mod_LoadNodes -================= -*/ -void Mod_LoadNodes (lump_t *l) -{ - int i, j, count, p; - dnode_t *in; - mnode_t *out; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->nodes = out; - loadmodel->numnodes = count; - - for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); - out->minmaxs[3+j] = LittleShort (in->maxs[j]); - } - - p = LittleLong(in->planenum); - out->plane = loadmodel->planes + p; - - out->firstsurface = LittleShort (in->firstface); - out->numsurfaces = LittleShort (in->numfaces); - - for (j=0 ; j<2 ; j++) - { - p = LittleShort (in->children[j]); - if (p >= 0) - out->children[j] = loadmodel->nodes + p; - else - out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p)); - } - } - - Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs -} - -/* -================= -Mod_LoadLeafs -================= -*/ -void Mod_LoadLeafs (lump_t *l) -{ - dleaf_t *in; - mleaf_t *out; - int i, j, count, p; - qboolean isnotmap = true; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->leafs = out; - loadmodel->numleafs = count; - if (!strncmp("maps/", loadmodel->name,5)) - isnotmap = false; - for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); - out->minmaxs[3+j] = LittleShort (in->maxs[j]); - } - - p = LittleLong(in->contents); - out->contents = p; - - out->firstmarksurface = loadmodel->marksurfaces + - LittleShort(in->firstmarksurface); - out->nummarksurfaces = LittleShort(in->nummarksurfaces); - - p = LittleLong(in->visofs); - if (p == -1) - out->compressed_vis = NULL; - else - out->compressed_vis = loadmodel->visdata + p; - out->efrags = NULL; - - for (j=0 ; j<4 ; j++) - out->ambient_sound_level[j] = in->ambient_level[j]; - - // gl underwater warp - if (out->contents != CONTENTS_EMPTY) - { - for (j=0 ; jnummarksurfaces ; j++) - out->firstmarksurface[j]->flags |= SURF_UNDERWATER; - } - if (isnotmap) - { - for (j=0 ; jnummarksurfaces ; j++) - out->firstmarksurface[j]->flags |= SURF_DONTWARP; - } - } -} - -/* -================= -Mod_LoadClipnodes -================= -*/ -void Mod_LoadClipnodes (lump_t *l) -{ - dclipnode_t *in, *out; - int i, count; - hull_t *hull; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->clipnodes = out; - loadmodel->numclipnodes = count; - - hull = &loadmodel->hulls[1]; - hull->clipnodes = out; - hull->firstclipnode = 0; - hull->lastclipnode = count-1; - hull->planes = loadmodel->planes; - hull->clip_mins[0] = -16; - hull->clip_mins[1] = -16; - hull->clip_mins[2] = -24; - hull->clip_maxs[0] = 16; - hull->clip_maxs[1] = 16; - hull->clip_maxs[2] = 32; - - hull = &loadmodel->hulls[2]; - hull->clipnodes = out; - hull->firstclipnode = 0; - hull->lastclipnode = count-1; - hull->planes = loadmodel->planes; - hull->clip_mins[0] = -32; - hull->clip_mins[1] = -32; - hull->clip_mins[2] = -24; - hull->clip_maxs[0] = 32; - hull->clip_maxs[1] = 32; - hull->clip_maxs[2] = 64; - - for (i=0 ; iplanenum = LittleLong(in->planenum); - out->children[0] = LittleShort(in->children[0]); - out->children[1] = LittleShort(in->children[1]); - } -} - -/* -================= -Mod_MakeHull0 - -Deplicate the drawing hull structure as a clipping hull -================= -*/ -void Mod_MakeHull0 (void) -{ - mnode_t *in, *child; - dclipnode_t *out; - int i, j, count; - hull_t *hull; - - hull = &loadmodel->hulls[0]; - - in = loadmodel->nodes; - count = loadmodel->numnodes; - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - hull->clipnodes = out; - hull->firstclipnode = 0; - hull->lastclipnode = count-1; - hull->planes = loadmodel->planes; - - for (i=0 ; iplanenum = in->plane - loadmodel->planes; - for (j=0 ; j<2 ; j++) - { - child = in->children[j]; - if (child->contents < 0) - out->children[j] = child->contents; - else - out->children[j] = child - loadmodel->nodes; - } - } -} - -/* -================= -Mod_LoadMarksurfaces -================= -*/ -void Mod_LoadMarksurfaces (lump_t *l) -{ - int i, j, count; - short *in; - msurface_t **out; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->marksurfaces = out; - loadmodel->nummarksurfaces = count; - - for ( i=0 ; i= loadmodel->numsurfaces) - Sys_Error ("Mod_ParseMarksurfaces: bad surface number"); - out[i] = loadmodel->surfaces + j; - } -} - -/* -================= -Mod_LoadSurfedges -================= -*/ -void Mod_LoadSurfedges (lump_t *l) -{ - int i, count; - int *in, *out; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->surfedges = out; - loadmodel->numsurfedges = count; - - for ( i=0 ; ifileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*2*sizeof(*out), loadname); - - loadmodel->planes = out; - loadmodel->numplanes = count; - - for ( i=0 ; inormal[j] = LittleFloat (in->normal[j]); - if (out->normal[j] < 0) - bits |= 1<dist = LittleFloat (in->dist); - out->type = LittleLong (in->type); - out->signbits = bits; - } -} - -/* -================= -RadiusFromBounds -================= -*/ -float RadiusFromBounds (vec3_t mins, vec3_t maxs) -{ - int i; - vec3_t corner; - - for (i=0 ; i<3 ; i++) - { - corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]); - } - - return Length (corner); -} - -/* -================= -Mod_LoadBrushModel -================= -*/ -void Mod_LoadBrushModel (model_t *mod, void *buffer) -{ - int i, j; - dheader_t *header; - dmodel_t *bm; - - loadmodel->type = mod_brush; - - header = (dheader_t *)buffer; - - i = LittleLong (header->version); - if (i != BSPVERSION) - Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION); - -// swap all the lumps - mod_base = (byte *)header; - - for (i=0 ; ichecksum = 0; - mod->checksum2 = 0; - - for (i = 0; i < HEADER_LUMPS; i++) { - if (i == LUMP_ENTITIES) - continue; - mod->checksum ^= LittleLong(Com_BlockChecksum(mod_base + header->lumps[i].fileofs, - header->lumps[i].filelen)); - - if (i == LUMP_VISIBILITY || i == LUMP_LEAFS || i == LUMP_NODES) - continue; - mod->checksum2 ^= LittleLong(Com_BlockChecksum(mod_base + header->lumps[i].fileofs, - header->lumps[i].filelen)); - } - -// load into heap - - Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]); - Mod_LoadEdges (&header->lumps[LUMP_EDGES]); - Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]); - Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]); - Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); - Mod_LoadPlanes (&header->lumps[LUMP_PLANES]); - Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); - Mod_LoadFaces (&header->lumps[LUMP_FACES]); - Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]); - Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); - Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]); - Mod_LoadNodes (&header->lumps[LUMP_NODES]); - Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]); - Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]); - Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]); - - Mod_MakeHull0 (); - - mod->numframes = 2; // regular and alternate animation - mod->flags = 0; - -// -// set up the submodels (FIXME: this is confusing) -// - for (i=0 ; inumsubmodels ; i++) - { - bm = &mod->submodels[i]; - - mod->hulls[0].firstclipnode = bm->headnode[0]; - for (j=1 ; jhulls[j].firstclipnode = bm->headnode[j]; - mod->hulls[j].lastclipnode = mod->numclipnodes-1; - } - - mod->firstmodelsurface = bm->firstface; - mod->nummodelsurfaces = bm->numfaces; - - VectorCopy (bm->maxs, mod->maxs); - VectorCopy (bm->mins, mod->mins); - - mod->radius = RadiusFromBounds (mod->mins, mod->maxs); - - mod->numleafs = bm->visleafs; - - if (i < mod->numsubmodels-1) - { // duplicate the basic information - char name[10]; - - snprintf (name, sizeof(name), "*%i", i+1); - loadmodel = Mod_FindName (name); - *loadmodel = *mod; - strcpy (loadmodel->name, name); - mod = loadmodel; - } - } -} diff --git a/source/model_brush.c b/source/model_brush.c new file mode 100644 index 0000000..ca3ce39 --- /dev/null +++ b/source/model_brush.c @@ -0,0 +1,1027 @@ +/* + model_brush.c + + model loading and caching + + Copyright (C) 1996-1997 Id Software, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + + $Id$ +*/ + +// models are the only shared resource between a client and server running +// on the same machine. + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "r_local.h" +#include "sys.h" +#include "console.h" +#include "qendian.h" +#include "checksum.h" +#include "glquake.h" + +byte *mod_base; + +extern char loadname[]; +extern model_t *loadmodel; +extern byte mod_novis[]; + +extern const int mod_lightmap_bytes; + +void Mod_LoadMMNearest(miptex_t *mt, texture_t *tx); +void Mod_LoadLighting (lump_t *l); + +/* +=============== +Mod_PointInLeaf +=============== +*/ +mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model) +{ + mnode_t *node; + float d; + mplane_t *plane; + + if (!model || !model->nodes) + Sys_Error ("Mod_PointInLeaf: bad model"); + + node = model->nodes; + while (1) + { + if (node->contents < 0) + return (mleaf_t *)node; + plane = node->plane; + d = DotProduct (p, plane->normal) - plane->dist; + if (d > 0) + node = node->children[0]; + else + node = node->children[1]; + } + + return NULL; // never reached +} + +/* +=================== +Mod_DecompressVis +=================== +*/ +byte *Mod_DecompressVis (byte *in, model_t *model) +{ + static byte decompressed[MAX_MAP_LEAFS/8]; + int c; + byte *out; + int row; + + row = (model->numleafs+7)>>3; + out = decompressed; + + if (!in) + { // no vis info, so make all visible + while (row) + { + *out++ = 0xff; + row--; + } + return decompressed; + } + + do + { + if (*in) + { + *out++ = *in++; + continue; + } + + c = in[1]; + in += 2; + while (c) + { + *out++ = 0; + c--; + } + } while (out - decompressed < row); + + return decompressed; +} + +byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model) +{ + if (leaf == model->leafs) + return mod_novis; + return Mod_DecompressVis (leaf->compressed_vis, model); +} + +/* +=============================================================================== + + BRUSHMODEL LOADING + +=============================================================================== +*/ + +/* +================= +Mod_LoadTextures +================= +*/ +void Mod_LoadTextures (lump_t *l) +{ + int i, j, pixels, num, max, altmax; + miptex_t *mt; + texture_t *tx, *tx2; + texture_t *anims[10]; + texture_t *altanims[10]; + dmiptexlump_t *m; + + if (!l->filelen) + { + loadmodel->textures = NULL; + return; + } + m = (dmiptexlump_t *)(mod_base + l->fileofs); + + m->nummiptex = LittleLong (m->nummiptex); + + loadmodel->numtextures = m->nummiptex; + loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname); + + for (i=0 ; inummiptex ; i++) + { + m->dataofs[i] = LittleLong(m->dataofs[i]); + if (m->dataofs[i] == -1) + continue; + mt = (miptex_t *)((byte *)m + m->dataofs[i]); + mt->width = LittleLong (mt->width); + mt->height = LittleLong (mt->height); + for (j=0 ; joffsets[j] = LittleLong (mt->offsets[j]); + + if ( (mt->width & 15) || (mt->height & 15) ) + Sys_Error ("Texture %s is not 16 aligned", mt->name); + pixels = mt->width*mt->height/64*85; + tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname ); + loadmodel->textures[i] = tx; + + memcpy (tx->name, mt->name, sizeof(tx->name)); + tx->width = mt->width; + tx->height = mt->height; + for (j=0 ; joffsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t); + // the pixels immediately follow the structures + memcpy ( tx+1, mt+1, pixels); + + if (!strncmp(mt->name,"sky",3)) + R_InitSky (tx); + else + { + Mod_LoadMMNearest(mt, tx); + } + } + +// +// sequence the animations +// + for (i=0 ; inummiptex ; i++) + { + tx = loadmodel->textures[i]; + if (!tx || tx->name[0] != '+') + continue; + if (tx->anim_next) + continue; // allready sequenced + + // find the number of frames in the animation + memset (anims, 0, sizeof(anims)); + memset (altanims, 0, sizeof(altanims)); + + max = tx->name[1]; + altmax = 0; + if (max >= 'a' && max <= 'z') + max -= 'a' - 'A'; + if (max >= '0' && max <= '9') + { + max -= '0'; + altmax = 0; + anims[max] = tx; + max++; + } + else if (max >= 'A' && max <= 'J') + { + altmax = max - 'A'; + max = 0; + altanims[altmax] = tx; + altmax++; + } + else + Sys_Error ("Bad animating texture %s", tx->name); + + for (j=i+1 ; jnummiptex ; j++) + { + tx2 = loadmodel->textures[j]; + if (!tx2 || tx2->name[0] != '+') + continue; + if (strcmp (tx2->name+2, tx->name+2)) + continue; + + num = tx2->name[1]; + if (num >= 'a' && num <= 'z') + num -= 'a' - 'A'; + if (num >= '0' && num <= '9') + { + num -= '0'; + anims[num] = tx2; + if (num+1 > max) + max = num + 1; + } + else if (num >= 'A' && num <= 'J') + { + num = num - 'A'; + altanims[num] = tx2; + if (num+1 > altmax) + altmax = num+1; + } + else + Sys_Error ("Bad animating texture %s", tx->name); + } + +#define ANIM_CYCLE 2 + // link them all together + for (j=0 ; jname); + tx2->anim_total = max * ANIM_CYCLE; + tx2->anim_min = j * ANIM_CYCLE; + tx2->anim_max = (j+1) * ANIM_CYCLE; + tx2->anim_next = anims[ (j+1)%max ]; + if (altmax) + tx2->alternate_anims = altanims[0]; + } + for (j=0 ; jname); + tx2->anim_total = altmax * ANIM_CYCLE; + tx2->anim_min = j * ANIM_CYCLE; + tx2->anim_max = (j+1) * ANIM_CYCLE; + tx2->anim_next = altanims[ (j+1)%altmax ]; + if (max) + tx2->alternate_anims = anims[0]; + } + } +} + +/* +================= +Mod_LoadVisibility +================= +*/ +void Mod_LoadVisibility (lump_t *l) +{ + if (!l->filelen) + { + loadmodel->visdata = NULL; + return; + } + loadmodel->visdata = Hunk_AllocName ( l->filelen, loadname); + memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen); +} + + +/* +================= +Mod_LoadEntities +================= +*/ +void Mod_LoadEntities (lump_t *l) +{ + if (!l->filelen) + { + loadmodel->entities = NULL; + return; + } + loadmodel->entities = Hunk_AllocName ( l->filelen, loadname); + memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen); +} + +/* +================= +Mod_LoadVertexes +================= +*/ +void Mod_LoadVertexes (lump_t *l) +{ + dvertex_t *in; + mvertex_t *out; + int i, count; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->vertexes = out; + loadmodel->numvertexes = count; + + for ( i=0 ; iposition[0] = LittleFloat (in->point[0]); + out->position[1] = LittleFloat (in->point[1]); + out->position[2] = LittleFloat (in->point[2]); + } +} + +/* +================= +Mod_LoadSubmodels +================= +*/ +void Mod_LoadSubmodels (lump_t *l) +{ + dmodel_t *in; + dmodel_t *out; + int i, j, count; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->submodels = out; + loadmodel->numsubmodels = count; + + for ( i=0 ; imins[j] = LittleFloat (in->mins[j]) - 1; + out->maxs[j] = LittleFloat (in->maxs[j]) + 1; + out->origin[j] = LittleFloat (in->origin[j]); + } + for (j=0 ; jheadnode[j] = LittleLong (in->headnode[j]); + out->visleafs = LittleLong (in->visleafs); + out->firstface = LittleLong (in->firstface); + out->numfaces = LittleLong (in->numfaces); + } +} + +/* +================= +Mod_LoadEdges +================= +*/ +void Mod_LoadEdges (lump_t *l) +{ + dedge_t *in; + medge_t *out; + int i, count; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( (count + 1) * sizeof(*out), loadname); + + loadmodel->edges = out; + loadmodel->numedges = count; + + for ( i=0 ; iv[0] = (unsigned short)LittleShort(in->v[0]); + out->v[1] = (unsigned short)LittleShort(in->v[1]); + } +} + +/* +================= +Mod_LoadTexinfo +================= +*/ +void Mod_LoadTexinfo (lump_t *l) +{ + texinfo_t *in; + mtexinfo_t *out; + int i, j, count; + int miptex; + float len1, len2; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->texinfo = out; + loadmodel->numtexinfo = count; + + for ( i=0 ; ivecs[0][j] = LittleFloat (in->vecs[0][j]); + out->vecs[1][j] = LittleFloat (in->vecs[1][j]); + } + len1 = Length (out->vecs[0]); + len2 = Length (out->vecs[1]); + + len1 = (len1 + len2)/2; + if (len1 < 0.32) + out->mipadjust = 4; + else if (len1 < 0.49) + out->mipadjust = 3; + else if (len1 < 0.99) + out->mipadjust = 2; + else + out->mipadjust = 1; + + miptex = LittleLong (in->miptex); + out->flags = LittleLong (in->flags); + + if (!loadmodel->textures) + { + out->texture = r_notexture_mip; // checkerboard texture + out->flags = 0; + } + else + { + if (miptex >= loadmodel->numtextures) + Sys_Error ("miptex >= loadmodel->numtextures"); + out->texture = loadmodel->textures[miptex]; + if (!out->texture) + { + out->texture = r_notexture_mip; // texture not found + out->flags = 0; + } + } + } +} + +/* +================ +CalcSurfaceExtents + +Fills in s->texturemins[] and s->extents[] +================ +*/ +void CalcSurfaceExtents (msurface_t *s) +{ + float mins[2], maxs[2], val; + int i,j, e; + mvertex_t *v; + mtexinfo_t *tex; + int bmins[2], bmaxs[2]; + + mins[0] = mins[1] = 999999; + maxs[0] = maxs[1] = -99999; + + tex = s->texinfo; + + for (i=0 ; inumedges ; i++) + { + e = loadmodel->surfedges[s->firstedge+i]; + if (e >= 0) + v = &loadmodel->vertexes[loadmodel->edges[e].v[0]]; + else + v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]]; + + for (j=0 ; j<2 ; j++) + { + val = v->position[0] * tex->vecs[j][0] + + v->position[1] * tex->vecs[j][1] + + v->position[2] * tex->vecs[j][2] + + tex->vecs[j][3]; + if (val < mins[j]) + mins[j] = val; + if (val > maxs[j]) + maxs[j] = val; + } + } + + for (i=0 ; i<2 ; i++) + { + bmins[i] = floor(mins[i]/16); + bmaxs[i] = ceil(maxs[i]/16); + + s->texturemins[i] = bmins[i] * 16; + s->extents[i] = (bmaxs[i] - bmins[i]) * 16; + if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 512 /* 256 */ ) + Sys_Error ("Bad surface extents"); + } +} + +/* +================= +Mod_LoadFaces +================= +*/ +void Mod_LoadFaces (lump_t *l) +{ + dface_t *in; + msurface_t *out; + int i, count, surfnum; + int planenum, side; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->surfaces = out; + loadmodel->numsurfaces = count; + + for ( surfnum=0 ; surfnumfirstedge = LittleLong(in->firstedge); + out->numedges = LittleShort(in->numedges); + out->flags = 0; + + planenum = LittleShort(in->planenum); + side = LittleShort(in->side); + if (side) + out->flags |= SURF_PLANEBACK; + + out->plane = loadmodel->planes + planenum; + + out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo); + + CalcSurfaceExtents (out); + + // lighting info + + for (i=0 ; istyles[i] = in->styles[i]; + i = LittleLong(in->lightofs); + if (i == -1) + out->samples = NULL; + else + out->samples = loadmodel->lightdata + (i * mod_lightmap_bytes); + + // set the drawing flags flag + + if (!strncmp(out->texinfo->texture->name,"sky",3)) // sky + { + out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED); + continue; + } + + if (!strncmp(out->texinfo->texture->name,"*",1)) // turbulent + { + out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED); + for (i=0 ; i<2 ; i++) + { + out->extents[i] = 16384; + out->texturemins[i] = -8192; + } + GL_SubdivideSurface (out); // cut up polygon for warps + continue; + } + } +} + +/* +================= +Mod_SetParent +================= +*/ +void Mod_SetParent (mnode_t *node, mnode_t *parent) +{ + node->parent = parent; + if (node->contents < 0) + return; + Mod_SetParent (node->children[0], node); + Mod_SetParent (node->children[1], node); +} + +/* +================= +Mod_LoadNodes +================= +*/ +void Mod_LoadNodes (lump_t *l) +{ + int i, j, count, p; + dnode_t *in; + mnode_t *out; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->nodes = out; + loadmodel->numnodes = count; + + for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); + out->minmaxs[3+j] = LittleShort (in->maxs[j]); + } + + p = LittleLong(in->planenum); + out->plane = loadmodel->planes + p; + + out->firstsurface = LittleShort (in->firstface); + out->numsurfaces = LittleShort (in->numfaces); + + for (j=0 ; j<2 ; j++) + { + p = LittleShort (in->children[j]); + if (p >= 0) + out->children[j] = loadmodel->nodes + p; + else + out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p)); + } + } + + Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs +} + +/* +================= +Mod_LoadLeafs +================= +*/ +void Mod_LoadLeafs (lump_t *l) +{ + dleaf_t *in; + mleaf_t *out; + int i, j, count, p; + qboolean isnotmap = true; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->leafs = out; + loadmodel->numleafs = count; + if (!strncmp("maps/", loadmodel->name,5)) + isnotmap = false; + for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); + out->minmaxs[3+j] = LittleShort (in->maxs[j]); + } + + p = LittleLong(in->contents); + out->contents = p; + + out->firstmarksurface = loadmodel->marksurfaces + + LittleShort(in->firstmarksurface); + out->nummarksurfaces = LittleShort(in->nummarksurfaces); + + p = LittleLong(in->visofs); + if (p == -1) + out->compressed_vis = NULL; + else + out->compressed_vis = loadmodel->visdata + p; + out->efrags = NULL; + + for (j=0 ; j<4 ; j++) + out->ambient_sound_level[j] = in->ambient_level[j]; + + // gl underwater warp + if (out->contents != CONTENTS_EMPTY) + { + for (j=0 ; jnummarksurfaces ; j++) + out->firstmarksurface[j]->flags |= SURF_UNDERWATER; + } + if (isnotmap) + { + for (j=0 ; jnummarksurfaces ; j++) + out->firstmarksurface[j]->flags |= SURF_DONTWARP; + } + } +} + +/* +================= +Mod_LoadClipnodes +================= +*/ +void Mod_LoadClipnodes (lump_t *l) +{ + dclipnode_t *in, *out; + int i, count; + hull_t *hull; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->clipnodes = out; + loadmodel->numclipnodes = count; + + hull = &loadmodel->hulls[1]; + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + hull->clip_mins[0] = -16; + hull->clip_mins[1] = -16; + hull->clip_mins[2] = -24; + hull->clip_maxs[0] = 16; + hull->clip_maxs[1] = 16; + hull->clip_maxs[2] = 32; + + hull = &loadmodel->hulls[2]; + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + hull->clip_mins[0] = -32; + hull->clip_mins[1] = -32; + hull->clip_mins[2] = -24; + hull->clip_maxs[0] = 32; + hull->clip_maxs[1] = 32; + hull->clip_maxs[2] = 64; + + for (i=0 ; iplanenum = LittleLong(in->planenum); + out->children[0] = LittleShort(in->children[0]); + out->children[1] = LittleShort(in->children[1]); + } +} + +/* +================= +Mod_MakeHull0 + +Deplicate the drawing hull structure as a clipping hull +================= +*/ +void Mod_MakeHull0 (void) +{ + mnode_t *in, *child; + dclipnode_t *out; + int i, j, count; + hull_t *hull; + + hull = &loadmodel->hulls[0]; + + in = loadmodel->nodes; + count = loadmodel->numnodes; + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + + for (i=0 ; iplanenum = in->plane - loadmodel->planes; + for (j=0 ; j<2 ; j++) + { + child = in->children[j]; + if (child->contents < 0) + out->children[j] = child->contents; + else + out->children[j] = child - loadmodel->nodes; + } + } +} + +/* +================= +Mod_LoadMarksurfaces +================= +*/ +void Mod_LoadMarksurfaces (lump_t *l) +{ + int i, j, count; + short *in; + msurface_t **out; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->marksurfaces = out; + loadmodel->nummarksurfaces = count; + + for ( i=0 ; i= loadmodel->numsurfaces) + Sys_Error ("Mod_ParseMarksurfaces: bad surface number"); + out[i] = loadmodel->surfaces + j; + } +} + +/* +================= +Mod_LoadSurfedges +================= +*/ +void Mod_LoadSurfedges (lump_t *l) +{ + int i, count; + int *in, *out; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->surfedges = out; + loadmodel->numsurfedges = count; + + for ( i=0 ; ifileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_AllocName ( count*2*sizeof(*out), loadname); + + loadmodel->planes = out; + loadmodel->numplanes = count; + + for ( i=0 ; inormal[j] = LittleFloat (in->normal[j]); + if (out->normal[j] < 0) + bits |= 1<dist = LittleFloat (in->dist); + out->type = LittleLong (in->type); + out->signbits = bits; + } +} + +/* +================= +RadiusFromBounds +================= +*/ +float RadiusFromBounds (vec3_t mins, vec3_t maxs) +{ + int i; + vec3_t corner; + + for (i=0 ; i<3 ; i++) + { + corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]); + } + + return Length (corner); +} + +/* +================= +Mod_LoadBrushModel +================= +*/ +void Mod_LoadBrushModel (model_t *mod, void *buffer) +{ + int i, j; + dheader_t *header; + dmodel_t *bm; + + loadmodel->type = mod_brush; + + header = (dheader_t *)buffer; + + i = LittleLong (header->version); + if (i != BSPVERSION) + Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION); + +// swap all the lumps + mod_base = (byte *)header; + + for (i=0 ; ichecksum = 0; + mod->checksum2 = 0; + + for (i = 0; i < HEADER_LUMPS; i++) { + if (i == LUMP_ENTITIES) + continue; + mod->checksum ^= LittleLong(Com_BlockChecksum(mod_base + header->lumps[i].fileofs, + header->lumps[i].filelen)); + + if (i == LUMP_VISIBILITY || i == LUMP_LEAFS || i == LUMP_NODES) + continue; + mod->checksum2 ^= LittleLong(Com_BlockChecksum(mod_base + header->lumps[i].fileofs, + header->lumps[i].filelen)); + } + +// load into heap + + Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]); + Mod_LoadEdges (&header->lumps[LUMP_EDGES]); + Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]); + Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]); + Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); + Mod_LoadPlanes (&header->lumps[LUMP_PLANES]); + Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); + Mod_LoadFaces (&header->lumps[LUMP_FACES]); + Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]); + Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); + Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]); + Mod_LoadNodes (&header->lumps[LUMP_NODES]); + Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]); + Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]); + Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]); + + Mod_MakeHull0 (); + + mod->numframes = 2; // regular and alternate animation + mod->flags = 0; + +// +// set up the submodels (FIXME: this is confusing) +// + for (i=0 ; inumsubmodels ; i++) + { + bm = &mod->submodels[i]; + + mod->hulls[0].firstclipnode = bm->headnode[0]; + for (j=1 ; jhulls[j].firstclipnode = bm->headnode[j]; + mod->hulls[j].lastclipnode = mod->numclipnodes-1; + } + + mod->firstmodelsurface = bm->firstface; + mod->nummodelsurfaces = bm->numfaces; + + VectorCopy (bm->maxs, mod->maxs); + VectorCopy (bm->mins, mod->mins); + + mod->radius = RadiusFromBounds (mod->mins, mod->maxs); + + mod->numleafs = bm->visleafs; + + if (i < mod->numsubmodels-1) + { // duplicate the basic information + char name[10]; + + snprintf (name, sizeof(name), "*%i", i+1); + loadmodel = Mod_FindName (name); + *loadmodel = *mod; + strcpy (loadmodel->name, name); + mod = loadmodel; + } + } +} diff --git a/source/sw_model_brush.c b/source/sw_model_brush.c index 9f9dee9..57bca61 100644 --- a/source/sw_model_brush.c +++ b/source/sw_model_brush.c @@ -1,5 +1,5 @@ /* - model.c + sw_model_brush.c model loading and caching @@ -39,248 +39,18 @@ extern char loadname[]; extern model_t *loadmodel; extern byte mod_novis[]; +extern byte *mod_base; -/* -=============== -Mod_PointInLeaf -=============== -*/ -mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model) +const int mod_lightmap_bytes = 1; + +void +GL_SubdivideSurface (msurface_t *fa) { - mnode_t *node; - float d; - mplane_t *plane; - - if (!model || !model->nodes) - Sys_Error ("Mod_PointInLeaf: bad model"); - - node = model->nodes; - while (1) - { - if (node->contents < 0) - return (mleaf_t *)node; - plane = node->plane; - d = DotProduct (p, plane->normal) - plane->dist; - if (d > 0) - node = node->children[0]; - else - node = node->children[1]; - } - - return NULL; // never reached } - -/* -=================== -Mod_DecompressVis -=================== -*/ -byte *Mod_DecompressVis (byte *in, model_t *model) +void +Mod_LoadMMNearest(miptex_t *mt, texture_t *tx) { - static byte decompressed[MAX_MAP_LEAFS/8]; - int c; - byte *out; - int row; - - row = (model->numleafs+7)>>3; - out = decompressed; - - if (!in) - { // no vis info, so make all visible - while (row) - { - *out++ = 0xff; - row--; - } - return decompressed; - } - - do - { - if (*in) - { - *out++ = *in++; - continue; - } - - c = in[1]; - in += 2; - while (c) - { - *out++ = 0; - c--; - } - } while (out - decompressed < row); - - return decompressed; -} - -byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model) -{ - if (leaf == model->leafs) - return mod_novis; - return Mod_DecompressVis (leaf->compressed_vis, model); -} - -/* -=============================================================================== - - BRUSHMODEL LOADING - -=============================================================================== -*/ - -byte *mod_base; - - -/* -================= -Mod_LoadTextures -================= -*/ -void Mod_LoadTextures (lump_t *l) -{ - int i, j, pixels, num, max, altmax; - miptex_t *mt; - texture_t *tx, *tx2; - texture_t *anims[10]; - texture_t *altanims[10]; - dmiptexlump_t *m; - - if (!l->filelen) - { - loadmodel->textures = NULL; - return; - } - m = (dmiptexlump_t *)(mod_base + l->fileofs); - - m->nummiptex = LittleLong (m->nummiptex); - - loadmodel->numtextures = m->nummiptex; - loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname); - - for (i=0 ; inummiptex ; i++) - { - m->dataofs[i] = LittleLong(m->dataofs[i]); - if (m->dataofs[i] == -1) - continue; - mt = (miptex_t *)((byte *)m + m->dataofs[i]); - mt->width = LittleLong (mt->width); - mt->height = LittleLong (mt->height); - for (j=0 ; joffsets[j] = LittleLong (mt->offsets[j]); - - if ( (mt->width & 15) || (mt->height & 15) ) - Sys_Error ("Texture %s is not 16 aligned", mt->name); - pixels = mt->width*mt->height/64*85; - tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname ); - loadmodel->textures[i] = tx; - - memcpy (tx->name, mt->name, sizeof(tx->name)); - tx->width = mt->width; - tx->height = mt->height; - for (j=0 ; joffsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t); - // the pixels immediately follow the structures - memcpy ( tx+1, mt+1, pixels); - - if (!strncmp(mt->name,"sky",3)) - R_InitSky (tx); - } - -// -// sequence the animations -// - for (i=0 ; inummiptex ; i++) - { - tx = loadmodel->textures[i]; - if (!tx || tx->name[0] != '+') - continue; - if (tx->anim_next) - continue; // allready sequenced - - // find the number of frames in the animation - memset (anims, 0, sizeof(anims)); - memset (altanims, 0, sizeof(altanims)); - - max = tx->name[1]; - altmax = 0; - if (max >= 'a' && max <= 'z') - max -= 'a' - 'A'; - if (max >= '0' && max <= '9') - { - max -= '0'; - altmax = 0; - anims[max] = tx; - max++; - } - else if (max >= 'A' && max <= 'J') - { - altmax = max - 'A'; - max = 0; - altanims[altmax] = tx; - altmax++; - } - else - Sys_Error ("Bad animating texture %s", tx->name); - - for (j=i+1 ; jnummiptex ; j++) - { - tx2 = loadmodel->textures[j]; - if (!tx2 || tx2->name[0] != '+') - continue; - if (strcmp (tx2->name+2, tx->name+2)) - continue; - - num = tx2->name[1]; - if (num >= 'a' && num <= 'z') - num -= 'a' - 'A'; - if (num >= '0' && num <= '9') - { - num -= '0'; - anims[num] = tx2; - if (num+1 > max) - max = num + 1; - } - else if (num >= 'A' && num <= 'J') - { - num = num - 'A'; - altanims[num] = tx2; - if (num+1 > altmax) - altmax = num+1; - } - else - Sys_Error ("Bad animating texture %s", tx->name); - } - -#define ANIM_CYCLE 2 - // link them all together - for (j=0 ; jname); - tx2->anim_total = max * ANIM_CYCLE; - tx2->anim_min = j * ANIM_CYCLE; - tx2->anim_max = (j+1) * ANIM_CYCLE; - tx2->anim_next = anims[ (j+1)%max ]; - if (altmax) - tx2->alternate_anims = altanims[0]; - } - for (j=0 ; jname); - tx2->anim_total = altmax * ANIM_CYCLE; - tx2->anim_min = j * ANIM_CYCLE; - tx2->anim_max = (j+1) * ANIM_CYCLE; - tx2->anim_next = altanims[ (j+1)%altmax ]; - if (max) - tx2->alternate_anims = anims[0]; - } - } } /* @@ -298,726 +68,3 @@ void Mod_LoadLighting (lump_t *l) loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname); memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen); } - - -/* -================= -Mod_LoadVisibility -================= -*/ -void Mod_LoadVisibility (lump_t *l) -{ - if (!l->filelen) - { - loadmodel->visdata = NULL; - return; - } - loadmodel->visdata = Hunk_AllocName ( l->filelen, loadname); - memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen); -} - - -/* -================= -Mod_LoadEntities -================= -*/ -void Mod_LoadEntities (lump_t *l) -{ - if (!l->filelen) - { - loadmodel->entities = NULL; - return; - } - loadmodel->entities = Hunk_AllocName ( l->filelen, loadname); - memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen); -} - - -/* -================= -Mod_LoadVertexes -================= -*/ -void Mod_LoadVertexes (lump_t *l) -{ - dvertex_t *in; - mvertex_t *out; - int i, count; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->vertexes = out; - loadmodel->numvertexes = count; - - for ( i=0 ; iposition[0] = LittleFloat (in->point[0]); - out->position[1] = LittleFloat (in->point[1]); - out->position[2] = LittleFloat (in->point[2]); - } -} - -/* -================= -Mod_LoadSubmodels -================= -*/ -void Mod_LoadSubmodels (lump_t *l) -{ - dmodel_t *in; - dmodel_t *out; - int i, j, count; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->submodels = out; - loadmodel->numsubmodels = count; - - for ( i=0 ; imins[j] = LittleFloat (in->mins[j]) - 1; - out->maxs[j] = LittleFloat (in->maxs[j]) + 1; - out->origin[j] = LittleFloat (in->origin[j]); - } - for (j=0 ; jheadnode[j] = LittleLong (in->headnode[j]); - out->visleafs = LittleLong (in->visleafs); - out->firstface = LittleLong (in->firstface); - out->numfaces = LittleLong (in->numfaces); - } -} - -/* -================= -Mod_LoadEdges -================= -*/ -void Mod_LoadEdges (lump_t *l) -{ - dedge_t *in; - medge_t *out; - int i, count; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( (count + 1) * sizeof(*out), loadname); - - loadmodel->edges = out; - loadmodel->numedges = count; - - for ( i=0 ; iv[0] = (unsigned short)LittleShort(in->v[0]); - out->v[1] = (unsigned short)LittleShort(in->v[1]); - } -} - -/* -================= -Mod_LoadTexinfo -================= -*/ -void Mod_LoadTexinfo (lump_t *l) -{ - texinfo_t *in; - mtexinfo_t *out; - int i, j, count; - int miptex; - float len1, len2; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->texinfo = out; - loadmodel->numtexinfo = count; - - for ( i=0 ; ivecs[0][j] = LittleFloat (in->vecs[0][j]); - out->vecs[1][j] = LittleFloat (in->vecs[1][j]); - } - len1 = Length (out->vecs[0]); - len2 = Length (out->vecs[1]); - - len1 = (len1 + len2)/2; - if (len1 < 0.32) - out->mipadjust = 4; - else if (len1 < 0.49) - out->mipadjust = 3; - else if (len1 < 0.99) - out->mipadjust = 2; - else - out->mipadjust = 1; - - miptex = LittleLong (in->miptex); - out->flags = LittleLong (in->flags); - - if (!loadmodel->textures) - { - out->texture = r_notexture_mip; // checkerboard texture - out->flags = 0; - } - else - { - if (miptex >= loadmodel->numtextures) - Sys_Error ("miptex >= loadmodel->numtextures"); - out->texture = loadmodel->textures[miptex]; - if (!out->texture) - { - out->texture = r_notexture_mip; // texture not found - out->flags = 0; - } - } - } -} - -/* -================ -CalcSurfaceExtents - -Fills in s->texturemins[] and s->extents[] -================ -*/ -void CalcSurfaceExtents (msurface_t *s) -{ - float mins[2], maxs[2], val; - int i,j, e; - mvertex_t *v; - mtexinfo_t *tex; - int bmins[2], bmaxs[2]; - - mins[0] = mins[1] = 999999; - maxs[0] = maxs[1] = -99999; - - tex = s->texinfo; - - for (i=0 ; inumedges ; i++) - { - e = loadmodel->surfedges[s->firstedge+i]; - if (e >= 0) - v = &loadmodel->vertexes[loadmodel->edges[e].v[0]]; - else - v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]]; - - for (j=0 ; j<2 ; j++) - { - val = v->position[0] * tex->vecs[j][0] + - v->position[1] * tex->vecs[j][1] + - v->position[2] * tex->vecs[j][2] + - tex->vecs[j][3]; - if (val < mins[j]) - mins[j] = val; - if (val > maxs[j]) - maxs[j] = val; - } - } - - for (i=0 ; i<2 ; i++) - { - bmins[i] = floor(mins[i]/16); - bmaxs[i] = ceil(maxs[i]/16); - - s->texturemins[i] = bmins[i] * 16; - s->extents[i] = (bmaxs[i] - bmins[i]) * 16; - if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 512 /* 256 */ ) - Sys_Error ("Bad surface extents"); - } -} - - -/* -================= -Mod_LoadFaces -================= -*/ -void Mod_LoadFaces (lump_t *l) -{ - dface_t *in; - msurface_t *out; - int i, count, surfnum; - int planenum, side; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->surfaces = out; - loadmodel->numsurfaces = count; - - for ( surfnum=0 ; surfnumfirstedge = LittleLong(in->firstedge); - out->numedges = LittleShort(in->numedges); - out->flags = 0; - - planenum = LittleShort(in->planenum); - side = LittleShort(in->side); - if (side) - out->flags |= SURF_PLANEBACK; - - out->plane = loadmodel->planes + planenum; - - out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo); - - CalcSurfaceExtents (out); - - // lighting info - - for (i=0 ; istyles[i] = in->styles[i]; - i = LittleLong(in->lightofs); - if (i == -1) - out->samples = NULL; - else - out->samples = loadmodel->lightdata + i; - - // set the drawing flags flag - - if (!strncmp(out->texinfo->texture->name,"sky",3)) // sky - { - out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED); - continue; - } - - if (!strncmp(out->texinfo->texture->name,"*",1)) // turbulent - { - out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED); - for (i=0 ; i<2 ; i++) - { - out->extents[i] = 16384; - out->texturemins[i] = -8192; - } - continue; - } - } -} - - -/* -================= -Mod_SetParent -================= -*/ -void Mod_SetParent (mnode_t *node, mnode_t *parent) -{ - node->parent = parent; - if (node->contents < 0) - return; - Mod_SetParent (node->children[0], node); - Mod_SetParent (node->children[1], node); -} - -/* -================= -Mod_LoadNodes -================= -*/ -void Mod_LoadNodes (lump_t *l) -{ - int i, j, count, p; - dnode_t *in; - mnode_t *out; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->nodes = out; - loadmodel->numnodes = count; - - for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); - out->minmaxs[3+j] = LittleShort (in->maxs[j]); - } - - p = LittleLong(in->planenum); - out->plane = loadmodel->planes + p; - - out->firstsurface = LittleShort (in->firstface); - out->numsurfaces = LittleShort (in->numfaces); - - for (j=0 ; j<2 ; j++) - { - p = LittleShort (in->children[j]); - if (p >= 0) - out->children[j] = loadmodel->nodes + p; - else - out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p)); - } - } - - Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs -} - -/* -================= -Mod_LoadLeafs -================= -*/ -void Mod_LoadLeafs (lump_t *l) -{ - dleaf_t *in; - mleaf_t *out; - int i, j, count, p; - qboolean isnotmap = true; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->leafs = out; - loadmodel->numleafs = count; - if (!strncmp("maps/", loadmodel->name,5)) - isnotmap = false; - for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); - out->minmaxs[3+j] = LittleShort (in->maxs[j]); - } - - p = LittleLong(in->contents); - out->contents = p; - - out->firstmarksurface = loadmodel->marksurfaces + - LittleShort(in->firstmarksurface); - out->nummarksurfaces = LittleShort(in->nummarksurfaces); - - p = LittleLong(in->visofs); - if (p == -1) - out->compressed_vis = NULL; - else - out->compressed_vis = loadmodel->visdata + p; - out->efrags = NULL; - - for (j=0 ; j<4 ; j++) - out->ambient_sound_level[j] = in->ambient_level[j]; - } -} - -/* -================= -Mod_LoadClipnodes -================= -*/ -void Mod_LoadClipnodes (lump_t *l) -{ - dclipnode_t *in, *out; - int i, count; - hull_t *hull; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->clipnodes = out; - loadmodel->numclipnodes = count; - - hull = &loadmodel->hulls[1]; - hull->clipnodes = out; - hull->firstclipnode = 0; - hull->lastclipnode = count-1; - hull->planes = loadmodel->planes; - hull->clip_mins[0] = -16; - hull->clip_mins[1] = -16; - hull->clip_mins[2] = -24; - hull->clip_maxs[0] = 16; - hull->clip_maxs[1] = 16; - hull->clip_maxs[2] = 32; - - hull = &loadmodel->hulls[2]; - hull->clipnodes = out; - hull->firstclipnode = 0; - hull->lastclipnode = count-1; - hull->planes = loadmodel->planes; - hull->clip_mins[0] = -32; - hull->clip_mins[1] = -32; - hull->clip_mins[2] = -24; - hull->clip_maxs[0] = 32; - hull->clip_maxs[1] = 32; - hull->clip_maxs[2] = 64; - - for (i=0 ; iplanenum = LittleLong(in->planenum); - out->children[0] = LittleShort(in->children[0]); - out->children[1] = LittleShort(in->children[1]); - } -} - -/* -================= -Mod_MakeHull0 - -Deplicate the drawing hull structure as a clipping hull -================= -*/ -void Mod_MakeHull0 (void) -{ - mnode_t *in, *child; - dclipnode_t *out; - int i, j, count; - hull_t *hull; - - hull = &loadmodel->hulls[0]; - - in = loadmodel->nodes; - count = loadmodel->numnodes; - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - hull->clipnodes = out; - hull->firstclipnode = 0; - hull->lastclipnode = count-1; - hull->planes = loadmodel->planes; - - for (i=0 ; iplanenum = in->plane - loadmodel->planes; - for (j=0 ; j<2 ; j++) - { - child = in->children[j]; - if (child->contents < 0) - out->children[j] = child->contents; - else - out->children[j] = child - loadmodel->nodes; - } - } -} - -/* -================= -Mod_LoadMarksurfaces -================= -*/ -void Mod_LoadMarksurfaces (lump_t *l) -{ - int i, j, count; - short *in; - msurface_t **out; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->marksurfaces = out; - loadmodel->nummarksurfaces = count; - - for ( i=0 ; i= loadmodel->numsurfaces) - Sys_Error ("Mod_ParseMarksurfaces: bad surface number"); - out[i] = loadmodel->surfaces + j; - } -} - -/* -================= -Mod_LoadSurfedges -================= -*/ -void Mod_LoadSurfedges (lump_t *l) -{ - int i, count; - int *in, *out; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->surfedges = out; - loadmodel->numsurfedges = count; - - for ( i=0 ; ifileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*2*sizeof(*out), loadname); - - loadmodel->planes = out; - loadmodel->numplanes = count; - - for ( i=0 ; inormal[j] = LittleFloat (in->normal[j]); - if (out->normal[j] < 0) - bits |= 1<dist = LittleFloat (in->dist); - out->type = LittleLong (in->type); - out->signbits = bits; - } -} - -/* -================= -RadiusFromBounds -================= -*/ -float RadiusFromBounds (vec3_t mins, vec3_t maxs) -{ - int i; - vec3_t corner; - - for (i=0 ; i<3 ; i++) - { - corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]); - } - - return Length (corner); -} - -/* -================= -Mod_LoadBrushModel -================= -*/ -void Mod_LoadBrushModel (model_t *mod, void *buffer) -{ - int i, j; - dheader_t *header; - dmodel_t *bm; - - loadmodel->type = mod_brush; - - header = (dheader_t *)buffer; - - i = LittleLong (header->version); - if (i != BSPVERSION) - Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION); - -// swap all the lumps - mod_base = (byte *)header; - - for (i=0 ; ichecksum = 0; - mod->checksum2 = 0; - - for (i = 0; i < HEADER_LUMPS; i++) { - if (i == LUMP_ENTITIES) - continue; - mod->checksum ^= LittleLong(Com_BlockChecksum(mod_base + header->lumps[i].fileofs, - header->lumps[i].filelen)); - - if (i == LUMP_VISIBILITY || i == LUMP_LEAFS || i == LUMP_NODES) - continue; - mod->checksum2 ^= LittleLong(Com_BlockChecksum(mod_base + header->lumps[i].fileofs, - header->lumps[i].filelen)); - } - -// load into heap - - Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]); - Mod_LoadEdges (&header->lumps[LUMP_EDGES]); - Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]); - Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]); - Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); - Mod_LoadPlanes (&header->lumps[LUMP_PLANES]); - Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); - Mod_LoadFaces (&header->lumps[LUMP_FACES]); - Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]); - Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); - Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]); - Mod_LoadNodes (&header->lumps[LUMP_NODES]); - Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]); - Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]); - Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]); - - Mod_MakeHull0 (); - - mod->numframes = 2; // regular and alternate animation - mod->flags = 0; - -// -// set up the submodels (FIXME: this is confusing) -// - for (i=0 ; inumsubmodels ; i++) - { - bm = &mod->submodels[i]; - - mod->hulls[0].firstclipnode = bm->headnode[0]; - for (j=1 ; jhulls[j].firstclipnode = bm->headnode[j]; - mod->hulls[j].lastclipnode = mod->numclipnodes-1; - } - - mod->firstmodelsurface = bm->firstface; - mod->nummodelsurfaces = bm->numfaces; - - VectorCopy (bm->maxs, mod->maxs); - VectorCopy (bm->mins, mod->mins); - - mod->radius = RadiusFromBounds (mod->mins, mod->maxs); - - mod->numleafs = bm->visleafs; - - if (i < mod->numsubmodels-1) - { // duplicate the basic information - char name[10]; - - snprintf (name, sizeof(name), "*%i", i+1); - loadmodel = Mod_FindName (name); - *loadmodel = *mod; - strcpy (loadmodel->name, name); - mod = loadmodel; - } - } -} From 73162d87835e53784bf75c6d75d2763a4c4442e4 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 11 Sep 2000 05:28:04 +0000 Subject: [PATCH 6/9] the model merge hack is almost complete. gl works but sw sefaults due to the alias model verts, tris and frames not being loaded correctly. --- include/model.h | 26 +-- source/Makefile.am | 2 +- source/gl_mesh.c | 20 +- source/gl_model_alias.c | 417 ++++++++-------------------------- source/gl_rmain.c | 18 +- source/gl_rmisc.c | 8 +- source/model_alias.c | 314 ++++++++++++++++++++++++++ source/sw_model_alias.c | 486 +++++++--------------------------------- 8 files changed, 523 insertions(+), 768 deletions(-) create mode 100644 source/model_alias.c diff --git a/include/model.h b/include/model.h index 8f09317..52adf54 100644 --- a/include/model.h +++ b/include/model.h @@ -318,21 +318,12 @@ typedef struct mtriangle_s { #define MAX_SKINS 32 typedef struct { - int ident; - int version; - vec3_t scale; - vec3_t scale_origin; - float boundingradius; - vec3_t eyeposition; - int numskins; - int skinwidth; - int skinheight; - int numverts; - int numtris; - int numframes; - synctype_t synctype; - int flags; - float size; + int model; + int stverts; + int skindesc; + int triangles; + + mdl_t mdl; int numposes; int poseverts; @@ -340,11 +331,8 @@ typedef struct { int commands; // gl command list with embedded s/t int gl_texturenum[MAX_SKINS][4]; int gl_fb_texturenum[MAX_SKINS][4]; - int model; - int stverts; - int skindesc; - int triangles; int texels[MAX_SKINS]; // only for player skins + maliasframedesc_t frames[1]; } aliashdr_t; diff --git a/source/Makefile.am b/source/Makefile.am index 27b57c1..e6f8d5c 100644 --- a/source/Makefile.am +++ b/source/Makefile.am @@ -49,7 +49,7 @@ common_ASM= sys_ia32.S worlda.S $(math_ASM) #endif common_SOURCES= crc.c cvar.c cmd.c mathlib.c wad.c world.c \ - model.c model_brush.c model_sprite.c \ + model.c model_alias.c model_brush.c model_sprite.c \ msg.c r_part.c sizebuf.c qendian.c qargs.c quakefs.c \ va.c quakeio.c link.c com.c \ zone.c $(common_ASM) diff --git a/source/gl_mesh.c b/source/gl_mesh.c index b54af12..9a189fc 100644 --- a/source/gl_mesh.c +++ b/source/gl_mesh.c @@ -109,7 +109,7 @@ int StripLength (int starttri, int startv) // look for a matching triangle nexttri: - for (j=starttri+1, check=&triangles[starttri+1] ; jnumtris ; j++, check++) + for (j=starttri+1, check=&triangles[starttri+1] ; jmdl.numtris ; j++, check++) { if (check->facesfront != last->facesfront) continue; @@ -143,7 +143,7 @@ nexttri: done: // clear the temp used flags - for (j=starttri+1 ; jnumtris ; j++) + for (j=starttri+1 ; jmdl.numtris ; j++) if (used[j] == 2) used[j] = 0; @@ -179,7 +179,7 @@ int FanLength (int starttri, int startv) // look for a matching triangle nexttri: - for (j=starttri+1, check=&triangles[starttri+1] ; jnumtris ; j++, check++) + for (j=starttri+1, check=&triangles[starttri+1] ; jmdl.numtris ; j++, check++) { if (check->facesfront != last->facesfront) continue; @@ -210,7 +210,7 @@ nexttri: done: // clear the temp used flags - for (j=starttri+1 ; jnumtris ; j++) + for (j=starttri+1 ; jmdl.numtris ; j++) if (used[j] == 2) used[j] = 0; @@ -242,7 +242,7 @@ void BuildTris (void) numorder = 0; numcommands = 0; memset (used, 0, sizeof(used)); - for (i=0 ; inumtris ; i++) + for (i=0 ; imdl.numtris ; i++) { // pick an unused triangle and start the trifan if (used[i]) @@ -289,9 +289,9 @@ void BuildTris (void) s = stverts[k].s; t = stverts[k].t; if (!triangles[besttris[0]].facesfront && stverts[k].onseam) - s += pheader->skinwidth / 2; // on back side - s = (s + 0.5) / pheader->skinwidth; - t = (t + 0.5) / pheader->skinheight; + s += pheader->mdl.skinwidth / 2; // on back side + s = (s + 0.5) / pheader->mdl.skinwidth; + t = (t + 0.5) / pheader->mdl.skinheight; *(float *)&commands[numcommands++] = s; *(float *)&commands[numcommands++] = t; @@ -300,10 +300,10 @@ void BuildTris (void) commands[numcommands++] = 0; // end of list marker - Con_DPrintf ("%3i tri %3i vert %3i cmd\n", pheader->numtris, numorder, numcommands); + Con_DPrintf ("%3i tri %3i vert %3i cmd\n", pheader->mdl.numtris, numorder, numcommands); allverts += numorder; - alltris += pheader->numtris; + alltris += pheader->mdl.numtris; } diff --git a/source/gl_model_alias.c b/source/gl_model_alias.c index 4187b3b..7476ee2 100644 --- a/source/gl_model_alias.c +++ b/source/gl_model_alias.c @@ -1,5 +1,5 @@ /* - gl_model.c + gl_model_alias.c model loading and caching @@ -51,100 +51,17 @@ ALIAS MODELS ============================================================================== */ -aliashdr_t *pheader; +extern aliashdr_t *pheader; -stvert_t stverts[MAXALIASVERTS]; -mtriangle_t triangles[MAXALIASTRIS]; +extern stvert_t stverts[MAXALIASVERTS]; +extern mtriangle_t triangles[MAXALIASTRIS]; // a pose is a single set of vertexes. a frame may be // an animating sequence of poses -trivertx_t *poseverts[MAXALIASFRAMES]; -int posenum; +extern trivertx_t *poseverts[MAXALIASFRAMES]; +extern int posenum; -byte player_8bit_texels[320*200]; - -/* -================= -Mod_LoadAliasFrame -================= -*/ -void * Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame) -{ - trivertx_t *pinframe; - int i; - daliasframe_t *pdaliasframe; - - pdaliasframe = (daliasframe_t *)pin; - - strcpy (frame->name, pdaliasframe->name); - frame->firstpose = posenum; - frame->numposes = 1; - - for (i=0 ; i<3 ; i++) - { - // these are byte values, so we don't have to worry about - // endianness - frame->bboxmin.v[i] = pdaliasframe->bboxmin.v[i]; - frame->bboxmin.v[i] = pdaliasframe->bboxmax.v[i]; - } - - pinframe = (trivertx_t *)(pdaliasframe + 1); - - poseverts[posenum] = pinframe; - posenum++; - - pinframe += pheader->numverts; - - return (void *)pinframe; -} - - -/* -================= -Mod_LoadAliasGroup -================= -*/ -void *Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame) -{ - daliasgroup_t *pingroup; - int i, numframes; - daliasinterval_t *pin_intervals; - void *ptemp; - - pingroup = (daliasgroup_t *)pin; - - numframes = LittleLong (pingroup->numframes); - - frame->firstpose = posenum; - frame->numposes = numframes; - - for (i=0 ; i<3 ; i++) - { - // these are byte values, so we don't have to worry about endianness - frame->bboxmin.v[i] = pingroup->bboxmin.v[i]; - frame->bboxmin.v[i] = pingroup->bboxmax.v[i]; - } - - pin_intervals = (daliasinterval_t *)(pingroup + 1); - - frame->interval = LittleFloat (pin_intervals->interval); - - pin_intervals += numframes; - - ptemp = (void *)pin_intervals; - - for (i=0 ; inumverts; - } - - return ptemp; -} - -//========================================================= +extern byte player_8bit_texels[320*200]; /* ================= @@ -222,92 +139,109 @@ void Mod_FloodFillSkin( byte *skin, int skinwidth, int skinheight ) } } +void *Mod_LoadSkin (byte *skin, int skinsize, int snum, int gnum, qboolean group) +{ + int j; + char name[32]; + + Mod_FloodFillSkin( skin, pheader->mdl.skinwidth, pheader->mdl.skinheight ); + + // This block is GL fullbright support for objects... + { + int pixels; + byte *ptexel; + + // Check for fullbright pixels.. + pixels = pheader->mdl.skinwidth * pheader->mdl.skinheight; + ptexel = (byte *)(skin + 1); + + for (j=0 ; j= 256-32) { + loadmodel->hasfullbrights = true; + break; + } + } + + if (loadmodel->hasfullbrights) { + byte *ptexels; + + //ptexels = Hunk_Alloc(s); + ptexels = malloc(pixels); + + if (group) { + snprintf(name, sizeof(name), "fb_%s_%i_%i", loadmodel->name,snum,gnum); + } else { + snprintf(name, sizeof(name), "fb_%s_%i", loadmodel->name,snum); + } + Con_DPrintf("FB Model ID: '%s'\n", name); + for (j=0 ; j= 256-32) { + ptexels[j] = ptexel[j]; + } else { + ptexels[j] = 255; + } + } + pheader->gl_fb_texturenum[snum][gnum] = + GL_LoadTexture (name, pheader->mdl.skinwidth, + pheader->mdl.skinheight, ptexels, true, true, 1); + + free(ptexels); + } + } + + if (group) { + snprintf(name, sizeof(name), "%s_%i_%i", loadmodel->name,snum,gnum); + } else { + snprintf(name, sizeof(name), "%s_%i", loadmodel->name,snum); + } + pheader->gl_texturenum[snum][gnum] = + GL_LoadTexture (name, pheader->mdl.skinwidth, + pheader->mdl.skinheight, skin, true, false, 1); + // alpha param was true for non group skins + return skin + skinsize; +} + /* =============== Mod_LoadAllSkins =============== */ -void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype) +void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype, int *pskinindex) { int i, j, k; - char name[32]; - int s; + int skinsize; byte *skin; daliasskingroup_t *pinskingroup; int groupskins; daliasskininterval_t *pinskinintervals; - skin = (byte *)(pskintype + 1); + skin = (byte *)pskintype; if (numskins < 1 || numskins > MAX_SKINS) Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins); - s = pheader->skinwidth * pheader->skinheight; + skinsize = pheader->mdl.skinwidth * pheader->mdl.skinheight; for (i=0 ; itype == ALIAS_SKIN_SINGLE) { - Mod_FloodFillSkin( skin, pheader->skinwidth, pheader->skinheight ); + skin+=4; + skin = Mod_LoadSkin (skin, skinsize, i, 0, false); // save 8 bit texels for the player model to remap if (!strcmp(loadmodel->name,"progs/player.mdl")) { - if (s > sizeof(player_8bit_texels)) + if (skinsize > sizeof(player_8bit_texels)) Sys_Error ("Player skin too large"); - memcpy (player_8bit_texels, (byte *)(pskintype + 1), s); + memcpy (player_8bit_texels, skin, skinsize); } - // This block is GL fullbright support for objects... - { - int pixels; - byte *ptexel; - - // Check for fullbright pixels.. - pixels = pheader->skinwidth * pheader->skinheight; - ptexel = (byte *)(pskintype + 1); - - for (j=0 ; j= 256-32) { - loadmodel->hasfullbrights = true; - break; - } - } - - if (loadmodel->hasfullbrights) { - byte *ptexels; - - //ptexels = Hunk_Alloc(s); - ptexels = malloc(pixels); - - snprintf(name, sizeof(name), "fb_%s_%i", loadmodel->name,i); - Con_DPrintf("FB Model ID: '%s'\n", name); - for (j=0 ; j= 256-32) { - ptexels[j] = ptexel[j]; - } else { - ptexels[j] = 255; - } - } - pheader->gl_fb_texturenum[i][0] = - pheader->gl_fb_texturenum[i][1] = - pheader->gl_fb_texturenum[i][2] = - pheader->gl_fb_texturenum[i][3] = - GL_LoadTexture (name, pheader->skinwidth, - pheader->skinheight, ptexels, true, true, 1); - - free(ptexels); - } + for (j=1; j < 4; j++) { + pheader->gl_texturenum[i][j] = + pheader->gl_texturenum[i][j - 1]; + pheader->gl_fb_texturenum[i][j] = + pheader->gl_fb_texturenum[i][j - 1]; } - - - snprintf (name, sizeof(name), "%s_%i", loadmodel->name, i); - pheader->gl_texturenum[i][0] = - pheader->gl_texturenum[i][1] = - pheader->gl_texturenum[i][2] = - pheader->gl_texturenum[i][3] = - GL_LoadTexture (name, pheader->skinwidth, - pheader->skinheight, (byte *)(pskintype + 1), true, true, 1); - pskintype = (daliasskintype_t *)((byte *)(pskintype+1) + s); } else { // animating skin group. yuck. Con_Printf("Animating Skin Group, if you get this message please notify warp@debian.org\n"); @@ -317,189 +251,22 @@ void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype) pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1); pskintype = (void *)(pinskinintervals + groupskins); + skin = (byte *)pskintype; for (j=0 ; jskinwidth, pheader->skinheight ); - snprintf (name, sizeof(name), "%s_%i_%i", loadmodel->name, i,j); - pheader->gl_texturenum[i][j&3] = - GL_LoadTexture (name, pheader->skinwidth, - pheader->skinheight, (byte *)(pskintype), true, false, 1); - pskintype = (daliasskintype_t *)((byte *)(pskintype) + s); + skin+=4; + skin = Mod_LoadSkin (skin, skinsize, i, j, true); } k = j; - for (/* */; j < 4; j++) - pheader->gl_texturenum[i][j&3] = - pheader->gl_texturenum[i][j - k]; + for (/* */; j < 4; j++) { + pheader->gl_texturenum[i][j] = + pheader->gl_texturenum[i][j - k]; + pheader->gl_fb_texturenum[i][j] = + pheader->gl_fb_texturenum[i][j - k]; + } } } - return (void *)pskintype; -} - - -//========================================================================= - -/* -================= -Mod_LoadAliasModel -================= -*/ -void Mod_LoadAliasModel (model_t *mod, void *buffer) -{ - int i, j; - mdl_t *pinmodel; - stvert_t *pinstverts; - dtriangle_t *pintriangles; - int version, numframes; - int size; - daliasframetype_t *pframetype; - daliasskintype_t *pskintype; - int start, end, total; - - start = Hunk_LowMark (); - - pinmodel = (mdl_t *)buffer; - - version = LittleLong (pinmodel->version); - if (version != ALIAS_VERSION) - Sys_Error ("%s has wrong version number (%i should be %i)", - mod->name, version, ALIAS_VERSION); - -// -// allocate space for a working header, plus all the data except the frames, -// skin and group info -// - size = sizeof (aliashdr_t) - + (LittleLong (pinmodel->numframes) - 1) * - sizeof (pheader->frames[0]); - pheader = Hunk_AllocName (size, loadname); - - mod->flags = LittleLong (pinmodel->flags); - -// -// endian-adjust and copy the data, starting with the alias model header -// - pheader->boundingradius = LittleFloat (pinmodel->boundingradius); - pheader->numskins = LittleLong (pinmodel->numskins); - pheader->skinwidth = LittleLong (pinmodel->skinwidth); - pheader->skinheight = LittleLong (pinmodel->skinheight); - - if (pheader->skinheight > MAX_LBM_HEIGHT) - Sys_Error ("model %s has a skin taller than %d", mod->name, - MAX_LBM_HEIGHT); - - pheader->numverts = LittleLong (pinmodel->numverts); - - if (pheader->numverts <= 0) - Sys_Error ("model %s has no vertices", mod->name); - - if (pheader->numverts > MAXALIASVERTS) - Sys_Error ("model %s has too many vertices", mod->name); - - pheader->numtris = LittleLong (pinmodel->numtris); - - if (pheader->numtris <= 0) - Sys_Error ("model %s has no triangles", mod->name); - - pheader->numframes = LittleLong (pinmodel->numframes); - numframes = pheader->numframes; - if (numframes < 1) - Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); - - pheader->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; - mod->synctype = LittleLong (pinmodel->synctype); - mod->numframes = pheader->numframes; - - for (i=0 ; i<3 ; i++) - { - pheader->scale[i] = LittleFloat (pinmodel->scale[i]); - pheader->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]); - pheader->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]); - } - - -// -// load the skins -// - pskintype = (daliasskintype_t *)&pinmodel[1]; - pskintype = Mod_LoadAllSkins (pheader->numskins, pskintype); - -// -// load base s and t vertices -// - pinstverts = (stvert_t *)pskintype; - - for (i=0 ; inumverts ; i++) - { - stverts[i].onseam = LittleLong (pinstverts[i].onseam); - stverts[i].s = LittleLong (pinstverts[i].s); - stverts[i].t = LittleLong (pinstverts[i].t); - } - -// -// load triangle lists -// - pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts]; - - for (i=0 ; inumtris ; i++) - { - triangles[i].facesfront = LittleLong (pintriangles[i].facesfront); - - for (j=0 ; j<3 ; j++) - { - triangles[i].vertindex[j] = - LittleLong (pintriangles[i].vertindex[j]); - } - } - -// -// load the frames -// - posenum = 0; - pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris]; - - for (i=0 ; itype); - - if (frametype == ALIAS_SINGLE) - { - pframetype = (daliasframetype_t *) - Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]); - } - else - { - pframetype = (daliasframetype_t *) - Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i]); - } - } - - pheader->numposes = posenum; - - mod->type = mod_alias; - -// FIXME: do this right - mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; - mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; - - // - // build the draw lists - // - GL_MakeAliasModelDisplayLists (mod, pheader); - -// -// move the complete, relocatable alias model to the cache -// - end = Hunk_LowMark (); - total = end - start; - - Cache_Alloc (&mod->cache, total, loadname); - if (!mod->cache.data) - return; - memcpy (mod->cache.data, pheader, total); - - Hunk_FreeToLowMark (start); + return (void *)skin; } diff --git a/source/gl_rmain.c b/source/gl_rmain.c index 00995ae..5764c49 100644 --- a/source/gl_rmain.c +++ b/source/gl_rmain.c @@ -469,9 +469,9 @@ static void GL_DrawAliasShadow (aliashdr_t *paliashdr, int posenum) order += 2; // normals and vertexes come from the frame list - point[0] = verts->v[0] * paliashdr->scale[0] + paliashdr->scale_origin[0]; - point[1] = verts->v[1] * paliashdr->scale[1] + paliashdr->scale_origin[1]; - point[2] = verts->v[2] * paliashdr->scale[2] + paliashdr->scale_origin[2]; + point[0] = verts->v[0] * paliashdr->mdl.scale[0] + paliashdr->mdl.scale_origin[0]; + point[1] = verts->v[1] * paliashdr->mdl.scale[1] + paliashdr->mdl.scale_origin[1]; + point[2] = verts->v[2] * paliashdr->mdl.scale[2] + paliashdr->mdl.scale_origin[2]; point[0] -= shadevector[0]*(point[2]+lheight); point[1] -= shadevector[1]*(point[2]+lheight); @@ -499,7 +499,7 @@ static void R_SetupAliasFrame (int frame, aliashdr_t *paliashdr, qboolean fb) int pose, numposes; float interval; - if ((frame >= paliashdr->numframes) || (frame < 0)) + if ((frame >= paliashdr->mdl.numframes) || (frame < 0)) { Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame); frame = 0; @@ -599,7 +599,7 @@ static void R_DrawAliasModel (entity_t *e) // paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model); - c_alias_polys += paliashdr->numtris; + c_alias_polys += paliashdr->mdl.numtris; // // draw all the triangles @@ -613,14 +613,14 @@ static void R_DrawAliasModel (entity_t *e) if (!strcmp (clmodel->name, "progs/eyes.mdl") ) { - glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2] - (22 + 8)); + glTranslatef (paliashdr->mdl.scale_origin[0], paliashdr->mdl.scale_origin[1], paliashdr->mdl.scale_origin[2] - (22 + 8)); // double size of eyes, since they are really hard to see in gl - glScalef (paliashdr->scale[0]*2, paliashdr->scale[1]*2, paliashdr->scale[2]*2); + glScalef (paliashdr->mdl.scale[0]*2, paliashdr->mdl.scale[1]*2, paliashdr->mdl.scale[2]*2); } else { - glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2]); - glScalef (paliashdr->scale[0], paliashdr->scale[1], paliashdr->scale[2]); + glTranslatef (paliashdr->mdl.scale_origin[0], paliashdr->mdl.scale_origin[1], paliashdr->mdl.scale_origin[2]); + glScalef (paliashdr->mdl.scale[0], paliashdr->mdl.scale[1], paliashdr->mdl.scale[2]); } anim = (int)(cl.time*10) & 3; diff --git a/source/gl_rmisc.c b/source/gl_rmisc.c index 0000e25..16c4ce5 100644 --- a/source/gl_rmisc.c +++ b/source/gl_rmisc.c @@ -340,8 +340,8 @@ void R_TranslatePlayerSkin (int playernum) return; // only translate skins on alias models paliashdr = (aliashdr_t *)Mod_Extradata (model); - s = paliashdr->skinwidth * paliashdr->skinheight; - if (currententity->skinnum < 0 || currententity->skinnum >= paliashdr->numskins) { + s = paliashdr->mdl.skinwidth * paliashdr->mdl.skinheight; + if (currententity->skinnum < 0 || currententity->skinnum >= paliashdr->mdl.numskins) { Con_Printf("(%d): Invalid player skin #%d\n", playernum, currententity->skinnum); original = (byte *)paliashdr + paliashdr->texels[0]; } else @@ -349,8 +349,8 @@ void R_TranslatePlayerSkin (int playernum) if (s & 3) Sys_Error ("R_TranslateSkin: s&3"); - inwidth = paliashdr->skinwidth; - inheight = paliashdr->skinheight; + inwidth = paliashdr->mdl.skinwidth; + inheight = paliashdr->mdl.skinheight; // because this happens during gameplay, do it fast // instead of sending it through gl_upload 8 diff --git a/source/model_alias.c b/source/model_alias.c new file mode 100644 index 0000000..c933f88 --- /dev/null +++ b/source/model_alias.c @@ -0,0 +1,314 @@ +/* + model_alias.c + + model loading and caching + + Copyright (C) 1996-1997 Id Software, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + + $Id$ +*/ + +// models are the only shared resource between a client and server running +// on the same machine. + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "r_local.h" +#include "sys.h" +#include "console.h" +#include "qendian.h" +#include "checksum.h" +#include "glquake.h" + +extern char loadname[]; +extern model_t *loadmodel; + +void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype, int *pskinindex); + +/* +============================================================================== + +ALIAS MODELS + +============================================================================== +*/ + +aliashdr_t *pheader; + +stvert_t stverts[MAXALIASVERTS]; +mtriangle_t triangles[MAXALIASTRIS]; + +// a pose is a single set of vertexes. a frame may be +// an animating sequence of poses +trivertx_t *poseverts[MAXALIASFRAMES]; +int posenum; + +byte player_8bit_texels[320*200]; + +/* +================= +Mod_LoadAliasFrame +================= +*/ +void * Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame) +{ + trivertx_t *pinframe; + int i; + daliasframe_t *pdaliasframe; + + pdaliasframe = (daliasframe_t *)pin; + + strcpy (frame->name, pdaliasframe->name); + frame->firstpose = posenum; + frame->numposes = 1; + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about + // endianness + frame->bboxmin.v[i] = pdaliasframe->bboxmin.v[i]; + frame->bboxmin.v[i] = pdaliasframe->bboxmax.v[i]; + } + + pinframe = (trivertx_t *)(pdaliasframe + 1); + + poseverts[posenum] = pinframe; + posenum++; + + pinframe += pheader->mdl.numverts; + + return (void *)pinframe; +} + + +/* +================= +Mod_LoadAliasGroup +================= +*/ +void *Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame) +{ + daliasgroup_t *pingroup; + int i, numframes; + daliasinterval_t *pin_intervals; + void *ptemp; + + pingroup = (daliasgroup_t *)pin; + + numframes = LittleLong (pingroup->numframes); + + frame->firstpose = posenum; + frame->numposes = numframes; + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about endianness + frame->bboxmin.v[i] = pingroup->bboxmin.v[i]; + frame->bboxmin.v[i] = pingroup->bboxmax.v[i]; + } + + pin_intervals = (daliasinterval_t *)(pingroup + 1); + + frame->interval = LittleFloat (pin_intervals->interval); + + pin_intervals += numframes; + + ptemp = (void *)pin_intervals; + + for (i=0 ; imdl.numverts; + } + + return ptemp; +} + +//========================================================================= + +/* +================= +Mod_LoadAliasModel +================= +*/ +void Mod_LoadAliasModel (model_t *mod, void *buffer) +{ + int i, j; + mdl_t *pinmodel, *pmodel; + stvert_t *pinstverts; + dtriangle_t *pintriangles; + int version, numframes; + int size; + daliasframetype_t *pframetype; + daliasskintype_t *pskintype; + int start, end, total; + + start = Hunk_LowMark (); + + pinmodel = (mdl_t *)buffer; + + version = LittleLong (pinmodel->version); + if (version != ALIAS_VERSION) + Sys_Error ("%s has wrong version number (%i should be %i)", + mod->name, version, ALIAS_VERSION); + +// +// allocate space for a working header, plus all the data except the frames, +// skin and group info +// + size = (int)&((aliashdr_t*)0)->frames[LittleLong (pinmodel->numframes)]; + pheader = Hunk_AllocName (size, loadname); + memset(pheader, 0, size); + pmodel = &pheader->mdl; + pheader->model = (byte*)pmodel - (byte*)pheader; + + mod->flags = LittleLong (pinmodel->flags); + +// +// endian-adjust and copy the data, starting with the alias model header +// + pmodel->boundingradius = LittleFloat (pinmodel->boundingradius); + pmodel->numskins = LittleLong (pinmodel->numskins); + pmodel->skinwidth = LittleLong (pinmodel->skinwidth); + pmodel->skinheight = LittleLong (pinmodel->skinheight); + + if (pmodel->skinheight > MAX_LBM_HEIGHT) + Sys_Error ("model %s has a skin taller than %d", mod->name, + MAX_LBM_HEIGHT); + + pmodel->numverts = LittleLong (pinmodel->numverts); + + if (pmodel->numverts <= 0) + Sys_Error ("model %s has no vertices", mod->name); + + if (pmodel->numverts > MAXALIASVERTS) + Sys_Error ("model %s has too many vertices", mod->name); + + pmodel->numtris = LittleLong (pinmodel->numtris); + + if (pmodel->numtris <= 0) + Sys_Error ("model %s has no triangles", mod->name); + + pmodel->numframes = LittleLong (pinmodel->numframes); + numframes = pmodel->numframes; + if (numframes < 1) + Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); + + pmodel->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; + mod->synctype = LittleLong (pinmodel->synctype); + mod->numframes = pmodel->numframes; + + for (i=0 ; i<3 ; i++) + { + pmodel->scale[i] = LittleFloat (pinmodel->scale[i]); + pmodel->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]); + pmodel->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]); + } + + +// +// load the skins +// + pskintype = (daliasskintype_t *)&pinmodel[1]; + pskintype = Mod_LoadAllSkins (pheader->mdl.numskins, pskintype, &pheader->skindesc); + +// +// load base s and t vertices +// + pinstverts = (stvert_t *)pskintype; + + for (i=0 ; imdl.numverts ; i++) + { + stverts[i].onseam = LittleLong (pinstverts[i].onseam); + stverts[i].s = LittleLong (pinstverts[i].s); + stverts[i].t = LittleLong (pinstverts[i].t); + } + +// +// load triangle lists +// + pintriangles = (dtriangle_t *)&pinstverts[pheader->mdl.numverts]; + + for (i=0 ; imdl.numtris ; i++) + { + triangles[i].facesfront = LittleLong (pintriangles[i].facesfront); + + for (j=0 ; j<3 ; j++) + { + triangles[i].vertindex[j] = + LittleLong (pintriangles[i].vertindex[j]); + } + } + +// +// load the frames +// + posenum = 0; + pframetype = (daliasframetype_t *)&pintriangles[pheader->mdl.numtris]; + + for (i=0 ; itype); + + if (frametype == ALIAS_SINGLE) + { + pframetype = (daliasframetype_t *) + Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]); + } + else + { + pframetype = (daliasframetype_t *) + Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i]); + } + } + + pheader->numposes = posenum; + + mod->type = mod_alias; + +// FIXME: do this right + mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; + mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; + + // + // build the draw lists + // + GL_MakeAliasModelDisplayLists (mod, pheader); + +// +// move the complete, relocatable alias model to the cache +// + end = Hunk_LowMark (); + total = end - start; + + Cache_Alloc (&mod->cache, total, loadname); + if (!mod->cache.data) + return; + memcpy (mod->cache.data, pheader, total); + + Hunk_FreeToLowMark (start); +} diff --git a/source/sw_model_alias.c b/source/sw_model_alias.c index f2b54c0..e1a9876 100644 --- a/source/sw_model_alias.c +++ b/source/sw_model_alias.c @@ -1,5 +1,5 @@ /* - model.c + sw_model_alias.c model loading and caching @@ -26,6 +26,9 @@ $Id$ */ +// models are the only shared resource between a client and server running +// on the same machine. + #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -35,8 +38,10 @@ #include "console.h" #include "qendian.h" #include "checksum.h" +#include "glquake.h" extern char loadname[]; +extern model_t *loadmodel; /* ============================================================================== @@ -46,434 +51,115 @@ ALIAS MODELS ============================================================================== */ -/* -================= -Mod_LoadAliasFrame -================= -*/ -void * Mod_LoadAliasFrame (void * pin, int *pframeindex, int numv, - trivertx_t *pbboxmin, trivertx_t *pbboxmax, aliashdr_t *pheader, char *name) -{ - trivertx_t *pframe, *pinframe; - int i, j; - daliasframe_t *pdaliasframe; - - pdaliasframe = (daliasframe_t *)pin; - - strcpy (name, pdaliasframe->name); - - for (i=0 ; i<3 ; i++) - { - // these are byte values, so we don't have to worry about - // endianness - pbboxmin->v[i] = pdaliasframe->bboxmin.v[i]; - pbboxmax->v[i] = pdaliasframe->bboxmax.v[i]; - } - - pinframe = (trivertx_t *)(pdaliasframe + 1); - pframe = Hunk_AllocName (numv * sizeof(*pframe), loadname); - - *pframeindex = (byte *)pframe - (byte *)pheader; - - for (j=0 ; jnumframes); - - paliasgroup = Hunk_AllocName (sizeof (maliasgroup_t) + - (numframes - 1) * sizeof (paliasgroup->frames[0]), loadname); - - paliasgroup->numframes = numframes; - - for (i=0 ; i<3 ; i++) - { - // these are byte values, so we don't have to worry about endianness - pbboxmin->v[i] = pingroup->bboxmin.v[i]; - pbboxmax->v[i] = pingroup->bboxmax.v[i]; - } - - *pframeindex = (byte *)paliasgroup - (byte *)pheader; - - pin_intervals = (daliasinterval_t *)(pingroup + 1); - - poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname); - - paliasgroup->intervals = (byte *)poutintervals - (byte *)pheader; - - for (i=0 ; iinterval); - if (*poutintervals <= 0.0) - Sys_Error ("Mod_LoadAliasGroup: interval<=0"); - - poutintervals++; - pin_intervals++; - } - - ptemp = (void *)pin_intervals; - - for (i=0 ; iframes[i].frame, - numv, - &paliasgroup->frames[i].bboxmin, - &paliasgroup->frames[i].bboxmax, - pheader, name); - } - - return ptemp; -} - - -/* -================= -Mod_LoadAliasSkin -================= -*/ -void * Mod_LoadAliasSkin (void * pin, int *pskinindex, int skinsize, - aliashdr_t *pheader) +extern aliashdr_t *pheader; + +extern stvert_t stverts[MAXALIASVERTS]; +extern mtriangle_t triangles[MAXALIASTRIS]; + +// a pose is a single set of vertexes. a frame may be +// an animating sequence of poses +extern trivertx_t *poseverts[MAXALIASFRAMES]; +extern int posenum; + +extern byte player_8bit_texels[320*200]; + +void *Mod_LoadSkin (byte *skin, int skinsize, int *pskinindex, int snum, int gnum) { + byte *pskin; + ushort *pusskin; int i; - byte *pskin, *pinskin; - unsigned short *pusskin; pskin = Hunk_AllocName (skinsize * r_pixbytes, loadname); - pinskin = (byte *)pin; *pskinindex = (byte *)pskin - (byte *)pheader; - if (r_pixbytes == 1) - { - memcpy (pskin, pinskin, skinsize); - } - else if (r_pixbytes == 2) - { - pusskin = (unsigned short *)pskin; - - for (i=0 ; inumskins); - - paliasskingroup = Hunk_AllocName (sizeof (maliasskingroup_t) + - (numskins - 1) * sizeof (paliasskingroup->skindescs[0]), - loadname); - - paliasskingroup->numskins = numskins; - - *pskinindex = (byte *)paliasskingroup - (byte *)pheader; - - pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1); - - poutskinintervals = Hunk_AllocName (numskins * sizeof (float),loadname); - - paliasskingroup->intervals = (byte *)poutskinintervals - (byte *)pheader; - - for (i=0 ; iinterval); - if (*poutskinintervals <= 0) - Sys_Error ("Mod_LoadAliasSkinGroup: interval<=0"); - - poutskinintervals++; - pinskinintervals++; - } - - ptemp = (void *)pinskinintervals; - - for (i=0 ; iskindescs[i].skin, skinsize, pheader); - } - - return ptemp; -} - - -/* -================= -Mod_LoadAliasModel -================= -*/ -void Mod_LoadAliasModel (model_t *mod, void *buffer) -{ - int i; - mdl_t *pmodel, *pinmodel; - stvert_t *pstverts, *pinstverts; - aliashdr_t *pheader; - mtriangle_t *ptri; - dtriangle_t *pintriangles; - int version, numframes, numskins; - int size; - daliasframetype_t *pframetype; - daliasskintype_t *pskintype; - maliasskindesc_t *pskindesc; - int skinsize; - int start, end, total; - - start = Hunk_LowMark (); - - pinmodel = (mdl_t *)buffer; - - version = LittleLong (pinmodel->version); - if (version != ALIAS_VERSION) - Sys_Error ("%s has wrong version number (%i should be %i)", - mod->name, version, ALIAS_VERSION); - -// -// allocate space for a working header, plus all the data except the frames, -// skin and group info -// - size = sizeof (aliashdr_t) + (LittleLong (pinmodel->numframes) - 1) * - sizeof (pheader->frames[0]) + - sizeof (mdl_t) + - LittleLong (pinmodel->numverts) * sizeof (stvert_t) + - LittleLong (pinmodel->numtris) * sizeof (mtriangle_t); - - pheader = Hunk_AllocName (size, loadname); - pmodel = (mdl_t *) ((byte *)&pheader[1] + - (LittleLong (pinmodel->numframes) - 1) * - sizeof (pheader->frames[0])); - -// mod->cache.data = pheader; - mod->flags = LittleLong (pinmodel->flags); - -// -// endian-adjust and copy the data, starting with the alias model header -// - pmodel->boundingradius = LittleFloat (pinmodel->boundingradius); - pmodel->numskins = LittleLong (pinmodel->numskins); - pmodel->skinwidth = LittleLong (pinmodel->skinwidth); - pmodel->skinheight = LittleLong (pinmodel->skinheight); - - if (pmodel->skinheight > MAX_LBM_HEIGHT) - Sys_Error ("model %s has a skin taller than %d", mod->name, - MAX_LBM_HEIGHT); - - pmodel->numverts = LittleLong (pinmodel->numverts); - - if (pmodel->numverts <= 0) - Sys_Error ("model %s has no vertices", mod->name); - - if (pmodel->numverts > MAXALIASVERTS) - Sys_Error ("model %s has too many vertices", mod->name); - - pmodel->numtris = LittleLong (pinmodel->numtris); - - if (pmodel->numtris <= 0) - Sys_Error ("model %s has no triangles", mod->name); - - pmodel->numframes = LittleLong (pinmodel->numframes); - pmodel->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; - mod->synctype = LittleLong (pinmodel->synctype); - mod->numframes = pmodel->numframes; - - for (i=0 ; i<3 ; i++) - { - pmodel->scale[i] = LittleFloat (pinmodel->scale[i]); - pmodel->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]); - pmodel->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]); - } - - numskins = pmodel->numskins; - numframes = pmodel->numframes; - - if (pmodel->skinwidth & 0x03) - Sys_Error ("Mod_LoadAliasModel: skinwidth not multiple of 4"); - - pheader->model = (byte *)pmodel - (byte *)pheader; - -// -// load the skins -// - skinsize = pmodel->skinheight * pmodel->skinwidth; - - if (numskins < 1) + if (numskins < 1 || numskins > MAX_SKINS) Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins); - pskintype = (daliasskintype_t *)&pinmodel[1]; - + skinsize = pheader->mdl.skinwidth * pheader->mdl.skinheight; pskindesc = Hunk_AllocName (numskins * sizeof (maliasskindesc_t), loadname); - pheader->skindesc = (byte *)pskindesc - (byte *)pheader; for (i=0 ; itype == ALIAS_SKIN_SINGLE) { + skin+=4; + skin = Mod_LoadSkin (skin, skinsize, &pskindesc[i].skin, i, 0); + } else { + pskintype++; + pinskingroup = (daliasskingroup_t *)pskintype; + groupskins = LittleLong (pinskingroup->numskins); - skintype = LittleLong (pskintype->type); - pskindesc[i].type = skintype; + j = sizeof (maliasskingroup_t) + + (groupskins - 1) * sizeof (paliasskingroup->skindescs[0]); + j = (int)&((maliasskingroup_t*)0)->skindescs[groupskins]; + paliasskingroup = Hunk_AllocName (j, loadname); + paliasskingroup->numskins = groupskins; - if (skintype == ALIAS_SKIN_SINGLE) - { - pskintype = (daliasskintype_t *) - Mod_LoadAliasSkin (pskintype + 1, - &pskindesc[i].skin, - skinsize, pheader); - } - else - { - pskintype = (daliasskintype_t *) - Mod_LoadAliasSkinGroup (pskintype + 1, - &pskindesc[i].skin, - skinsize, pheader); + *pskinindex = (byte *)paliasskingroup - (byte *)pheader; + + pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1); + poutskinintervals = Hunk_AllocName (groupskins * sizeof (float),loadname); + paliasskingroup->intervals = (byte *)poutskinintervals - (byte *)pheader; + for (i=0 ; iinterval); + if (*poutskinintervals <= 0) + Sys_Error ("Mod_LoadAliasSkinGroup: interval<=0"); + + poutskinintervals++; + pinskinintervals++; + } + + pskintype = (void *)pinskinintervals; + skin = (byte *)pskintype; + + for (j=0 ; jskindescs[i].skin, i, j); + } } } -// -// set base s and t vertices -// - pstverts = (stvert_t *)&pmodel[1]; - pinstverts = (stvert_t *)pskintype; - - pheader->stverts = (byte *)pstverts - (byte *)pheader; - - for (i=0 ; inumverts ; i++) - { - pstverts[i].onseam = LittleLong (pinstverts[i].onseam); - // put s and t in 16.16 format - pstverts[i].s = LittleLong (pinstverts[i].s) << 16; - pstverts[i].t = LittleLong (pinstverts[i].t) << 16; - } - -// -// set up the triangles -// - ptri = (mtriangle_t *)&pstverts[pmodel->numverts]; - pintriangles = (dtriangle_t *)&pinstverts[pmodel->numverts]; - - pheader->triangles = (byte *)ptri - (byte *)pheader; - - for (i=0 ; inumtris ; i++) - { - int j; - - ptri[i].facesfront = LittleLong (pintriangles[i].facesfront); - - for (j=0 ; j<3 ; j++) - { - ptri[i].vertindex[j] = - LittleLong (pintriangles[i].vertindex[j]); - } - } - -// -// load the frames -// - if (numframes < 1) - Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); - - pframetype = (daliasframetype_t *)&pintriangles[pmodel->numtris]; - - for (i=0 ; itype); - pheader->frames[i].type = frametype; - - if (frametype == ALIAS_SINGLE) - { - pframetype = (daliasframetype_t *) - Mod_LoadAliasFrame (pframetype + 1, - &pheader->frames[i].frame, - pmodel->numverts, - &pheader->frames[i].bboxmin, - &pheader->frames[i].bboxmax, - pheader, pheader->frames[i].name); - } - else - { - pframetype = (daliasframetype_t *) - Mod_LoadAliasGroup (pframetype + 1, - &pheader->frames[i].frame, - pmodel->numverts, - &pheader->frames[i].bboxmin, - &pheader->frames[i].bboxmax, - pheader, pheader->frames[i].name); - } - } - - mod->type = mod_alias; - -// FIXME: do this right - mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; - mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; - -// -// move the complete, relocatable alias model to the cache -// - end = Hunk_LowMark (); - total = end - start; - - Cache_Alloc (&mod->cache, total, loadname); - if (!mod->cache.data) - return; - memcpy (mod->cache.data, pheader, total); - - Hunk_FreeToLowMark (start); + return (void *)skin; +} + +void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr) +{ } From 81400a6374699df99e733f8c04f5276b807fb71b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 11 Sep 2000 15:31:46 +0000 Subject: [PATCH 7/9] add .vimrc --- source/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/source/.gitignore b/source/.gitignore index d92f2b7..148e440 100644 --- a/source/.gitignore +++ b/source/.gitignore @@ -1,3 +1,4 @@ +.vimrc *.a *.d *.o From 2322b564b9796f58d3524f4edb53afed703c7703 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 11 Sep 2000 23:13:06 +0000 Subject: [PATCH 8/9] now builds with --disable-asmop. NOTE: d_copy.S is still used anyway (too lazy to figure out how to do it in C) --- source/d_copy.S | 4 ++-- source/d_vars.c | 1 + source/mathlib.c | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/source/d_copy.S b/source/d_copy.S index 80ec79e..0d41911 100644 --- a/source/d_copy.S +++ b/source/d_copy.S @@ -33,7 +33,7 @@ #include "quakeasm.h" #include "asm_draw.h" -#ifdef USE_INTEL_ASM +//#ifdef USE_INTEL_ASM .data LCopyWidth: .long 0 @@ -173,4 +173,4 @@ LLRowLoop: popl %ebp // restore the caller's stack frame ret -#endif /* USE_INTEL_ASM */ +//#endif /* USE_INTEL_ASM */ diff --git a/source/d_vars.c b/source/d_vars.c index a20b6fb..28d74b5 100644 --- a/source/d_vars.c +++ b/source/d_vars.c @@ -32,6 +32,7 @@ #ifndef USE_INTEL_ASM +#include "qtypes.h" // all global and static refresh variables are collected in a contiguous block // to avoid cache conflicts. diff --git a/source/mathlib.c b/source/mathlib.c index 5eb70f0..8ba87fd 100644 --- a/source/mathlib.c +++ b/source/mathlib.c @@ -34,6 +34,7 @@ #include "mathlib.h" #include "sys.h" +#include "model.h" vec3_t vec3_origin = {0,0,0}; int nanmask = 255<<23; From 13e5ef92d3db482a8d22c894e2543d68676f1edb Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 11 Sep 2000 23:17:55 +0000 Subject: [PATCH 9/9] sw no longer segs!:) I'm not 100% satisfied with how I attacked frame loading, but I'll look into that later. I was getting tired of not having a running program on this branch. Basicly, frames loading needs a little more study. --- include/model.h | 7 ++- source/.gdbinit | 1 + source/gl_model_alias.c | 80 +++++++++++++++++++++++++ source/model_alias.c | 83 +------------------------- source/sw_model_alias.c | 128 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 216 insertions(+), 83 deletions(-) create mode 100644 source/.gdbinit diff --git a/include/model.h b/include/model.h index 52adf54..68e2768 100644 --- a/include/model.h +++ b/include/model.h @@ -270,15 +270,16 @@ Alias models are position independent, so the cache manager can move them. ============================================================================== */ +/* NOTE: the first three lines must match maliasgroupframedesc_t */ typedef struct { + trivertx_t bboxmin; + trivertx_t bboxmax; + int frame; aliasframetype_t type; int firstpose; int numposes; float interval; - trivertx_t bboxmin; - trivertx_t bboxmax; - int frame; char name[16]; } maliasframedesc_t; diff --git a/source/.gdbinit b/source/.gdbinit new file mode 100644 index 0000000..dc48ee5 --- /dev/null +++ b/source/.gdbinit @@ -0,0 +1 @@ +set args -nodga -nosound +set _windowed_mouse 0 diff --git a/source/gl_model_alias.c b/source/gl_model_alias.c index 7476ee2..ae65b20 100644 --- a/source/gl_model_alias.c +++ b/source/gl_model_alias.c @@ -270,3 +270,83 @@ void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype, int *pskinind return (void *)skin; } + +/* +================= +Mod_LoadAliasFrame +================= +*/ +void * Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame) +{ + trivertx_t *pinframe; + int i; + daliasframe_t *pdaliasframe; + + pdaliasframe = (daliasframe_t *)pin; + + strcpy (frame->name, pdaliasframe->name); + frame->firstpose = posenum; + frame->numposes = 1; + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about + // endianness + frame->bboxmin.v[i] = pdaliasframe->bboxmin.v[i]; + frame->bboxmin.v[i] = pdaliasframe->bboxmax.v[i]; + } + + pinframe = (trivertx_t *)(pdaliasframe + 1); + + poseverts[posenum] = pinframe; + posenum++; + + pinframe += pheader->mdl.numverts; + + return (void *)pinframe; +} + +/* +================= +Mod_LoadAliasGroup +================= +*/ +void *Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame) +{ + daliasgroup_t *pingroup; + int i, numframes; + daliasinterval_t *pin_intervals; + void *ptemp; + + pingroup = (daliasgroup_t *)pin; + + numframes = LittleLong (pingroup->numframes); + + frame->firstpose = posenum; + frame->numposes = numframes; + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about endianness + frame->bboxmin.v[i] = pingroup->bboxmin.v[i]; + frame->bboxmin.v[i] = pingroup->bboxmax.v[i]; + } + + pin_intervals = (daliasinterval_t *)(pingroup + 1); + + frame->interval = LittleFloat (pin_intervals->interval); + + pin_intervals += numframes; + + ptemp = (void *)pin_intervals; + + for (i=0 ; imdl.numverts; + } + + return ptemp; +} diff --git a/source/model_alias.c b/source/model_alias.c index c933f88..824a5fb 100644 --- a/source/model_alias.c +++ b/source/model_alias.c @@ -65,86 +65,8 @@ int posenum; byte player_8bit_texels[320*200]; -/* -================= -Mod_LoadAliasFrame -================= -*/ -void * Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame) -{ - trivertx_t *pinframe; - int i; - daliasframe_t *pdaliasframe; - - pdaliasframe = (daliasframe_t *)pin; - - strcpy (frame->name, pdaliasframe->name); - frame->firstpose = posenum; - frame->numposes = 1; - - for (i=0 ; i<3 ; i++) - { - // these are byte values, so we don't have to worry about - // endianness - frame->bboxmin.v[i] = pdaliasframe->bboxmin.v[i]; - frame->bboxmin.v[i] = pdaliasframe->bboxmax.v[i]; - } - - pinframe = (trivertx_t *)(pdaliasframe + 1); - - poseverts[posenum] = pinframe; - posenum++; - - pinframe += pheader->mdl.numverts; - - return (void *)pinframe; -} - - -/* -================= -Mod_LoadAliasGroup -================= -*/ -void *Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame) -{ - daliasgroup_t *pingroup; - int i, numframes; - daliasinterval_t *pin_intervals; - void *ptemp; - - pingroup = (daliasgroup_t *)pin; - - numframes = LittleLong (pingroup->numframes); - - frame->firstpose = posenum; - frame->numposes = numframes; - - for (i=0 ; i<3 ; i++) - { - // these are byte values, so we don't have to worry about endianness - frame->bboxmin.v[i] = pingroup->bboxmin.v[i]; - frame->bboxmin.v[i] = pingroup->bboxmax.v[i]; - } - - pin_intervals = (daliasinterval_t *)(pingroup + 1); - - frame->interval = LittleFloat (pin_intervals->interval); - - pin_intervals += numframes; - - ptemp = (void *)pin_intervals; - - for (i=0 ; imdl.numverts; - } - - return ptemp; -} +void *Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame); +void *Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame); //========================================================================= @@ -273,6 +195,7 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer) aliasframetype_t frametype; frametype = LittleLong (pframetype->type); + pheader->frames[i].type = frametype; if (frametype == ALIAS_SINGLE) { diff --git a/source/sw_model_alias.c b/source/sw_model_alias.c index e1a9876..9bf75af 100644 --- a/source/sw_model_alias.c +++ b/source/sw_model_alias.c @@ -162,4 +162,132 @@ void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype, int *pskinind void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr) { + int i, j; + stvert_t *pstverts; + mtriangle_t *ptri; + int numv = hdr->mdl.numverts; + int numt = hdr->mdl.numtris; + + pstverts = (stvert_t *)Hunk_AllocName(numv * sizeof(stvert_t),loadname); + ptri = (mtriangle_t *)Hunk_AllocName(numt * sizeof(mtriangle_t),loadname); + + hdr->stverts = (byte *)pstverts - (byte *)hdr; + hdr->triangles = (byte *)ptri - (byte *)hdr; + + for (i=0; iname, pdaliasframe->name); + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about + // endianness + frame->bboxmin.v[i] = pdaliasframe->bboxmin.v[i]; + frame->bboxmax.v[i] = pdaliasframe->bboxmax.v[i]; + } + + pinframe = (trivertx_t *)(pdaliasframe + 1); + pframe = Hunk_AllocName (pheader->mdl.numverts * sizeof(*pframe), loadname); + + frame->frame = (byte *)pframe - (byte *)pheader; + + for (j=0 ; jmdl.numverts ; j++) + { + int k; + + // these are all byte values, so no need to deal with endianness + pframe[j].lightnormalindex = pinframe[j].lightnormalindex; + + for (k=0 ; k<3 ; k++) + { + pframe[j].v[k] = pinframe[j].v[k]; + } + } + + pinframe += pheader->mdl.numverts; + + return (void *)pinframe; +} + +/* +================= +Mod_LoadAliasGroup +================= +*/ +void * Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame) +{ + daliasgroup_t *pingroup; + maliasgroup_t *paliasgroup; + int i, numframes; + daliasinterval_t *pin_intervals; + float *poutintervals; + void *ptemp; + + pingroup = (daliasgroup_t *)pin; + + numframes = LittleLong (pingroup->numframes); + + paliasgroup = Hunk_AllocName (sizeof (maliasgroup_t) + + (numframes - 1) * sizeof (paliasgroup->frames[0]), loadname); + + paliasgroup->numframes = numframes; + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about endianness + frame->bboxmin.v[i] = pingroup->bboxmin.v[i]; + frame->bboxmax.v[i] = pingroup->bboxmax.v[i]; + } + + frame->frame = (byte *)paliasgroup - (byte *)pheader; + + pin_intervals = (daliasinterval_t *)(pingroup + 1); + + poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname); + + paliasgroup->intervals = (byte *)poutintervals - (byte *)pheader; + + for (i=0 ; iinterval); + if (*poutintervals <= 0.0) + Sys_Error ("Mod_LoadAliasGroup: interval<=0"); + + poutintervals++; + pin_intervals++; + } + + ptemp = (void *)pin_intervals; + + for (i=0 ; iframes[i]); + } + + return ptemp; }