From 359462389187c9e5ec36f38f9bb21447639c9e7f Mon Sep 17 00:00:00 2001
From: toaster <rollerorbital@gmail.com>
Date: Sun, 24 Nov 2019 16:42:13 +0000
Subject: [PATCH] Courteousy of fickle, an adjustment to papersprite rendering
 that prevents the object's x1 and x2 being slightly off where they should be.
 Not perfect, but absolutely better than it was!

Also, tweak the Minecart segment spawning position, since this was originally placed based on the awkward rendering.
---
 src/p_mobj.c   |  2 +-
 src/r_things.c | 62 +++++++++++++++++++++++++++++++-------------------
 2 files changed, 39 insertions(+), 25 deletions(-)

diff --git a/src/p_mobj.c b/src/p_mobj.c
index f2dd1a734f..f1984783b2 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -7082,7 +7082,7 @@ static void P_SpawnMinecartSegments(mobj_t *mobj, boolean mode)
 		seg = P_SpawnMobj(x, y, z, MT_MINECARTSEG);
 		P_SetMobjState(seg, (statenum_t)(S_MINECARTSEG_FRONT + i));
 		if (i >= 2)
-			seg->extravalue1 = (i == 2) ? -18 : 18;
+			seg->extravalue1 = (i == 2) ? -20 : 20;
 		else
 		{
 			seg->extravalue2 = (i == 0) ? 24 : -24;
diff --git a/src/r_things.c b/src/r_things.c
index c89d87bf45..9763648cd0 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -1137,8 +1137,6 @@ static void R_ProjectSprite(mobj_t *thing)
 	UINT32 rollangle = AngleFixed(arollangle)>>FRACBITS;
 #endif
 
-	fixed_t ang_scale = FRACUNIT;
-
 	// transform the origin point
 	tr_x = thing->x - viewx;
 	tr_y = thing->y - viewy;
@@ -1223,8 +1221,6 @@ static void R_ProjectSprite(mobj_t *thing)
 	if (sprframe->rotate != SRF_SINGLE || papersprite)
 	{
 		ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle);
-		if (papersprite)
-			ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT));
 	}
 
 	if (sprframe->rotate == SRF_SINGLE)
@@ -1286,24 +1282,11 @@ static void R_ProjectSprite(mobj_t *thing)
 	else
 		offset = -spr_offset;
 	offset = FixedMul(offset, this_scale);
-	tx += FixedMul(offset, ang_scale);
-	x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS;
-
-	// off the right side?
-	if (x1 > viewwidth)
-		return;
-
 	offset2 = FixedMul(spr_width, this_scale);
-	tx += FixedMul(offset2, ang_scale);
-	x2 = ((centerxfrac + FixedMul (tx,xscale)) >> FRACBITS) - (papersprite ? 2 : 1);
-
-	// off the left side
-	if (x2 < 0)
-		return;
 
 	if (papersprite)
 	{
-		fixed_t yscale2, cosmul, sinmul, tz2;
+		fixed_t xscale2, yscale2, cosmul, sinmul, tz2;
 		INT32 range;
 
 		if (ang >= ANGLE_180)
@@ -1323,6 +1306,16 @@ static void R_ProjectSprite(mobj_t *thing)
 		yscale = FixedDiv(projectiony, tz);
 		if (yscale < 64) return; // Fix some funky visuals
 
+		gxt = -FixedMul(tr_x, viewsin);
+		gyt = FixedMul(tr_y, viewcos);
+		tx = -(gyt + gxt);
+		xscale = FixedDiv(projection, tz);
+		x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
+
+		// off the right side?
+		if (x1 > viewwidth)
+			return;
+
 		tr_x += FixedMul(offset2, cosmul);
 		tr_y += FixedMul(offset2, sinmul);
 		gxt = FixedMul(tr_x, viewcos);
@@ -1331,15 +1324,25 @@ static void R_ProjectSprite(mobj_t *thing)
 		yscale2 = FixedDiv(projectiony, tz2);
 		if (yscale2 < 64) return; // ditto
 
+		gxt = -FixedMul(tr_x, viewsin);
+		gyt = FixedMul(tr_y, viewcos);
+		tx = -(gyt + gxt);
+		xscale2 = FixedDiv(projection, tz2);
+		x2 = (centerxfrac + FixedMul(tx,xscale2))>>FRACBITS; x2--;
+
+		// off the left side
+		if (x2 < 0)
+			return;
+
 		if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier
 			return;
 
-		if (x2 > x1)
-			range = (x2 - x1);
-		else
+		if ((range = x2 - x1) <= 0)
 			range = 1;
 
-		scalestep = (yscale2 - yscale)/range ?: 1;
+		scalestep = (yscale2 - yscale)/range;
+		scalestep = scalestep ? scalestep : 1;
+		xscale = FixedDiv(range<<FRACBITS, abs(offset2))+1;
 
 		// The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2?
 		// sortscale = max(yscale, yscale2);
@@ -1349,9 +1352,20 @@ static void R_ProjectSprite(mobj_t *thing)
 	{
 		scalestep = 0;
 		yscale = sortscale;
-	}
+		tx += offset;
+		x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
+
+		// off the right side?
+		if (x1 > viewwidth)
+			return;
 
-	xscale = FixedMul(xscale, ang_scale);
+		tx += offset2;
+		x2 = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS); x2--;
+
+		// off the left side
+		if (x2 < 0)
+			return;
+	}
 
 	if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY)
 	{
-- 
GitLab