From 117f568cd7aa54b33ee835a214cb24a21d4e393b Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Mon, 3 Jul 2017 01:31:36 -0600 Subject: [PATCH] qbsp: don't write unused texinfo. also cleanup planes writing --- include/qbsp/qbsp.hh | 1 + include/qbsp/writebsp.hh | 2 + qbsp/map.cc | 1 + qbsp/qbsp.cc | 2 + qbsp/surfaces.cc | 2 +- qbsp/writebsp.cc | 119 ++++++++++++++++++++++++++------------- 6 files changed, 87 insertions(+), 40 deletions(-) diff --git a/include/qbsp/qbsp.hh b/include/qbsp/qbsp.hh index c406e735..21739b56 100644 --- a/include/qbsp/qbsp.hh +++ b/include/qbsp/qbsp.hh @@ -204,6 +204,7 @@ typedef struct mtexinfo_s { float vecs[2][4]; /* [s/t][xyz offset] */ int32_t miptex; uint64_t flags; + int outputnum; // -1 until added to bsp bool operator<(const mtexinfo_s &other) const { if (this->miptex < other.miptex) diff --git a/include/qbsp/writebsp.hh b/include/qbsp/writebsp.hh index 26244cf6..2f46eb2e 100644 --- a/include/qbsp/writebsp.hh +++ b/include/qbsp/writebsp.hh @@ -23,8 +23,10 @@ #define QBSP_WRITEBSP_HH int ExportMapPlane(int planenum); +int ExportMapTexinfo(int texinfonum); void AllocBSPPlanes(); +void AllocBSPTexinfo(); void BeginBSPFile(void); void FinishBSPFile(void); diff --git a/qbsp/map.cc b/qbsp/map.cc index 128ed83c..216ed476 100644 --- a/qbsp/map.cc +++ b/qbsp/map.cc @@ -239,6 +239,7 @@ FindTexinfo(mtexinfo_t *texinfo, uint64_t flags) { /* Set the texture flags */ texinfo->flags = flags; + texinfo->outputnum = -1; /* Don't worry about texture alignment on skip or hint surfaces */ if (texinfo->flags & (TEX_SKIP | TEX_HINT)) { diff --git a/qbsp/qbsp.cc b/qbsp/qbsp.cc index 927fce42..6cb0b002 100644 --- a/qbsp/qbsp.cc +++ b/qbsp/qbsp.cc @@ -175,6 +175,7 @@ ProcessEntity(mapentity_t *entity, const int hullnum) } } AllocBSPPlanes(); + AllocBSPTexinfo(); ExportClipNodes(entity, nodes, hullnum); } else { /* @@ -225,6 +226,7 @@ ProcessEntity(mapentity_t *entity, const int hullnum) DetailToSolid(nodes); AllocBSPPlanes(); + AllocBSPTexinfo(); firstface = MakeFaceEdges(entity, nodes, std::vector {}); ExportDrawNodes(entity, nodes, firstface); diff --git a/qbsp/surfaces.cc b/qbsp/surfaces.cc index b2d9a01e..beb29b91 100644 --- a/qbsp/surfaces.cc +++ b/qbsp/surfaces.cc @@ -469,7 +469,7 @@ EmitFace_Internal(mapentity_t *entity, face_t *face) out = (DFACE *)faces->data + faces->index; out->planenum = ExportMapPlane(face->planenum); out->side = face->planeside; - out->texinfo = face->texinfo; + out->texinfo = ExportMapTexinfo(face->texinfo); for (i = 0; i < MAXLIGHTMAPS; i++) out->styles[i] = 255; out->lightofs = -1; diff --git a/qbsp/writebsp.cc b/qbsp/writebsp.cc index 2226d0fb..4096faf2 100644 --- a/qbsp/writebsp.cc +++ b/qbsp/writebsp.cc @@ -23,6 +23,9 @@ #include #include +#include +#include + static void AssertVanillaContentType(int content) { @@ -82,10 +85,44 @@ ExportMapPlane(int planenum) planes->index++; map.cTotal[LUMP_PLANES]++; + Q_assert(planes->index == map.cTotal[LUMP_PLANES]); + plane->outputplanenum = newIndex; return newIndex; } +int +ExportMapTexinfo(int texinfonum) +{ + mtexinfo_t *src = &map.mtexinfos.at(texinfonum); + if (src->outputnum != -1) + return src->outputnum; + + struct lumpdata *texinfo = &pWorldEnt()->lumps[LUMP_TEXINFO]; + + if (texinfo->index >= texinfo->count) + Error("Internal error: texinfo count mismatch (%s)", __func__); + + const int i = texinfo->index; + + texinfo_t *dest = &(static_cast(texinfo->data)[i]); + dest->flags = static_cast(src->flags & TEX_SPECIAL); + dest->miptex = src->miptex; + for (int j=0; j<2; j++) { + for (int k=0; k<4; k++) { + dest->vecs[j][k] = src->vecs[j][k]; + } + } + + texinfo->index++; + map.cTotal[LUMP_TEXINFO]++; + + Q_assert(texinfo->index == map.cTotal[LUMP_TEXINFO]); + + src->outputnum = i; + return i; +} + /* ================== AllocBSPPlanes @@ -109,6 +146,29 @@ AllocBSPPlanes() } } +/* +================== +AllocBSPTexinfo +================== +*/ +void +AllocBSPTexinfo() +{ + struct lumpdata *texinfo = &pWorldEnt()->lumps[LUMP_TEXINFO]; + + // OK just need one plane array, stick it in worldmodel + if (map.numtexinfo() > texinfo->count) { + int newcount = map.numtexinfo(); + struct lumpdata *newtexinfo = (struct lumpdata *)AllocMem(BSP_TEXINFO, newcount, true); + + memcpy(newtexinfo, texinfo->data, MemSize[BSP_TEXINFO] * texinfo->count); + FreeMem(texinfo->data, BSP_TEXINFO, texinfo->count); + + texinfo->count = newcount; + texinfo->data = newtexinfo; + } +} + //=========================================================================== @@ -738,6 +798,12 @@ WriteExtendedTexinfoFlags(void) if (!needwrite) return; + // sort by output texinfo number + std::vector texinfos_sorted(map.mtexinfos); + std::sort(texinfos_sorted.begin(), texinfos_sorted.end(), [](const mtexinfo_t &a, const mtexinfo_t &b) { + return a.outputnum < b.outputnum; + }); + FILE *texinfofile; StripExtension(options.szBSPName); strcat(options.szBSPName, ".texinfo"); @@ -745,40 +811,19 @@ WriteExtendedTexinfoFlags(void) if (!texinfofile) Error("Failed to open %s: %s", options.szBSPName, strerror(errno)); - for (int i = 0; i < num_texinfo; i++) { - fprintf(texinfofile, "%llu\n", static_cast(map.mtexinfos.at(i).flags)); - } - fclose(texinfofile); -} - -/* - * Remove any extra texinfo flags we added that are not normally written - * Standard quake utils only ever write the TEX_SPECIAL flag. - */ -static void -ExportTexinfo(void) -{ - const int num_texinfo = map.numtexinfo(); - - struct lumpdata *texinfo = &pWorldEnt()->lumps[LUMP_TEXINFO]; - texinfo->data = AllocMem(BSP_TEXINFO, num_texinfo, true); - texinfo->count = num_texinfo; - texinfo->index = num_texinfo; - - for (int i=0; i(texinfo->data)[i]); + int count = 0; + for (const auto &tx : texinfos_sorted) { + if (tx.outputnum == -1) + continue; - dest->flags = static_cast(src->flags & TEX_SPECIAL); - dest->miptex = src->miptex; - for (int j=0; j<2; j++) { - for (int k=0; k<4; k++) { - dest->vecs[j][k] = src->vecs[j][k]; - } - } + Q_assert(count == tx.outputnum); // check we are outputting them in the proper sequence + + fprintf(texinfofile, "%llu\n", static_cast(tx.flags)); + count++; } + Q_assert(count == map.cTotal[LUMP_TEXINFO]); - map.cTotal[LUMP_TEXINFO] = num_texinfo; + fclose(texinfofile); } /* @@ -789,21 +834,17 @@ FinishBSPFile void FinishBSPFile(void) { - struct lumpdata *planes = &pWorldEnt()->lumps[LUMP_PLANES]; - dplane_t *newdata; - options.fVerbose = true; Message(msgProgress, "WriteBSPFile"); // TODO: Fix this somewhere else? - newdata = (dplane_t *)AllocMem(BSP_PLANE, map.cTotal[LUMP_PLANES], true); - memcpy(newdata, planes->data, map.cTotal[LUMP_PLANES] * MemSize[BSP_PLANE]); - FreeMem(planes->data, BSP_PLANE, planes->count); - planes->data = newdata; + struct lumpdata *planes = &pWorldEnt()->lumps[LUMP_PLANES]; planes->count = map.cTotal[LUMP_PLANES]; + struct lumpdata *texinfo = &pWorldEnt()->lumps[LUMP_TEXINFO]; + texinfo->count = map.cTotal[LUMP_TEXINFO]; + WriteExtendedTexinfoFlags(); - ExportTexinfo(); WriteBSPFile(); PrintBSPFileSizes();