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.
This commit is contained in:
Bill Currie 2010-08-23 11:56:43 +09:00
parent 7fca21837a
commit cd159e1cc1
7 changed files with 138 additions and 145 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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 ();

View File

@ -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);
}

View File

@ -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)
{
}

View File

@ -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);