shithub: qk1

Download patch

ref: 8d1771774944a92cfd9650ba36007889e9b3e861
parent: 00cb56d2fbc9dfd9d920112694c4d20987a15b85
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Tue Oct 10 00:01:51 EDT 2023

dynamically adjust surface/edge/span limits

--- a/r_draw.c
+++ b/r_draw.c
@@ -353,7 +353,6 @@
 	r_emitted = 1;
 }
 
-
 /*
 ================
 R_RenderFace
--- a/r_edge.c
+++ b/r_edge.c
@@ -51,7 +51,41 @@
 void R_LeadingEdgeBackwards (edge_t *edge);
 void R_TrailingEdge (surf_t *surf, edge_t *edge);
 
+void R_SetupEdges(void)
+{
+	while(r_outofedges > 0){
+		r_edges = Hunk_Double(r_edges);
+		r_outofedges -= r_numallocatededges;
+		r_numallocatededges *= 2;
+	}
+	r_outofedges = 0;
+	edge_p = r_edges;
+	edge_max = &r_edges[r_numallocatededges];
+}
 
+void R_SetupSurfaces(void)
+{
+	while(r_outofsurfaces > 0){
+		surfaces = Hunk_Double(surfaces);
+		r_outofsurfaces -= r_cnumsurfs;
+		r_cnumsurfs *= 2;
+	}
+	r_outofsurfaces = 0;
+	surface_p = surfaces;
+	surf_max = &surfaces[r_cnumsurfs];
+}
+
+void R_SetupSpans(void)
+{
+	while(r_outofspans > 0){
+		r_basespans = Hunk_Double(r_basespans);
+		r_outofspans -= r_numallocatedbasespans;
+		r_numallocatedbasespans *= 2;
+	}
+	r_outofspans = 0;
+}
+
+
 //=============================================================================
 
 
@@ -97,7 +131,6 @@
 	}
 }
 
-
 /*
 ==============
 R_BeginEdgeFrame
@@ -107,8 +140,8 @@
 {
 	int		v;
 
-	edge_p = r_edges;
-	edge_max = &r_edges[r_numallocatededges];
+	R_SetupEdges();
+	R_SetupSurfaces();
 
 	surface_p = &surfaces[2];	// background is surface 1,
 								//  surface 0 is a dummy
@@ -610,7 +643,6 @@
 	R_CleanupSpan ();
 }
 
-
 /*
 ==============
 R_ScanEdges
@@ -629,10 +661,10 @@
 	espan_t	*basespan_p;
 	surf_t	*s;
 
+	R_SetupSpans();
 	basespan_p = (espan_t *)
 			((uintptr)(r_basespans + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
-	max_span_p = &basespan_p[MAXSPANS - r_refdef.vrect.width];
-
+	max_span_p = &basespan_p[r_numallocatedbasespans - r_refdef.vrect.width];
 	span_p = basespan_p;
 
 // clear active edges to just the background edges around the whole screen
@@ -686,6 +718,7 @@
 	// the next scan
 		if (span_p >= max_span_p)
 		{
+			r_outofspans++;
 			if (r_drawculledpolys)
 			{
 				R_DrawCulledPolys ();
--- a/r_local.h
+++ b/r_local.h
@@ -239,6 +239,7 @@
 
 extern int		r_outofsurfaces;
 extern int		r_outofedges;
+extern int		r_outofspans;
 
 extern mvertex_t	*r_pcurrentvertbase;
 extern int			r_maxvalidedgeoffset;
--- a/r_main.c
+++ b/r_main.c
@@ -20,6 +20,7 @@
 float		r_aliasuvscale = 1.0;
 int			r_outofsurfaces;
 int			r_outofedges;
+int			r_outofspans;
 
 qboolean	r_dowarp, r_dowarpold, r_viewchanged;
 
@@ -205,6 +206,8 @@
 	D_Init ();
 }
 
+void R_SetupSurfaces(void);
+
 /*
 ===============
 R_NewMap
@@ -226,11 +229,7 @@
 
 	r_cnumsurfs = MAXSURFACES;
 	surfaces = Hunk_Alloc(r_cnumsurfs * sizeof *surfaces);
-	surface_p = surfaces;
-	surf_max = &surfaces[r_cnumsurfs];
-	// surface 0 doesn't really exist; it's just a dummy because index 0
-	// is used to indicate no edge attached to surface
-	surfaces--;
+	R_SetupSurfaces();
 
 	r_maxedgesseen = 0;
 	r_maxsurfsseen = 0;
@@ -817,7 +816,6 @@
 	if (!(r_drawpolys | r_drawculledpolys))
 		R_ScanEdges ();
 }
-
 
 /*
 ================
--- a/r_misc.c
+++ b/r_misc.c
@@ -429,8 +429,6 @@
 	r_drawnpolycount = 0;
 	r_wholepolycount = 0;
 	r_amodels_drawn = 0;
-	r_outofsurfaces = 0;
-	r_outofedges = 0;
 
 	D_SetupFrame ();
 }
--- a/r_shared.h
+++ b/r_shared.h
@@ -36,9 +36,9 @@
 extern	entity_t		*currententity;
 
 // NOTE: these are only initial values. limits are supposed to scale up dynamically
-#define	MAXEDGES			8192
-#define MAXSURFACES			8192
-#define	MAXSPANS			8192
+#define	MAXEDGES			32
+#define MAXSURFACES			800
+#define	MAXSPANS			3000
 
 // !!! if this is changed, it must be changed in asm_draw.h too !!!
 typedef struct espan_s
--- a/zone.c
+++ b/zone.c
@@ -76,6 +76,31 @@
 }
 
 void *
+Hunk_Double(void *p)
+{
+	mem_t *m, *n;
+	ulong t;
+
+	m = p;
+	m--;
+	t = getmalloctag(m);
+	n = realloc(m, sizeof(*m) + m->size*2);
+	if(m == nil)
+		sysfatal("Hunk_Double: %r");
+	if(hunk_head == m)
+		hunk_head = n;
+	m = n;
+	setmalloctag(m, t);
+	memset((byte*)(m+1) + m->size, 0, m->size);
+	m->size *= 2;
+	if(m->prev != nil)
+		m->prev->next = m;
+	if(m->next != nil)
+		m->next->prev = m;
+	return m+1;
+}
+
+void *
 Hunk_Mark(void)
 {
 	return hunk_head;
--- a/zone.h
+++ b/zone.h
@@ -9,6 +9,7 @@
 int Hunk_From(void *p);
 void Hunk_CacheFrom(mem_user_t *c, void *p);
 void *Hunk_Alloc(int size);
+void *Hunk_Double(void *p);
 void *Hunk_Mark(void);
 void Hunk_FreeToMark(void *mark);
 void *Hunk_TempAlloc(int size);