From 470f481619ed5244f41c79f4429ef85dc3cff371 Mon Sep 17 00:00:00 2001
From: Mitchell Richters <mjr4077au@gmail.com>
Date: Wed, 23 Sep 2020 15:34:03 +1000
Subject: [PATCH] - Duke: Simplify entire camera angle setup.

---
 source/games/duke/src/actors.cpp    |  3 ++-
 source/games/duke/src/input.cpp     |  5 ----
 source/games/duke/src/player_d.cpp  |  7 -----
 source/games/duke/src/player_r.cpp  |  6 -----
 source/games/duke/src/render.cpp    | 40 ++++++++++++++---------------
 source/games/duke/src/sectors_d.cpp |  1 -
 source/games/duke/src/sectors_r.cpp |  1 -
 source/games/duke/src/types.h       |  3 +--
 8 files changed, 23 insertions(+), 43 deletions(-)

diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp
index 911b55752..52ac7783c 100644
--- a/source/games/duke/src/actors.cpp
+++ b/source/games/duke/src/actors.cpp
@@ -1995,9 +1995,10 @@ void camera(int i)
 			}
 		}
 
+		hittype[i].tempang = s->ang;
+		
 		if (s->hitag > 0)
 		{
-			hittype[i].tempang = s->ang;
 			if (t[1] < s->hitag)
 				s->ang += 8;
 			else if (t[1] < (s->hitag * 3))
diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp
index 715460674..9dd2d17c7 100644
--- a/source/games/duke/src/input.cpp
+++ b/source/games/duke/src/input.cpp
@@ -530,11 +530,6 @@ static void processInputBits(player_struct *p, ControlInfo* const hidInput)
 		loc.actions &= ~(SB_WEAPONMASK_BITS | SB_TURNAROUND | SB_CENTERVIEW | SB_HOLSTER | SB_JUMP | SB_CROUCH | SB_RUN | 
 			SB_AIM_UP | SB_AIM_DOWN | SB_AIMMODE | SB_LOOK_UP | SB_LOOK_DOWN | SB_LOOK_LEFT | SB_LOOK_RIGHT);
 	}
-	else if (p->newowner != -1)
-	{
-		// Remove look left/right bits if looking through a camera.
-		loc.actions &= ~(SB_LOOK_LEFT | SB_LOOK_RIGHT);
-	}
 	else
 	{
 		if (buttonMap.ButtonDown(gamefunc_Quick_Kick)) // this shares a bit with another function so cannot be in the common code.
diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp
index 1142ffb6a..5a01229a8 100644
--- a/source/games/duke/src/player_d.cpp
+++ b/source/games/duke/src/player_d.cpp
@@ -2782,14 +2782,7 @@ void processinput_d(int snum)
 	if (p->newowner >= 0)
 	{
 		i = p->newowner;
-		hittype[i].oq16ang = p->q16ang;
-		p->posx = sprite[i].x;
-		p->posy = sprite[i].y;
-		p->posz = sprite[i].z;
-		p->setang(sprite[i].ang);
 		p->posxv = p->posyv = s->xvel = 0;
-		p->setlookang(0);
-		p->setrotscrnang(0);
 
 		fi.doincrements(p);
 
diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp
index e6c885e19..03905ec8a 100644
--- a/source/games/duke/src/player_r.cpp
+++ b/source/games/duke/src/player_r.cpp
@@ -3667,13 +3667,7 @@ void processinput_r(int snum)
 	if (p->newowner >= 0)
 	{
 		i = p->newowner;
-		p->posx = sprite[i].x;
-		p->posy = sprite[i].y;
-		p->posz = sprite[i].z;
-		p->setang(sprite[i].ang);
 		p->posxv = p->posyv = s->xvel = 0;
-		p->setlookang(0);
-		p->setrotscrnang(0);
 
 		fi.doincrements(p);
 
diff --git a/source/games/duke/src/render.cpp b/source/games/duke/src/render.cpp
index 049003fa6..47640ceb4 100644
--- a/source/games/duke/src/render.cpp
+++ b/source/games/duke/src/render.cpp
@@ -244,6 +244,17 @@ void renderMirror(int cposx, int cposy, int cposz, binangle cang, fixedhoriz cho
 //
 //---------------------------------------------------------------------------
 
+static inline int16_t getcamspriteang(short const newowner, double const smoothratio)
+{
+	return hittype[newowner].tempang + xs_CRoundToInt(fmulscale16(((sprite[newowner].ang - hittype[newowner].tempang + 1024) & 2047) - 1024, smoothratio));
+}
+
+//---------------------------------------------------------------------------
+//
+// 
+//
+//---------------------------------------------------------------------------
+
 void animatecamsprite(double smoothratio)
 {
 	const int VIEWSCREEN_ACTIVE_DISTANCE = 8192;
@@ -269,7 +280,7 @@ void animatecamsprite(double smoothratio)
 		screen->RenderTextureView(canvas, [=](IntRect& rect)
 			{
 				auto camera = &sprite[sp->owner];
-				auto ang = hittype[sp->owner].tempang + xs_CRoundToInt(fmulscale16(((camera->ang - hittype[sp->owner].tempang + 1024) & 2047) - 1024, smoothratio));
+				auto ang = getcamspriteang(sp->owner, smoothratio);
 				// Note: no ROR or camera here for now - the current setup has no means to detect these things before rendering the scene itself.
 				drawrooms(camera->x, camera->y, camera->z, ang, 100 + camera->shade, camera->sectnum); // why 'shade'...?
 				display_mirror = 1; // should really be 'display external view'.
@@ -468,6 +479,7 @@ void displayrooms(int snum, double smoothratio)
 	short sect;
 	binangle cang;
 	fixedhoriz choriz;
+	fixed_t q16rotscrnang;
 	struct player_struct* p;
 	int tiltcs = 0; // JBF 20030807
 
@@ -531,10 +543,8 @@ void displayrooms(int snum, double smoothratio)
 			setdrugmode(p, i);
 		}
 
-		if (!cl_syncinput)
-			renderSetRollAngle(FixedToFloat(p->q16rotscrnang));
-		else
-			renderSetRollAngle(FixedToFloat(p->oq16rotscrnang + fmulscale16(((p->q16rotscrnang - p->oq16rotscrnang + dang) & 0x7FFFFFF) - dang, smoothratio)));
+		// set screen rotation.
+		q16rotscrnang = !cl_syncinput ? p->q16rotscrnang : p->oq16rotscrnang + fmulscale16(((p->q16rotscrnang - p->oq16rotscrnang + dang) & 0x7FFFFFF) - dang, smoothratio);
 
 		if ((snum == myconnectindex) && (numplayers > 1))
 		{
@@ -581,34 +591,24 @@ void displayrooms(int snum, double smoothratio)
 
 		if (p->newowner >= 0)
 		{
-			fixed_t& oang = hittype[p->newowner].oq16ang;
-			fixed_t& ang = p->q16ang;
-
-			if (p->newowner != p->oldowner)
-			{
-				oang = ang = IntToFixed(sprite[p->newowner].ang);
-				cang = q16ang(ang);
-				p->oldowner = p->newowner;
-			}
-			else
-			{
-				cang = q16ang(oang + xs_CRoundToInt(fmulscale16(((ang + dang - oang) & 0x7FFFFFF) - dang, smoothratio)));
-			}
-
+			cang = buildang(getcamspriteang(p->newowner, smoothratio));
 			choriz = q16horiz(p->q16horiz + p->q16horizoff);
 			cposx = sprite[p->newowner].pos.x;
 			cposy = sprite[p->newowner].pos.y;
 			cposz = sprite[p->newowner].pos.z;
 			sect = sprite[p->newowner].sectnum;
+			q16rotscrnang = 0;
 			smoothratio = MaxSmoothRatio;
 		}
 		else if (p->over_shoulder_on == 0)
 		{
-			p->oldowner = -1;
 			if (cl_viewbob) cposz += p->opyoff + xs_CRoundToInt(fmulscale16(p->pyoff - p->opyoff, smoothratio));
 		}
 		else view(p, &cposx, &cposy, &cposz, &sect, cang.asbuild(), choriz.asbuild(), smoothratio);
 
+		// do screen rotation.
+		renderSetRollAngle(FixedToInt(q16rotscrnang));
+
 		cz = hittype[p->i].ceilingz;
 		fz = hittype[p->i].floorz;
 
diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp
index afad2d096..e07202d84 100644
--- a/source/games/duke/src/sectors_d.cpp
+++ b/source/games/duke/src/sectors_d.cpp
@@ -1733,7 +1733,6 @@ void checksectors_d(int snum)
 				p->posx = p->oposx;
 				p->posy = p->oposy;
 				p->posz = p->oposz;
-				p->q16ang = p->oq16ang;
 				p->newowner = -1;
 
 				updatesector(p->posx, p->posy, &p->cursectnum);
diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp
index 42ec2f645..4d7b327bf 100644
--- a/source/games/duke/src/sectors_r.cpp
+++ b/source/games/duke/src/sectors_r.cpp
@@ -2409,7 +2409,6 @@ void checkhitsprite_r(int i, int sn)
 					ps[p].posx = ps[p].oposx;
 					ps[p].posy = ps[p].oposy;
 					ps[p].posz = ps[p].oposz;
-					ps[p].q16ang = ps[p].oq16ang;
 
 					updatesector(ps[p].posx, ps[p].posy, &ps[p].cursectnum);
 					setpal(&ps[p]);
diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h
index 3e4cd1e40..e023a5945 100644
--- a/source/games/duke/src/types.h
+++ b/source/games/duke/src/types.h
@@ -27,7 +27,6 @@ struct weaponhit
 	short timetosleep;
 	int floorz, ceilingz, lastvx, lastvy, bposx, bposy, bposz, aflags;
 	int temp_data[6];
-	fixed_t oq16ang;	// for interpolating security cameras in displayrooms() when p->newowner >= 0.
 };
 
 struct animwalltype
@@ -137,7 +136,7 @@ struct player_struct
 	short ammo_amount[MAX_WEAPONS], wackedbyactor, frag, fraggedself;
 
 	short curr_weapon, last_weapon, tipincs, wantweaponfire;
-	short holoduke_amount, newowner, oldowner, hurt_delay, hbomb_hold_delay;
+	short holoduke_amount, newowner, hurt_delay, hbomb_hold_delay;
 	short jumping_counter, airleft, knee_incs, access_incs;
 	short ftq, access_wallnum, access_spritenum;
 	short got_access, weapon_ang, firstaid_amount;