From f19e8be3a00f55093e036c8added754ab6cd24a6 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 30 Nov 2021 14:03:56 -0500 Subject: [PATCH 1/9] Enable lagless cam I left it off because I think Kart intentionally removed it, but the reason we did might not apply anymore...? --- src/d_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index 52cd7b46c..f185d7430 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -813,7 +813,7 @@ void D_SRB2Loop(void) } else if (rendertimeout < entertic) // in case the server hang or netsplit { -#if 0 +#if 1 // Lagless camera! Yay! if (gamestate == GS_LEVEL && netgame) { From 4a8222d397a41119ffb51e6a835f06be46531d8d Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 30 Nov 2021 14:28:27 -0500 Subject: [PATCH 2/9] Just set default renderdelta when paused Supports multiple pause types too --- src/d_main.c | 2 +- src/hardware/hw_main.c | 6 +++--- src/hardware/hw_md2.c | 2 +- src/r_things.c | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index f185d7430..a220e0c34 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -774,7 +774,7 @@ void D_SRB2Loop(void) // process tics (but maybe not if realtic == 0) TryRunTics(realtics); - if (cv_frameinterpolation.value == 1) + if (cv_frameinterpolation.value == 1 && !(paused || P_AutoPause())) { fixed_t entertimefrac = I_GetTimeFrac(); // renderdeltatics is a bit awkard to evaluate, since the system time interface is whole tic-based diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index b74bd71ea..e605b6c66 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3645,7 +3645,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) fixed_t interpz = thing->z; // do interpolation - if (cv_frameinterpolation.value == 1 && !paused) + if (cv_frameinterpolation.value == 1) { interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x); interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y); @@ -5085,7 +5085,7 @@ static void HWR_ProjectSprite(mobj_t *thing) interpz = thing->z; interpangle = mobjangle; - if (cv_frameinterpolation.value == 1 && !paused) + if (cv_frameinterpolation.value == 1) { interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x); interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y); @@ -5515,7 +5515,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) interpz = thing->z; // do interpolation - if (cv_frameinterpolation.value == 1 && !paused) + if (cv_frameinterpolation.value == 1) { interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x); interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y); diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 70c064081..aadb1b398 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1372,7 +1372,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) fixed_t interpz = spr->mobj->z; // do interpolation - if (cv_frameinterpolation.value == 1 && !paused) + if (cv_frameinterpolation.value == 1) { interpx = spr->mobj->old_x + FixedMul(rendertimefrac, spr->mobj->x - spr->mobj->old_x); interpy = spr->mobj->old_y + FixedMul(rendertimefrac, spr->mobj->y - spr->mobj->old_y); diff --git a/src/r_things.c b/src/r_things.c index 6d9cca7a4..f383d6d6a 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1437,7 +1437,7 @@ static void R_ProjectSprite(mobj_t *thing) if (thing->player) interpangle = thing->player->drawangle; // do interpolation - if (cv_frameinterpolation.value == 1 && !paused) + if (cv_frameinterpolation.value == 1) { interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x); interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y); @@ -1777,7 +1777,7 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t linkscale; thing = thing->tracer; - if (cv_frameinterpolation.value == 1 && !paused) + if (cv_frameinterpolation.value == 1) { interpx = thing->old_x + FixedMul(thing->x - thing->old_x, rendertimefrac); interpy = thing->old_y + FixedMul(thing->y - thing->old_y, rendertimefrac); @@ -2126,7 +2126,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) fixed_t interpz = thing->z; // do interpolation - if (cv_frameinterpolation.value == 1 && !paused) + if (cv_frameinterpolation.value == 1) { interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x); interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y); From 43356ca73eaf0c4cd49a2e90a41a8537a408eccb Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 30 Nov 2021 18:10:51 -0500 Subject: [PATCH 3/9] Nope, it actually just causes camera hitches even when alone, even if this fixes the problem its not the solution --- src/d_main.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index a220e0c34..425231347 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -813,20 +813,6 @@ void D_SRB2Loop(void) } else if (rendertimeout < entertic) // in case the server hang or netsplit { -#if 1 - // Lagless camera! Yay! - if (gamestate == GS_LEVEL && netgame) - { - INT32 i; - - for (i = 0; i <= r_splitscreen; i++) - { - if (camera[i].chase) - P_MoveChaseCamera(&players[displayplayers[i]], &camera[i], false); - } - } -#endif - // (Only display if not already done for frame interp) cv_frameinterpolation.value == 0 ? D_Display() : 0; From 6ecac4159a9f58eae87b1846c104419531a5a143 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 1 Dec 2021 06:45:02 -0500 Subject: [PATCH 4/9] This seems to fix the camera stuttering in netgames when I try it on my own Feel like this might be wrong so TRY IT first!! --- src/d_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index 425231347..b8fad8ec6 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -774,7 +774,7 @@ void D_SRB2Loop(void) // process tics (but maybe not if realtic == 0) TryRunTics(realtics); - if (cv_frameinterpolation.value == 1 && !(paused || P_AutoPause())) + if (cv_frameinterpolation.value == 1 && !(paused || P_AutoPause() || hu_stopped)) { fixed_t entertimefrac = I_GetTimeFrac(); // renderdeltatics is a bit awkard to evaluate, since the system time interface is whole tic-based From 7238a1be837ada9b2e55eedccdf8edaca1592a8f Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 1 Dec 2021 10:53:15 -0500 Subject: [PATCH 5/9] Interpolate camera roll, fix skybox in opengl --- src/hardware/hw_main.c | 7 +++--- src/r_fps.c | 26 ++++++----------------- src/r_fps.h | 1 + src/r_main.c | 48 ++++++++++++++++++++++++------------------ src/r_state.h | 2 +- 5 files changed, 38 insertions(+), 46 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e605b6c66..38fdd0e3c 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5803,8 +5803,7 @@ static void HWR_DrawSkyBackground(player_t *player) dometransform.scalez = 1; dometransform.fovxangle = fpov; // Tails dometransform.fovyangle = fpov; // Tails - HWR_RollTransform(&dometransform, - R_ViewRollAngle(player)); + HWR_RollTransform(&dometransform, viewroll); dometransform.splitscreen = r_splitscreen; HWR_GetTexture(texturetranslation[skytexture]); @@ -6096,7 +6095,7 @@ void HWR_RenderSkyboxView(player_t *player) atransform.fovxangle = fpov; // Tails atransform.fovyangle = fpov; // Tails - HWR_RollTransform(&atransform, R_ViewRollAngle(player)); + HWR_RollTransform(&atransform, viewroll); atransform.splitscreen = r_splitscreen; gl_fovlud = (float)(1.0l/tan((double)(fpov*M_PIl/360l))); @@ -6308,7 +6307,7 @@ void HWR_RenderPlayerView(void) atransform.fovxangle = fpov; // Tails atransform.fovyangle = fpov; // Tails - HWR_RollTransform(&atransform, R_ViewRollAngle(player)); + HWR_RollTransform(&atransform, viewroll); atransform.splitscreen = r_splitscreen; gl_fovlud = (float)(1.0l/tan((double)(fpov*M_PIl/360l))); diff --git a/src/r_fps.c b/src/r_fps.c index 2d2b4f61e..fe1adb062 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -83,10 +83,7 @@ static void R_SetupFreelook(player_t *player, boolean skybox) void R_InterpolateView(fixed_t frac) { - boolean skybox = false; - INT32 i; - - if (FIXED_TO_FLOAT(frac) < 0) + if (frac < 0) frac = 0; if (frac > FRACUNIT) frac = FRACUNIT; @@ -97,31 +94,20 @@ void R_InterpolateView(fixed_t frac) viewangle = oldview->angle + R_LerpAngle(oldview->angle, newview->angle, frac); aimingangle = oldview->aim + R_LerpAngle(oldview->aim, newview->aim, frac); + viewroll = oldview->roll + R_LerpAngle(oldview->roll, newview->roll, frac); viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); - // this is gonna create some interesting visual errors for long distance teleports... - // might want to recalculate the view sector every frame instead... viewplayer = newview->player; viewsector = R_PointInSubsector(viewx, viewy)->sector; - // well, this ain't pretty - for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) - { - if (newview == &skyview_new[i]) - { - skybox = true; - break; - } - } - - R_SetupFreelook(newview->player, skybox); + R_SetupFreelook(newview->player, newview->sky); } void R_UpdateViewInterpolation(void) { - INT32 i; + UINT8 i; for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) { @@ -132,7 +118,7 @@ void R_UpdateViewInterpolation(void) void R_SetViewContext(enum viewcontext_e _viewcontext) { - INT32 i; + UINT8 i = 0; I_Assert(_viewcontext >= VIEWCONTEXT_PLAYER1 && _viewcontext <= VIEWCONTEXT_SKY4); @@ -149,7 +135,7 @@ void R_SetViewContext(enum viewcontext_e _viewcontext) newview = &pview_new[i]; break; case VIEWCONTEXT_SKY1: - case VIEWCONTEXT_SKY2: + case VIEWCONTEXT_SKY2:; case VIEWCONTEXT_SKY3: case VIEWCONTEXT_SKY4: i = viewcontext - VIEWCONTEXT_SKY1; diff --git a/src/r_fps.h b/src/r_fps.h index 2d4dbe874..eb674b142 100644 --- a/src/r_fps.h +++ b/src/r_fps.h @@ -41,6 +41,7 @@ typedef struct { angle_t angle; angle_t aim; + angle_t roll; fixed_t cos; fixed_t sin; mobj_t *mobj; diff --git a/src/r_main.c b/src/r_main.c index 231bde280..ea0d8482d 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -71,7 +71,7 @@ size_t framecount; size_t loopcount; fixed_t viewx, viewy, viewz; -angle_t viewangle, aimingangle; +angle_t viewangle, aimingangle, viewroll; UINT8 viewssnum; fixed_t viewcos, viewsin; sector_t *viewsector; @@ -656,7 +656,7 @@ void R_CheckViewMorph(int s) float fisheyemap[MAXVIDWIDTH/2 + 1]; #endif - angle_t rollangle = R_ViewRollAngle(&players[displayplayers[s]]); + angle_t rollangle = viewroll; #ifdef WOUGHMP_WOUGHMP fixed_t fisheye = cv_cam2_turnmultiplier.value; // temporary test value #endif @@ -1206,8 +1206,8 @@ subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y) void R_SetupFrame(player_t *player) { camera_t *thiscam = &camera[0]; - boolean chasecam = false; - UINT8 i; + boolean chasecam = (cv_chasecam[0].value != 0); + UINT8 i = 0; for (i = 0; i <= r_splitscreen; i++) { @@ -1221,12 +1221,17 @@ void R_SetupFrame(player_t *player) } if (i > r_splitscreen) - return; // shouldn't be possible, but just in case + { + i = 0; // Shouldn't be possible, but just in case. + thiscam = &camera[0]; + chasecam = (cv_chasecam[0].value != 0); + R_SetViewContext(VIEWCONTEXT_PLAYER1); + } if (player->spectator) // no spectator chasecam chasecam = false; // force chasecam off - if (chasecam && !thiscam->chase) + if (chasecam && (thiscam && !thiscam->chase)) { P_ResetCamera(player, thiscam); thiscam->chase = true; @@ -1270,6 +1275,7 @@ void R_SetupFrame(player_t *player) newview->aim = localaiming[i]; } } + newview->roll = R_ViewRollAngle(player); newview->z += quake.z; newview->player = player; @@ -1302,7 +1308,7 @@ void R_SetupFrame(player_t *player) // newview->sin = FINESINE(viewangle>>ANGLETOFINESHIFT); // newview->cos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); - R_InterpolateView(cv_frameinterpolation.value == 1 ? rendertimefrac : FRACUNIT); + R_InterpolateView(rendertimefrac); } void R_SkyboxFrame(player_t *player) @@ -1310,22 +1316,21 @@ void R_SkyboxFrame(player_t *player) camera_t *thiscam = &camera[0]; UINT8 i = 0; - if (r_splitscreen) + for (i = 0; i <= r_splitscreen; i++) { - for (i = 1; i <= r_splitscreen; i++) + if (player == &players[displayplayers[i]]) { - if (player == &players[displayplayers[i]]) - { - thiscam = &camera[i]; - R_SetViewContext(VIEWCONTEXT_SKY1 + i); - break; - } + thiscam = &camera[i]; + R_SetViewContext(VIEWCONTEXT_SKY1 + i); + break; } + } - if (i > r_splitscreen) - { - i = 0; - } + if (i > r_splitscreen) + { + i = 0; // Shouldn't be possible, but just in case. + thiscam = &camera[0]; + R_SetViewContext(VIEWCONTEXT_SKY1); } // cut-away view stuff @@ -1343,7 +1348,7 @@ void R_SkyboxFrame(player_t *player) newview->aim = player->awayviewaiming; newview->angle = player->awayviewmobj->angle; } - else if (thiscam->chase) + else if (thiscam && thiscam->chase) { newview->aim = thiscam->aiming; newview->angle = thiscam->angle; @@ -1359,6 +1364,7 @@ void R_SkyboxFrame(player_t *player) } } newview->angle += r_viewmobj->angle; + newview->roll = R_ViewRollAngle(player); newview->player = player; @@ -1445,7 +1451,7 @@ void R_SkyboxFrame(player_t *player) // newview->sin = FINESINE(viewangle>>ANGLETOFINESHIFT); // newview->cos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); - R_InterpolateView(cv_frameinterpolation.value == 1 ? rendertimefrac : FRACUNIT); + R_InterpolateView(rendertimefrac); } boolean R_ViewpointHasChasecam(player_t *player) diff --git a/src/r_state.h b/src/r_state.h index cb55e2c2b..6f9008cc7 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -93,7 +93,7 @@ extern side_t *spawnsides; // POV data. // extern fixed_t viewx, viewy, viewz; -extern angle_t viewangle, aimingangle; +extern angle_t viewangle, aimingangle, viewroll; extern UINT8 viewssnum; // splitscreen view number extern boolean viewsky, skyVisible; extern boolean skyVisiblePerPlayer[MAXSPLITSCREENPLAYERS]; // saved values of skyVisible of each splitscreen player From 3e227654c7b5925db5a83ec40a4a34e8927ce2fe Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 1 Dec 2021 12:46:41 -0500 Subject: [PATCH 6/9] Little unneeded semicolon --- src/r_fps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_fps.c b/src/r_fps.c index fe1adb062..7258d3b75 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -135,7 +135,7 @@ void R_SetViewContext(enum viewcontext_e _viewcontext) newview = &pview_new[i]; break; case VIEWCONTEXT_SKY1: - case VIEWCONTEXT_SKY2:; + case VIEWCONTEXT_SKY2: case VIEWCONTEXT_SKY3: case VIEWCONTEXT_SKY4: i = viewcontext - VIEWCONTEXT_SKY1; From 225590b7ba099348a013dcfc306ee5c9e77f4b48 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 1 Dec 2021 13:52:51 -0500 Subject: [PATCH 7/9] Draw framerate counter properly in uncapped --- src/i_system.h | 2 +- src/screen.c | 89 ++++++++++++++++++++++++++++++++++++++++------- src/screen.h | 3 ++ src/sdl/i_video.c | 2 ++ 4 files changed, 82 insertions(+), 14 deletions(-) diff --git a/src/i_system.h b/src/i_system.h index 4bc0e73da..789117eaa 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -56,7 +56,7 @@ precise_t I_GetPreciseTime(void); /** \brief Returns the difference between precise times as microseconds. */ -int I_PreciseToMicros(precise_t); +int I_PreciseToMicros(precise_t d); /** \brief The I_Sleep function diff --git a/src/screen.c b/src/screen.c index abc302748..ef5fa7769 100644 --- a/src/screen.c +++ b/src/screen.c @@ -453,9 +453,46 @@ boolean SCR_IsAspectCorrect(INT32 width, INT32 height) // XMOD FPS display // moved out of os-specific code for consistency -static boolean fpsgraph[TICRATE]; +static boolean ticsgraph[TICRATE]; static tic_t lasttic; +static UINT32 fpstime = 0; +static UINT32 lastupdatetime = 0; + +#define FPSUPDATERATE 1/20 // What fraction of a second to update at. The fraction will not simplify to 0, trust me. +#define FPSMAXSAMPLES 16 + +static UINT32 fpssamples[FPSMAXSAMPLES]; +static UINT32 fpssampleslen = 0; +static UINT32 fpssum = 0; +double aproxfps = 0.0f; + +void SCR_CalcAproxFps(void) +{ + tic_t i = 0; + if (I_PreciseToMicros(fpstime - lastupdatetime) > 1000000 * FPSUPDATERATE) + { + if (fpssampleslen == FPSMAXSAMPLES) + { + fpssum -= fpssamples[0]; + + for (i = 1; i < fpssampleslen; i++) + fpssamples[i-1] = fpssamples[i]; + } + else + fpssampleslen++; + + fpssamples[fpssampleslen-1] = I_GetPreciseTime() - fpstime; + fpssum += fpssamples[fpssampleslen-1]; + + aproxfps = 1000000 / (I_PreciseToMicros(fpssum) / (double)fpssampleslen); + + lastupdatetime = I_GetPreciseTime(); + } + + fpstime = I_GetPreciseTime(); +} + void SCR_DisplayTicRate(void) { tic_t i; @@ -464,25 +501,51 @@ void SCR_DisplayTicRate(void) const UINT8 *ticcntcolor = NULL; for (i = lasttic + 1; i < TICRATE+lasttic && i < ontic; ++i) - fpsgraph[i % TICRATE] = false; + ticsgraph[i % TICRATE] = false; - fpsgraph[ontic % TICRATE] = true; + ticsgraph[ontic % TICRATE] = true; for (i = 0;i < TICRATE;++i) - if (fpsgraph[i]) + if (ticsgraph[i]) ++totaltics; - if (totaltics <= TICRATE/2) ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_RASPBERRY, GTC_CACHE); - else if (totaltics == TICRATE) ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_MINT, GTC_CACHE); - // draw "FPS" V_DrawFixedPatch(306<= 60.0f) ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_MINT, GTC_CACHE); + + /* + if (cv_fpscap.value != 0) + { + // draw total frame: + //V_DrawPingNum(318, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, cv_fpscap.value, ticcntcolor); + // draw "/" + //V_DrawFixedPatch(306<= TICRATE) ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_MINT, GTC_CACHE); + + // draw total frame: + V_DrawPingNum(318, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, TICRATE, ticcntcolor); + // draw "/" + V_DrawFixedPatch(306< Date: Wed, 1 Dec 2021 15:51:57 -0500 Subject: [PATCH 8/9] Enable the thinker of NOTHINK... OK so we kind of need NOTHINK objects to still think because otherwise they can never update their interpolation values. This should probably replaced with some other kind of system, consider this temporary... (MF_NOTHINK is still mostly covered by a very early return in MobjThinker, if you're unaware, just means this might have to waste the extra time iterating through them...) --- src/p_mobj.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 533eb8de7..c70c9a2cc 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9930,7 +9930,13 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) } } + // OK so we kind of need NOTHINK objects to still think + // because otherwise they can never update their + // interpolation values. They might need some other kind + // of system, so consider this temporary... +#if 0 if (!(mobj->flags & MF_NOTHINK)) +#endif P_AddThinker(THINK_MOBJ, &mobj->thinker); if (mobj->skin) // correct inadequecies above. From 83444ce5d583445c24f774f849e62dad93912080 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 1 Dec 2021 16:50:17 -0500 Subject: [PATCH 9/9] Interpolate angle & nametags --- src/d_player.h | 2 + src/hardware/hw_main.c | 17 +++++--- src/k_hud.c | 96 +++++++++++++++++++++++++++++++++++------- src/p_local.h | 4 ++ src/p_mobj.c | 12 ++++++ src/p_mobj.h | 2 + src/p_user.c | 22 +++++++--- src/r_things.c | 10 ++--- 8 files changed, 134 insertions(+), 31 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 0a406f785..e1ec7f2e8 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -312,6 +312,7 @@ typedef struct player_s fixed_t bob; angle_t viewrollangle; + angle_t old_viewrollangle; // camera tilt // TODO: expose to lua angle_t tilt; @@ -325,6 +326,7 @@ typedef struct player_s // fun thing for player sprite angle_t drawangle; + angle_t old_drawangle; // interp // Bit flags. // See pflags_t, above. diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 38fdd0e3c..ffb8ef521 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5055,7 +5055,6 @@ static void HWR_ProjectSprite(mobj_t *thing) INT32 heightsec, phs; const boolean splat = R_ThingIsFloorSprite(thing); const boolean papersprite = (R_ThingIsPaperSprite(thing) && !splat); - angle_t mobjangle = (thing->player ? thing->player->drawangle : thing->angle); float z1, z2; fixed_t spr_width, spr_height; @@ -5083,14 +5082,22 @@ static void HWR_ProjectSprite(mobj_t *thing) interpx = thing->x; interpy = thing->y; interpz = thing->z; - interpangle = mobjangle; + interpangle = (thing->player ? thing->player->drawangle : thing->angle); if (cv_frameinterpolation.value == 1) { interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x); interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y); interpz = thing->old_z + FixedMul(rendertimefrac, thing->z - thing->old_z); - interpangle = mobjangle; + + if (thing->player) + { + interpangle = thing->player->old_drawangle + FixedMul(rendertimefrac, thing->player->drawangle - thing->player->old_drawangle); + } + else + { + interpangle = thing->old_angle + FixedMul(rendertimefrac, thing->angle - thing->old_angle); + } } // hitlag vibrating (todo: interp somehow?) @@ -5276,8 +5283,8 @@ static void HWR_ProjectSprite(mobj_t *thing) if (papersprite) { - rightsin = FIXED_TO_FLOAT(FINESINE((mobjangle)>>ANGLETOFINESHIFT)); - rightcos = FIXED_TO_FLOAT(FINECOSINE((mobjangle)>>ANGLETOFINESHIFT)); + rightsin = FIXED_TO_FLOAT(FINESINE((interpangle)>>ANGLETOFINESHIFT)); + rightcos = FIXED_TO_FLOAT(FINECOSINE((interpangle)>>ANGLETOFINESHIFT)); } else { diff --git a/src/k_hud.c b/src/k_hud.c index 589467bd6..b4ef2f32a 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -801,7 +801,7 @@ void K_ObjectTracking(trackingResult_t *result, vector3_t *point, UINT8 cameraNu player_t *player; fixed_t viewpointX, viewpointY, viewpointZ; - angle_t viewpointAngle, viewpointAiming; + angle_t viewpointAngle, viewpointAiming, viewpointRoll; INT32 screenWidth, screenHeight; fixed_t screenHalfW, screenHalfH; @@ -829,12 +829,13 @@ void K_ObjectTracking(trackingResult_t *result, vector3_t *point, UINT8 cameraNu cam = &camera[cameraNum]; player = &players[displayplayers[cameraNum]]; - if (cam == NULL || player == NULL) + if (cam == NULL || player == NULL || player->mo == NULL || P_MobjWasRemoved(player->mo) == true) { // Shouldn't be possible? return; } + // TODO: needs da interp if (cam->chase == true && !player->spectator) { // Use the camera's properties. @@ -843,26 +844,45 @@ void K_ObjectTracking(trackingResult_t *result, vector3_t *point, UINT8 cameraNu viewpointZ = cam->z - point->z; viewpointAngle = (INT32)cam->angle; viewpointAiming = (INT32)cam->aiming; + viewpointRoll = (INT32)player->viewrollangle; + + if (cv_frameinterpolation.value == 1) + { + viewpointX = cam->old_x + FixedMul(rendertimefrac, cam->x - cam->old_x); + viewpointY = cam->old_y + FixedMul(rendertimefrac, cam->y - cam->old_y); + viewpointZ = (cam->old_z + FixedMul(rendertimefrac, cam->z - cam->old_z)) - point->z; + + viewpointAngle = (INT32)(cam->old_angle + FixedMul(rendertimefrac, cam->angle - cam->old_angle)); + viewpointAiming = (INT32)(cam->old_aiming + FixedMul(rendertimefrac, cam->aiming - cam->old_aiming)); + viewpointRoll = (INT32)(player->old_viewrollangle + FixedMul(rendertimefrac, player->viewrollangle - player->old_viewrollangle)); + } } else { // Use player properties. - - if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true) - { - // This shouldn't happen. - return; - } - viewpointX = player->mo->x; viewpointY = player->mo->y; viewpointZ = player->viewz - point->z; viewpointAngle = (INT32)player->mo->angle; viewpointAiming = (INT32)player->aiming; + viewpointRoll = (INT32)player->viewrollangle; + + if (cv_frameinterpolation.value == 1) + { + viewpointX = player->mo->old_x + FixedMul(rendertimefrac, player->mo->x - player->mo->old_x); + viewpointY = player->mo->old_y + FixedMul(rendertimefrac, player->mo->y - player->mo->old_y); + viewpointZ = (player->mo->old_z + FixedMul(rendertimefrac, player->viewz - player->mo->old_z)) - point->z; //player->old_viewz + + viewpointAngle = (INT32)(player->mo->old_angle + FixedMul(rendertimefrac, player->mo->angle - player->mo->old_angle)); + //viewpointAiming = (INT32)(player->mo->old_aiming + FixedMul(rendertimefrac, player->mo->aiming - player->mo->old_aiming)); + viewpointRoll = (INT32)(player->old_viewrollangle + FixedMul(rendertimefrac, player->viewrollangle - player->old_viewrollangle)); + } } viewpointAngle += (INT32)angleOffset; + (void)viewpointRoll; // will be used later... + // Calculate screen size adjustments. // TODO: Anyone want to make this support non-green resolutions somehow? :V screenWidth = BASEVIDWIDTH; @@ -2590,6 +2610,7 @@ static void K_drawKartPlayerCheck(void) UINT8 *colormap = NULL; UINT8 pnum = 0; vector3_t v; + vector3_t pPos; trackingResult_t result; if (!playeringame[i] || checkplayer->spectator) @@ -2614,7 +2635,22 @@ static void K_drawKartPlayerCheck(void) v.y = checkplayer->mo->y; v.z = checkplayer->mo->z; - distance = R_PointToDist2(stplyr->mo->x, stplyr->mo->y, v.x, v.y); + pPos.x = stplyr->mo->x; + pPos.y = stplyr->mo->y; + pPos.z = stplyr->mo->z; + + if (cv_frameinterpolation.value == 1) + { + v.x = checkplayer->mo->old_x + FixedMul(rendertimefrac, checkplayer->mo->x - checkplayer->mo->old_x); + v.y = checkplayer->mo->old_y + FixedMul(rendertimefrac, checkplayer->mo->y - checkplayer->mo->old_y); + v.z = checkplayer->mo->old_z + FixedMul(rendertimefrac, checkplayer->mo->z - checkplayer->mo->old_z); + + pPos.x = stplyr->mo->old_x + FixedMul(rendertimefrac, stplyr->mo->x - stplyr->mo->old_x); + pPos.y = stplyr->mo->old_y + FixedMul(rendertimefrac, stplyr->mo->y - stplyr->mo->old_y); + pPos.z = stplyr->mo->old_z + FixedMul(rendertimefrac, stplyr->mo->z - stplyr->mo->old_z); + } + + distance = R_PointToDist2(pPos.x, pPos.y, v.x, v.y); if (distance > maxdistance) { @@ -2801,12 +2837,26 @@ static void K_drawKartNameTags(void) c.x = thiscam->x; c.y = thiscam->y; c.z = thiscam->z; + + if (cv_frameinterpolation.value == 1) + { + c.x = thiscam->old_x + FixedMul(rendertimefrac, thiscam->x - thiscam->old_x); + c.y = thiscam->old_y + FixedMul(rendertimefrac, thiscam->y - thiscam->old_y); + c.z = thiscam->old_z + FixedMul(rendertimefrac, thiscam->z - thiscam->old_z); + } } else { c.x = stplyr->mo->x; c.y = stplyr->mo->y; c.z = stplyr->mo->z; + + if (cv_frameinterpolation.value == 1) + { + c.x = stplyr->mo->old_x + FixedMul(rendertimefrac, stplyr->mo->x - stplyr->mo->old_x); + c.y = stplyr->mo->old_y + FixedMul(rendertimefrac, stplyr->mo->y - stplyr->mo->old_y); + c.z = stplyr->mo->old_z + FixedMul(rendertimefrac, stplyr->mo->z - stplyr->mo->old_z); + } } for (i = 0; i < MAXPLAYERS; i++) @@ -2849,6 +2899,13 @@ static void K_drawKartNameTags(void) v.y = ntplayer->mo->y; v.z = ntplayer->mo->z; + if (cv_frameinterpolation.value == 1) + { + v.x = ntplayer->mo->old_x + FixedMul(rendertimefrac, ntplayer->mo->x - ntplayer->mo->old_x); + v.y = ntplayer->mo->old_y + FixedMul(rendertimefrac, ntplayer->mo->y - ntplayer->mo->old_y); + v.z = ntplayer->mo->old_z + FixedMul(rendertimefrac, ntplayer->mo->z - ntplayer->mo->old_z); + } + if (!(ntplayer->mo->eflags & MFE_VERTICALFLIP)) { v.z += ntplayer->mo->height; @@ -2904,7 +2961,16 @@ static void K_drawKartNameTags(void) v.x = ntplayer->mo->x; v.y = ntplayer->mo->y; - v.z = ntplayer->mo->z + (ntplayer->mo->height / 2); + v.z = ntplayer->mo->z; + + if (cv_frameinterpolation.value == 1) + { + v.x = ntplayer->mo->old_x + FixedMul(rendertimefrac, ntplayer->mo->x - ntplayer->mo->old_x); + v.y = ntplayer->mo->old_y + FixedMul(rendertimefrac, ntplayer->mo->y - ntplayer->mo->old_y); + v.z = ntplayer->mo->old_z + FixedMul(rendertimefrac, ntplayer->mo->z - ntplayer->mo->old_z); + } + + v.z += (ntplayer->mo->height / 2); if (stplyr->mo->eflags & MFE_VERTICALFLIP) { @@ -3145,7 +3211,7 @@ static void K_drawKartMinimap(void) interpx = g->mo->x; interpy = g->mo->y; - if (cv_frameinterpolation.value == 1 && !paused) + if (cv_frameinterpolation.value == 1) { interpx = g->mo->old_x + FixedMul(rendertimefrac, g->mo->x - g->mo->old_x); interpy = g->mo->old_y + FixedMul(rendertimefrac, g->mo->y - g->mo->old_y); @@ -3210,7 +3276,7 @@ static void K_drawKartMinimap(void) interpx = players[i].mo->x; interpy = players[i].mo->y; - if (cv_frameinterpolation.value == 1 && !paused) + if (cv_frameinterpolation.value == 1) { interpx = players[i].mo->old_x + FixedMul(rendertimefrac, players[i].mo->x - players[i].mo->old_x); interpy = players[i].mo->old_y + FixedMul(rendertimefrac, players[i].mo->y - players[i].mo->old_y); @@ -3245,7 +3311,7 @@ static void K_drawKartMinimap(void) interpx = mobj->x; interpy = mobj->y; - if (cv_frameinterpolation.value == 1 && !paused) + if (cv_frameinterpolation.value == 1) { interpx = mobj->old_x + FixedMul(rendertimefrac, mobj->x - mobj->old_x); interpy = mobj->old_y + FixedMul(rendertimefrac, mobj->y - mobj->old_y); @@ -3282,7 +3348,7 @@ static void K_drawKartMinimap(void) interpx = players[localplayers[i]].mo->x; interpy = players[localplayers[i]].mo->y; - if (cv_frameinterpolation.value == 1 && !paused) + if (cv_frameinterpolation.value == 1) { interpx = players[localplayers[i]].mo->old_x + FixedMul(rendertimefrac, players[localplayers[i]].mo->x - players[localplayers[i]].mo->old_x); interpy = players[localplayers[i]].mo->old_y + FixedMul(rendertimefrac, players[localplayers[i]].mo->y - players[localplayers[i]].mo->old_y); diff --git a/src/p_local.h b/src/p_local.h index 631920bb6..61a8cf3a0 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -112,6 +112,10 @@ typedef struct camera_s fixed_t pan; // SRB2Kart: camera pitches on slopes angle_t pitch; + + // Interpolation data + fixed_t old_x, old_y, old_z; + angle_t old_angle, old_aiming; } camera_t; // demo freecam or something before i commit die diff --git a/src/p_mobj.c b/src/p_mobj.c index c70c9a2cc..5a7c4d0d5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3661,6 +3661,9 @@ void P_PrecipThinker(precipmobj_t *mobj) mobj->old_x = mobj->x; mobj->old_y = mobj->y; mobj->old_z = mobj->z; + mobj->old_angle = mobj->angle; + mobj->old_pitch = mobj->pitch; + mobj->old_roll = mobj->roll; P_CycleStateAnimation((mobj_t *)mobj); @@ -8822,6 +8825,9 @@ void P_MobjThinker(mobj_t *mobj) mobj->old_x = mobj->x; mobj->old_y = mobj->y; mobj->old_z = mobj->z; + mobj->old_angle = mobj->angle; + mobj->old_pitch = mobj->pitch; + mobj->old_roll = mobj->roll; // Remove dead target/tracer. if (mobj->target && P_MobjWasRemoved(mobj->target)) @@ -9976,6 +9982,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->old_x = mobj->x; mobj->old_y = mobj->y; mobj->old_z = mobj->z; + mobj->old_angle = mobj->angle; + mobj->old_pitch = mobj->pitch; + mobj->old_roll = mobj->roll; return mobj; } @@ -10032,6 +10041,9 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype mobj->old_x = mobj->x; mobj->old_y = mobj->y; mobj->old_z = mobj->z; + mobj->old_angle = mobj->angle; + mobj->old_pitch = mobj->pitch; + mobj->old_roll = mobj->roll; return mobj; } diff --git a/src/p_mobj.h b/src/p_mobj.h index 3c7ab4367..2373bdca4 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -285,6 +285,7 @@ typedef struct mobj_s // More drawing info: to determine current sprite. angle_t angle, pitch, roll; // orientation + angle_t old_angle, old_pitch, old_roll; // orientation interpolation angle_t rollangle; spritenum_t sprite; // used to find patch_t and flip value UINT32 frame; // frame number, plus bits see p_pspr.h @@ -424,6 +425,7 @@ typedef struct precipmobj_s // More drawing info: to determine current sprite. angle_t angle, pitch, roll; // orientation + angle_t old_angle, old_pitch, old_roll; // orientation interpolation angle_t rollangle; spritenum_t sprite; // used to find patch_t and flip value UINT32 frame; // frame number, plus bits see p_pspr.h diff --git a/src/p_user.c b/src/p_user.c index c36ef75f0..4b857972d 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1145,6 +1145,9 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->old_x = mobj->old_x; ghost->old_y = mobj->old_y; ghost->old_z = mobj->old_z; + ghost->old_angle = (mobj->player ? mobj->player->old_drawangle : mobj->old_angle); + ghost->old_pitch = mobj->old_pitch; + ghost->old_roll = mobj->old_roll; return ghost; } @@ -2848,6 +2851,12 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall subsector_t *newsubsec; #endif + thiscam->old_x = thiscam->x; + thiscam->old_y = thiscam->y; + thiscam->old_z = thiscam->z; + thiscam->old_angle = thiscam->angle; + thiscam->old_aiming = thiscam->aiming; + democam.soundmobj = NULL; // reset this each frame, we don't want the game crashing for stupid reasons now do we // We probably shouldn't move the camera if there is no player or player mobj somehow @@ -4160,6 +4169,9 @@ void P_PlayerThink(player_t *player) ticcmd_t *cmd; const size_t playeri = (size_t)(player - players); + player->old_drawangle = player->drawangle; + player->old_viewrollangle = player->viewrollangle; + #ifdef PARANOIA if (!player->mo) I_Error("p_playerthink: players[%s].mo == NULL", sizeu1(playeri)); @@ -4172,11 +4184,6 @@ void P_PlayerThink(player_t *player) player->playerstate = PST_DEAD; } - if (player->mo->hitlag > 0) - { - return; - } - if (player->awayviewmobj && P_MobjWasRemoved(player->awayviewmobj)) { P_SetTarget(&player->awayviewmobj, NULL); // remove awayviewmobj asap if invalid @@ -4192,6 +4199,11 @@ void P_PlayerThink(player_t *player) if (player->awayviewtics && player->awayviewtics != -1) player->awayviewtics--; + if (player->mo->hitlag > 0) + { + return; + } + // Track airtime if (P_IsObjectOnGround(player->mo)) { diff --git a/src/r_things.c b/src/r_things.c index f383d6d6a..2e50e732c 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1431,10 +1431,7 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t interpx = thing->x; fixed_t interpy = thing->y; fixed_t interpz = thing->z; - angle_t interpangle = thing->angle; - - // use player drawangle if player - if (thing->player) interpangle = thing->player->drawangle; + angle_t interpangle = (thing->player ? thing->player->drawangle : thing->angle); // do interpolation if (cv_frameinterpolation.value == 1) @@ -1442,13 +1439,14 @@ static void R_ProjectSprite(mobj_t *thing) interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x); interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y); interpz = thing->old_z + FixedMul(rendertimefrac, thing->z - thing->old_z); + if (thing->player) { - interpangle = thing->player->drawangle; + interpangle = thing->player->old_drawangle + FixedMul(rendertimefrac, thing->player->drawangle - thing->player->old_drawangle); } else { - interpangle = thing->angle; + interpangle = thing->old_angle + FixedMul(rendertimefrac, thing->angle - thing->old_angle); } }