#ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_STRING_H # include #endif #include #include "QF/qendian.h" #include "QF/sys.h" #include "QF/va.h" #include "tools/qfbsp/include/brush.h" #include "tools/qfbsp/include/bsp5.h" #include "tools/qfbsp/include/draw.h" #include "tools/qfbsp/include/options.h" typedef struct lumpinfo_s { const char *name; int data; int size; const char *(*extra) (const void *data); } lumpinfo_t; static const char * num_textures (const void *data) { __auto_type d = (const dmiptexlump_t *)data; return va (0, " %7d", LittleLong (d->nummiptex)); } #define O(f) field_offset (bsp_t, f) static lumpinfo_t lump_info[] = { { "entities", O(entdata), O(entdatasize) }, { "planes", O(planes), O(numplanes) }, { "textures", O(texdata), O(texdatasize), num_textures }, { "vertices", O(vertexes), O(numvertexes) }, { "visibility", O(visdata), O(visdatasize) }, { "nodes", O(nodes), O(numnodes) }, { "texinfo", O(texinfo), O(numtexinfo) }, { "faces", O(faces), O(numfaces) }, { "lighting", O(lightdata), O(lightdatasize) }, { "clipnodes", O(clipnodes), O(numclipnodes) }, { "leafs", O(leafs), O(numleafs) }, { "marksurfaces", O(marksurfaces), O(nummarksurfaces) }, { "edges", O(edges), O(numedges) }, { "surfedges", O(surfedges), O(numsurfedges) }, { "models", O(models), O(nummodels) }, }; typedef struct { int count; int depth; uint32_t node_faces; uint32_t leaf_faces; } nodedata_t; static void get_nodedata (int node, nodedata_t *data, int depth) { if (node < 0) { // hit a leaf, no surfaces if (depth > data->depth) { data->depth = depth; } dleaf_t *leaf = bsp->leafs + ~node; if (leaf->nummarksurfaces > data->leaf_faces) { data->leaf_faces = leaf->nummarksurfaces; } return; } data->count++; dnode_t *dnode = &bsp->nodes[node]; if (dnode->numfaces > data->node_faces) { data->node_faces = dnode->numfaces; } get_nodedata (dnode->children[0], data, depth + 1); get_nodedata (dnode->children[1], data, depth + 1); } static void get_clipdata (int node, nodedata_t *data, int depth) { if (node < 0 || (uint32_t) node >= bsp->numclipnodes) { // hit contents if (depth > data->depth) { data->depth = depth; } return; } data->count++; dclipnode_t *cnode = &bsp->clipnodes[node]; get_clipdata (cnode->children[0], data, depth + 1); get_clipdata (cnode->children[1], data, depth + 1); } void bspinfo () { printf ("version: %x\n", bsp->header->version); for (int i = 0; i < HEADER_LUMPS; i++) { lump_t *lump = &bsp->header->lumps[i]; lumpinfo_t *info = &lump_info[i]; const void *data = *(void **)((byte *) bsp + info->data); size_t *size = (size_t *)((byte *) bsp + info->size); const char *extra = ""; if (info->extra) { extra = info->extra (data); } printf (" %-12s: %7d %7d %7zd%s\n", info->name, lump->fileofs, lump->filelen, *size, extra); } for (unsigned i = 0; i < bsp->nummodels; i++) { dmodel_t *model = &bsp->models[i]; printf ("model: *%d\n", i); printf (" mins : [%g, %g, %g]\n", VectorExpand (model->mins)); printf (" maxs : [%g, %g, %g]\n", VectorExpand (model->maxs)); printf (" origin : [%g, %g, %g]\n", VectorExpand (model->origin)); printf (" headnode:"); nodedata_t nodedata[MAX_MAP_HULLS] = {}; for (int j = 0; j < MAX_MAP_HULLS; j++) { int k; for (k = 1; k < j; k++) { if (model->headnode[j] == model->headnode[k]) { nodedata[j] = nodedata[k]; break; } } if (k >= j) { if (j) { get_clipdata (model->headnode[j], &nodedata[j], 0); } else { get_nodedata (model->headnode[j], &nodedata[j], 0); } } printf (" %5d", model->headnode[j]); } printf ("\n nodes:"); for (int j = 0; j < MAX_MAP_HULLS; j++) { if (model->headnode[j] < model->headnode[0]) { continue; } printf (" %5d", nodedata[j].count); } printf ("\n depth:"); for (int j = 0; j < MAX_MAP_HULLS; j++) { if (model->headnode[j] < model->headnode[0]) { continue; } printf (" %5d", nodedata[j].depth); } printf ("\n"); printf (" max faces: n: %d l:%d\n", nodedata[0].node_faces, nodedata[0].leaf_faces); printf (" visleafs: %d\n", model->visleafs); printf (" faces : %7d %7d\n", model->firstface, model->numfaces); } }