From 6026fa42eb1cea15614348e901cbe9f1cd279bdf Mon Sep 17 00:00:00 2001
From: RedEnchilada <redenchilada@derpymail.com>
Date: Mon, 3 Aug 2015 14:47:05 -0500
Subject: [PATCH] Add masked FOF slopes (+other rendering tweaks)

---
 src/r_draw.h  |   1 +
 src/r_draw8.c | 171 +++++++++++++++++++++++++++++++++++++++++++++-----
 src/r_plane.c |   8 ++-
 3 files changed, 163 insertions(+), 17 deletions(-)

diff --git a/src/r_draw.h b/src/r_draw.h
index e1818545b7..63fecc0465 100644
--- a/src/r_draw.h
+++ b/src/r_draw.h
@@ -154,6 +154,7 @@ void R_DrawSpan_8(void);
 #ifdef ESLOPE
 void R_DrawTiltedSpan_8(void);
 void R_DrawTiltedTranslucentSpan_8(void);
+void R_DrawTiltedSplat_8(void);
 #endif
 void R_DrawSplat_8(void);
 void R_DrawTranslucentSplat_8(void);
diff --git a/src/r_draw8.c b/src/r_draw8.c
index 279690492c..f78f1494b9 100644
--- a/src/r_draw8.c
+++ b/src/r_draw8.c
@@ -593,8 +593,8 @@ void R_DrawTiltedSpan_8(void)
 	do
 	{
 		double z = 1.f/iz;
-		u = (UINT32)(uz*z) + viewx;
-		v = (UINT32)(vz*z) + viewy;
+		u = (INT64)(uz*z) + viewx;
+		v = (INT64)(vz*z) + viewy;
 
 		colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
 
@@ -630,8 +630,8 @@ void R_DrawTiltedSpan_8(void)
 		double endv = vz*endz;
 		UINT32 stepu = (INT64)((endu - startu) * INVSPAN);
 		UINT32 stepv = (INT64)((endv - startv) * INVSPAN);
-		u = (UINT32)(startu) + viewx;
-		v = (UINT32)(startv) + viewy;
+		u = (INT64)(startu) + viewx;
+		v = (INT64)(startv) + viewy;
 
 		for (i = SPANSIZE-1; i >= 0; i--)
 		{
@@ -649,8 +649,8 @@ void R_DrawTiltedSpan_8(void)
 	{
 		if (width == 1)
 		{
-			u = (UINT32)(startu);
-			v = (UINT32)(startv);
+			u = (INT64)(startu);
+			v = (INT64)(startv);
 			colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
 			*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
 		}
@@ -667,8 +667,8 @@ void R_DrawTiltedSpan_8(void)
 			left = 1.f/left;
 			UINT32 stepu = (INT64)((endu - startu) * left);
 			UINT32 stepv = (INT64)((endv - startv) * left);
-			u = (UINT32)(startu) + viewx;
-			v = (UINT32)(startv) + viewy;
+			u = (INT64)(startu) + viewx;
+			v = (INT64)(startv) + viewy;
 
 			for (; width != 0; width--)
 			{
@@ -726,8 +726,8 @@ void R_DrawTiltedTranslucentSpan_8(void)
 	do
 	{
 		double z = 1.f/iz;
-		u = (UINT32)(uz*z) + viewx;
-		v = (UINT32)(vz*z) + viewy;
+		u = (INT64)(uz*z) + viewx;
+		v = (INT64)(vz*z) + viewy;
 
 		colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
 
@@ -763,8 +763,8 @@ void R_DrawTiltedTranslucentSpan_8(void)
 		double endv = vz*endz;
 		UINT32 stepu = (INT64)((endu - startu) * INVSPAN);
 		UINT32 stepv = (INT64)((endv - startv) * INVSPAN);
-		u = (UINT32)(startu) + viewx;
-		v = (UINT32)(startv) + viewy;
+		u = (INT64)(startu) + viewx;
+		v = (INT64)(startv) + viewy;
 
 		for (i = SPANSIZE-1; i >= 0; i--)
 		{
@@ -782,8 +782,8 @@ void R_DrawTiltedTranslucentSpan_8(void)
 	{
 		if (width == 1)
 		{
-			u = (UINT32)(startu);
-			v = (UINT32)(startv);
+			u = (INT64)(startu);
+			v = (INT64)(startv);
 			colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
 			*dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])];
 		}
@@ -800,8 +800,8 @@ void R_DrawTiltedTranslucentSpan_8(void)
 			left = 1.f/left;
 			UINT32 stepu = (INT64)((endu - startu) * left);
 			UINT32 stepv = (INT64)((endv - startv) * left);
-			u = (UINT32)(startu) + viewx;
-			v = (UINT32)(startv) + viewy;
+			u = (INT64)(startu) + viewx;
+			v = (INT64)(startv) + viewy;
 
 			for (; width != 0; width--)
 			{
@@ -815,6 +815,145 @@ void R_DrawTiltedTranslucentSpan_8(void)
 	}
 #endif
 }
+
+void R_DrawTiltedSplat_8(void)
+{
+	// x1, x2 = ds_x1, ds_x2
+	int width = ds_x2 - ds_x1;
+	double iz, uz, vz;
+	UINT32 u, v;
+	int i;
+
+	UINT8 *source;
+	UINT8 *colormap;
+	UINT8 *dest;
+
+	UINT8 val;
+
+	iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
+
+	// Lighting is simple. It's just linear interpolation from start to end
+	{
+		float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
+		float lightstart, lightend;
+
+		lightend = (iz + ds_sz.x*width) * planelightfloat;
+		lightstart = iz * planelightfloat;
+
+		R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
+		//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
+	}
+
+	uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
+	vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
+
+	dest = ylookup[ds_y] + columnofs[ds_x1];
+	source = ds_source;
+	//colormap = ds_colormap;
+
+#if 0	// The "perfect" reference version of this routine. Pretty slow.
+		// Use it only to see how things are supposed to look.
+	i = 0;
+	do
+	{
+		double z = 1.f/iz;
+		u = (INT64)(uz*z) + viewx;
+		v = (INT64)(vz*z) + viewy;
+
+		colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+
+		val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+		if (val != TRANSPARENTPIXEL)
+			*dest = val;
+		dest++;
+		iz += ds_sz.x;
+		uz += ds_su.x;
+		vz += ds_sv.x;
+	} while (--width >= 0);
+#else
+#define SPANSIZE 16
+#define INVSPAN	0.0625f
+
+	double startz = 1.f/iz;
+	double startu = uz*startz;
+	double startv = vz*startz;
+	double izstep, uzstep, vzstep;
+
+	izstep = ds_sz.x * SPANSIZE;
+	uzstep = ds_su.x * SPANSIZE;
+	vzstep = ds_sv.x * SPANSIZE;
+	//x1 = 0;
+	width++;
+
+	while (width >= SPANSIZE)
+	{
+		iz += izstep;
+		uz += uzstep;
+		vz += vzstep;
+
+		double endz = 1.f/iz;
+		double endu = uz*endz;
+		double endv = vz*endz;
+		UINT32 stepu = (INT64)((endu - startu) * INVSPAN);
+		UINT32 stepv = (INT64)((endv - startv) * INVSPAN);
+		u = (INT64)(startu) + viewx;
+		v = (INT64)(startv) + viewy;
+
+		for (i = SPANSIZE-1; i >= 0; i--)
+		{
+			colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+			val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+			if (val != TRANSPARENTPIXEL)
+				*dest = val;
+			dest++;
+			u += stepu;
+			v += stepv;
+		}
+		startu = endu;
+		startv = endv;
+		width -= SPANSIZE;
+	}
+	if (width > 0)
+	{
+		if (width == 1)
+		{
+			u = (INT64)(startu);
+			v = (INT64)(startv);
+			colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+			val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+			if (val != TRANSPARENTPIXEL)
+				*dest = val;
+		}
+		else
+		{
+			double left = width;
+			iz += ds_sz.x * left;
+			uz += ds_su.x * left;
+			vz += ds_sv.x * left;
+
+			double endz = 1.f/iz;
+			double endu = uz*endz;
+			double endv = vz*endz;
+			left = 1.f/left;
+			UINT32 stepu = (INT64)((endu - startu) * left);
+			UINT32 stepv = (INT64)((endv - startv) * left);
+			u = (INT64)(startu) + viewx;
+			v = (INT64)(startv) + viewy;
+
+			for (; width != 0; width--)
+			{
+				colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+				val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
+				if (val != TRANSPARENTPIXEL)
+					*dest = val;
+				dest++;
+				u += stepu;
+				v += stepv;
+			}
+		}
+	}
+#endif
+}
 #endif // ESLOPE
 
 /**	\brief The R_DrawSplat_8 function
diff --git a/src/r_plane.c b/src/r_plane.c
index 6aae1e250b..406a38d7b7 100644
--- a/src/r_plane.c
+++ b/src/r_plane.c
@@ -836,7 +836,11 @@ void R_DrawSinglePlane(visplane_t *pl)
 		else light = (pl->lightlevel >> LIGHTSEGSHIFT);
 
 #ifndef NOWATER
-		if (pl->ffloor->flags & FF_RIPPLE)
+		if (pl->ffloor->flags & FF_RIPPLE
+#ifdef ESLOPE
+				&& !pl->slope
+#endif
+			)
 		{
 			INT32 top, bottom;
 
@@ -1024,6 +1028,8 @@ void R_DrawSinglePlane(visplane_t *pl)
 
 		if (spanfunc == R_DrawTranslucentSpan_8)
 			spanfunc = R_DrawTiltedTranslucentSpan_8;
+		else if (spanfunc == splatfunc)
+			spanfunc = R_DrawTiltedSplat_8;
 		else
 			spanfunc = R_DrawTiltedSpan_8;
 
-- 
GitLab