#include "bsp5.h" int headclipnode; int firstface; //=========================================================================== /* ================== findfinalplane used to find plane index numbers for clip nodes read from child processes ================== */ int findfinalplane (dplane_t *p) { int i; dplane_t *dplane; for (i=0, dplane = dplanes ; itype != dplane->type) continue; if (p->dist != dplane->dist) continue; if (p->normal[0] != dplane->normal[0]) continue; if (p->normal[1] != dplane->normal[1]) continue; if (p->normal[2] != dplane->normal[2]) continue; return i; } // // new plane // if (numplanes == max_map_planes) error ("numplanes == max_map_planes"); dplane = &dplanes[numplanes]; *dplane = *p; numplanes++; return numplanes - 1; } int planemapping[max_map_planes]; void writenodeplanes_r (node_t *node) { plane_t *plane; dplane_t *dplane; if (node->planenum == -1) return; if (planemapping[node->planenum] == -1) { // a new plane planemapping[node->planenum] = numplanes; if (numplanes == max_map_planes) error ("numplanes == max_map_planes"); plane = &planes[node->planenum]; dplane = &dplanes[numplanes]; 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; numplanes++; } node->outputplanenum = planemapping[node->planenum]; writenodeplanes_r (node->children[0]); writenodeplanes_r (node->children[1]); } /* ================== writenodeplanes ================== */ void writenodeplanes (node_t *nodes) { memset (planemapping,-1, sizeof(planemapping)); writenodeplanes_r (nodes); } //=========================================================================== /* ================== writeclipnodes_r ================== */ int writeclipnodes_r (node_t *node) { int i, c; dclipnode_t *cn; int num; // fixme: free more stuff? if (node->planenum == -1) { num = node->contents; free (node); return num; } // emit a clipnode c = numclipnodes; cn = &dclipnodes[numclipnodes]; numclipnodes++; cn->planenum = node->outputplanenum; for (i=0 ; i<2 ; i++) cn->children[i] = writeclipnodes_r(node->children[i]); free (node); return c; } /* ================== writeclipnodes called after the clipping hull is completed. generates a disk format representation and frees the original memory. ================== */ void writeclipnodes (node_t *nodes) { headclipnode = numclipnodes; writeclipnodes_r (nodes); } //=========================================================================== /* ================== writeleaf ================== */ void writeleaf (node_t *node) { face_t **fp, *f; dleaf_t *leaf_p; // emit a leaf leaf_p = &dleafs[numleafs]; numleafs++; leaf_p->contents = node->contents; // // write bounding box info // vectorcopy (node->mins, leaf_p->mins); vectorcopy (node->maxs, leaf_p->maxs); leaf_p->visofs = -1; // no vis info yet // // write the marksurfaces // leaf_p->firstmarksurface = nummarksurfaces; for (fp=node->markfaces ; *fp ; fp++) { // emit a marksurface if (nummarksurfaces == max_map_marksurfaces) error ("nummarksurfaces == max_map_marksurfaces"); f = *fp; do { dmarksurfaces[nummarksurfaces] = f->outputnumber; nummarksurfaces++; f=f->original; // grab tjunction split faces } while (f); } leaf_p->nummarksurfaces = nummarksurfaces - leaf_p->firstmarksurface; } /* ================== writedrawnodes_r ================== */ void writedrawnodes_r (node_t *node) { dnode_t *n; int i; // emit a node if (numnodes == max_map_nodes) error ("numnodes == max_map_nodes"); n = &dnodes[numnodes]; numnodes++; vectorcopy (node->mins, n->mins); vectorcopy (node->maxs, n->maxs); n->planenum = node->outputplanenum; n->firstface = node->firstface; n->numfaces = node->numfaces; // // recursively output the other nodes // for (i=0 ; i<2 ; i++) { if (node->children[i]->planenum == -1) { if (node->children[i]->contents == contents_solid) n->children[i] = -1; else { n->children[i] = -(numleafs + 1); writeleaf (node->children[i]); } } else { n->children[i] = numnodes; writedrawnodes_r (node->children[i]); } } } /* ================== writedrawnodes ================== */ void writedrawnodes (node_t *headnode) { int i; int start; dmodel_t *bm; #if 0 if (headnode->contents < 0) error ("finishbspmodel: empty model"); #endif // emit a model if (nummodels == max_map_models) error ("nummodels == max_map_models"); bm = &dmodels[nummodels]; nummodels++; bm->headnode[0] = numnodes; bm->firstface = firstface; bm->numfaces = numfaces - firstface; firstface = numfaces; start = numleafs; if (headnode->contents < 0) writeleaf (headnode); else writedrawnodes_r (headnode); bm->visleafs = numleafs - start; for (i=0 ; i<3 ; i++) { bm->mins[i] = headnode->mins[i] + sidespace + 1; // remove the padding bm->maxs[i] = headnode->maxs[i] - sidespace - 1; } // fixme: are all the children decendant of padded nodes? } /* ================== bumpmodel used by the clipping hull processes that only need to store headclipnode ================== */ void bumpmodel (int hullnum) { dmodel_t *bm; // emit a model if (nummodels == max_map_models) error ("nummodels == max_map_models"); bm = &dmodels[nummodels]; nummodels++; bm->headnode[hullnum] = headclipnode; } //============================================================================= typedef struct { char identification[4]; // should be wad2 int numlumps; int infotableofs; } wadinfo_t; typedef struct { int filepos; int disksize; int size; // uncompressed char type; char compression; char pad1, pad2; char name[16]; // must be null terminated } lumpinfo_t; file *texfile; wadinfo_t wadinfo; lumpinfo_t *lumpinfo; void cleanupname (char *in, char *out) { int i; for (i=0 ; i< 16 ; i++ ) { if (!in[i]) break; out[i] = toupper(in[i]); } for ( ; i< 16 ; i++ ) out[i] = 0; } /* ================= tex_initfromwad ================= */ void tex_initfromwad (char *path) { int i; texfile = safeopenread (path); saferead (texfile, &wadinfo, sizeof(wadinfo)); if (strncmp (wadinfo.identification, "wad2", 4)) error ("tex_initfromwad: %s isn't a wadfile",path); wadinfo.numlumps = littlelong(wadinfo.numlumps); wadinfo.infotableofs = littlelong(wadinfo.infotableofs); fseek (texfile, wadinfo.infotableofs, seek_set); lumpinfo = malloc(wadinfo.numlumps*sizeof(lumpinfo_t)); saferead (texfile, lumpinfo, wadinfo.numlumps*sizeof(lumpinfo_t)); for (i=0 ; idataofs[nummiptex]; l->nummiptex = nummiptex; for (i=0 ; idataofs[i] = data - (byte *)l; len = loadlump (miptex[i], data); if (data + len - dtexdata >= max_map_miptex) error ("textures exceeded max_map_miptex"); if (!len) l->dataofs[i] = -1; // didn't find the texture data += len; } texdatasize = data - dtexdata; } //=========================================================================== /* ================== beginbspfile ================== */ void beginbspfile (void) { // edge 0 is not used, because 0 can't be negated numedges = 1; // leaf 0 is common solid with no faces numleafs = 1; dleafs[0].contents = contents_solid; firstface = 0; } /* ================== finishbspfile ================== */ void finishbspfile (void) { printf ("--- finishbspfile ---\n"); printf ("writebspfile: %s\n", bspfilename); writemiptex (); printbspfilesizes (); writebspfile (bspfilename); }