From cd159e1cc152e9985e9adcb267c5754435a14b8c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 23 Aug 2010 11:56:43 +0900 Subject: [PATCH] Use LoadBSPMem to load brush models. Now that Mod_LoadBrushModel uses bspfile.[ch], the engine uses the same code as the tools to work with bsp files. --- include/QF/bspfile.h | 19 ++- include/QF/model.h | 2 +- libs/models/brush/gl_model_brush.c | 22 ++-- libs/models/brush/model_brush.c | 196 ++++++++++++----------------- libs/models/brush/sw_model_brush.c | 8 +- libs/models/null_model.c | 2 +- libs/util/bspfile.c | 34 ++--- 7 files changed, 138 insertions(+), 145 deletions(-) diff --git a/include/QF/bspfile.h b/include/QF/bspfile.h index efc9f6722..e60cc22f7 100644 --- a/include/QF/bspfile.h +++ b/include/QF/bspfile.h @@ -292,7 +292,24 @@ typedef struct bsp_s { int32_t *surfedges; } bsp_t; -bsp_t *LoadBSPMem (void *mem, size_t size); +/** Create a bsp structure from a memory buffer. + The returned structure will be setup to point into the supplied buffer. + All structures within the bsp will be byte-swapped. For this reason, if + a callback is provided, the callback be called after byteswapping the + header, but before byteswapping any data in the lumps. + + \param mem The buffer holding the bsp data. + \param size The size of the buffer. This is used for sanity checking. + \param cb Pointer to the callback function. + \param cbdata Pointer to extra data for the callback. + \return Initialized bsp structure. + + \note The caller maintains ownership of the memory buffer. BSP_Free will + free only the bsp structure itself. However, if the caller wishes to + relinquish ownership of the buffer, set bsp_t::own_header to true. +*/ +bsp_t *LoadBSPMem (void *mem, size_t size, void (*cb) (const bsp_t *, void *), + void *cbdata); bsp_t *LoadBSPFile (QFile *file, size_t size); void WriteBSPFile (const bsp_t *bsp, QFile *file); bsp_t *BSP_New (void); diff --git a/include/QF/model.h b/include/QF/model.h index 2407d062b..67790253f 100644 --- a/include/QF/model.h +++ b/include/QF/model.h @@ -436,7 +436,7 @@ model_t *Mod_FindName (const char *name); void Mod_ProcessTexture(miptex_t *mt, texture_t *tx); void Mod_LoadExternalSkins (model_t * mod); void Mod_LoadExternalTextures (model_t * mod); -void Mod_LoadLighting (lump_t *l); +void Mod_LoadLighting (bsp_t *bsp); int Mod_CalcFullbright (byte *in, byte *out, int pixels); int Mod_Fullbright (byte * skin, int width, int height, char *name); diff --git a/libs/models/brush/gl_model_brush.c b/libs/models/brush/gl_model_brush.c index 5418f72e9..78a73d3b6 100644 --- a/libs/models/brush/gl_model_brush.c +++ b/libs/models/brush/gl_model_brush.c @@ -137,12 +137,13 @@ Mod_LoadExternalTextures (model_t *mod) } void -Mod_LoadLighting (lump_t *l) +Mod_LoadLighting (bsp_t *bsp) { byte d; byte *in, *out, *data; dstring_t *litfilename = dstring_new (); - int i; + size_t i; + int ver; dstring_copystr (litfilename, loadmodel->name); loadmodel->lightdata = NULL; @@ -154,36 +155,37 @@ Mod_LoadLighting (lump_t *l) if (data) { if (data[0] == 'Q' && data[1] == 'L' && data[2] == 'I' && data[3] == 'T') { - i = LittleLong (((int *) data)[1]); - if (i == 1) { + ver = LittleLong (((int32_t *) data)[1]); + if (ver == 1) { Sys_DPrintf ("%s loaded", litfilename->str); loadmodel->lightdata = data + 8; return; } else - Sys_DPrintf ("Unknown .lit file version (%d)\n", i); + Sys_DPrintf ("Unknown .lit file version (%d)\n", ver); } else Sys_DPrintf ("Corrupt .lit file (old version?), ignoring\n"); } } // LordHavoc: oh well, expand the white lighting data - if (!l->filelen) { + if (!bsp->lightdatasize) { dstring_delete (litfilename); return; } - loadmodel->lightdata = Hunk_AllocName (l->filelen * mod_lightmap_bytes, + loadmodel->lightdata = Hunk_AllocName (bsp->lightdatasize + * mod_lightmap_bytes, litfilename->str); - in = mod_base + l->fileofs; + in = bsp->lightdata; out = loadmodel->lightdata; if (mod_lightmap_bytes > 1) - for (i = 0; i < l->filelen ; i++) { + for (i = 0; i < bsp->lightdatasize ; i++) { d = gammatable[*in++]; *out++ = d; *out++ = d; *out++ = d; } else - for (i = 0; i < l->filelen ; i++) + for (i = 0; i < bsp->lightdatasize ; i++) *out++ = gammatable[*in++]; dstring_delete (litfilename); } diff --git a/libs/models/brush/model_brush.c b/libs/models/brush/model_brush.c index 21f751dbc..45fb0c2ef 100644 --- a/libs/models/brush/model_brush.c +++ b/libs/models/brush/model_brush.c @@ -128,8 +128,6 @@ Mod_LeafPVS (mleaf_t *leaf, model_t *model) // BRUSHMODEL LOADING ========================================================= -byte *mod_base; - //FIXME SLOW! static void mod_unique_miptex_name (texture_t **textures, texture_t *tx, int ind) @@ -156,7 +154,7 @@ mod_unique_miptex_name (texture_t **textures, texture_t *tx, int ind) } static void -Mod_LoadTextures (lump_t *l) +Mod_LoadTextures (bsp_t *bsp) { dmiptexlump_t *m; int i, j, pixels, num, max, altmax; @@ -164,11 +162,11 @@ Mod_LoadTextures (lump_t *l) texture_t *tx, *tx2; texture_t *anims[10], *altanims[10]; - if (!l->filelen) { + if (!bsp->texdatasize) { loadmodel->textures = NULL; return; } - m = (dmiptexlump_t *) (mod_base + l->fileofs); + m = (dmiptexlump_t *) bsp->texdata; m->nummiptex = LittleLong (m->nummiptex); @@ -292,38 +290,36 @@ Mod_LoadTextures (lump_t *l) } static void -Mod_LoadVisibility (lump_t *l) +Mod_LoadVisibility (bsp_t *bsp) { - if (!l->filelen) { + if (!bsp->visdatasize) { loadmodel->visdata = NULL; return; } - loadmodel->visdata = Hunk_AllocName (l->filelen, loadname); - memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen); + loadmodel->visdata = Hunk_AllocName (bsp->visdatasize, loadname); + memcpy (loadmodel->visdata, bsp->visdata, bsp->visdatasize); } static void -Mod_LoadEntities (lump_t *l) +Mod_LoadEntities (bsp_t *bsp) { - if (!l->filelen) { + if (!bsp->entdatasize) { loadmodel->entities = NULL; return; } - loadmodel->entities = Hunk_AllocName (l->filelen, loadname); - memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen); + loadmodel->entities = Hunk_AllocName (bsp->entdatasize, loadname); + memcpy (loadmodel->entities, bsp->entdata, bsp->entdatasize); } static void -Mod_LoadVertexes (lump_t *l) +Mod_LoadVertexes (bsp_t *bsp) { dvertex_t *in; int count, i; mvertex_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); + in = bsp->vertexes; + count = bsp->numvertexes; out = Hunk_AllocName (count * sizeof (*out), loadname); loadmodel->vertexes = out; @@ -337,15 +333,13 @@ Mod_LoadVertexes (lump_t *l) } static void -Mod_LoadSubmodels (lump_t *l) +Mod_LoadSubmodels (bsp_t *bsp) { dmodel_t *in, *out; int count, i, j; - 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); + in = bsp->models; + count = bsp->nummodels; out = Hunk_AllocName (count * sizeof (*out), loadname); loadmodel->submodels = out; @@ -366,16 +360,14 @@ Mod_LoadSubmodels (lump_t *l) } static void -Mod_LoadEdges (lump_t *l) +Mod_LoadEdges (bsp_t *bsp) { dedge_t *in; int count, i; medge_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); + in = bsp->edges; + count = bsp->numedges; out = Hunk_AllocName ((count + 1) * sizeof (*out), loadname); loadmodel->edges = out; @@ -388,17 +380,15 @@ Mod_LoadEdges (lump_t *l) } static void -Mod_LoadTexinfo (lump_t *l) +Mod_LoadTexinfo (bsp_t *bsp) { float len1, len2; int count, miptex, i, j; mtexinfo_t *out; texinfo_t *in; - 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); + in = bsp->texinfo; + count = bsp->numtexinfo; out = Hunk_AllocName (count * sizeof (*out), loadname); loadmodel->texinfo = out; @@ -491,16 +481,14 @@ CalcSurfaceExtents (msurface_t *s) } static void -Mod_LoadFaces (lump_t *l) +Mod_LoadFaces (bsp_t *bsp) { dface_t *in; int count, planenum, side, surfnum, i; 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); + in = bsp->faces; + count = bsp->numfaces; out = Hunk_AllocName (count * sizeof (*out), loadname); loadmodel->surfaces = out; @@ -568,16 +556,14 @@ Mod_SetParent (mnode_t *node, mnode_t *parent) } static void -Mod_LoadNodes (lump_t *l) +Mod_LoadNodes (bsp_t *bsp) { dnode_t *in; int count, i, j, p; 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); + in = bsp->nodes; + count = bsp->numnodes; out = Hunk_AllocName (count * sizeof (*out), loadname); loadmodel->nodes = out; @@ -608,17 +594,15 @@ Mod_LoadNodes (lump_t *l) } static void -Mod_LoadLeafs (lump_t *l) +Mod_LoadLeafs (bsp_t *bsp) { dleaf_t *in; int count, i, j, p; mleaf_t *out; 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); + in = bsp->leafs; + count = bsp->numleafs; out = Hunk_AllocName (count * sizeof (*out), loadname); loadmodel->leafs = out; @@ -663,16 +647,14 @@ Mod_LoadLeafs (lump_t *l) } static void -Mod_LoadClipnodes (lump_t *l) +Mod_LoadClipnodes (bsp_t *bsp) { dclipnode_t *in, *out; hull_t *hull; int count, i; - 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); + in = bsp->clipnodes; + count = bsp->numclipnodes; out = Hunk_AllocName (count * sizeof (*out), loadname); loadmodel->clipnodes = out; @@ -756,16 +738,14 @@ Mod_MakeHull0 (void) } static void -Mod_LoadMarksurfaces (lump_t *l) +Mod_LoadMarksurfaces (bsp_t *bsp) { int count, i, j; msurface_t **out; - short *in; + uint16_t *in; - 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); + in = bsp->marksurfaces; + count = bsp->nummarksurfaces; out = Hunk_AllocName (count * sizeof (*out), loadname); loadmodel->marksurfaces = out; @@ -780,15 +760,14 @@ Mod_LoadMarksurfaces (lump_t *l) } static void -Mod_LoadSurfedges (lump_t *l) +Mod_LoadSurfedges (bsp_t *bsp) { - int count, i; - int *in, *out; + int count, i; + int32_t *in; + int *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); + in = bsp->surfedges; + count = bsp->numsurfedges; out = Hunk_AllocName (count * sizeof (*out), loadname); loadmodel->surfedges = out; @@ -799,16 +778,14 @@ Mod_LoadSurfedges (lump_t *l) } static void -Mod_LoadPlanes (lump_t *l) +Mod_LoadPlanes (bsp_t *bsp) { dplane_t *in; int bits, count, i, j; mplane_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); + in = bsp->planes; + count = bsp->numplanes; out = Hunk_AllocName (count * 2 * sizeof (*out), loadname); loadmodel->planes = out; @@ -828,66 +805,59 @@ Mod_LoadPlanes (lump_t *l) } } -void -Mod_LoadBrushModel (model_t *mod, void *buffer) +static void +do_checksums (const bsp_t *bsp, void *_mod) { - dheader_t *header; - dmodel_t *bm; - int i, j; + int i; + model_t *mod = (model_t *) _mod; + byte *base; - 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; i < (int) sizeof (dheader_t) / 4; i++) - ((int *) header)[i] = LittleLong (((int *) header)[i]); + base = (byte *) bsp->header; // checksum all of the map, except for entities mod->checksum = 0; mod->checksum2 = 0; - for (i = 0; i < HEADER_LUMPS; i++) { - lump_t *lump = header->lumps + i; + lump_t *lump = bsp->header->lumps + i; int csum; - if (lump->fileofs > qfs_filesize - || (lump->fileofs + lump->filelen) > qfs_filesize) - Sys_Error ("Mod_LoadBrushModel: %s seems to be truncated", - mod->name); if (i == LUMP_ENTITIES) continue; - csum = Com_BlockChecksum (mod_base + lump->fileofs, lump->filelen); + csum = Com_BlockChecksum (base + lump->fileofs, lump->filelen); mod->checksum ^= csum; if (i != LUMP_VISIBILITY && i != LUMP_LEAFS && i != LUMP_NODES) mod->checksum2 ^= csum; } +} + +void +Mod_LoadBrushModel (model_t *mod, void *buffer) +{ + dmodel_t *bm; + int i, j; + bsp_t *bsp; + + loadmodel->type = mod_brush; + + bsp = LoadBSPMem (buffer, qfs_filesize, do_checksums, mod); // 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_LoadVertexes (bsp); + Mod_LoadEdges (bsp); + Mod_LoadSurfedges (bsp); + Mod_LoadTextures (bsp); + Mod_LoadLighting (bsp); + Mod_LoadPlanes (bsp); + Mod_LoadTexinfo (bsp); + Mod_LoadFaces (bsp); + Mod_LoadMarksurfaces (bsp); + Mod_LoadVisibility (bsp); + Mod_LoadLeafs (bsp); + Mod_LoadNodes (bsp); + Mod_LoadClipnodes (bsp); + Mod_LoadEntities (bsp); + Mod_LoadSubmodels (bsp); Mod_MakeHull0 (); diff --git a/libs/models/brush/sw_model_brush.c b/libs/models/brush/sw_model_brush.c index d072779f8..4d875fffc 100644 --- a/libs/models/brush/sw_model_brush.c +++ b/libs/models/brush/sw_model_brush.c @@ -62,13 +62,13 @@ Mod_LoadExternalTextures (model_t *mod) } void -Mod_LoadLighting (lump_t *l) +Mod_LoadLighting (bsp_t *bsp) { mod_lightmap_bytes = 1; - if (!l->filelen) { + if (!bsp->lightdatasize) { loadmodel->lightdata = NULL; return; } - loadmodel->lightdata = Hunk_AllocName (l->filelen, loadname); - memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen); + loadmodel->lightdata = Hunk_AllocName (bsp->lightdatasize, loadname); + memcpy (loadmodel->lightdata, bsp->lightdata, bsp->lightdatasize); } diff --git a/libs/models/null_model.c b/libs/models/null_model.c index 6f77a7fa2..bd6ccac38 100644 --- a/libs/models/null_model.c +++ b/libs/models/null_model.c @@ -38,7 +38,7 @@ static __attribute__ ((used)) const char rcsid[] = int mod_lightmap_bytes = 1; void -Mod_LoadLighting (lump_t *l) +Mod_LoadLighting (bsp_t *bsp) { } diff --git a/libs/util/bspfile.c b/libs/util/bspfile.c index d0f05b565..a0b10c2bb 100644 --- a/libs/util/bspfile.c +++ b/libs/util/bspfile.c @@ -47,7 +47,8 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/sys.h" static void -swap_bsp (bsp_t *bsp, int todisk) +swap_bsp (bsp_t *bsp, int todisk, void (*cb) (const bsp_t *, void *), + void *cbdata) { int c, i, j; dmiptexlump_t *mtl; @@ -61,6 +62,8 @@ swap_bsp (bsp_t *bsp, int todisk) bsp->header->lumps[i].filelen = LittleLong (bsp->header->lumps[i].filelen); } + if (cb) + cb (bsp, cbdata); } // models @@ -186,11 +189,10 @@ swap_bsp (bsp_t *bsp, int todisk) } bsp_t * -LoadBSPMem (void *mem, size_t mem_size) +LoadBSPMem (void *mem, size_t mem_size, void (*cb) (const bsp_t *, void *), + void *cbdata) { - byte *data = mem; bsp_t *bsp; - size_t size; bsp = calloc (sizeof (bsp_t), 1); @@ -203,11 +205,13 @@ LoadBSPMem (void *mem, size_t mem_size) #undef SET_LUMP #define SET_LUMP(l,n) \ do { \ - size = LittleLong (bsp->header->lumps[l].filelen); \ - data = (byte *) mem + LittleLong (bsp->header->lumps[l].fileofs); \ - if ((data + size) > ((byte *) mem + mem_size)) { \ + size_t size = LittleLong (bsp->header->lumps[l].filelen); \ + size_t offs = LittleLong (bsp->header->lumps[l].fileofs); \ + void *data = (byte *) mem + offs; \ + if (offs >= mem_size || (offs + size) > mem_size) \ Sys_Error ("invalid lump"); \ - } \ + if (size % sizeof (bsp->n[0])) \ + Sys_Error ("funny lump size"); \ bsp->n = 0; \ if (size) \ bsp->n = (void *) data; \ @@ -229,11 +233,11 @@ do { \ #undef SET_LUMP #define SET_LUMP(l,n) \ do { \ - size = LittleLong (bsp->header->lumps[l].filelen); \ - data = (byte *) mem + LittleLong (bsp->header->lumps[l].fileofs); \ - if ((data + size) > ((byte *) mem + mem_size)) { \ + size_t size = LittleLong (bsp->header->lumps[l].filelen); \ + size_t offs = LittleLong (bsp->header->lumps[l].fileofs); \ + void *data = (byte *) mem + offs; \ + if (offs >= mem_size || (offs + size) > mem_size) \ Sys_Error ("invalid lump"); \ - } \ bsp->n = 0; \ if (size) \ bsp->n = (void *) data; \ @@ -245,7 +249,7 @@ do { \ SET_LUMP (LUMP_ENTITIES, entdata); SET_LUMP (LUMP_TEXTURES, texdata); - swap_bsp (bsp, 0); + swap_bsp (bsp, 0, cb, cbdata); return bsp; } @@ -257,7 +261,7 @@ LoadBSPFile (QFile *file, size_t size) buf = malloc (size); Qread (file, buf, size); - bsp = LoadBSPMem (buf, size); + bsp = LoadBSPMem (buf, size, 0, 0); bsp->own_header = 1; return bsp; } @@ -347,7 +351,7 @@ do { \ SET_LUMP (LUMP_ENTITIES, entdata); SET_LUMP (LUMP_TEXTURES, texdata); - swap_bsp (&tbsp, 1); + swap_bsp (&tbsp, 1, 0, 0); Qwrite (file, tbsp.header, size); free (tbsp.header);