shithub: qk1

Download patch

ref: 9084a389eba9cd1089560473306b57b418730ef5
parent: f447b03876ddf74796f10c04450d880c966b3042
author: Sigrid Solveig Haflínudóttir <[email protected]>
date: Mon Oct 16 09:39:06 EDT 2023

steal fence drawing from super8 (useless comments removed)

--- a/d_edge.c
+++ b/d_edge.c
@@ -185,7 +185,7 @@
 			if (!s->spans)
 				continue;
 
-			if (s->flags & SURF_TRANS)
+			if((s->flags & SURF_TRANS) ^ r_drawflags)
 				continue;
 
 			r_drawnpolycount++;
@@ -270,8 +270,11 @@
 				}
 
 				pface = s->data;
-				miplevel = D_MipLevelForScale (s->nearzi * scale_for_mip
-				* pface->texinfo->mipadjust);
+				if(s->flags & SURF_FENCE)
+					miplevel = 0;
+				else
+					miplevel = D_MipLevelForScale (s->nearzi * scale_for_mip
+					* pface->texinfo->mipadjust);
 
 			// FIXME: make this passed in to D_CacheSurface
 				pcurrentcache = D_CacheSurface (pface, miplevel);
@@ -281,7 +284,10 @@
 
 				D_CalcGradients (pface);
 
-				(*d_drawspans) (s->spans);
+				if(s->flags & SURF_FENCE)
+					D_DrawSpans16_Fence(s->spans);
+				else
+					(*d_drawspans) (s->spans);
 
 				D_DrawZSpans (s->spans);
 
--- a/d_local.h
+++ b/d_local.h
@@ -56,6 +56,7 @@
 void D_DrawZSpans (espan_t *pspans);
 void Turbulent8 (espan_t *pspan);
 void D_SpriteDrawSpans (sspan_t *pspan);
+void D_DrawSpans16_Fence (espan_t *pspan);
 
 void D_DrawSkyScans8 (espan_t *pspan);
 void D_DrawSkyScans16 (espan_t *pspan);
--- a/d_scan.c
+++ b/d_scan.c
@@ -221,6 +221,159 @@
 	} while ((pspan = pspan->pnext) != nil);
 }
 
+#define WRITEFENCE(i) do{ \
+	fencepix = *(pbase + (s >> 16) + (t >> 16) * cachewidth); \
+	if (pz[i] <= (izi >> 16) && fencepix != 255) \
+		pdest[i] = fencepix; pz[i] = (izi >> 16); \
+	izi += izistep; \
+	s += sstep; \
+	t += tstep; \
+}
+
+void D_DrawSpans16_Fence (espan_t *pspan)
+{
+	byte fencepix;
+	byte *pbase = (byte *)cacheblock, *pdest;
+	int count, spancount, izi, izistep;
+	fixed16_t s, t, snext, tnext, sstep, tstep;
+	float sdivz, tdivz, zi, z, du, dv, spancountminus1;
+	float sdivzstepu, tdivzstepu, zistepu;
+	uzint *pz;
+
+	sdivzstepu = d_sdivzstepu * 16;
+	tdivzstepu = d_tdivzstepu * 16;
+	zistepu = d_zistepu * 16;
+
+	// we count on FP exceptions being turned off to avoid range problems
+	izistep = (int)(d_zistepu * 0x8000 * 0x10000);
+
+	do
+	{
+		pdest = (byte *)((byte *)d_viewbuffer + (screenwidth * pspan->v) + pspan->u);
+		pz = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
+
+		count = pspan->count >> 4;
+		spancount = pspan->count % 16;
+
+		// calculate the initial s/z, t/z, 1/z, s, and t and clamp
+		du = (float)pspan->u;
+		dv = (float)pspan->v;
+
+		sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
+		tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
+		zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
+		z = (float)0x10000 / zi;		// prescale to 16.16 fixed-point
+		// we count on FP exceptions being turned off to avoid range problems
+		izi = (int)(zi * 0x8000 * 0x10000);
+
+		s = (int)(sdivz * z) + sadjust;
+		if (s > bbextents)
+			s = bbextents;
+		else if (s < 0)
+			s = 0;
+
+		t = (int)(tdivz * z) + tadjust;
+		if (t > bbextentt)
+			t = bbextentt;
+		else if (t < 0)
+			t = 0;
+
+		while (count--){
+			// calculate s/z, t/z, zi->fixed s and t at far end of span,
+			// calculate s and t steps across span by shifting
+			sdivz += sdivzstepu;
+			tdivz += tdivzstepu;
+			zi += zistepu;
+			z = (float)0x10000 / zi;   // prescale to 16.16 fixed-point
+
+			snext = (int) (sdivz * z) + sadjust;
+			if (snext > bbextents)
+				snext = bbextents;
+			else if (snext <= 16)
+				snext = 16;   // prevent round-off error on <0 steps causing overstepping & running off the edge of the texture
+
+			tnext = (int) (tdivz * z) + tadjust;
+			if (tnext > bbextentt)
+				tnext = bbextentt;
+			else if (tnext < 16)
+				tnext = 16;   // guard against round-off error on <0 steps
+
+			sstep = (snext - s) >> 4;
+			tstep = (tnext - t) >> 4;
+
+			pdest += 16;
+			pz += 16;
+			WRITEFENCE(-16);
+			WRITEFENCE(-15);
+			WRITEFENCE(-14);
+			WRITEFENCE(-13);
+			WRITEFENCE(-12);
+			WRITEFENCE(-11);
+			WRITEFENCE(-10);
+			WRITEFENCE(-9);
+			WRITEFENCE(-8);
+			WRITEFENCE(-7);
+			WRITEFENCE(-6);
+			WRITEFENCE(-5);
+			WRITEFENCE(-4);
+			WRITEFENCE(-3);
+			WRITEFENCE(-2);
+			WRITEFENCE(-1);
+
+			s = snext;
+			t = tnext;
+		}
+		if (spancount > 0)
+		{
+			// 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 span by division, biasing steps low so we don't run off the texture
+			spancountminus1 = (float)(spancount - 1);
+			sdivz += d_sdivzstepu * spancountminus1;
+			tdivz += d_tdivzstepu * spancountminus1;
+			zi += d_zistepu * spancountminus1;
+			z = (float)0x10000 / zi;   // prescale to 16.16 fixed-point
+			snext = (int)(sdivz * z) + sadjust;
+			if (snext > bbextents)
+				snext = bbextents;
+			else if (snext < 16)
+				snext = 16;   // prevent round-off error on <0 steps from causing overstepping & running off the edge of the texture
+
+			tnext = (int)(tdivz * z) + tadjust;
+			if (tnext > bbextentt)
+				tnext = bbextentt;
+			else if (tnext < 16)
+				tnext = 16;   // guard against round-off error on <0 steps
+
+			if (spancount > 1){
+				sstep = (snext - s) / (spancount - 1);
+				tstep = (tnext - t) / (spancount - 1);
+			}
+
+			pdest += spancount;
+			pz += spancount;
+			switch (spancount){
+			case 16: WRITEFENCE(-16);
+			case 15: WRITEFENCE(-15);
+			case 14: WRITEFENCE(-14);
+			case 13: WRITEFENCE(-13);
+			case 12: WRITEFENCE(-12);
+			case 11: WRITEFENCE(-11);
+			case 10: WRITEFENCE(-10);
+			case  9: WRITEFENCE(-9);
+			case  8: WRITEFENCE(-8);
+			case  7: WRITEFENCE(-7);
+			case  6: WRITEFENCE(-6);
+			case  5: WRITEFENCE(-5);
+			case  4: WRITEFENCE(-4);
+			case  3: WRITEFENCE(-3);
+			case  2: WRITEFENCE(-2);
+			case  1: WRITEFENCE(-1);
+			}
+		}
+	}
+	while ((pspan = pspan->pnext) != nil);
+}
+
 /*
 =============
 D_DrawSpans16
--- a/r_bsp.c
+++ b/r_bsp.c
@@ -327,7 +327,7 @@
 
 	for (i=0 ; i<numsurfaces ; i++, psurf++)
 	{
-		if(psurf->flags & SURF_TRANS)
+		if((psurf->flags & SURF_TRANS) ^ r_drawflags)
 			continue;
 	// find which side of the node we are on
 		pplane = psurf->plane;
@@ -406,7 +406,7 @@
 
 	for (i=0 ; i<numsurfaces ; i++, psurf++)
 	{
-		if(psurf->flags & SURF_TRANS)
+		if((psurf->flags & SURF_TRANS) ^ r_drawflags)
 			continue;
 
 	// find which side of the node we are on
--- a/r_draw.c
+++ b/r_draw.c
@@ -18,8 +18,8 @@
 
 polydesc_t		r_polydesc;
 
+int r_drawflags;
 
-
 clipplane_t	*entity_clipplanes;
 clipplane_t	view_clipplanes[4];
 clipplane_t	world_clipplanes[16];
@@ -382,7 +382,7 @@
 		return;
 	}
 
-	if(fa->flags & SURF_TRANS)
+	if((fa->flags & SURF_TRANS) ^ r_drawflags)
 		return;
 
 	c_faceclip++;
--- a/r_local.h
+++ b/r_local.h
@@ -96,6 +96,7 @@
 //=============================================================================
 
 extern int	vstartscan;
+extern int r_drawflags;
 
 
 void R_ClearPolyList (void);
--- a/r_main.c
+++ b/r_main.c
@@ -855,9 +855,9 @@
 
 	if (!cl_entities[0].model || !cl.worldmodel)
 		fatal ("R_RenderView: NULL worldmodel");
-	
+	r_drawflags = 0;
 	R_EdgeDrawing ();
-	
+
 	if (r_dspeeds.value)
 	{
 		se_time2 = dtime ();
@@ -881,6 +881,10 @@
 	}
 
 	R_DrawParticles ();
+
+	r_drawflags = SURF_TRANS;
+	R_EdgeDrawing ();
+	r_drawflags = 0;
 
 	if (r_dspeeds.value)
 		dp_time2 = dtime ();