From eaa86c71c638a7cc2feb85ba3702209c11d8d1e1 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Mon, 23 Aug 2021 11:56:33 -0400 Subject: [PATCH] Q2BSP + QBSP (#313) * Add QBSP - the BSP2-esque variant to Q2BSP - to bspinfo, and all of its accompanying structures. * pass around ident, since Q2 needs it - admittedly it's a bit ugly, but it works for now. conversion for QBSP * Fix light * _qbsp_ -> _qbism_ * Introduced bspversion_t, a struct that holds pertinent information about different BSP versions and also acts as a tagged pointer type for direct comparisons. This makes a lot of code paths simpler. I'm not entirely set on the wordings or usages yet, and maybe we can stuff boolean flags inside of them for different behaviors (for instance Q2, QBism and HL would have the "colored lightmap" boolean set to true, which replaces the check-for-all-three in the lightmapper) Swapped arguments to ConvertBSPFormat to have the conversion target last instead of first Finished rename of qbsp -> qbism Tested: - bspinfo on various BSPs I had laying around (Q1, Q2, Qbism) - bsputil converting between Q2 and Qbism, and that they loaded in engine/roundtripped properly Not tested: - vis/rad on anything major (I still can't run rad due to embree being weird) - bsputil conversion of Q1-esque maps --- bsputil/bsputil.cc | 32 +- common/bspfile.cc | 1859 ++++++++++++++++++++++++------------- common/bsputils.cc | 13 +- include/common/bspfile.hh | 147 ++- light/entities.cc | 2 +- light/imglib.cc | 6 +- light/light.cc | 18 +- light/ltface.cc | 6 +- light/trace.cc | 2 +- light/trace_embree.cc | 11 +- vis/vis.cc | 6 +- 11 files changed, 1388 insertions(+), 714 deletions(-) diff --git a/bsputil/bsputil.cc b/bsputil/bsputil.cc index 240a536a..4ce08b44 100644 --- a/bsputil/bsputil.cc +++ b/bsputil/bsputil.cc @@ -541,7 +541,7 @@ main(int argc, char **argv) LoadBSPFile(source, &bspdata); - ConvertBSPFormat(GENERIC_BSP, &bspdata); + ConvertBSPFormat(&bspdata, &bspver_generic); for (i = 0; i < argc - 1; i++) { if (!strcmp(argv[i], "--compare")) { @@ -556,7 +556,7 @@ main(int argc, char **argv) strcpy(refbspname, argv[i]); DefaultExtension(refbspname, ".bsp"); LoadBSPFile(refbspname, &refbspdata); - ConvertBSPFormat(GENERIC_BSP, &refbspdata); + ConvertBSPFormat(&refbspdata, &bspver_generic); printf("comparing reference bsp %s with test bsp %s\n", refbspname, source); @@ -569,21 +569,21 @@ main(int argc, char **argv) if (!(i < argc - 1)) { Error("--convert requires an argument"); } - - int fmt; - if (!strcmp(argv[i], "bsp29")) { - fmt = BSPVERSION; - } else if (!strcmp(argv[i], "bsp2")) { - fmt = BSP2VERSION; - } else if (!strcmp(argv[i], "bsp2rmq")) { - fmt = BSP2RMQVERSION; - } else if (!strcmp(argv[i], "q2bsp")) { - fmt = Q2_BSPVERSION; - } else { + + const bspversion_t *fmt = nullptr; + + for (const bspversion_t *bspver : bspversions) { + if (!strcmp(argv[i], bspver->short_name)) { + fmt = bspver; + break; + } + } + + if (!fmt) { Error("Unsupported format %s", argv[i]); } - - ConvertBSPFormat(fmt, &bspdata); + + ConvertBSPFormat(&bspdata, fmt); StripExtension(source); strcat(source, "-"); @@ -671,7 +671,7 @@ main(int argc, char **argv) bsp2_dface_t* face = BSP_GetFace(bsp, fnum); face->texinfo = texinfonum; - ConvertBSPFormat(bspdata.loadversion, &bspdata); + ConvertBSPFormat(&bspdata, bspdata.loadversion); // Overwrite source bsp! WriteBSPFile(source, &bspdata); diff --git a/common/bspfile.cc b/common/bspfile.cc index def143c8..91584f63 100644 --- a/common/bspfile.cc +++ b/common/bspfile.cc @@ -21,43 +21,45 @@ #include #include +const bspversion_t bspver_generic { NO_VERSION, NO_VERSION, "mbsp", "generic BSP" }; +const bspversion_t bspver_q1 { BSPVERSION, NO_VERSION, "bsp29", "Quake BSP" }; +/* Hexen II doesn't use a separate version, but we can still use a separate tag/name for it */ +const bspversion_t bspver_h2 { BSPVERSION, NO_VERSION, "hexen2", "Hexen II BSP" }; +const bspversion_t bspver_bsp2 { BSP2VERSION, NO_VERSION, "bsp2", "Quake BSP2" }; +const bspversion_t bspver_bsp2rmq { BSP2RMQVERSION, NO_VERSION, "bsp2rmq", "Quake BSP2-RMQ" }; +const bspversion_t bspver_hl { BSPHLVERSION, NO_VERSION, "hl", "Half-Life BSP" }; +const bspversion_t bspver_q2 { Q2_BSPIDENT, Q2_BSPVERSION, "q2bsp", "Quake II BSP" }; +const bspversion_t bspver_qbism { Q2_QBISMIDENT, Q2_BSPVERSION, "qbism", "Quake II Qbism BSP" }; + static const char * -BSPVersionString(int32_t version) +BSPVersionString(const bspversion_t *version) { + if (version->name) { + return version->name; + } + static char buffers[2][20]; static int index; - char *buffer; - - switch (version) { - case BSP2RMQVERSION: - return "BSP2rmq"; - case BSP2VERSION: - return "BSP2"; - case BSPHLVERSION: - return "HLBSP"; - case Q2_BSPVERSION: - return "Q2BSP"; - default: - buffer = buffers[1 & ++index]; - q_snprintf(buffer, sizeof(buffers[0]), "%d", version); - return buffer; + char *buffer = buffers[1 & ++index]; + if (version->version != NO_VERSION) { + q_snprintf(buffer, sizeof(buffers[0]), "%d:%d", version->version, version->ident); + } else { + q_snprintf(buffer, sizeof(buffers[0]), "%d", version->version); } + return buffer; } static qboolean -BSPVersionSupported(int32_t version) +BSPVersionSupported(int32_t ident, int32_t version, const bspversion_t **out_version) { - switch (version) { - case BSPVERSION: - case BSP2VERSION: - case BSP2RMQVERSION: - case BSPHLVERSION: - return true; - case Q2_BSPVERSION: - return true; - default: - return false; + for (const bspversion_t *bspver : bspversions) { + if (bspver->ident == ident && bspver->version == version) { + *out_version = bspver; + return true; + } } + + return false; } /* @@ -566,6 +568,200 @@ void Q2_SwapBSPFile (q2bsp_t *bsp, qboolean todisk) } } +/* +============= +Q2_Qbism_SwapBSPFile + +Byte swaps all data in a bsp file. +============= +*/ +void Q2_Qbism_SwapBSPFile (q2bsp_qbism_t *bsp, qboolean todisk) +{ + int i, j; + q2_dmodel_t *d; + + + // models + for (i=0 ; inummodels ; i++) + { + d = &bsp->dmodels[i]; + + d->firstface = LittleLong (d->firstface); + d->numfaces = LittleLong (d->numfaces); + d->headnode = LittleLong (d->headnode); + + for (j=0 ; j<3 ; j++) + { + d->mins[j] = LittleFloat(d->mins[j]); + d->maxs[j] = LittleFloat(d->maxs[j]); + d->origin[j] = LittleFloat(d->origin[j]); + } + } + + // + // vertexes + // + for (i=0 ; inumvertexes ; i++) + { + for (j=0 ; j<3 ; j++) + bsp->dvertexes[i].point[j] = LittleFloat (bsp->dvertexes[i].point[j]); + } + + // + // planes + // + for (i=0 ; inumplanes ; i++) + { + for (j=0 ; j<3 ; j++) + bsp->dplanes[i].normal[j] = LittleFloat (bsp->dplanes[i].normal[j]); + bsp->dplanes[i].dist = LittleFloat (bsp->dplanes[i].dist); + bsp->dplanes[i].type = LittleLong (bsp->dplanes[i].type); + } + + // + // texinfos + // + for (i=0 ; inumtexinfo ; i++) + { + for (j=0 ; j<4 ; j++) + { + bsp->texinfo[i].vecs[0][j] = LittleFloat(bsp->texinfo[i].vecs[0][j]); + bsp->texinfo[i].vecs[1][j] = LittleFloat(bsp->texinfo[i].vecs[1][j]); + } + bsp->texinfo[i].flags = LittleLong (bsp->texinfo[i].flags); + bsp->texinfo[i].value = LittleLong (bsp->texinfo[i].value); + bsp->texinfo[i].nexttexinfo = LittleLong (bsp->texinfo[i].nexttexinfo); + } + + // + // faces + // + for (i=0 ; inumfaces ; i++) + { + bsp->dfaces[i].texinfo = LittleLong (bsp->dfaces[i].texinfo); + bsp->dfaces[i].planenum = LittleLong (bsp->dfaces[i].planenum); + bsp->dfaces[i].side = LittleLong (bsp->dfaces[i].side); + bsp->dfaces[i].lightofs = LittleLong (bsp->dfaces[i].lightofs); + bsp->dfaces[i].firstedge = LittleLong (bsp->dfaces[i].firstedge); + bsp->dfaces[i].numedges = LittleLong (bsp->dfaces[i].numedges); + } + + // + // nodes + // + for (i=0 ; inumnodes ; i++) + { + bsp->dnodes[i].planenum = LittleLong (bsp->dnodes[i].planenum); + for (j=0 ; j<3 ; j++) + { + bsp->dnodes[i].mins[j] = LittleFloat (bsp->dnodes[i].mins[j]); + bsp->dnodes[i].maxs[j] = LittleFloat (bsp->dnodes[i].maxs[j]); + } + bsp->dnodes[i].children[0] = LittleLong (bsp->dnodes[i].children[0]); + bsp->dnodes[i].children[1] = LittleLong (bsp->dnodes[i].children[1]); + bsp->dnodes[i].firstface = LittleLong (bsp->dnodes[i].firstface); + bsp->dnodes[i].numfaces = LittleLong (bsp->dnodes[i].numfaces); + } + + // + // leafs + // + for (i=0 ; inumleafs ; i++) + { + bsp->dleafs[i].contents = LittleLong (bsp->dleafs[i].contents); + bsp->dleafs[i].cluster = LittleLong (bsp->dleafs[i].cluster); + bsp->dleafs[i].area = LittleLong (bsp->dleafs[i].area); + for (j=0 ; j<3 ; j++) + { + bsp->dleafs[i].mins[j] = LittleFloat (bsp->dleafs[i].mins[j]); + bsp->dleafs[i].maxs[j] = LittleFloat (bsp->dleafs[i].maxs[j]); + } + + bsp->dleafs[i].firstleafface = LittleLong (bsp->dleafs[i].firstleafface); + bsp->dleafs[i].numleaffaces = LittleLong (bsp->dleafs[i].numleaffaces); + bsp->dleafs[i].firstleafbrush = LittleLong (bsp->dleafs[i].firstleafbrush); + bsp->dleafs[i].numleafbrushes = LittleLong (bsp->dleafs[i].numleafbrushes); + } + + // + // leaffaces + // + for (i=0 ; inumleaffaces ; i++) + bsp->dleaffaces[i] = LittleLong (bsp->dleaffaces[i]); + + // + // leafbrushes + // + for (i=0 ; inumleafbrushes ; i++) + bsp->dleafbrushes[i] = LittleLong (bsp->dleafbrushes[i]); + + // + // surfedges + // + for (i=0 ; inumsurfedges ; i++) + bsp->dsurfedges[i] = LittleLong (bsp->dsurfedges[i]); + + // + // edges + // + for (i=0 ; inumedges ; i++) + { + bsp->dedges[i].v[0] = LittleLong (bsp->dedges[i].v[0]); + bsp->dedges[i].v[1] = LittleLong (bsp->dedges[i].v[1]); + } + + // + // brushes + // + for (i=0 ; inumbrushes ; i++) + { + bsp->dbrushes[i].firstside = LittleLong (bsp->dbrushes[i].firstside); + bsp->dbrushes[i].numsides = LittleLong (bsp->dbrushes[i].numsides); + bsp->dbrushes[i].contents = LittleLong (bsp->dbrushes[i].contents); + } + + // + // areas + // + for (i=0 ; inumareas ; i++) + { + bsp->dareas[i].numareaportals = LittleLong (bsp->dareas[i].numareaportals); + bsp->dareas[i].firstareaportal = LittleLong (bsp->dareas[i].firstareaportal); + } + + // + // areasportals + // + for (i=0 ; inumareaportals ; i++) + { + bsp->dareaportals[i].portalnum = LittleLong (bsp->dareaportals[i].portalnum); + bsp->dareaportals[i].otherarea = LittleLong (bsp->dareaportals[i].otherarea); + } + + // + // brushsides + // + for (i=0 ; inumbrushsides ; i++) + { + bsp->dbrushsides[i].planenum = LittleLong (bsp->dbrushsides[i].planenum); + bsp->dbrushsides[i].texinfo = LittleLong (bsp->dbrushsides[i].texinfo); + } + + // + // visibility + // + if (todisk) + j = bsp->dvis->numclusters; + else + j = LittleLong(bsp->dvis->numclusters); + bsp->dvis->numclusters = LittleLong (bsp->dvis->numclusters); + for (i=0 ; idvis->bitofs[i][0] = LittleLong (bsp->dvis->bitofs[i][0]); + bsp->dvis->bitofs[i][1] = LittleLong (bsp->dvis->bitofs[i][1]); + } +} + /* * ============= * SwapBSPFile @@ -575,15 +771,17 @@ void Q2_SwapBSPFile (q2bsp_t *bsp, qboolean todisk) static void SwapBSPFile(bspdata_t *bspdata, swaptype_t swap) { - if (bspdata->version == Q2_BSPVERSION) { + if (bspdata->version == &bspver_q2) { q2bsp_t *bsp = &bspdata->data.q2bsp; - Q2_SwapBSPFile(bsp, swap == TO_DISK); - + return; + } else if (bspdata->version == &bspver_qbism) { + q2bsp_qbism_t *bsp = &bspdata->data.q2bsp_qbism; + Q2_Qbism_SwapBSPFile(bsp, swap == TO_DISK); return; } - if (bspdata->version == BSPVERSION || bspdata->version == BSPHLVERSION) { + if (bspdata->version == &bspver_q1 || bspdata->version == &bspver_h2 || bspdata->version == &bspver_hl) { bsp29_t *bsp = &bspdata->data.bsp29; SwapBSPVertexes(bsp->numvertexes, bsp->dvertexes); @@ -602,7 +800,7 @@ SwapBSPFile(bspdata_t *bspdata, swaptype_t swap) return; } - if (bspdata->version == BSP2RMQVERSION) { + if (bspdata->version == &bspver_bsp2rmq) { bsp2rmq_t *bsp = &bspdata->data.bsp2rmq; SwapBSPVertexes(bsp->numvertexes, bsp->dvertexes); @@ -621,7 +819,7 @@ SwapBSPFile(bspdata_t *bspdata, swaptype_t swap) return; } - if (bspdata->version == BSP2VERSION) { + if (bspdata->version == &bspver_bsp2) { bsp2_t *bsp = &bspdata->data.bsp2; SwapBSPVertexes(bsp->numvertexes, bsp->dvertexes); @@ -813,6 +1011,33 @@ Q2BSPtoM_Leafs(const q2_dleaf_t *dleafsq2, int numleafs) { return newdata; } +static mleaf_t * +Q2BSP_QBSPtoM_Leafs(const q2_dleaf_qbism_t *dleafsq2, int numleafs) { + const q2_dleaf_qbism_t *dleafq2 = dleafsq2; + mleaf_t *newdata, *mleaf; + int i, j; + + newdata = mleaf = (mleaf_t *)calloc(numleafs, sizeof(*mleaf)); + + for (i = 0; i < numleafs; i++, dleafq2++, mleaf++) { + mleaf->contents = dleafq2->contents; + mleaf->cluster = dleafq2->cluster; + mleaf->area = dleafq2->area; + + for (j = 0; j < 3; j++) { + mleaf->mins[j] = dleafq2->mins[j]; + mleaf->maxs[j] = dleafq2->maxs[j]; + } + mleaf->firstmarksurface = dleafq2->firstleafface; + mleaf->nummarksurfaces = dleafq2->numleaffaces; + + mleaf->firstleafbrush = dleafq2->firstleafbrush; + mleaf->numleafbrushes = dleafq2->numleafbrushes; + } + + return newdata; +} + static q2_dleaf_t * MBSPtoQ2_Leafs(const mleaf_t *mleafs, int numleafs) { const mleaf_t *mleaf = mleafs; @@ -840,6 +1065,33 @@ MBSPtoQ2_Leafs(const mleaf_t *mleafs, int numleafs) { return newdata; } +static q2_dleaf_qbism_t * +MBSPtoQ2_Qbism_Leafs(const mleaf_t *mleafs, int numleafs) { + const mleaf_t *mleaf = mleafs; + q2_dleaf_qbism_t *newdata, *dleafq2; + int i, j; + + newdata = dleafq2 = (q2_dleaf_qbism_t *)calloc(numleafs, sizeof(*dleafq2)); + + for (i = 0; i < numleafs; i++, mleaf++, dleafq2++) { + dleafq2->contents = mleaf->contents; + dleafq2->cluster = mleaf->cluster; + dleafq2->area = mleaf->area; + + for (j = 0; j < 3; j++) { + dleafq2->mins[j] = mleaf->mins[j]; + dleafq2->maxs[j] = mleaf->maxs[j]; + } + dleafq2->firstleafface = mleaf->firstmarksurface; + dleafq2->numleaffaces = mleaf->nummarksurfaces; + + dleafq2->firstleafbrush = mleaf->firstleafbrush; + dleafq2->numleafbrushes = mleaf->numleafbrushes; + } + + return newdata; +} + static bsp2_dnode_t * Q2BSPto2_Nodes(const q2_dnode_t *dnodesq2, int numnodes) { const q2_dnode_t *dnodeq2 = dnodesq2; @@ -908,6 +1160,28 @@ Q2BSPto2_Faces(const q2_dface_t *dfacesq2, int numfaces) { return newdata; } +static bsp2_dface_t * +Q2BSP_QBSPto2_Faces(const q2_dface_qbism_t *dfacesq2, int numfaces) { + const q2_dface_qbism_t *dfaceq2 = dfacesq2; + bsp2_dface_t *newdata, *dface2; + int i, j; + + newdata = dface2 = static_cast(malloc(numfaces * sizeof(*dface2))); + + for (i = 0; i < numfaces; i++, dfaceq2++, dface2++) { + dface2->planenum = dfaceq2->planenum; + dface2->side = dfaceq2->side; + dface2->firstedge = dfaceq2->firstedge; + dface2->numedges = dfaceq2->numedges; + dface2->texinfo = dfaceq2->texinfo; + for (j = 0; j < MAXLIGHTMAPS; j++) + dface2->styles[j] = dfaceq2->styles[j]; + dface2->lightofs = dfaceq2->lightofs; + } + + return newdata; +} + static q2_dface_t * BSP2toQ2_Faces(const bsp2_dface_t *dfaces2, int numfaces) { const bsp2_dface_t *dface2 = dfaces2; @@ -930,6 +1204,28 @@ BSP2toQ2_Faces(const bsp2_dface_t *dfaces2, int numfaces) { return newdata; } +static q2_dface_qbism_t * +BSP2toQ2_Qbism_Faces(const bsp2_dface_t *dfaces2, int numfaces) { + const bsp2_dface_t *dface2 = dfaces2; + q2_dface_qbism_t *newdata, *dfaceq2; + int i, j; + + newdata = dfaceq2 = static_cast(malloc(numfaces * sizeof(*dfaceq2))); + + for (i = 0; i < numfaces; i++, dface2++, dfaceq2++) { + dfaceq2->planenum = dface2->planenum; + dfaceq2->side = dface2->side; + dfaceq2->firstedge = dface2->firstedge; + dfaceq2->numedges = dface2->numedges; + dfaceq2->texinfo = dface2->texinfo; + for (j = 0; j < MAXLIGHTMAPS; j++) + dfaceq2->styles[j] = dface2->styles[j]; + dfaceq2->lightofs = dface2->lightofs; + } + + return newdata; +} + static gtexinfo_t * Q2BSPtoM_Texinfo(const q2_texinfo_t *dtexinfosq2, int numtexinfos) { const q2_texinfo_t *dtexinfoq2 = dtexinfosq2; @@ -1415,9 +1711,37 @@ static bsp2_dnode_t *BSP2_CopyNodes(const bsp2_dnode_t *dnodes, int numnodes) return (bsp2_dnode_t *)CopyArray(dnodes, numnodes, sizeof(*dnodes)); } -static uint16_t *Q2BSP_CopyLeafBrushes(const uint16_t *leafbrushes, int count) +static uint32_t *Q2BSPtoM_CopyLeafBrushes(const uint16_t *leafbrushes, int count) { - return (uint16_t *)CopyArray(leafbrushes, count, sizeof(*leafbrushes)); + const uint16_t *leafbrush = leafbrushes; + uint32_t *newdata, *leafbrushes2; + int i; + + newdata = leafbrushes2 = static_cast(malloc(count * sizeof(*leafbrushes2))); + + for (i = 0; i < count; i++, leafbrush++, leafbrushes2++) + *leafbrushes2 = *leafbrush; + + return newdata; +} + +static uint16_t *MBSPtoQ2_CopyLeafBrushes(const uint32_t *leafbrushes, int count) +{ + const uint32_t *leafbrush = leafbrushes; + uint16_t *newdata, *leafbrushes2; + int i; + + newdata = leafbrushes2 = static_cast(malloc(count * sizeof(*leafbrushes2))); + + for (i = 0; i < count; i++, leafbrush++, leafbrushes2++) + *leafbrushes2 = *leafbrush; + + return newdata; +} + +static uint32_t *Q2BSP_Qbism_CopyLeafBrushes(const uint32_t *leafbrushes, int count) +{ + return (uint32_t *)CopyArray(leafbrushes, count, sizeof(*leafbrushes)); } static darea_t *Q2BSP_CopyAreas(const darea_t *areas, int count) @@ -1435,9 +1759,41 @@ static dbrush_t *Q2BSP_CopyBrushes(const dbrush_t *brushes, int count) return (dbrush_t *)CopyArray(brushes, count, sizeof(*brushes)); } -static dbrushside_t *Q2BSP_CopyBrushSides(const dbrushside_t *dbrushsides, int count) +static q2_dbrushside_qbism_t *Q2BSPtoM_CopyBrushSides(const dbrushside_t *dbrushsides, int count) { - return (dbrushside_t *)CopyArray(dbrushsides, count, sizeof(*dbrushsides)); + const dbrushside_t *brushside = dbrushsides; + q2_dbrushside_qbism_t *newdata, *brushsides2; + int i; + + newdata = brushsides2 = static_cast(malloc(count * sizeof(*brushsides2))); + + for (i = 0; i < count; i++, brushside++, brushsides2++) { + brushsides2->planenum = brushside->planenum; + brushsides2->texinfo = brushside->texinfo; + } + + return newdata; +} + +static q2_dbrushside_qbism_t *Q2BSP_Qbism_CopyBrushSides(const q2_dbrushside_qbism_t *brushsides, int count) +{ + return (q2_dbrushside_qbism_t *)CopyArray(brushsides, count, sizeof(*brushsides)); +} + +static dbrushside_t *MBSPtoQ2_CopyBrushSides(const q2_dbrushside_qbism_t *dbrushsides, int count) +{ + const q2_dbrushside_qbism_t *brushside = dbrushsides; + dbrushside_t *newdata, *brushsides2; + int i; + + newdata = brushsides2 = static_cast(malloc(count * sizeof(*brushsides2))); + + for (i = 0; i < count; i++, brushside++, brushsides2++) { + brushsides2->planenum = brushside->planenum; + brushsides2->texinfo = brushside->texinfo; + } + + return newdata; } @@ -1530,6 +1886,29 @@ static void FreeQ2BSP(q2bsp_t *bsp) memset(bsp, 0, sizeof(*bsp)); } +static void FreeQ2BSP_QBSP(q2bsp_qbism_t *bsp) +{ + free(bsp->dmodels); + free(bsp->dvis); + free(bsp->dlightdata); + free(bsp->dentdata); + free(bsp->dleafs); + free(bsp->dplanes); + free(bsp->dvertexes); + free(bsp->dnodes); + free(bsp->texinfo); + free(bsp->dfaces); + free(bsp->dedges); + free(bsp->dleaffaces); + free(bsp->dleafbrushes); + free(bsp->dsurfedges); + free(bsp->dareas); + free(bsp->dareaportals); + free(bsp->dbrushes); + free(bsp->dbrushsides); + memset(bsp, 0, sizeof(*bsp)); +} + static void FreeMBSP(mbsp_t *bsp) { free(bsp->dmodels); @@ -1556,6 +1935,13 @@ static void FreeMBSP(mbsp_t *bsp) memset(bsp, 0, sizeof(*bsp)); } +inline void +ConvertBSPToMFormatComplete(const bspversion_t **mbsp_loadversion, const bspversion_t *version, bspdata_t *bspdata) +{ + *mbsp_loadversion = bspdata->version; + bspdata->version = version; +} + /* * ========================================================================= * ConvertBSPFormat @@ -1564,440 +1950,547 @@ static void FreeMBSP(mbsp_t *bsp) * ========================================================================= */ void -ConvertBSPFormat(int32_t version, bspdata_t *bspdata) +ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) { - if (bspdata->version == version) + if (bspdata->version == to_version) return; // conversions to GENERIC_BSP + if (to_version == &bspver_generic) { + if (bspdata->version == &bspver_q1 || bspdata->version == &bspver_h2 || bspdata->version == &bspver_hl) { + const bsp29_t *bsp29 = &bspdata->data.bsp29; + mbsp_t *mbsp = &bspdata->data.mbsp; + + memset(mbsp, 0, sizeof(*mbsp)); + + // copy counts + mbsp->nummodels = bsp29->nummodels; + mbsp->visdatasize = bsp29->visdatasize; + mbsp->lightdatasize = bsp29->lightdatasize; + mbsp->texdatasize = bsp29->texdatasize; + mbsp->entdatasize = bsp29->entdatasize; + mbsp->numleafs = bsp29->numleafs; + mbsp->numplanes = bsp29->numplanes; + mbsp->numvertexes = bsp29->numvertexes; + mbsp->numnodes = bsp29->numnodes; + mbsp->numtexinfo = bsp29->numtexinfo; + mbsp->numfaces = bsp29->numfaces; + mbsp->numclipnodes = bsp29->numclipnodes; + mbsp->numedges = bsp29->numedges; + mbsp->numleaffaces = bsp29->nummarksurfaces; + mbsp->numsurfedges = bsp29->numsurfedges; + + // copy or convert data + mbsp->dmodels = BSP29_CopyModels(bsp29->dmodels, bsp29->nummodels); + mbsp->dvisdata = BSP29_CopyVisData(bsp29->dvisdata, bsp29->visdatasize); + mbsp->dlightdata = BSP29_CopyLightData(bsp29->dlightdata, bsp29->lightdatasize); + mbsp->dtexdata = BSP29_CopyTexData(bsp29->dtexdata, bsp29->texdatasize); + mbsp->dentdata = BSP29_CopyEntData(bsp29->dentdata, bsp29->entdatasize); + mbsp->dleafs = BSP29toM_Leafs(bsp29->dleafs, bsp29->numleafs); + mbsp->dplanes = BSP29_CopyPlanes(bsp29->dplanes, bsp29->numplanes); + mbsp->dvertexes = BSP29_CopyVertexes(bsp29->dvertexes, bsp29->numvertexes); + mbsp->dnodes = BSP29to2_Nodes(bsp29->dnodes, bsp29->numnodes); + mbsp->texinfo = BSP29toM_Texinfo(bsp29->texinfo, bsp29->numtexinfo); + mbsp->dfaces = BSP29to2_Faces(bsp29->dfaces, bsp29->numfaces); + mbsp->dclipnodes = BSP29to2_Clipnodes(bsp29->dclipnodes, bsp29->numclipnodes); + mbsp->dedges = BSP29to2_Edges(bsp29->dedges, bsp29->numedges); + mbsp->dleaffaces = BSP29to2_Marksurfaces(bsp29->dmarksurfaces, bsp29->nummarksurfaces); + mbsp->dsurfedges = BSP29_CopySurfedges(bsp29->dsurfedges, bsp29->numsurfedges); + + /* Free old data */ + FreeBSP29((bsp29_t *)bsp29); + + /* Conversion complete! */ + ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata); + + return; + } - if ((bspdata->version == BSPVERSION || bspdata->version == BSPHLVERSION) && version == GENERIC_BSP) { - const bsp29_t *bsp29 = &bspdata->data.bsp29; - mbsp_t *mbsp = &bspdata->data.mbsp; + else if (bspdata->version == &bspver_q2) { + const q2bsp_t *q2bsp = &bspdata->data.q2bsp; + mbsp_t *mbsp = &bspdata->data.mbsp; - memset(mbsp, 0, sizeof(*mbsp)); + memset(mbsp, 0, sizeof(*mbsp)); - // copy counts - mbsp->nummodels = bsp29->nummodels; - mbsp->visdatasize = bsp29->visdatasize; - mbsp->lightdatasize = bsp29->lightdatasize; - mbsp->texdatasize = bsp29->texdatasize; - mbsp->entdatasize = bsp29->entdatasize; - mbsp->numleafs = bsp29->numleafs; - mbsp->numplanes = bsp29->numplanes; - mbsp->numvertexes = bsp29->numvertexes; - mbsp->numnodes = bsp29->numnodes; - mbsp->numtexinfo = bsp29->numtexinfo; - mbsp->numfaces = bsp29->numfaces; - mbsp->numclipnodes = bsp29->numclipnodes; - mbsp->numedges = bsp29->numedges; - mbsp->numleaffaces = bsp29->nummarksurfaces; - mbsp->numsurfedges = bsp29->numsurfedges; + // copy counts + mbsp->nummodels = q2bsp->nummodels; + mbsp->visdatasize = q2bsp->visdatasize; + mbsp->lightdatasize = q2bsp->lightdatasize; + mbsp->entdatasize = q2bsp->entdatasize; + mbsp->numleafs = q2bsp->numleafs; + mbsp->numplanes = q2bsp->numplanes; + mbsp->numvertexes = q2bsp->numvertexes; + mbsp->numnodes = q2bsp->numnodes; + mbsp->numtexinfo = q2bsp->numtexinfo; + mbsp->numfaces = q2bsp->numfaces; + mbsp->numedges = q2bsp->numedges; + mbsp->numleaffaces = q2bsp->numleaffaces; + mbsp->numleafbrushes = q2bsp->numleafbrushes; + mbsp->numsurfedges = q2bsp->numsurfedges; + mbsp->numareas = q2bsp->numareas; + mbsp->numareaportals = q2bsp->numareaportals; + mbsp->numbrushes = q2bsp->numbrushes; + mbsp->numbrushsides = q2bsp->numbrushsides; - // copy or convert data - mbsp->dmodels = BSP29_CopyModels(bsp29->dmodels, bsp29->nummodels); - mbsp->dvisdata = BSP29_CopyVisData(bsp29->dvisdata, bsp29->visdatasize); - mbsp->dlightdata = BSP29_CopyLightData(bsp29->dlightdata, bsp29->lightdatasize); - mbsp->dtexdata = BSP29_CopyTexData(bsp29->dtexdata, bsp29->texdatasize); - mbsp->dentdata = BSP29_CopyEntData(bsp29->dentdata, bsp29->entdatasize); - mbsp->dleafs = BSP29toM_Leafs(bsp29->dleafs, bsp29->numleafs); - mbsp->dplanes = BSP29_CopyPlanes(bsp29->dplanes, bsp29->numplanes); - mbsp->dvertexes = BSP29_CopyVertexes(bsp29->dvertexes, bsp29->numvertexes); - mbsp->dnodes = BSP29to2_Nodes(bsp29->dnodes, bsp29->numnodes); - mbsp->texinfo = BSP29toM_Texinfo(bsp29->texinfo, bsp29->numtexinfo); - mbsp->dfaces = BSP29to2_Faces(bsp29->dfaces, bsp29->numfaces); - mbsp->dclipnodes = BSP29to2_Clipnodes(bsp29->dclipnodes, bsp29->numclipnodes); - mbsp->dedges = BSP29to2_Edges(bsp29->dedges, bsp29->numedges); - mbsp->dleaffaces = BSP29to2_Marksurfaces(bsp29->dmarksurfaces, bsp29->nummarksurfaces); - mbsp->dsurfedges = BSP29_CopySurfedges(bsp29->dsurfedges, bsp29->numsurfedges); + // copy or convert data + mbsp->dmodels = Q2BSPtoM_Models(q2bsp->dmodels, q2bsp->nummodels); + mbsp->dvisdata = (uint8_t *)CopyArray(q2bsp->dvis, q2bsp->visdatasize, 1); + mbsp->dlightdata = BSP29_CopyLightData(q2bsp->dlightdata, q2bsp->lightdatasize); + mbsp->dentdata = BSP29_CopyEntData(q2bsp->dentdata, q2bsp->entdatasize); + mbsp->dleafs = Q2BSPtoM_Leafs(q2bsp->dleafs, q2bsp->numleafs); + mbsp->dplanes = BSP29_CopyPlanes(q2bsp->dplanes, q2bsp->numplanes); + mbsp->dvertexes = BSP29_CopyVertexes(q2bsp->dvertexes, q2bsp->numvertexes); + mbsp->dnodes = Q2BSPto2_Nodes(q2bsp->dnodes, q2bsp->numnodes); + mbsp->texinfo = Q2BSPtoM_Texinfo(q2bsp->texinfo, q2bsp->numtexinfo); + mbsp->dfaces = Q2BSPto2_Faces(q2bsp->dfaces, q2bsp->numfaces); + mbsp->dedges = BSP29to2_Edges(q2bsp->dedges, q2bsp->numedges); + mbsp->dleaffaces = BSP29to2_Marksurfaces(q2bsp->dleaffaces, q2bsp->numleaffaces); + mbsp->dleafbrushes = Q2BSPtoM_CopyLeafBrushes(q2bsp->dleafbrushes, q2bsp->numleafbrushes); + mbsp->dsurfedges = BSP29_CopySurfedges(q2bsp->dsurfedges, q2bsp->numsurfedges); - /* Free old data */ - FreeBSP29((bsp29_t *)bsp29); + mbsp->dareas = Q2BSP_CopyAreas(q2bsp->dareas, q2bsp->numareas); + mbsp->dareaportals = Q2BSP_CopyAreaPortals(q2bsp->dareaportals, q2bsp->numareaportals); - /* Conversion complete! */ - mbsp->loadversion = bspdata->version; - bspdata->version = version; + mbsp->dbrushes = Q2BSP_CopyBrushes(q2bsp->dbrushes, q2bsp->numbrushes); + mbsp->dbrushsides = Q2BSPtoM_CopyBrushSides(q2bsp->dbrushsides, q2bsp->numbrushsides); - return; - } - - if (bspdata->version == Q2_BSPVERSION && version == GENERIC_BSP) { - const q2bsp_t *q2bsp = &bspdata->data.q2bsp; - mbsp_t *mbsp = &bspdata->data.mbsp; + /* Free old data */ + FreeQ2BSP((q2bsp_t *)q2bsp); - memset(mbsp, 0, sizeof(*mbsp)); - - // copy counts - mbsp->nummodels = q2bsp->nummodels; - mbsp->visdatasize = q2bsp->visdatasize; - mbsp->lightdatasize = q2bsp->lightdatasize; - mbsp->entdatasize = q2bsp->entdatasize; - mbsp->numleafs = q2bsp->numleafs; - mbsp->numplanes = q2bsp->numplanes; - mbsp->numvertexes = q2bsp->numvertexes; - mbsp->numnodes = q2bsp->numnodes; - mbsp->numtexinfo = q2bsp->numtexinfo; - mbsp->numfaces = q2bsp->numfaces; - mbsp->numedges = q2bsp->numedges; - mbsp->numleaffaces = q2bsp->numleaffaces; - mbsp->numleafbrushes = q2bsp->numleafbrushes; - mbsp->numsurfedges = q2bsp->numsurfedges; - mbsp->numareas = q2bsp->numareas; - mbsp->numareaportals = q2bsp->numareaportals; - mbsp->numbrushes = q2bsp->numbrushes; - mbsp->numbrushsides = q2bsp->numbrushsides; - - // copy or convert data - mbsp->dmodels = Q2BSPtoM_Models(q2bsp->dmodels, q2bsp->nummodels); - mbsp->dvisdata = (uint8_t *)CopyArray(q2bsp->dvis, q2bsp->visdatasize, 1); - mbsp->dlightdata = BSP29_CopyLightData(q2bsp->dlightdata, q2bsp->lightdatasize); - mbsp->dentdata = BSP29_CopyEntData(q2bsp->dentdata, q2bsp->entdatasize); - mbsp->dleafs = Q2BSPtoM_Leafs(q2bsp->dleafs, q2bsp->numleafs); - mbsp->dplanes = BSP29_CopyPlanes(q2bsp->dplanes, q2bsp->numplanes); - mbsp->dvertexes = BSP29_CopyVertexes(q2bsp->dvertexes, q2bsp->numvertexes); - mbsp->dnodes = Q2BSPto2_Nodes(q2bsp->dnodes, q2bsp->numnodes); - mbsp->texinfo = Q2BSPtoM_Texinfo(q2bsp->texinfo, q2bsp->numtexinfo); - mbsp->dfaces = Q2BSPto2_Faces(q2bsp->dfaces, q2bsp->numfaces); - mbsp->dedges = BSP29to2_Edges(q2bsp->dedges, q2bsp->numedges); - mbsp->dleaffaces = BSP29to2_Marksurfaces(q2bsp->dleaffaces, q2bsp->numleaffaces); - mbsp->dleafbrushes = Q2BSP_CopyLeafBrushes(q2bsp->dleafbrushes, q2bsp->numleafbrushes); - mbsp->dsurfedges = BSP29_CopySurfedges(q2bsp->dsurfedges, q2bsp->numsurfedges); - - mbsp->dareas = Q2BSP_CopyAreas(q2bsp->dareas, q2bsp->numareas); - mbsp->dareaportals = Q2BSP_CopyAreaPortals(q2bsp->dareaportals, q2bsp->numareaportals); - - mbsp->dbrushes = Q2BSP_CopyBrushes(q2bsp->dbrushes, q2bsp->numbrushes); - mbsp->dbrushsides = Q2BSP_CopyBrushSides(q2bsp->dbrushsides, q2bsp->numbrushsides); - - /* Free old data */ - FreeQ2BSP((q2bsp_t *)q2bsp); - - /* Conversion complete! */ - mbsp->loadversion = bspdata->version; - bspdata->version = version; - - return; - } - - if (bspdata->version == BSP2RMQVERSION && version == GENERIC_BSP) { - const bsp2rmq_t *bsp2rmq = &bspdata->data.bsp2rmq; - mbsp_t *mbsp = &bspdata->data.mbsp; - - memset(mbsp, 0, sizeof(*mbsp)); - - // copy counts - mbsp->nummodels = bsp2rmq->nummodels; - mbsp->visdatasize = bsp2rmq->visdatasize; - mbsp->lightdatasize = bsp2rmq->lightdatasize; - mbsp->texdatasize = bsp2rmq->texdatasize; - mbsp->entdatasize = bsp2rmq->entdatasize; - mbsp->numleafs = bsp2rmq->numleafs; - mbsp->numplanes = bsp2rmq->numplanes; - mbsp->numvertexes = bsp2rmq->numvertexes; - mbsp->numnodes = bsp2rmq->numnodes; - mbsp->numtexinfo = bsp2rmq->numtexinfo; - mbsp->numfaces = bsp2rmq->numfaces; - mbsp->numclipnodes = bsp2rmq->numclipnodes; - mbsp->numedges = bsp2rmq->numedges; - mbsp->numleaffaces = bsp2rmq->nummarksurfaces; - mbsp->numsurfedges = bsp2rmq->numsurfedges; - - // copy or convert data - mbsp->dmodels = BSP29_CopyModels(bsp2rmq->dmodels, bsp2rmq->nummodels); - mbsp->dvisdata = BSP29_CopyVisData(bsp2rmq->dvisdata, bsp2rmq->visdatasize); - mbsp->dlightdata = BSP29_CopyLightData(bsp2rmq->dlightdata, bsp2rmq->lightdatasize); - mbsp->dtexdata = BSP29_CopyTexData(bsp2rmq->dtexdata, bsp2rmq->texdatasize); - mbsp->dentdata = BSP29_CopyEntData(bsp2rmq->dentdata, bsp2rmq->entdatasize); - mbsp->dleafs = BSP2rmqtoM_Leafs(bsp2rmq->dleafs, bsp2rmq->numleafs); - mbsp->dplanes = BSP29_CopyPlanes(bsp2rmq->dplanes, bsp2rmq->numplanes); - mbsp->dvertexes = BSP29_CopyVertexes(bsp2rmq->dvertexes, bsp2rmq->numvertexes); - mbsp->dnodes = BSP2rmqto2_Nodes(bsp2rmq->dnodes, bsp2rmq->numnodes); - mbsp->texinfo = BSP29toM_Texinfo(bsp2rmq->texinfo, bsp2rmq->numtexinfo); - mbsp->dfaces = BSP2_CopyFaces(bsp2rmq->dfaces, bsp2rmq->numfaces); - mbsp->dclipnodes = BSP2_CopyClipnodes(bsp2rmq->dclipnodes, bsp2rmq->numclipnodes); - mbsp->dedges = BSP2_CopyEdges(bsp2rmq->dedges, bsp2rmq->numedges); - mbsp->dleaffaces = BSP2_CopyMarksurfaces(bsp2rmq->dmarksurfaces, bsp2rmq->nummarksurfaces); - mbsp->dsurfedges = BSP29_CopySurfedges(bsp2rmq->dsurfedges, bsp2rmq->numsurfedges); - - /* Free old data */ - FreeBSP2RMQ((bsp2rmq_t *)bsp2rmq); - - /* Conversion complete! */ - mbsp->loadversion = bspdata->version; - bspdata->version = version; - - return; - } - - if (bspdata->version == BSP2VERSION && version == GENERIC_BSP) { - const bsp2_t *bsp2 = &bspdata->data.bsp2; - mbsp_t *mbsp = &bspdata->data.mbsp; - - memset(mbsp, 0, sizeof(*mbsp)); - - // copy counts - mbsp->nummodels = bsp2->nummodels; - mbsp->visdatasize = bsp2->visdatasize; - mbsp->lightdatasize = bsp2->lightdatasize; - mbsp->texdatasize = bsp2->texdatasize; - mbsp->entdatasize = bsp2->entdatasize; - mbsp->numleafs = bsp2->numleafs; - mbsp->numplanes = bsp2->numplanes; - mbsp->numvertexes = bsp2->numvertexes; - mbsp->numnodes = bsp2->numnodes; - mbsp->numtexinfo = bsp2->numtexinfo; - mbsp->numfaces = bsp2->numfaces; - mbsp->numclipnodes = bsp2->numclipnodes; - mbsp->numedges = bsp2->numedges; - mbsp->numleaffaces = bsp2->nummarksurfaces; - mbsp->numsurfedges = bsp2->numsurfedges; - - // copy or convert data - mbsp->dmodels = BSP29_CopyModels(bsp2->dmodels, bsp2->nummodels); - mbsp->dvisdata = BSP29_CopyVisData(bsp2->dvisdata, bsp2->visdatasize); - mbsp->dlightdata = BSP29_CopyLightData(bsp2->dlightdata, bsp2->lightdatasize); - mbsp->dtexdata = BSP29_CopyTexData(bsp2->dtexdata, bsp2->texdatasize); - mbsp->dentdata = BSP29_CopyEntData(bsp2->dentdata, bsp2->entdatasize); - mbsp->dleafs = BSP2toM_Leafs(bsp2->dleafs, bsp2->numleafs); - mbsp->dplanes = BSP29_CopyPlanes(bsp2->dplanes, bsp2->numplanes); - mbsp->dvertexes = BSP29_CopyVertexes(bsp2->dvertexes, bsp2->numvertexes); - mbsp->dnodes = BSP2_CopyNodes(bsp2->dnodes, bsp2->numnodes); - mbsp->texinfo = BSP29toM_Texinfo(bsp2->texinfo, bsp2->numtexinfo); - mbsp->dfaces = BSP2_CopyFaces(bsp2->dfaces, bsp2->numfaces); - mbsp->dclipnodes = BSP2_CopyClipnodes(bsp2->dclipnodes, bsp2->numclipnodes); - mbsp->dedges = BSP2_CopyEdges(bsp2->dedges, bsp2->numedges); - mbsp->dleaffaces = BSP2_CopyMarksurfaces(bsp2->dmarksurfaces, bsp2->nummarksurfaces); - mbsp->dsurfedges = BSP29_CopySurfedges(bsp2->dsurfedges, bsp2->numsurfedges); - - /* Free old data */ - FreeBSP2((bsp2_t *)bsp2); - - /* Conversion complete! */ - mbsp->loadversion = bspdata->version; - bspdata->version = version; + /* Conversion complete! */ + ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata); - return; - } + return; + } else if (bspdata->version == &bspver_qbism) { + const q2bsp_qbism_t *q2bsp = &bspdata->data.q2bsp_qbism; + mbsp_t *mbsp = &bspdata->data.mbsp; + + memset(mbsp, 0, sizeof(*mbsp)); + + // copy counts + mbsp->nummodels = q2bsp->nummodels; + mbsp->visdatasize = q2bsp->visdatasize; + mbsp->lightdatasize = q2bsp->lightdatasize; + mbsp->entdatasize = q2bsp->entdatasize; + mbsp->numleafs = q2bsp->numleafs; + mbsp->numplanes = q2bsp->numplanes; + mbsp->numvertexes = q2bsp->numvertexes; + mbsp->numnodes = q2bsp->numnodes; + mbsp->numtexinfo = q2bsp->numtexinfo; + mbsp->numfaces = q2bsp->numfaces; + mbsp->numedges = q2bsp->numedges; + mbsp->numleaffaces = q2bsp->numleaffaces; + mbsp->numleafbrushes = q2bsp->numleafbrushes; + mbsp->numsurfedges = q2bsp->numsurfedges; + mbsp->numareas = q2bsp->numareas; + mbsp->numareaportals = q2bsp->numareaportals; + mbsp->numbrushes = q2bsp->numbrushes; + mbsp->numbrushsides = q2bsp->numbrushsides; + + // copy or convert data + mbsp->dmodels = Q2BSPtoM_Models(q2bsp->dmodels, q2bsp->nummodels); + mbsp->dvisdata = (uint8_t *)CopyArray(q2bsp->dvis, q2bsp->visdatasize, 1); + mbsp->dlightdata = BSP29_CopyLightData(q2bsp->dlightdata, q2bsp->lightdatasize); + mbsp->dentdata = BSP29_CopyEntData(q2bsp->dentdata, q2bsp->entdatasize); + mbsp->dleafs = Q2BSP_QBSPtoM_Leafs(q2bsp->dleafs, q2bsp->numleafs); + mbsp->dplanes = BSP29_CopyPlanes(q2bsp->dplanes, q2bsp->numplanes); + mbsp->dvertexes = BSP29_CopyVertexes(q2bsp->dvertexes, q2bsp->numvertexes); + mbsp->dnodes = BSP2_CopyNodes(q2bsp->dnodes, q2bsp->numnodes); + mbsp->texinfo = Q2BSPtoM_Texinfo(q2bsp->texinfo, q2bsp->numtexinfo); + mbsp->dfaces = Q2BSP_QBSPto2_Faces(q2bsp->dfaces, q2bsp->numfaces); + mbsp->dedges = BSP2_CopyEdges(q2bsp->dedges, q2bsp->numedges); + mbsp->dleaffaces = BSP2_CopyMarksurfaces(q2bsp->dleaffaces, q2bsp->numleaffaces); + mbsp->dleafbrushes = Q2BSP_Qbism_CopyLeafBrushes(q2bsp->dleafbrushes, q2bsp->numleafbrushes); + mbsp->dsurfedges = BSP29_CopySurfedges(q2bsp->dsurfedges, q2bsp->numsurfedges); + + mbsp->dareas = Q2BSP_CopyAreas(q2bsp->dareas, q2bsp->numareas); + mbsp->dareaportals = Q2BSP_CopyAreaPortals(q2bsp->dareaportals, q2bsp->numareaportals); + + mbsp->dbrushes = Q2BSP_CopyBrushes(q2bsp->dbrushes, q2bsp->numbrushes); + mbsp->dbrushsides = Q2BSP_Qbism_CopyBrushSides(q2bsp->dbrushsides, q2bsp->numbrushsides); + + /* Free old data */ + FreeQ2BSP_QBSP((q2bsp_qbism_t *)q2bsp); + + /* Conversion complete! */ + ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata); + + return; + } + else if (bspdata->version == &bspver_bsp2rmq) { + const bsp2rmq_t *bsp2rmq = &bspdata->data.bsp2rmq; + mbsp_t *mbsp = &bspdata->data.mbsp; + + memset(mbsp, 0, sizeof(*mbsp)); + + // copy counts + mbsp->nummodels = bsp2rmq->nummodels; + mbsp->visdatasize = bsp2rmq->visdatasize; + mbsp->lightdatasize = bsp2rmq->lightdatasize; + mbsp->texdatasize = bsp2rmq->texdatasize; + mbsp->entdatasize = bsp2rmq->entdatasize; + mbsp->numleafs = bsp2rmq->numleafs; + mbsp->numplanes = bsp2rmq->numplanes; + mbsp->numvertexes = bsp2rmq->numvertexes; + mbsp->numnodes = bsp2rmq->numnodes; + mbsp->numtexinfo = bsp2rmq->numtexinfo; + mbsp->numfaces = bsp2rmq->numfaces; + mbsp->numclipnodes = bsp2rmq->numclipnodes; + mbsp->numedges = bsp2rmq->numedges; + mbsp->numleaffaces = bsp2rmq->nummarksurfaces; + mbsp->numsurfedges = bsp2rmq->numsurfedges; + + // copy or convert data + mbsp->dmodels = BSP29_CopyModels(bsp2rmq->dmodels, bsp2rmq->nummodels); + mbsp->dvisdata = BSP29_CopyVisData(bsp2rmq->dvisdata, bsp2rmq->visdatasize); + mbsp->dlightdata = BSP29_CopyLightData(bsp2rmq->dlightdata, bsp2rmq->lightdatasize); + mbsp->dtexdata = BSP29_CopyTexData(bsp2rmq->dtexdata, bsp2rmq->texdatasize); + mbsp->dentdata = BSP29_CopyEntData(bsp2rmq->dentdata, bsp2rmq->entdatasize); + mbsp->dleafs = BSP2rmqtoM_Leafs(bsp2rmq->dleafs, bsp2rmq->numleafs); + mbsp->dplanes = BSP29_CopyPlanes(bsp2rmq->dplanes, bsp2rmq->numplanes); + mbsp->dvertexes = BSP29_CopyVertexes(bsp2rmq->dvertexes, bsp2rmq->numvertexes); + mbsp->dnodes = BSP2rmqto2_Nodes(bsp2rmq->dnodes, bsp2rmq->numnodes); + mbsp->texinfo = BSP29toM_Texinfo(bsp2rmq->texinfo, bsp2rmq->numtexinfo); + mbsp->dfaces = BSP2_CopyFaces(bsp2rmq->dfaces, bsp2rmq->numfaces); + mbsp->dclipnodes = BSP2_CopyClipnodes(bsp2rmq->dclipnodes, bsp2rmq->numclipnodes); + mbsp->dedges = BSP2_CopyEdges(bsp2rmq->dedges, bsp2rmq->numedges); + mbsp->dleaffaces = BSP2_CopyMarksurfaces(bsp2rmq->dmarksurfaces, bsp2rmq->nummarksurfaces); + mbsp->dsurfedges = BSP29_CopySurfedges(bsp2rmq->dsurfedges, bsp2rmq->numsurfedges); + + /* Free old data */ + FreeBSP2RMQ((bsp2rmq_t *)bsp2rmq); + + /* Conversion complete! */ + ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata); + + return; + } + + else if (bspdata->version == &bspver_bsp2) { + const bsp2_t *bsp2 = &bspdata->data.bsp2; + mbsp_t *mbsp = &bspdata->data.mbsp; + + memset(mbsp, 0, sizeof(*mbsp)); + + // copy counts + mbsp->nummodels = bsp2->nummodels; + mbsp->visdatasize = bsp2->visdatasize; + mbsp->lightdatasize = bsp2->lightdatasize; + mbsp->texdatasize = bsp2->texdatasize; + mbsp->entdatasize = bsp2->entdatasize; + mbsp->numleafs = bsp2->numleafs; + mbsp->numplanes = bsp2->numplanes; + mbsp->numvertexes = bsp2->numvertexes; + mbsp->numnodes = bsp2->numnodes; + mbsp->numtexinfo = bsp2->numtexinfo; + mbsp->numfaces = bsp2->numfaces; + mbsp->numclipnodes = bsp2->numclipnodes; + mbsp->numedges = bsp2->numedges; + mbsp->numleaffaces = bsp2->nummarksurfaces; + mbsp->numsurfedges = bsp2->numsurfedges; + + // copy or convert data + mbsp->dmodels = BSP29_CopyModels(bsp2->dmodels, bsp2->nummodels); + mbsp->dvisdata = BSP29_CopyVisData(bsp2->dvisdata, bsp2->visdatasize); + mbsp->dlightdata = BSP29_CopyLightData(bsp2->dlightdata, bsp2->lightdatasize); + mbsp->dtexdata = BSP29_CopyTexData(bsp2->dtexdata, bsp2->texdatasize); + mbsp->dentdata = BSP29_CopyEntData(bsp2->dentdata, bsp2->entdatasize); + mbsp->dleafs = BSP2toM_Leafs(bsp2->dleafs, bsp2->numleafs); + mbsp->dplanes = BSP29_CopyPlanes(bsp2->dplanes, bsp2->numplanes); + mbsp->dvertexes = BSP29_CopyVertexes(bsp2->dvertexes, bsp2->numvertexes); + mbsp->dnodes = BSP2_CopyNodes(bsp2->dnodes, bsp2->numnodes); + mbsp->texinfo = BSP29toM_Texinfo(bsp2->texinfo, bsp2->numtexinfo); + mbsp->dfaces = BSP2_CopyFaces(bsp2->dfaces, bsp2->numfaces); + mbsp->dclipnodes = BSP2_CopyClipnodes(bsp2->dclipnodes, bsp2->numclipnodes); + mbsp->dedges = BSP2_CopyEdges(bsp2->dedges, bsp2->numedges); + mbsp->dleaffaces = BSP2_CopyMarksurfaces(bsp2->dmarksurfaces, bsp2->nummarksurfaces); + mbsp->dsurfedges = BSP29_CopySurfedges(bsp2->dsurfedges, bsp2->numsurfedges); + + /* Free old data */ + FreeBSP2((bsp2_t *)bsp2); + + /* Conversion complete! */ + ConvertBSPToMFormatComplete(&mbsp->loadversion, to_version, bspdata); + + return; + } + } // conversions from GENERIC_BSP + else if (bspdata->version == &bspver_generic) { + if (to_version == &bspver_q1 || to_version == &bspver_h2 || to_version == &bspver_hl) { + bsp29_t *bsp29 = &bspdata->data.bsp29; + const mbsp_t *mbsp = &bspdata->data.mbsp; + + memset(bsp29, 0, sizeof(*bsp29)); + + // copy counts + bsp29->nummodels = mbsp->nummodels; + bsp29->visdatasize = mbsp->visdatasize; + bsp29->lightdatasize = mbsp->lightdatasize; + bsp29->texdatasize = mbsp->texdatasize; + bsp29->entdatasize = mbsp->entdatasize; + bsp29->numleafs = mbsp->numleafs; + bsp29->numplanes = mbsp->numplanes; + bsp29->numvertexes = mbsp->numvertexes; + bsp29->numnodes = mbsp->numnodes; + bsp29->numtexinfo = mbsp->numtexinfo; + bsp29->numfaces = mbsp->numfaces; + bsp29->numclipnodes = mbsp->numclipnodes; + bsp29->numedges = mbsp->numedges; + bsp29->nummarksurfaces = mbsp->numleaffaces; + bsp29->numsurfedges = mbsp->numsurfedges; + + // copy or convert data + bsp29->dmodels = BSP29_CopyModels(mbsp->dmodels, mbsp->nummodels); + bsp29->dvisdata = BSP29_CopyVisData(mbsp->dvisdata, mbsp->visdatasize); + bsp29->dlightdata = BSP29_CopyLightData(mbsp->dlightdata, mbsp->lightdatasize); + bsp29->dtexdata = BSP29_CopyTexData(mbsp->dtexdata, mbsp->texdatasize); + bsp29->dentdata = BSP29_CopyEntData(mbsp->dentdata, mbsp->entdatasize); + bsp29->dleafs = MBSPto29_Leafs(mbsp->dleafs, mbsp->numleafs); + bsp29->dplanes = BSP29_CopyPlanes(mbsp->dplanes, mbsp->numplanes); + bsp29->dvertexes = BSP29_CopyVertexes(mbsp->dvertexes, mbsp->numvertexes); + bsp29->dnodes = BSP2to29_Nodes(mbsp->dnodes, mbsp->numnodes); + bsp29->texinfo = MBSPto29_Texinfo(mbsp->texinfo, mbsp->numtexinfo); + bsp29->dfaces = BSP2to29_Faces(mbsp->dfaces, mbsp->numfaces); + bsp29->dclipnodes = BSP2to29_Clipnodes(mbsp->dclipnodes, mbsp->numclipnodes); + bsp29->dedges = BSP2to29_Edges(mbsp->dedges, mbsp->numedges); + bsp29->dmarksurfaces = BSP2to29_Marksurfaces(mbsp->dleaffaces, mbsp->numleaffaces); + bsp29->dsurfedges = BSP29_CopySurfedges(mbsp->dsurfedges, mbsp->numsurfedges); + + /* Free old data */ + FreeMBSP((mbsp_t *)mbsp); + + /* Conversion complete! */ + bspdata->version = to_version; + + return; + } - if (bspdata->version == GENERIC_BSP && (version == BSPVERSION || version == BSPHLVERSION)) { - bsp29_t *bsp29 = &bspdata->data.bsp29; - const mbsp_t *mbsp = &bspdata->data.mbsp; + else if (to_version == &bspver_q2) { + const mbsp_t *mbsp = &bspdata->data.mbsp; + q2bsp_t *q2bsp = &bspdata->data.q2bsp; - memset(bsp29, 0, sizeof(*bsp29)); + memset(q2bsp, 0, sizeof(*q2bsp)); - // copy counts - bsp29->nummodels = mbsp->nummodels; - bsp29->visdatasize = mbsp->visdatasize; - bsp29->lightdatasize = mbsp->lightdatasize; - bsp29->texdatasize = mbsp->texdatasize; - bsp29->entdatasize = mbsp->entdatasize; - bsp29->numleafs = mbsp->numleafs; - bsp29->numplanes = mbsp->numplanes; - bsp29->numvertexes = mbsp->numvertexes; - bsp29->numnodes = mbsp->numnodes; - bsp29->numtexinfo = mbsp->numtexinfo; - bsp29->numfaces = mbsp->numfaces; - bsp29->numclipnodes = mbsp->numclipnodes; - bsp29->numedges = mbsp->numedges; - bsp29->nummarksurfaces = mbsp->numleaffaces; - bsp29->numsurfedges = mbsp->numsurfedges; + // copy counts + q2bsp->nummodels = mbsp->nummodels; + q2bsp->visdatasize = mbsp->visdatasize; + q2bsp->lightdatasize = mbsp->lightdatasize; + q2bsp->entdatasize = mbsp->entdatasize; + q2bsp->numleafs = mbsp->numleafs; + q2bsp->numplanes = mbsp->numplanes; + q2bsp->numvertexes = mbsp->numvertexes; + q2bsp->numnodes = mbsp->numnodes; + q2bsp->numtexinfo = mbsp->numtexinfo; + q2bsp->numfaces = mbsp->numfaces; + q2bsp->numedges = mbsp->numedges; + q2bsp->numleaffaces = mbsp->numleaffaces; + q2bsp->numleafbrushes = mbsp->numleafbrushes; + q2bsp->numsurfedges = mbsp->numsurfedges; + q2bsp->numareas = mbsp->numareas; + q2bsp->numareaportals = mbsp->numareaportals; + q2bsp->numbrushes = mbsp->numbrushes; + q2bsp->numbrushsides = mbsp->numbrushsides; - // copy or convert data - bsp29->dmodels = BSP29_CopyModels(mbsp->dmodels, mbsp->nummodels); - bsp29->dvisdata = BSP29_CopyVisData(mbsp->dvisdata, mbsp->visdatasize); - bsp29->dlightdata = BSP29_CopyLightData(mbsp->dlightdata, mbsp->lightdatasize); - bsp29->dtexdata = BSP29_CopyTexData(mbsp->dtexdata, mbsp->texdatasize); - bsp29->dentdata = BSP29_CopyEntData(mbsp->dentdata, mbsp->entdatasize); - bsp29->dleafs = MBSPto29_Leafs(mbsp->dleafs, mbsp->numleafs); - bsp29->dplanes = BSP29_CopyPlanes(mbsp->dplanes, mbsp->numplanes); - bsp29->dvertexes = BSP29_CopyVertexes(mbsp->dvertexes, mbsp->numvertexes); - bsp29->dnodes = BSP2to29_Nodes(mbsp->dnodes, mbsp->numnodes); - bsp29->texinfo = MBSPto29_Texinfo(mbsp->texinfo, mbsp->numtexinfo); - bsp29->dfaces = BSP2to29_Faces(mbsp->dfaces, mbsp->numfaces); - bsp29->dclipnodes = BSP2to29_Clipnodes(mbsp->dclipnodes, mbsp->numclipnodes); - bsp29->dedges = BSP2to29_Edges(mbsp->dedges, mbsp->numedges); - bsp29->dmarksurfaces = BSP2to29_Marksurfaces(mbsp->dleaffaces, mbsp->numleaffaces); - bsp29->dsurfedges = BSP29_CopySurfedges(mbsp->dsurfedges, mbsp->numsurfedges); + // copy or convert data + q2bsp->dmodels = MBSPtoQ2_Models(mbsp->dmodels, mbsp->nummodels); + q2bsp->dvis = (dvis_t *)CopyArray(mbsp->dvisdata, mbsp->visdatasize, 1); + q2bsp->dlightdata = BSP29_CopyLightData(mbsp->dlightdata, mbsp->lightdatasize); + q2bsp->dentdata = BSP29_CopyEntData(mbsp->dentdata, mbsp->entdatasize); + q2bsp->dleafs = MBSPtoQ2_Leafs(mbsp->dleafs, mbsp->numleafs); + q2bsp->dplanes = BSP29_CopyPlanes(mbsp->dplanes, mbsp->numplanes); + q2bsp->dvertexes = BSP29_CopyVertexes(mbsp->dvertexes, mbsp->numvertexes); + q2bsp->dnodes = BSP2toQ2_Nodes(mbsp->dnodes, mbsp->numnodes); + q2bsp->texinfo = MBSPtoQ2_Texinfo(mbsp->texinfo, mbsp->numtexinfo); + q2bsp->dfaces = BSP2toQ2_Faces(mbsp->dfaces, mbsp->numfaces); + q2bsp->dedges = BSP2to29_Edges(mbsp->dedges, mbsp->numedges); + q2bsp->dleaffaces = BSP2to29_Marksurfaces(mbsp->dleaffaces, mbsp->numleaffaces); + q2bsp->dleafbrushes = MBSPtoQ2_CopyLeafBrushes(mbsp->dleafbrushes, mbsp->numleafbrushes); + q2bsp->dsurfedges = BSP29_CopySurfedges(mbsp->dsurfedges, mbsp->numsurfedges); - /* Free old data */ - FreeMBSP((mbsp_t *)mbsp); + q2bsp->dareas = Q2BSP_CopyAreas(mbsp->dareas, mbsp->numareas); + q2bsp->dareaportals = Q2BSP_CopyAreaPortals(mbsp->dareaportals, mbsp->numareaportals); - /* Conversion complete! */ - bspdata->version = version; + q2bsp->dbrushes = Q2BSP_CopyBrushes(mbsp->dbrushes, mbsp->numbrushes); + q2bsp->dbrushsides = MBSPtoQ2_CopyBrushSides(mbsp->dbrushsides, mbsp->numbrushsides); - return; - } + /* Free old data */ + FreeMBSP((mbsp_t *)mbsp); + + /* Conversion complete! */ + bspdata->version = to_version; + + return; + } else if (to_version == &bspver_qbism) { + const mbsp_t *mbsp = &bspdata->data.mbsp; + q2bsp_qbism_t *q2bsp = &bspdata->data.q2bsp_qbism; + + memset(q2bsp, 0, sizeof(*q2bsp)); + + // copy counts + q2bsp->nummodels = mbsp->nummodels; + q2bsp->visdatasize = mbsp->visdatasize; + q2bsp->lightdatasize = mbsp->lightdatasize; + q2bsp->entdatasize = mbsp->entdatasize; + q2bsp->numleafs = mbsp->numleafs; + q2bsp->numplanes = mbsp->numplanes; + q2bsp->numvertexes = mbsp->numvertexes; + q2bsp->numnodes = mbsp->numnodes; + q2bsp->numtexinfo = mbsp->numtexinfo; + q2bsp->numfaces = mbsp->numfaces; + q2bsp->numedges = mbsp->numedges; + q2bsp->numleaffaces = mbsp->numleaffaces; + q2bsp->numleafbrushes = mbsp->numleafbrushes; + q2bsp->numsurfedges = mbsp->numsurfedges; + q2bsp->numareas = mbsp->numareas; + q2bsp->numareaportals = mbsp->numareaportals; + q2bsp->numbrushes = mbsp->numbrushes; + q2bsp->numbrushsides = mbsp->numbrushsides; + + // copy or convert data + q2bsp->dmodels = MBSPtoQ2_Models(mbsp->dmodels, mbsp->nummodels); + q2bsp->dvis = (dvis_t *)CopyArray(mbsp->dvisdata, mbsp->visdatasize, 1); + q2bsp->dlightdata = BSP29_CopyLightData(mbsp->dlightdata, mbsp->lightdatasize); + q2bsp->dentdata = BSP29_CopyEntData(mbsp->dentdata, mbsp->entdatasize); + q2bsp->dleafs = MBSPtoQ2_Qbism_Leafs(mbsp->dleafs, mbsp->numleafs); + q2bsp->dplanes = BSP29_CopyPlanes(mbsp->dplanes, mbsp->numplanes); + q2bsp->dvertexes = BSP29_CopyVertexes(mbsp->dvertexes, mbsp->numvertexes); + q2bsp->dnodes = BSP2_CopyNodes(mbsp->dnodes, mbsp->numnodes); + q2bsp->texinfo = MBSPtoQ2_Texinfo(mbsp->texinfo, mbsp->numtexinfo); + q2bsp->dfaces = BSP2toQ2_Qbism_Faces(mbsp->dfaces, mbsp->numfaces); + q2bsp->dedges = BSP2_CopyEdges(mbsp->dedges, mbsp->numedges); + q2bsp->dleaffaces = BSP2_CopyMarksurfaces(mbsp->dleaffaces, mbsp->numleaffaces); + q2bsp->dleafbrushes = Q2BSP_Qbism_CopyLeafBrushes(mbsp->dleafbrushes, mbsp->numleafbrushes); + q2bsp->dsurfedges = BSP29_CopySurfedges(mbsp->dsurfedges, mbsp->numsurfedges); + + q2bsp->dareas = Q2BSP_CopyAreas(mbsp->dareas, mbsp->numareas); + q2bsp->dareaportals = Q2BSP_CopyAreaPortals(mbsp->dareaportals, mbsp->numareaportals); + + q2bsp->dbrushes = Q2BSP_CopyBrushes(mbsp->dbrushes, mbsp->numbrushes); + q2bsp->dbrushsides = Q2BSP_Qbism_CopyBrushSides(mbsp->dbrushsides, mbsp->numbrushsides); + + /* Free old data */ + FreeMBSP((mbsp_t *)mbsp); + + /* Conversion complete! */ + bspdata->version = to_version; + + return; + } - if (bspdata->version == GENERIC_BSP && version == Q2_BSPVERSION) { - const mbsp_t *mbsp = &bspdata->data.mbsp; - q2bsp_t *q2bsp = &bspdata->data.q2bsp; + else if (to_version == &bspver_bsp2rmq) { + bsp2rmq_t *bsp2rmq = &bspdata->data.bsp2rmq; + const mbsp_t *mbsp = &bspdata->data.mbsp; - memset(q2bsp, 0, sizeof(*q2bsp)); + memset(bsp2rmq, 0, sizeof(*bsp2rmq)); - // copy counts - q2bsp->nummodels = mbsp->nummodels; - q2bsp->visdatasize = mbsp->visdatasize; - q2bsp->lightdatasize = mbsp->lightdatasize; - q2bsp->entdatasize = mbsp->entdatasize; - q2bsp->numleafs = mbsp->numleafs; - q2bsp->numplanes = mbsp->numplanes; - q2bsp->numvertexes = mbsp->numvertexes; - q2bsp->numnodes = mbsp->numnodes; - q2bsp->numtexinfo = mbsp->numtexinfo; - q2bsp->numfaces = mbsp->numfaces; - q2bsp->numedges = mbsp->numedges; - q2bsp->numleaffaces = mbsp->numleaffaces; - q2bsp->numleafbrushes = mbsp->numleafbrushes; - q2bsp->numsurfedges = mbsp->numsurfedges; - q2bsp->numareas = mbsp->numareas; - q2bsp->numareaportals = mbsp->numareaportals; - q2bsp->numbrushes = mbsp->numbrushes; - q2bsp->numbrushsides = mbsp->numbrushsides; + // copy counts + bsp2rmq->nummodels = mbsp->nummodels; + bsp2rmq->visdatasize = mbsp->visdatasize; + bsp2rmq->lightdatasize = mbsp->lightdatasize; + bsp2rmq->texdatasize = mbsp->texdatasize; + bsp2rmq->entdatasize = mbsp->entdatasize; + bsp2rmq->numleafs = mbsp->numleafs; + bsp2rmq->numplanes = mbsp->numplanes; + bsp2rmq->numvertexes = mbsp->numvertexes; + bsp2rmq->numnodes = mbsp->numnodes; + bsp2rmq->numtexinfo = mbsp->numtexinfo; + bsp2rmq->numfaces = mbsp->numfaces; + bsp2rmq->numclipnodes = mbsp->numclipnodes; + bsp2rmq->numedges = mbsp->numedges; + bsp2rmq->nummarksurfaces = mbsp->numleaffaces; + bsp2rmq->numsurfedges = mbsp->numsurfedges; - // copy or convert data - q2bsp->dmodels = MBSPtoQ2_Models(mbsp->dmodels, mbsp->nummodels); - q2bsp->dvis = (dvis_t *)CopyArray(mbsp->dvisdata, mbsp->visdatasize, 1); - q2bsp->dlightdata = BSP29_CopyLightData(mbsp->dlightdata, mbsp->lightdatasize); - q2bsp->dentdata = BSP29_CopyEntData(mbsp->dentdata, mbsp->entdatasize); - q2bsp->dleafs = MBSPtoQ2_Leafs(mbsp->dleafs, mbsp->numleafs); - q2bsp->dplanes = BSP29_CopyPlanes(mbsp->dplanes, mbsp->numplanes); - q2bsp->dvertexes = BSP29_CopyVertexes(mbsp->dvertexes, mbsp->numvertexes); - q2bsp->dnodes = BSP2toQ2_Nodes(mbsp->dnodes, mbsp->numnodes); - q2bsp->texinfo = MBSPtoQ2_Texinfo(mbsp->texinfo, mbsp->numtexinfo); - q2bsp->dfaces = BSP2toQ2_Faces(mbsp->dfaces, mbsp->numfaces); - q2bsp->dedges = BSP2to29_Edges(mbsp->dedges, mbsp->numedges); - q2bsp->dleaffaces = BSP2to29_Marksurfaces(mbsp->dleaffaces, mbsp->numleaffaces); - q2bsp->dleafbrushes = Q2BSP_CopyLeafBrushes(mbsp->dleafbrushes, mbsp->numleafbrushes); - q2bsp->dsurfedges = BSP29_CopySurfedges(mbsp->dsurfedges, mbsp->numsurfedges); + // copy or convert data + bsp2rmq->dmodels = BSP29_CopyModels(mbsp->dmodels, mbsp->nummodels); + bsp2rmq->dvisdata = BSP29_CopyVisData(mbsp->dvisdata, mbsp->visdatasize); + bsp2rmq->dlightdata = BSP29_CopyLightData(mbsp->dlightdata, mbsp->lightdatasize); + bsp2rmq->dtexdata = BSP29_CopyTexData(mbsp->dtexdata, mbsp->texdatasize); + bsp2rmq->dentdata = BSP29_CopyEntData(mbsp->dentdata, mbsp->entdatasize); + bsp2rmq->dleafs = MBSPto2rmq_Leafs(mbsp->dleafs, mbsp->numleafs); + bsp2rmq->dplanes = BSP29_CopyPlanes(mbsp->dplanes, mbsp->numplanes); + bsp2rmq->dvertexes = BSP29_CopyVertexes(mbsp->dvertexes, mbsp->numvertexes); + bsp2rmq->dnodes = BSP2to2rmq_Nodes(mbsp->dnodes, mbsp->numnodes); + bsp2rmq->texinfo = MBSPto29_Texinfo(mbsp->texinfo, mbsp->numtexinfo); + bsp2rmq->dfaces = BSP2_CopyFaces(mbsp->dfaces, mbsp->numfaces); + bsp2rmq->dclipnodes = BSP2_CopyClipnodes(mbsp->dclipnodes, mbsp->numclipnodes); + bsp2rmq->dedges = BSP2_CopyEdges(mbsp->dedges, mbsp->numedges); + bsp2rmq->dmarksurfaces = BSP2_CopyMarksurfaces(mbsp->dleaffaces, mbsp->numleaffaces); + bsp2rmq->dsurfedges = BSP29_CopySurfedges(mbsp->dsurfedges, mbsp->numsurfedges); - q2bsp->dareas = Q2BSP_CopyAreas(mbsp->dareas, mbsp->numareas); - q2bsp->dareaportals = Q2BSP_CopyAreaPortals(mbsp->dareaportals, mbsp->numareaportals); + /* Free old data */ + FreeMBSP((mbsp_t *)mbsp); - q2bsp->dbrushes = Q2BSP_CopyBrushes(mbsp->dbrushes, mbsp->numbrushes); - q2bsp->dbrushsides = Q2BSP_CopyBrushSides(mbsp->dbrushsides, mbsp->numbrushsides); + /* Conversion complete! */ + bspdata->version = to_version; - /* Free old data */ - FreeMBSP((mbsp_t *)mbsp); - - /* Conversion complete! */ - bspdata->version = version; - - return; - } + return; + } - if (bspdata->version == GENERIC_BSP && version == BSP2RMQVERSION) { - bsp2rmq_t *bsp2rmq = &bspdata->data.bsp2rmq; - const mbsp_t *mbsp = &bspdata->data.mbsp; + else if (to_version == &bspver_bsp2) { + bsp2_t *bsp2 = &bspdata->data.bsp2; + const mbsp_t *mbsp = &bspdata->data.mbsp; - memset(bsp2rmq, 0, sizeof(*bsp2rmq)); + memset(bsp2, 0, sizeof(*bsp2)); - // copy counts - bsp2rmq->nummodels = mbsp->nummodels; - bsp2rmq->visdatasize = mbsp->visdatasize; - bsp2rmq->lightdatasize = mbsp->lightdatasize; - bsp2rmq->texdatasize = mbsp->texdatasize; - bsp2rmq->entdatasize = mbsp->entdatasize; - bsp2rmq->numleafs = mbsp->numleafs; - bsp2rmq->numplanes = mbsp->numplanes; - bsp2rmq->numvertexes = mbsp->numvertexes; - bsp2rmq->numnodes = mbsp->numnodes; - bsp2rmq->numtexinfo = mbsp->numtexinfo; - bsp2rmq->numfaces = mbsp->numfaces; - bsp2rmq->numclipnodes = mbsp->numclipnodes; - bsp2rmq->numedges = mbsp->numedges; - bsp2rmq->nummarksurfaces = mbsp->numleaffaces; - bsp2rmq->numsurfedges = mbsp->numsurfedges; + // copy counts + bsp2->nummodels = mbsp->nummodels; + bsp2->visdatasize = mbsp->visdatasize; + bsp2->lightdatasize = mbsp->lightdatasize; + bsp2->texdatasize = mbsp->texdatasize; + bsp2->entdatasize = mbsp->entdatasize; + bsp2->numleafs = mbsp->numleafs; + bsp2->numplanes = mbsp->numplanes; + bsp2->numvertexes = mbsp->numvertexes; + bsp2->numnodes = mbsp->numnodes; + bsp2->numtexinfo = mbsp->numtexinfo; + bsp2->numfaces = mbsp->numfaces; + bsp2->numclipnodes = mbsp->numclipnodes; + bsp2->numedges = mbsp->numedges; + bsp2->nummarksurfaces = mbsp->numleaffaces; + bsp2->numsurfedges = mbsp->numsurfedges; - // copy or convert data - bsp2rmq->dmodels = BSP29_CopyModels(mbsp->dmodels, mbsp->nummodels); - bsp2rmq->dvisdata = BSP29_CopyVisData(mbsp->dvisdata, mbsp->visdatasize); - bsp2rmq->dlightdata = BSP29_CopyLightData(mbsp->dlightdata, mbsp->lightdatasize); - bsp2rmq->dtexdata = BSP29_CopyTexData(mbsp->dtexdata, mbsp->texdatasize); - bsp2rmq->dentdata = BSP29_CopyEntData(mbsp->dentdata, mbsp->entdatasize); - bsp2rmq->dleafs = MBSPto2rmq_Leafs(mbsp->dleafs, mbsp->numleafs); - bsp2rmq->dplanes = BSP29_CopyPlanes(mbsp->dplanes, mbsp->numplanes); - bsp2rmq->dvertexes = BSP29_CopyVertexes(mbsp->dvertexes, mbsp->numvertexes); - bsp2rmq->dnodes = BSP2to2rmq_Nodes(mbsp->dnodes, mbsp->numnodes); - bsp2rmq->texinfo = MBSPto29_Texinfo(mbsp->texinfo, mbsp->numtexinfo); - bsp2rmq->dfaces = BSP2_CopyFaces(mbsp->dfaces, mbsp->numfaces); - bsp2rmq->dclipnodes = BSP2_CopyClipnodes(mbsp->dclipnodes, mbsp->numclipnodes); - bsp2rmq->dedges = BSP2_CopyEdges(mbsp->dedges, mbsp->numedges); - bsp2rmq->dmarksurfaces = BSP2_CopyMarksurfaces(mbsp->dleaffaces, mbsp->numleaffaces); - bsp2rmq->dsurfedges = BSP29_CopySurfedges(mbsp->dsurfedges, mbsp->numsurfedges); + // copy or convert data + bsp2->dmodels = BSP29_CopyModels(mbsp->dmodels, mbsp->nummodels); + bsp2->dvisdata = BSP29_CopyVisData(mbsp->dvisdata, mbsp->visdatasize); + bsp2->dlightdata = BSP29_CopyLightData(mbsp->dlightdata, mbsp->lightdatasize); + bsp2->dtexdata = BSP29_CopyTexData(mbsp->dtexdata, mbsp->texdatasize); + bsp2->dentdata = BSP29_CopyEntData(mbsp->dentdata, mbsp->entdatasize); + bsp2->dleafs = MBSPto2_Leafs(mbsp->dleafs, mbsp->numleafs); + bsp2->dplanes = BSP29_CopyPlanes(mbsp->dplanes, mbsp->numplanes); + bsp2->dvertexes = BSP29_CopyVertexes(mbsp->dvertexes, mbsp->numvertexes); + bsp2->dnodes = BSP2_CopyNodes(mbsp->dnodes, mbsp->numnodes); + bsp2->texinfo = MBSPto29_Texinfo(mbsp->texinfo, mbsp->numtexinfo); + bsp2->dfaces = BSP2_CopyFaces(mbsp->dfaces, mbsp->numfaces); + bsp2->dclipnodes = BSP2_CopyClipnodes(mbsp->dclipnodes, mbsp->numclipnodes); + bsp2->dedges = BSP2_CopyEdges(mbsp->dedges, mbsp->numedges); + bsp2->dmarksurfaces = BSP2_CopyMarksurfaces(mbsp->dleaffaces, mbsp->numleaffaces); + bsp2->dsurfedges = BSP29_CopySurfedges(mbsp->dsurfedges, mbsp->numsurfedges); - /* Free old data */ - FreeMBSP((mbsp_t *)mbsp); + /* Free old data */ + FreeMBSP((mbsp_t *)mbsp); - /* Conversion complete! */ - bspdata->version = version; + /* Conversion complete! */ + bspdata->version = to_version; - return; - } - - if (bspdata->version == GENERIC_BSP && version == BSP2VERSION) { - bsp2_t *bsp2 = &bspdata->data.bsp2; - const mbsp_t *mbsp = &bspdata->data.mbsp; - - memset(bsp2, 0, sizeof(*bsp2)); - - // copy counts - bsp2->nummodels = mbsp->nummodels; - bsp2->visdatasize = mbsp->visdatasize; - bsp2->lightdatasize = mbsp->lightdatasize; - bsp2->texdatasize = mbsp->texdatasize; - bsp2->entdatasize = mbsp->entdatasize; - bsp2->numleafs = mbsp->numleafs; - bsp2->numplanes = mbsp->numplanes; - bsp2->numvertexes = mbsp->numvertexes; - bsp2->numnodes = mbsp->numnodes; - bsp2->numtexinfo = mbsp->numtexinfo; - bsp2->numfaces = mbsp->numfaces; - bsp2->numclipnodes = mbsp->numclipnodes; - bsp2->numedges = mbsp->numedges; - bsp2->nummarksurfaces = mbsp->numleaffaces; - bsp2->numsurfedges = mbsp->numsurfedges; - - // copy or convert data - bsp2->dmodels = BSP29_CopyModels(mbsp->dmodels, mbsp->nummodels); - bsp2->dvisdata = BSP29_CopyVisData(mbsp->dvisdata, mbsp->visdatasize); - bsp2->dlightdata = BSP29_CopyLightData(mbsp->dlightdata, mbsp->lightdatasize); - bsp2->dtexdata = BSP29_CopyTexData(mbsp->dtexdata, mbsp->texdatasize); - bsp2->dentdata = BSP29_CopyEntData(mbsp->dentdata, mbsp->entdatasize); - bsp2->dleafs = MBSPto2_Leafs(mbsp->dleafs, mbsp->numleafs); - bsp2->dplanes = BSP29_CopyPlanes(mbsp->dplanes, mbsp->numplanes); - bsp2->dvertexes = BSP29_CopyVertexes(mbsp->dvertexes, mbsp->numvertexes); - bsp2->dnodes = BSP2_CopyNodes(mbsp->dnodes, mbsp->numnodes); - bsp2->texinfo = MBSPto29_Texinfo(mbsp->texinfo, mbsp->numtexinfo); - bsp2->dfaces = BSP2_CopyFaces(mbsp->dfaces, mbsp->numfaces); - bsp2->dclipnodes = BSP2_CopyClipnodes(mbsp->dclipnodes, mbsp->numclipnodes); - bsp2->dedges = BSP2_CopyEdges(mbsp->dedges, mbsp->numedges); - bsp2->dmarksurfaces = BSP2_CopyMarksurfaces(mbsp->dleaffaces, mbsp->numleaffaces); - bsp2->dsurfedges = BSP29_CopySurfedges(mbsp->dsurfedges, mbsp->numsurfedges); - - /* Free old data */ - FreeMBSP((mbsp_t *)mbsp); - - /* Conversion complete! */ - bspdata->version = version; - - return; + return; + } } Error("Don't know how to convert BSP version %s to %s", - BSPVersionString(bspdata->version), BSPVersionString(version)); + BSPVersionString(bspdata->version), BSPVersionString(to_version)); } static int isHexen2(const dheader_t *header) { - /* + /* the world should always have some face. however, if the sizes are wrong then we're actually reading headnode[6]. hexen2 only used 5 hulls, so this should be 0 in hexen2, and not in quake. - */ - const dmodelq1_t *modelsq1 = (const dmodelq1_t*)((const uint8_t *)header + header->lumps[LUMP_MODELS].fileofs); - return !modelsq1->numfaces; + */ + const dmodelq1_t *modelsq1 = (const dmodelq1_t*)((const uint8_t *)header + header->lumps[LUMP_MODELS].fileofs); + return !modelsq1->numfaces; } /* @@ -2082,8 +2575,30 @@ const lumpspec_t lumpspec_q2bsp[] = { { "areaportals", sizeof(dareaportal_t) }, }; +const lumpspec_t lumpspec_qbism[] = { + { "entities", sizeof(char) }, + { "planes", sizeof(dplane_t) }, + { "vertexes", sizeof(dvertex_t) }, + { "visibility", sizeof(uint8_t) }, + { "nodes", sizeof(q2_dnode_qbism_t) }, + { "texinfos", sizeof(q2_texinfo_t) }, + { "faces", sizeof(q2_dface_qbism_t) }, + { "lighting", sizeof(uint8_t) }, + { "leafs", sizeof(q2_dleaf_qbism_t) }, + { "leaffaces", sizeof(uint32_t) }, + { "leafbrushes", sizeof(uint32_t) }, + { "edges", sizeof(q2_dedge_qbism_t) }, + { "surfedges", sizeof(int32_t) }, + { "models", sizeof(q2_dmodel_t) }, + { "brushes", sizeof(dbrush_t) }, + { "brushsides", sizeof(q2_dbrushside_qbism_t) }, + { "pop", sizeof(uint8_t) }, + { "areas", sizeof(darea_t) }, + { "areaportals", sizeof(dareaportal_t) }, +}; + static int -CopyLump(const dheader_t *header, int lumpnum, void *destptr) +CopyLump(const void *header, const bspversion_t *version, const lump_t *lumps, int lumpnum, void *destptr) { const lumpspec_t *lumpspec; uint8_t **bufferptr = static_cast(destptr); @@ -2091,29 +2606,29 @@ CopyLump(const dheader_t *header, int lumpnum, void *destptr) int length; int ofs; - switch (header->version) { - case BSPVERSION: - case BSPHLVERSION: + if (version == &bspver_q1 || version == &bspver_h2 || version == &bspver_hl) { lumpspec = &lumpspec_bsp29[lumpnum]; - break; - case BSP2RMQVERSION: + } else if (version == &bspver_bsp2rmq) { lumpspec = &lumpspec_bsp2rmq[lumpnum]; - break; - case BSP2VERSION: + } else if (version == &bspver_bsp2) { lumpspec = &lumpspec_bsp2[lumpnum]; - break; - default: - Error("Unsupported BSP version: %d", header->version); + } else if (version == &bspver_q2) { + lumpspec = &lumpspec_q2bsp[lumpnum]; + } else if (version == &bspver_qbism) { + lumpspec = &lumpspec_qbism[lumpnum]; + } else { + Error("Unsupported BSP version: %s", BSPVersionString(version)); throw; //mxd. Fixes "Uninitialized variable" warning } - length = header->lumps[lumpnum].filelen; - ofs = header->lumps[lumpnum].fileofs; + length = lumps[lumpnum].filelen; + ofs = lumps[lumpnum].fileofs; if (buffer) free(buffer); - if (lumpnum == LUMP_MODELS && !isHexen2(header)) + // convert non-Hexen II BSP model hulls over to Hexen II ones + if (lumpnum == LUMP_MODELS && (version == &bspver_q1 || version == &bspver_hl)) { /*convert in-place. no need to care about endian here.*/ const dmodelq1_t *in = (const dmodelq1_t*)((const uint8_t *)header + ofs); dmodel_t *out; @@ -2160,45 +2675,6 @@ CopyLump(const dheader_t *header, int lumpnum, void *destptr) } } -// FIXME: Could merge this with CopyLump once the hexen 2 hack is moved elsewhere -static int -Q2_CopyLump(const q2_dheader_t *header, int lumpnum, void *destptr) -{ - const lumpspec_t *lumpspec; - uint8_t **bufferptr = static_cast(destptr); - uint8_t *buffer = *bufferptr; - int length; - int ofs; - - switch (header->version) { - case Q2_BSPVERSION: - lumpspec = &lumpspec_q2bsp[lumpnum]; - break; - default: - Error("Unsupported BSP version: %d", header->version); - throw; //mxd. Fixes "Uninitialized variable" warning - } - - length = header->lumps[lumpnum].filelen; - ofs = header->lumps[lumpnum].fileofs; - - if (buffer) - free(buffer); - - if (length % lumpspec->size) - Error("%s: odd %s lump size", __func__, lumpspec->name); - - buffer = *bufferptr = static_cast(malloc(length + 1)); - if (!buffer) - Error("%s: allocation of %i bytes failed.", __func__, length); - - memcpy(buffer, (const uint8_t *)header + ofs, length); - buffer[length] = 0; /* In case of corrupt entity lump */ - - return length / lumpspec->size; -} - - void BSPX_AddLump(bspdata_t *bspdata, const char *xname, const void *xdata, size_t xsize) { bspxentry_t *e; @@ -2284,32 +2760,37 @@ LoadBSPFile(char *filename, bspdata_t *bspdata) /* transfer the header data to these variables */ int numlumps; - int32_t version; lump_t *lumps; /* check for IBSP */ - if (LittleLong(((int *)file_data)[0]) == Q2_BSPIDENT) { + bspversion_t temp_version { LittleLong(((int *)file_data)[0]) }; + + if (temp_version.ident == Q2_BSPIDENT || + temp_version.ident == Q2_QBISMIDENT) { q2_dheader_t *q2header = (q2_dheader_t *)file_data; q2header->version = LittleLong(q2header->version); numlumps = Q2_HEADER_LUMPS; - version = q2header->version; + temp_version.version = q2header->version; lumps = q2header->lumps; } else { dheader_t *q1header = (dheader_t *)file_data; q1header->version = LittleLong(q1header->version); numlumps = BSP_LUMPS; - version = q1header->version; lumps = q1header->lumps; + + // not useful for Q1BSP, but we'll initialize it to -1 + temp_version.version = NO_VERSION; } - bspdata->loadversion = version; - /* check the file version */ - logprint("BSP is version %s\n", BSPVersionString(version)); - if (!BSPVersionSupported(version)) + if (!BSPVersionSupported(temp_version.ident, temp_version.version, &bspdata->version)) { + logprint("BSP is version %s\n", BSPVersionString(&temp_version)); Error("Sorry, this bsp version is not supported."); + } else { + logprint("BSP is version %s\n", BSPVersionString(bspdata->version)); + } /* swap the lump headers */ for (i = 0; i < numlumps; i++) { @@ -2317,152 +2798,175 @@ LoadBSPFile(char *filename, bspdata_t *bspdata) lumps[i].filelen = LittleLong(lumps[i].filelen); } - if (isHexen2((dheader_t *)file_data)) - { - logprint("BSP appears to be from hexen2\n"); - bspdata->hullcount = MAX_MAP_HULLS_H2; - } - else - bspdata->hullcount = MAX_MAP_HULLS_Q1; - /* copy the data */ - if (version == Q2_BSPVERSION) { + if (bspdata->version == &bspver_q2) { q2_dheader_t *header = (q2_dheader_t *)file_data; q2bsp_t *bsp = &bspdata->data.q2bsp; - + memset(bsp, 0, sizeof(*bsp)); - bspdata->version = header->version; + + bsp->nummodels = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_MODELS, &bsp->dmodels); + bsp->numvertexes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_VERTEXES, &bsp->dvertexes); + bsp->numplanes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_PLANES, &bsp->dplanes); + bsp->numleafs = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_LEAFS, &bsp->dleafs); + bsp->numnodes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_NODES, &bsp->dnodes); + bsp->numtexinfo = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_TEXINFO, &bsp->texinfo); + bsp->numfaces = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_FACES, &bsp->dfaces); + bsp->numleaffaces = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_LEAFFACES, &bsp->dleaffaces); + bsp->numleafbrushes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_LEAFBRUSHES, &bsp->dleafbrushes); + bsp->numsurfedges = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_SURFEDGES, &bsp->dsurfedges); + bsp->numedges = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_EDGES, &bsp->dedges); + bsp->numbrushes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_BRUSHES, &bsp->dbrushes); + bsp->numbrushsides = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_BRUSHSIDES, &bsp->dbrushsides); + bsp->numareas = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_AREAS, &bsp->dareas); + bsp->numareaportals = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_AREAPORTALS, &bsp->dareaportals); - bsp->nummodels = Q2_CopyLump (header, Q2_LUMP_MODELS, &bsp->dmodels); - bsp->numvertexes = Q2_CopyLump (header, Q2_LUMP_VERTEXES, &bsp->dvertexes); - bsp->numplanes = Q2_CopyLump (header, Q2_LUMP_PLANES, &bsp->dplanes); - bsp->numleafs = Q2_CopyLump (header, Q2_LUMP_LEAFS, &bsp->dleafs); - bsp->numnodes = Q2_CopyLump (header, Q2_LUMP_NODES, &bsp->dnodes); - bsp->numtexinfo = Q2_CopyLump (header, Q2_LUMP_TEXINFO, &bsp->texinfo); - bsp->numfaces = Q2_CopyLump (header, Q2_LUMP_FACES, &bsp->dfaces); - bsp->numleaffaces = Q2_CopyLump (header, Q2_LUMP_LEAFFACES, &bsp->dleaffaces); - bsp->numleafbrushes = Q2_CopyLump (header, Q2_LUMP_LEAFBRUSHES, &bsp->dleafbrushes); - bsp->numsurfedges = Q2_CopyLump (header, Q2_LUMP_SURFEDGES, &bsp->dsurfedges); - bsp->numedges = Q2_CopyLump (header, Q2_LUMP_EDGES, &bsp->dedges); - bsp->numbrushes = Q2_CopyLump (header, Q2_LUMP_BRUSHES, &bsp->dbrushes); - bsp->numbrushsides = Q2_CopyLump (header, Q2_LUMP_BRUSHSIDES, &bsp->dbrushsides); - bsp->numareas = Q2_CopyLump (header, Q2_LUMP_AREAS, &bsp->dareas); - bsp->numareaportals = Q2_CopyLump (header, Q2_LUMP_AREAPORTALS, &bsp->dareaportals); + bsp->visdatasize = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_VISIBILITY, &bsp->dvis); + bsp->lightdatasize = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_LIGHTING, &bsp->dlightdata); + bsp->entdatasize = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_ENTITIES, &bsp->dentdata); - bsp->visdatasize = Q2_CopyLump (header, Q2_LUMP_VISIBILITY, &bsp->dvis); - bsp->lightdatasize = Q2_CopyLump (header, Q2_LUMP_LIGHTING, &bsp->dlightdata); - bsp->entdatasize = Q2_CopyLump (header, Q2_LUMP_ENTITIES, &bsp->dentdata); + CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_POP, &bsp->dpop); + } else if (bspdata->version == &bspver_qbism) { + q2_dheader_t *header = (q2_dheader_t *)file_data; + q2bsp_qbism_t *bsp = &bspdata->data.q2bsp_qbism; + + memset(bsp, 0, sizeof(*bsp)); + + bsp->nummodels = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_MODELS, &bsp->dmodels); + bsp->numvertexes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_VERTEXES, &bsp->dvertexes); + bsp->numplanes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_PLANES, &bsp->dplanes); + bsp->numleafs = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_LEAFS, &bsp->dleafs); + bsp->numnodes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_NODES, &bsp->dnodes); + bsp->numtexinfo = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_TEXINFO, &bsp->texinfo); + bsp->numfaces = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_FACES, &bsp->dfaces); + bsp->numleaffaces = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_LEAFFACES, &bsp->dleaffaces); + bsp->numleafbrushes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_LEAFBRUSHES, &bsp->dleafbrushes); + bsp->numsurfedges = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_SURFEDGES, &bsp->dsurfedges); + bsp->numedges = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_EDGES, &bsp->dedges); + bsp->numbrushes = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_BRUSHES, &bsp->dbrushes); + bsp->numbrushsides = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_BRUSHSIDES, &bsp->dbrushsides); + bsp->numareas = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_AREAS, &bsp->dareas); + bsp->numareaportals = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_AREAPORTALS, &bsp->dareaportals); - Q2_CopyLump (header, Q2_LUMP_POP, &bsp->dpop); + bsp->visdatasize = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_VISIBILITY, &bsp->dvis); + bsp->lightdatasize = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_LIGHTING, &bsp->dlightdata); + bsp->entdatasize = CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_ENTITIES, &bsp->dentdata); + + CopyLump (header, bspdata->version, header->lumps, Q2_LUMP_POP, &bsp->dpop); + } else { + // Only Q1-like maps need hullcount + if (isHexen2((dheader_t *)file_data)) { + logprint("BSP appears to be from hexen2\n"); + // swap version over to H2 + bspdata->version = &bspver_h2; + bspdata->hullcount = MAX_MAP_HULLS_H2; + } else { + bspdata->hullcount = MAX_MAP_HULLS_Q1; + } } - if (version == BSPVERSION || version == BSPHLVERSION) { + if (bspdata->version == &bspver_q1 || bspdata->version == &bspver_h2 || bspdata->version == &bspver_hl) { dheader_t *header = (dheader_t *)file_data; bsp29_t *bsp = &bspdata->data.bsp29; memset(bsp, 0, sizeof(*bsp)); - bspdata->version = header->version; - bsp->nummodels = CopyLump(header, LUMP_MODELS, &bsp->dmodels); - bsp->numvertexes = CopyLump(header, LUMP_VERTEXES, &bsp->dvertexes); - bsp->numplanes = CopyLump(header, LUMP_PLANES, &bsp->dplanes); - bsp->numleafs = CopyLump(header, LUMP_LEAFS, &bsp->dleafs); - bsp->numnodes = CopyLump(header, LUMP_NODES, &bsp->dnodes); - bsp->numtexinfo = CopyLump(header, LUMP_TEXINFO, &bsp->texinfo); - bsp->numclipnodes = CopyLump(header, LUMP_CLIPNODES, &bsp->dclipnodes); - bsp->numfaces = CopyLump(header, LUMP_FACES, &bsp->dfaces); - bsp->nummarksurfaces = CopyLump(header, LUMP_MARKSURFACES, &bsp->dmarksurfaces); - bsp->numsurfedges = CopyLump(header, LUMP_SURFEDGES, &bsp->dsurfedges); - bsp->numedges = CopyLump(header, LUMP_EDGES, &bsp->dedges); - bsp->texdatasize = CopyLump(header, LUMP_TEXTURES, &bsp->dtexdata); - bsp->visdatasize = CopyLump(header, LUMP_VISIBILITY, &bsp->dvisdata); - bsp->lightdatasize = CopyLump(header, LUMP_LIGHTING, &bsp->dlightdata); - bsp->entdatasize = CopyLump(header, LUMP_ENTITIES, &bsp->dentdata); - } + bsp->nummodels = CopyLump(header, bspdata->version, header->lumps, LUMP_MODELS, &bsp->dmodels); + bsp->numvertexes = CopyLump(header, bspdata->version, header->lumps, LUMP_VERTEXES, &bsp->dvertexes); + bsp->numplanes = CopyLump(header, bspdata->version, header->lumps, LUMP_PLANES, &bsp->dplanes); + bsp->numleafs = CopyLump(header, bspdata->version, header->lumps, LUMP_LEAFS, &bsp->dleafs); + bsp->numnodes = CopyLump(header, bspdata->version, header->lumps, LUMP_NODES, &bsp->dnodes); + bsp->numtexinfo = CopyLump(header, bspdata->version, header->lumps, LUMP_TEXINFO, &bsp->texinfo); + bsp->numclipnodes = CopyLump(header, bspdata->version, header->lumps, LUMP_CLIPNODES, &bsp->dclipnodes); + bsp->numfaces = CopyLump(header, bspdata->version, header->lumps, LUMP_FACES, &bsp->dfaces); + bsp->nummarksurfaces = CopyLump(header, bspdata->version, header->lumps, LUMP_MARKSURFACES, &bsp->dmarksurfaces); + bsp->numsurfedges = CopyLump(header, bspdata->version, header->lumps, LUMP_SURFEDGES, &bsp->dsurfedges); + bsp->numedges = CopyLump(header, bspdata->version, header->lumps, LUMP_EDGES, &bsp->dedges); - if (version == BSP2RMQVERSION) { + bsp->texdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_TEXTURES, &bsp->dtexdata); + bsp->visdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_VISIBILITY, &bsp->dvisdata); + bsp->lightdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_LIGHTING, &bsp->dlightdata); + bsp->entdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_ENTITIES, &bsp->dentdata); + } else if (bspdata->version == &bspver_bsp2rmq) { dheader_t *header = (dheader_t *)file_data; bsp2rmq_t *bsp = &bspdata->data.bsp2rmq; memset(bsp, 0, sizeof(*bsp)); - bspdata->version = header->version; - bsp->nummodels = CopyLump(header, LUMP_MODELS, &bsp->dmodels); - bsp->numvertexes = CopyLump(header, LUMP_VERTEXES, &bsp->dvertexes); - bsp->numplanes = CopyLump(header, LUMP_PLANES, &bsp->dplanes); - bsp->numleafs = CopyLump(header, LUMP_LEAFS, &bsp->dleafs); - bsp->numnodes = CopyLump(header, LUMP_NODES, &bsp->dnodes); - bsp->numtexinfo = CopyLump(header, LUMP_TEXINFO, &bsp->texinfo); - bsp->numclipnodes = CopyLump(header, LUMP_CLIPNODES, &bsp->dclipnodes); - bsp->numfaces = CopyLump(header, LUMP_FACES, &bsp->dfaces); - bsp->nummarksurfaces = CopyLump(header, LUMP_MARKSURFACES, &bsp->dmarksurfaces); - bsp->numsurfedges = CopyLump(header, LUMP_SURFEDGES, &bsp->dsurfedges); - bsp->numedges = CopyLump(header, LUMP_EDGES, &bsp->dedges); - bsp->texdatasize = CopyLump(header, LUMP_TEXTURES, &bsp->dtexdata); - bsp->visdatasize = CopyLump(header, LUMP_VISIBILITY, &bsp->dvisdata); - bsp->lightdatasize = CopyLump(header, LUMP_LIGHTING, &bsp->dlightdata); - bsp->entdatasize = CopyLump(header, LUMP_ENTITIES, &bsp->dentdata); - } + bsp->nummodels = CopyLump(header, bspdata->version, header->lumps, LUMP_MODELS, &bsp->dmodels); + bsp->numvertexes = CopyLump(header, bspdata->version, header->lumps, LUMP_VERTEXES, &bsp->dvertexes); + bsp->numplanes = CopyLump(header, bspdata->version, header->lumps, LUMP_PLANES, &bsp->dplanes); + bsp->numleafs = CopyLump(header, bspdata->version, header->lumps, LUMP_LEAFS, &bsp->dleafs); + bsp->numnodes = CopyLump(header, bspdata->version, header->lumps, LUMP_NODES, &bsp->dnodes); + bsp->numtexinfo = CopyLump(header, bspdata->version, header->lumps, LUMP_TEXINFO, &bsp->texinfo); + bsp->numclipnodes = CopyLump(header, bspdata->version, header->lumps, LUMP_CLIPNODES, &bsp->dclipnodes); + bsp->numfaces = CopyLump(header, bspdata->version, header->lumps, LUMP_FACES, &bsp->dfaces); + bsp->nummarksurfaces = CopyLump(header, bspdata->version, header->lumps, LUMP_MARKSURFACES, &bsp->dmarksurfaces); + bsp->numsurfedges = CopyLump(header, bspdata->version, header->lumps, LUMP_SURFEDGES, &bsp->dsurfedges); + bsp->numedges = CopyLump(header, bspdata->version, header->lumps, LUMP_EDGES, &bsp->dedges); - if (version == BSP2VERSION) { + bsp->texdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_TEXTURES, &bsp->dtexdata); + bsp->visdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_VISIBILITY, &bsp->dvisdata); + bsp->lightdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_LIGHTING, &bsp->dlightdata); + bsp->entdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_ENTITIES, &bsp->dentdata); + } else if (bspdata->version == &bspver_bsp2) { dheader_t *header = (dheader_t *)file_data; bsp2_t *bsp = &bspdata->data.bsp2; memset(bsp, 0, sizeof(*bsp)); - bspdata->version = header->version; - bsp->nummodels = CopyLump(header, LUMP_MODELS, &bsp->dmodels); - bsp->numvertexes = CopyLump(header, LUMP_VERTEXES, &bsp->dvertexes); - bsp->numplanes = CopyLump(header, LUMP_PLANES, &bsp->dplanes); - bsp->numleafs = CopyLump(header, LUMP_LEAFS, &bsp->dleafs); - bsp->numnodes = CopyLump(header, LUMP_NODES, &bsp->dnodes); - bsp->numtexinfo = CopyLump(header, LUMP_TEXINFO, &bsp->texinfo); - bsp->numclipnodes = CopyLump(header, LUMP_CLIPNODES, &bsp->dclipnodes); - bsp->numfaces = CopyLump(header, LUMP_FACES, &bsp->dfaces); - bsp->nummarksurfaces = CopyLump(header, LUMP_MARKSURFACES, &bsp->dmarksurfaces); - bsp->numsurfedges = CopyLump(header, LUMP_SURFEDGES, &bsp->dsurfedges); - bsp->numedges = CopyLump(header, LUMP_EDGES, &bsp->dedges); - bsp->texdatasize = CopyLump(header, LUMP_TEXTURES, &bsp->dtexdata); - bsp->visdatasize = CopyLump(header, LUMP_VISIBILITY, &bsp->dvisdata); - bsp->lightdatasize = CopyLump(header, LUMP_LIGHTING, &bsp->dlightdata); - bsp->entdatasize = CopyLump(header, LUMP_ENTITIES, &bsp->dentdata); + bsp->nummodels = CopyLump(header, bspdata->version, header->lumps, LUMP_MODELS, &bsp->dmodels); + bsp->numvertexes = CopyLump(header, bspdata->version, header->lumps, LUMP_VERTEXES, &bsp->dvertexes); + bsp->numplanes = CopyLump(header, bspdata->version, header->lumps, LUMP_PLANES, &bsp->dplanes); + bsp->numleafs = CopyLump(header, bspdata->version, header->lumps, LUMP_LEAFS, &bsp->dleafs); + bsp->numnodes = CopyLump(header, bspdata->version, header->lumps, LUMP_NODES, &bsp->dnodes); + bsp->numtexinfo = CopyLump(header, bspdata->version, header->lumps, LUMP_TEXINFO, &bsp->texinfo); + bsp->numclipnodes = CopyLump(header, bspdata->version, header->lumps, LUMP_CLIPNODES, &bsp->dclipnodes); + bsp->numfaces = CopyLump(header, bspdata->version, header->lumps, LUMP_FACES, &bsp->dfaces); + bsp->nummarksurfaces = CopyLump(header, bspdata->version, header->lumps, LUMP_MARKSURFACES, &bsp->dmarksurfaces); + bsp->numsurfedges = CopyLump(header, bspdata->version, header->lumps, LUMP_SURFEDGES, &bsp->dsurfedges); + bsp->numedges = CopyLump(header, bspdata->version, header->lumps, LUMP_EDGES, &bsp->dedges); + + bsp->texdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_TEXTURES, &bsp->dtexdata); + bsp->visdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_VISIBILITY, &bsp->dvisdata); + bsp->lightdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_LIGHTING, &bsp->dlightdata); + bsp->entdatasize = CopyLump(header, bspdata->version, header->lumps, LUMP_ENTITIES, &bsp->dentdata); } - if (version != Q2_BSPVERSION) { - dheader_t *header = (dheader_t *)file_data; + // detect BSPX + dheader_t *header = (dheader_t *)file_data; - /*bspx header is positioned exactly+4align at the end of the last lump position (regardless of order)*/ - for (i = 0, bspxofs = 0; i < BSP_LUMPS; i++) + /*bspx header is positioned exactly+4align at the end of the last lump position (regardless of order)*/ + for (i = 0, bspxofs = 0; i < BSP_LUMPS; i++) + { + if (bspxofs < header->lumps[i].fileofs + header->lumps[i].filelen) + bspxofs = header->lumps[i].fileofs + header->lumps[i].filelen; + } + bspxofs = (bspxofs+3) & ~3; + /*okay, so that's where it *should* be if it exists */ + if (bspxofs + sizeof(*bspx) <= flen) + { + int xlumps; + const bspx_lump_t *xlump; + bspx = (const bspx_header_t*)((const uint8_t*)header + bspxofs); + xlump = (const bspx_lump_t*)(bspx+1); + xlumps = LittleLong(bspx->numlumps); + if (!memcmp(&bspx->id,"BSPX",4) && xlumps >= 0 && bspxofs+sizeof(*bspx)+sizeof(*xlump)*xlumps <= flen) { - if (bspxofs < header->lumps[i].fileofs + header->lumps[i].filelen) - bspxofs = header->lumps[i].fileofs + header->lumps[i].filelen; + /*header seems valid so far. just add the lumps as we normally would if we were generating them, ensuring that they get written out anew*/ + while(xlumps --> 0) + { + uint32_t ofs = LittleLong(xlump[xlumps].fileofs); + uint32_t len = LittleLong(xlump[xlumps].filelen); + void *lumpdata = malloc(len); + memcpy(lumpdata, (const uint8_t*)header + ofs, len); + BSPX_AddLump(bspdata, xlump[xlumps].lumpname, lumpdata, len); + } } - bspxofs = (bspxofs+3) & ~3; - /*okay, so that's where it *should* be if it exists */ - if (bspxofs + sizeof(*bspx) <= flen) + else { - int xlumps; - const bspx_lump_t *xlump; - bspx = (const bspx_header_t*)((const uint8_t*)header + bspxofs); - xlump = (const bspx_lump_t*)(bspx+1); - xlumps = LittleLong(bspx->numlumps); - if (!memcmp(&bspx->id,"BSPX",4) && xlumps >= 0 && bspxofs+sizeof(*bspx)+sizeof(*xlump)*xlumps <= flen) - { - /*header seems valid so far. just add the lumps as we normally would if we were generating them, ensuring that they get written out anew*/ - while(xlumps --> 0) - { - uint32_t ofs = LittleLong(xlump[xlumps].fileofs); - uint32_t len = LittleLong(xlump[xlumps].filelen); - void *lumpdata = malloc(len); - memcpy(lumpdata, (const uint8_t*)header + ofs, len); - BSPX_AddLump(bspdata, xlump[xlumps].lumpname, lumpdata, len); - } - } - else - { - if (!memcmp(&bspx->id,"BSPX",4)) - printf("invalid bspx header\n"); - } + if (!memcmp(&bspx->id,"BSPX",4)) + printf("invalid bspx header\n"); } } @@ -2476,11 +2980,13 @@ LoadBSPFile(char *filename, bspdata_t *bspdata) /* ========================================================================= */ typedef struct { - int version; + const bspversion_t *version; // which one is used depends on version - dheader_t q1header; - q2_dheader_t q2header; + union { + dheader_t q1header; + q2_dheader_t q2header; + }; FILE *file; } bspfile_t; @@ -2490,33 +2996,33 @@ AddLump(bspfile_t *bspfile, int lumpnum, const void *data, int count) { bool q2 = false; size_t size; - - switch (bspfile->version) { - case BSPVERSION: - case BSPHLVERSION: - size = lumpspec_bsp29[lumpnum].size * count; - break; - case BSP2RMQVERSION: - size = lumpspec_bsp2rmq[lumpnum].size * count; - break; - case BSP2VERSION: - size = lumpspec_bsp2[lumpnum].size * count; - break; - case Q2_BSPVERSION: - size = lumpspec_q2bsp[lumpnum].size * count; - q2 = true; - break; - default: - Error("Unsupported BSP version: %d", LittleLong(bspfile->version)); + const lumpspec_t *lumpspec; + lump_t *lumps; + + if (bspfile->version == &bspver_q1 || bspfile->version == &bspver_h2 || bspfile->version == &bspver_hl) { + lumpspec = &lumpspec_bsp29[lumpnum]; + lumps = bspfile->q1header.lumps; + } else if (bspfile->version == &bspver_bsp2rmq) { + lumpspec = &lumpspec_bsp2rmq[lumpnum]; + lumps = bspfile->q1header.lumps; + } else if (bspfile->version == &bspver_bsp2) { + lumpspec = &lumpspec_bsp2[lumpnum]; + lumps = bspfile->q1header.lumps; + } else if (bspfile->version == &bspver_q2) { + lumpspec = &lumpspec_q2bsp[lumpnum]; + lumps = bspfile->q2header.lumps; + } else if (bspfile->version == &bspver_qbism) { + lumpspec = &lumpspec_qbism[lumpnum]; + lumps = bspfile->q2header.lumps; + } else { + Error("Unsupported BSP version: %s", BSPVersionString(bspfile->version)); throw; //mxd. Fixes "Uninitialized variable" warning } + size = lumpspec->size * count; + uint8_t pad[4] = {0}; - lump_t *lump; - if (q2) - lump = &bspfile->q2header.lumps[lumpnum]; - else - lump = &bspfile->q1header.lumps[lumpnum]; + lump_t *lump = &lumps[lumpnum]; lump->fileofs = LittleLong(ftell(bspfile->file)); lump->filelen = LittleLong(size); @@ -2573,25 +3079,27 @@ WriteBSPFile(const char *filename, bspdata_t *bspdata) SwapBSPFile(bspdata, TO_DISK); bspfile.version = bspdata->version; - if (bspfile.version == Q2_BSPVERSION) { - bspfile.q2header.ident = LittleLong(Q2_BSPIDENT); - bspfile.q2header.version = LittleLong(Q2_BSPVERSION); - } else { - bspfile.q1header.version = LittleLong(bspfile.version); + + // headers are union'd, so this sets both + bspfile.q2header.ident = LittleLong(bspfile.version->ident); + + if (bspfile.version->version != NO_VERSION) { + bspfile.q2header.version = LittleLong(bspfile.version->version); } logprint("Writing %s as BSP version %s\n", filename, BSPVersionString(bspdata->version)); bspfile.file = SafeOpenWrite(filename); /* Save header space, updated after adding the lumps */ - if (bspfile.version == Q2_BSPVERSION) { + if (bspfile.version->version != NO_VERSION) { SafeWrite(bspfile.file, &bspfile.q2header, sizeof(bspfile.q2header)); } else { SafeWrite(bspfile.file, &bspfile.q1header, sizeof(bspfile.q1header)); } - if (bspdata->version == BSPVERSION || - bspdata->version == BSPHLVERSION) { + if (bspdata->version == &bspver_q1 || + bspdata->version == &bspver_h2 || + bspdata->version == &bspver_hl) { bsp29_t *bsp = &bspdata->data.bsp29; AddLump(&bspfile, LUMP_PLANES, bsp->dplanes, bsp->numplanes); @@ -2610,7 +3118,7 @@ WriteBSPFile(const char *filename, bspdata_t *bspdata) AddLump(&bspfile, LUMP_VISIBILITY, bsp->dvisdata, bsp->visdatasize); AddLump(&bspfile, LUMP_ENTITIES, bsp->dentdata, bsp->entdatasize); AddLump(&bspfile, LUMP_TEXTURES, bsp->dtexdata, bsp->texdatasize); - } else if (bspdata->version == BSP2RMQVERSION) { + } else if (bspdata->version == &bspver_bsp2rmq) { bsp2rmq_t *bsp = &bspdata->data.bsp2rmq; AddLump(&bspfile, LUMP_PLANES, bsp->dplanes, bsp->numplanes); @@ -2629,7 +3137,7 @@ WriteBSPFile(const char *filename, bspdata_t *bspdata) AddLump(&bspfile, LUMP_VISIBILITY, bsp->dvisdata, bsp->visdatasize); AddLump(&bspfile, LUMP_ENTITIES, bsp->dentdata, bsp->entdatasize); AddLump(&bspfile, LUMP_TEXTURES, bsp->dtexdata, bsp->texdatasize); - } else if (bspdata->version == BSP2VERSION) { + } else if (bspdata->version == &bspver_bsp2) { bsp2_t *bsp = &bspdata->data.bsp2; AddLump(&bspfile, LUMP_PLANES, bsp->dplanes, bsp->numplanes); @@ -2648,7 +3156,7 @@ WriteBSPFile(const char *filename, bspdata_t *bspdata) AddLump(&bspfile, LUMP_VISIBILITY, bsp->dvisdata, bsp->visdatasize); AddLump(&bspfile, LUMP_ENTITIES, bsp->dentdata, bsp->entdatasize); AddLump(&bspfile, LUMP_TEXTURES, bsp->dtexdata, bsp->texdatasize); - } else if (bspdata->version == Q2_BSPVERSION) { + } else if (bspdata->version == &bspver_q2) { q2bsp_t *bsp = &bspdata->data.q2bsp; AddLump(&bspfile, Q2_LUMP_MODELS, bsp->dmodels, bsp->nummodels); @@ -2667,6 +3175,29 @@ WriteBSPFile(const char *filename, bspdata_t *bspdata) AddLump(&bspfile, Q2_LUMP_AREAS, bsp->dareas, bsp->numareas); AddLump(&bspfile, Q2_LUMP_AREAPORTALS, bsp->dareaportals, bsp->numareaportals); + AddLump(&bspfile, Q2_LUMP_VISIBILITY, bsp->dvis, bsp->visdatasize); + AddLump(&bspfile, Q2_LUMP_LIGHTING, bsp->dlightdata, bsp->lightdatasize); + AddLump(&bspfile, Q2_LUMP_ENTITIES, bsp->dentdata, bsp->entdatasize); + AddLump(&bspfile, Q2_LUMP_POP, bsp->dpop, sizeof(bsp->dpop)); + } else if (bspdata->version == &bspver_qbism) { + q2bsp_qbism_t *bsp = &bspdata->data.q2bsp_qbism; + + AddLump(&bspfile, Q2_LUMP_MODELS, bsp->dmodels, bsp->nummodels); + AddLump(&bspfile, Q2_LUMP_VERTEXES, bsp->dvertexes, bsp->numvertexes); + AddLump(&bspfile, Q2_LUMP_PLANES, bsp->dplanes, bsp->numplanes); + AddLump(&bspfile, Q2_LUMP_LEAFS, bsp->dleafs, bsp->numleafs); + AddLump(&bspfile, Q2_LUMP_NODES, bsp->dnodes, bsp->numnodes); + AddLump(&bspfile, Q2_LUMP_TEXINFO, bsp->texinfo, bsp->numtexinfo); + AddLump(&bspfile, Q2_LUMP_FACES, bsp->dfaces, bsp->numfaces); + AddLump(&bspfile, Q2_LUMP_LEAFFACES, bsp->dleaffaces, bsp->numleaffaces); + AddLump(&bspfile, Q2_LUMP_LEAFBRUSHES, bsp->dleafbrushes, bsp->numleafbrushes); + AddLump(&bspfile, Q2_LUMP_SURFEDGES, bsp->dsurfedges, bsp->numsurfedges); + AddLump(&bspfile, Q2_LUMP_EDGES, bsp->dedges, bsp->numedges); + AddLump(&bspfile, Q2_LUMP_BRUSHES, bsp->dbrushes, bsp->numbrushes); + AddLump(&bspfile, Q2_LUMP_BRUSHSIDES, bsp->dbrushsides, bsp->numbrushsides); + AddLump(&bspfile, Q2_LUMP_AREAS, bsp->dareas, bsp->numareas); + AddLump(&bspfile, Q2_LUMP_AREAPORTALS, bsp->dareaportals, bsp->numareaportals); + AddLump(&bspfile, Q2_LUMP_VISIBILITY, bsp->dvis, bsp->visdatasize); AddLump(&bspfile, Q2_LUMP_LIGHTING, bsp->dlightdata, bsp->lightdatasize); AddLump(&bspfile, Q2_LUMP_ENTITIES, bsp->dentdata, bsp->entdatasize); @@ -2718,7 +3249,7 @@ WriteBSPFile(const char *filename, bspdata_t *bspdata) fseek(bspfile.file, 0, SEEK_SET); // write the real header - if (bspfile.version == Q2_BSPVERSION) { + if (bspfile.version->version != NO_VERSION) { SafeWrite(bspfile.file, &bspfile.q2header, sizeof(bspfile.q2header)); } else { SafeWrite(bspfile.file, &bspfile.q1header, sizeof(bspfile.q1header)); @@ -2747,7 +3278,7 @@ PrintBSPFileSizes(const bspdata_t *bspdata) { int numtextures = 0; - if (bspdata->version == Q2_BSPVERSION) { + if (bspdata->version == &bspver_q2) { const q2bsp_t *bsp = &bspdata->data.q2bsp; const lumpspec_t *lumpspec = lumpspec_q2bsp; @@ -2771,9 +3302,31 @@ PrintBSPFileSizes(const bspdata_t *bspdata) logprint("%7s %-12s %10i\n", "", "lightdata", bsp->lightdatasize); logprint("%7s %-12s %10i\n", "", "visdata", bsp->visdatasize); logprint("%7s %-12s %10i\n", "", "entdata", bsp->entdatasize); - } - - if (bspdata->version == BSPVERSION || bspdata->version == BSPHLVERSION) { + } else if (bspdata->version == &bspver_qbism) { + const q2bsp_qbism_t *bsp = &bspdata->data.q2bsp_qbism; + const lumpspec_t *lumpspec = lumpspec_qbism; + + logprint("%7i %-12s\n", bsp->nummodels, "models"); + + PrintLumpSize(lumpspec, Q2_LUMP_PLANES, bsp->numplanes); + PrintLumpSize(lumpspec, Q2_LUMP_VERTEXES, bsp->numvertexes); + PrintLumpSize(lumpspec, Q2_LUMP_NODES, bsp->numnodes); + PrintLumpSize(lumpspec, Q2_LUMP_TEXINFO, bsp->numtexinfo); + PrintLumpSize(lumpspec, Q2_LUMP_FACES, bsp->numfaces); + PrintLumpSize(lumpspec, Q2_LUMP_LEAFS, bsp->numleafs); + PrintLumpSize(lumpspec, Q2_LUMP_LEAFFACES, bsp->numleaffaces); + PrintLumpSize(lumpspec, Q2_LUMP_LEAFBRUSHES, bsp->numleafbrushes); + PrintLumpSize(lumpspec, Q2_LUMP_EDGES, bsp->numedges); + PrintLumpSize(lumpspec, Q2_LUMP_SURFEDGES, bsp->numsurfedges); + PrintLumpSize(lumpspec, Q2_LUMP_BRUSHES, bsp->numbrushes); + PrintLumpSize(lumpspec, Q2_LUMP_BRUSHSIDES, bsp->numbrushsides); + PrintLumpSize(lumpspec, Q2_LUMP_AREAS, bsp->numareas); + PrintLumpSize(lumpspec, Q2_LUMP_AREAPORTALS, bsp->numareaportals); + + logprint("%7s %-12s %10i\n", "", "lightdata", bsp->lightdatasize); + logprint("%7s %-12s %10i\n", "", "visdata", bsp->visdatasize); + logprint("%7s %-12s %10i\n", "", "entdata", bsp->entdatasize); + } else if (bspdata->version == &bspver_q1 || bspdata->version == &bspver_h2 || bspdata->version == &bspver_hl) { const bsp29_t *bsp = &bspdata->data.bsp29; const lumpspec_t *lumpspec = lumpspec_bsp29; @@ -2797,9 +3350,15 @@ PrintBSPFileSizes(const bspdata_t *bspdata) logprint("%7s %-12s %10i\n", "", "lightdata", bsp->lightdatasize); logprint("%7s %-12s %10i\n", "", "visdata", bsp->visdatasize); logprint("%7s %-12s %10i\n", "", "entdata", bsp->entdatasize); - } - if (bspdata->version == BSP2RMQVERSION) { + if (bspdata->bspxentries) + { + bspxentry_t *x; + for (x = bspdata->bspxentries; x; x = x->next) { + logprint("%7s %-12s %10i\n", "BSPX", x->lumpname, (int)x->lumpsize); + } + } + } else if (bspdata->version == &bspver_bsp2rmq) { const bsp2rmq_t *bsp = &bspdata->data.bsp2rmq; const lumpspec_t *lumpspec = lumpspec_bsp2rmq; @@ -2823,9 +3382,7 @@ PrintBSPFileSizes(const bspdata_t *bspdata) logprint("%7s %-12s %10i\n", "", "lightdata", bsp->lightdatasize); logprint("%7s %-12s %10i\n", "", "visdata", bsp->visdatasize); logprint("%7s %-12s %10i\n", "", "entdata", bsp->entdatasize); - } - - if (bspdata->version == BSP2VERSION) { + } else if (bspdata->version == &bspver_bsp2) { const bsp2_t *bsp = &bspdata->data.bsp2; const lumpspec_t *lumpspec = lumpspec_bsp2; @@ -2850,12 +3407,4 @@ PrintBSPFileSizes(const bspdata_t *bspdata) logprint("%7s %-12s %10i\n", "", "visdata", bsp->visdatasize); logprint("%7s %-12s %10i\n", "", "entdata", bsp->entdatasize); } - - if (bspdata->bspxentries) - { - bspxentry_t *x; - for (x = bspdata->bspxentries; x; x = x->next) { - logprint("%7s %-12s %10i\n", "BSPX", x->lumpname, (int)x->lumpsize); - } - } } diff --git a/common/bsputils.cc b/common/bsputils.cc index b49cdeec..53be82bf 100644 --- a/common/bsputils.cc +++ b/common/bsputils.cc @@ -188,7 +188,7 @@ bool Face_IsLightmapped(const mbsp_t *bsp, const bsp2_dface_t *face) if (texinfo == nullptr) return false; - if (bsp->loadversion == Q2_BSPVERSION) { + if (bsp->loadversion == &bspver_q2 || bsp->loadversion == &bspver_qbism) { if (texinfo->flags & (Q2_SURF_WARP|Q2_SURF_SKY|Q2_SURF_NODRAW)) { //mxd. +Q2_SURF_NODRAW return false; } @@ -223,7 +223,7 @@ TextureName_Contents(const char *texname) bool //mxd Contents_IsTranslucent(const mbsp_t *bsp, const int contents) { - if (bsp->loadversion == Q2_BSPVERSION) + if (bsp->loadversion == &bspver_q2 || bsp->loadversion == &bspver_qbism) return (contents & Q2_SURF_TRANSLUCENT) && ((contents & Q2_SURF_TRANSLUCENT) != Q2_SURF_TRANSLUCENT); // Don't count KMQ2 fence flags combo as translucent else return contents == CONTENTS_WATER || contents == CONTENTS_LAVA || contents == CONTENTS_SLIME; @@ -238,7 +238,7 @@ Face_IsTranslucent(const mbsp_t *bsp, const bsp2_dface_t *face) int //mxd. Returns CONTENTS_ value for Q1, Q2_SURF_ bitflags for Q2... Face_Contents(const mbsp_t *bsp, const bsp2_dface_t *face) { - if (bsp->loadversion == Q2_BSPVERSION) { + if (bsp->loadversion == &bspver_q2 || bsp->loadversion == &bspver_qbism) { const gtexinfo_t *info = Face_Texinfo(bsp, face); return info->flags; } else { @@ -281,8 +281,13 @@ static bool Light_PointInSolid_r(const mbsp_t *bsp, const int nodenum, const vec { if (nodenum < 0) { const mleaf_t *leaf = BSP_GetLeafFromNodeNum(bsp, nodenum); + + //mxd + if (bsp->loadversion == &bspver_q2 || bsp->loadversion == &bspver_qbism) { + return leaf->contents & Q2_CONTENTS_SOLID; + } - return (bsp->loadversion == Q2_BSPVERSION ? leaf->contents & Q2_CONTENTS_SOLID : (leaf->contents == CONTENTS_SOLID || leaf->contents == CONTENTS_SKY)); //mxd + return (leaf->contents == CONTENTS_SOLID || leaf->contents == CONTENTS_SKY); } const bsp2_dnode_t *node = &bsp->dnodes[nodenum]; diff --git a/include/common/bspfile.hh b/include/common/bspfile.hh index 7a6cb51c..9183755b 100644 --- a/include/common/bspfile.hh +++ b/include/common/bspfile.hh @@ -52,17 +52,41 @@ #define MAX_ENT_KEY 32 #define MAX_ENT_VALUE 1024 +struct bspversion_t +{ + /* identifier value, the first int32_t in the header */ + int32_t ident; + /* version value, if supported; use NO_VERSION if a version is not required */ + int32_t version; + /* short name used for command line args, etc */ + const char *short_name; + /* full display name for printing */ + const char *name; +}; + +#define NO_VERSION -1 + #define BSPVERSION 29 #define BSP2RMQVERSION (('B' << 24) | ('S' << 16) | ('P' << 8) | '2') #define BSP2VERSION ('B' | ('S' << 8) | ('P' << 16) | ('2' << 24)) #define BSPHLVERSION 30 //24bit lighting, and private palettes in the textures lump. #define Q2_BSPIDENT (('P'<<24)+('S'<<16)+('B'<<8)+'I') #define Q2_BSPVERSION 38 +#define Q2_QBISMIDENT (('P'<<24)+('S'<<16)+('B'<<8)+'Q') -/* Not an actual file format, but the mbsp_t struct */ -/* TODO: Should probably separate the type tag for bspdata_t from the file - version numbers */ -#define GENERIC_BSP 99 +extern const bspversion_t bspver_generic, bspver_q1, bspver_h2, bspver_bsp2, bspver_bsp2rmq, bspver_hl, bspver_q2, bspver_qbism; + +/* table of supported versions */ +constexpr const bspversion_t *const bspversions[] = { + &bspver_generic, + &bspver_q1, + &bspver_h2, + &bspver_bsp2, + &bspver_bsp2rmq, + &bspver_hl, + &bspver_q2, + &bspver_qbism +}; typedef struct { int32_t fileofs; @@ -290,6 +314,8 @@ struct q2_dnode_t { uint16_t numfaces; // counting both sides }; +using q2_dnode_qbism_t = bsp2_dnode_t; + /* * Note that children are interpreted as unsigned values now, so that we can * handle > 32k clipnodes. Values > 0xFFF0 can be assumed to be CONTENTS @@ -387,6 +413,8 @@ typedef struct { uint32_t v[2]; /* vertex numbers */ } bsp2_dedge_t; +using q2_dedge_qbism_t = bsp2_dedge_t; + #define MAXLIGHTMAPS 4 typedef struct { int16_t planenum; @@ -424,6 +452,18 @@ typedef struct { int32_t lightofs; // start of [numstyles*surfsize] samples } q2_dface_t; +typedef struct { + uint32_t planenum; // NOTE: only difference from bsp2_dface_t + int32_t side; + int32_t firstedge; // we must support > 64k edges + int32_t numedges; + int32_t texinfo; + + // lighting info + uint8_t styles[MAXLIGHTMAPS]; + int32_t lightofs; // start of [numstyles*surfsize] samples +} q2_dface_qbism_t; + /* Ambient Sounds */ #define AMBIENT_WATER 0 #define AMBIENT_SKY 1 @@ -481,6 +521,22 @@ typedef struct { uint16_t numleafbrushes; } q2_dleaf_t; +typedef struct { + int32_t contents; // OR of all brushes (not needed?) + + int32_t cluster; + int32_t area; + + float mins[3]; // for frustum culling + float maxs[3]; + + uint32_t firstleafface; + uint32_t numleaffaces; + + uint32_t firstleafbrush; + uint32_t numleafbrushes; +} q2_dleaf_qbism_t; + typedef struct { // bsp2_dleaf_t int32_t contents; @@ -492,10 +548,10 @@ typedef struct { uint8_t ambient_level[NUM_AMBIENTS]; // q2 extras - int16_t cluster; - int16_t area; - uint16_t firstleafbrush; - uint16_t numleafbrushes; + int32_t cluster; + int32_t area; + uint32_t firstleafbrush; + uint32_t numleafbrushes; } mleaf_t; typedef struct { @@ -503,6 +559,11 @@ typedef struct { int16_t texinfo; } dbrushside_t; +typedef struct { + uint32_t planenum; // facing out of the leaf + int32_t texinfo; +} q2_dbrushside_qbism_t; + typedef struct { int32_t firstside; int32_t numsides; @@ -742,8 +803,66 @@ typedef struct { uint8_t dpop[256]; } q2bsp_t; +typedef struct { + int nummodels; + q2_dmodel_t *dmodels; + + int visdatasize; + dvis_t *dvis; + + int lightdatasize; + uint8_t *dlightdata; + + int entdatasize; + char *dentdata; + + int numleafs; + q2_dleaf_qbism_t *dleafs; + + int numplanes; + dplane_t *dplanes; + + int numvertexes; + dvertex_t *dvertexes; + + int numnodes; + q2_dnode_qbism_t *dnodes; + + int numtexinfo; + q2_texinfo_t *texinfo; + + int numfaces; + q2_dface_qbism_t *dfaces; + + int numedges; + q2_dedge_qbism_t *dedges; + + int numleaffaces; + uint32_t *dleaffaces; + + int numleafbrushes; + uint32_t *dleafbrushes; + + int numsurfedges; + int32_t *dsurfedges; + + int numareas; + darea_t *dareas; + + int numareaportals; + dareaportal_t *dareaportals; + + int numbrushes; + dbrush_t *dbrushes; + + int numbrushsides; + q2_dbrushside_qbism_t *dbrushsides; + + uint8_t dpop[256]; +} q2bsp_qbism_t; + struct mbsp_t { - int32_t loadversion; + const bspversion_t *loadversion; int nummodels; dmodelh2_t *dmodels; @@ -792,7 +911,7 @@ struct mbsp_t { uint32_t *dleaffaces; int numleafbrushes; - uint16_t *dleafbrushes; + uint32_t *dleafbrushes; int numsurfedges; int32_t *dsurfedges; @@ -807,7 +926,7 @@ struct mbsp_t { dbrush_t *dbrushes; int numbrushsides; - dbrushside_t *dbrushsides; + q2_dbrushside_qbism_t *dbrushsides; uint8_t dpop[256]; }; // "generic" bsp - superset of all other supported types @@ -824,8 +943,7 @@ typedef struct { } q2_dheader_t; typedef struct { - int32_t loadversion; - int32_t version; + const bspversion_t *version, *loadversion; int hullcount; struct { @@ -834,6 +952,7 @@ typedef struct { bsp2_t bsp2; q2bsp_t q2bsp; mbsp_t mbsp; + q2bsp_qbism_t q2bsp_qbism; } data; bspxentry_t *bspxentries; @@ -842,7 +961,7 @@ 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(int32_t version, bspdata_t *bspdata); +void 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); diff --git a/light/entities.cc b/light/entities.cc index be2fd378..5ee1e76e 100644 --- a/light/entities.cc +++ b/light/entities.cc @@ -1579,7 +1579,7 @@ static void MakeSurfaceLights(const mbsp_t *bsp) for (int i = 0; i < bsp->numleafs; i++) { const mleaf_t *leaf = bsp->dleafs + i; - const qboolean underwater = (bsp->loadversion == Q2_BSPVERSION ? leaf->contents & Q2_CONTENTS_LIQUID : leaf->contents != CONTENTS_EMPTY); //mxd + const qboolean underwater = ((bsp->loadversion == &bspver_q2 || bsp->loadversion == &bspver_qbism) ? leaf->contents & Q2_CONTENTS_LIQUID : leaf->contents != CONTENTS_EMPTY); //mxd for (int k = 0; k < leaf->nummarksurfaces; k++) { const int facenum = bsp->dleaffaces[leaf->firstmarksurface + k]; diff --git a/light/imglib.cc b/light/imglib.cc index 3093db64..37e9abac 100644 --- a/light/imglib.cc +++ b/light/imglib.cc @@ -44,7 +44,7 @@ void // WHO TOUCHED MY PALET? LoadPalette(bspdata_t *bspdata) { // Load Quake 2 palette - if (bspdata->loadversion == Q2_BSPVERSION) { + if (bspdata->loadversion == &bspver_q2 || bspdata->loadversion == &bspver_qbism) { uint8_t *palette; char path[1024]; char colormap[] = "pics/colormap.pcx"; @@ -66,7 +66,7 @@ LoadPalette(bspdata_t *bspdata) for (int i = 0; i < 768; i++) thepalette[i] = palette[i]; - } else if (bspdata->hullcount == MAX_MAP_HULLS_H2) { // Gross hacks + } else if (bspdata->loadversion == &bspver_h2) { // Copy Hexen 2 palette for (int i = 0; i < 768; i++) thepalette[i] = hexen2palette[i]; @@ -721,7 +721,7 @@ void // Expects correct palette and game/mod paths to be set LoadOrConvertTextures(mbsp_t *bsp) { // Load or convert textures... - if (bsp->loadversion == Q2_BSPVERSION) + if (bsp->loadversion == &bspver_q2 || bsp->loadversion == &bspver_qbism) LoadTextures(bsp); else if (bsp->texdatasize > 0) ConvertTextures(bsp); diff --git a/light/light.cc b/light/light.cc index 2851c2b2..4c4c0a90 100644 --- a/light/light.cc +++ b/light/light.cc @@ -439,7 +439,7 @@ LightWorld(bspdata_t *bspdata, qboolean forcedscale) CalcualateVertexNormals(bsp); const qboolean bouncerequired = cfg_static.bounce.boolValue() && (debugmode == debugmode_none || debugmode == debugmode_bounce || debugmode == debugmode_bouncelights); //mxd - const qboolean isQuake2map = (bsp->loadversion == Q2_BSPVERSION); //mxd + const qboolean isQuake2map = (bsp->loadversion == &bspver_q2 || bsp->loadversion == &bspver_qbism); //mxd if (bouncerequired || isQuake2map) { MakeTextureColors(bsp); @@ -470,7 +470,7 @@ LightWorld(bspdata_t *bspdata, qboolean forcedscale) // Transfer greyscale lightmap (or color lightmap for Q2/HL) to the bsp and update lightdatasize if (!litonly) { free(bsp->dlightdata); - if (bsp->loadversion == Q2_BSPVERSION || bsp->loadversion == BSPHLVERSION) { + if (isQuake2map || bsp->loadversion == &bspver_hl) { bsp->lightdatasize = lit_file_p; bsp->dlightdata = (uint8_t *)malloc(bsp->lightdatasize); memcpy(bsp->dlightdata, lit_filebase, bsp->lightdatasize); @@ -545,9 +545,9 @@ LoadExtendedTexinfoFlags(const char *sourcefilename, const mbsp_t *bsp) static const char* //mxd GetBaseDirName(bspdata_t *bspdata) { - if (bspdata->loadversion == Q2_BSPVERSION) + if (bspdata->loadversion == &bspver_q2 || bspdata->loadversion == &bspver_qbism) return "BASEQ2"; - if (bspdata->hullcount == MAX_MAP_HULLS_H2) + if (bspdata->loadversion == &bspver_h2) return "DATA1"; return "ID1"; } @@ -951,7 +951,7 @@ light_main(int argc, const char **argv) { bspdata_t bspdata; mbsp_t *const bsp = &bspdata.data.mbsp; - int32_t loadversion; + const bspversion_t *loadversion; int i; double start; double end; @@ -1199,10 +1199,10 @@ light_main(int argc, const char **argv) LoadBSPFile(source, &bspdata); loadversion = bspdata.version; - ConvertBSPFormat(GENERIC_BSP, &bspdata); + ConvertBSPFormat(&bspdata, &bspver_generic); //mxd. Use 1.0 rangescale as a default to better match with qrad3/arghrad - if (loadversion == Q2_BSPVERSION && !cfg.rangescale.isChanged()) + if ((loadversion == &bspver_q2 || loadversion == &bspver_qbism) && !cfg.rangescale.isChanged()) { const auto rs = new lockable_vec_t(cfg.rangescale.primaryName(), 1.0f, 0.0f, 100.0f); cfg.rangescale = *rs; // Gross hacks to avoid displaying this in OptionsSummary... @@ -1242,7 +1242,7 @@ light_main(int argc, const char **argv) if (!onlyents) { - if (loadversion != Q2_BSPVERSION && bsp->loadversion != BSPHLVERSION) //mxd. No lit for Quake 2 + if (loadversion != &bspver_q2 && loadversion != &bspver_qbism && bsp->loadversion != &bspver_hl) //mxd. No lit for Quake 2 CheckLitNeeded(cfg); SetupDirt(cfg); @@ -1281,7 +1281,7 @@ light_main(int argc, const char **argv) WriteEntitiesToString(cfg, bsp); /* Convert data format back if necessary */ - ConvertBSPFormat(loadversion, &bspdata); + ConvertBSPFormat(&bspdata, loadversion); if (!litonly) { WriteBSPFile(source, &bspdata); diff --git a/light/ltface.cc b/light/ltface.cc index 6c964877..365663f5 100644 --- a/light/ltface.cc +++ b/light/ltface.cc @@ -1034,7 +1034,7 @@ GetLightContrib(const globalconfig_t &cfg, const light_t *entity, const vec3_t s if (dist < 0.1) { // Catch 0 distance between sample point and light (produces infinite brightness / nan's) and causes // problems later - dist = 0.1; + dist = 0.1f; VectorSet(surfpointToLightDir_out, 0, 0, 1); } const float add = GetLightValueWithAngle(cfg, entity, surfnorm, surfpointToLightDir_out, dist, twosided); @@ -3081,7 +3081,7 @@ WriteLightmaps(const mbsp_t *bsp, bsp2_dface_t *face, facesup_t *facesup, const continue; // skip lightmaps where all samples have brightness below 1 - if (bsp->loadversion != Q2_BSPVERSION) { // HACK: don't do this on Q2. seems if all styles are 0xff, the face is drawn fullbright instead of black (Q1) + if (bsp->loadversion != &bspver_q2 && bsp->loadversion != &bspver_qbism) { // HACK: don't do this on Q2. seems if all styles are 0xff, the face is drawn fullbright instead of black (Q1) const float maxb = Lightmap_MaxBrightness(&lightmap, lightsurf); if (maxb < 1) continue; @@ -3146,7 +3146,7 @@ WriteLightmaps(const mbsp_t *bsp, bsp2_dface_t *face, facesup_t *facesup, const // q2 support int lightofs; - if (bsp->loadversion == Q2_BSPVERSION || bsp->loadversion == BSPHLVERSION) { + if (bsp->loadversion == &bspver_q2 || bsp->loadversion == &bspver_qbism || bsp->loadversion == &bspver_hl) { lightofs = lit - lit_filebase; } else { lightofs = out - filebase; diff --git a/light/trace.cc b/light/trace.cc index 3828cca3..4bcf6174 100644 --- a/light/trace.cc +++ b/light/trace.cc @@ -716,7 +716,7 @@ TraceFaces (traceinfo_t *ti, int node, const vec3_t start, const vec3_t end) // only solid and sky faces stop the trace. bool issolid, issky; //mxd - if(bsp_static->loadversion == Q2_BSPVERSION) { + if(bsp_static->loadversion == &bspver_q2 || bsp_static->loadversion == &bspver_qbism) { issolid = !(fi->content & Q2_SURF_TRANSLUCENT); issky = (fi->content & Q2_SURF_SKY); } else { diff --git a/light/trace_embree.cc b/light/trace_embree.cc index 811fe4bc..f9a5322e 100644 --- a/light/trace_embree.cc +++ b/light/trace_embree.cc @@ -354,7 +354,7 @@ Embree_FilterFuncN(const struct RTCFilterFunctionNArguments* args) //mxd bool isFence, isGlass; - if(bsp_static->loadversion == Q2_BSPVERSION) { + if(bsp_static->loadversion == &bspver_q2 || bsp_static->loadversion == &bspver_qbism) { const int contents = Face_Contents(bsp_static, face); isFence = ((contents & Q2_SURF_TRANSLUCENT) == Q2_SURF_TRANSLUCENT); // KMQuake 2-specific. Use texture alpha chanel when both flags are set. isGlass = !isFence && (contents & Q2_SURF_TRANSLUCENT); @@ -559,7 +559,7 @@ MakeFaces_r(const mbsp_t *bsp, const int nodenum, std::vector *planes, const int leafnum = -nodenum - 1; const mleaf_t *leaf = &bsp->dleafs[leafnum]; - if (bsp->loadversion == Q2_BSPVERSION ? leaf->contents & Q2_CONTENTS_SOLID : leaf->contents == CONTENTS_SOLID) { + if ((bsp->loadversion == &bspver_q2 || bsp->loadversion == &bspver_qbism) ? leaf->contents & Q2_CONTENTS_SOLID : leaf->contents == CONTENTS_SOLID) { std::vector leaf_windings = Leaf_MakeFaces(bsp, leaf, *planes); for (winding_t *w : leaf_windings) { result->push_back(w); @@ -631,15 +631,16 @@ Embree_TraceInit(const mbsp_t *bsp) const int contents = Face_Contents(bsp, face); //mxd const gtexinfo_t *texinfo = Face_Texinfo(bsp, face); + const bool is_q2 = bsp->loadversion == &bspver_q2 || bsp->loadversion == &bspver_qbism; //mxd. Skip NODRAW faces, but not SKY ones (Q2's sky01.wal has both flags set) - if(bsp->loadversion == Q2_BSPVERSION && (contents & Q2_SURF_NODRAW) && !(contents & Q2_SURF_SKY)) + if(is_q2 && (contents & Q2_SURF_NODRAW) && !(contents & Q2_SURF_SKY)) continue; // handle glass / water const float alpha = Face_Alpha(model, face); if (alpha < 1.0f - || (bsp->loadversion == Q2_BSPVERSION && (contents & Q2_SURF_TRANSLUCENT))) { //mxd. Both fence and transparent textures are done using SURF_TRANS flags in Q2 + || (is_q2 && (contents & Q2_SURF_TRANSLUCENT))) { //mxd. Both fence and transparent textures are done using SURF_TRANS flags in Q2 filterfaces.push_back(face); continue; } @@ -652,7 +653,7 @@ Embree_TraceInit(const mbsp_t *bsp) } // handle sky - if (bsp->loadversion == Q2_BSPVERSION) { + if (is_q2) { // Q2: arghrad compat: sky faces only emit sunlight if: // sky flag set, light flag set, value nonzero if ((contents & Q2_SURF_SKY) != 0 diff --git a/vis/vis.cc b/vis/vis.cc index 64daa1b8..afe29eaf 100644 --- a/vis/vis.cc +++ b/vis/vis.cc @@ -1234,7 +1234,7 @@ main(int argc, char **argv) { bspdata_t bspdata; mbsp_t *const bsp = &bspdata.data.mbsp; - int32_t loadversion; + const bspversion_t *loadversion; int i; init_log("vis.log"); @@ -1309,7 +1309,7 @@ main(int argc, char **argv) LoadBSPFile(sourcefile, &bspdata); loadversion = bspdata.version; - ConvertBSPFormat(GENERIC_BSP, &bspdata); + ConvertBSPFormat(&bspdata, &bspver_generic); strcpy(portalfile, argv[i]); StripExtension(portalfile); @@ -1341,7 +1341,7 @@ main(int argc, char **argv) CalcAmbientSounds(bsp); /* Convert data format back if necessary */ - ConvertBSPFormat(loadversion, &bspdata); + ConvertBSPFormat(&bspdata, loadversion); WriteBSPFile(sourcefile, &bspdata);