From 6a50313ded9b4ed38bec72411f708671ecc1123c Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Thu, 26 Aug 2021 19:26:57 -0600 Subject: [PATCH 1/5] qbsp: add AddLumpFromBuffer function --- qbsp/bspfile.cc | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/qbsp/bspfile.cc b/qbsp/bspfile.cc index 23a7d3bb..1db87d4e 100644 --- a/qbsp/bspfile.cc +++ b/qbsp/bspfile.cc @@ -191,6 +191,33 @@ AddLump(FILE *f, int Type) } } +// TODO: remove this once we switch to common +static void +AddLumpFromBuffer(FILE *f, int Type, void* src, size_t srcbytes) +{ + lump_t *lump; + size_t ret; + + lump = &header->lumps[Type]; + lump->fileofs = ftell(f); + + if (srcbytes) { + ret = fwrite(src, 1, srcbytes, f); + if (ret != srcbytes) + Error("Failure writing to file"); + } + + lump->filelen = srcbytes; + + // Pad to 4-byte boundary + if (srcbytes % 4 != 0) { + size_t pad = 4 - (srcbytes % 4); + ret = fwrite(" ", 1, pad, f); + if (ret != pad) + Error("Failure writing to file"); + } +} + static void GenLump(const char *bspxlump, int Type, size_t sz) { From 8a1bc3ef20f92173de5e63cf980a0b335f8ac46c Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Thu, 26 Aug 2021 19:55:39 -0600 Subject: [PATCH 2/5] qbsp: refactor clipnode writing (changes .bsp output) - drop reshuffling feature from ExportClipNodes As far as I can tell, the only purpose of this was to keep clipnodes for a given model contiguous within the lump (i.e. keep the different hulls contiguous). Vanilla qbsp didn't appear to have done this, and the code was unmaintainable/complex, so I'm dropping the feature. --- include/qbsp/map.hh | 3 ++ qbsp/bspfile.cc | 14 +++++- qbsp/writebsp.cc | 109 ++++++++++---------------------------------- 3 files changed, 40 insertions(+), 86 deletions(-) diff --git a/include/qbsp/map.hh b/include/qbsp/map.hh index 1f17ebd3..3dec381d 100644 --- a/include/qbsp/map.hh +++ b/include/qbsp/map.hh @@ -153,6 +153,9 @@ typedef struct mapdata_s { /* Misc other global state for the compile process */ bool leakfile; /* Flag once we've written a leak (.por/.pts) file */ + std::vector exported_clipnodes_bsp29; + std::vector exported_clipnodes_bsp2; + // helpers std::string texinfoTextureName(int texinfo) const { int mt = mtexinfos.at(texinfo).miptex; diff --git a/qbsp/bspfile.cc b/qbsp/bspfile.cc index 1db87d4e..1099e1f3 100644 --- a/qbsp/bspfile.cc +++ b/qbsp/bspfile.cc @@ -298,7 +298,13 @@ WriteBSPFile(void) AddLump(f, LUMP_NODES); AddLump(f, LUMP_TEXINFO); AddLump(f, LUMP_FACES); - AddLump(f, LUMP_CLIPNODES); + if (!map.exported_clipnodes_bsp2.empty()) { + AddLumpFromBuffer(f, LUMP_CLIPNODES, map.exported_clipnodes_bsp2.data(), map.exported_clipnodes_bsp2.size() * sizeof(map.exported_clipnodes_bsp2[0])); + Q_assert(map.exported_clipnodes_bsp29.empty()); + } else { + AddLumpFromBuffer(f, LUMP_CLIPNODES, map.exported_clipnodes_bsp29.data(), map.exported_clipnodes_bsp29.size() * sizeof(map.exported_clipnodes_bsp29[0])); + Q_assert(map.exported_clipnodes_bsp2.empty()); + } AddLump(f, LUMP_MARKSURFACES); AddLump(f, LUMP_SURFEDGES); AddLump(f, LUMP_EDGES); @@ -385,7 +391,11 @@ PrintBSPFileSizes(void) Message(msgStat, "%8d nodes %10d", map.cTotal[LUMP_NODES], map.cTotal[LUMP_NODES] * MemSize[BSP_NODE]); Message(msgStat, "%8d texinfo %10d", map.cTotal[LUMP_TEXINFO], map.cTotal[LUMP_TEXINFO] * MemSize[BSP_TEXINFO]); Message(msgStat, "%8d faces %10d", map.cTotal[LUMP_FACES], map.cTotal[LUMP_FACES] * MemSize[BSP_FACE]); - Message(msgStat, "%8d clipnodes %10d", map.cTotal[LUMP_CLIPNODES], map.cTotal[LUMP_CLIPNODES] * MemSize[BSP_CLIPNODE]); + if (!map.exported_clipnodes_bsp2.empty()) { + Message(msgStat, "%8d clipnodes %10d", static_cast(map.exported_clipnodes_bsp2.size()), static_cast(map.exported_clipnodes_bsp2.size()) * MemSize[BSP_CLIPNODE]); + } else { + Message(msgStat, "%8d clipnodes %10d", static_cast(map.exported_clipnodes_bsp29.size()), static_cast(map.exported_clipnodes_bsp29.size()) * MemSize[BSP_CLIPNODE]); + } Message(msgStat, "%8d leafs %10d", map.cTotal[LUMP_LEAFS], map.cTotal[LUMP_LEAFS] * MemSize[BSP_LEAF]); Message(msgStat, "%8d marksurfaces %10d", map.cTotal[LUMP_MARKSURFACES], map.cTotal[LUMP_MARKSURFACES] * MemSize[BSP_MARKSURF]); Message(msgStat, "%8d surfedges %10d", map.cTotal[LUMP_SURFEDGES], map.cTotal[LUMP_SURFEDGES] * MemSize[BSP_SURFEDGE]); diff --git a/qbsp/writebsp.cc b/qbsp/writebsp.cc index 2ec664e3..5e3e15b8 100644 --- a/qbsp/writebsp.cc +++ b/qbsp/writebsp.cc @@ -175,24 +175,6 @@ AllocBSPTexinfo() //=========================================================================== - -/* -================== -CountClipNodes_r -================== -*/ -static void -CountClipNodes_r(mapentity_t *entity, node_t *node) -{ - if (node->planenum == -1) - return; - - entity->lumps[LUMP_CLIPNODES].count++; - - CountClipNodes_r(entity, node->children[0]); - CountClipNodes_r(entity, node->children[1]); -} - /* ================== ExportClipNodes @@ -201,10 +183,8 @@ ExportClipNodes static int ExportClipNodes_BSP29(mapentity_t *entity, node_t *node) { - int nodenum; bsp29_dclipnode_t *clipnode; face_t *face, *next; - struct lumpdata *clipnodes = &entity->lumps[LUMP_CLIPNODES]; // FIXME: free more stuff? if (node->planenum == -1) { @@ -214,14 +194,17 @@ ExportClipNodes_BSP29(mapentity_t *entity, node_t *node) } /* emit a clipnode */ - clipnode = (bsp29_dclipnode_t *)clipnodes->data + clipnodes->index; - clipnodes->index++; - nodenum = map.cTotal[LUMP_CLIPNODES]; - map.cTotal[LUMP_CLIPNODES]++; + const int nodenum = static_cast(map.exported_clipnodes_bsp29.size()); + map.exported_clipnodes_bsp29.push_back({}); + const int child0 = ExportClipNodes_BSP29(entity, node->children[0]); + const int child1 = ExportClipNodes_BSP29(entity, node->children[1]); + + // Careful not to modify the vector while using this clipnode pointer + clipnode = &map.exported_clipnodes_bsp29.at(nodenum); clipnode->planenum = ExportMapPlane(node->planenum); - clipnode->children[0] = ExportClipNodes_BSP29(entity, node->children[0]); - clipnode->children[1] = ExportClipNodes_BSP29(entity, node->children[1]); + clipnode->children[0] = child0; + clipnode->children[1] = child1; for (face = node->faces; face; face = next) { next = face->next; @@ -236,10 +219,8 @@ ExportClipNodes_BSP29(mapentity_t *entity, node_t *node) static int ExportClipNodes_BSP2(mapentity_t *entity, node_t *node) { - int nodenum; bsp2_dclipnode_t *clipnode; face_t *face, *next; - struct lumpdata *clipnodes = &entity->lumps[LUMP_CLIPNODES]; // FIXME: free more stuff? if (node->planenum == -1) { @@ -249,14 +230,17 @@ ExportClipNodes_BSP2(mapentity_t *entity, node_t *node) } /* emit a clipnode */ - clipnode = (bsp2_dclipnode_t *)clipnodes->data + clipnodes->index; - clipnodes->index++; - nodenum = map.cTotal[LUMP_CLIPNODES]; - map.cTotal[LUMP_CLIPNODES]++; + const int nodenum = static_cast(map.exported_clipnodes_bsp2.size()); + map.exported_clipnodes_bsp2.push_back({}); + const int child0 = ExportClipNodes_BSP2(entity, node->children[0]); + const int child1 = ExportClipNodes_BSP2(entity, node->children[1]); + + // Careful not to modify the vector while using this clipnode pointer + clipnode = &map.exported_clipnodes_bsp2.at(nodenum); clipnode->planenum = ExportMapPlane(node->planenum); - clipnode->children[0] = ExportClipNodes_BSP2(entity, node->children[0]); - clipnode->children[1] = ExportClipNodes_BSP2(entity, node->children[1]); + clipnode->children[0] = child0; + clipnode->children[1] = child1; for (face = node->faces; face; face = next) { next = face->next; @@ -283,61 +267,18 @@ accomodate new data interleaved with old. void ExportClipNodes(mapentity_t *entity, node_t *nodes, const int hullnum) { - int oldcount, i, diff; - int clipcount = 0; - void *olddata; - struct lumpdata *clipnodes = &entity->lumps[LUMP_CLIPNODES]; dmodel_t *model = (dmodel_t *)entity->lumps[LUMP_MODELS].data; - oldcount = clipnodes->count; + if (options.BSPVersion == BSPVERSION || options.BSPVersion == BSPHLVERSION) { + model->headnode[hullnum] = ExportClipNodes_BSP29(entity, nodes); - /* Count nodes before this one */ - const int entnum = entity - &map.entities.at(0); - for (i = 0; i < entnum; i++) - clipcount += map.entities.at(i).lumps[LUMP_CLIPNODES].count; - model->headnode[hullnum] = clipcount + oldcount; - - CountClipNodes_r(entity, nodes); - if (clipnodes->count > MAX_BSP_CLIPNODES && (options.BSPVersion == BSPVERSION || options.BSPVersion == BSPHLVERSION)) - Error("Clipnode count exceeds bsp 29 max (%d > %d)", - clipnodes->count, MAX_BSP_CLIPNODES); - - olddata = clipnodes->data; - clipnodes->data = AllocMem(BSP_CLIPNODE, clipnodes->count, true); - if (olddata) { - memcpy(clipnodes->data, olddata, oldcount * MemSize[BSP_CLIPNODE]); - FreeMem(olddata, BSP_CLIPNODE, oldcount); - - /* Worth special-casing for entity 0 (no modification needed) */ - diff = clipcount - model->headnode[1]; - if (diff != 0) { - for (i = 1; i < hullnum; i++) - model->headnode[i] += diff; - if (options.BSPVersion == BSPVERSION || options.BSPVersion == BSPHLVERSION) { - bsp29_dclipnode_t *clipnode = (bsp29_dclipnode_t *)clipnodes->data; - for (i = 0; i < oldcount; i++, clipnode++) { - if (clipnode->children[0] < MAX_BSP_CLIPNODES) - clipnode->children[0] += diff; - if (clipnode->children[1] < MAX_BSP_CLIPNODES) - clipnode->children[1] += diff; - } - } else { - bsp2_dclipnode_t *clipnode = (bsp2_dclipnode_t *)clipnodes->data; - for (i = 0; i < oldcount; i++, clipnode++) { - if (clipnode->children[0] >= 0) - clipnode->children[0] += diff; - if (clipnode->children[1] >= 0) - clipnode->children[1] += diff; - } - } + const int clipnodecount = static_cast(map.exported_clipnodes_bsp29.size()); + if (clipnodecount > MAX_BSP_CLIPNODES) { + Error("Clipnode count exceeds bsp 29 max (%d > %d)", clipnodecount, MAX_BSP_CLIPNODES); } + } else { + model->headnode[hullnum] = ExportClipNodes_BSP2(entity, nodes); } - - map.cTotal[LUMP_CLIPNODES] = clipcount + oldcount; - if (options.BSPVersion == BSPVERSION || options.BSPVersion == BSPHLVERSION) - ExportClipNodes_BSP29(entity, nodes); - else - ExportClipNodes_BSP2(entity, nodes); } //=========================================================================== From f0d1c8488bac9c7f441c33083ab01d51e5b11418 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Thu, 26 Aug 2021 20:03:47 -0600 Subject: [PATCH 3/5] qbsp: pad lumps with \0 rather than ' ', for consistency with common/bspfile --- qbsp/bspfile.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qbsp/bspfile.cc b/qbsp/bspfile.cc index 1099e1f3..ba69dfd6 100644 --- a/qbsp/bspfile.cc +++ b/qbsp/bspfile.cc @@ -185,7 +185,8 @@ AddLump(FILE *f, int Type) // Pad to 4-byte boundary if (cLen % 4 != 0) { size_t pad = 4 - (cLen % 4); - ret = fwrite(" ", 1, pad, f); + const char zeroBytes[] = {0, 0, 0, 0}; + ret = fwrite(zeroBytes, 1, pad, f); if (ret != pad) Error("Failure writing to file"); } @@ -212,7 +213,8 @@ AddLumpFromBuffer(FILE *f, int Type, void* src, size_t srcbytes) // Pad to 4-byte boundary if (srcbytes % 4 != 0) { size_t pad = 4 - (srcbytes % 4); - ret = fwrite(" ", 1, pad, f); + const char zeroBytes[] = {0, 0, 0, 0}; + ret = fwrite(zeroBytes, 1, pad, f); if (ret != pad) Error("Failure writing to file"); } From 9688af5be3c97b9233fbbca1d48e45e69342c9f7 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Thu, 26 Aug 2021 20:13:26 -0600 Subject: [PATCH 4/5] build: msvc: silence 64->32 bit conversion warning until the codebase is cleaned up --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index dd0b95f1..dea9ba1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,6 +124,10 @@ if (MSVC) add_definitions("/wd4244") # disable "conversion from .. to .., possible loss of data" warning add_definitions("/wd4018") # disable "signed/unsigned mismatch" warning add_definitions("/wd4200") # disable "nonstandard extension used: zero-sized array in struct/union" warning + add_definitions("/wd4264") # disable "conversion from 'size_t' to 'int', possible loss of data" warning + add_definitions("/wd4267") # disable "conversion from 'size_t' to 'int', possible loss of data" warning + add_definitions("/wd4305") # disable "truncation from 'double' to 'float'" warning + endif (MSVC) # 10.9: minimum version that supports unordered_map From 8beda9a03918dcd217818f428a9175c3e6bfbd03 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Thu, 26 Aug 2021 20:22:09 -0600 Subject: [PATCH 5/5] common, qbsp: make Error() noreturn --- common/cmdlib.cc | 2 +- common/threads.cc | 2 +- include/common/cmdlib.hh | 2 +- include/qbsp/util.hh | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common/cmdlib.cc b/common/cmdlib.cc index 65c8c6c2..7dc1b61a 100644 --- a/common/cmdlib.cc +++ b/common/cmdlib.cc @@ -57,7 +57,7 @@ char archivedir[1024]; * For abnormal program terminations * ================= */ -void +[[noreturn]] void Error(const char *error, ...) { va_list argptr; diff --git a/common/threads.cc b/common/threads.cc index 3584e439..b6b384a0 100644 --- a/common/threads.cc +++ b/common/threads.cc @@ -12,7 +12,7 @@ * thread/logging code. Error() would normally be defined in * either common/cmdlib.h or qbsp/qbsp.h. */ -void Error(const char *error, ...) +[[noreturn]] void Error(const char *error, ...) __attribute__((format(printf,1,2),noreturn)); /* Make the locks no-ops if we aren't running threads */ diff --git a/include/common/cmdlib.hh b/include/common/cmdlib.hh index 690128e9..b2f203ec 100644 --- a/include/common/cmdlib.hh +++ b/include/common/cmdlib.hh @@ -81,7 +81,7 @@ char *ExpandPathAndArchive(char *path); double I_FloatTime(void); -void Error(const char *error, ...) +[[noreturn]] void Error(const char *error, ...) __attribute__((format(printf,1,2),noreturn)); int CheckParm(const char *check); diff --git a/include/qbsp/util.hh b/include/qbsp/util.hh index 61a96734..50ce6a79 100644 --- a/include/qbsp/util.hh +++ b/include/qbsp/util.hh @@ -42,7 +42,7 @@ void FreeAllMem(void); void PrintMem(void); void Message(int MsgType, ...); -void Error(const char *error, ...) +[[noreturn]] void Error(const char *error, ...) __attribute__((format(printf,1,2),noreturn)); int q_snprintf(char *str, size_t size, const char *format, ...);