diff --git a/common/bsputils.cc b/common/bsputils.cc index 747eea3e..2039c399 100644 --- a/common/bsputils.cc +++ b/common/bsputils.cc @@ -543,27 +543,28 @@ void Face_DebugPrint(const mbsp_t *bsp, const mface_t *face) CompressRow =============== */ -void CompressRow(const uint8_t *vis, const size_t numbytes, std::back_insert_iterator> it) +int CompressRow(const uint8_t *vis, const int numbytes, uint8_t *out) { - for (size_t i = 0; i < numbytes; i++) { - it++ = vis[i]; + int i, rep; + uint8_t *dst; - if (vis[i]) { + dst = out; + for (i = 0; i < numbytes; i++) { + *dst++ = vis[i]; + if (vis[i]) continue; - } - int32_t rep = 1; - - for (i++; i < numbytes; i++) { - if (vis[i] || rep == 255) { + rep = 1; + for (i++; i < numbytes; i++) + if (vis[i] || rep == 255) break; - } - rep++; - } - - it++ = rep; + else + rep++; + *dst++ = rep; i--; } + + return dst - out; } /* diff --git a/include/common/bsputils.hh b/include/common/bsputils.hh index 14931626..d86039af 100644 --- a/include/common/bsputils.hh +++ b/include/common/bsputils.hh @@ -81,7 +81,5 @@ std::vector GLM_FacePoints(const mbsp_t *bsp, const mface_t *face); qvec3f Face_Centroid(const mbsp_t *bsp, const mface_t *face); void Face_DebugPrint(const mbsp_t *bsp, const mface_t *face); -#include - -void CompressRow(const uint8_t *vis, const size_t numbytes, std::back_insert_iterator> it); +int CompressRow(const uint8_t *vis, const int numbytes, uint8_t *out); void DecompressRow(const uint8_t *in, const int numbytes, uint8_t *decompressed); diff --git a/vis/soundpvs.cc b/vis/soundpvs.cc index 58c5b5af..327a9b4b 100644 --- a/vis/soundpvs.cc +++ b/vis/soundpvs.cc @@ -163,7 +163,7 @@ void CalcPHS(mbsp_t *bsp) // FIXME: should this use alloca? uint8_t *uncompressed = new uint8_t[leafbytes]; uint8_t *uncompressed_2 = new uint8_t[leafbytes]; - std::vector compressed(leafbytes * 2); + uint8_t *compressed = new uint8_t[leafbytes * 2]; uint8_t *uncompressed_orig = new uint8_t[leafbytes]; int32_t count = 0; @@ -202,16 +202,16 @@ void CalcPHS(mbsp_t *bsp) // // compress the bit string // - compressed.clear(); - CompressRow(uncompressed, leafbytes, std::back_inserter(compressed)); + int32_t j = CompressRow(uncompressed, leafbytes, compressed); bsp->dvis.set_bit_offset(VIS_PHS, i, bsp->dvis.bits.size()); - std::copy(compressed.begin(), compressed.end(), std::back_inserter(bsp->dvis.bits)); + std::copy(compressed, compressed + j, std::back_inserter(bsp->dvis.bits)); } delete[] uncompressed; delete[] uncompressed_2; + delete[] compressed; delete[] uncompressed_orig; fmt::print("Average clusters hearable: {}\n", count / portalleafs); diff --git a/vis/vis.cc b/vis/vis.cc index 5557af0d..b14c5e3a 100644 --- a/vis/vis.cc +++ b/vis/vis.cc @@ -30,7 +30,9 @@ int c_noclip = 0; bool showgetleaf = true; -static std::vector vismap; +static uint8_t *vismap; +static uint8_t *vismap_p; +static uint8_t *vismap_end; // past visfile uint32_t originalvismapsize; @@ -399,14 +401,14 @@ void LeafThread(size_t) */ int64_t totalvis; -static std::vector compressed; - static void ClusterFlow(int clusternum, leafbits_t &buffer, mbsp_t *bsp) { leaf_t *leaf; uint8_t *outbuffer; - int i, j; + uint8_t *compressed; + int i, j, len; int numvis, numblocks; + uint8_t *dest; const portal_t *p; /* @@ -472,17 +474,23 @@ static void ClusterFlow(int clusternum, leafbits_t &buffer, mbsp_t *bsp) } } - compressed.clear(); - /* Allocate for worst case where RLE might grow the data (unlikely) */ if (bsp->loadversion->game->id == GAME_QUAKE_II) { - CompressRow(outbuffer, (portalleafs + 7) >> 3, std::back_inserter(compressed)); + compressed = new uint8_t[max(1, (portalleafs * 2) / 8)]; + len = CompressRow(outbuffer, (portalleafs + 7) >> 3, compressed); } else { - CompressRow(outbuffer, (portalleafs_real + 7) >> 3, std::back_inserter(compressed)); + compressed = new uint8_t[max(1, (portalleafs_real * 2) / 8)]; + len = CompressRow(outbuffer, (portalleafs_real + 7) >> 3, compressed); } + dest = vismap_p; + vismap_p += len; + + if (vismap_p > vismap_end) + FError("Vismap expansion overflow"); + /* leaf 0 is a common solid */ - int32_t visofs = vismap.size(); + int32_t visofs = dest - vismap; bsp->dvis.set_bit_offset(VIS_PVS, clusternum, visofs); @@ -501,7 +509,8 @@ static void ClusterFlow(int clusternum, leafbits_t &buffer, mbsp_t *bsp) } } - std::copy(compressed.begin(), compressed.end(), std::back_inserter(vismap)); + memcpy(dest, compressed, len); + delete[] compressed; } /* @@ -605,14 +614,6 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp) portalleafs = prtfile.portalleafs; portalleafs_real = prtfile.portalleafs_real; - - /* Allocate for worst case where RLE might grow the data (unlikely) */ - if (bsp->loadversion->game->id == GAME_QUAKE_II) { - compressed.reserve(max(1, (portalleafs * 2) / 8)); - } else { - compressed.reserve(max(1, (portalleafs_real * 2) / 8)); - } - numportals = prtfile.portals.size(); if (bsp->loadversion->game->id != GAME_QUAKE_II) { @@ -644,7 +645,10 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp) bsp->dvis.resize(portalleafs); - vismap.reserve(originalvismapsize * 2); + bsp->dvis.bits.resize(originalvismapsize * 2); + + vismap = vismap_p = bsp->dvis.bits.data(); + vismap_end = vismap + bsp->dvis.bits.size(); for (i = 0, p = portals; i < numportals; i++) { const auto &sourceportal = prtfile.portals[i]; @@ -748,7 +752,7 @@ int vis_main(int argc, const char **argv) logging::print("c_noclip: {}\n", c_noclip); logging::print("c_chains: {}\n", c_chains); - bsp.dvis.bits = std::move(vismap); + bsp.dvis.bits.resize(vismap_p - bsp.dvis.bits.data()); bsp.dvis.bits.shrink_to_fit(); logging::print("visdatasize:{} compressed from {}\n", bsp.dvis.bits.size(), originalvismapsize); }