From cf1ac82da3cee849be60625c7387ef339741d246 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 1 Dec 2022 21:46:50 +1100 Subject: [PATCH] - Set up interpolated camera angle changes to occur at framerate when all conditions in `P_NoInterpolation()` are met. --- src/playsim/d_player.h | 4 +++ src/playsim/p_mobj.cpp | 63 +++++++++++++++++++++++++++++++------ src/rendering/r_utility.cpp | 35 +++++++++++++++++++++ 3 files changed, 93 insertions(+), 9 deletions(-) diff --git a/src/playsim/d_player.h b/src/playsim/d_player.h index 2a64415fb..efaabdb9e 100644 --- a/src/playsim/d_player.h +++ b/src/playsim/d_player.h @@ -449,6 +449,10 @@ public: void SetFOV(float fov); bool HasWeaponsInSlot(int slot) const; bool Resurrect(); + + // Scaled angle adjustment info. Not for direct manipulation. + DRotator angleTargets; + DRotator angleAppliedAmounts; }; // Bookkeeping on players - state. diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index 1b4684b8c..1a4c65211 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -3427,10 +3427,25 @@ void AActor::SetPitch(DAngle p, int fflags) if (p != Angles.Pitch) { - Angles.Pitch = p; - if (player != nullptr && (fflags & SPF_INTERPOLATE)) + if (player != nullptr) { - player->cheats |= CF_INTERPVIEW; + if (fflags & SPF_INTERPOLATE) + { + if (P_NoInterpolation(player, this)) + { + player->angleTargets.Pitch = deltaangle(Angles.Pitch, p); + player->angleAppliedAmounts.Pitch = nullAngle; + } + else + { + Angles.Pitch = p; + player->cheats |= CF_INTERPVIEW; + } + } + } + else + { + Angles.Pitch = p; } } @@ -3440,10 +3455,25 @@ void AActor::SetAngle(DAngle ang, int fflags) { if (ang != Angles.Yaw) { - Angles.Yaw = ang; - if (player != nullptr && (fflags & SPF_INTERPOLATE)) + if (player != nullptr) { - player->cheats |= CF_INTERPVIEW; + if (fflags & SPF_INTERPOLATE) + { + if (P_NoInterpolation(player, this)) + { + player->angleTargets.Yaw = deltaangle(Angles.Yaw, ang); + player->angleAppliedAmounts.Yaw = nullAngle; + } + else + { + Angles.Yaw = ang; + player->cheats |= CF_INTERPVIEW; + } + } + } + else + { + Angles.Yaw = ang; } } @@ -3453,10 +3483,25 @@ void AActor::SetRoll(DAngle r, int fflags) { if (r != Angles.Roll) { - Angles.Roll = r; - if (player != nullptr && (fflags & SPF_INTERPOLATE)) + if (player != nullptr) { - player->cheats |= CF_INTERPVIEW; + if (fflags & SPF_INTERPOLATE) + { + if (P_NoInterpolation(player, this)) + { + player->angleTargets.Roll = deltaangle(Angles.Roll, r); + player->angleAppliedAmounts.Roll = nullAngle; + } + else + { + Angles.Roll = r; + player->cheats |= CF_INTERPVIEW; + } + } + } + else + { + Angles.Roll = r; } } } diff --git a/src/rendering/r_utility.cpp b/src/rendering/r_utility.cpp index 80690db12..1af920a7f 100644 --- a/src/rendering/r_utility.cpp +++ b/src/rendering/r_utility.cpp @@ -762,6 +762,35 @@ static double QuakePower(double factor, double intensity, double offset) return factor * (offset + randumb); } +//========================================================================== +// +// R_DoActorTickerAngleChanges +// +//========================================================================== + +static void R_DoActorTickerAngleChanges(player_t* const player, AActor* const actor, const double scale) +{ + for (unsigned i = 0; i < 3; i++) + { + if (player->angleTargets[i].Sgn()) + { + // Calculate scaled amount of target and add to the accumlation buffer. + DAngle addition = player->angleTargets[i] * scale; + player->angleAppliedAmounts[i] += addition; + + // Test whether we're now reached/exceeded our target. + if (abs(player->angleAppliedAmounts[i]) >= abs(player->angleTargets[i])) + { + addition -= player->angleAppliedAmounts[i] - player->angleTargets[i]; + player->angleTargets[i] = player->angleAppliedAmounts[i] = nullAngle; + } + + // Apply the scaled addition to the angle. + actor->Angles[i] += addition; + } + } +} + //========================================================================== // // R_SetupFrame @@ -799,6 +828,12 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor I_Error ("You lost your body. Bad dehacked work is likely to blame."); } + // [MR] Process player angle changes if permitted to do so. + if (player && P_NoInterpolation(player, viewpoint.camera)) + { + R_DoActorTickerAngleChanges(player, viewpoint.camera, I_GetInputFrac(false)); + } + iview = FindPastViewer (viewpoint.camera); int nowtic = I_GetTime ();