shithub: qk1

Download patch

ref: caf029c6244503aa40992ba5b3750850e90930e3
parent: aa84da621a8b302933639033ffbb5a131536264c
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Wed Oct 11 15:25:01 EDT 2023

fix pvs for huge maps; define and use mclipnode for bigger maps; few short→int retypings

--- a/bspfile.h
+++ b/bspfile.h
@@ -4,13 +4,11 @@
 
 #define	MAX_MAP_MODELS		256
 #define	MAX_MAP_BRUSHES		4096
-#define	MAX_MAP_ENTITIES	1024
 #define	MAX_MAP_ENTSTRING	65536
 
 #define	MAX_MAP_PLANES		32767
 #define	MAX_MAP_NODES		32767		// because negative shorts are contents
 #define	MAX_MAP_CLIPNODES	32767		//
-#define	MAX_MAP_LEAFS		65535
 #define	MAX_MAP_VERTS		65535
 #define	MAX_MAP_FACES		65535
 #define	MAX_MAP_MARKSURFACES 65535
--- a/model.c
+++ b/model.c
@@ -12,7 +12,8 @@
 void Mod_LoadAliasModel (model_t *mod, void *buffer);
 model_t *Mod_LoadModel (model_t *mod, qboolean crash);
 
-byte	mod_novis[MAX_MAP_LEAFS/8];
+static byte *mod_novis;
+static int mod_novis_size;
 
 #define	MAX_MOD_KNOWN	4096
 model_t	*mod_known;
@@ -26,7 +27,6 @@
 void
 Mod_Init(void)
 {
-	memset(mod_novis, 0xff, sizeof mod_novis);
 	mod_known = Hunk_Alloc(MAX_MOD_KNOWN * sizeof(*mod_known));
 }
 
@@ -88,12 +88,17 @@
 */
 byte *Mod_DecompressVis (byte *in, model_t *model)
 {
-	static byte	decompressed[MAX_MAP_LEAFS/8];
+	static byte	*decompressed;
+	static int decompressed_size;
 	int		c;
 	byte	*out;
 	int		row;
 
 	row = (model->numleafs+7)>>3;	
+	if(decompressed == nil || row > decompressed_size){
+		decompressed_size = (row + 15) & ~15;
+		decompressed = realloc(decompressed, decompressed_size);
+	}
 	out = decompressed;
 
 	if (!in)
@@ -128,8 +133,17 @@
 
 byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model)
 {
-	if (leaf == model->leafs)
+	int sz;
+	sz = (model->numleafs+7)/8;
+	sz = (sz+3)&~3;
+	if (leaf == model->leafs) {
+		if(mod_novis == nil || mod_novis_size < sz){
+			mod_novis = realloc(mod_novis, sz);
+			mod_novis_size = sz;
+		}
+		memset(mod_novis, 0xff, mod_novis_size);
 		return mod_novis;
+	}
 	return Mod_DecompressVis (leaf->compressed_vis, model);
 }
 
@@ -849,13 +863,15 @@
 		
 		for (j=0 ; j<2 ; j++)
 		{
-			p = (unsigned short)LittleShort (in->children[j]);
+			p = (ushort)LittleShort (in->children[j]);
 			if (p < count)
 				out->children[j] = loadmodel->nodes + p;
 			else{
-				if((p = 0xffff - p) >= count)
-					p = 0;
-				out->children[j] = (mnode_t *)(loadmodel->leafs + p);
+				p = -1 - (signed)(0xffff0000 | p);
+				if(p >= 0 && p < loadmodel->numleafs)
+					out->children[j] = (mnode_t *)(loadmodel->leafs + p);
+				else
+					Con_Printf("Mod_LoadNodes: invalid node child\n");
 			}
 		}
 	}
@@ -917,7 +933,8 @@
 */
 void Mod_LoadClipnodes (lump_t *l)
 {
-	dclipnode_t *in, *out;
+	dclipnode_t *in;
+	mclipnode_t	*out;
 	int			i, count;
 	hull_t		*hull;
 
@@ -976,7 +993,7 @@
 void Mod_MakeHull0 (void)
 {
 	mnode_t		*in, *child;
-	dclipnode_t *out;
+	mclipnode_t *out;
 	int			i, j, count;
 	hull_t		*hull;
 	
--- a/model.h
+++ b/model.h
@@ -66,7 +66,7 @@
 // !!! if this is changed, it must be changed in asm_draw.h too !!!
 typedef struct
 {
-	unsigned short	v[2];
+	unsigned int	v[2];
 	unsigned int	cachededgeoffset;
 } medge_t;
 
@@ -94,7 +94,7 @@
 // surface generation data
 	struct surfcache_s	*cachespots[MIPLEVELS];
 
-	short		texturemins[2];
+	int		texturemins[2];
 	short		extents[2];
 
 	mtexinfo_t	*texinfo;
@@ -110,7 +110,7 @@
 	int			contents;		// 0, to differentiate from leafs
 	int			visframe;		// node needs to be traversed if current
 	
-	short		minmaxs[6];		// for bounding box culling
+	int		minmaxs[6];		// for bounding box culling
 
 	struct mnode_s	*parent;
 
@@ -118,8 +118,8 @@
 	mplane_t	*plane;
 	struct mnode_s	*children[2];	
 
-	unsigned short		firstsurface;
-	unsigned short		numsurfaces;
+	unsigned int		firstsurface;
+	unsigned int		numsurfaces;
 } mnode_t;
 
 
@@ -130,7 +130,7 @@
 	int			contents;		// wil be a negative contents number
 	int			visframe;		// node needs to be traversed if current
 
-	short		minmaxs[6];		// for bounding box culling
+	int		minmaxs[6];		// for bounding box culling
 
 	struct mnode_s	*parent;
 
@@ -144,10 +144,16 @@
 	byte		ambient_sound_level[Namb];
 } mleaf_t;
 
+typedef struct
+{
+	int planenum;
+	int children[2];
+}mclipnode_t;
+
 // !!! if this is changed, it must be changed in asm_i386.h too !!!
 typedef struct
 {
-	dclipnode_t	*clipnodes;
+	mclipnode_t	*clipnodes;
 	mplane_t	*planes;
 	int			firstclipnode;
 	int			lastclipnode;
@@ -326,7 +332,7 @@
 	int			*surfedges;
 
 	int			numclipnodes;
-	dclipnode_t	*clipnodes;
+	mclipnode_t	*clipnodes;
 
 	int			nummarksurfaces;
 	msurface_t	**marksurfaces;
--- a/pr_cmds.c
+++ b/pr_cmds.c
@@ -635,11 +635,12 @@
 
 //============================================================================
 
-byte	checkpvs[MAX_MAP_LEAFS/8];
+static byte *checkpvs;
+static int checkpvs_size;
 
 int PF_newcheckclient (int check)
 {
-	int		i;
+	int		i, size;
 	byte	*pvs;
 	edict_t	*ent;
 	mleaf_t	*leaf;
@@ -682,7 +683,12 @@
 	VectorAdd (ent->v.origin, ent->v.view_ofs, org);
 	leaf = Mod_PointInLeaf (org, sv.worldmodel);
 	pvs = Mod_LeafPVS (leaf, sv.worldmodel);
-	memcpy (checkpvs, pvs, (sv.worldmodel->numleafs+7)>>3 );
+	size = (sv.worldmodel->numleafs+7)>>3;
+	if(checkpvs == nil || size > checkpvs_size){
+		checkpvs = realloc(checkpvs, size);
+		checkpvs_size = size;
+	}
+	memcpy (checkpvs, pvs, size);
 
 	return i;
 }
--- a/sv_main.c
+++ b/sv_main.c
@@ -131,6 +131,9 @@
     }
     
 	ent = NUM_FOR_EDICT(entity);
+	if(ent > 8191 || channel > 7 || sound_num > 255){ // FIXME(sigrid) - better protocol
+		return;
+	}
 
 	channel = (ent<<3) | channel;
 
@@ -336,8 +339,9 @@
 =============================================================================
 */
 
-int		fatbytes;
-byte	fatpvs[MAX_MAP_LEAFS/8];
+static int fatbytes;
+static byte	*fatpvs;
+static int fatpvs_size;
 
 void SV_AddToFatPVS (vec3_t org, mnode_t *node)
 {
@@ -385,6 +389,10 @@
 byte *SV_FatPVS (vec3_t org)
 {
 	fatbytes = (sv.worldmodel->numleafs+31)>>3;
+	if(fatpvs == nil || fatbytes > fatpvs_size){
+		fatpvs = realloc(fatpvs, fatbytes);
+		fatpvs_size = fatbytes;
+	}
 	memset(fatpvs, 0, fatbytes);
 	SV_AddToFatPVS (org, sv.worldmodel->nodes);
 	return fatpvs;
@@ -416,11 +424,15 @@
 	ent = NEXT_EDICT(sv.edicts);
 	for (e=1 ; e<sv.num_edicts ; e++, ent = NEXT_EDICT(ent))
 	{
+		if (e > 65535) // FIXME(sigrid) - better protocol
+			continue;
 // ignore if not touching a PV leaf
 		if (ent != clent)	// clent is ALLWAYS sent
 		{
 // ignore ents without visible models
 			if (!ent->v.modelindex || !*PR_Str(ent->v.model))
+				continue;
+			if(ent->v.modelindex > 0xff) // FIXME(sigrid) - better protocol
 				continue;
 
 			for (i=0 ; i < ent->num_leafs ; i++)
--- a/world.c
+++ b/world.c
@@ -37,7 +37,7 @@
 
 
 static	hull_t		box_hull;
-static	dclipnode_t	box_clipnodes[6];
+static	mclipnode_t	box_clipnodes[6];
 static	mplane_t	box_planes[6];
 
 /*
@@ -444,7 +444,7 @@
 int SV_HullPointContents (hull_t *hull, int num, vec3_t p)
 {
 	float		d;
-	dclipnode_t	*node;
+	mclipnode_t	*node;
 	mplane_t	*plane;
 
 	while (num >= 0)
@@ -531,7 +531,7 @@
 */
 qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, trace_t *trace)
 {
-	dclipnode_t	*node;
+	mclipnode_t	*node;
 	mplane_t	*plane;
 	float		t1, t2;
 	float		frac;