diff --git a/common/bspfile.cc b/common/bspfile.cc index 91584f63..3d985849 100644 --- a/common/bspfile.cc +++ b/common/bspfile.cc @@ -962,6 +962,36 @@ Q2BSPtoM_Models(const q2_dmodel_t *dmodelsq2, int nummodels) { return newdata; } +static uint8_t * +Q2BSPtoM_CopyVisData(const dvis_t *dvisq2, int vissize, int *outvissize, mleaf_t *leafs, int numleafs) { + + if (!*outvissize) { + return ((uint8_t *) dvisq2); + } + + // FIXME: assumes PHS always follows PVS. + int32_t phs_start = INT_MAX, pvs_start = INT_MAX; + size_t header_offset = sizeof(dvis_t) + (sizeof(int32_t) * dvisq2->numclusters * 2); + + for (int32_t i = 0; i < dvisq2->numclusters; i++) { + pvs_start = std::min(pvs_start, (int32_t) (dvisq2->bitofs[i][DVIS_PVS])); + phs_start = std::min(phs_start, (int32_t) (dvisq2->bitofs[i][DVIS_PHS] - header_offset)); + + for (int32_t l = 0; l < numleafs; l++) { + if (leafs[l].cluster == i) { + leafs[l].visofs = dvisq2->bitofs[i][DVIS_PVS] - header_offset; + } + } + } + + // cut off the PHS and header + *outvissize -= header_offset + ((*outvissize - header_offset) - phs_start); + + uint8_t *vis = (uint8_t *) calloc(1, *outvissize); + memcpy(vis, ((uint8_t *) dvisq2) + pvs_start, *outvissize); + return vis; +} + static q2_dmodel_t * MBSPtoQ2_Models(const dmodelh2_t *dmodelsh2, int nummodels) { const dmodelh2_t *dmodelh2 = dmodelsh2; @@ -984,6 +1014,128 @@ MBSPtoQ2_Models(const dmodelh2_t *dmodelsh2, int nummodels) { return newdata; } + +/* +================ +CalcPHS + +Calculate the PHS (Potentially Hearable Set) +by ORing together all the PVS visible from a leaf +================ +*/ +static std::vector CalcPHS(int32_t portalclusters, const uint8_t *visdata, int *visdatasize, int32_t bitofs[][2]) +{ + const int32_t leafbytes = (portalclusters + 7) >> 3; + const int32_t leaflongs = leafbytes / sizeof(long); + std::vector compressed_phs; + uint8_t *uncompressed = (uint8_t *) calloc(1, leafbytes); + uint8_t *uncompressed_2 = (uint8_t *) calloc(1, leafbytes); + uint8_t *compressed = (uint8_t *) calloc(1, leafbytes * 2); + uint8_t *uncompressed_orig = (uint8_t *) calloc(1, leafbytes); + + printf ("Building PHS...\n"); + + int32_t count = 0; + for (int32_t i = 0; i < portalclusters; i++) + { + const uint8_t *scan = &visdata[bitofs[i][DVIS_PVS]]; + + DecompressRow(scan, leafbytes, uncompressed); + memset(uncompressed_orig, 0, leafbytes); + memcpy(uncompressed_orig, uncompressed, leafbytes); + + scan = uncompressed_orig; + + for (int32_t j = 0; j < leafbytes; j++) + { + uint8_t bitbyte = scan[j]; + if (!bitbyte) + continue; + for (int32_t k = 0; k < 8; k++) + { + if (! (bitbyte & (1<= portalclusters) + Error ("Bad bit in PVS"); // pad bits should be 0 + const uint8_t *src_compressed = &visdata[bitofs[index][DVIS_PVS]]; + DecompressRow(src_compressed, leafbytes, uncompressed_2); + const long *src = (long *) uncompressed_2; + long *dest = (long *) uncompressed; + for (int32_t l = 0; l < leaflongs; l++) + ((long *)uncompressed)[l] |= src[l]; + } + } + for (int32_t j = 0; j < portalclusters; j++) + if (uncompressed[j>>3] & (1<<(j&7)) ) + count++; + + // + // compress the bit string + // + int32_t j = CompressRow (uncompressed, leafbytes, compressed); + + bitofs[i][DVIS_PHS] = compressed_phs.size(); + + compressed_phs.insert(compressed_phs.end(), compressed, compressed + j); + } + + free(uncompressed); + free(uncompressed_2); + free(compressed); + free(uncompressed_orig); + + printf ("Average clusters hearable: %i\n", count / portalclusters); + + return compressed_phs; +} + +static dvis_t * +MBSPtoQ2_CopyVisData(const uint8_t *visdata, int *visdatasize, int numleafs, const mleaf_t *leafs) { + int32_t num_clusters = 0; + + for (int32_t i = 0; i < numleafs; i++) { + num_clusters = std::max(num_clusters, leafs[i].cluster + 1); + } + + size_t vis_offset = sizeof(dvis_t) + (sizeof(int32_t) * num_clusters * 2); + dvis_t *vis = (dvis_t *)calloc(1, vis_offset + *visdatasize); + + vis->numclusters = num_clusters; + + // the leaves are already using a per-cluster visofs, so just find one matching + // cluster and note it down under bitofs. + // we're also not worrying about PHS currently. + for (int32_t i = 0; i < num_clusters; i++) { + for (int32_t l = 0; l < numleafs; l++) { + if (leafs[l].cluster == i) { + // copy PVS visofs + vis->bitofs[i][DVIS_PVS] = leafs[l].visofs; + break; + } + } + } + + std::vector phs = CalcPHS(num_clusters, visdata, visdatasize, vis->bitofs); + + vis = (dvis_t *) realloc(vis, vis_offset + *visdatasize + phs.size()); + + // offset the pvs/phs properly + for (int32_t i = 0; i < num_clusters; i++) { + vis->bitofs[i][DVIS_PVS] += vis_offset; + vis->bitofs[i][DVIS_PHS] += vis_offset + *visdatasize; + } + + memcpy(((uint8_t *) vis) + vis_offset, visdata, *visdatasize); + *visdatasize += vis_offset; + + memcpy(((uint8_t *) vis) + *visdatasize, phs.data(), phs.size()); + *visdatasize += phs.size(); + + return vis; +} + static mleaf_t * Q2BSPtoM_Leafs(const q2_dleaf_t *dleafsq2, int numleafs) { const q2_dleaf_t *dleafq2 = dleafsq2; @@ -1938,7 +2090,7 @@ static void FreeMBSP(mbsp_t *bsp) inline void ConvertBSPToMFormatComplete(const bspversion_t **mbsp_loadversion, const bspversion_t *version, bspdata_t *bspdata) { - *mbsp_loadversion = bspdata->version; + bspdata->loadversion = *mbsp_loadversion = bspdata->version; bspdata->version = version; } @@ -2034,7 +2186,6 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) // 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); @@ -2047,6 +2198,8 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) mbsp->dleaffaces = BSP29to2_Marksurfaces(q2bsp->dleaffaces, q2bsp->numleaffaces); mbsp->dleafbrushes = Q2BSPtoM_CopyLeafBrushes(q2bsp->dleafbrushes, q2bsp->numleafbrushes); mbsp->dsurfedges = BSP29_CopySurfedges(q2bsp->dsurfedges, q2bsp->numsurfedges); + + mbsp->dvisdata = Q2BSPtoM_CopyVisData(q2bsp->dvis, q2bsp->visdatasize, &mbsp->visdatasize, mbsp->dleafs, mbsp->numleafs); mbsp->dareas = Q2BSP_CopyAreas(q2bsp->dareas, q2bsp->numareas); mbsp->dareaportals = Q2BSP_CopyAreaPortals(q2bsp->dareaportals, q2bsp->numareaportals); @@ -2089,7 +2242,6 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) // 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); @@ -2102,6 +2254,8 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) 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->dvisdata = Q2BSPtoM_CopyVisData(q2bsp->dvis, q2bsp->visdatasize, &mbsp->visdatasize, mbsp->dleafs, mbsp->numleafs); mbsp->dareas = Q2BSP_CopyAreas(q2bsp->dareas, q2bsp->numareas); mbsp->dareaportals = Q2BSP_CopyAreaPortals(q2bsp->dareaportals, q2bsp->numareaportals); @@ -2295,7 +2449,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) // copy or convert data q2bsp->dmodels = MBSPtoQ2_Models(mbsp->dmodels, mbsp->nummodels); - q2bsp->dvis = (dvis_t *)CopyArray(mbsp->dvisdata, mbsp->visdatasize, 1); + q2bsp->dvis = MBSPtoQ2_CopyVisData(mbsp->dvisdata, &q2bsp->visdatasize, mbsp->numleafs, mbsp->dleafs); q2bsp->dlightdata = BSP29_CopyLightData(mbsp->dlightdata, mbsp->lightdatasize); q2bsp->dentdata = BSP29_CopyEntData(mbsp->dentdata, mbsp->entdatasize); q2bsp->dleafs = MBSPtoQ2_Leafs(mbsp->dleafs, mbsp->numleafs); @@ -2350,7 +2504,7 @@ ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) // copy or convert data q2bsp->dmodels = MBSPtoQ2_Models(mbsp->dmodels, mbsp->nummodels); - q2bsp->dvis = (dvis_t *)CopyArray(mbsp->dvisdata, mbsp->visdatasize, 1); + q2bsp->dvis = MBSPtoQ2_CopyVisData(mbsp->dvisdata, &q2bsp->visdatasize, mbsp->numleafs, mbsp->dleafs); 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); @@ -3408,3 +3562,68 @@ PrintBSPFileSizes(const bspdata_t *bspdata) logprint("%7s %-12s %10i\n", "", "entdata", bsp->entdatasize); } } + +/* + =============== + CompressRow + =============== +*/ +int +CompressRow(const uint8_t *vis, const int numbytes, uint8_t *out) +{ + int i, rep; + uint8_t *dst; + + dst = out; + for (i = 0; i < numbytes; i++) { + *dst++ = vis[i]; + if (vis[i]) + continue; + + rep = 1; + for (i++; i < numbytes; i++) + if (vis[i] || rep == 255) + break; + else + rep++; + *dst++ = rep; + i--; + } + + return dst - out; +} + +/* +=================== +DecompressRow +=================== +*/ +void +DecompressRow (const uint8_t *in, const int numbytes, uint8_t *decompressed) +{ + int c; + uint8_t *out; + int row; + + row = numbytes; + out = decompressed; + + do + { + if (*in) + { + *out++ = *in++; + continue; + } + + c = in[1]; + if (!c) + Error ("DecompressVis: 0 repeat"); + in += 2; + while (c) + { + *out++ = 0; + c--; + } + } while (out - decompressed < row); +} \ No newline at end of file diff --git a/common/cmdlib.cc b/common/cmdlib.cc index 7dc1b61a..acf6b921 100644 --- a/common/cmdlib.cc +++ b/common/cmdlib.cc @@ -217,7 +217,7 @@ SetQdirFromPath(const char *basedirname, const char *path) } if (pos == -1) { - logprint("SetQ2dirFromPath: failed to find %s in '%s'", basedir, path); + logprint("SetQ2dirFromPath: failed to find %s in '%s'\n", basedir, path); ClearQdir(); return; } diff --git a/include/common/bspfile.hh b/include/common/bspfile.hh index 9183755b..68463364 100644 --- a/include/common/bspfile.hh +++ b/include/common/bspfile.hh @@ -575,10 +575,10 @@ typedef struct { // compressed bit vectors #define DVIS_PVS 0 #define DVIS_PHS 1 -typedef struct { +struct dvis_t { int32_t numclusters; - int32_t bitofs[8][2]; // bitofs[numclusters][2] -} dvis_t; + int32_t bitofs[][2]; // bitofs[numclusters][2] +}; // each area has a list of portals that lead into other areas // when portals are closed, other areas may not be visible or @@ -965,4 +965,10 @@ 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); +void +DecompressRow (const uint8_t *in, const int numbytes, uint8_t *decompressed); + +int +CompressRow(const uint8_t *vis, const int numbytes, uint8_t *out); + #endif /* __COMMON_BSPFILE_H__ */ diff --git a/light/trace_embree.cc b/light/trace_embree.cc index f9a5322e..0575f804 100644 --- a/light/trace_embree.cc +++ b/light/trace_embree.cc @@ -657,8 +657,8 @@ Embree_TraceInit(const mbsp_t *bsp) // Q2: arghrad compat: sky faces only emit sunlight if: // sky flag set, light flag set, value nonzero if ((contents & Q2_SURF_SKY) != 0 - && (contents & Q2_SURF_LIGHT) != 0 - && texinfo->value != 0) + && (!arghradcompat || ((contents & Q2_SURF_LIGHT) != 0 + && texinfo->value != 0))) { skyfaces.push_back(face); continue; diff --git a/qbsp3/common/bspfile.cc b/qbsp3/common/bspfile.cc index 61997668..6f01ea62 100644 --- a/qbsp3/common/bspfile.cc +++ b/qbsp3/common/bspfile.cc @@ -86,78 +86,6 @@ dareaportal_t dareaportals[MAX_MAP_AREAPORTALS]; uint8_t dpop[256]; -/* -=============== -CompressVis - -=============== -*/ -int CompressVis (uint8_t *vis, uint8_t *dest) -{ - int j; - int rep; - int visrow; - uint8_t *dest_p; - - dest_p = dest; -// visrow = (r_numvisleafs + 7)>>3; - visrow = (dvis->numclusters + 7)>>3; - - for (j=0 ; j>3; - row = (dvis->numclusters+7)>>3; - out = decompressed; - - do - { - if (*in) - { - *out++ = *in++; - continue; - } - - c = in[1]; - if (!c) - Error ("DecompressVis: 0 repeat"); - in += 2; - while (c) - { - *out++ = 0; - c--; - } - } while (out - decompressed < row); -} - //============================================================================= /* diff --git a/qbsp3/common/bspfile.h b/qbsp3/common/bspfile.h index 7e388a4b..02f11053 100644 --- a/qbsp3/common/bspfile.h +++ b/qbsp3/common/bspfile.h @@ -80,9 +80,6 @@ extern dbrushside_t dbrushsides[MAX_MAP_BRUSHSIDES]; extern uint8_t dpop[256]; -void DecompressVis (uint8_t *in, uint8_t *decompressed); -int CompressVis (uint8_t *vis, uint8_t *dest); - void LoadBSPFile (char *filename); void LoadBSPFileTexinfo (char *filename); // just for qdata void WriteBSPFile (char *filename); diff --git a/vis/vis.cc b/vis/vis.cc index afe29eaf..84c1813f 100644 --- a/vis/vis.cc +++ b/vis/vis.cc @@ -31,10 +31,12 @@ static uint8_t *vismap; static uint8_t *vismap_p; static uint8_t *vismap_end; // past visfile -int originalvismapsize; +uint32_t originalvismapsize; uint8_t *uncompressed; // [leafbytes_real*portalleafs] +uint8_t *uncompressed_q2; // [leafbytes*portalleafs] + int leafbytes; // (portalleafs+63)>>3 int leaflongs; int leafbytes_real; // (portalleafs_real+63)>>3 @@ -545,36 +547,6 @@ LeafThread(void *arg) return NULL; } -/* - =============== - CompressRow - =============== -*/ -static int -CompressRow(const uint8_t *vis, const int numbytes, uint8_t *out) -{ - int i, rep; - uint8_t *dst; - - dst = out; - for (i = 0; i < numbytes; i++) { - *dst++ = vis[i]; - if (vis[i]) - continue; - - rep = 1; - for (i++; i < numbytes; i++) - if (vis[i] || rep == 255) - break; - else - rep++; - *dst++ = rep; - i--; - } - - return dst - out; -} - /* =============== @@ -586,7 +558,7 @@ CompressRow(const uint8_t *vis, const int numbytes, uint8_t *out) int64_t totalvis; static void -LeafFlow(int leafnum, mleaf_t *dleaf) +LeafFlow(int leafnum, mleaf_t *dleaf, const mbsp_t *bsp) { leaf_t *leaf; uint8_t *outbuffer; @@ -599,7 +571,7 @@ LeafFlow(int leafnum, mleaf_t *dleaf) /* * flow through all portals, collecting visible bits */ - outbuffer = uncompressed + leafnum * leafbytes; + outbuffer = (bsp->loadversion == &bspver_q2 || bsp->loadversion == &bspver_qbism ? uncompressed_q2 : uncompressed) + leafnum * leafbytes; leaf = &leafs[leafnum]; for (i = 0; i < leaf->numportals; i++) { p = leaf->portals[i]; @@ -645,8 +617,8 @@ LeafFlow(int leafnum, mleaf_t *dleaf) } -void -ClusterFlow(int clusternum, leafbits_t *buffer) +static void +ClusterFlow(int clusternum, leafbits_t *buffer, const mbsp_t *bsp) { leaf_t *leaf; uint8_t *outbuffer; @@ -680,11 +652,22 @@ ClusterFlow(int clusternum, leafbits_t *buffer) * Now expand the clusters into the full leaf visibility map */ numvis = 0; - outbuffer = uncompressed + clusternum * leafbytes_real; - for (i = 0; i < portalleafs_real; i++) { - if (TestLeafBit(buffer, clustermap[i])) { - outbuffer[i >> 3] |= (1 << (i & 7)); - numvis++; + + if (bsp->loadversion == &bspver_q2 || bsp->loadversion == &bspver_qbism) { + outbuffer = uncompressed_q2 + clusternum * leafbytes; + for (i = 0; i < portalleafs; i++) { + if (TestLeafBit(buffer, i)) { + outbuffer[i >> 3] |= (1 << (i & 7)); + numvis++; + } + } + } else { + outbuffer = uncompressed + clusternum * leafbytes_real; + for (i = 0; i < portalleafs_real; i++) { + if (TestLeafBit(buffer, clustermap[i])) { + outbuffer[i >> 3] |= (1 << (i & 7)); + numvis++; + } } } @@ -705,8 +688,13 @@ ClusterFlow(int clusternum, leafbits_t *buffer) } /* Allocate for worst case where RLE might grow the data (unlikely) */ - compressed = static_cast(malloc(portalleafs_real * 2 / 8)); - len = CompressRow(outbuffer, (portalleafs_real + 7) >> 3, compressed); + if (bsp->loadversion == &bspver_q2 || bsp->loadversion == &bspver_qbism) { + compressed = static_cast(malloc(portalleafs * 2 / 8)); + len = CompressRow(outbuffer, (portalleafs + 7) >> 3, compressed); + } else { + compressed = static_cast(malloc(portalleafs_real * 2 / 8)); + len = CompressRow(outbuffer, (portalleafs_real + 7) >> 3, compressed); + } dest = vismap_p; vismap_p += len; @@ -751,6 +739,8 @@ CalcPortalVis(const mbsp_t *bsp) } RunThreadsOn(startcount, numportals * 2, LeafThread, NULL); + SaveVisState(); + if (verbose) { logprint("portalcheck: %i portaltest: %i portalpass: %i\n", c_portalcheck, c_portaltest, c_portalpass); @@ -785,7 +775,7 @@ CalcVis(const mbsp_t *bsp) // if (portalleafs == portalleafs_real) { for (i = 0; i < portalleafs; i++) - LeafFlow(i, &bsp->dleafs[i + 1]); + LeafFlow(i, &bsp->dleafs[i + 1], bsp); } else { leafbits_t *buffer; @@ -793,7 +783,7 @@ CalcVis(const mbsp_t *bsp) buffer = static_cast(malloc(LeafbitsSize(portalleafs))); for (i = 0; i < portalleafs; i++) { memset(buffer, 0, LeafbitsSize(portalleafs)); - ClusterFlow(i, buffer); + ClusterFlow(i, buffer, bsp); } free(buffer); @@ -1070,9 +1060,17 @@ LoadPortals(char *name, mbsp_t *bsp) count = fscanf(f, "%i\n%i\n", &portalleafs, &numportals); if (count != 2) Error("%s: unable to parse %s HEADER\n", __func__, PORTALFILE); - portalleafs_real = portalleafs; - logprint("%6d leafs\n", portalleafs); - logprint("%6d portals\n", numportals); + + if (bsp->loadversion == &bspver_q2 || bsp->loadversion == &bspver_qbism) { + portalleafs_real = bsp->numleafs; + logprint("%6d leafs\n", portalleafs_real); + logprint("%6d clusters\n", portalleafs); + logprint("%6d portals\n", numportals); + } else { + portalleafs_real = portalleafs; + logprint("%6d leafs\n", portalleafs); + logprint("%6d portals\n", numportals); + } } else if (!strcmp(magic, PORTALFILE2)) { count = fscanf(f, "%i\n%i\n%i\n", &portalleafs_real, &portalleafs, &numportals); @@ -1103,7 +1101,11 @@ LoadPortals(char *name, mbsp_t *bsp) leafs = static_cast(malloc(portalleafs * sizeof(leaf_t))); memset(leafs, 0, portalleafs * sizeof(leaf_t)); - originalvismapsize = portalleafs_real * ((portalleafs_real + 7) / 8); + if (bsp->loadversion == &bspver_q2 || bsp->loadversion == &bspver_qbism) { + originalvismapsize = portalleafs * ((portalleafs + 7) / 8); + } else { + originalvismapsize = portalleafs_real * ((portalleafs_real + 7) / 8); + } // FIXME - more intelligent allocation? bsp->dvisdata = static_cast(malloc(MAX_MAP_VISIBILITY)); @@ -1178,7 +1180,13 @@ LoadPortals(char *name, mbsp_t *bsp) } /* Load the cluster expansion map if needed */ - if (portalleafs != portalleafs_real) { + if (bsp->loadversion == &bspver_q2 || bsp->loadversion == &bspver_qbism) { + clustermap = static_cast(malloc(portalleafs_real * sizeof(int))); + + for (int32_t i = 0; i < bsp->numleafs; i++) { + clustermap[i] = bsp->dleafs[i + 1].cluster; + } + } else if (portalleafs != portalleafs_real) { clustermap = static_cast(malloc(portalleafs_real * sizeof(int))); if (!strcmp(magic, PORTALFILE2)) { for (i = 0; i < portalleafs; i++) { @@ -1325,7 +1333,11 @@ main(int argc, char **argv) StripExtension(statetmpfile); DefaultExtension(statetmpfile, ".vi0"); - uncompressed = static_cast(calloc(portalleafs, leafbytes_real)); + if (bsp->loadversion != &bspver_q2 && bsp->loadversion != &bspver_qbism) { + uncompressed = static_cast(calloc(portalleafs, leafbytes_real)); + } else { + uncompressed_q2 = static_cast(calloc(portalleafs, leafbytes)); + } // CalcPassages (); @@ -1335,10 +1347,13 @@ main(int argc, char **argv) logprint("c_chains: %lu\n", c_chains); bsp->visdatasize = vismap_p - bsp->dvisdata; - logprint("visdatasize:%i compressed from %i\n", + logprint("visdatasize:%i compressed from %u\n", bsp->visdatasize, originalvismapsize); - - CalcAmbientSounds(bsp); + + // no ambient sounds for Q2 + if (bsp->loadversion != &bspver_q2 && bsp->loadversion != &bspver_qbism) { + CalcAmbientSounds(bsp); + } /* Convert data format back if necessary */ ConvertBSPFormat(&bspdata, loadversion);