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);