diff --git a/common/bsputils.cc b/common/bsputils.cc index 2039c399..747eea3e 100644 --- a/common/bsputils.cc +++ b/common/bsputils.cc @@ -543,28 +543,27 @@ void Face_DebugPrint(const mbsp_t *bsp, const mface_t *face) CompressRow =============== */ -int CompressRow(const uint8_t *vis, const int numbytes, uint8_t *out) +void CompressRow(const uint8_t *vis, const size_t numbytes, std::back_insert_iterator> it) { - int i, rep; - uint8_t *dst; + for (size_t i = 0; i < numbytes; i++) { + it++ = vis[i]; - dst = out; - for (i = 0; i < numbytes; i++) { - *dst++ = vis[i]; - if (vis[i]) + if (vis[i]) { continue; + } - rep = 1; - for (i++; i < numbytes; i++) - if (vis[i] || rep == 255) + int32_t rep = 1; + + for (i++; i < numbytes; i++) { + if (vis[i] || rep == 255) { break; - else - rep++; - *dst++ = rep; + } + rep++; + } + + it++ = rep; i--; } - - return dst - out; } /* diff --git a/include/common/bsputils.hh b/include/common/bsputils.hh index d86039af..14931626 100644 --- a/include/common/bsputils.hh +++ b/include/common/bsputils.hh @@ -81,5 +81,7 @@ 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); -int CompressRow(const uint8_t *vis, const int numbytes, uint8_t *out); +#include + +void CompressRow(const uint8_t *vis, const size_t numbytes, std::back_insert_iterator> it); void DecompressRow(const uint8_t *in, const int numbytes, uint8_t *decompressed); diff --git a/vis/soundpvs.cc b/vis/soundpvs.cc index 327a9b4b..58c5b5af 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]; - uint8_t *compressed = new uint8_t[leafbytes * 2]; + std::vector compressed(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 // - int32_t j = CompressRow(uncompressed, leafbytes, compressed); + compressed.clear(); + CompressRow(uncompressed, leafbytes, std::back_inserter(compressed)); bsp->dvis.set_bit_offset(VIS_PHS, i, bsp->dvis.bits.size()); - std::copy(compressed, compressed + j, std::back_inserter(bsp->dvis.bits)); + std::copy(compressed.begin(), compressed.end(), 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 897271d8..2e5c9fba 100644 --- a/vis/vis.cc +++ b/vis/vis.cc @@ -30,9 +30,7 @@ int c_noclip = 0; bool showgetleaf = true; -static uint8_t *vismap; -static uint8_t *vismap_p; -static uint8_t *vismap_end; // past visfile +static std::vector vismap; uint32_t originalvismapsize; @@ -404,14 +402,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; - uint8_t *compressed; - int i, j, len; + int i, j; int numvis, numblocks; - uint8_t *dest; const portal_t *p; /* @@ -477,23 +475,17 @@ 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) { - compressed = new uint8_t[max(1, (portalleafs * 2) / 8)]; - len = CompressRow(outbuffer, (portalleafs + 7) >> 3, compressed); + CompressRow(outbuffer, (portalleafs + 7) >> 3, std::back_inserter(compressed)); } else { - compressed = new uint8_t[max(1, (portalleafs_real * 2) / 8)]; - len = CompressRow(outbuffer, (portalleafs_real + 7) >> 3, compressed); + CompressRow(outbuffer, (portalleafs_real + 7) >> 3, std::back_inserter(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 = dest - vismap; + int32_t visofs = vismap.size(); bsp->dvis.set_bit_offset(VIS_PVS, clusternum, visofs); @@ -512,8 +504,7 @@ static void ClusterFlow(int clusternum, leafbits_t &buffer, mbsp_t *bsp) } } - memcpy(dest, compressed, len); - delete[] compressed; + std::copy(compressed.begin(), compressed.end(), std::back_inserter(vismap)); } /* @@ -617,6 +608,14 @@ 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) { @@ -648,10 +647,7 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp) bsp->dvis.resize(portalleafs); - bsp->dvis.bits.resize(originalvismapsize * 2); - - vismap = vismap_p = bsp->dvis.bits.data(); - vismap_end = vismap + bsp->dvis.bits.size(); + vismap.reserve(originalvismapsize * 2); for (i = 0, p = portals; i < numportals; i++) { const auto &sourceportal = prtfile.portals[i]; @@ -756,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.resize(vismap_p - bsp.dvis.bits.data()); + bsp.dvis.bits = std::move(vismap); bsp.dvis.bits.shrink_to_fit(); logging::print("visdatasize:{} compressed from {}\n", bsp.dvis.bits.size(), originalvismapsize); }