ref: 11daf02d521a0e7d13085167e81246d9b1e88283
parent: 964902ba628e0aecc635f888b4e0c09803c179cd
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Fri Jan 5 12:06:54 EST 2024
spans: try to draw in bigger chunks Take "safe span step" calculation from Quake 2.
--- a/d_edge.c
+++ b/d_edge.c
@@ -135,7 +135,7 @@
D_DrawSolidSurface(s, q1pal[(int)r_clearcolor.value & 0xFF]);
}else if(s->flags & SURF_DRAWTURB){
D_CalcGradients(0, pface, transformed_modelorg);
- D_DrawSpans16(s->spans, pface->texinfo->texture->pixels, 64, alpha, SPAN_TURB);
+ D_DrawSpans(s->spans, pface->texinfo->texture->pixels, 64, alpha, SPAN_TURB);
}else{
miplevel = D_MipLevelForScale(s->nearzi * scale_for_mip * pface->texinfo->mipadjust);
if(s->flags & SURF_FENCE)
@@ -143,7 +143,7 @@
pcurrentcache = D_CacheSurface(pface, miplevel);
D_CalcGradients(miplevel, pface, transformed_modelorg);
- D_DrawSpans16(s->spans, pcurrentcache->pixels, pcurrentcache->width, alpha,
+ D_DrawSpans(s->spans, pcurrentcache->pixels, pcurrentcache->width, alpha,
(alpha == 255 && s->flags & SURF_FENCE) ? SPAN_FENCE : (blend ? SPAN_BLEND : SPAN_SOLID)
);
}
--- a/d_local.h
+++ b/d_local.h
@@ -65,12 +65,10 @@
SPAN_TURB,
};
-void D_DrawSpans16(espan_t *pspan, pixel_t *pbase, int width, byte alpha, int spanfunc);
-void Turbulent8 (espan_t *pspan, byte alpha);
+void D_DrawSpans(espan_t *pspan, pixel_t *pbase, int width, byte alpha, int spanfunc);
void D_DrawSkyScans8 (espan_t *pspan);
-void R_ShowSubDiv (void);
surfcache_t *D_CacheSurface (msurface_t *surface, int miplevel);
extern int *d_pscantable;
--- a/d_scan.c
+++ b/d_scan.c
@@ -205,10 +205,29 @@
}
+static int
+D_DrawSpanGetMax(float u, float v)
+{
+ int s, m;
+ float us, vs;
+
+ s = 4;
+ us = u * (1<<16);
+ vs = v * (1<<16);
+ do{
+ m = 1 << (s+1);
+ if((int)(us*m) != 0 || (int)(vs*m) != 0)
+ return s;
+ s++;
+ }while(m < (int)dvars.width);
+
+ return s;
+}
+
void
-D_DrawSpans16(espan_t *pspan, pixel_t *pbase, int width, byte alpha, int spanfunc)
+D_DrawSpans(espan_t *pspan, pixel_t *pbase, int width, byte alpha, int spanfunc)
{
- int count, spancount, izistep, spancountminus1;
+ int count, spancount, izistep, spancountminus1, spanshift, spanmax;
pixel_t *pdest;
uzint *pz, izi;
fixed16_t s, t, snext, tnext, sstep, tstep;
@@ -221,9 +240,12 @@
tstep = 0; // ditto
memset(&fog, 0, sizeof(fog));
- sdivzstepu = dvars.sdivzstepu * 16;
- tdivzstepu = dvars.tdivzstepu * 16;
- zistepu = dvars.zistepu * 16;
+ spanshift = D_DrawSpanGetMax(dvars.zistepu, dvars.zistepv);
+ spanmax = 1 << spanshift;
+
+ sdivzstepu = dvars.sdivzstepu * spanmax;
+ tdivzstepu = dvars.tdivzstepu * spanmax;
+ zistepu = dvars.zistepu * spanmax;
izistep = (int)(dvars.zistepu * 0x8000 * 0x10000);
fogenabled = isfogged();
@@ -241,7 +263,7 @@
sdivz = dvars.sdivzorigin + dv*dvars.sdivzstepv + du*dvars.sdivzstepu;
tdivz = dvars.tdivzorigin + dv*dvars.tdivzstepv + du*dvars.tdivzstepu;
- z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
+ z = (float)(1<<16) / zi; // prescale to 16.16 fixed-point
s = (int)(sdivz * z) + dvars.sadjust;
s = clamp(s, 0, dvars.bbextents);
@@ -251,7 +273,7 @@
do{
// calculate s and t at the far end of the span
- spancount = min(count, 16);
+ spancount = min(count, spanmax);
count -= spancount;
fogged = fogenabled && fogcalc(izi, izi + izistep*spancount, spancount, &fog);
@@ -261,20 +283,20 @@
sdivz += sdivzstepu;
tdivz += tdivzstepu;
// prescale to 16.16 fixed-point
- z = (float)0x10000 / (zi + zistepu);
+ z = (float)(1<<16) / (zi + zistepu);
snext = (int)(sdivz * z) + dvars.sadjust;
// prevent round-off error on <0 steps from
- // from causing overstepping & running off the
+ // causing overstepping & running off the
// edge of the texture
- snext = clamp(snext, 16, dvars.bbextents);
+ snext = clamp(snext, spanmax, dvars.bbextents);
tnext = (int)(tdivz * z) + dvars.tadjust;
// guard against round-off error on <0 steps
- tnext = clamp(tnext, 16, dvars.bbextentt);
+ tnext = clamp(tnext, spanmax, dvars.bbextentt);
- sstep = (snext - s) >> 4;
- tstep = (tnext - t) >> 4;
+ sstep = (snext - s) >> spanshift;
+ tstep = (tnext - t) >> spanshift;
}else{
// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
// can't step off polygon), clamp, calculate s and t steps across
@@ -284,16 +306,16 @@
sdivz += dvars.sdivzstepu * spancountminus1;
tdivz += dvars.tdivzstepu * spancountminus1;
// prescale to 16.16 fixed-point
- z = (float)0x10000 / (zi + dvars.zistepu * spancountminus1);
+ z = (float)(1<<16) / (zi + dvars.zistepu * spancountminus1);
snext = (int)(sdivz * z) + dvars.sadjust;
// prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
- snext = clamp(snext, 16, dvars.bbextents);
+ snext = clamp(snext, spanmax, dvars.bbextents);
tnext = (int)(tdivz * z) + dvars.tadjust;
// guard against round-off error on <0 steps
- tnext = clamp(tnext, 16, dvars.bbextentt);
+ tnext = clamp(tnext, spanmax, dvars.bbextentt);
if(spancount > 1){
sstep = (snext - s) / spancountminus1;