From db59ec59989eba4a053557e2e7ae4444e983cb1a Mon Sep 17 00:00:00 2001
From: Zwip-Zwap Zapony <ZwipZwapZapony@gmail.com>
Date: Thu, 17 Aug 2023 17:39:24 +0200
Subject: [PATCH] Fix interpolation when curling up while flipped

Also fix scaling interpolation while flipped, and fix the NiGHTS Drone flip interpolation on its first tic
---
 src/hardware/hw_main.c | 5 ++++-
 src/hardware/hw_md2.c  | 7 ++++++-
 src/p_mobj.c           | 2 +-
 src/p_user.c           | 5 ++++-
 src/r_things.c         | 6 +++++-
 5 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index 36ff86abd7..f253861de3 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -5378,7 +5378,10 @@ static void HWR_ProjectSprite(mobj_t *thing)
 
 		if (vflip)
 		{
-			gz = FIXED_TO_FLOAT(interp.z + thing->height) - (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
+			if (thing->scale != thing->old_scale) // Interpolate heights in reverse gravity when scaling mobjs
+				gz = FIXED_TO_FLOAT(interp.z + FixedMul(thing->height, FixedDiv(interp.scale, thing->scale))) - (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
+			else
+				gz = FIXED_TO_FLOAT(interp.z + thing->height) - (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
 			gzt = gz + (FIXED_TO_FLOAT(spr_height) * this_yscale);
 		}
 		else
diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c
index d005f00377..87881be8d6 100644
--- a/src/hardware/hw_md2.c
+++ b/src/hardware/hw_md2.c
@@ -1585,7 +1585,12 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
 		p.y = FIXED_TO_FLOAT(interp.y)+md2->offset;
 
 		if (flip)
-			p.z = FIXED_TO_FLOAT(interp.z + spr->mobj->height);
+		{
+			if (spr->mobj->scale != spr->mobj->old_scale) // Interpolate heights in reverse gravity when scaling mobjs
+				p.z = FIXED_TO_FLOAT(interp.z + FixedMul(spr->mobj->height, FixedDiv(interp.scale, spr->mobj->scale)));
+			else
+				p.z = FIXED_TO_FLOAT(interp.z + spr->mobj->height);
+		}
 		else
 			p.z = FIXED_TO_FLOAT(interp.z);
 
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 2a40175dc7..9550535f10 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -12593,7 +12593,7 @@ static boolean P_SetupNiGHTSDrone(mapthing_t *mthing, mobj_t *mobj)
 	dronemangoaldiff = max(mobjinfo[MT_NIGHTSDRONE_MAN].height - mobjinfo[MT_NIGHTSDRONE_GOAL].height, 0);
 
 	if (flip && mobj->height != oldheight)
-		P_MoveOrigin(mobj, mobj->x, mobj->y, mobj->z - (mobj->height - oldheight));
+		P_SetOrigin(mobj, mobj->x, mobj->y, mobj->z - (mobj->height - oldheight));
 
 	if (!flip)
 	{
diff --git a/src/p_user.c b/src/p_user.c
index 84d0c0abf0..48141815c3 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -8717,7 +8717,10 @@ void P_MovePlayer(player_t *player)
 			player->mo->height = P_GetPlayerHeight(player);
 
 		if (player->mo->eflags & MFE_VERTICALFLIP && player->mo->height != oldheight) // adjust z height for reverse gravity, similar to how it's done for scaling
-			player->mo->z -= player->mo->height - oldheight;
+		{
+			player->mo->z     -= player->mo->height - oldheight;
+			player->mo->old_z -= player->mo->height - oldheight; // Snap the Z adjustment, while keeping the Z interpolation
+		}
 
 		// Crush test...
 		if ((player->mo->ceilingz - player->mo->floorz < player->mo->height)
diff --git a/src/r_things.c b/src/r_things.c
index 90b80dda8f..e69fe1b822 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -2114,7 +2114,11 @@ static void R_ProjectSprite(mobj_t *thing)
 			// When vertical flipped, draw sprites from the top down, at least as far as offsets are concerned.
 			// sprite height - sprite topoffset is the proper inverse of the vertical offset, of course.
 			// remember gz and gzt should be seperated by sprite height, not thing height - thing height can be shorter than the sprite itself sometimes!
-			gz = interp.z + oldthing->height - FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale));
+
+			if (oldthing->scale != oldthing->old_scale) // Interpolate heights in reverse gravity when scaling mobjs
+				gz = interp.z + FixedMul(oldthing->height, FixedDiv(interp.scale, oldthing->scale)) - FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale));
+			else
+				gz = interp.z + oldthing->height - FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale));
 			gzt = gz + FixedMul(spr_height, FixedMul(spriteyscale, this_scale));
 		}
 		else
-- 
GitLab