From 872b31563d946e71180d0cb9ff9c4c26dafcf3ba Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 14 Aug 2023 01:58:47 -0700 Subject: [PATCH] P_DemoCameraMovement: even out vertical angle after toggling After turning on freecam, the vertical angle is tilted slightly downward (this is carried over from normal chasecam). Interpolate that angle back to normal while moving forward. This makes it so you don't need to manually adjust the vertical angle, since it would cause forward movement to send you into the ground. --- src/menus/transient/pause-replay.c | 1 + src/p_local.h | 1 + src/p_user.c | 55 +++++++++++++++++++++++++++--- 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/menus/transient/pause-replay.c b/src/menus/transient/pause-replay.c index 46c0a6cfb..fba7ec7ed 100644 --- a/src/menus/transient/pause-replay.c +++ b/src/menus/transient/pause-replay.c @@ -240,6 +240,7 @@ void M_PlaybackToggleFreecam(INT32 choice) { demo.freecam = true; democam.button_a_held = 2; + democam.reset_aiming = true; } else // toggle off { diff --git a/src/p_local.h b/src/p_local.h index 1ebcecbff..35a024177 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -137,6 +137,7 @@ struct camera_t struct demofreecam_s { UINT8 button_a_held; // A button was held since entering from menu, so don't move camera + boolean reset_aiming; // camera aiming needs to be reset from chase camera }; extern struct demofreecam_s democam; diff --git a/src/p_user.c b/src/p_user.c index 3d6b81d5c..603b13c88 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2658,21 +2658,33 @@ void P_DemoCameraMovement(camera_t *cam) angle_t thrustangle; player_t *lastp; + boolean moving = false; + // first off we need to get button input G_BuildTiccmd(cmd, 1, UINT8_MAX); - cam->aiming += cmd->aiming << TICCMD_REDUCE; - cam->angle += cmd->turning << TICCMD_REDUCE; + if (cmd->aiming != 0) + { + cam->aiming += cmd->aiming << TICCMD_REDUCE; - cam->aiming = G_ClipAimingPitch((INT32 *)&cam->aiming); + democam.reset_aiming = false; + } + + cam->angle += cmd->turning << TICCMD_REDUCE; // camera movement: if (!democam.button_a_held) { if (cmd->buttons & BT_ACCELERATE) + { cam->z += 32*mapobjectscale; + moving = true; + } else if (cmd->buttons & BT_BRAKE) + { cam->z -= 32*mapobjectscale; + moving = true; + } } if (!(cmd->buttons & BT_ACCELERATE) && democam.button_a_held) @@ -2686,8 +2698,39 @@ void P_DemoCameraMovement(camera_t *cam) lastp = &players[displayplayers[0]]; // Fun fact, I was trying displayplayers[0]->mo as if it was Lua like an absolute idiot. cam->angle = R_PointToAngle2(cam->x, cam->y, lastp->mo->x, lastp->mo->y); cam->aiming = R_PointToAngle2(0, cam->z, R_PointToDist2(cam->x, cam->y, lastp->mo->x, lastp->mo->y), lastp->mo->z + lastp->mo->scale*128*P_MobjFlip(lastp->mo)); // This is still unholy. Aim a bit above their heads. + + democam.reset_aiming = false; } + if (cmd->forwardmove != 0) + { + moving = true; + } + + // After switching to democam, the vertical angle of + // chasecam is inherited. This is intentional because it + // creates a smooth transition. However, moving + // forward/back will have a slope. So, as long as democam + // controls haven't been used to alter the vertical angle, + // slowly reset it to flat. + if (democam.reset_aiming && moving) + { + INT32 aiming = cam->aiming; + INT32 smooth = FixedMul(ANGLE_11hh / 4, FCOS(cam->aiming)); + + if (abs(smooth) < abs(aiming)) + { + cam->aiming -= smooth * intsign(aiming); + } + else + { + cam->aiming = 0; + democam.reset_aiming = false; // completely smoothed out + } + } + + G_FinalClipAimingPitch((INT32 *)&cam->aiming, NULL, false); + cam->momx = cam->momy = cam->momz = 0; if (cmd->forwardmove != 0) @@ -2696,7 +2739,11 @@ void P_DemoCameraMovement(camera_t *cam) cam->x += FixedMul(cmd->forwardmove*mapobjectscale, FINECOSINE(thrustangle)); cam->y += FixedMul(cmd->forwardmove*mapobjectscale, FINESINE(thrustangle)); - cam->z += FixedMul(cmd->forwardmove*mapobjectscale, AIMINGTOSLOPE(cam->aiming)); + + if (!democam.reset_aiming) + { + cam->z += FixedMul(cmd->forwardmove*mapobjectscale, AIMINGTOSLOPE(cam->aiming)); + } // momentums are useless here, directly add to the coordinates // this.......... doesn't actually check for floors and walls and whatnot but the function to do that is a pure mess so fuck that.