[qfvis] Optionally use utf8 to encode run lengths

Adds 50 bytes to marcher's fat-pvs, but removes about 4.7MB from
ad_tear's fat-pvs.
This commit is contained in:
Bill Currie 2021-07-27 21:47:19 +09:00
parent 5b4428420e
commit e39bc83a6a
5 changed files with 40 additions and 16 deletions

View file

@ -36,6 +36,7 @@ typedef struct {
qboolean minimal;
qboolean no_auto_pvs;
qboolean fat_pvs;
qboolean utf8;
int level;
size_t portal_limit;
struct dstring_s *bspfile;

View file

@ -214,7 +214,9 @@ void PortalBase (basethread_t *thread, portal_t *portal);
void PortalFlow (threaddata_t *data, portal_t *portal);
void CalcAmbientSounds (void);
int CompressRow (byte *dest, const byte *vis, unsigned num_leafs);
struct sizebuf_s;
int CompressRow (struct sizebuf_s *dest, const byte *vis, unsigned num_leafs,
int utf8);
void CalcFatPVS (void);

View file

@ -221,7 +221,7 @@ compress_thread (void *d)
{
fatstats_t stats = { };
int thread = (intptr_t) d;
byte compressed[(visbytes * 3) / 2];
qboolean rle = options.utf8;
while (1) {
unsigned leaf_num = next_leaf ();
@ -231,10 +231,10 @@ compress_thread (void *d)
if (leaf_num == ~0u) {
break;
}
sizebuf_t *compressed = &cmp_pvs[leaf_num];
const byte *fat_bytes = (const byte *) fat_pvs[leaf_num].map;
int cmp_bytes = CompressRow (compressed, fat_bytes, num_leafs);
SZ_Write (&cmp_pvs[leaf_num], compressed, cmp_bytes);
stats.fat_bytes += cmp_bytes;
int bytes = CompressRow (compressed, fat_bytes, num_leafs, rle);
stats.fat_bytes += bytes;
}
update_stats (&stats);
return 0;
@ -275,6 +275,9 @@ CalcFatPVS (void)
pvsfile->version = PVS_VERSION;
pvsfile->md4_offset = 0; //FIXME add
pvsfile->flags = PVS_IS_FATPVS;
if (options.utf8) {
pvsfile->flags |= PVS_UTF8_RLE;
}
pvsfile->visleafs = num_leafs;
for (unsigned i = 0; i < num_leafs; i++) {
unsigned size = cmp_pvs[i].cursize;

View file

@ -51,11 +51,13 @@ enum {
OPT_PORTAL_LIMIT,
OPT_FAT_PVS,
OPT_FULL_PVS,
OPT_UTF8,
};
static struct option const long_options[] = {
{"fat-pvs", no_argument, 0, OPT_FAT_PVS},
{"full-pvs", no_argument, 0, OPT_FULL_PVS},
{"utf8", no_argument, 0, OPT_UTF8},
{"quiet", no_argument, 0, 'q'},
{"verbose", no_argument, 0, 'v'},
{"help", no_argument, 0, 'h'},
@ -151,6 +153,9 @@ DecodeArgs (int argc, char **argv)
case OPT_FULL_PVS:
options.fat_pvs = true;
break;
case OPT_UTF8:
options.utf8 = true;
break;
case 'm': // minimal vis
options.minimal = true;
break;

View file

@ -54,8 +54,9 @@
#include "QF/cmem.h"
#include "QF/dstring.h"
#include "QF/mathlib.h"
#include "QF/qtypes.h"
#include "QF/msg.h"
#include "QF/quakefs.h"
#include "QF/sizebuf.h"
#include "QF/sys.h"
#include "tools/qfvis/include/vis.h"
@ -784,12 +785,14 @@ RunThreads (void *(*thread_func) (void *), int (*progress)(int, int))
}
int
CompressRow (byte *dest, const byte *vis, unsigned num_leafs)
CompressRow (sizebuf_t *dest, const byte *vis, unsigned num_leafs, int utf8)
{
int rep, visrow, j;
byte *dest_p;
// if we ever need 2GB (32Gb) of vis data for a single leaf...
int maxrep = utf8 ? 0x7fffffff : 255;
dest_p = dest;
dest_p = dest->data;
visrow = (num_leafs + 7) >> 3;
for (j = 0; j < visrow; j++) {
@ -799,15 +802,21 @@ CompressRow (byte *dest, const byte *vis, unsigned num_leafs)
rep = 1;
for (j++; j < visrow; j++)
if (vis[j] || rep == 255)
if (vis[j] || rep == maxrep)
break;
else
rep++;
*dest_p++ = rep;
if (utf8) {
dest->cursize = dest_p - dest->data;
MSG_WriteUTF8 (dest, rep);
dest_p = dest->data + dest->cursize;
} else {
*dest_p++ = rep;
}
j--;
}
return dest_p - dest;
dest->cursize = dest_p - dest->data;
return dest->cursize;
}
static void
@ -835,7 +844,11 @@ void
ClusterFlow (int clusternum)
{
set_t *visclusters;
byte compressed[MAP_PVS_BYTES];
sizebuf_t compressed = {
.maxsize = (bitbytes_l * 3) / 2,
.data = alloca ((bitbytes_l * 3) / 2)
};
byte *outbuffer;
int numvis, i;
cluster_t *cluster;
@ -846,7 +859,7 @@ ClusterFlow (int clusternum)
// flow through all portals, collecting visible bits
memset (compressed, 0, sizeof (compressed));
memset (compressed.data, 0, compressed.maxsize);
visclusters = set_new ();
for (i = 0; i < cluster->numportals; i++) {
portal = cluster->portals[i];
@ -872,9 +885,9 @@ ClusterFlow (int clusternum)
printf ("cluster %4i : %4i visible\n", clusternum, numvis);
totalvis += numvis;
i = CompressRow (compressed, outbuffer, numrealleafs);
i = CompressRow (&compressed, outbuffer, numrealleafs, 0);
cluster->visofs = visdata->size;
dstring_append (visdata, (char *) compressed, i);
dstring_append (visdata, (char *) compressed.data, i);
}
static int