mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-22 02:42:20 +00:00
Implement interpolation at the renderer level
Instead of interpolating thinkers, we interpolate mobjs inside the renderer. Further interpolation is TBI.
This commit is contained in:
parent
d9799540c6
commit
b625076c87
20 changed files with 537 additions and 143 deletions
|
@ -156,7 +156,7 @@ ifdef DEBUGMODE
|
|||
ifdef GCC48
|
||||
opts+=-Og
|
||||
else
|
||||
opts+=O0
|
||||
opts+=-O0
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ tables.c
|
|||
r_bsp.c
|
||||
r_data.c
|
||||
r_draw.c
|
||||
r_fps.c
|
||||
r_main.c
|
||||
r_plane.c
|
||||
r_segs.c
|
||||
|
|
|
@ -88,6 +88,12 @@ tic_t I_GetTime(void)
|
|||
return (since_start*TICRATE)/1000000;
|
||||
}
|
||||
|
||||
fixed_t I_GetTimeFrac(void)
|
||||
{
|
||||
//stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
void I_Sleep(void){}
|
||||
|
||||
void I_GetEvent(void){}
|
||||
|
|
|
@ -5270,6 +5270,7 @@ void TryRunTics(tic_t realtics)
|
|||
boolean update_stats = !(paused || P_AutoPause());
|
||||
|
||||
DEBFILE(va("============ Running tic %d (local %d)\n", gametic, localgametic));
|
||||
prev_tics = I_GetTime();
|
||||
|
||||
if (update_stats)
|
||||
PS_START_TIMING(ps_tictime);
|
||||
|
|
21
src/d_main.c
21
src/d_main.c
|
@ -64,6 +64,7 @@
|
|||
#include "deh_tables.h" // Dehacked list test
|
||||
#include "m_cond.h" // condition initialization
|
||||
#include "fastcmp.h"
|
||||
#include "r_fps.h" // Frame interpolation/uncapped
|
||||
#include "keys.h"
|
||||
#include "filesrch.h" // refreshdirmenu
|
||||
#include "g_input.h" // tutorial mode control scheming
|
||||
|
@ -147,6 +148,7 @@ event_t events[MAXEVENTS];
|
|||
INT32 eventhead, eventtail;
|
||||
|
||||
boolean dedicated = false;
|
||||
boolean tic_happened = false; // Frame interpolation/uncapped
|
||||
|
||||
//
|
||||
// D_PostEvent
|
||||
|
@ -764,7 +766,7 @@ void D_SRB2Loop(void)
|
|||
debugload--;
|
||||
#endif
|
||||
|
||||
if (!realtics && !singletics)
|
||||
if (!realtics && !singletics && cv_frameinterpolation.value != 1)
|
||||
{
|
||||
I_Sleep();
|
||||
continue;
|
||||
|
@ -780,15 +782,27 @@ void D_SRB2Loop(void)
|
|||
realtics = 1;
|
||||
|
||||
// process tics (but maybe not if realtic == 0)
|
||||
tic_happened = realtics ? true : false;
|
||||
TryRunTics(realtics);
|
||||
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
rendertimefrac = I_GetTimeFrac();
|
||||
else
|
||||
rendertimefrac = FRACUNIT;
|
||||
|
||||
if (cv_frameinterpolation.value == 1)
|
||||
{
|
||||
D_Display();
|
||||
}
|
||||
|
||||
if (lastdraw || singletics || gametic > rendergametic)
|
||||
{
|
||||
rendergametic = gametic;
|
||||
rendertimeout = entertic+TICRATE/17;
|
||||
|
||||
// Update display, next frame, with current state.
|
||||
D_Display();
|
||||
// (Only display if not already done for frame interp)
|
||||
cv_frameinterpolation.value == 0 ? D_Display() : 0;
|
||||
|
||||
if (moviemode)
|
||||
M_SaveFrame();
|
||||
|
@ -805,7 +819,8 @@ void D_SRB2Loop(void)
|
|||
if (camera.chase)
|
||||
P_MoveChaseCamera(&players[displayplayer], &camera, false);
|
||||
}
|
||||
D_Display();
|
||||
// (Only display if not already done for frame interp)
|
||||
cv_frameinterpolation.value == 0 ? D_Display() : 0;
|
||||
|
||||
if (moviemode)
|
||||
M_SaveFrame();
|
||||
|
|
|
@ -26,6 +26,7 @@ extern char srb2home[256]; //Alam: My Home
|
|||
extern boolean usehome; //Alam: which path?
|
||||
extern const char *pandf; //Alam: how to path?
|
||||
extern char srb2path[256]; //Alam: SRB2's Home
|
||||
extern boolean tic_happened; // Frame interpolation/uncapped
|
||||
|
||||
// the infinite loop of D_SRB2Loop() called from win_main for windows version
|
||||
void D_SRB2Loop(void) FUNCNORETURN;
|
||||
|
|
|
@ -16,7 +16,7 @@ tic_t I_GetTime(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int I_GetTimeMicros(void)
|
||||
fixed_t I_GetTimeFrac(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
10
src/g_game.c
10
src/g_game.c
|
@ -46,6 +46,7 @@
|
|||
#include "b_bot.h"
|
||||
#include "m_cond.h" // condition sets
|
||||
#include "lua_script.h"
|
||||
#include "r_fps.h" // frame interpolation/uncapped
|
||||
|
||||
#include "lua_hud.h"
|
||||
|
||||
|
@ -2362,6 +2363,8 @@ void G_Ticker(boolean run)
|
|||
F_TextPromptTicker();
|
||||
AM_Ticker();
|
||||
HU_Ticker();
|
||||
R_UpdateViewInterpolation();
|
||||
|
||||
break;
|
||||
|
||||
case GS_INTERMISSION:
|
||||
|
@ -2414,7 +2417,12 @@ void G_Ticker(boolean run)
|
|||
break;
|
||||
|
||||
case GS_TITLESCREEN:
|
||||
if (titlemapinaction) P_Ticker(run); // then intentionally fall through
|
||||
if (titlemapinaction)
|
||||
{
|
||||
P_Ticker(run);
|
||||
R_UpdateViewInterpolation();
|
||||
// then intentionally fall through
|
||||
}
|
||||
/* FALLTHRU */
|
||||
case GS_WAITINGPLAYERS:
|
||||
F_MenuPresTicker(run);
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "../m_cheat.h"
|
||||
#include "../f_finale.h"
|
||||
#include "../r_things.h" // R_GetShadowZ
|
||||
#include "../d_main.h"
|
||||
#include "../p_slopes.h"
|
||||
#include "hw_md2.h"
|
||||
|
||||
|
@ -5050,6 +5051,12 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
INT32 rollangle = 0;
|
||||
#endif
|
||||
|
||||
// uncapped/interpolation
|
||||
fixed_t interpx;
|
||||
fixed_t interpy;
|
||||
fixed_t interpz;
|
||||
angle_t interpangle;
|
||||
|
||||
if (!thing)
|
||||
return;
|
||||
|
||||
|
@ -5071,13 +5078,26 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
dispoffset = thing->info->dispoffset;
|
||||
|
||||
interpx = thing->x;
|
||||
interpy = thing->y;
|
||||
interpz = thing->z;
|
||||
interpangle = mobjangle;
|
||||
|
||||
if (cv_frameinterpolation.value == 1 && !paused)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
this_scale = FIXED_TO_FLOAT(thing->scale);
|
||||
spritexscale = FIXED_TO_FLOAT(thing->spritexscale);
|
||||
spriteyscale = FIXED_TO_FLOAT(thing->spriteyscale);
|
||||
|
||||
// transform the origin point
|
||||
tr_x = FIXED_TO_FLOAT(thing->x) - gl_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(thing->y) - gl_viewy;
|
||||
tr_x = FIXED_TO_FLOAT(interpx) - gl_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(interpy) - gl_viewy;
|
||||
|
||||
// rotation around vertical axis
|
||||
tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin);
|
||||
|
@ -5100,8 +5120,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
}
|
||||
|
||||
// The above can stay as it works for cutting sprites that are too close
|
||||
tr_x = FIXED_TO_FLOAT(thing->x);
|
||||
tr_y = FIXED_TO_FLOAT(thing->y);
|
||||
tr_x = FIXED_TO_FLOAT(interpx);
|
||||
tr_y = FIXED_TO_FLOAT(interpy);
|
||||
|
||||
// decide which patch to use for sprite relative to player
|
||||
#ifdef RANGECHECK
|
||||
|
@ -5149,7 +5169,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
I_Error("sprframes NULL for sprite %d\n", thing->sprite);
|
||||
#endif
|
||||
|
||||
ang = R_PointToAngle (thing->x, thing->y) - mobjangle;
|
||||
ang = R_PointToAngle (interpx, interpy) - interpangle;
|
||||
if (mirrored)
|
||||
ang = InvAngle(ang);
|
||||
|
||||
|
@ -5295,12 +5315,12 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (vflip)
|
||||
{
|
||||
gz = FIXED_TO_FLOAT(thing->z + thing->height) - (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
|
||||
gz = FIXED_TO_FLOAT(interpz + thing->height) - (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
|
||||
gzt = gz + (FIXED_TO_FLOAT(spr_height) * this_yscale);
|
||||
}
|
||||
else
|
||||
{
|
||||
gzt = FIXED_TO_FLOAT(thing->z) + (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
|
||||
gzt = FIXED_TO_FLOAT(interpz) + (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
|
||||
gz = gzt - (FIXED_TO_FLOAT(spr_height) * this_yscale);
|
||||
}
|
||||
|
||||
|
@ -5461,6 +5481,9 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
unsigned rot = 0;
|
||||
UINT8 flip;
|
||||
|
||||
if (!thing)
|
||||
return;
|
||||
|
||||
// Visibility check by the blend mode.
|
||||
if (thing->frame & FF_TRANSMASK)
|
||||
{
|
||||
|
@ -5468,9 +5491,22 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
return;
|
||||
}
|
||||
|
||||
// uncapped/interpolation
|
||||
fixed_t interpx = thing->x;
|
||||
fixed_t interpy = thing->y;
|
||||
fixed_t interpz = thing->z;
|
||||
|
||||
// do interpolation
|
||||
if (cv_frameinterpolation.value == 1 && !paused)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
// transform the origin point
|
||||
tr_x = FIXED_TO_FLOAT(thing->x) - gl_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(thing->y) - gl_viewy;
|
||||
tr_x = FIXED_TO_FLOAT(interpx) - gl_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(interpy) - gl_viewy;
|
||||
|
||||
// rotation around vertical axis
|
||||
tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin);
|
||||
|
@ -5479,8 +5515,8 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
if (tz < ZCLIP_PLANE)
|
||||
return;
|
||||
|
||||
tr_x = FIXED_TO_FLOAT(thing->x);
|
||||
tr_y = FIXED_TO_FLOAT(thing->y);
|
||||
tr_x = FIXED_TO_FLOAT(interpx);
|
||||
tr_y = FIXED_TO_FLOAT(interpy);
|
||||
|
||||
// decide which patch to use for sprite relative to player
|
||||
if ((unsigned)thing->sprite >= numsprites)
|
||||
|
@ -5542,7 +5578,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
vis->colormap = NULL;
|
||||
|
||||
// set top/bottom coords
|
||||
vis->gzt = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset);
|
||||
vis->gzt = FIXED_TO_FLOAT(interpz + spritecachedinfo[lumpoff].topoffset);
|
||||
vis->gz = vis->gzt - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].height);
|
||||
|
||||
vis->precip = true;
|
||||
|
@ -6678,6 +6714,8 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
// 10 by 10 grid. 2 coordinates (xy)
|
||||
float v[SCREENVERTS][SCREENVERTS][2];
|
||||
static double disStart = 0;
|
||||
static float last_fractime = 0;
|
||||
|
||||
UINT8 x, y;
|
||||
INT32 WAVELENGTH;
|
||||
INT32 AMPLITUDE;
|
||||
|
@ -6709,6 +6747,16 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
HWD.pfnPostImgRedraw(v);
|
||||
if (!(paused || P_AutoPause()))
|
||||
disStart += 1;
|
||||
fixed_t fractime = I_GetTimeFrac();
|
||||
if (tic_happened)
|
||||
{
|
||||
disStart = disStart - last_fractime + 1 + FIXED_TO_FLOAT(fractime);
|
||||
}
|
||||
else
|
||||
{
|
||||
disStart = disStart - last_fractime + FIXED_TO_FLOAT(fractime);
|
||||
}
|
||||
last_fractime = fractime;
|
||||
|
||||
// Capture the screen again for screen waving on the intermission
|
||||
if(gamestate != GS_INTERMISSION)
|
||||
|
|
|
@ -46,6 +46,10 @@ UINT32 I_GetFreeMem(UINT32 *total);
|
|||
*/
|
||||
tic_t I_GetTime(void);
|
||||
|
||||
/** \brief Get the current time as a fraction of a tic since the last tic.
|
||||
*/
|
||||
fixed_t I_GetTimeFrac(void);
|
||||
|
||||
/** \brief Returns precise time value for performance measurement.
|
||||
*/
|
||||
precise_t I_GetPreciseTime(void);
|
||||
|
|
25
src/p_mobj.c
25
src/p_mobj.c
|
@ -4027,6 +4027,11 @@ void P_NullPrecipThinker(precipmobj_t *mobj)
|
|||
|
||||
void P_SnowThinker(precipmobj_t *mobj)
|
||||
{
|
||||
// reset old state (for interpolation)
|
||||
mobj->old_x = mobj->x;
|
||||
mobj->old_y = mobj->y;
|
||||
mobj->old_z = mobj->z;
|
||||
|
||||
P_CycleStateAnimation((mobj_t *)mobj);
|
||||
|
||||
// adjust height
|
||||
|
@ -4036,6 +4041,11 @@ void P_SnowThinker(precipmobj_t *mobj)
|
|||
|
||||
void P_RainThinker(precipmobj_t *mobj)
|
||||
{
|
||||
// reset old state (for interpolation)
|
||||
mobj->old_x = mobj->x;
|
||||
mobj->old_y = mobj->y;
|
||||
mobj->old_z = mobj->z;
|
||||
|
||||
P_CycleStateAnimation((mobj_t *)mobj);
|
||||
|
||||
if (mobj->state != &states[S_RAIN1])
|
||||
|
@ -10032,6 +10042,11 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
I_Assert(mobj != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(mobj));
|
||||
|
||||
// Set old position (for interpolation)
|
||||
mobj->old_x = mobj->x;
|
||||
mobj->old_y = mobj->y;
|
||||
mobj->old_z = mobj->z;
|
||||
|
||||
if (mobj->flags & MF_NOTHINK)
|
||||
return;
|
||||
|
||||
|
@ -10897,6 +10912,11 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
if (CheckForReverseGravity && !(mobj->flags & MF_NOBLOCKMAP))
|
||||
P_CheckGravity(mobj, false);
|
||||
|
||||
// set old state too (for interpolation)
|
||||
mobj->old_x = mobj->x;
|
||||
mobj->old_y = mobj->y;
|
||||
mobj->old_z = mobj->z;
|
||||
|
||||
return mobj;
|
||||
}
|
||||
|
||||
|
@ -10944,6 +10964,11 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
|
|||
|| mobj->subsector->sector->floorpic == skyflatnum)
|
||||
mobj->precipflags |= PCF_PIT;
|
||||
|
||||
// set initial old positions (for interpolation)
|
||||
mobj->old_x = mobj->x;
|
||||
mobj->old_y = mobj->y;
|
||||
mobj->old_z = mobj->z;
|
||||
|
||||
return mobj;
|
||||
}
|
||||
|
||||
|
|
|
@ -281,6 +281,7 @@ typedef struct mobj_s
|
|||
|
||||
// Info for drawing: position.
|
||||
fixed_t x, y, z;
|
||||
fixed_t old_x, old_y, old_z; // position interpolation
|
||||
|
||||
// More list: links in sector (if needed)
|
||||
struct mobj_s *snext;
|
||||
|
@ -408,6 +409,7 @@ typedef struct precipmobj_s
|
|||
|
||||
// Info for drawing: position.
|
||||
fixed_t x, y, z;
|
||||
fixed_t old_x, old_y, old_z; // position interpolation
|
||||
|
||||
// More list: links in sector (if needed)
|
||||
struct precipmobj_s *snext;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "lua_hook.h"
|
||||
#include "m_perfstats.h"
|
||||
#include "i_system.h" // I_GetPreciseTime
|
||||
#include "r_fps.h"
|
||||
|
||||
// Object place
|
||||
#include "m_cheat.h"
|
||||
|
|
169
src/r_fps.c
Normal file
169
src/r_fps.c
Normal file
|
@ -0,0 +1,169 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze, Andrey Budko (prboom)
|
||||
// Copyright (C) 1999-2019 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file r_fps.h
|
||||
/// \brief Uncapped framerate stuff.
|
||||
|
||||
#include "r_fps.h"
|
||||
|
||||
#include "r_main.h"
|
||||
#include "g_game.h"
|
||||
#include "i_video.h"
|
||||
#include "r_plane.h"
|
||||
#include "p_spec.h"
|
||||
#include "r_state.h"
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h" // for cv_glshearing
|
||||
#endif
|
||||
|
||||
static viewvars_t p1view_old;
|
||||
static viewvars_t p1view_new;
|
||||
static viewvars_t p2view_old;
|
||||
static viewvars_t p2view_new;
|
||||
static viewvars_t sky1view_old;
|
||||
static viewvars_t sky1view_new;
|
||||
static viewvars_t sky2view_old;
|
||||
static viewvars_t sky2view_new;
|
||||
|
||||
static viewvars_t *oldview = &p1view_old;
|
||||
viewvars_t *newview = &p1view_new;
|
||||
|
||||
|
||||
enum viewcontext_e viewcontext = VIEWCONTEXT_PLAYER1;
|
||||
|
||||
// recalc necessary stuff for mouseaiming
|
||||
// slopes are already calculated for the full possible view (which is 4*viewheight).
|
||||
// 18/08/18: (No it's actually 16*viewheight, thanks Jimita for finding this out)
|
||||
static void R_SetupFreelook(player_t *player, boolean skybox)
|
||||
{
|
||||
#ifndef HWRENDER
|
||||
(void)player;
|
||||
(void)skybox;
|
||||
#endif
|
||||
|
||||
// clip it in the case we are looking a hardware 90 degrees full aiming
|
||||
// (lmps, network and use F12...)
|
||||
if (rendermode == render_soft
|
||||
#ifdef HWRENDER
|
||||
|| (rendermode == render_opengl
|
||||
&& (cv_glshearing.value == 1
|
||||
|| (cv_glshearing.value == 2 && R_IsViewpointThirdPerson(player, skybox))))
|
||||
#endif
|
||||
)
|
||||
{
|
||||
G_SoftwareClipAimingPitch((INT32 *)&aimingangle);
|
||||
}
|
||||
|
||||
centeryfrac = (viewheight/2)<<FRACBITS;
|
||||
|
||||
if (rendermode == render_soft)
|
||||
centeryfrac += FixedMul(AIMINGTODY(aimingangle), FixedDiv(viewwidth<<FRACBITS, BASEVIDWIDTH<<FRACBITS));
|
||||
|
||||
centery = FixedInt(FixedRound(centeryfrac));
|
||||
|
||||
if (rendermode == render_soft)
|
||||
yslope = &yslopetab[viewheight*8 - centery];
|
||||
}
|
||||
|
||||
#undef AIMINGTODY
|
||||
|
||||
void R_InterpolateView(fixed_t frac)
|
||||
{
|
||||
boolean skybox = 0;
|
||||
if (FIXED_TO_FLOAT(frac) < 0)
|
||||
frac = 0;
|
||||
|
||||
viewx = oldview->x + R_LerpFixed(oldview->x, newview->x, frac);
|
||||
viewy = oldview->y + R_LerpFixed(oldview->y, newview->y, frac);
|
||||
viewz = oldview->z + R_LerpFixed(oldview->z, newview->z, frac);
|
||||
|
||||
viewangle = oldview->angle + R_LerpAngle(oldview->angle, newview->angle, frac);
|
||||
aimingangle = oldview->aim + R_LerpAngle(oldview->aim, newview->aim, 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...
|
||||
if (frac >= FRACUNIT)
|
||||
{
|
||||
viewplayer = newview->player;
|
||||
viewsector = newview->sector;
|
||||
}
|
||||
else
|
||||
{
|
||||
viewplayer = oldview->player;
|
||||
viewsector = oldview->sector;
|
||||
}
|
||||
|
||||
// well, this ain't pretty
|
||||
if (newview == &sky1view_new || newview == &sky2view_new)
|
||||
{
|
||||
skybox = 1;
|
||||
}
|
||||
|
||||
R_SetupFreelook(newview->player, skybox);
|
||||
}
|
||||
|
||||
void R_UpdateViewInterpolation(void)
|
||||
{
|
||||
p1view_old = p1view_new;
|
||||
p2view_old = p2view_new;
|
||||
sky1view_old = sky1view_new;
|
||||
sky2view_old = sky2view_new;
|
||||
}
|
||||
|
||||
void R_SetViewContext(enum viewcontext_e _viewcontext)
|
||||
{
|
||||
I_Assert(_viewcontext == VIEWCONTEXT_PLAYER1
|
||||
|| _viewcontext == VIEWCONTEXT_PLAYER2
|
||||
|| _viewcontext == VIEWCONTEXT_SKY1
|
||||
|| _viewcontext == VIEWCONTEXT_SKY2);
|
||||
viewcontext = _viewcontext;
|
||||
|
||||
switch (viewcontext)
|
||||
{
|
||||
case VIEWCONTEXT_PLAYER1:
|
||||
oldview = &p1view_old;
|
||||
newview = &p1view_new;
|
||||
break;
|
||||
case VIEWCONTEXT_PLAYER2:
|
||||
oldview = &p2view_old;
|
||||
newview = &p2view_new;
|
||||
break;
|
||||
case VIEWCONTEXT_SKY1:
|
||||
oldview = &sky1view_old;
|
||||
newview = &sky1view_new;
|
||||
break;
|
||||
case VIEWCONTEXT_SKY2:
|
||||
oldview = &sky2view_old;
|
||||
newview = &sky2view_new;
|
||||
break;
|
||||
default:
|
||||
I_Error("viewcontext value is invalid: we should never get here without an assert!!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fixed_t R_LerpFixed(fixed_t from, fixed_t to, fixed_t frac)
|
||||
{
|
||||
return FixedMul(frac, to - from);
|
||||
}
|
||||
|
||||
INT32 R_LerpInt32(INT32 from, INT32 to, fixed_t frac)
|
||||
{
|
||||
return FixedInt(FixedMul(frac, (to*FRACUNIT) - (from*FRACUNIT)));
|
||||
}
|
||||
|
||||
angle_t R_LerpAngle(angle_t from, angle_t to, fixed_t frac)
|
||||
{
|
||||
return FixedMul(frac, to - from);
|
||||
}
|
59
src/r_fps.h
Normal file
59
src/r_fps.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze, Andrey Budko (prboom)
|
||||
// Copyright (C) 1999-2019 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file r_fps.h
|
||||
/// \brief Uncapped framerate stuff.
|
||||
|
||||
#ifndef __R_FPS_H__
|
||||
#define __R_FPS_H__
|
||||
|
||||
#include "m_fixed.h"
|
||||
#include "p_local.h"
|
||||
#include "r_state.h"
|
||||
|
||||
enum viewcontext_e
|
||||
{
|
||||
VIEWCONTEXT_PLAYER1 = 0,
|
||||
VIEWCONTEXT_PLAYER2,
|
||||
VIEWCONTEXT_SKY1,
|
||||
VIEWCONTEXT_SKY2
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
fixed_t x;
|
||||
fixed_t y;
|
||||
fixed_t z;
|
||||
boolean sky;
|
||||
sector_t *sector;
|
||||
player_t *player;
|
||||
|
||||
angle_t angle;
|
||||
angle_t aim;
|
||||
fixed_t cos;
|
||||
fixed_t sin;
|
||||
mobj_t *mobj;
|
||||
} viewvars_t;
|
||||
|
||||
extern viewvars_t *newview;
|
||||
|
||||
// Interpolates the current view variables (r_state.h) against the selected view context in R_SetViewContext
|
||||
void R_InterpolateView(fixed_t frac);
|
||||
// Buffer the current new views into the old views. Call once after each real tic.
|
||||
void R_UpdateViewInterpolation(void);
|
||||
// Set the current view context (the viewvars pointed to by newview)
|
||||
void R_SetViewContext(enum viewcontext_e _viewcontext);
|
||||
|
||||
fixed_t R_LerpFixed(fixed_t from, fixed_t to, fixed_t frac);
|
||||
INT32 R_LerpInt32(INT32 from, INT32 to, fixed_t frac);
|
||||
UINT32 R_LerpUInt32(UINT32 from, UINT32 to, fixed_t frac);
|
||||
angle_t R_LerpAngle(angle_t from, angle_t to, fixed_t frac);
|
||||
|
||||
#endif
|
182
src/r_main.c
182
src/r_main.c
|
@ -35,6 +35,7 @@
|
|||
#include "r_portal.h"
|
||||
#include "r_main.h"
|
||||
#include "i_system.h" // I_GetPreciseTime
|
||||
#include "r_fps.h" // Frame interpolation/uncapped
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
|
@ -75,6 +76,8 @@ sector_t *viewsector;
|
|||
player_t *viewplayer;
|
||||
mobj_t *r_viewmobj;
|
||||
|
||||
fixed_t rendertimefrac;
|
||||
|
||||
//
|
||||
// precalculated math tables
|
||||
//
|
||||
|
@ -96,6 +99,9 @@ lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
|
|||
lighttable_t *scalelightfixed[MAXLIGHTSCALE];
|
||||
lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
|
||||
|
||||
// Frame interpolation/uncapped
|
||||
tic_t prev_tics;
|
||||
|
||||
// Hack to support extra boom colormaps.
|
||||
extracolormap_t *extra_colormaps = NULL;
|
||||
|
||||
|
@ -164,6 +170,9 @@ consvar_t cv_drawdist_precip = CVAR_INIT ("drawdist_precip", "1024", CV_SAVE, dr
|
|||
//consvar_t cv_precipdensity = CVAR_INIT ("precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL);
|
||||
consvar_t cv_fov = CVAR_INIT ("fov", "90", CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange);
|
||||
|
||||
// Frame interpolation/uncapped
|
||||
consvar_t cv_frameinterpolation = {"frameinterpolation", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// Okay, whoever said homremoval causes a performance hit should be shot.
|
||||
consvar_t cv_homremoval = CVAR_INIT ("homremoval", "No", CV_SAVE, homremoval_cons_t, NULL);
|
||||
|
||||
|
@ -1084,41 +1093,6 @@ subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y)
|
|||
//
|
||||
// R_SetupFrame
|
||||
//
|
||||
|
||||
// recalc necessary stuff for mouseaiming
|
||||
// slopes are already calculated for the full possible view (which is 4*viewheight).
|
||||
// 18/08/18: (No it's actually 16*viewheight, thanks Jimita for finding this out)
|
||||
static void R_SetupFreelook(player_t *player, boolean skybox)
|
||||
{
|
||||
#ifndef HWRENDER
|
||||
(void)player;
|
||||
(void)skybox;
|
||||
#endif
|
||||
|
||||
// clip it in the case we are looking a hardware 90 degrees full aiming
|
||||
// (lmps, network and use F12...)
|
||||
if (rendermode == render_soft
|
||||
#ifdef HWRENDER
|
||||
|| (rendermode == render_opengl
|
||||
&& (cv_glshearing.value == 1
|
||||
|| (cv_glshearing.value == 2 && R_IsViewpointThirdPerson(player, skybox))))
|
||||
#endif
|
||||
)
|
||||
{
|
||||
G_SoftwareClipAimingPitch((INT32 *)&aimingangle);
|
||||
}
|
||||
|
||||
centeryfrac = (viewheight/2)<<FRACBITS;
|
||||
|
||||
if (rendermode == render_soft)
|
||||
centeryfrac += FixedMul(AIMINGTODY(aimingangle), FixedDiv(viewwidth<<FRACBITS, BASEVIDWIDTH<<FRACBITS));
|
||||
|
||||
centery = FixedInt(FixedRound(centeryfrac));
|
||||
|
||||
if (rendermode == render_soft)
|
||||
yslope = &yslopetab[viewheight*8 - centery];
|
||||
}
|
||||
|
||||
void R_SetupFrame(player_t *player)
|
||||
{
|
||||
camera_t *thiscam;
|
||||
|
@ -1129,11 +1103,13 @@ void R_SetupFrame(player_t *player)
|
|||
{
|
||||
thiscam = &camera2;
|
||||
chasecam = (cv_chasecam2.value != 0);
|
||||
R_SetViewContext(VIEWCONTEXT_PLAYER2);
|
||||
}
|
||||
else
|
||||
{
|
||||
thiscam = &camera;
|
||||
chasecam = (cv_chasecam.value != 0);
|
||||
R_SetViewContext(VIEWCONTEXT_PLAYER1);
|
||||
}
|
||||
|
||||
if (player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN || tutorialmode)
|
||||
|
@ -1149,81 +1125,83 @@ void R_SetupFrame(player_t *player)
|
|||
else if (!chasecam)
|
||||
thiscam->chase = false;
|
||||
|
||||
newview->sky = false;
|
||||
|
||||
if (player->awayviewtics)
|
||||
{
|
||||
// cut-away view stuff
|
||||
r_viewmobj = player->awayviewmobj; // should be a MT_ALTVIEWMAN
|
||||
I_Assert(r_viewmobj != NULL);
|
||||
viewz = r_viewmobj->z + 20*FRACUNIT;
|
||||
aimingangle = player->awayviewaiming;
|
||||
viewangle = r_viewmobj->angle;
|
||||
newview->z = r_viewmobj->z + 20*FRACUNIT;
|
||||
newview->aim = player->awayviewaiming;
|
||||
newview->angle = r_viewmobj->angle;
|
||||
}
|
||||
else if (!player->spectator && chasecam)
|
||||
// use outside cam view
|
||||
{
|
||||
r_viewmobj = NULL;
|
||||
viewz = thiscam->z + (thiscam->height>>1);
|
||||
aimingangle = thiscam->aiming;
|
||||
viewangle = thiscam->angle;
|
||||
newview->z = thiscam->z + (thiscam->height>>1);
|
||||
newview->aim = thiscam->aiming;
|
||||
newview->angle = thiscam->angle;
|
||||
}
|
||||
else
|
||||
// use the player's eyes view
|
||||
{
|
||||
viewz = player->viewz;
|
||||
newview->z = player->viewz;
|
||||
|
||||
r_viewmobj = player->mo;
|
||||
I_Assert(r_viewmobj != NULL);
|
||||
|
||||
aimingangle = player->aiming;
|
||||
viewangle = r_viewmobj->angle;
|
||||
newview->aim = player->aiming;
|
||||
newview->angle = r_viewmobj->angle;
|
||||
|
||||
if (!demoplayback && player->playerstate != PST_DEAD)
|
||||
{
|
||||
if (player == &players[consoleplayer])
|
||||
{
|
||||
viewangle = localangle; // WARNING: camera uses this
|
||||
aimingangle = localaiming;
|
||||
newview->angle = localangle; // WARNING: camera uses this
|
||||
newview->aim = localaiming;
|
||||
}
|
||||
else if (player == &players[secondarydisplayplayer])
|
||||
{
|
||||
viewangle = localangle2;
|
||||
aimingangle = localaiming2;
|
||||
newview->angle = localangle2;
|
||||
newview->aim = localaiming2;
|
||||
}
|
||||
}
|
||||
}
|
||||
viewz += quake.z;
|
||||
newview->z += quake.z;
|
||||
|
||||
viewplayer = player;
|
||||
newview->player = player;
|
||||
|
||||
if (chasecam && !player->awayviewtics && !player->spectator)
|
||||
{
|
||||
viewx = thiscam->x;
|
||||
viewy = thiscam->y;
|
||||
viewx += quake.x;
|
||||
viewy += quake.y;
|
||||
newview->x = thiscam->x;
|
||||
newview->y = thiscam->y;
|
||||
newview->x += quake.x;
|
||||
newview->y += quake.y;
|
||||
|
||||
if (thiscam->subsector)
|
||||
viewsector = thiscam->subsector->sector;
|
||||
newview->sector = thiscam->subsector->sector;
|
||||
else
|
||||
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
||||
newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;
|
||||
}
|
||||
else
|
||||
{
|
||||
viewx = r_viewmobj->x;
|
||||
viewy = r_viewmobj->y;
|
||||
viewx += quake.x;
|
||||
viewy += quake.y;
|
||||
newview->x = r_viewmobj->x;
|
||||
newview->y = r_viewmobj->y;
|
||||
newview->x += quake.x;
|
||||
newview->y += quake.y;
|
||||
|
||||
if (r_viewmobj->subsector)
|
||||
viewsector = r_viewmobj->subsector->sector;
|
||||
newview->sector = r_viewmobj->subsector->sector;
|
||||
else
|
||||
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
||||
newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;
|
||||
}
|
||||
|
||||
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
// newview->sin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
// newview->cos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
|
||||
R_SetupFreelook(player, false);
|
||||
R_InterpolateView(cv_frameinterpolation.value == 1 ? rendertimefrac : FRACUNIT);
|
||||
}
|
||||
|
||||
void R_SkyboxFrame(player_t *player)
|
||||
|
@ -1232,11 +1210,18 @@ void R_SkyboxFrame(player_t *player)
|
|||
|
||||
if (splitscreen && player == &players[secondarydisplayplayer]
|
||||
&& player != &players[consoleplayer])
|
||||
{
|
||||
thiscam = &camera2;
|
||||
R_SetViewContext(VIEWCONTEXT_SKY2);
|
||||
}
|
||||
else
|
||||
{
|
||||
thiscam = &camera;
|
||||
R_SetViewContext(VIEWCONTEXT_SKY1);
|
||||
}
|
||||
|
||||
// cut-away view stuff
|
||||
newview->sky = true;
|
||||
r_viewmobj = skyboxmo[0];
|
||||
#ifdef PARANOIA
|
||||
if (!r_viewmobj)
|
||||
|
@ -1247,39 +1232,39 @@ void R_SkyboxFrame(player_t *player)
|
|||
#endif
|
||||
if (player->awayviewtics)
|
||||
{
|
||||
aimingangle = player->awayviewaiming;
|
||||
viewangle = player->awayviewmobj->angle;
|
||||
newview->aim = player->awayviewaiming;
|
||||
newview->angle = player->awayviewmobj->angle;
|
||||
}
|
||||
else if (thiscam->chase)
|
||||
{
|
||||
aimingangle = thiscam->aiming;
|
||||
viewangle = thiscam->angle;
|
||||
newview->aim = thiscam->aiming;
|
||||
newview->angle = thiscam->angle;
|
||||
}
|
||||
else
|
||||
{
|
||||
aimingangle = player->aiming;
|
||||
viewangle = player->mo->angle;
|
||||
newview->aim = player->aiming;
|
||||
newview->angle = player->mo->angle;
|
||||
if (!demoplayback && player->playerstate != PST_DEAD)
|
||||
{
|
||||
if (player == &players[consoleplayer])
|
||||
{
|
||||
viewangle = localangle; // WARNING: camera uses this
|
||||
aimingangle = localaiming;
|
||||
newview->angle = localangle; // WARNING: camera uses this
|
||||
newview->aim = localaiming;
|
||||
}
|
||||
else if (player == &players[secondarydisplayplayer])
|
||||
{
|
||||
viewangle = localangle2;
|
||||
aimingangle = localaiming2;
|
||||
newview->angle = localangle2;
|
||||
newview->aim = localaiming2;
|
||||
}
|
||||
}
|
||||
}
|
||||
viewangle += r_viewmobj->angle;
|
||||
newview->angle += r_viewmobj->angle;
|
||||
|
||||
viewplayer = player;
|
||||
newview->player = player;
|
||||
|
||||
viewx = r_viewmobj->x;
|
||||
viewy = r_viewmobj->y;
|
||||
viewz = r_viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle!
|
||||
newview->x = r_viewmobj->x;
|
||||
newview->y = r_viewmobj->y;
|
||||
newview->z = r_viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle!
|
||||
|
||||
if (mapheaderinfo[gamemap-1])
|
||||
{
|
||||
|
@ -1321,46 +1306,46 @@ void R_SkyboxFrame(player_t *player)
|
|||
|
||||
if (r_viewmobj->angle == 0)
|
||||
{
|
||||
viewx += x;
|
||||
viewy += y;
|
||||
newview->x += x;
|
||||
newview->y += y;
|
||||
}
|
||||
else if (r_viewmobj->angle == ANGLE_90)
|
||||
{
|
||||
viewx -= y;
|
||||
viewy += x;
|
||||
newview->x -= y;
|
||||
newview->y += x;
|
||||
}
|
||||
else if (r_viewmobj->angle == ANGLE_180)
|
||||
{
|
||||
viewx -= x;
|
||||
viewy -= y;
|
||||
newview->x -= x;
|
||||
newview->y -= y;
|
||||
}
|
||||
else if (r_viewmobj->angle == ANGLE_270)
|
||||
{
|
||||
viewx += y;
|
||||
viewy -= x;
|
||||
newview->x += y;
|
||||
newview->y -= x;
|
||||
}
|
||||
else
|
||||
{
|
||||
angle_t ang = r_viewmobj->angle>>ANGLETOFINESHIFT;
|
||||
viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
|
||||
viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang));
|
||||
newview->x += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
|
||||
newview->y += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang));
|
||||
}
|
||||
}
|
||||
if (mh->skybox_scalez > 0)
|
||||
viewz += campos.z / mh->skybox_scalez;
|
||||
newview->z += campos.z / mh->skybox_scalez;
|
||||
else if (mh->skybox_scalez < 0)
|
||||
viewz += campos.z * -mh->skybox_scalez;
|
||||
newview->z += campos.z * -mh->skybox_scalez;
|
||||
}
|
||||
|
||||
if (r_viewmobj->subsector)
|
||||
viewsector = r_viewmobj->subsector->sector;
|
||||
newview->sector = r_viewmobj->subsector->sector;
|
||||
else
|
||||
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
||||
newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;
|
||||
|
||||
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
// newview->sin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
// newview->cos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
|
||||
R_SetupFreelook(player, true);
|
||||
R_InterpolateView(cv_frameinterpolation.value == 1 ? rendertimefrac : FRACUNIT);
|
||||
}
|
||||
|
||||
boolean R_ViewpointHasChasecam(player_t *player)
|
||||
|
@ -1642,4 +1627,7 @@ void R_RegisterEngineStuff(void)
|
|||
CV_RegisterVar(&cv_maxportals);
|
||||
|
||||
CV_RegisterVar(&cv_movebob);
|
||||
|
||||
// Frame interpolation/uncapped
|
||||
CV_RegisterVar(&cv_frameinterpolation);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ extern fixed_t fovtan;
|
|||
|
||||
extern size_t validcount, linecount, loopcount, framecount;
|
||||
|
||||
extern fixed_t rendertimefrac;
|
||||
|
||||
//
|
||||
// Lighting LUT.
|
||||
// Used for z-depth cuing per column/row,
|
||||
|
@ -114,6 +116,10 @@ extern consvar_t cv_fov;
|
|||
extern consvar_t cv_skybox;
|
||||
extern consvar_t cv_tailspickup;
|
||||
|
||||
// Frame interpolation (uncapped framerate)
|
||||
extern tic_t prev_tics;
|
||||
extern consvar_t cv_frameinterpolation;
|
||||
|
||||
// Called by startup code.
|
||||
void R_Init(void);
|
||||
|
||||
|
|
|
@ -1480,9 +1480,34 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
INT32 rollangle = 0;
|
||||
#endif
|
||||
|
||||
// uncapped/interpolation
|
||||
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;
|
||||
|
||||
// do interpolation
|
||||
if (cv_frameinterpolation.value == 1 && !paused)
|
||||
{
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
interpangle = thing->angle;
|
||||
}
|
||||
}
|
||||
|
||||
// transform the origin point
|
||||
tr_x = thing->x - viewx;
|
||||
tr_y = thing->y - viewy;
|
||||
tr_x = interpx - viewx;
|
||||
tr_y = interpy - viewy;
|
||||
|
||||
basetz = tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance
|
||||
|
||||
|
@ -1559,7 +1584,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (sprframe->rotate != SRF_SINGLE || papersprite)
|
||||
{
|
||||
ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle);
|
||||
ang = R_PointToAngle (interpx, interpy) - interpangle;
|
||||
if (mirrored)
|
||||
ang = InvAngle(ang);
|
||||
}
|
||||
|
@ -1574,7 +1599,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
else
|
||||
{
|
||||
// choose a different rotation based on player view
|
||||
//ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
|
||||
//ang = R_PointToAngle (interpx, interpy) - interpangle;
|
||||
|
||||
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
|
||||
rot = 6; // F7 slot
|
||||
|
@ -1791,12 +1816,17 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
fixed_t linkscale;
|
||||
|
||||
thing = thing->tracer;
|
||||
if (cv_frameinterpolation.value == 1 && !paused)
|
||||
{
|
||||
interpx = thing->old_x + FixedMul(thing->x - thing->old_x, rendertimefrac);
|
||||
interpy = thing->old_y + FixedMul(thing->y - thing->old_y, rendertimefrac);
|
||||
}
|
||||
|
||||
if (! R_ThingVisible(thing))
|
||||
return;
|
||||
|
||||
tr_x = (thing->x + sort_x) - viewx;
|
||||
tr_y = (thing->y + sort_y) - viewy;
|
||||
tr_x = (interpx + sort_x) - viewx;
|
||||
tr_y = (interpy + sort_y) - viewy;
|
||||
tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
|
||||
linkscale = FixedDiv(projectiony, tz);
|
||||
|
||||
|
@ -1832,7 +1862,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if (x2 < portalclipstart || x1 >= portalclipend)
|
||||
return;
|
||||
|
||||
if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0)
|
||||
if (P_PointOnLineSide(interpx, interpy, portalclipline) != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1921,12 +1951,12 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
// When vertical flipped, draw sprites from the top down, at least as far as offsets are concerned.
|
||||
// sprite height - sprite topoffset is the proper inverse of the vertical offset, of course.
|
||||
// remember gz and gzt should be seperated by sprite height, not thing height - thing height can be shorter than the sprite itself sometimes!
|
||||
gz = oldthing->z + oldthing->height - FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale));
|
||||
gz = interpz + oldthing->height - FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale));
|
||||
gzt = gz + FixedMul(spr_height, FixedMul(spriteyscale, this_scale));
|
||||
}
|
||||
else
|
||||
{
|
||||
gzt = oldthing->z + FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale));
|
||||
gzt = interpz + FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale));
|
||||
gz = gzt - FixedMul(spr_height, FixedMul(spriteyscale, this_scale));
|
||||
}
|
||||
}
|
||||
|
@ -1945,7 +1975,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
// R_GetPlaneLight won't work on sloped lights!
|
||||
for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) {
|
||||
fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], thing->x, thing->y);
|
||||
fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], interpx, interpy);
|
||||
if (h <= top) {
|
||||
light = lightnum - 1;
|
||||
break;
|
||||
|
@ -1995,12 +2025,12 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
vis->sortscale = sortscale;
|
||||
vis->sortsplat = sortsplat;
|
||||
vis->dispoffset = dispoffset; // Monster Iestyn: 23/11/15
|
||||
vis->gx = thing->x;
|
||||
vis->gy = thing->y;
|
||||
vis->gx = interpx;
|
||||
vis->gy = interpy;
|
||||
vis->gz = gz;
|
||||
vis->gzt = gzt;
|
||||
vis->thingheight = thing->height;
|
||||
vis->pz = thing->z;
|
||||
vis->pz = interpz;
|
||||
vis->pzt = vis->pz + vis->thingheight;
|
||||
vis->texturemid = FixedDiv(gzt - viewz, spriteyscale);
|
||||
vis->scalestep = scalestep;
|
||||
|
@ -2139,9 +2169,22 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
//SoM: 3/17/2000
|
||||
fixed_t gz, gzt;
|
||||
|
||||
// uncapped/interpolation
|
||||
fixed_t interpx = thing->x;
|
||||
fixed_t interpy = thing->y;
|
||||
fixed_t interpz = thing->z;
|
||||
|
||||
// do interpolation
|
||||
if (cv_frameinterpolation.value == 1 && !paused)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
// transform the origin point
|
||||
tr_x = thing->x - viewx;
|
||||
tr_y = thing->y - viewy;
|
||||
tr_x = interpx - viewx;
|
||||
tr_y = interpy - viewy;
|
||||
|
||||
tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance
|
||||
|
||||
|
@ -2205,13 +2248,13 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
if (x2 < portalclipstart || x1 >= portalclipend)
|
||||
return;
|
||||
|
||||
if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0)
|
||||
if (P_PointOnLineSide(interpx, interpy, portalclipline) != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//SoM: 3/17/2000: Disregard sprites that are out of view..
|
||||
gzt = thing->z + spritecachedinfo[lump].topoffset;
|
||||
gzt = interpz + spritecachedinfo[lump].topoffset;
|
||||
gz = gzt - spritecachedinfo[lump].height;
|
||||
|
||||
if (thing->subsector->sector->cullheight)
|
||||
|
@ -2224,12 +2267,12 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
vis = R_NewVisSprite();
|
||||
vis->scale = vis->sortscale = yscale; //<<detailshift;
|
||||
vis->dispoffset = 0; // Monster Iestyn: 23/11/15
|
||||
vis->gx = thing->x;
|
||||
vis->gy = thing->y;
|
||||
vis->gx = interpx;
|
||||
vis->gy = interpy;
|
||||
vis->gz = gz;
|
||||
vis->gzt = gzt;
|
||||
vis->thingheight = 4*FRACUNIT;
|
||||
vis->pz = thing->z;
|
||||
vis->pz = interpz;
|
||||
vis->pzt = vis->pz + vis->thingheight;
|
||||
vis->texturemid = vis->gzt - viewz;
|
||||
vis->scalestep = 0;
|
||||
|
|
|
@ -185,7 +185,7 @@ static char returnWadPath[256];
|
|||
|
||||
#include "../m_argv.h"
|
||||
|
||||
#include "../m_menu.h"
|
||||
#include "../r_main.h" // Frame interpolation/uncapped
|
||||
|
||||
#ifdef MAC_ALERT
|
||||
#include "macosx/mac_alert.h"
|
||||
|
@ -2144,17 +2144,27 @@ static Uint64 timer_frequency;
|
|||
|
||||
static double tic_frequency;
|
||||
static Uint64 tic_epoch;
|
||||
static double elapsed_tics;
|
||||
|
||||
static void UpdateElapsedTics(void)
|
||||
{
|
||||
const Uint64 now = SDL_GetPerformanceCounter();
|
||||
|
||||
elapsed_tics += (now - tic_epoch) / tic_frequency;
|
||||
tic_epoch = now; // moving epoch
|
||||
}
|
||||
|
||||
tic_t I_GetTime(void)
|
||||
{
|
||||
static double elapsed;
|
||||
UpdateElapsedTics();
|
||||
return (tic_t) floor(elapsed_tics);
|
||||
}
|
||||
|
||||
const Uint64 now = SDL_GetPerformanceCounter();
|
||||
|
||||
elapsed += (now - tic_epoch) / tic_frequency;
|
||||
tic_epoch = now; // moving epoch
|
||||
|
||||
return (tic_t)elapsed;
|
||||
fixed_t I_GetTimeFrac(void)
|
||||
{
|
||||
UpdateElapsedTics();
|
||||
|
||||
return FLOAT_TO_FIXED((float) (elapsed_tics - floor(elapsed_tics)));
|
||||
}
|
||||
|
||||
precise_t I_GetPreciseTime(void)
|
||||
|
@ -2182,6 +2192,7 @@ void I_StartupTimer(void)
|
|||
tic_epoch = SDL_GetPerformanceCounter();
|
||||
|
||||
tic_frequency = timer_frequency / (double)NEWTICRATE;
|
||||
elapsed_tics = 0.0;
|
||||
}
|
||||
|
||||
void I_Sleep(void)
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "../d_main.h"
|
||||
|
||||
#include "../m_argv.h"
|
||||
#include "../m_fixed.h"
|
||||
|
||||
#include "../w_wad.h"
|
||||
#include "../z_zone.h"
|
||||
|
@ -261,6 +262,11 @@ tic_t I_GetTime(void)
|
|||
return newtics;
|
||||
}
|
||||
|
||||
fixed_t I_GetTimeFrac(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void I_Sleep(void)
|
||||
{
|
||||
if (cv_sleep.value != -1)
|
||||
|
|
Loading…
Reference in a new issue