Skip to content

Commit

Permalink
allocate on the heap in Sky_ClipPoly if MAX_CLIP_VERTS limit is reached
Browse files Browse the repository at this point in the history
Fixes a Sys_Error in lim_daviddg map from Liminal Spaces Jam
  • Loading branch information
sezero committed Jul 25, 2024
1 parent 7e7a1b6 commit e35ecad
Showing 1 changed file with 48 additions and 18 deletions.
66 changes: 48 additions & 18 deletions Quake/gl_sky.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,14 +495,16 @@ static void Sky_ClipPoly (int nump, vec3_t vecs, int stage)
float *v;
qboolean front, back;
float d, e;
float dists[MAX_CLIP_VERTS];
int sides[MAX_CLIP_VERTS];
vec3_t newv[2][MAX_CLIP_VERTS];
int newc[2];
int i, j;

if (nump > MAX_CLIP_VERTS-2)
Sys_Error ("Sky_ClipPoly: MAX_CLIP_VERTS");
const int max_clip_verts = nump + 2;
const int on_heap = max_clip_verts > MAX_CLIP_VERTS;
int *sides;
float *dists;
vec3_t *newv_0;
vec3_t *newv_1;

if (stage == 6) // fully clipped
{
Sky_ProjectPoly (nump, vecs);
Expand All @@ -511,6 +513,10 @@ static void Sky_ClipPoly (int nump, vec3_t vecs, int stage)

front = back = false;
norm = skyclip[stage];

sides = (int *) (on_heap ? malloc(max_clip_verts * sizeof(int)) : alloca(max_clip_verts * sizeof(int)));
dists = (float *) (on_heap ? malloc(max_clip_verts * sizeof(float)) : alloca(max_clip_verts * sizeof(float)));

for (i=0, v = vecs ; i<nump ; i++, v+=3)
{
d = DotProduct (v, norm);
Expand All @@ -532,6 +538,10 @@ static void Sky_ClipPoly (int nump, vec3_t vecs, int stage)
if (!front || !back)
{ // not clipped
Sky_ClipPoly (nump, vecs, stage+1);
if (on_heap) {
free(dists);
free(sides);
}
return;
}

Expand All @@ -541,22 +551,26 @@ static void Sky_ClipPoly (int nump, vec3_t vecs, int stage)
VectorCopy (vecs, (vecs+(i*3)) );
newc[0] = newc[1] = 0;

// 2-dim vec3_t newv[2][MAX_CLIP_VERTS]; as 2 arrays
newv_0 = (vec3_t *) (on_heap ? malloc(max_clip_verts * sizeof(vec3_t)) : alloca(max_clip_verts * sizeof(vec3_t)));
newv_1 = (vec3_t *) (on_heap ? malloc(max_clip_verts * sizeof(vec3_t)) : alloca(max_clip_verts * sizeof(vec3_t)));

for (i=0, v = vecs ; i<nump ; i++, v+=3)
{
switch (sides[i])
{
case SIDE_FRONT:
VectorCopy (v, newv[0][newc[0]]);
VectorCopy (v, newv_0[newc[0]]);
newc[0]++;
break;
case SIDE_BACK:
VectorCopy (v, newv[1][newc[1]]);
VectorCopy (v, newv_1[newc[1]]);
newc[1]++;
break;
case SIDE_ON:
VectorCopy (v, newv[0][newc[0]]);
VectorCopy (v, newv_0[newc[0]]);
newc[0]++;
VectorCopy (v, newv[1][newc[1]]);
VectorCopy (v, newv_1[newc[1]]);
newc[1]++;
break;
}
Expand All @@ -568,16 +582,24 @@ static void Sky_ClipPoly (int nump, vec3_t vecs, int stage)
for (j=0 ; j<3 ; j++)
{
e = v[j] + d*(v[j+3] - v[j]);
newv[0][newc[0]][j] = e;
newv[1][newc[1]][j] = e;
newv_0[newc[0]][j] = e;
newv_1[newc[1]][j] = e;
}
newc[0]++;
newc[1]++;
}

// continue
Sky_ClipPoly (newc[0], newv[0][0], stage+1);
Sky_ClipPoly (newc[1], newv[1][0], stage+1);
Sky_ClipPoly (newc[0], newv_0[0], stage+1);
Sky_ClipPoly (newc[1], newv_1[0], stage+1);

if (on_heap)
{
free(dists);
free(sides);
free(newv_0);
free(newv_1);
}
}

/*
Expand All @@ -587,19 +609,27 @@ Sky_ProcessPoly
*/
void Sky_ProcessPoly (glpoly_t *p)
{
int i;
vec3_t verts[MAX_CLIP_VERTS];

//draw it
DrawGLPoly(p);
rs_brushpasses++;

//update sky bounds
if (!r_fastsky.value)
{
for (i=0 ; i<p->numverts ; i++)
const int max_clip_verts = p->numverts + 2;
const int num_verts = p->numverts;
const int on_heap = max_clip_verts > MAX_CLIP_VERTS;
vec3_t *verts = (vec3_t *) (on_heap ?
malloc(max_clip_verts * sizeof(vec3_t)) :
alloca(max_clip_verts * sizeof(vec3_t)));
int i = 0;

for ( ; i < num_verts; i++) {
VectorSubtract (p->verts[i], r_origin, verts[i]);
Sky_ClipPoly (p->numverts, verts[0], 0);
}
Sky_ClipPoly (num_verts, verts[0], 0);

if (on_heap) free(verts);
}
}

Expand Down

0 comments on commit e35ecad

Please sign in to comment.