diff --git a/source/core/gameinput.cpp b/source/core/gameinput.cpp
index 7b863da45..622518630 100644
--- a/source/core/gameinput.cpp
+++ b/source/core/gameinput.cpp
@@ -347,7 +347,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerAngles& w, P
 
 		if (arc.isReading())
 		{
-			w.ZzOLDANGLE = w.ZzANGLE();
+			w.ZzOLDANGLE() = w.ZzANGLE();
 			w.ZzOLDLOOKANG = w.ZzLOOKANG;
 			w.ZzOLDROTSCRNANG = w.ZzROTSCRNANG;
 			w.legacyDisabledYaw = w.legacyDisabledYaw;
diff --git a/source/core/gameinput.h b/source/core/gameinput.h
index aa6d1614d..6e38c649f 100644
--- a/source/core/gameinput.h
+++ b/source/core/gameinput.h
@@ -15,6 +15,8 @@ struct PlayerAngles
 	DAngle& ZzOLDHORIZON() { return prevHoriz; }
 	DAngle thisAngle;
 	DAngle& ZzANGLE() { return thisAngle; }
+	DAngle prevAngle;
+	DAngle& ZzOLDANGLE() { return prevAngle; }
 
 	friend FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerAngles& w, PlayerAngles* def);
 
@@ -86,7 +88,7 @@ struct PlayerAngles
 		else
 		{
 			ZzANGLE() = value;
-			if (backup) ZzOLDANGLE = ZzANGLE();
+			if (backup) ZzOLDANGLE() = ZzANGLE();
 		}
 	}
 
@@ -146,7 +148,7 @@ struct PlayerAngles
 	DAngle horizLERPSUM(double const interpfrac) { return interpolatedvalue(horizOLDSUM(), horizSUM(), interpfrac); }
 	void resetAdjustmentPitch() { legacyAdjustmentPitch = nullAngle; }
 
-	DAngle ZzOLDANGLE, ZzLOOKANG, ZzOLDLOOKANG, ZzROTSCRNANG, ZzOLDROTSCRNANG, YawSpin;
+	DAngle ZzLOOKANG, ZzOLDLOOKANG, ZzROTSCRNANG, ZzOLDROTSCRNANG, YawSpin;
 	void processLegacyHelperYaw(double const scaleAdjust)
 	{
 		if (targetedYaw())
@@ -170,20 +172,20 @@ struct PlayerAngles
 	}
 	void backupYaw()
 	{
-		ZzOLDANGLE = ZzANGLE();
+		ZzOLDANGLE() = ZzANGLE();
 		ZzOLDLOOKANG = ZzLOOKANG;
 		ZzOLDROTSCRNANG = ZzROTSCRNANG;
 	}
 	void restoreYaw()
 	{
-		ZzANGLE() = ZzOLDANGLE;
+		ZzANGLE() = ZzOLDANGLE();
 		ZzLOOKANG = ZzOLDLOOKANG;
 		ZzROTSCRNANG = ZzOLDROTSCRNANG;
 	}
-	DAngle angOLDSUM() { return ZzOLDANGLE + ZzOLDLOOKANG; }
+	DAngle angOLDSUM() { return ZzOLDANGLE() + ZzOLDLOOKANG; }
 	DAngle angSUM() { return ZzANGLE() + ZzLOOKANG; }
 	DAngle angLERPSUM(double const interpfrac) { return interpolatedvalue(angOLDSUM(), angSUM(), interpfrac); }
-	DAngle angLERPANG(double const interpfrac) { return interpolatedvalue(ZzOLDANGLE, ZzANGLE(), interpfrac); }
+	DAngle angLERPANG(double const interpfrac) { return interpolatedvalue(ZzOLDANGLE(), ZzANGLE(), interpfrac); }
 	DAngle angLERPLOOKANG(double const interpfrac) { return interpolatedvalue(ZzOLDLOOKANG, ZzLOOKANG, interpfrac); }
 	DAngle angLERPROTSCRN(double const interpfrac) { return interpolatedvalue(ZzOLDROTSCRNANG, ZzROTSCRNANG, interpfrac); }
 	DAngle angRENDERLOOKANG(double const interpfrac) { return !SyncInput() ? ZzLOOKANG : angLERPLOOKANG(interpfrac); }
diff --git a/source/games/blood/src/osdcmd.cpp b/source/games/blood/src/osdcmd.cpp
index 625006620..be40e5834 100644
--- a/source/games/blood/src/osdcmd.cpp
+++ b/source/games/blood/src/osdcmd.cpp
@@ -40,7 +40,7 @@ void GameInterface::WarpToCoords(double x, double y, double z, DAngle ang)
 
 	if (ang != DAngle::fromDeg(INT_MIN))
 	{
-		pPlayer->Angles.ZzOLDANGLE = pPlayer->Angles.ZzANGLE() = ang;
+		pPlayer->Angles.ZzOLDANGLE() = pPlayer->Angles.ZzANGLE() = ang;
 	}
 }
 
diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp
index 181f11655..0efb51e67 100644
--- a/source/games/duke/src/actors.cpp
+++ b/source/games/duke/src/actors.cpp
@@ -401,7 +401,7 @@ void moveplayers(void)
 			{
 				act->restorepos();
 				act->backupz();
-				act->spr.Angles.Yaw = p->Angles.ZzOLDANGLE;
+				act->spr.Angles.Yaw = p->Angles.ZzOLDANGLE();
 				SetActor(act, act->spr.pos);
 			}
 			else
diff --git a/source/games/duke/src/ccmds.cpp b/source/games/duke/src/ccmds.cpp
index 7624fde59..cf4c0c560 100644
--- a/source/games/duke/src/ccmds.cpp
+++ b/source/games/duke/src/ccmds.cpp
@@ -123,7 +123,7 @@ void GameInterface::WarpToCoords(double x, double y, double z, DAngle ang)
 
 	if (ang != DAngle::fromDeg(INT_MIN))
 	{
-		p->Angles.ZzOLDANGLE = p->Angles.ZzANGLE() = ang;
+		p->Angles.ZzOLDANGLE() = p->Angles.ZzANGLE() = ang;
 	}
 }
 
diff --git a/source/games/duke/src/game_misc.cpp b/source/games/duke/src/game_misc.cpp
index ce0d0107e..ca12a03ba 100644
--- a/source/games/duke/src/game_misc.cpp
+++ b/source/games/duke/src/game_misc.cpp
@@ -274,13 +274,13 @@ void drawoverlays(double interpfrac)
 				else
 				{
 					cposxy = interpolatedvalue(pp->GetActor()->getPrevPosWithOffsetZ(), pp->GetActor()->getPosWithOffsetZ(), interpfrac).XY();
-					cang = !SyncInput() ? pp->Angles.ZzANGLE() : interpolatedvalue(pp->Angles.ZzOLDANGLE, pp->Angles.ZzANGLE(), interpfrac);
+					cang = !SyncInput() ? pp->Angles.ZzANGLE() : interpolatedvalue(pp->Angles.ZzOLDANGLE(), pp->Angles.ZzANGLE(), interpfrac);
 				}
 			}
 			else
 			{
 				cposxy = pp->GetActor()->opos.XY();
-				cang = pp->Angles.ZzOLDANGLE;
+				cang = pp->Angles.ZzOLDANGLE();
 			}
 			DrawOverheadMap(cposxy, cang, interpfrac);
 			RestoreInterpolations();
diff --git a/source/games/duke/src/gameexec.cpp b/source/games/duke/src/gameexec.cpp
index 597361d3c..3dcf9a347 100644
--- a/source/games/duke/src/gameexec.cpp
+++ b/source/games/duke/src/gameexec.cpp
@@ -477,7 +477,7 @@ void DoPlayer(bool bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor,
 		break;
 
 	case PLAYER_OANG:
-		if (!bSet) SetGameVarID(lVar2, ps[iPlayer].Angles.ZzOLDANGLE.Buildang(), sActor, sPlayer);
+		if (!bSet) SetGameVarID(lVar2, ps[iPlayer].Angles.ZzOLDANGLE().Buildang(), sActor, sPlayer);
 		break;
 
 	case PLAYER_ANGVEL: // This no longer exists.
diff --git a/source/games/duke/src/premap.cpp b/source/games/duke/src/premap.cpp
index 39921d48a..2bbac1d9a 100644
--- a/source/games/duke/src/premap.cpp
+++ b/source/games/duke/src/premap.cpp
@@ -72,7 +72,7 @@ void pickrandomspot(int snum)
 	p->GetActor()->spr.pos = po[i].opos;
 	p->GetActor()->backuppos();
 	p->setbobpos();
-	p->Angles.ZzOLDANGLE = p->Angles.ZzANGLE() = po[i].oa;
+	p->Angles.ZzOLDANGLE() = p->Angles.ZzANGLE() = po[i].oa;
 	p->setCursector(po[i].os);
 }
 
@@ -627,7 +627,7 @@ void resetpspritevars(int g, const DVector3& startpos)
 			act->SetOwner(act);
 
 			ps[j].setbobpos();
-			ps[j].Angles.ZzOLDANGLE = ps[j].Angles.ZzANGLE() = act->spr.Angles.Yaw; // check me out later.
+			ps[j].Angles.ZzOLDANGLE() = ps[j].Angles.ZzANGLE() = act->spr.Angles.Yaw; // check me out later.
 
 			updatesector(act->spr.pos, &ps[j].cursector);
 
diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp
index 37732ba4d..1983d7ce8 100644
--- a/source/games/duke/src/sectors_d.cpp
+++ b/source/games/duke/src/sectors_d.cpp
@@ -1516,17 +1516,17 @@ void checksectors_d(int snum)
 					return;
 		}
 		if (p->newOwner != nullptr)
-			neartag(p->GetActor()->getPrevPosWithOffsetZ(), p->GetActor()->sector(), p->Angles.ZzOLDANGLE, near, 80., NT_Lotag);
+			neartag(p->GetActor()->getPrevPosWithOffsetZ(), p->GetActor()->sector(), p->Angles.ZzOLDANGLE(), near, 80., NT_Lotag);
 		else
 		{
-			neartag(p->GetActor()->getPosWithOffsetZ(), p->GetActor()->sector(), p->Angles.ZzOLDANGLE, near, 80., NT_Lotag);
+			neartag(p->GetActor()->getPosWithOffsetZ(), p->GetActor()->sector(), p->Angles.ZzOLDANGLE(), near, 80., NT_Lotag);
 			if (near.actor() == nullptr && near.hitWall == nullptr && near.hitSector == nullptr)
-				neartag(p->GetActor()->getPosWithOffsetZ().plusZ(8), p->GetActor()->sector(), p->Angles.ZzOLDANGLE, near, 80., NT_Lotag);
+				neartag(p->GetActor()->getPosWithOffsetZ().plusZ(8), p->GetActor()->sector(), p->Angles.ZzOLDANGLE(), near, 80., NT_Lotag);
 			if (near.actor() == nullptr && near.hitWall == nullptr && near.hitSector == nullptr)
-				neartag(p->GetActor()->getPosWithOffsetZ().plusZ(16), p->GetActor()->sector(), p->Angles.ZzOLDANGLE, near, 80., NT_Lotag);
+				neartag(p->GetActor()->getPosWithOffsetZ().plusZ(16), p->GetActor()->sector(), p->Angles.ZzOLDANGLE(), near, 80., NT_Lotag);
 			if (near.actor() == nullptr && near.hitWall == nullptr && near.hitSector == nullptr)
 			{
-				neartag(p->GetActor()->getPosWithOffsetZ().plusZ(16), p->GetActor()->sector(), p->Angles.ZzOLDANGLE, near, 80., NT_Lotag | NT_Hitag);
+				neartag(p->GetActor()->getPosWithOffsetZ().plusZ(16), p->GetActor()->sector(), p->Angles.ZzOLDANGLE(), near, 80., NT_Lotag | NT_Hitag);
 				if (near.actor() != nullptr)
 				{
 					switch (near.actor()->spr.picnum)
diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp
index 12936bd9c..74ac9c7f0 100644
--- a/source/games/duke/src/sectors_r.cpp
+++ b/source/games/duke/src/sectors_r.cpp
@@ -2379,21 +2379,21 @@ void checksectors_r(int snum)
 				}
 				return;
 			}
-			neartag(p->GetActor()->getPosWithOffsetZ(), p->GetActor()->sector(), p->Angles.ZzOLDANGLE, near , 80., NT_Lotag | NT_Hitag);
+			neartag(p->GetActor()->getPosWithOffsetZ(), p->GetActor()->sector(), p->Angles.ZzOLDANGLE(), near , 80., NT_Lotag | NT_Hitag);
 		}
 
 		if (p->newOwner != nullptr)
-			neartag(p->GetActor()->getPrevPosWithOffsetZ(), p->GetActor()->sector(), p->Angles.ZzOLDANGLE, near, 80., NT_Lotag);
+			neartag(p->GetActor()->getPrevPosWithOffsetZ(), p->GetActor()->sector(), p->Angles.ZzOLDANGLE(), near, 80., NT_Lotag);
 		else
 		{
-			neartag(p->GetActor()->getPosWithOffsetZ(), p->GetActor()->sector(), p->Angles.ZzOLDANGLE, near, 80., NT_Lotag);
+			neartag(p->GetActor()->getPosWithOffsetZ(), p->GetActor()->sector(), p->Angles.ZzOLDANGLE(), near, 80., NT_Lotag);
 			if (near.actor() == nullptr && near.hitWall == nullptr && near.hitSector == nullptr)
-				neartag(p->GetActor()->getPosWithOffsetZ().plusZ(8), p->GetActor()->sector(), p->Angles.ZzOLDANGLE, near, 80., NT_Lotag);
+				neartag(p->GetActor()->getPosWithOffsetZ().plusZ(8), p->GetActor()->sector(), p->Angles.ZzOLDANGLE(), near, 80., NT_Lotag);
 			if (near.actor() == nullptr && near.hitWall == nullptr && near.hitSector == nullptr)
-				neartag(p->GetActor()->getPosWithOffsetZ().plusZ(16), p->GetActor()->sector(), p->Angles.ZzOLDANGLE, near, 80., NT_Lotag);
+				neartag(p->GetActor()->getPosWithOffsetZ().plusZ(16), p->GetActor()->sector(), p->Angles.ZzOLDANGLE(), near, 80., NT_Lotag);
 			if (near.actor() == nullptr && near.hitWall == nullptr && near.hitSector == nullptr)
 			{
-				neartag(p->GetActor()->getPosWithOffsetZ().plusZ(16), p->GetActor()->sector(), p->Angles.ZzOLDANGLE, near, 80., NT_Lotag | NT_Hitag);
+				neartag(p->GetActor()->getPosWithOffsetZ().plusZ(16), p->GetActor()->sector(), p->Angles.ZzOLDANGLE(), near, 80., NT_Lotag | NT_Hitag);
 				if (near.actor() != nullptr)
 				{
 					switch (near.actor()->spr.picnum)
diff --git a/source/games/exhumed/src/osdcmds.cpp b/source/games/exhumed/src/osdcmds.cpp
index 2452882eb..86e50e978 100644
--- a/source/games/exhumed/src/osdcmds.cpp
+++ b/source/games/exhumed/src/osdcmds.cpp
@@ -48,7 +48,7 @@ void GameInterface::WarpToCoords(double x, double y, double z, DAngle ang)
 
     if (ang != DAngle::fromDeg(INT_MIN))
     {
-        nPlayer->Angles.ZzOLDANGLE = nPlayer->Angles.ZzANGLE() = ang;
+        nPlayer->Angles.ZzOLDANGLE() = nPlayer->Angles.ZzANGLE() = ang;
     }
 }
 
diff --git a/source/games/sw/src/osdcmds.cpp b/source/games/sw/src/osdcmds.cpp
index 3d293d93d..c183a839c 100644
--- a/source/games/sw/src/osdcmds.cpp
+++ b/source/games/sw/src/osdcmds.cpp
@@ -66,7 +66,7 @@ void GameInterface::WarpToCoords(double x, double y, double z, DAngle ang)
 
     if (ang != DAngle::fromDeg(INT_MIN))
     {
-		Player->Angles.ZzOLDANGLE = Player->Angles.ZzANGLE() = ang;
+		Player->Angles.ZzOLDANGLE() = Player->Angles.ZzANGLE() = ang;
     }
 }
 
diff --git a/source/games/sw/src/player.cpp b/source/games/sw/src/player.cpp
index 5c7ec8fa6..bf360e915 100644
--- a/source/games/sw/src/player.cpp
+++ b/source/games/sw/src/player.cpp
@@ -1311,7 +1311,7 @@ void DoPlayerTeleportPause(PLAYER* pp)
 
 void DoPlayerTeleportToSprite(PLAYER* pp, DVector3& pos, DAngle ang)
 {
-    pp->Angles.ZzANGLE() = pp->Angles.ZzOLDANGLE = ang;
+    pp->Angles.ZzANGLE() = pp->Angles.ZzOLDANGLE() = ang;
     pp->actor->spr.pos = pos;
     pp->actor->backuppos();
 
@@ -5122,7 +5122,7 @@ void DoPlayerBeginOperate(PLAYER* pp)
     pp->sop = pp->sop_control = sop;
     sop->controller = pp->actor;
 
-    pp->Angles.ZzOLDANGLE = pp->Angles.ZzANGLE() = sop->ang;
+    pp->Angles.ZzOLDANGLE() = pp->Angles.ZzANGLE() = sop->ang;
     pp->actor->spr.pos.XY() = sop->pmid.XY();
     updatesector(pp->actor->getPosWithOffsetZ(), &pp->cursector);
     calcSlope(pp->cursector, pp->actor->getPosWithOffsetZ(), &cz, &fz);
@@ -5212,7 +5212,7 @@ void DoPlayerBeginRemoteOperate(PLAYER* pp, SECTOR_OBJECT* sop)
 
     auto save_sect = pp->cursector;
 
-    pp->Angles.ZzOLDANGLE = pp->Angles.ZzANGLE() = sop->ang;
+    pp->Angles.ZzOLDANGLE() = pp->Angles.ZzANGLE() = sop->ang;
     pp->actor->spr.pos.XY() = sop->pmid.XY();
     updatesector(pp->actor->getPosWithOffsetZ(), &pp->cursector);
     calcSlope(pp->cursector, pp->actor->getPosWithOffsetZ(), &cz, &fz);
@@ -5334,9 +5334,9 @@ void DoPlayerStopOperate(PLAYER* pp)
     {
         DSWActor* rsp = pp->remoteActor;
         if (TEST_BOOL1(rsp))
-            pp->Angles.ZzANGLE() = pp->Angles.ZzOLDANGLE = rsp->spr.Angles.Yaw; // check me out later.
+            pp->Angles.ZzANGLE() = pp->Angles.ZzOLDANGLE() = rsp->spr.Angles.Yaw; // check me out later.
         else
-            pp->Angles.ZzANGLE() = pp->Angles.ZzOLDANGLE = (pp->sop_remote->pmid.XY() - pp->actor->spr.pos.XY()).Angle();
+            pp->Angles.ZzANGLE() = pp->Angles.ZzOLDANGLE() = (pp->sop_remote->pmid.XY() - pp->actor->spr.pos.XY()).Angle();
     }
 
     if (pp->sop_control)
@@ -7047,7 +7047,7 @@ void InitAllPlayers(void)
     // Initialize all [MAX_SW_PLAYERS] arrays here!
     for (pp = Player; pp < &Player[MAX_SW_PLAYERS]; pp++)
     {
-        pp->Angles.ZzANGLE() = pp->Angles.ZzOLDANGLE = pfirst->Angles.ZzANGLE();
+        pp->Angles.ZzANGLE() = pp->Angles.ZzOLDANGLE() = pfirst->Angles.ZzANGLE();
         pp->Angles.ZzHORIZON() = pp->Angles.ZzOLDHORIZON() = pfirst->Angles.ZzHORIZON();
         pp->cursector = pfirst->cursector;
         // set like this so that player can trigger something on start of the level
@@ -7203,7 +7203,7 @@ void PlayerSpawnPosition(PLAYER* pp)
 
     ASSERT(spawn_sprite != nullptr);
 
-    pp->Angles.ZzANGLE() = pp->Angles.ZzOLDANGLE = spawn_sprite->spr.Angles.Yaw; // check me out later.
+    pp->Angles.ZzANGLE() = pp->Angles.ZzOLDANGLE() = spawn_sprite->spr.Angles.Yaw; // check me out later.
     pp->setcursector(spawn_sprite->sector());
 
     if (pp->actor)