Q2bsp VIS support (#315)
* 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 * Q2 VIS Almost working, just in-game is not 100% functional * PHS! Q2 VIS! * Fix missing loadversion assignment Fix missing \n * Implement q2bsp -> mbsp visdata copy fix sky lighting to use arghrad compat
This commit is contained in:
parent
968a840e47
commit
90973e1198
|
|
@ -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<uint8_t> 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<uint8_t> 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<<k)) )
|
||||
continue;
|
||||
// OR this pvs row into the phs
|
||||
int32_t index = ((j<<3)+k);
|
||||
if (index >= 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<uint8_t> 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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<visrow ; j++)
|
||||
{
|
||||
*dest_p++ = vis[j];
|
||||
if (vis[j])
|
||||
continue;
|
||||
|
||||
rep = 1;
|
||||
for ( j++; j<visrow ; j++)
|
||||
if (vis[j] || rep == 255)
|
||||
break;
|
||||
else
|
||||
rep++;
|
||||
*dest_p++ = rep;
|
||||
j--;
|
||||
}
|
||||
|
||||
return dest_p - dest;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
DecompressVis
|
||||
===================
|
||||
*/
|
||||
void DecompressVis (uint8_t *in, uint8_t *decompressed)
|
||||
{
|
||||
int c;
|
||||
uint8_t *out;
|
||||
int row;
|
||||
|
||||
// row = (r_numvisleafs+7)>>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);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
121
vis/vis.cc
121
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<uint8_t *>(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<uint8_t *>(malloc(portalleafs * 2 / 8));
|
||||
len = CompressRow(outbuffer, (portalleafs + 7) >> 3, compressed);
|
||||
} else {
|
||||
compressed = static_cast<uint8_t *>(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<leafbits_t *>(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<leaf_t *>(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<uint8_t *>(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<int *>(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<int *>(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<uint8_t *>(calloc(portalleafs, leafbytes_real));
|
||||
if (bsp->loadversion != &bspver_q2 && bsp->loadversion != &bspver_qbism) {
|
||||
uncompressed = static_cast<uint8_t *>(calloc(portalleafs, leafbytes_real));
|
||||
} else {
|
||||
uncompressed_q2 = static_cast<uint8_t *>(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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue