From f9aeee5b4a7bb93845398408e9019518fbe222ac Mon Sep 17 00:00:00 2001
From: Mitchell Richters <mjr4077au@gmail.com>
Date: Fri, 9 Dec 2022 17:52:52 +1100
Subject: [PATCH] - Split out view angle stuff out of
 `PlayerAngles::applyYaw()` into `PlayerAngles::doViewYaw()`.

* Do all the view angle stuff as interpolated changes in the playsim as well, there's no need for these to be done at ticrate.
---
 source/core/gameinput.cpp             | 35 ++++++++++++++++++---------
 source/core/gameinput.h               | 14 +++++------
 source/games/blood/src/player.cpp     |  2 ++
 source/games/blood/src/view.cpp       |  7 +++---
 source/games/duke/src/hudweapon_d.cpp |  2 +-
 source/games/duke/src/input.cpp       |  1 -
 source/games/duke/src/player.cpp      | 12 ++++-----
 source/games/duke/src/player_d.cpp    |  1 +
 source/games/duke/src/player_r.cpp    |  3 ++-
 source/games/duke/src/render.cpp      |  4 +--
 source/games/duke/src/types.h         |  2 +-
 source/games/exhumed/src/map.cpp      |  2 +-
 source/games/exhumed/src/player.cpp   |  2 ++
 source/games/exhumed/src/view.cpp     |  6 ++---
 source/games/sw/src/draw.cpp          |  5 ++--
 source/games/sw/src/panel.cpp         |  2 +-
 source/games/sw/src/player.cpp        |  2 ++
 17 files changed, 58 insertions(+), 44 deletions(-)

diff --git a/source/core/gameinput.cpp b/source/core/gameinput.cpp
index b11e845fa..38a48e24e 100644
--- a/source/core/gameinput.cpp
+++ b/source/core/gameinput.cpp
@@ -80,7 +80,7 @@ inline static DAngle getscaledangle(const DAngle value, const double scaleAdjust
 	return ((object.Normalized180() * getTicrateScale(value)) + push) * getCorrectedScale(scaleAdjust);
 }
 
-inline static void scaletozero(DAngle& object, const DAngle value, const double scaleAdjust, const DAngle push = DAngle::fromDeg(32. / 465.))
+inline static void scaletozero(DAngle& object, const DAngle value, const double scaleAdjust = 1, const DAngle push = DAngle::fromDeg(32. / 465.))
 {
 	if (auto sgn = object.Sgn())
 	{
@@ -224,17 +224,7 @@ void PlayerAngles::applyPitch(float const horz, ESyncBits* actions, double const
 
 void PlayerAngles::applyYaw(float const avel, ESyncBits* actions, double const scaleAdjust)
 {
-	// Process angle return to zeros.
-	scaletozero(ViewAngles.Roll, YAW_LOOKRETURN, scaleAdjust);
-	scaletozero(ViewAngles.Yaw, YAW_LOOKRETURN, scaleAdjust);
-
-	// Process keyboard input.
-	if (auto looking = !!(*actions & SB_LOOK_RIGHT) - !!(*actions & SB_LOOK_LEFT))
-	{
-		ViewAngles.Yaw += getTicrateScale(YAW_LOOKINGSPEED) * getCorrectedScale(scaleAdjust) * looking;
-		ViewAngles.Roll += getTicrateScale(YAW_ROTATESPEED) * getCorrectedScale(scaleAdjust) * looking;
-	}
-
+	// Process only if movement isn't locked.
 	if (!lockedYaw())
 	{
 		// add player's input
@@ -324,6 +314,27 @@ void PlayerAngles::doViewPitch(const DVector2& pos, DAngle const ang, bool const
 }
 
 
+//---------------------------------------------------------------------------
+//
+// Player's look left/right key angle handler.
+//
+//---------------------------------------------------------------------------
+
+void PlayerAngles::doViewYaw(const ESyncBits actions)
+{
+	// Process angle return to zeros.
+	scaletozero(ViewAngles.Yaw, YAW_LOOKRETURN);
+	scaletozero(ViewAngles.Roll, YAW_LOOKRETURN);
+
+	// Process keyboard input.
+	if (auto looking = !!(actions & SB_LOOK_RIGHT) - !!(actions & SB_LOOK_LEFT))
+	{
+		ViewAngles.Yaw += getTicrateScale(YAW_LOOKINGSPEED) * looking;
+		ViewAngles.Roll += getTicrateScale(YAW_ROTATESPEED) * looking;
+	}
+}
+
+
 //---------------------------------------------------------------------------
 //
 //
diff --git a/source/core/gameinput.h b/source/core/gameinput.h
index 871fa1ad1..deb02b581 100644
--- a/source/core/gameinput.h
+++ b/source/core/gameinput.h
@@ -28,6 +28,7 @@ struct PlayerAngles
 
 	// Prototypes for applying view.
 	void doViewPitch(const DVector2& pos, DAngle const ang, bool const aimmode, bool const canslopetilt, sectortype* const cursectnum, double const scaleAdjust = 1, bool const climbing = false);
+	void doViewYaw(const ESyncBits actions);
 
 	// General methods.
 	void resetAdjustments() { Adjustments = {}; }
@@ -82,13 +83,13 @@ struct PlayerAngles
 	}
 
 	// Miscellaneous helpers.
-	double angLOOKANGHALF(double const interpfrac) { return angRENDERLOOKANG(interpfrac).Normalized180().Degrees() * (128. / 45.); }
-	double angLOOKINGARC(double const interpfrac) { return fabs(angRENDERLOOKANG(interpfrac).Normalized180().Degrees() * (1024. / 1620.)); }
+	double angLOOKANGHALF(double const interpfrac) { return angLERPLOOKANG(interpfrac).Normalized180().Degrees() * (128. / 45.); }
+	double angLOOKINGARC(double const interpfrac) { return fabs(angLERPLOOKANG(interpfrac).Normalized180().Degrees() * (1024. / 1620.)); }
 
 	// Crosshair x/y offsets based on look_ang's tangent.
 	DVector2 angCROSSHAIROFFSETS(const double interpfrac)
 	{
-		return DVector2(159.72, 145.5 * -angRENDERROTSCRN(interpfrac).Sin()) * -angRENDERLOOKANG(interpfrac).Tan() * (1. / tan(r_fov * pi::pi() / 360.));
+		return DVector2(159.72, 145.5 * -angLERPROTSCRN(interpfrac).Sin()) * -angLERPLOOKANG(interpfrac).Tan() * (1. / tan(r_fov * pi::pi() / 360.));
 	}
 
 	// Weapon x/y offsets based on the above.
@@ -103,14 +104,11 @@ struct PlayerAngles
 	DAngle horizOLDSUM() { return ZzOLDHORIZON() + PrevViewAngles.Pitch; }
 	DAngle horizSUM() { return ZzHORIZON() + ViewAngles.Pitch; }
 	DAngle horizLERPSUM(double const interpfrac) { return interpolatedvalue(horizOLDSUM(), horizSUM(), interpfrac); }
-	DAngle angOLDSUM() { return ZzOLDANGLE() + PrevViewAngles.Yaw; }
-	DAngle angSUM() { return ZzANGLE() + ViewAngles.Yaw; }
-	DAngle angLERPSUM(double const interpfrac) { return interpolatedvalue(angOLDSUM(), angSUM(), interpfrac); }
+	DAngle angSUM(const double interpfrac) { return ZzANGLE() + angLERPLOOKANG(interpfrac); }
+	DAngle angLERPSUM(double const interpfrac) { return interpolatedvalue(ZzOLDANGLE() + PrevViewAngles.Yaw, ZzANGLE() + ViewAngles.Yaw, interpfrac); }
 	DAngle angLERPANG(double const interpfrac) { return interpolatedvalue(ZzOLDANGLE(), ZzANGLE(), interpfrac); }
 	DAngle angLERPLOOKANG(double const interpfrac) { return interpolatedvalue(PrevViewAngles.Yaw, ViewAngles.Yaw, interpfrac); }
 	DAngle angLERPROTSCRN(double const interpfrac) { return interpolatedvalue(PrevViewAngles.Roll, ViewAngles.Roll, interpfrac); }
-	DAngle angRENDERLOOKANG(double const interpfrac) { return !SyncInput() ? ViewAngles.Yaw : angLERPLOOKANG(interpfrac); }
-	DAngle angRENDERROTSCRN(double const interpfrac) { return !SyncInput() ? ViewAngles.Roll : angLERPROTSCRN(interpfrac); }
 
 private:
 	// DRotator indices.
diff --git a/source/games/blood/src/player.cpp b/source/games/blood/src/player.cpp
index 39cba8e11..41f7e8c63 100644
--- a/source/games/blood/src/player.cpp
+++ b/source/games/blood/src/player.cpp
@@ -1585,6 +1585,8 @@ void ProcessInput(PLAYER* pPlayer)
 		actor->vel.XY() += DVector2(pInput->fvel * fvAccel, pInput->svel * svAccel).Rotated(actor->spr.Angles.Yaw) * speed;
 	}
 
+	pPlayer->Angles.doViewYaw(pInput->actions);
+
 	if (SyncInput())
 	{
 		pPlayer->Angles.applyYaw(pInput->avel, &pInput->actions);
diff --git a/source/games/blood/src/view.cpp b/source/games/blood/src/view.cpp
index bd982fcdb..4a3a914f2 100644
--- a/source/games/blood/src/view.cpp
+++ b/source/games/blood/src/view.cpp
@@ -446,7 +446,7 @@ static void DrawMap(PLAYER* pPlayer, const double interpfrac)
 		setViewport(Hud_Stbar);
 		tm = 1;
 	}
-	auto ang = !SyncInput() ? pPlayer->Angles.angSUM() : pPlayer->Angles.angLERPSUM(interpfrac);
+	auto ang = !SyncInput() ? pPlayer->Angles.angSUM(interpfrac) : pPlayer->Angles.angLERPSUM(interpfrac);
 	DrawOverheadMap(pPlayer->actor->interpolatedpos(interpfrac).XY(), ang, interpfrac);
 	if (tm)
 		setViewport(hud_size);
@@ -501,16 +501,15 @@ static void SetupView(PLAYER* pPlayer, DVector3& cPos, DAngle& cA, DAngle& cH, s
 
 		if (!SyncInput())
 		{
-			cA = pPlayer->Angles.angSUM();
+			cA = pPlayer->Angles.angSUM(interpfrac);
 			cH = pPlayer->Angles.horizSUM();
-			rotscrnang = pPlayer->Angles.ViewAngles.Roll;
 		}
 		else
 		{
 			cA = pPlayer->Angles.angLERPSUM(interpfrac);
 			cH = pPlayer->Angles.horizLERPSUM(interpfrac);
-			rotscrnang = pPlayer->Angles.angLERPROTSCRN(interpfrac);
 		}
+		rotscrnang = pPlayer->Angles.angLERPROTSCRN(interpfrac);
 	}
 
 	viewUpdateShake(pPlayer, cPos, cA, cH, shakeX, shakeY);
diff --git a/source/games/duke/src/hudweapon_d.cpp b/source/games/duke/src/hudweapon_d.cpp
index 304d0d06f..0bc7ae1c7 100644
--- a/source/games/duke/src/hudweapon_d.cpp
+++ b/source/games/duke/src/hudweapon_d.cpp
@@ -232,7 +232,7 @@ void displayweapon_d(int snum, double interpfrac)
 	auto horiz = !SyncInput() ? p->Angles.horizSUM() : p->Angles.horizLERPSUM(interpfrac);
 	auto pitchoffset = interpolatedvalue(0., 16., horiz / DAngle90);
 	auto yawinput = getavel(snum) * (1. / 16.);
-	auto angle = -p->Angles.angRENDERROTSCRN(interpfrac);
+	auto angle = -p->Angles.angLERPROTSCRN(interpfrac);
 	auto weapon_xoffset = 160 - 90 - (BobVal(512 + weapon_sway * 0.5) * (16384. / 1536.)) - 58 - p->weapon_ang;
 	auto shade = min(p->GetActor()->spr.shade, (int8_t)24);
 
diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp
index 198e072dd..7b69002f3 100644
--- a/source/games/duke/src/input.cpp
+++ b/source/games/duke/src/input.cpp
@@ -837,7 +837,6 @@ void GameInterface::GetInput(ControlInfo* const hidInput, double const scaleAdju
 			// Do these in the same order as the old code.
 			doslopetilting(p, scaleAdjust);
 			p->Angles.applyYaw(p->adjustavel(input.avel), &p->sync.actions, scaleAdjust);
-			p->apply_seasick(scaleAdjust);
 			p->Angles.applyPitch(input.horz, &p->sync.actions, scaleAdjust);
 		}
 
diff --git a/source/games/duke/src/player.cpp b/source/games/duke/src/player.cpp
index 68d677d3b..3e838fabf 100644
--- a/source/games/duke/src/player.cpp
+++ b/source/games/duke/src/player.cpp
@@ -729,23 +729,23 @@ void playerJump(int snum, double floorz, double ceilingz)
 //
 //---------------------------------------------------------------------------
 
-void player_struct::apply_seasick(double factor)
+void player_struct::apply_seasick()
 {
 	if (isRRRA() && SeaSick && (dead_flag == 0 || (dead_flag && resurrected)))
 	{
 		if (SeaSick < 250)
 		{
 			if (SeaSick >= 180)
-				Angles.ViewAngles.Roll -= DAngle::fromDeg(24 * factor * BAngToDegree);
+				Angles.ViewAngles.Roll -= DAngle::fromDeg(24 * BAngToDegree);
 			else if (SeaSick >= 130)
-				Angles.ViewAngles.Roll += DAngle::fromDeg(24 * factor * BAngToDegree);
+				Angles.ViewAngles.Roll += DAngle::fromDeg(24 * BAngToDegree);
 			else if (SeaSick >= 70)
-				Angles.ViewAngles.Roll -= DAngle::fromDeg(24 * factor * BAngToDegree);
+				Angles.ViewAngles.Roll -= DAngle::fromDeg(24 * BAngToDegree);
 			else if (SeaSick >= 20)
-				Angles.ViewAngles.Roll += DAngle::fromDeg(24 * factor * BAngToDegree);
+				Angles.ViewAngles.Roll += DAngle::fromDeg(24 * BAngToDegree);
 		}
 		if (SeaSick < 250)
-			Angles.ViewAngles.Yaw = DAngle::fromDeg(((krand() & 255) - 128) * factor * BAngToDegree);
+			Angles.ViewAngles.Yaw = DAngle::fromDeg(((krand() & 255) - 128) * BAngToDegree);
 	}
 }
 
diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp
index 759061137..73ef5402a 100644
--- a/source/games/duke/src/player_d.cpp
+++ b/source/games/duke/src/player_d.cpp
@@ -2889,6 +2889,7 @@ void processinput_d(int snum)
 	p->psectlotag = psectlotag;
 
 	//Do the quick lefts and rights
+	p->Angles.doViewYaw(actions);
 
 	if (movementBlocked(p))
 	{
diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp
index acea553e4..a0f4c3557 100644
--- a/source/games/duke/src/player_r.cpp
+++ b/source/games/duke/src/player_r.cpp
@@ -3497,7 +3497,7 @@ void processinput_r(int snum)
 	doubvel = TICSPERFRAME;
 
 	checklook(snum, actions);
-	p->apply_seasick(1);
+	p->apply_seasick();
 
 	auto oldpos = p->GetActor()->opos;
 
@@ -3544,6 +3544,7 @@ void processinput_r(int snum)
 	p->psectlotag = psectlotag;
 
 	//Do the quick lefts and rights
+	p->Angles.doViewYaw(actions);
 
 	if (movementBlocked(p))
 	{
diff --git a/source/games/duke/src/render.cpp b/source/games/duke/src/render.cpp
index 9f4cc10c2..c37576170 100644
--- a/source/games/duke/src/render.cpp
+++ b/source/games/duke/src/render.cpp
@@ -271,7 +271,7 @@ void displayrooms(int snum, double interpfrac, bool sceneonly)
 		setgamepalette(setpal(p));
 
 		// set screen rotation.
-		rotscrnang = !SyncInput() ? p->Angles.ViewAngles.Roll : p->Angles.angLERPROTSCRN(interpfrac);
+		rotscrnang = p->Angles.angLERPROTSCRN(interpfrac);
 
 		// use player's actor initially.
 		viewer = p->GetActor();
@@ -304,7 +304,7 @@ void displayrooms(int snum, double interpfrac, bool sceneonly)
 			else
 			{
 				// This is for real time updating of the view direction.
-				cang = p->Angles.angSUM();
+				cang = p->Angles.angSUM(interpfrac);
 				choriz = p->Angles.horizSUM();
 			}
 		}
diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h
index 0abfe8c8a..6bfc066b1 100644
--- a/source/games/duke/src/types.h
+++ b/source/games/duke/src/types.h
@@ -309,7 +309,7 @@ struct player_struct
 	DDukeActor* GetActor();
 	int GetPlayerNum();
 
-	void apply_seasick(double factor);
+	void apply_seasick();
 	void backuppos(bool noclipping = false);
 	void backupweapon();
 	void checkhardlanding();
diff --git a/source/games/exhumed/src/map.cpp b/source/games/exhumed/src/map.cpp
index 0cc203ca7..3a2422634 100644
--- a/source/games/exhumed/src/map.cpp
+++ b/source/games/exhumed/src/map.cpp
@@ -55,7 +55,7 @@ void DrawMap(double const interpfrac)
     if (!nFreeze && automapMode != am_off) 
     {
         auto pPlayerActor = PlayerList[nLocalPlayer].pActor;
-        auto ang = !SyncInput() ? PlayerList[nLocalPlayer].Angles.angSUM() : PlayerList[nLocalPlayer].Angles.angLERPSUM(interpfrac);
+        auto ang = !SyncInput() ? PlayerList[nLocalPlayer].Angles.angSUM(interpfrac) : PlayerList[nLocalPlayer].Angles.angLERPSUM(interpfrac);
         DrawOverheadMap(pPlayerActor->interpolatedpos(interpfrac).XY(), ang, interpfrac);
     }
 }
diff --git a/source/games/exhumed/src/player.cpp b/source/games/exhumed/src/player.cpp
index d97cc82df..0fe41cf32 100644
--- a/source/games/exhumed/src/player.cpp
+++ b/source/games/exhumed/src/player.cpp
@@ -980,6 +980,8 @@ void AIPlayer::Tick(RunListEvent* ev)
         }
     }
 
+    PlayerList[nPlayer].Angles.doViewYaw(sPlayerInput[nLocalPlayer].actions);
+
     // loc_1A494:
     if (SyncInput())
     {
diff --git a/source/games/exhumed/src/view.cpp b/source/games/exhumed/src/view.cpp
index 145862eca..7d50615f1 100644
--- a/source/games/exhumed/src/view.cpp
+++ b/source/games/exhumed/src/view.cpp
@@ -235,15 +235,15 @@ void DrawView(double interpfrac, bool sceneonly)
         if (!SyncInput())
         {
             nCamerapan = PlayerList[nLocalPlayer].Angles.horizSUM();
-            nCameraang = PlayerList[nLocalPlayer].Angles.angSUM();
-            rotscrnang = PlayerList[nLocalPlayer].Angles.ViewAngles.Roll;
+            nCameraang = PlayerList[nLocalPlayer].Angles.angSUM(interpfrac);
         }
         else
         {
             nCamerapan = PlayerList[nLocalPlayer].Angles.horizLERPSUM(interpfrac);
             nCameraang = PlayerList[nLocalPlayer].Angles.angLERPSUM(interpfrac);
-            rotscrnang = PlayerList[nLocalPlayer].Angles.angLERPROTSCRN(interpfrac);
+            
         }
+        rotscrnang = PlayerList[nLocalPlayer].Angles.angLERPROTSCRN(interpfrac);
 
         if (!bCamera)
         {
diff --git a/source/games/sw/src/draw.cpp b/source/games/sw/src/draw.cpp
index 0a64d22c6..e8aa0d376 100644
--- a/source/games/sw/src/draw.cpp
+++ b/source/games/sw/src/draw.cpp
@@ -1246,14 +1246,13 @@ void drawscreen(PLAYER* pp, double interpfrac, bool sceneonly)
     {
         tang = camerapp->Angles.angLERPSUM(interpfrac);
         thoriz = camerapp->Angles.horizLERPSUM(interpfrac);
-        trotscrnang = camerapp->Angles.angLERPROTSCRN(interpfrac);
     }
     else
     {
-        tang = pp->Angles.angSUM();
+        tang = pp->Angles.angSUM(interpfrac);
         thoriz = pp->Angles.horizSUM();
-        trotscrnang = pp->Angles.ViewAngles.Roll;
     }
+    trotscrnang = camerapp->Angles.angLERPROTSCRN(interpfrac);
     tsect = camerapp->cursector;
 
     updatesector(tpos, &tsect);
diff --git a/source/games/sw/src/panel.cpp b/source/games/sw/src/panel.cpp
index a414b4f7c..078fb83c4 100644
--- a/source/games/sw/src/panel.cpp
+++ b/source/games/sw/src/panel.cpp
@@ -7429,7 +7429,7 @@ void pDisplaySprites(PLAYER* pp, double interpfrac)
     int flags;
 
     const auto offsets = pp->Angles.angWEAPONOFFSETS(interpfrac);
-    const auto angle = -pp->Angles.angRENDERROTSCRN(interpfrac).Buildfang();
+    const auto angle = -pp->Angles.angLERPROTSCRN(interpfrac).Buildfang();
 
     auto list = pp->GetPanelSpriteList();
     for (auto psp = list->Next; next = psp->Next, psp != list; psp = next)
diff --git a/source/games/sw/src/player.cpp b/source/games/sw/src/player.cpp
index 37a5dec27..7313beff1 100644
--- a/source/games/sw/src/player.cpp
+++ b/source/games/sw/src/player.cpp
@@ -2069,6 +2069,8 @@ void DoPlayerMove(PLAYER* pp)
 
     SlipSlope(pp);
 
+    pp->Angles.doViewYaw(pp->input.actions);
+
     if (!SyncInput())
     {
         pp->Flags2 |= (PF2_INPUT_CAN_TURN_GENERAL);