From 1142d17dd82274ccd41279ad9b322f42ef3f1672 Mon Sep 17 00:00:00 2001
From: chromaticpipe <chromaticpipe@gmail.com>
Date: Wed, 26 Mar 2025 12:40:44 -0500
Subject: [PATCH 1/5] Add a hardcoded viewroll command

---
 src/p_local.h |  2 ++
 src/p_user.c  | 37 +++++++++++++++++++++++++++++++++++++
 src/r_main.c  |  2 ++
 3 files changed, 41 insertions(+)

diff --git a/src/p_local.h b/src/p_local.h
index 6123e001e9..70714ce3b4 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -115,6 +115,8 @@ extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed, cv_cam_turnmultip
 extern consvar_t cv_cam2_dist, cv_cam2_still, cv_cam2_height;
 extern consvar_t cv_cam2_speed, cv_cam2_rotate, cv_cam2_rotspeed, cv_cam2_turnmultiplier, cv_cam2_orbit, cv_cam2_adjust;
 
+extern consvar_t cv_viewroll;
+
 extern consvar_t cv_cam_savedist[2][2], cv_cam_saveheight[2][2];
 void CV_UpdateCamDist(void);
 void CV_UpdateCam2Dist(void);
diff --git a/src/p_user.c b/src/p_user.c
index e1edeca8b2..67e63fa433 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -9849,6 +9849,8 @@ consvar_t cv_cam2_turnmultiplier = CVAR_INIT ("cam2_turnmultiplier", "0.75", NUL
 consvar_t cv_cam2_orbit = CVAR_INIT ("cam2_orbit", "Off", "If enabled, vertical camera movement will rotate around the player character rather than staying in place", CV_SAVE|CV_ALLOWLUA, CV_OnOff, NULL);
 consvar_t cv_cam2_adjust = CVAR_INIT ("cam2_adjust", "On", "Adjust camera angle relative to the slope the player is on", CV_SAVE|CV_ALLOWLUA, CV_OnOff, NULL);
 
+consvar_t cv_viewroll = CVAR_INIT ("viewroll", "Off", "Tilt camera on sloped surfaces", CV_SAVE, CV_OnOff, NULL);;
+
 // [standard vs simple][p1 or p2]
 consvar_t cv_cam_savedist[2][2] = {
 	{ // standard
@@ -11735,6 +11737,40 @@ void P_DoFollowMobj(player_t *player, mobj_t *followmobj)
 	}
 }
 
+
+
+static void
+DoABarrelRoll (player_t *player)
+{
+	angle_t slope;
+	angle_t delta;
+
+	if (player->mo->standingslope)
+	{
+		slope = player->mo->standingslope->zangle;
+	}
+	else
+	{
+		slope = 0;
+	}
+
+	
+	if (player->mo->standingslope && cv_viewroll.value && (abs((INT32)slope) > ANGLE_11hh))
+	{
+		delta = ( player->mo->angle - player->mo->standingslope->xydirection );
+		slope = -(FixedMul(FINESINE (delta>>ANGLETOFINESHIFT), slope));
+	}
+	else
+		slope = 0;
+
+	delta = (INT32)( slope - player->viewrollangle )/ 16;
+
+	if (delta)
+		player->viewrollangle += delta;
+	else
+		player->viewrollangle  = slope;
+}
+
 //
 // P_PlayerThink
 //
@@ -12664,6 +12700,7 @@ void P_PlayerThink(player_t *player)
 
 		I_Error("I'm done!\n");
 	}*/
+	DoABarrelRoll(player);
 }
 
 // Checks if the mobj is above lava. Used by Pterabyte.
diff --git a/src/r_main.c b/src/r_main.c
index 133c1862a3..7a3fe512ea 100644
--- a/src/r_main.c
+++ b/src/r_main.c
@@ -1734,6 +1734,8 @@ void R_RegisterEngineStuff(void)
 	CV_RegisterVar(&cv_cam_saveheight[1][0]);
 	CV_RegisterVar(&cv_cam_saveheight[1][1]);
 
+	CV_RegisterVar(&cv_viewroll);
+
 	CV_RegisterVar(&cv_showhud);
 	CV_RegisterVar(&cv_translucenthud);
 
-- 
GitLab


From e2f688ca2d891b4e81d588da714522d58c926048 Mon Sep 17 00:00:00 2001
From: chromaticpipe <chromaticpipe@gmail.com>
Date: Wed, 26 Mar 2025 12:42:39 -0500
Subject: [PATCH 2/5] Revert "Disable sprite/model rotation on slopes for now"

This reverts commit bc9e7c146126bdd65f79c8fb5f37930d41b2816e.
---
 src/hardware/hw_md2.c | 5 -----
 src/p_mobj.c          | 5 -----
 src/r_patchrotation.c | 4 ----
 3 files changed, 14 deletions(-)

diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c
index 397dcdfba2..8c48cfab68 100644
--- a/src/hardware/hw_md2.c
+++ b/src/hardware/hw_md2.c
@@ -1692,13 +1692,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
 			}
 		}
 
-#if 0
 		p.anglez = FIXED_TO_FLOAT(AngleFixed(interp.pitch));
 		p.anglex = FIXED_TO_FLOAT(AngleFixed(interp.roll));
-#else
-		p.anglez = 0.f;
-		p.anglex = 0.f;
-#endif
 
 		p.flip = atransform.flip;
 		p.mirror = atransform.mirror;
diff --git a/src/p_mobj.c b/src/p_mobj.c
index fd5d6f8924..d248c517ee 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -1442,7 +1442,6 @@ void P_CheckGravity(mobj_t *mo, boolean affect)
 //
 void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope)
 {
-#if 0
 	if (slope)
 	{
 		fixed_t tempz = slope->normal.z;
@@ -1456,10 +1455,6 @@ void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope)
 	{
 		mo->pitch = mo->roll = 0;
 	}
-#else
-	(void)mo;
-	(void)slope;
-#endif
 }
 
 #define STOPSPEED (FRACUNIT)
diff --git a/src/r_patchrotation.c b/src/r_patchrotation.c
index 989665d741..6fb8783369 100644
--- a/src/r_patchrotation.c
+++ b/src/r_patchrotation.c
@@ -26,7 +26,6 @@ angle_t R_ModelRotationAngle(interpmobjstate_t *interp)
 
 angle_t R_SpriteRotationAngle(interpmobjstate_t *interp)
 {
-#if 0
 	angle_t viewingAngle = R_PointToAngle(interp->x, interp->y);
 
 	fixed_t pitchMul = -FINESINE(viewingAngle >> ANGLETOFINESHIFT);
@@ -35,9 +34,6 @@ angle_t R_SpriteRotationAngle(interpmobjstate_t *interp)
 	angle_t rollOrPitch = FixedMul(interp->pitch, pitchMul) + FixedMul(interp->roll, rollMul);
 
 	return (rollOrPitch + R_ModelRotationAngle(interp));
-#else
-	return R_ModelRotationAngle(interp);
-#endif
 }
 
 INT32 R_GetRollAngle(angle_t rollangle)
-- 
GitLab


From 5d1940619b073fe5490462ab38b477d8c4e3f180 Mon Sep 17 00:00:00 2001
From: chromaticpipe <chromaticpipe@gmail.com>
Date: Wed, 26 Mar 2025 13:44:27 -0500
Subject: [PATCH 3/5] Add sloperoll variable

---
 src/g_game.c | 2 ++
 src/g_game.h | 2 ++
 src/p_mobj.c | 2 +-
 src/r_main.c | 2 ++
 4 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/g_game.c b/src/g_game.c
index bbe6e7374c..6867f925ca 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -414,6 +414,8 @@ consvar_t cv_firenaxis2 = CVAR_INIT ("joyaxis2_firenormal", "Z-Axis", NULL, CV_S
 consvar_t cv_deadzone2 = CVAR_INIT ("joy_deadzone2", "0.125", "How far a joystick have to be pushed before it registers any input", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
 consvar_t cv_digitaldeadzone2 = CVAR_INIT ("joy_digdeadzone2", "0.25", NULL, CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
 
+consvar_t cv_sloperoll = CVAR_INIT ("sloperoll", "Off", "Rotate sprites/models of objects on sloped surfaces", CV_SAVE, CV_OnOff, NULL);
+
 player_t *seenplayer; // player we're aiming at right now
 
 // now automatically allocated in D_RegisterClientCommands
diff --git a/src/g_game.h b/src/g_game.h
index f72ea6b41b..258c8c27c7 100644
--- a/src/g_game.h
+++ b/src/g_game.h
@@ -61,6 +61,8 @@ extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_chasefreelook2, cv_mous
 extern consvar_t cv_useranalog[2], cv_analog[2];
 extern consvar_t cv_directionchar[2];
 
+extern consvar_t cv_sloperoll;
+
 typedef enum {
 	CS_LEGACY,
 	CS_LMAOGALOG,
diff --git a/src/p_mobj.c b/src/p_mobj.c
index d248c517ee..e3daf69965 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -1442,7 +1442,7 @@ void P_CheckGravity(mobj_t *mo, boolean affect)
 //
 void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope)
 {
-	if (slope)
+	if (slope && cv_sloperoll.value)
 	{
 		fixed_t tempz = slope->normal.z;
 		fixed_t tempy = slope->normal.y;
diff --git a/src/r_main.c b/src/r_main.c
index 7a3fe512ea..d724db8ec5 100644
--- a/src/r_main.c
+++ b/src/r_main.c
@@ -1736,6 +1736,8 @@ void R_RegisterEngineStuff(void)
 
 	CV_RegisterVar(&cv_viewroll);
 
+	CV_RegisterVar(&cv_sloperoll);
+
 	CV_RegisterVar(&cv_showhud);
 	CV_RegisterVar(&cv_translucenthud);
 
-- 
GitLab


From b816ecd5d50c2b3710c6f88bf2f77b138ffd31f8 Mon Sep 17 00:00:00 2001
From: chromaticpipe <chromaticpipe@gmail.com>
Date: Wed, 26 Mar 2025 14:01:29 -0500
Subject: [PATCH 4/5] Add rolling for Tails's tails and shields

---
 src/p_mobj.c | 4 ++++
 src/p_user.c | 3 +++
 2 files changed, 7 insertions(+)

diff --git a/src/p_mobj.c b/src/p_mobj.c
index e3daf69965..35ef31db11 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -6695,6 +6695,10 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield)
 	}
 	P_SetThingPosition(thing);
 	P_CheckPosition(thing, thing->x, thing->y);
+
+	thing->pitch = thing->target->pitch;
+	thing->roll = thing->target->roll;
+	
 #undef NewMH
 #undef NewPH
 #undef OldMH
diff --git a/src/p_user.c b/src/p_user.c
index 67e63fa433..1c5e00bf96 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -11514,6 +11514,9 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails)
 		tails->flags2 |= MF2_SHADOW;
 	else
 		tails->flags2 &= ~MF2_SHADOW;
+	
+	tails->pitch = player->mo->pitch;
+	tails->roll = player->mo->roll;
 }
 
 // Metal Sonic's jet fume
-- 
GitLab


From d3241425968bfd5e6cfca3f5df296c8a08382ca6 Mon Sep 17 00:00:00 2001
From: chromaticpipe <chromaticpipe@gmail.com>
Date: Wed, 26 Mar 2025 15:46:40 -0500
Subject: [PATCH 5/5] Fix angle not resetting in the hackiest way possible and
 only apply rollangle to players

---
 src/p_local.h  |  3 ++-
 src/p_map.c    |  4 ++--
 src/p_mobj.c   | 22 ++++++++++++++++------
 src/p_slopes.c |  4 ++--
 src/p_user.c   |  5 +++++
 5 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/src/p_local.h b/src/p_local.h
index 70714ce3b4..be7e2a6b88 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -555,6 +555,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings);
 void P_DoSuperDetransformation(player_t *player);
 void P_ExplodeMissile(mobj_t *mo);
 void P_CheckGravity(mobj_t *mo, boolean affect);
-void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope);
+void P_SetPitchRollFromSlope(player_t *player, pslope_t *slope);
+void P_ResetPitchRoll(mobj_t *mo);
 
 #endif // __P_LOCAL__
diff --git a/src/p_map.c b/src/p_map.c
index 849249bf5f..13cfabd2c3 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -2900,7 +2900,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
 			if (thing->momz <= 0)
 			{
 				thing->standingslope = tmfloorslope;
-				P_SetPitchRollFromSlope(thing, thing->standingslope);
+				//P_SetPitchRollFromSlope(thing, thing->standingslope);
 
 				if (thing->momz == 0 && thing->player && !startingonground)
 					P_PlayerHitFloor(thing->player, true);
@@ -2913,7 +2913,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
 			if (thing->momz >= 0)
 			{
 				thing->standingslope = tmceilingslope;
-				P_SetPitchRollFromSlope(thing, thing->standingslope);
+				//P_SetPitchRollFromSlope(thing, thing->standingslope);
 
 				if (thing->momz == 0 && thing->player && !startingonground)
 					P_PlayerHitFloor(thing->player, true);
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 35ef31db11..d5a98c97cf 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -1440,7 +1440,7 @@ void P_CheckGravity(mobj_t *mo, boolean affect)
 //
 // P_SetPitchRollFromSlope
 //
-void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope)
+void P_SetPitchRollFromSlope(player_t *player, pslope_t *slope)
 {
 	if (slope && cv_sloperoll.value)
 	{
@@ -1448,15 +1448,25 @@ void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope)
 		fixed_t tempy = slope->normal.y;
 		fixed_t tempx = slope->normal.x;
 
-		mo->pitch = R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx);
-		mo->roll = R_PointToAngle2(0, 0, tempz, tempy);
+		player->mo->pitch = R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx);
+		player->mo->roll = R_PointToAngle2(0, 0, tempz, tempy);
 	}
 	else
 	{
-		mo->pitch = mo->roll = 0;
+		P_ResetPitchRoll(player->mo);
 	}
 }
 
+//
+// P_ResetPitchRoll
+//
+void P_ResetPitchRoll(mobj_t *mo)
+{
+	mo->pitch = 0;
+	mo->roll = 0;
+}
+
+
 #define STOPSPEED (FRACUNIT)
 
 //
@@ -1890,7 +1900,7 @@ void P_XYMovement(mobj_t *mo)
 			// Now compare the Zs of the different quantizations
 			if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later
 				mo->standingslope = oldslope;
-				P_SetPitchRollFromSlope(mo, mo->standingslope);
+				//P_SetPitchRollFromSlope(mo, mo->standingslope);
 				P_SlopeLaunch(mo);
 
 				//CONS_Printf("launched off of slope - ");
@@ -2440,7 +2450,7 @@ boolean P_ZMovement(mobj_t *mo)
 		if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM))
 		{
 			mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope;
-			P_SetPitchRollFromSlope(mo, mo->standingslope);
+			//P_SetPitchRollFromSlope(mo, mo->standingslope);
 			P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope);
 		}
 
diff --git a/src/p_slopes.c b/src/p_slopes.c
index e7d084e690..a78d5c46f7 100644
--- a/src/p_slopes.c
+++ b/src/p_slopes.c
@@ -1099,7 +1099,7 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
 		if (P_MobjFlip(thing)*(thing->momz) < 0) // falling, land on slope
 		{
 			thing->standingslope = slope;
-			P_SetPitchRollFromSlope(thing, slope);
+			//P_SetPitchRollFromSlope(thing, slope);
 
 			if (!thing->player || !(thing->player->pflags & PF_BOUNCING))
 				thing->momz = -P_MobjFlip(thing);
@@ -1117,7 +1117,7 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
 		thing->momx = mom.x;
 		thing->momy = mom.y;
 		thing->standingslope = slope;
-		P_SetPitchRollFromSlope(thing, slope);
+		//P_SetPitchRollFromSlope(thing, slope);
 		if (!thing->player || !(thing->player->pflags & PF_BOUNCING))
 			thing->momz = -P_MobjFlip(thing);
 	}
diff --git a/src/p_user.c b/src/p_user.c
index 1c5e00bf96..5a812a7e4b 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -1117,6 +1117,10 @@ void P_ResetPlayer(player_t *player)
 	player->skidtime = 0;
 	if (player-players == consoleplayer && botingame)
 		CV_SetValue(&cv_analog[1], true);
+	if (player->mo != NULL && P_MobjWasRemoved(player->mo) == false)
+	{
+		P_ResetPitchRoll(player->mo);
+	}
 }
 
 // P_PlayerCanDamage
@@ -12704,6 +12708,7 @@ void P_PlayerThink(player_t *player)
 		I_Error("I'm done!\n");
 	}*/
 	DoABarrelRoll(player);
+	P_SetPitchRollFromSlope(player, player->mo->standingslope);
 }
 
 // Checks if the mobj is above lava. Used by Pterabyte.
-- 
GitLab