[PATCH] qbsp: Remove big mapentity_t union

Remove the big union in mapentity_t, collecting together the information for
each lump in a struct. Still not 100% sure where I'm going with this, but I
think this will help me with removing some of the reliance on globals further
along (which will be important once it comes to multi-threading).

Signed-off-by: Tyrann <tyrann@disenchant.net>
This commit is contained in:
Tyrann 2007-08-21 23:18:56 +09:30
parent 1cfdcdb85a
commit d5f000838f
7 changed files with 204 additions and 230 deletions

View File

@ -752,15 +752,17 @@ static brush_t *
LoadBrush(int iBrush)
{
brush_t *b;
mapbrush_t *mb;
int contents;
char *szName;
face_t *pFaceList;
mapface_t *face;
texinfo_t *texinfo = pWorldEnt->lumps[BSPTEXINFO].data;
// check texture name for attributes
szName =
rgszMiptex[pWorldEnt->
pTexinfo[map.rgFaces[map.rgBrushes[iBrush].iFaceStart].
texinfo].miptex];
/* check texture name for attributes */
mb = &map.rgBrushes[iBrush];
face = &map.rgFaces[mb->iFaceStart];
szName = rgszMiptex[texinfo[face->texinfo].miptex];
if (!strcasecmp(szName, "clip") && hullnum == 0)
return NULL; // "clip" brushes don't show up in the draw hull
@ -783,13 +785,9 @@ LoadBrush(int iBrush)
if (hullnum && contents != CONTENTS_SOLID && contents != CONTENTS_SKY)
return NULL; // water brushes don't show up in clipping hulls
// no seperate textures on clip hull
// create the faces
numbrushfaces =
map.rgBrushes[iBrush].iFaceEnd - map.rgBrushes[iBrush].iFaceStart;
memcpy(faces, &(map.rgFaces[map.rgBrushes[iBrush].iFaceStart]),
numbrushfaces * sizeof(mapface_t));
numbrushfaces = mb->iFaceEnd - mb->iFaceStart;
memcpy(faces, face, numbrushfaces * sizeof(mapface_t));
pFaceList = CreateBrushFaces();

View File

@ -36,6 +36,7 @@ LoadBSPFile(void)
{
int i;
int cFileSize, cLumpSize, iLumpOff;
mapentity_t *ent;
// Load the file header
StripExtension(options.szBSPName);
@ -46,20 +47,18 @@ LoadBSPFile(void)
Message(msgError, errBadVersion, options.szBSPName, header->version,
BSPVERSION);
// Throw all of the data into the first entity to be written out later
/* Throw all of the data into the first entity to be written out later */
ent = map.rgEntities;
for (i = 0; i < BSP_LUMPS; i++) {
map.cTotal[i] = cLumpSize = header->lumps[i].filelen;
iLumpOff = header->lumps[i].fileofs;
if (cLumpSize % rgcMemSize[i])
Message(msgError, errDeformedBSPLump, rgcMemSize[i], cLumpSize);
map.rgEntities[0].cData[i] = cLumpSize / rgcMemSize[i];
map.rgEntities[0].pData[i] =
AllocMem(i, map.rgEntities[0].cData[i], false);
ent->lumps[i].count = cLumpSize / rgcMemSize[i];
ent->lumps[i].data = AllocMem(i, ent->lumps[i].count, false);
memcpy(map.rgEntities[0].pData[i], (byte *)header + iLumpOff,
cLumpSize);
memcpy(ent->lumps[i].data, (byte *)header + iLumpOff, cLumpSize);
}
FreeMem(header, OTHER, cFileSize + 1);
@ -72,20 +71,21 @@ static void
AddLump(FILE *f, int Type)
{
lump_t *lump;
int cLen = 0, templen;
int cLen = 0;
int iEntity;
size_t ret;
struct lumpdata *entities;
lump = &header->lumps[Type];
lump->fileofs = ftell(f);
for (iEntity = 0; iEntity < map.cEntities; iEntity++) {
if (map.rgEntities[iEntity].pData[Type] != NULL) {
templen = map.rgEntities[iEntity].cData[Type] * rgcMemSize[Type];
ret = fwrite(map.rgEntities[iEntity].pData[Type], 1, templen, f);
if (ret != templen)
entities = &map.rgEntities[iEntity].lumps[Type];
if (entities->data) {
ret = fwrite(entities->data, rgcMemSize[Type], entities->count, f);
if (ret != entities->count)
Message(msgError, errWriteFailure);
cLen += templen;
cLen += entities->count * rgcMemSize[Type];
}
}
@ -171,6 +171,8 @@ Dumps info about current file
void
PrintBSPFileSizes(void)
{
struct lumpdata *lump;
Message(msgStat, "%5i planes %6i", map.cTotal[BSPPLANE],
map.cTotal[BSPPLANE] * rgcMemSize[BSPPLANE]);
Message(msgStat, "%5i vertexes %6i", map.cTotal[BSPVERTEX],
@ -191,12 +193,14 @@ PrintBSPFileSizes(void)
map.cTotal[BSPSURFEDGE] * rgcMemSize[BSPSURFEDGE]);
Message(msgStat, "%5i edges %6i", map.cTotal[BSPEDGE],
map.cTotal[BSPEDGE] * rgcMemSize[BSPEDGE]);
if (!pWorldEnt->cTexdata)
Message(msgStat, " 0 textures 0");
else
lump = &pWorldEnt->lumps[BSPTEX];
if (lump->data)
Message(msgStat, "%5i textures %6i",
((dmiptexlump_t *)pWorldEnt->pTexdata)->nummiptex,
pWorldEnt->cTexdata);
((dmiptexlump_t *)lump->data)->nummiptex, lump->count);
else
Message(msgStat, " 0 textures 0");
Message(msgStat, " lightdata %6i", map.cTotal[BSPLIGHT]);
Message(msgStat, " visdata %6i", map.cTotal[BSPVIS]);
Message(msgStat, " entdata %6i", map.cTotal[BSPENT] + 1); // +1 for null terminator

View File

@ -70,8 +70,8 @@ FindTexinfo(texinfo_t *t)
&& !options.fSplitspecial)
t->flags |= TEX_SPECIAL;
tex = pWorldEnt->pTexinfo;
for (i = 0; i < pWorldEnt->iTexinfo; i++, tex++) {
tex = (texinfo_t *)pWorldEnt->lumps[BSPTEXINFO].data;
for (i = 0; i < pWorldEnt->lumps[BSPTEXINFO].index; i++, tex++) {
if (t->miptex != tex->miptex)
continue;
if (t->flags != tex->flags)
@ -87,8 +87,8 @@ FindTexinfo(texinfo_t *t)
}
// allocate a new texture
pWorldEnt->pTexinfo[i] = *t;
pWorldEnt->iTexinfo++;
*((texinfo_t *)pWorldEnt->lumps[BSPTEXINFO].data + i) = *t;
pWorldEnt->lumps[BSPTEXINFO].index++;
map.cTotal[BSPTEXINFO]++;
return i;
@ -426,7 +426,7 @@ ParseEntity(mapentity_t *e)
if (map.iEntities >= map.cEntities)
Message(msgError, errLowEntCount);
pCurEnt->iBrushEnd = map.iBrushes + 1;
e->iBrushEnd = map.iBrushes + 1;
do {
if (!ParseToken(PARSE_NORMAL))
@ -440,10 +440,10 @@ ParseEntity(mapentity_t *e)
} while (1);
// Allocate some model memory while we're here
pCurEnt->iBrushStart = map.iBrushes + 1;
if (pCurEnt->iBrushStart != pCurEnt->iBrushEnd) {
pCurEnt->pModels = AllocMem(BSPMODEL, 1, true);
pCurEnt->cModels = 1;
e->iBrushStart = map.iBrushes + 1;
if (e->iBrushStart != e->iBrushEnd) {
e->lumps[BSPMODEL].data = AllocMem(BSPMODEL, 1, true);
e->lumps[BSPMODEL].count = 1;
}
return true;
@ -454,6 +454,7 @@ static void
PreParseFile(char *buf)
{
int braces = 0;
struct lumpdata *texinfo;
map.cEntities = map.cBrushes = map.cFaces = 0;
@ -500,8 +501,9 @@ PreParseFile(char *buf)
// Allocate maximum memory here, copy over later
// Maximum possible is one miptex/texinfo per face
rgszMiptex = AllocMem(MIPTEX, map.cFaces, true);
pWorldEnt->pTexinfo = AllocMem(BSPTEXINFO, map.cFaces, true);
pWorldEnt->cTexinfo = map.cFaces;
texinfo = &pWorldEnt->lumps[BSPTEXINFO];
texinfo->data = AllocMem(BSPTEXINFO, map.cFaces, true);
texinfo->count = map.cFaces;
}
@ -511,6 +513,7 @@ LoadMapFile(void)
char *buf;
int i, j, length;
void *pTemp;
struct lumpdata *texinfo;
Message(msgProgress, "LoadMapFile");
@ -551,15 +554,15 @@ LoadMapFile(void)
FreeMem(pTemp, MIPTEX, map.cFaces);
}
if (pWorldEnt->iTexinfo > pWorldEnt->cTexinfo)
texinfo = &pWorldEnt->lumps[BSPTEXINFO];
if (texinfo->index > texinfo->count)
Message(msgError, errLowTexinfoCount);
else if (pWorldEnt->iTexinfo < pWorldEnt->cTexinfo) {
pTemp = (void *)pWorldEnt->pTexinfo;
pWorldEnt->pTexinfo = AllocMem(BSPTEXINFO, pWorldEnt->iTexinfo, true);
memcpy(pWorldEnt->pTexinfo, pTemp,
pWorldEnt->iTexinfo * rgcMemSize[BSPTEXINFO]);
FreeMem(pTemp, BSPTEXINFO, pWorldEnt->cTexinfo);
pWorldEnt->cTexinfo = pWorldEnt->iTexinfo;
else if (texinfo->index < texinfo->count) {
pTemp = texinfo->data;
texinfo->data = AllocMem(BSPTEXINFO, texinfo->index, true);
memcpy(texinfo->data, pTemp, texinfo->index * rgcMemSize[BSPTEXINFO]);
FreeMem(pTemp, BSPTEXINFO, texinfo->count);
texinfo->count = texinfo->index;
}
// One plane per face + 6 for portals
cPlanes = map.cFaces + 6;
@ -604,7 +607,7 @@ LoadMapFile(void)
Message(msgStat, "%5i brushes", map.cBrushes);
Message(msgStat, "%5i entities", map.cEntities);
Message(msgStat, "%5i unique texnames", cMiptex);
Message(msgStat, "%5i texinfo", pWorldEnt->cTexinfo);
Message(msgStat, "%5i texinfo", texinfo->count);
Message(msgLiteral, "\n");
}
@ -675,16 +678,18 @@ WriteEntitiesToString(void)
char szLine[129];
int iEntity;
int cLen;
struct lumpdata *entities;
map.cTotal[BSPENT] = 0;
for (iEntity = 0; iEntity < map.cEntities; iEntity++) {
ep = map.rgEntities[iEntity].epairs;
entities = &map.rgEntities[iEntity].lumps[BSPENT];
// ent got removed
if (!ep) {
map.rgEntities[iEntity].cEntdata = 0;
map.rgEntities[iEntity].pEntdata = NULL;
entities->count = 0;
entities->data = NULL;
continue;
}
@ -702,9 +707,9 @@ WriteEntitiesToString(void)
// Add 4 for {\n and }\n
cLen += 4;
map.rgEntities[iEntity].cEntdata = cLen;
entities->count = cLen;
map.cTotal[BSPENT] += cLen;
map.rgEntities[iEntity].pEntdata = pCur = AllocMem(BSPENT, cLen, true);
entities->data = pCur = AllocMem(BSPENT, cLen, true);
*pCur = 0;
strcat(pCur, "{\n");

View File

@ -574,76 +574,21 @@ typedef struct mapbrush_s {
int iFaceEnd;
} mapbrush_t;
struct lumpdata {
int count;
int index;
void *data;
};
typedef struct mapentity_s {
vec3_t origin;
int iBrushStart;
int iBrushEnd;
epair_t *epairs;
vec3_t mins, maxs;
brush_t *pBrushes; // NULL terminated list
brush_t *pBrushes; /* NULL terminated list */
int cBrushes;
// Contains two alternate ways of accessing memory, via enum or individual vars
// Ensure vars match up with the lump enum
union {
struct {
// Total counts
int cEntdata;
int cPlanes;
int cTexdata;
int cVertices;
int cVisdata;
int cNodes;
int cTexinfo;
int cFaces;
int cLightdata;
int cClipnodes;
int cLeaves;
int cMarksurfaces;
int cEdges;
int cSurfedges;
int cModels;
// Current indices into data
int iEntdata;
int iPlanes;
int iTexdata;
int iVertices;
int iVisdata;
int iNodes;
int iTexinfo;
int iFaces;
int iLightdata;
int iClipnodes;
int iLeaves;
int iMarksurfaces;
int iEdges;
int iSurfedges;
int iModels;
// Pointers to data
char *pEntdata;
dplane_t *pPlanes;
byte *pTexdata;
dvertex_t *pVertices;
byte *pVisdata;
dnode_t *pNodes;
texinfo_t *pTexinfo;
dface_t *pFaces;
byte *pLightdata;
dclipnode_t *pClipnodes;
dleaf_t *pLeaves;
unsigned short *pMarksurfaces;
dedge_t *pEdges;
int *pSurfedges;
dmodel_t *pModels;
};
struct {
int cData[BSP_LUMPS];
int iData[BSP_LUMPS];
void *pData[BSP_LUMPS];
};
};
struct lumpdata lumps[BSP_LUMPS];
} mapentity_t;
typedef struct mapdata_s {

View File

@ -49,9 +49,8 @@ SubdivideFace(face_t *f, face_t **prevptr)
texinfo_t *tex;
vec3_t tmp;
// special (non-surface cached) faces don't need subdivision
tex = &pWorldEnt->pTexinfo[f->texturenum];
/* special (non-surface cached) faces don't need subdivision */
tex = (texinfo_t *)pWorldEnt->lumps[BSPTEXINFO].data + f->texturenum;
if (tex->flags & TEX_SPECIAL)
return;
@ -213,6 +212,7 @@ GetVertex(vec3_t in)
int i;
hashvert_t *hv;
vec3_t vert;
struct lumpdata *vertices = &pCurEnt->lumps[BSPVERTEX];
for (i = 0; i < 3; i++) {
if (fabs(in[i] - Q_rint(in[i])) < ZERO_EPSILON)
@ -241,13 +241,13 @@ GetVertex(vec3_t in)
hvert_p++;
// emit a vertex
pCurEnt->pVertices[pCurEnt->iVertices].point[0] = vert[0];
pCurEnt->pVertices[pCurEnt->iVertices].point[1] = vert[1];
pCurEnt->pVertices[pCurEnt->iVertices].point[2] = vert[2];
pCurEnt->iVertices++;
((dvertex_t *)vertices->data)[vertices->index].point[0] = vert[0];
((dvertex_t *)vertices->data)[vertices->index].point[1] = vert[1];
((dvertex_t *)vertices->data)[vertices->index].point[2] = vert[2];
vertices->index++;
map.cTotal[BSPVERTEX]++;
if (pCurEnt->iVertices > pCurEnt->cVertices)
if (vertices->index > vertices->count)
Message(msgError, errLowVertexCount);
return hv->num;
@ -270,6 +270,7 @@ GetEdge(vec3_t p1, vec3_t p2, face_t *f)
int v1, v2;
dedge_t *edge;
int i;
struct lumpdata *edges = &pCurEnt->lumps[BSPEDGE];
if (!f->contents[0])
Message(msgError, errZeroContents);
@ -277,8 +278,9 @@ GetEdge(vec3_t p1, vec3_t p2, face_t *f)
c_tryedges++;
v1 = GetVertex(p1);
v2 = GetVertex(p2);
for (i = 0; i < pCurEnt->iEdges; i++) {
edge = pCurEnt->pEdges + i;
for (i = 0; i < edges->index; i++) {
edge = (dedge_t *)edges->data + i;
if (v1 == edge->v[1] && v2 == edge->v[0]
&& pEdgeFaces1[i] == NULL
&& pEdgeFaces0[i]->contents[0] == f->contents[0]) {
@ -288,11 +290,11 @@ GetEdge(vec3_t p1, vec3_t p2, face_t *f)
}
// emit an edge
if (pCurEnt->iEdges >= pCurEnt->cEdges)
if (edges->index >= edges->count)
Message(msgError, errLowEdgeCount);
edge = pCurEnt->pEdges + pCurEnt->iEdges;
pCurEnt->iEdges++;
edge = (dedge_t *)edges->data + edges->index;
edges->index++;
map.cTotal[BSPEDGE]++;
edge->v[0] = v1;
edge->v[1] = v2;
@ -357,6 +359,8 @@ GrowNodeRegion_r(node_t *node)
dface_t *r;
face_t *f;
int i;
struct lumpdata *surfedges = &pCurEnt->lumps[BSPSURFEDGE];
struct lumpdata *faces = &pCurEnt->lumps[BSPFACE];
if (node->planenum == PLANENUM_LEAF)
return;
@ -369,7 +373,7 @@ GrowNodeRegion_r(node_t *node)
// emit a region
f->outputnumber = map.cTotal[BSPFACE];
r = pCurEnt->pFaces + pCurEnt->iFaces;
r = (dface_t *)faces->data + faces->index;
r->planenum = node->outputplanenum;
r->side = f->planeside;
@ -380,8 +384,8 @@ GrowNodeRegion_r(node_t *node)
r->firstedge = map.cTotal[BSPSURFEDGE];
for (i = 0; i < f->w.numpoints; i++) {
pCurEnt->pSurfedges[pCurEnt->iSurfedges] = f->edges[i];
pCurEnt->iSurfedges++;
((int *)surfedges->data)[surfedges->index] = f->edges[i];
surfedges->index++;
map.cTotal[BSPSURFEDGE]++;
}
FreeMem(f->edges, OTHER, f->w.numpoints * sizeof(int));
@ -389,7 +393,7 @@ GrowNodeRegion_r(node_t *node)
r->numedges = map.cTotal[BSPSURFEDGE] - r->firstedge;
map.cTotal[BSPFACE]++;
pCurEnt->iFaces++;
faces->index++;
}
node->numfaces = map.cTotal[BSPFACE] - node->firstface;
@ -412,8 +416,8 @@ CountData_r(node_t *node)
return;
for (f = node->faces; f; f = f->next) {
pCurEnt->cFaces++;
pCurEnt->cVertices += f->w.numpoints;
pCurEnt->lumps[BSPFACE].count++;
pCurEnt->lumps[BSPVERTEX].count += f->w.numpoints;
}
CountData_r(node->children[0]);
@ -431,30 +435,35 @@ MakeFaceEdges(node_t *headnode)
{
int i;
void *pTemp;
struct lumpdata *surfedges = &pCurEnt->lumps[BSPSURFEDGE];
struct lumpdata *edges = &pCurEnt->lumps[BSPEDGE];
struct lumpdata *vertices = &pCurEnt->lumps[BSPVERTEX];
struct lumpdata *faces = &pCurEnt->lumps[BSPFACE];
Message(msgProgress, "MakeFaceEdges");
cStartEdge = 0;
for (i = 0; i < map.iEntities; i++)
cStartEdge += map.rgEntities[i].cEdges;
cStartEdge += map.rgEntities[i].lumps[BSPEDGE].count;
CountData_r(headnode);
// Guess: less than half vertices actually are unique. Add one to round up odd
// values. Remember edges are +1 in BeginBSPFile.
pCurEnt->cSurfedges = pCurEnt->cVertices;
pCurEnt->cVertices++;
pCurEnt->cVertices /= 2;
// pCurEnt->cEdges = pCurEnt->cVertices;
pCurEnt->cEdges += pCurEnt->cSurfedges;
/*
* Guess: less than half vertices actually are unique. Add one to round up
* odd values. Remember edges are +1 in BeginBSPFile.
*/
surfedges->count = vertices->count;
vertices->count++;
vertices->count /= 2;
edges->count += surfedges->count;
pCurEnt->pVertices = AllocMem(BSPVERTEX, pCurEnt->cVertices, true);
pCurEnt->pEdges = AllocMem(BSPEDGE, pCurEnt->cEdges, true);
vertices->data = AllocMem(BSPVERTEX, vertices->count, true);
edges->data = AllocMem(BSPEDGE, edges->count, true);
// Accessory data
pHashverts = AllocMem(HASHVERT, pCurEnt->cVertices, true);
pEdgeFaces0 = AllocMem(OTHER, sizeof(face_t *) * pCurEnt->cEdges, true);
pEdgeFaces1 = AllocMem(OTHER, sizeof(face_t *) * pCurEnt->cEdges, true);
pHashverts = AllocMem(HASHVERT, vertices->count, true);
pEdgeFaces0 = AllocMem(OTHER, sizeof(face_t *) * edges->count, true);
pEdgeFaces1 = AllocMem(OTHER, sizeof(face_t *) * edges->count, true);
InitHash();
c_tryedges = 0;
@ -462,29 +471,28 @@ MakeFaceEdges(node_t *headnode)
MakeFaceEdges_r(headnode);
FreeMem(pHashverts, HASHVERT, pCurEnt->cVertices);
FreeMem(pEdgeFaces0, OTHER, sizeof(face_t *) * pCurEnt->cEdges);
FreeMem(pEdgeFaces1, OTHER, sizeof(face_t *) * pCurEnt->cEdges);
FreeMem(pHashverts, HASHVERT, vertices->count);
FreeMem(pEdgeFaces0, OTHER, sizeof(face_t *) * edges->count);
FreeMem(pEdgeFaces1, OTHER, sizeof(face_t *) * edges->count);
// Swap these...
if (pCurEnt->iVertices < pCurEnt->cVertices) {
pTemp = AllocMem(BSPVERTEX, pCurEnt->iVertices, true);
memcpy(pTemp, pCurEnt->pVertices,
rgcMemSize[BSPVERTEX] * pCurEnt->iVertices);
FreeMem(pCurEnt->pVertices, BSPVERTEX, pCurEnt->cVertices);
pCurEnt->pVertices = (dvertex_t *)pTemp;
pCurEnt->cVertices = pCurEnt->iVertices;
if (vertices->index < vertices->count) {
pTemp = AllocMem(BSPVERTEX, vertices->index, true);
memcpy(pTemp, vertices->data, rgcMemSize[BSPVERTEX] * vertices->index);
FreeMem(vertices->data, BSPVERTEX, vertices->count);
vertices->data = pTemp;
vertices->count = vertices->index;
}
if (pCurEnt->iEdges < pCurEnt->cEdges) {
pTemp = AllocMem(BSPEDGE, pCurEnt->iEdges, true);
memcpy(pTemp, pCurEnt->pEdges, rgcMemSize[BSPEDGE] * pCurEnt->iEdges);
FreeMem(pCurEnt->pEdges, BSPEDGE, pCurEnt->cEdges);
pCurEnt->pEdges = (dedge_t *)pTemp;
pCurEnt->cEdges = pCurEnt->iEdges;
if (edges->index < edges->count) {
pTemp = AllocMem(BSPEDGE, edges->index, true);
memcpy(pTemp, edges->data, rgcMemSize[BSPEDGE] * edges->index);
FreeMem(edges->data, BSPEDGE, edges->count);
edges->data = pTemp;
edges->count = edges->index;
}
pCurEnt->pSurfedges = AllocMem(BSPSURFEDGE, pCurEnt->cSurfedges, true);
pCurEnt->pFaces = AllocMem(BSPFACE, pCurEnt->cFaces, true);
surfedges->data = AllocMem(BSPSURFEDGE, surfedges->count, true);
faces->data = AllocMem(BSPFACE, faces->count, true);
Message(msgProgress, "GrowRegions");
GrowNodeRegion_r(headnode);

View File

@ -136,7 +136,8 @@ void
WADList_Process(wad_t *wads, int numwads)
{
int i, j, k;
dmiptexlump_t *l;
dmiptexlump_t *miptex;
struct lumpdata *texdata = &pWorldEnt->lumps[BSPTEX];
if (numwads < 1)
return;
@ -149,7 +150,7 @@ WADList_Process(wad_t *wads, int numwads)
for (k = 0; k < wads[j].header.numlumps; k++)
if (!strcasecmp(rgszMiptex[i], wads[j].lumps[k].name)) {
// Found it. Add in the size and skip to outer loop.
pWorldEnt->cTexdata += wads[j].lumps[k].disksize;
texdata->count += wads[j].lumps[k].disksize;
j = numwads;
break;
}
@ -158,19 +159,19 @@ WADList_Process(wad_t *wads, int numwads)
break;
}
pWorldEnt->cTexdata += sizeof(int) * (cMiptex + 1);
texdata->count += sizeof(int) * (cMiptex + 1);
// Default texture data to store in worldmodel
pWorldEnt->pTexdata = AllocMem(BSPTEX, pWorldEnt->cTexdata, true);
l = (dmiptexlump_t *)pWorldEnt->pTexdata;
l->nummiptex = cMiptex;
texdata->data = AllocMem(BSPTEX, texdata->count, true);
miptex = (dmiptexlump_t *)texdata->data;
miptex->nummiptex = cMiptex;
WADList_LoadTextures(wads, numwads, l);
WADList_LoadTextures(wads, numwads, miptex);
// Last pass, mark unfound textures as such
for (i = 0; i < cMiptex; i++)
if (l->dataofs[i] == 0) {
l->dataofs[i] = -1;
if (miptex->dataofs[i] == 0) {
miptex->dataofs[i] = -1;
Message(msgWarning, warnTextureNotFound, rgszMiptex[i]);
}
}
@ -181,6 +182,7 @@ WADList_LoadTextures(wad_t *wads, int numwads, dmiptexlump_t *l)
{
int i, j, len;
byte *data;
struct lumpdata *texdata = &pWorldEnt->lumps[BSPTEX];
data = (byte *)&l->dataofs[cMiptex];
for (i = 0; i < numwads; i++) {
@ -191,7 +193,7 @@ WADList_LoadTextures(wad_t *wads, int numwads, dmiptexlump_t *l)
l->dataofs[j] = data - (byte *)l;
len = WAD_LoadLump(wads + i, rgszMiptex[j], data);
if (data + len - pWorldEnt->pTexdata > pWorldEnt->cTexdata)
if (data + len - (byte *)texdata->data > texdata->count)
Message(msgError, errLowTextureCount);
// didn't find the texture

View File

@ -33,15 +33,16 @@ ExportNodePlanes_r(node_t *node)
dplane_t *dplane;
int i;
vec3_t tmp;
struct lumpdata *planes = &pWorldEnt->lumps[BSPPLANE];
if (node->planenum == -1)
return;
if (planemapping[node->planenum] == -1) {
plane = &pPlanes[node->planenum];
dplane = pWorldEnt->pPlanes;
dplane = (dplane_t *)planes->data;
// search for an equivalent plane
for (i = 0; i < pWorldEnt->iPlanes; i++, dplane++) {
for (i = 0; i < planes->index; i++, dplane++) {
tmp[0] = dplane->normal[0];
tmp[1] = dplane->normal[1];
tmp[2] = dplane->normal[2];
@ -54,18 +55,18 @@ ExportNodePlanes_r(node_t *node)
// a new plane
planemapping[node->planenum] = i;
if (i == pWorldEnt->iPlanes) {
if (pWorldEnt->iPlanes >= pWorldEnt->cPlanes)
if (i == planes->index) {
if (planes->index >= planes->count)
Message(msgError, errLowPlaneCount);
plane = &pPlanes[node->planenum];
dplane = pWorldEnt->pPlanes + pWorldEnt->iPlanes;
dplane = (dplane_t *)planes->data + planes->index;
dplane->normal[0] = plane->normal[0];
dplane->normal[1] = plane->normal[1];
dplane->normal[2] = plane->normal[2];
dplane->dist = plane->dist;
dplane->type = plane->type;
pWorldEnt->iPlanes++;
planes->index++;
map.cTotal[BSPPLANE]++;
}
}
@ -84,17 +85,19 @@ ExportNodePlanes
void
ExportNodePlanes(node_t *nodes)
{
struct lumpdata *planes = &pWorldEnt->lumps[BSPPLANE];
// OK just need one plane array, stick it in worldmodel
if (pWorldEnt->pPlanes == NULL) {
if (!planes->data) {
// I'd like to use numbrushplanes here but we haven't seen every entity yet...
pWorldEnt->cPlanes = cPlanes;
pWorldEnt->pPlanes = AllocMem(BSPPLANE, pWorldEnt->cPlanes, true);
planes->count = cPlanes;
planes->data = AllocMem(BSPPLANE, planes->count, true);
}
// TODO: make one-time allocation?
planemapping = AllocMem(OTHER, sizeof(int) * pWorldEnt->cPlanes, true);
memset(planemapping, -1, sizeof(int *) * pWorldEnt->cPlanes);
planemapping = AllocMem(OTHER, sizeof(int) * planes->count, true);
memset(planemapping, -1, sizeof(int *) * planes->count);
ExportNodePlanes_r(nodes);
FreeMem(planemapping, OTHER, sizeof(int) * pWorldEnt->cPlanes);
FreeMem(planemapping, OTHER, sizeof(int) * planes->count);
}
//===========================================================================
@ -111,7 +114,7 @@ CountClipNodes_r(node_t *node)
if (node->planenum == -1)
return;
pCurEnt->cClipnodes++;
pCurEnt->lumps[BSPCLIPNODE].count++;
CountClipNodes_r(node->children[0]);
CountClipNodes_r(node->children[1]);
@ -128,6 +131,7 @@ ExportClipNodes_r(node_t *node)
int i, c;
dclipnode_t *cn;
face_t *f, *next;
struct lumpdata *clipnodes = &pCurEnt->lumps[BSPCLIPNODE];
// FIXME: free more stuff?
if (node->planenum == -1) {
@ -137,8 +141,8 @@ ExportClipNodes_r(node_t *node)
}
// emit a clipnode
c = map.cTotal[BSPCLIPNODE];
cn = pCurEnt->pClipnodes + pCurEnt->iClipnodes;
pCurEnt->iClipnodes++;
cn = (dclipnode_t *)clipnodes->data + clipnodes->index;
clipnodes->index++;
map.cTotal[BSPCLIPNODE]++;
cn->planenum = node->outputplanenum;
@ -172,31 +176,32 @@ ExportClipNodes(node_t *nodes)
int oldcount, i, diff;
int clipcount = 0;
dclipnode_t *pTemp;
struct lumpdata *clipnodes = &pCurEnt->lumps[BSPCLIPNODE];
dmodel_t *model = (dmodel_t *)pCurEnt->lumps[BSPMODEL].data;
oldcount = pCurEnt->cClipnodes;
oldcount = clipnodes->count;
// Count nodes before this one
for (i = 0; i < map.iEntities; i++)
clipcount += map.rgEntities[i].cClipnodes;
pCurEnt->pModels->headnode[hullnum] = clipcount + oldcount;
clipcount += map.rgEntities[i].lumps[BSPCLIPNODE].count;
model->headnode[hullnum] = clipcount + oldcount;
CountClipNodes_r(nodes);
if (pCurEnt->cClipnodes > MAX_BSP_CLIPNODES)
if (clipnodes->count > MAX_BSP_CLIPNODES)
Message(msgError, errTooManyClipnodes);
pTemp = pCurEnt->pClipnodes;
pCurEnt->pClipnodes = AllocMem(BSPCLIPNODE, pCurEnt->cClipnodes, true);
if (pTemp != NULL) {
memcpy(pCurEnt->pClipnodes, pTemp,
oldcount * rgcMemSize[BSPCLIPNODE]);
pTemp = clipnodes->data;
clipnodes->data = AllocMem(BSPCLIPNODE, clipnodes->count, true);
if (pTemp) {
memcpy(clipnodes->data, pTemp, oldcount * rgcMemSize[BSPCLIPNODE]);
FreeMem(pTemp, BSPCLIPNODE, oldcount);
// Worthwhile to special-case this for entity 0 (no modification needed)
diff = clipcount - pCurEnt->pModels->headnode[1];
diff = clipcount - model->headnode[1];
if (diff != 0) {
pCurEnt->pModels->headnode[1] += diff;
model->headnode[1] += diff;
for (i = 0; i < oldcount; i++) {
pTemp = pCurEnt->pClipnodes + i;
pTemp = (dclipnode_t *)clipnodes->data + i;
if (pTemp->children[0] >= 0)
pTemp->children[0] += diff;
if (pTemp->children[1] >= 0)
@ -222,10 +227,10 @@ CountLeaves(node_t *node)
{
face_t **fp, *f;
pCurEnt->cLeaves++;
pCurEnt->lumps[BSPLEAF].count++;
for (fp = node->markfaces; *fp; fp++)
for (f = *fp; f; f = f->original)
pCurEnt->cMarksurfaces++;
pCurEnt->lumps[BSPMARKSURF].count++;
}
/*
@ -238,7 +243,7 @@ CountNodes_r(node_t *node)
{
int i;
pCurEnt->cNodes++;
pCurEnt->lumps[BSPNODE].count++;
for (i = 0; i < 2; i++) {
if (node->children[i]->planenum == -1) {
@ -273,10 +278,12 @@ ExportLeaf(node_t *node)
{
face_t **fp, *f;
dleaf_t *leaf_p;
struct lumpdata *leaves = &pCurEnt->lumps[BSPLEAF];
struct lumpdata *marksurfs = &pCurEnt->lumps[BSPMARKSURF];
// ptr arithmetic to get correct leaf in memory
leaf_p = pCurEnt->pLeaves + pCurEnt->iLeaves;
pCurEnt->iLeaves++;
leaf_p = (dleaf_t *)leaves->data + leaves->index;
leaves->index++;
map.cTotal[BSPLEAF]++;
leaf_p->contents = node->contents;
@ -301,9 +308,9 @@ ExportLeaf(node_t *node)
// emit a marksurface
f = *fp;
do {
*(pCurEnt->pMarksurfaces + pCurEnt->iMarksurfaces) =
*((unsigned short *)marksurfs->data + marksurfs->index) =
f->outputnumber;
pCurEnt->iMarksurfaces++;
marksurfs->index++;
map.cTotal[BSPMARKSURF]++;
f = f->original; // grab tjunction split faces
} while (f);
@ -324,10 +331,11 @@ ExportDrawNodes_r(node_t *node)
{
dnode_t *n;
int i;
struct lumpdata *nodes = &pCurEnt->lumps[BSPNODE];
// ptr arithmetic to get correct node in memory
n = pCurEnt->pNodes + pCurEnt->iNodes;
pCurEnt->iNodes++;
n = (dnode_t *)nodes->data + nodes->index;
nodes->index++;
map.cTotal[BSPNODE]++;
// VectorCopy doesn't work since dest are shorts
@ -368,21 +376,25 @@ ExportDrawNodes(node_t *headnode)
{
int i;
dmodel_t *bm;
struct lumpdata *nodes = &pCurEnt->lumps[BSPNODE];
struct lumpdata *leaves = &pCurEnt->lumps[BSPLEAF];
struct lumpdata *marksurfs = &pCurEnt->lumps[BSPMARKSURF];
// Get a feel for how many of these things there are.
CountNodes(headnode);
// emit a model
pCurEnt->pNodes = AllocMem(BSPNODE, pCurEnt->cNodes, true);
pCurEnt->pLeaves = AllocMem(BSPLEAF, pCurEnt->cLeaves, true);
pCurEnt->pMarksurfaces = AllocMem(BSPMARKSURF, pCurEnt->cMarksurfaces,
true);
nodes->data = AllocMem(BSPNODE, nodes->count, true);
leaves->data = AllocMem(BSPLEAF, leaves->count, true);
marksurfs->data = AllocMem(BSPMARKSURF, marksurfs->count, true);
// Set leaf 0 properly (must be solid). cLeaves etc incremented in BeginBSPFile.
pWorldEnt->pLeaves->contents = CONTENTS_SOLID;
bm = pCurEnt->pModels;
/*
* Set leaf 0 properly (must be solid). cLeaves etc incremented in
* BeginBSPFile.
*/
((dleaf_t *)pWorldEnt->lumps[BSPLEAF].data)->contents = CONTENTS_SOLID;
bm = (dmodel_t *)pCurEnt->lumps[BSPMODEL].data;
bm->headnode[0] = map.cTotal[BSPNODE];
bm->firstface = firstface;
bm->numfaces = map.cTotal[BSPFACE] - firstface;
@ -394,7 +406,7 @@ ExportDrawNodes(node_t *headnode)
ExportDrawNodes_r(headnode);
// Not counting initial vis leaf
bm->visleafs = pCurEnt->cLeaves;
bm->visleafs = leaves->count;
if (map.iEntities == 0)
bm->visleafs--;
@ -417,13 +429,13 @@ BeginBSPFile(void)
firstface = 0;
// First edge must remain unused because 0 can't be negated
pWorldEnt->cEdges++;
pWorldEnt->iEdges++;
pWorldEnt->lumps[BSPEDGE].count++;
pWorldEnt->lumps[BSPEDGE].index++;
map.cTotal[BSPEDGE]++;
// Leave room for leaf 0 (must be solid)
pWorldEnt->cLeaves++;
pWorldEnt->iLeaves++;
pWorldEnt->lumps[BSPLEAF].count++;
pWorldEnt->lumps[BSPLEAF].index++;
map.cTotal[BSPLEAF]++;
}
@ -437,17 +449,17 @@ void
FinishBSPFile(void)
{
dplane_t *pTemp;
struct lumpdata *planes = &pWorldEnt->lumps[BSPPLANE];
options.fVerbose = true;
Message(msgProgress, "WriteBSPFile");
// TODO: Fix this somewhere else?
pTemp = AllocMem(BSPPLANE, map.cTotal[BSPPLANE], true);
memcpy(pTemp, pWorldEnt->pPlanes,
map.cTotal[BSPPLANE] * rgcMemSize[BSPPLANE]);
FreeMem(pWorldEnt->pPlanes, BSPPLANE, pWorldEnt->cPlanes);
pWorldEnt->pPlanes = pTemp;
pWorldEnt->cPlanes = map.cTotal[BSPPLANE];
memcpy(pTemp, planes->data, map.cTotal[BSPPLANE] * rgcMemSize[BSPPLANE]);
FreeMem(planes->data, BSPPLANE, planes->count);
planes->data = pTemp;
planes->count = map.cTotal[BSPPLANE];
PrintBSPFileSizes();
WriteBSPFile();