From 1e6e938ead52e25cade4ce098ba6e17e4e8bc765 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Sat, 4 Sep 2021 10:47:43 -0600 Subject: [PATCH 1/9] qbsp: restore writing LMSHIFT bspx lump --- qbsp/writebsp.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qbsp/writebsp.cc b/qbsp/writebsp.cc index 2eff1a6f..5f5b65cb 100644 --- a/qbsp/writebsp.cc +++ b/qbsp/writebsp.cc @@ -438,9 +438,9 @@ WriteBSPFile() CopyString(map.exported_entities, true, &bspdata.data.mbsp.entdatasize, (void**)&bspdata.data.mbsp.dentdata); CopyString(map.exported_texdata, false, &bspdata.data.mbsp.texdatasize, (void**)&bspdata.data.mbsp.dtexdata); - // TODO: pass bspx lumps to generic bsp code so they are written - - //GenLump("LMSHIFT", BSPX_LMSHIFT, 1); + if (map.needslmshifts) { + BSPX_AddLump(&bspdata, "LMSHIFT", map.exported_lmshifts.data(), map.exported_lmshifts.size()); + } ConvertBSPFormat(&bspdata, options.target_version); From 54799a11fc11880e636d0c709312928c5f77f968 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Sat, 4 Sep 2021 11:47:33 -0600 Subject: [PATCH 2/9] qbsp: restore bspx brushes writing --- include/qbsp/map.hh | 8 +++----- qbsp/qbsp.cc | 31 +++++++++++++++---------------- qbsp/writebsp.cc | 3 +++ 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/include/qbsp/map.hh b/include/qbsp/map.hh index 3e87b930..36d24d1e 100644 --- a/include/qbsp/map.hh +++ b/include/qbsp/map.hh @@ -173,6 +173,7 @@ typedef struct mapdata_s { // bspx data std::vector exported_lmshifts; bool needslmshifts = false; + std::vector exported_bspxbrushes; // helpers std::string texinfoTextureName(int texinfo) const { @@ -222,11 +223,8 @@ int MakeFaceEdges(mapentity_t *entity, node_t *headnode); void ExportClipNodes(mapentity_t *entity, node_t *headnode, const int hullnum); void ExportDrawNodes(mapentity_t *entity, node_t *headnode, int firstface); -struct bspxbrushes_s -{ - uint8_t *lumpinfo; - size_t lumpsize; - size_t lumpmaxsize; +struct bspxbrushes_s { + std::vector lumpdata; }; void BSPX_Brushes_Finalize(struct bspxbrushes_s *ctx); void BSPX_Brushes_Init(struct bspxbrushes_s *ctx); diff --git a/qbsp/qbsp.cc b/qbsp/qbsp.cc index 1ac89c8a..812db5d6 100644 --- a/qbsp/qbsp.cc +++ b/qbsp/qbsp.cc @@ -316,14 +316,21 @@ This lump replaces the clipnodes stuff for custom collision sizes. */ void BSPX_Brushes_Finalize(struct bspxbrushes_s *ctx) { - //BSPX_AddLump("BRUSHLIST", ctx->lumpinfo, ctx->lumpsize); // FIXME: fix bspx - -// free(ctx->lumpinfo); + // Actually written in WriteBSPFile() + map.exported_bspxbrushes = std::move(ctx->lumpdata); } void BSPX_Brushes_Init(struct bspxbrushes_s *ctx) { - memset(ctx, 0, sizeof(*ctx)); + ctx->lumpdata.clear(); } + +static void +vec_push_bytes(std::vector& vec, const void* data, size_t count) { + const uint8_t* bytes = static_cast(data); + + vec.insert(vec.end(), bytes, bytes + count); +} + /* WriteBrushes Generates a submodel's direct brush information to a separate file, so the engine doesn't need to depend upon specific hull sizes @@ -372,18 +379,11 @@ void BSPX_Brushes_AddModel(struct bspxbrushes_s *ctx, int modelnum, brush_t *bru } } - if (ctx->lumpmaxsize < ctx->lumpsize + sizeof(permodel) + permodel.numbrushes*sizeof(perbrush) + permodel.numfaces*sizeof(perface)) - { - ctx->lumpmaxsize = (ctx->lumpsize + sizeof(permodel) + permodel.numbrushes*sizeof(perbrush) + permodel.numfaces*sizeof(perface))*2; - ctx->lumpinfo = (uint8_t *) realloc(ctx->lumpinfo, ctx->lumpmaxsize); - } - permodel.ver = LittleLong(1); permodel.modelnum = LittleLong(modelnum); permodel.numbrushes = LittleLong(permodel.numbrushes); permodel.numfaces = LittleLong(permodel.numfaces); - memcpy(ctx->lumpinfo+ctx->lumpsize, &permodel, sizeof(permodel)); - ctx->lumpsize += sizeof(permodel); + vec_push_bytes(ctx->lumpdata, &permodel, sizeof(permodel)); for (b = brushes; b; b = b->next) { @@ -428,8 +428,7 @@ void BSPX_Brushes_AddModel(struct bspxbrushes_s *ctx, int modelnum, brush_t *bru } perbrush.contents = LittleShort(perbrush.contents); perbrush.numfaces = LittleShort(perbrush.numfaces); - memcpy(ctx->lumpinfo+ctx->lumpsize, &perbrush, sizeof(perbrush)); - ctx->lumpsize += sizeof(perbrush); + vec_push_bytes(ctx->lumpdata, &perbrush, sizeof(perbrush)); for (f = b->faces; f; f = f->next) { @@ -454,11 +453,11 @@ void BSPX_Brushes_AddModel(struct bspxbrushes_s *ctx, int modelnum, brush_t *bru perface.dist = map.planes[f->planenum].dist; } - memcpy(ctx->lumpinfo+ctx->lumpsize, &perface, sizeof(perface)); - ctx->lumpsize += sizeof(perface); + vec_push_bytes(ctx->lumpdata, &perface, sizeof(perface)); } } } + /* for generating BRUSHLIST bspx lump */ static void BSPX_CreateBrushList(void) { diff --git a/qbsp/writebsp.cc b/qbsp/writebsp.cc index 5f5b65cb..e24ede16 100644 --- a/qbsp/writebsp.cc +++ b/qbsp/writebsp.cc @@ -441,6 +441,9 @@ WriteBSPFile() if (map.needslmshifts) { BSPX_AddLump(&bspdata, "LMSHIFT", map.exported_lmshifts.data(), map.exported_lmshifts.size()); } + if (!map.exported_bspxbrushes.empty()) { + BSPX_AddLump(&bspdata, "BRUSHLIST", map.exported_bspxbrushes.data(), map.exported_bspxbrushes.size()); + } ConvertBSPFormat(&bspdata, options.target_version); From f978d2a8d5bb469560714cccff483c28b6146ad9 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Sun, 5 Sep 2021 00:44:25 -0600 Subject: [PATCH 3/9] common: start adding overflow checks to ConvertBSPFormat --- common/bspfile.cc | 90 +++++++++++++++++++++++++++++++-------- include/common/bspfile.hh | 5 ++- 2 files changed, 76 insertions(+), 19 deletions(-) diff --git a/common/bspfile.cc b/common/bspfile.cc index 3b5efa8f..d1bca906 100644 --- a/common/bspfile.cc +++ b/common/bspfile.cc @@ -21,6 +21,8 @@ #include #include +#include + /* hexen2, quake2 */ const bspversion_t bspver_generic { NO_VERSION, NO_VERSION, "mbsp", "generic BSP", false, false }; const bspversion_t bspver_q1 { BSPVERSION, NO_VERSION, "bsp29", "Quake BSP", false, false }; @@ -954,6 +956,49 @@ BSP29toM_Leafs(const bsp29_dleaf_t *dleafs29, int numleafs) { return newdata; } +static bool +OverflowsInt16(float input) { + constexpr float minvalue = static_cast(INT16_MIN); + constexpr float maxvalue = static_cast(INT16_MAX); + + if (input < minvalue) { + return true; + } + if (input > maxvalue) { + return true; + } + return false; +} + +static bool +OverflowsUint16(uint32_t input) { + if (input > INT16_MAX) { + return true; + } + return false; +} + +static bool +MBSPto29_Leafs_Validate(const mleaf_t *mleafs, int numleafs) { + const mleaf_t *mleaf = mleafs; + + for (int i = 0; i < numleafs; i++, mleaf++) { + for (int j = 0; j < 3; j++) { + const float min_j = floor(mleaf->mins[j]); + const float max_j = ceil(mleaf->maxs[j]); + + if (OverflowsInt16(min_j) || OverflowsInt16(max_j)) { + return false; + } + } + if (OverflowsUint16(mleaf->firstmarksurface) + || OverflowsUint16(mleaf->nummarksurfaces)) { + return false; + } + } + return true; +} + static bsp29_dleaf_t * MBSPto29_Leafs(const mleaf_t *mleafs, int numleafs) { const mleaf_t *mleaf = mleafs; @@ -966,8 +1011,8 @@ MBSPto29_Leafs(const mleaf_t *mleafs, int numleafs) { dleaf29->contents = mleaf->contents; dleaf29->visofs = mleaf->visofs; for (j = 0; j < 3; j++) { - dleaf29->mins[j] = mleaf->mins[j]; - dleaf29->maxs[j] = mleaf->maxs[j]; + dleaf29->mins[j] = floor(mleaf->mins[j]); + dleaf29->maxs[j] = ceil(mleaf->maxs[j]); } dleaf29->firstmarksurface = mleaf->firstmarksurface; dleaf29->nummarksurfaces = mleaf->nummarksurfaces; @@ -2187,14 +2232,16 @@ ConvertBSPToMFormatComplete(const bspversion_t **mbsp_loadversion, const bspvers * - No checks are done here (yet) for overflow of values when down-converting * ========================================================================= */ -void +bool ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) { if (bspdata->version == to_version) - return; + return true; - // conversions to bspver_generic if (to_version == &bspver_generic) { + // Conversions to bspver_generic + // NOTE: these always succeed + if (bspdata->version == &bspver_q1 || bspdata->version == &bspver_h2 || bspdata->version == &bspver_hl) { // bspver_q1, bspver_h2, bspver_hl -> bspver_generic @@ -2247,7 +2294,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) /* Conversion complete! */ ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata); - return; + return true; } else if (bspdata->version == &bspver_q2) { // bspver_q2 -> bspver_generic @@ -2305,7 +2352,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) /* Conversion complete! */ ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata); - return; + return true; } else if (bspdata->version == &bspver_qbism) { // bspver_qbism -> bspver_generic @@ -2363,7 +2410,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) /* Conversion complete! */ ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata); - return; + return true; } else if (bspdata->version == &bspver_bsp2rmq || bspdata->version == &bspver_h2bsp2rmq) { // bspver_bsp2rmq, bspver_h2bsp2rmq -> bspver_generic @@ -2416,7 +2463,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) /* Conversion complete! */ ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata); - return; + return true; } else if (bspdata->version == &bspver_bsp2 || bspdata->version == &bspver_h2bsp2) { // bspver_bsp2, bspver_h2bsp2 -> bspver_generic @@ -2469,17 +2516,24 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) /* Conversion complete! */ ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata); - return; + return true; } - } - // conversions from GENERIC_BSP + } else if (bspdata->version == &bspver_generic) { + // Conversions from bspver_generic + if (to_version == &bspver_q1 || to_version == &bspver_h2 || to_version == &bspver_hl) { // bspver_generic -> bspver_q1, bspver_h2, bspver_hl bsp29_t *bsp29 = &bspdata->data.bsp29; const mbsp_t *mbsp = &bspdata->data.mbsp; + // validate that the conversion is possible + if (!MBSPto29_Leafs_Validate(mbsp->dleafs, mbsp->numleafs)) { + return false; + } + + // zero destination struct memset(bsp29, 0, sizeof(*bsp29)); // copy counts @@ -2526,7 +2580,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) /* Conversion complete! */ bspdata->version = to_version; - return; + return true; } else if (to_version == &bspver_q2) { // bspver_generic -> bspver_q2 @@ -2583,7 +2637,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) /* Conversion complete! */ bspdata->version = to_version; - return; + return true; } else if (to_version == &bspver_qbism) { // bspver_generic -> bspver_qbism @@ -2640,13 +2694,13 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) /* Conversion complete! */ bspdata->version = to_version; - return; + return true; } else if (to_version == &bspver_bsp2rmq || to_version == &bspver_h2bsp2rmq) { // bspver_generic -> bspver_bsp2rmq, bspver_h2bsp2rmq bsp2rmq_t *bsp2rmq = &bspdata->data.bsp2rmq; const mbsp_t *mbsp = &bspdata->data.mbsp; - + memset(bsp2rmq, 0, sizeof(*bsp2rmq)); // copy counts @@ -2693,7 +2747,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) /* Conversion complete! */ bspdata->version = to_version; - return; + return true; } else if (to_version == &bspver_bsp2 || to_version == &bspver_h2bsp2) { // bspver_generic -> bspver_bsp2, bspver_h2bsp2 @@ -2746,7 +2800,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) /* Conversion complete! */ bspdata->version = to_version; - return; + return true; } } diff --git a/include/common/bspfile.hh b/include/common/bspfile.hh index 3fd3fed5..8f8f106b 100644 --- a/include/common/bspfile.hh +++ b/include/common/bspfile.hh @@ -985,7 +985,10 @@ typedef struct { void LoadBSPFile(char *filename, bspdata_t *bspdata); //returns the filename as contained inside a bsp void WriteBSPFile(const char *filename, bspdata_t *bspdata); void PrintBSPFileSizes(const bspdata_t *bspdata); -void ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version); +/** + * Returns false if the conversion failed. + */ +bool ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version); void BSPX_AddLump(bspdata_t *bspdata, const char *xname, const void *xdata, size_t xsize); const void *BSPX_GetLump(bspdata_t *bspdata, const char *xname, size_t *xsize); From a0ccb765e8f62fc4899c3486aefc9789dfe08a67 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Sun, 5 Sep 2021 01:04:39 -0600 Subject: [PATCH 4/9] common: validate bsp29 nodes and faces --- common/bspfile.cc | 68 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/common/bspfile.cc b/common/bspfile.cc index d1bca906..ec6ba16c 100644 --- a/common/bspfile.cc +++ b/common/bspfile.cc @@ -970,6 +970,17 @@ OverflowsInt16(float input) { return false; } +static bool +OverflowsInt16(int32_t input) { + if (input < INT16_MIN) { + return true; + } + if (input > INT16_MAX) { + return true; + } + return false; +} + static bool OverflowsUint16(uint32_t input) { if (input > INT16_MAX) { @@ -1685,6 +1696,31 @@ BSP29to2_Nodes(const bsp29_dnode_t *dnodes29, int numnodes) { return newdata; } +static bool +BSP2to29_Nodes_Validate(const bsp2_dnode_t *dnodes2, int numnodes) { + const bsp2_dnode_t *dnode2 = dnodes2; + + for (int i = 0; i < numnodes; i++, dnode2++) { + if (OverflowsInt16(dnode2->children[0]) || OverflowsInt16(dnode2->children[1])) { + return false; + } + for (int j = 0; j < 3; j++) { + const float min_j = floor(dnode2->mins[j]); + const float max_j = ceil(dnode2->maxs[j]); + + if (OverflowsInt16(min_j) || OverflowsInt16(max_j)) { + return false; + } + } + if (OverflowsUint16(dnode2->firstface) + || OverflowsUint16(dnode2->numfaces)) { + return false; + } + } + + return true; +} + static bsp29_dnode_t * BSP2to29_Nodes(const bsp2_dnode_t *dnodes2, int numnodes) { const bsp2_dnode_t *dnode2 = dnodes2; @@ -1698,8 +1734,8 @@ BSP2to29_Nodes(const bsp2_dnode_t *dnodes2, int numnodes) { dnode29->children[0] = dnode2->children[0]; dnode29->children[1] = dnode2->children[1]; for (j = 0; j < 3; j++) { - dnode29->mins[j] = dnode2->mins[j]; - dnode29->maxs[j] = dnode2->maxs[j]; + dnode29->mins[j] = floor(dnode2->mins[j]); + dnode29->maxs[j] = ceil(dnode2->maxs[j]); } dnode29->firstface = dnode2->firstface; dnode29->numfaces = dnode2->numfaces; @@ -1730,6 +1766,28 @@ BSP29to2_Faces(const bsp29_dface_t *dfaces29, int numfaces) { return newdata; } +static bool +BSP2to29_Faces_Validate(const bsp2_dface_t *dfaces2, int numfaces) { + const bsp2_dface_t *dface2 = dfaces2; + + for (int i = 0; i < numfaces; i++, dface2++) { + if (OverflowsInt16(dface2->planenum)) { + return false; + } + if (OverflowsInt16(dface2->side)) { + return false; + } + if (OverflowsInt16(dface2->numedges)) { + return false; + } + if (OverflowsInt16(dface2->texinfo)) { + return false; + } + } + + return true; +} + static bsp29_dface_t * BSP2to29_Faces(const bsp2_dface_t *dfaces2, int numfaces) { const bsp2_dface_t *dface2 = dfaces2; @@ -2532,6 +2590,12 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) if (!MBSPto29_Leafs_Validate(mbsp->dleafs, mbsp->numleafs)) { return false; } + if (!BSP2to29_Nodes_Validate(mbsp->dnodes, mbsp->numnodes)) { + return false; + } + if (!BSP2to29_Faces_Validate(mbsp->dfaces, mbsp->numfaces)) { + return false; + } // zero destination struct memset(bsp29, 0, sizeof(*bsp29)); From 948932f333cd26b686d084d3cb9d4979a0a0783b Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Sun, 5 Sep 2021 01:10:23 -0600 Subject: [PATCH 5/9] common: bsp29: validate clipnodes --- common/bspfile.cc | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/common/bspfile.cc b/common/bspfile.cc index ec6ba16c..342458bb 100644 --- a/common/bspfile.cc +++ b/common/bspfile.cc @@ -1830,6 +1830,24 @@ BSP29to2_Clipnodes(const bsp29_dclipnode_t *dclipnodes29, int numclipnodes) { return newdata; } +static bool +BSP2to29_Clipnodes_Validate(const bsp2_dclipnode_t *dclipnodes2, int numclipnodes) { + const bsp2_dclipnode_t *dclipnode2 = dclipnodes2; + + for (int i = 0; i < numclipnodes; i++, dclipnode2++) { + for (int j = 0; j < 2; j++) { + /* Slightly tricky since we support > 32k clipnodes */ + int32_t child = dclipnode2->children[j]; + int32_t child_bsp29 = child < 0 ? child + 0x10000 : child; + if (OverflowsInt16(child_bsp29)) { + return false; + } + } + } + + return true; +} + static bsp29_dclipnode_t * BSP2to29_Clipnodes(const bsp2_dclipnode_t *dclipnodes2, int numclipnodes) { const bsp2_dclipnode_t *dclipnode2 = dclipnodes2; @@ -2596,6 +2614,9 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) if (!BSP2to29_Faces_Validate(mbsp->dfaces, mbsp->numfaces)) { return false; } + if (!BSP2to29_Clipnodes_Validate(mbsp->dclipnodes, mbsp->numclipnodes)) { + return false; + } // zero destination struct memset(bsp29, 0, sizeof(*bsp29)); From c90ac7d6a75418b0a0570bf755884dbf1b6f7cf7 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Sun, 5 Sep 2021 01:28:58 -0600 Subject: [PATCH 6/9] common: bsp29: validate edges/marksurfaces --- common/bspfile.cc | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/common/bspfile.cc b/common/bspfile.cc index 342458bb..f5b11e5f 100644 --- a/common/bspfile.cc +++ b/common/bspfile.cc @@ -1838,8 +1838,7 @@ BSP2to29_Clipnodes_Validate(const bsp2_dclipnode_t *dclipnodes2, int numclipnode for (int j = 0; j < 2; j++) { /* Slightly tricky since we support > 32k clipnodes */ int32_t child = dclipnode2->children[j]; - int32_t child_bsp29 = child < 0 ? child + 0x10000 : child; - if (OverflowsInt16(child_bsp29)) { + if (child < -15 || child > 0xFFF0) { return false; } } @@ -1885,6 +1884,21 @@ BSP29to2_Edges(const bsp29_dedge_t *dedges29, int numedges) return newdata; } +static bool +BSP2to29_Edges_Validate(const bsp2_dedge_t *dedges2, int numedges) +{ + const bsp2_dedge_t *dedge2 = dedges2; + + for (int i = 0; i < numedges; i++, dedge2++) { + if (OverflowsUint16(dedge2->v[0]) + || OverflowsUint16(dedge2->v[1])) { + return false; + } + } + + return true; +} + static bsp29_dedge_t * BSP2to29_Edges(const bsp2_dedge_t *dedges2, int numedges) { @@ -1917,6 +1931,20 @@ BSP29to2_Marksurfaces(const uint16_t *dmarksurfaces29, int nummarksurfaces) return newdata; } +static bool +BSP2to29_Marksurfaces_Validate(const uint32_t *dmarksurfaces2, int nummarksurfaces) +{ + const uint32_t *dmarksurface2 = dmarksurfaces2; + + for (int i = 0; i < nummarksurfaces; i++, dmarksurface2++) { + if (OverflowsUint16(*dmarksurface2)) { + return false; + } + } + + return true; +} + static uint16_t * BSP2to29_Marksurfaces(const uint32_t *dmarksurfaces2, int nummarksurfaces) { @@ -2617,6 +2645,12 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) if (!BSP2to29_Clipnodes_Validate(mbsp->dclipnodes, mbsp->numclipnodes)) { return false; } + if (!BSP2to29_Edges_Validate(mbsp->dedges, mbsp->numedges)) { + return false; + } + if (!BSP2to29_Marksurfaces_Validate(mbsp->dleaffaces, mbsp->numleaffaces)) { + return false; + } // zero destination struct memset(bsp29, 0, sizeof(*bsp29)); From dc81db8b2f0c822a62387429d33f5d9d3bdb4d4f Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Sun, 5 Sep 2021 17:57:13 -0600 Subject: [PATCH 7/9] testmaps: add phongtest2.map --- testmaps/phongtest2.map | 142 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 testmaps/phongtest2.map diff --git a/testmaps/phongtest2.map b/testmaps/phongtest2.map new file mode 100644 index 00000000..2acad374 --- /dev/null +++ b/testmaps/phongtest2.map @@ -0,0 +1,142 @@ +// Game: Quake +// Format: Standard +// entity 0 +{ +"spawnflags" "0" +"classname" "worldspawn" +"wad" "free_wad.wad" +"_sun_mangle" "-60 -35 0" +"_sunlight_color" "1 0.631373 0.631373" +"_sunlight" "300" +"_sunlight2" "300" +// brush 0 +{ +( -3136 -1600 640 ) ( -3136 -544 640 ) ( -3136 -1600 672 ) sky3 192 64 0 1 1 +( -1440 -3584 640 ) ( -1440 -3584 672 ) ( 672 -3584 640 ) sky3 0 64 0 1 1 +( -1440 -1600 2512 ) ( 672 -1600 2512 ) ( -1440 -544 2512 ) sky3 0 -80 0 1 1 +( 672 -544 2544 ) ( 672 -1600 2544 ) ( -1440 -544 2544 ) sky3 0 -64 0 1 1 +( 672 544 672 ) ( -1440 544 672 ) ( 672 544 640 ) sky3 0 64 0 1 1 +( 1568 -544 672 ) ( 1568 -544 640 ) ( 1568 -1600 672 ) sky3 192 64 0 1 1 +} +// brush 1 +{ +( -3136 -1600 640 ) ( -3136 -544 640 ) ( -3136 -1600 672 ) sky3 192 64 0 1 1 +( -1440 -3584 640 ) ( -1440 -3584 672 ) ( 672 -3584 640 ) sky3 0 64 0 1 1 +( -1440 -1600 624 ) ( 672 -1600 624 ) ( -1440 -544 624 ) sky3 0 -64 0 1 1 +( 672 -544 3120 ) ( 672 -1600 3120 ) ( -1440 -544 3120 ) sky3 0 -64 0 1 1 +( 672 544 672 ) ( -1440 544 672 ) ( 672 544 640 ) sky3 0 64 0 1 1 +( -3072 -544 672 ) ( -3072 -544 640 ) ( -3072 -1600 672 ) sky3 192 64 0 1 1 +} +// brush 2 +{ +( -3136 -1600 640 ) ( -3136 -544 640 ) ( -3136 -1600 672 ) sky3 192 64 0 1 1 +( -1440 480 640 ) ( -1440 480 672 ) ( 672 480 640 ) sky3 0 64 0 1 1 +( -1440 -1600 624 ) ( 672 -1600 624 ) ( -1440 -544 624 ) sky3 0 -64 0 1 1 +( 672 -544 2544 ) ( 672 -1600 2544 ) ( -1440 -544 2544 ) sky3 0 -64 0 1 1 +( 672 544 672 ) ( -1440 544 672 ) ( 672 544 640 ) sky3 0 64 0 1 1 +( 1568 -544 672 ) ( 1568 -544 640 ) ( 1568 -1600 672 ) sky3 192 64 0 1 1 +} +// brush 3 +{ +( -3136 -1600 640 ) ( -3136 -544 640 ) ( -3136 -1600 672 ) sky3 192 64 0 1 1 +( -1440 -3584 640 ) ( -1440 -3584 672 ) ( 672 -3584 640 ) sky3 0 64 0 1 1 +( -1440 -1600 624 ) ( 672 -1600 624 ) ( -1440 -544 624 ) sky3 0 -64 0 1 1 +( 672 -544 2736 ) ( 672 -1600 2736 ) ( -1440 -544 2736 ) sky3 0 -64 0 1 1 +( 672 -3456 672 ) ( -1440 -3456 672 ) ( 672 -3456 640 ) sky3 0 64 0 1 1 +( 1568 -544 672 ) ( 1568 -544 640 ) ( 1568 -1600 672 ) sky3 192 64 0 1 1 +} +// brush 4 +{ +( -3136 -1600 640 ) ( -3136 -544 640 ) ( -3136 -1600 672 ) brownstone 0 0 0 1 1 +( -1440 -3584 640 ) ( -1440 -3584 672 ) ( 672 -3584 640 ) brownstone 0 0 0 1 1 +( -1440 -1600 624 ) ( 672 -1600 624 ) ( -1440 -544 624 ) brownstone 0 0 0 1 1 +( 672 -544 752 ) ( 672 -1600 752 ) ( -1440 -544 752 ) brownstone 0 0 0 1 1 +( 672 512 672 ) ( -1440 512 672 ) ( 672 512 640 ) brownstone 0 0 0 1 1 +( 1568 -544 672 ) ( 1568 -544 640 ) ( 1568 -1600 672 ) brownstone 0 0 0 1 1 +} +// brush 5 +{ +( 1536 -1600 640 ) ( 1536 -544 640 ) ( 1536 -1600 672 ) sky3 192 64 0 1 1 +( -1440 -3584 640 ) ( -1440 -3584 672 ) ( 672 -3584 640 ) sky3 0 64 0 1 1 +( -1440 -1600 624 ) ( 672 -1600 624 ) ( -1440 -544 624 ) sky3 0 -64 0 1 1 +( 672 -544 2576 ) ( 672 -1600 2576 ) ( -1440 -544 2576 ) sky3 0 -64 0 1 1 +( 672 544 672 ) ( -1440 544 672 ) ( 672 544 640 ) sky3 0 64 0 1 1 +( 1568 -544 672 ) ( 1568 -544 640 ) ( 1568 -1600 672 ) sky3 192 64 0 1 1 +} +} +// entity 1 +{ +"classname" "info_player_start" +"origin" "-1952 -2368 776" +} +// entity 2 +{ +"classname" "func_detail" +"_phong" "1" +// brush 0 +{ +( -1616 -2272 752 ) ( -1616 -2271 752 ) ( -1616 -2272 753 ) bolt1 0 0 0 1 1 +( -1616 -2256 912 ) ( -1600 -2272 1040 ) ( -1600 -2272 912 ) bolt1 0 0 0 1 1 +( -1600 -2160 912 ) ( -1616 -2176 1040 ) ( -1616 -2176 912 ) bolt1 0 0 0 1 1 +( -1616 -2272 752 ) ( -1616 -2272 753 ) ( -1615 -2272 752 ) bolt1 0 0 0 1 1 +( -1616 -2272 752 ) ( -1615 -2272 752 ) ( -1616 -2271 752 ) bolt1 0 0 0 1 1 +( -1488 -2160 912 ) ( -1488 -2159 912 ) ( -1487 -2160 912 ) bolt1 0 0 0 1 1 +( -1488 -2160 768 ) ( -1487 -2160 768 ) ( -1488 -2160 769 ) bolt1 0 0 0 1 1 +( -1584 -2176 912 ) ( -1584 -2208 912 ) ( -1584 -2208 1040 ) bolt1 0 0 0 1 1 +} +// brush 1 +{ +( -1584 -2176 912 ) ( -1584 -2208 1040 ) ( -1584 -2208 912 ) bolt1 0 0 0 1 1 +( -1616 -2256 752 ) ( -1616 -2256 753 ) ( -1615 -2256 752 ) bolt1 0 0 0 1 1 +( -1616 -2272 752 ) ( -1615 -2272 752 ) ( -1616 -2271 752 ) bolt1 0 0 0 1 1 +( -1488 -2160 912 ) ( -1488 -2159 912 ) ( -1487 -2160 912 ) bolt1 0 0 0 1 1 +( -1488 -2176 768 ) ( -1487 -2176 768 ) ( -1488 -2176 769 ) bolt1 0 0 0 1 1 +( -1536 -2176 912 ) ( -1536 -2208 912 ) ( -1536 -2208 1040 ) bolt1 0 0 0 1 1 +} +// brush 2 +{ +( -1536 -2176 912 ) ( -1536 -2208 1040 ) ( -1536 -2208 912 ) bolt1 0 0 0 1 1 +( -1616 -2272 752 ) ( -1616 -2272 753 ) ( -1615 -2272 752 ) bolt1 0 0 0 1 1 +( -1616 -2272 752 ) ( -1615 -2272 752 ) ( -1616 -2271 752 ) bolt1 0 0 0 1 1 +( -1488 -2160 912 ) ( -1488 -2159 912 ) ( -1487 -2160 912 ) bolt1 0 0 0 1 1 +( -1488 -2160 768 ) ( -1487 -2160 768 ) ( -1488 -2160 769 ) bolt1 0 0 0 1 1 +( -1504 -2272 912 ) ( -1488 -2256 1040 ) ( -1488 -2256 912 ) bolt1 0 0 0 1 1 +( -1488 -2176 912 ) ( -1504 -2160 1040 ) ( -1504 -2160 912 ) bolt1 0 0 0 1 1 +( -1488 -2160 768 ) ( -1488 -2160 769 ) ( -1488 -2159 768 ) bolt1 0 0 0 1 1 +} +} +// entity 3 +{ +"classname" "func_detail" +// brush 0 +{ +( -1616 -2560 752 ) ( -1616 -2559 752 ) ( -1616 -2560 753 ) bolt1 32 0 0 1 1 +( -1616 -2544 912 ) ( -1600 -2560 1040 ) ( -1600 -2560 912 ) bolt1 32 0 0 1 1 +( -1600 -2448 912 ) ( -1616 -2464 1040 ) ( -1616 -2464 912 ) bolt1 32 0 0 1 1 +( -1616 -2560 752 ) ( -1616 -2560 753 ) ( -1615 -2560 752 ) bolt1 0 0 0 1 1 +( -1616 -2560 752 ) ( -1615 -2560 752 ) ( -1616 -2559 752 ) bolt1 0 -32 0 1 1 +( -1488 -2448 912 ) ( -1488 -2447 912 ) ( -1487 -2448 912 ) bolt1 0 -32 0 1 1 +( -1488 -2448 768 ) ( -1487 -2448 768 ) ( -1488 -2448 769 ) bolt1 0 0 0 1 1 +( -1584 -2176 912 ) ( -1584 -2208 912 ) ( -1584 -2208 1040 ) bolt1 32 0 0 1 1 +} +// brush 1 +{ +( -1584 -2176 912 ) ( -1584 -2208 1040 ) ( -1584 -2208 912 ) bolt1 32 0 0 1 1 +( -1616 -2544 752 ) ( -1616 -2544 753 ) ( -1615 -2544 752 ) bolt1 0 0 0 1 1 +( -1616 -2560 752 ) ( -1615 -2560 752 ) ( -1616 -2559 752 ) bolt1 0 -32 0 1 1 +( -1488 -2448 912 ) ( -1488 -2447 912 ) ( -1487 -2448 912 ) bolt1 0 -32 0 1 1 +( -1488 -2464 768 ) ( -1487 -2464 768 ) ( -1488 -2464 769 ) bolt1 0 0 0 1 1 +( -1536 -2176 912 ) ( -1536 -2208 912 ) ( -1536 -2208 1040 ) bolt1 32 0 0 1 1 +} +// brush 2 +{ +( -1536 -2176 912 ) ( -1536 -2208 1040 ) ( -1536 -2208 912 ) bolt1 32 0 0 1 1 +( -1616 -2560 752 ) ( -1616 -2560 753 ) ( -1615 -2560 752 ) bolt1 0 0 0 1 1 +( -1616 -2560 752 ) ( -1615 -2560 752 ) ( -1616 -2559 752 ) bolt1 0 -32 0 1 1 +( -1488 -2448 912 ) ( -1488 -2447 912 ) ( -1487 -2448 912 ) bolt1 0 -32 0 1 1 +( -1488 -2448 768 ) ( -1487 -2448 768 ) ( -1488 -2448 769 ) bolt1 0 0 0 1 1 +( -1504 -2560 912 ) ( -1488 -2544 1040 ) ( -1488 -2544 912 ) bolt1 32 0 0 1 1 +( -1488 -2464 912 ) ( -1504 -2448 1040 ) ( -1504 -2448 912 ) bolt1 32 0 0 1 1 +( -1488 -2448 768 ) ( -1488 -2448 769 ) ( -1488 -2447 768 ) bolt1 32 0 0 1 1 +} +} From 648ef89845296bc6a9ac72f0a1b2bf0c7842eda0 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Mon, 6 Sep 2021 13:44:36 -0600 Subject: [PATCH 8/9] qbsp: naming fix --- include/qbsp/map.hh | 4 ++-- qbsp/writebsp.cc | 32 ++++++++++++++++---------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/include/qbsp/map.hh b/include/qbsp/map.hh index 36d24d1e..2545ed1f 100644 --- a/include/qbsp/map.hh +++ b/include/qbsp/map.hh @@ -158,8 +158,8 @@ typedef struct mapdata_s { // Final, exported data std::vector exported_texinfos; std::vector exported_planes; - std::vector exported_leafs_bsp29; - std::vector exported_nodes_bsp29; + std::vector exported_leafs; + std::vector exported_nodes; std::vector exported_marksurfaces; std::vector exported_clipnodes; std::vector exported_edges; diff --git a/qbsp/writebsp.cc b/qbsp/writebsp.cc index e24ede16..c6a2a45c 100644 --- a/qbsp/writebsp.cc +++ b/qbsp/writebsp.cc @@ -186,8 +186,8 @@ ExportLeaf static void ExportLeaf(mapentity_t *entity, node_t *node) { - map.exported_leafs_bsp29.push_back({}); - mleaf_t *dleaf = &map.exported_leafs_bsp29.back(); + map.exported_leafs.push_back({}); + mleaf_t *dleaf = &map.exported_leafs.back(); dleaf->contents = RemapContentsForExport(node->contents); AssertVanillaContentType(dleaf->contents); @@ -236,10 +236,10 @@ ExportDrawNodes(mapentity_t *entity, node_t *node) bsp2_dnode_t *dnode; int i; - const size_t ourNodeIndex = map.exported_nodes_bsp29.size(); - map.exported_nodes_bsp29.push_back({}); + const size_t ourNodeIndex = map.exported_nodes.size(); + map.exported_nodes.push_back({}); - dnode = &map.exported_nodes_bsp29[ourNodeIndex]; + dnode = &map.exported_nodes[ourNodeIndex]; // VectorCopy doesn't work since dest are shorts dnode->mins[0] = (short)node->mins[0]; @@ -259,19 +259,19 @@ ExportDrawNodes(mapentity_t *entity, node_t *node) if (node->children[i]->contents == CONTENTS_SOLID) dnode->children[i] = -1; else { - int nextLeafIndex = static_cast(map.exported_leafs_bsp29.size()); + int nextLeafIndex = static_cast(map.exported_leafs.size()); const int childnum = -(nextLeafIndex + 1); dnode->children[i] = childnum; ExportLeaf(entity, node->children[i]); } } else { - const int childnum = static_cast(map.exported_nodes_bsp29.size()); + const int childnum = static_cast(map.exported_nodes.size()); dnode->children[i] = childnum; ExportDrawNodes(entity, node->children[i]); // Important: our dnode pointer may be invalid after the recursive call, if the vector got resized. // So re-set the pointer. - dnode = &map.exported_nodes_bsp29[ourNodeIndex]; + dnode = &map.exported_nodes[ourNodeIndex]; } } @@ -296,11 +296,11 @@ ExportDrawNodes(mapentity_t *entity, node_t *headnode, int firstface) // populate model struct (which was emitted previously) dmodel = &map.exported_models.at(static_cast(entity->outputmodelnumber)); - dmodel->headnode[0] = static_cast(map.exported_nodes_bsp29.size()); + dmodel->headnode[0] = static_cast(map.exported_nodes.size()); dmodel->firstface = firstface; dmodel->numfaces = static_cast(map.exported_faces.size()) - firstface; - const size_t mapleafsAtStart = map.exported_leafs_bsp29.size(); + const size_t mapleafsAtStart = map.exported_leafs.size(); { if (headnode->contents < 0) @@ -310,7 +310,7 @@ ExportDrawNodes(mapentity_t *entity, node_t *headnode, int firstface) } // count how many leafs were exported by the above calls - dmodel->visleafs = static_cast(map.exported_leafs_bsp29.size() - mapleafsAtStart); + dmodel->visleafs = static_cast(map.exported_leafs.size() - mapleafsAtStart); /* remove the headnode padding */ for (i = 0; i < 3; i++) { @@ -334,9 +334,9 @@ BeginBSPFile(void) Q_assert(map.exported_edges.size() == 1); // Leave room for leaf 0 (must be solid) - map.exported_leafs_bsp29.push_back({}); - map.exported_leafs_bsp29.back().contents = CONTENTS_SOLID; // FIXME-Q2: use Q2_CONTENTS_SOLID - Q_assert(map.exported_leafs_bsp29.size() == 1); + map.exported_leafs.push_back({}); + map.exported_leafs.back().contents = CONTENTS_SOLID; // FIXME-Q2: use Q2_CONTENTS_SOLID + Q_assert(map.exported_leafs.size() == 1); } /* @@ -424,9 +424,9 @@ WriteBSPFile() bspdata.version = &bspver_generic; CopyVector(map.exported_planes, &bspdata.data.mbsp.numplanes, &bspdata.data.mbsp.dplanes); - CopyVector(map.exported_leafs_bsp29, &bspdata.data.mbsp.numleafs, &bspdata.data.mbsp.dleafs); + CopyVector(map.exported_leafs, &bspdata.data.mbsp.numleafs, &bspdata.data.mbsp.dleafs); CopyVector(map.exported_vertexes, &bspdata.data.mbsp.numvertexes, &bspdata.data.mbsp.dvertexes); - CopyVector(map.exported_nodes_bsp29, &bspdata.data.mbsp.numnodes, &bspdata.data.mbsp.dnodes); + CopyVector(map.exported_nodes, &bspdata.data.mbsp.numnodes, &bspdata.data.mbsp.dnodes); CopyVector(map.exported_texinfos, &bspdata.data.mbsp.numtexinfo, &bspdata.data.mbsp.texinfo); CopyVector(map.exported_faces, &bspdata.data.mbsp.numfaces, &bspdata.data.mbsp.dfaces); CopyVector(map.exported_clipnodes, &bspdata.data.mbsp.numclipnodes, &bspdata.data.mbsp.dclipnodes); From 71bb22dc280f38d5ad04de5195a2c717e4f28180 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Mon, 6 Sep 2021 14:20:51 -0600 Subject: [PATCH 9/9] qbsp: auto switch to extended limits formats --- qbsp/writebsp.cc | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/qbsp/writebsp.cc b/qbsp/writebsp.cc index ec03ad88..144a945b 100644 --- a/qbsp/writebsp.cc +++ b/qbsp/writebsp.cc @@ -442,7 +442,23 @@ WriteBSPFile() BSPX_AddLump(&bspdata, "BRUSHLIST", map.exported_bspxbrushes.data(), map.exported_bspxbrushes.size()); } - ConvertBSPFormat(&bspdata, options.target_version); + if (!ConvertBSPFormat(&bspdata, options.target_version)) { + const bspversion_t* highLimitsFormat = nullptr; + + if (options.target_version == &bspver_q1) { + highLimitsFormat = &bspver_bsp2; + } else if (options.target_version == &bspver_h2) { + highLimitsFormat = &bspver_h2bsp2; + } else if (options.target_version == &bspver_q2) { + highLimitsFormat = &bspver_qbism; + } else { + Error("No high limits version of %s available", options.target_version->name); + } + + logprint("NOTE: limits exceeded for %s - switching to %s\n", options.target_version->name, highLimitsFormat->name); + + Q_assert(ConvertBSPFormat(&bspdata, highLimitsFormat)); + } StripExtension(options.szBSPName); strcat(options.szBSPName, ".bsp");