Merge branch 'uncapped' into 'master'

Eidolon's interpolation

See merge request KartKrew/Kart!468
This commit is contained in:
Sal 2021-11-30 02:28:38 +00:00
commit 7f8a9dc4e5
34 changed files with 926 additions and 280 deletions

View file

@ -162,7 +162,7 @@ ifdef DEBUGMODE
ifdef GCC48 ifdef GCC48
opts+=-Og opts+=-Og
else else
opts+=O0 opts+=-O0
endif endif
endif endif

View file

@ -56,6 +56,7 @@ tables.c
r_bsp.c r_bsp.c
r_data.c r_data.c
r_draw.c r_draw.c
r_fps.c
r_main.c r_main.c
r_plane.c r_plane.c
r_segs.c r_segs.c

View file

@ -88,6 +88,12 @@ tic_t I_GetTime(void)
return (since_start*TICRATE)/1000000; return (since_start*TICRATE)/1000000;
} }
fixed_t I_GetTimeFrac(void)
{
//stub
return 0;
}
void I_Sleep(void){} void I_Sleep(void){}
void I_GetEvent(void){} void I_GetEvent(void){}

View file

@ -5264,12 +5264,14 @@ void TryRunTics(tic_t realtics)
if (neededtic > gametic) if (neededtic > gametic)
{ {
hu_stopped = false; if (realtics)
hu_stopped = false;
} }
if (player_joining) if (player_joining)
{ {
hu_stopped = true; if (realtics)
hu_stopped = true;
return; return;
} }
@ -5288,6 +5290,7 @@ void TryRunTics(tic_t realtics)
while (neededtic > gametic) while (neededtic > gametic)
{ {
DEBFILE(va("============ Running tic %d (local %d)\n", gametic, localgametic)); DEBFILE(va("============ Running tic %d (local %d)\n", gametic, localgametic));
prev_tics = I_GetTime();
ps_tictime = I_GetPreciseTime(); ps_tictime = I_GetPreciseTime();
@ -5306,7 +5309,8 @@ void TryRunTics(tic_t realtics)
} }
else else
{ {
hu_stopped = true; if (realtics)
hu_stopped = true;
} }
} }

View file

@ -63,6 +63,7 @@
#include "deh_tables.h" // Dehacked list test #include "deh_tables.h" // Dehacked list test
#include "m_cond.h" // condition initialization #include "m_cond.h" // condition initialization
#include "fastcmp.h" #include "fastcmp.h"
#include "r_fps.h" // Frame interpolation/uncapped
#include "keys.h" #include "keys.h"
#include "filesrch.h" // refreshdirmenu #include "filesrch.h" // refreshdirmenu
#include "g_input.h" // tutorial mode control scheming #include "g_input.h" // tutorial mode control scheming
@ -755,7 +756,7 @@ void D_SRB2Loop(void)
debugload--; debugload--;
#endif #endif
if (!realtics && !singletics) if (!realtics && !singletics && cv_frameinterpolation.value != 1)
{ {
I_Sleep(); I_Sleep();
continue; continue;
@ -773,13 +774,37 @@ void D_SRB2Loop(void)
// process tics (but maybe not if realtic == 0) // process tics (but maybe not if realtic == 0)
TryRunTics(realtics); TryRunTics(realtics);
if (cv_frameinterpolation.value == 1)
{
fixed_t entertimefrac = I_GetTimeFrac();
// renderdeltatics is a bit awkard to evaluate, since the system time interface is whole tic-based
renderdeltatics = realtics * FRACUNIT;
if (entertimefrac > rendertimefrac)
renderdeltatics += entertimefrac - rendertimefrac;
else
renderdeltatics -= rendertimefrac - entertimefrac;
rendertimefrac = entertimefrac;
}
else
{
rendertimefrac = FRACUNIT;
renderdeltatics = realtics * FRACUNIT;
}
if (cv_frameinterpolation.value == 1)
{
D_Display();
}
if (lastdraw || singletics || gametic > rendergametic) if (lastdraw || singletics || gametic > rendergametic)
{ {
rendergametic = gametic; rendergametic = gametic;
rendertimeout = entertic+TICRATE/17; rendertimeout = entertic+TICRATE/17;
// Update display, next frame, with current state. // 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) if (moviemode)
M_SaveFrame(); M_SaveFrame();
@ -788,7 +813,22 @@ void D_SRB2Loop(void)
} }
else if (rendertimeout < entertic) // in case the server hang or netsplit else if (rendertimeout < entertic) // in case the server hang or netsplit
{ {
D_Display(); #if 0
// 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;
if (moviemode) if (moviemode)
M_SaveFrame(); M_SaveFrame();
@ -1639,6 +1679,8 @@ void D_SRB2Main(void)
// as having been modified for the first game. // as having been modified for the first game.
M_PushSpecialParameters(); // push all "+" parameter at the command buffer M_PushSpecialParameters(); // push all "+" parameter at the command buffer
COM_BufExecute(); // ensure the command buffer gets executed before the map starts (+skin)
strncpy(connectedservername, cv_servername.string, MAXSERVERNAME); strncpy(connectedservername, cv_servername.string, MAXSERVERNAME);
if (M_CheckParm("-gametype") && M_IsNextParm()) if (M_CheckParm("-gametype") && M_IsNextParm())

View file

@ -16,7 +16,7 @@ tic_t I_GetTime(void)
return 0; return 0;
} }
int I_GetTimeMicros(void) fixed_t I_GetTimeFrac(void)
{ {
return 0; return 0;
} }

View file

@ -1580,7 +1580,7 @@ void G_ReadMetalTic(mobj_t *metal)
oldmetal.x = READFIXED(metal_p); oldmetal.x = READFIXED(metal_p);
oldmetal.y = READFIXED(metal_p); oldmetal.y = READFIXED(metal_p);
oldmetal.z = READFIXED(metal_p); oldmetal.z = READFIXED(metal_p);
P_TeleportMove(metal, oldmetal.x, oldmetal.y, oldmetal.z); P_MoveOrigin(metal, oldmetal.x, oldmetal.y, oldmetal.z);
oldmetal.x = metal->x; oldmetal.x = metal->x;
oldmetal.y = metal->y; oldmetal.y = metal->y;
oldmetal.z = metal->z; oldmetal.z = metal->z;

View file

@ -45,8 +45,8 @@
#include "y_inter.h" #include "y_inter.h"
#include "v_video.h" #include "v_video.h"
#include "lua_hook.h" #include "lua_hook.h"
#include "k_bot.h"
#include "m_cond.h" // condition sets #include "m_cond.h" // condition sets
#include "r_fps.h" // frame interpolation/uncapped
#include "lua_hud.h" #include "lua_hud.h"
// SRB2kart // SRB2kart
@ -56,6 +56,7 @@
#include "k_color.h" #include "k_color.h"
#include "k_respawn.h" #include "k_respawn.h"
#include "k_grandprix.h" #include "k_grandprix.h"
#include "k_bot.h"
#include "doomstat.h" #include "doomstat.h"
#ifdef HAVE_DISCORDRPC #ifdef HAVE_DISCORDRPC
@ -1920,6 +1921,8 @@ void G_Ticker(boolean run)
F_TextPromptTicker(); F_TextPromptTicker();
AM_Ticker(); AM_Ticker();
HU_Ticker(); HU_Ticker();
R_UpdateViewInterpolation();
break; break;
case GS_INTERMISSION: case GS_INTERMISSION:
@ -1976,7 +1979,12 @@ void G_Ticker(boolean run)
break; break;
case GS_TITLESCREEN: case GS_TITLESCREEN:
if (titlemapinaction) P_Ticker(run); if (titlemapinaction)
{
P_Ticker(run);
R_UpdateViewInterpolation();
}
F_TitleScreenTicker(run); F_TitleScreenTicker(run);
break; break;

View file

@ -38,6 +38,7 @@
#include "../m_cheat.h" #include "../m_cheat.h"
#include "../f_finale.h" #include "../f_finale.h"
#include "../r_things.h" // R_GetShadowZ #include "../r_things.h" // R_GetShadowZ
#include "../d_main.h"
#include "../p_slopes.h" #include "../p_slopes.h"
#include "hw_md2.h" #include "hw_md2.h"
@ -3623,10 +3624,6 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v
static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
{ {
fixed_t thingxpos = thing->x + thing->sprxoff;
fixed_t thingypos = thing->y + thing->spryoff;
fixed_t thingzpos = thing->z + thing->sprzoff;
patch_t *gpatch; patch_t *gpatch;
FOutVector shadowVerts[4]; FOutVector shadowVerts[4];
FSurfaceInfo sSurf; FSurfaceInfo sSurf;
@ -3643,7 +3640,19 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
fixed_t slopez; fixed_t slopez;
pslope_t *groundslope; pslope_t *groundslope;
// hitlag vibrating 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);
}
// hitlag vibrating (todo: interp somehow?)
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG)) if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
{ {
fixed_t mul = thing->hitlag * (FRACUNIT / 10); fixed_t mul = thing->hitlag * (FRACUNIT / 10);
@ -3653,14 +3662,19 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
mul = -mul; mul = -mul;
} }
thingxpos += FixedMul(thing->momx, mul); interpx += FixedMul(thing->momx, mul);
thingypos += FixedMul(thing->momy, mul); interpy += FixedMul(thing->momy, mul);
thingzpos += FixedMul(thing->momz, mul); interpz += FixedMul(thing->momz, mul);
} }
// sprite offset
interpx += thing->sprxoff;
interpy += thing->spryoff;
interpz += thing->sprzoff;
groundz = R_GetShadowZ(thing, &groundslope); groundz = R_GetShadowZ(thing, &groundslope);
floordiff = abs((flip < 0 ? thing->height : 0) + thingzpos - groundz); floordiff = abs((flip < 0 ? thing->height : 0) + interpz - groundz);
alpha = floordiff / (4*FRACUNIT) + 75; alpha = floordiff / (4*FRACUNIT) + 75;
if (alpha >= 255) return; if (alpha >= 255) return;
@ -3674,8 +3688,8 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height); scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height);
fscale = FIXED_TO_FLOAT(scalemul); fscale = FIXED_TO_FLOAT(scalemul);
fx = FIXED_TO_FLOAT(thingxpos); fx = FIXED_TO_FLOAT(interpx);
fy = FIXED_TO_FLOAT(thingypos); fy = FIXED_TO_FLOAT(interpy);
// 3--2 // 3--2
// | /| // | /|
@ -5013,10 +5027,6 @@ static void HWR_AddSprites(sector_t *sec)
// BP why not use xtoviexangle/viewangletox like in bsp ?.... // BP why not use xtoviexangle/viewangletox like in bsp ?....
static void HWR_ProjectSprite(mobj_t *thing) static void HWR_ProjectSprite(mobj_t *thing)
{ {
fixed_t thingxpos = thing->x + thing->sprxoff;
fixed_t thingypos = thing->y + thing->spryoff;
fixed_t thingzpos = thing->z + thing->sprzoff;
gl_vissprite_t *vis; gl_vissprite_t *vis;
float tr_x, tr_y; float tr_x, tr_y;
float tz; float tz;
@ -5056,13 +5066,34 @@ static void HWR_ProjectSprite(mobj_t *thing)
angle_t spriterotangle = 0; angle_t spriterotangle = 0;
#endif #endif
// uncapped/interpolation
fixed_t interpx;
fixed_t interpy;
fixed_t interpz;
angle_t interpangle;
if (!thing) if (!thing)
return; return;
if (thing->spritexscale < 1 || thing->spriteyscale < 1) if (thing->spritexscale < 1 || thing->spriteyscale < 1)
return; return;
// hitlag vibrating 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;
}
// hitlag vibrating (todo: interp somehow?)
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG)) if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
{ {
fixed_t mul = thing->hitlag * (FRACUNIT / 10); fixed_t mul = thing->hitlag * (FRACUNIT / 10);
@ -5072,20 +5103,23 @@ static void HWR_ProjectSprite(mobj_t *thing)
mul = -mul; mul = -mul;
} }
thingxpos += FixedMul(thing->momx, mul); interpx += FixedMul(thing->momx, mul);
thingypos += FixedMul(thing->momy, mul); interpy += FixedMul(thing->momy, mul);
thingzpos += FixedMul(thing->momz, mul); interpz += FixedMul(thing->momz, mul);
} }
dispoffset = thing->info->dispoffset; // sprite offset
interpx += thing->sprxoff;
interpy += thing->spryoff;
interpz += thing->sprzoff;
this_scale = FIXED_TO_FLOAT(thing->scale); this_scale = FIXED_TO_FLOAT(thing->scale);
spritexscale = FIXED_TO_FLOAT(thing->spritexscale); spritexscale = FIXED_TO_FLOAT(thing->spritexscale);
spriteyscale = FIXED_TO_FLOAT(thing->spriteyscale); spriteyscale = FIXED_TO_FLOAT(thing->spriteyscale);
// transform the origin point // transform the origin point
tr_x = FIXED_TO_FLOAT(thingxpos) - gl_viewx; tr_x = FIXED_TO_FLOAT(interpx) - gl_viewx;
tr_y = FIXED_TO_FLOAT(thingypos) - gl_viewy; tr_y = FIXED_TO_FLOAT(interpy) - gl_viewy;
// rotation around vertical axis // rotation around vertical axis
tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin); tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin);
@ -5108,8 +5142,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
} }
// The above can stay as it works for cutting sprites that are too close // The above can stay as it works for cutting sprites that are too close
tr_x = FIXED_TO_FLOAT(thingxpos); tr_x = FIXED_TO_FLOAT(interpx);
tr_y = FIXED_TO_FLOAT(thingypos); tr_y = FIXED_TO_FLOAT(interpy);
// decide which patch to use for sprite relative to player // decide which patch to use for sprite relative to player
#ifdef RANGECHECK #ifdef RANGECHECK
@ -5157,7 +5191,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
I_Error("sprframes NULL for sprite %d\n", thing->sprite); I_Error("sprframes NULL for sprite %d\n", thing->sprite);
#endif #endif
ang = R_PointToAngle (thingxpos, thingypos) - mobjangle; ang = R_PointToAngle (interpx, interpy) - interpangle;
if (mirrored) if (mirrored)
ang = InvAngle(ang); ang = InvAngle(ang);
@ -5304,12 +5338,12 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (vflip) if (vflip)
{ {
gz = FIXED_TO_FLOAT(thingzpos + 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); gzt = gz + (FIXED_TO_FLOAT(spr_height) * this_yscale);
} }
else else
{ {
gzt = FIXED_TO_FLOAT(thingzpos) + (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); gz = gzt - (FIXED_TO_FLOAT(spr_height) * this_yscale);
} }
@ -5320,7 +5354,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
} }
heightsec = thing->subsector->sector->heightsec; heightsec = thing->subsector->sector->heightsec;
if (viewplayer->mo && viewplayer->mo->subsector) if (viewplayer && viewplayer->mo && viewplayer->mo->subsector)
phs = viewplayer->mo->subsector->sector->heightsec; phs = viewplayer->mo->subsector->sector->heightsec;
else else
phs = -1; phs = -1;
@ -5328,12 +5362,12 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (heightsec != -1 && phs != -1) // only clip things which are in special sectors if (heightsec != -1 && phs != -1) // only clip things which are in special sectors
{ {
if (gl_viewz < FIXED_TO_FLOAT(sectors[phs].floorheight) ? if (gl_viewz < FIXED_TO_FLOAT(sectors[phs].floorheight) ?
FIXED_TO_FLOAT(thingzpos) >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) : FIXED_TO_FLOAT(interpz) >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) :
gzt < FIXED_TO_FLOAT(sectors[heightsec].floorheight)) gzt < FIXED_TO_FLOAT(sectors[heightsec].floorheight))
return; return;
if (gl_viewz > FIXED_TO_FLOAT(sectors[phs].ceilingheight) ? if (gl_viewz > FIXED_TO_FLOAT(sectors[phs].ceilingheight) ?
gzt < FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) && gl_viewz >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) : gzt < FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) && gl_viewz >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) :
FIXED_TO_FLOAT(thingzpos) >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight)) FIXED_TO_FLOAT(interpz) >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight))
return; return;
} }
@ -5468,9 +5502,29 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
unsigned rot = 0; unsigned rot = 0;
UINT8 flip; UINT8 flip;
// uncapped/interpolation
fixed_t interpx;
fixed_t interpy;
fixed_t interpz;
if (!thing)
return;
interpx = thing->x;
interpy = thing->y;
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 // transform the origin point
tr_x = FIXED_TO_FLOAT(thing->x) - gl_viewx; tr_x = FIXED_TO_FLOAT(interpx) - gl_viewx;
tr_y = FIXED_TO_FLOAT(thing->y) - gl_viewy; tr_y = FIXED_TO_FLOAT(interpy) - gl_viewy;
// rotation around vertical axis // rotation around vertical axis
tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin); tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin);
@ -5479,8 +5533,8 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
if (tz < ZCLIP_PLANE) if (tz < ZCLIP_PLANE)
return; return;
tr_x = FIXED_TO_FLOAT(thing->x); tr_x = FIXED_TO_FLOAT(interpx);
tr_y = FIXED_TO_FLOAT(thing->y); tr_y = FIXED_TO_FLOAT(interpy);
// decide which patch to use for sprite relative to player // decide which patch to use for sprite relative to player
if ((unsigned)thing->sprite >= numsprites) if ((unsigned)thing->sprite >= numsprites)
@ -5547,7 +5601,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
#endif #endif
// set top/bottom coords // 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->gz = vis->gzt - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].height);
vis->precip = true; vis->precip = true;
@ -6702,6 +6756,8 @@ void HWR_DoPostProcessor(player_t *player)
// 10 by 10 grid. 2 coordinates (xy) // 10 by 10 grid. 2 coordinates (xy)
float v[SCREENVERTS][SCREENVERTS][2]; float v[SCREENVERTS][SCREENVERTS][2];
static double disStart = 0; static double disStart = 0;
static fixed_t last_fractime = 0;
UINT8 x, y; UINT8 x, y;
INT32 WAVELENGTH; INT32 WAVELENGTH;
INT32 AMPLITUDE; INT32 AMPLITUDE;
@ -6733,6 +6789,15 @@ void HWR_DoPostProcessor(player_t *player)
HWD.pfnPostImgRedraw(v); HWD.pfnPostImgRedraw(v);
if (!(paused || P_AutoPause())) if (!(paused || P_AutoPause()))
disStart += 1; disStart += 1;
if (renderdeltatics > FRACUNIT)
{
disStart = disStart - FIXED_TO_FLOAT(last_fractime) + 1 + FIXED_TO_FLOAT(rendertimefrac);
}
else
{
disStart = disStart - FIXED_TO_FLOAT(last_fractime) + FIXED_TO_FLOAT(rendertimefrac);
}
last_fractime = rendertimefrac;
// Capture the screen again for screen waving on the intermission // Capture the screen again for screen waving on the intermission
if(gamestate != GS_INTERMISSION) if(gamestate != GS_INTERMISSION)

View file

@ -1355,10 +1355,6 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
// Look at HWR_ProjectSprite for more // Look at HWR_ProjectSprite for more
{ {
fixed_t thingxpos = spr->mobj->x + spr->mobj->sprxoff;
fixed_t thingypos = spr->mobj->y + spr->mobj->spryoff;
fixed_t thingzpos = spr->mobj->z + spr->mobj->sprzoff;
patch_t *gpatch, *blendgpatch; patch_t *gpatch, *blendgpatch;
GLPatch_t *hwrPatch = NULL, *hwrBlendPatch = NULL; GLPatch_t *hwrPatch = NULL, *hwrBlendPatch = NULL;
INT32 durs = spr->mobj->state->tics; INT32 durs = spr->mobj->state->tics;
@ -1371,6 +1367,18 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
INT32 mod; INT32 mod;
float finalscale; float finalscale;
fixed_t interpx = spr->mobj->x;
fixed_t interpy = spr->mobj->y;
fixed_t interpz = spr->mobj->z;
// do interpolation
if (cv_frameinterpolation.value == 1 && !paused)
{
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);
interpz = spr->mobj->old_z + FixedMul(rendertimefrac, spr->mobj->z - spr->mobj->old_z);
}
// hitlag vibrating // hitlag vibrating
if (spr->mobj->hitlag > 0 && (spr->mobj->eflags & MFE_DAMAGEHITLAG)) if (spr->mobj->hitlag > 0 && (spr->mobj->eflags & MFE_DAMAGEHITLAG))
{ {
@ -1381,11 +1389,16 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
mul = -mul; mul = -mul;
} }
thingxpos += FixedMul(spr->mobj->momx, mul); interpx += FixedMul(spr->mobj->momx, mul);
thingypos += FixedMul(spr->mobj->momy, mul); interpy += FixedMul(spr->mobj->momy, mul);
thingzpos += FixedMul(spr->mobj->momz, mul); interpy += FixedMul(spr->mobj->momz, mul);
} }
// sprite offset
interpx += spr->mobj->sprxoff;
interpy += spr->mobj->spryoff;
interpz += spr->mobj->sprzoff;
// Apparently people don't like jump frames like that, so back it goes // Apparently people don't like jump frames like that, so back it goes
//if (tics > durs) //if (tics > durs)
//durs = tics; //durs = tics;
@ -1605,13 +1618,13 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
#endif #endif
//Hurdler: it seems there is still a small problem with mobj angle //Hurdler: it seems there is still a small problem with mobj angle
p.x = FIXED_TO_FLOAT(thingxpos); p.x = FIXED_TO_FLOAT(interpx);
p.y = FIXED_TO_FLOAT(thingypos) + md2->offset; p.y = FIXED_TO_FLOAT(interpy) + md2->offset;
if (flip) if (flip)
p.z = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height); p.z = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height);
else else
p.z = FIXED_TO_FLOAT(thingzpos); p.z = FIXED_TO_FLOAT(interpz);
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
sprdef = &((skin_t *)spr->mobj->skin)->sprites[spr->mobj->sprite2]; sprdef = &((skin_t *)spr->mobj->skin)->sprites[spr->mobj->sprite2];
@ -1631,7 +1644,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
} }
else else
{ {
const fixed_t anglef = AngleFixed((R_PointToAngle(thingxpos, thingypos))-ANGLE_180); const fixed_t anglef = AngleFixed((R_PointToAngle(interpx, interpy))-ANGLE_180);
p.angley = FIXED_TO_FLOAT(anglef); p.angley = FIXED_TO_FLOAT(anglef);
} }

View file

@ -46,6 +46,10 @@ UINT32 I_GetFreeMem(UINT32 *total);
*/ */
tic_t I_GetTime(void); 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. /** \brief Returns precise time value for performance measurement.
*/ */
precise_t I_GetPreciseTime(void); precise_t I_GetPreciseTime(void);

View file

@ -9199,7 +9199,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // mass 0, // mass
0, // damage 0, // damage
sfx_None, // activesound sfx_None, // activesound
MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_NOTHINK|MF_DONTENCOREMAP, // flags MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags
S_NULL // raisestate S_NULL // raisestate
}, },

View file

@ -761,9 +761,14 @@ void K_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 du
if (lt_exitticker < length) if (lt_exitticker < length)
{ {
INT32 offset = screenwidth - ((lt_exitticker * screenwidth) / length);
boolean slidefromright = false; boolean slidefromright = false;
const INT32 offsetAmount = (screenwidth * FRACUNIT) / length;
fixed_t offset = (screenwidth * FRACUNIT) - (lt_exitticker * offsetAmount);
offset += FixedMul(offsetAmount, renderdeltatics);
offset /= FRACUNIT;
if (r_splitscreen > 1) if (r_splitscreen > 1)
{ {
if (stplyr == &players[displayplayers[1]] || stplyr == &players[displayplayers[3]]) if (stplyr == &players[displayplayers[1]] || stplyr == &players[displayplayers[3]])
@ -3041,6 +3046,7 @@ static void K_drawKartMinimap(void)
SINT8 numlocalplayers = 0; SINT8 numlocalplayers = 0;
INT32 hyu = hyudorotime; INT32 hyu = hyudorotime;
mobj_t *mobj, *next; // for SPB drawing (or any other item(s) we may wanna draw, I dunno!) mobj_t *mobj, *next; // for SPB drawing (or any other item(s) we may wanna draw, I dunno!)
fixed_t interpx, interpy;
// Draw the HUD only when playing in a level. // Draw the HUD only when playing in a level.
// hu_stuff needs this, unlike st_stuff. // hu_stuff needs this, unlike st_stuff.
@ -3135,7 +3141,17 @@ static void K_drawKartMinimap(void)
} }
else else
colormap = NULL; colormap = NULL;
K_drawKartMinimapIcon(g->mo->x, g->mo->y, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic);
interpx = g->mo->x;
interpy = g->mo->y;
if (cv_frameinterpolation.value == 1 && !paused)
{
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);
}
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic);
g = g->next; g = g->next;
} }
@ -3191,11 +3207,22 @@ static void K_drawKartMinimap(void)
else else
colormap = NULL; colormap = NULL;
K_drawKartMinimapIcon(players[i].mo->x, players[i].mo->y, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic); interpx = players[i].mo->x;
interpy = players[i].mo->y;
if (cv_frameinterpolation.value == 1 && !paused)
{
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);
}
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic);
// Target reticule // Target reticule
if ((gametype == GT_RACE && players[i].position == spbplace) if ((gametype == GT_RACE && players[i].position == spbplace)
|| (gametype == GT_BATTLE && K_IsPlayerWanted(&players[i]))) || (gametype == GT_BATTLE && K_IsPlayerWanted(&players[i])))
K_drawKartMinimapIcon(players[i].mo->x, players[i].mo->y, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic); {
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic);
}
} }
} }
@ -3215,7 +3242,16 @@ static void K_drawKartMinimap(void)
colormap = R_GetTranslationColormap(TC_RAINBOW, mobj->color, GTC_CACHE); colormap = R_GetTranslationColormap(TC_RAINBOW, mobj->color, GTC_CACHE);
} }
K_drawKartMinimapIcon(mobj->x, mobj->y, x, y, splitflags, kp_spbminimap, colormap, AutomapPic); interpx = mobj->x;
interpy = mobj->y;
if (cv_frameinterpolation.value == 1 && !paused)
{
interpx = mobj->old_x + FixedMul(rendertimefrac, mobj->x - mobj->old_x);
interpy = mobj->old_y + FixedMul(rendertimefrac, mobj->y - mobj->old_y);
}
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_spbminimap, colormap, AutomapPic);
} }
} }
@ -3243,12 +3279,23 @@ static void K_drawKartMinimap(void)
else else
colormap = NULL; colormap = NULL;
K_drawKartMinimapIcon(players[localplayers[i]].mo->x, players[localplayers[i]].mo->y, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic); interpx = players[localplayers[i]].mo->x;
interpy = players[localplayers[i]].mo->y;
if (cv_frameinterpolation.value == 1 && !paused)
{
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);
}
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic);
// Target reticule // Target reticule
if ((gametype == GT_RACE && players[localplayers[i]].position == spbplace) if ((gametype == GT_RACE && players[localplayers[i]].position == spbplace)
|| (gametype == GT_BATTLE && K_IsPlayerWanted(&players[localplayers[i]]))) || (gametype == GT_BATTLE && K_IsPlayerWanted(&players[localplayers[i]])))
K_drawKartMinimapIcon(players[localplayers[i]].mo->x, players[localplayers[i]].mo->y, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic); {
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic);
}
} }
} }
@ -3508,7 +3555,7 @@ static void K_drawKartFinish(void)
//else -- 1/2p, scrolling FINISH //else -- 1/2p, scrolling FINISH
{ {
INT32 x, xval; INT32 x, xval, ox, interpx;
if (r_splitscreen) // wide splitscreen if (r_splitscreen) // wide splitscreen
pnum += 4; pnum += 4;
@ -3516,11 +3563,14 @@ static void K_drawKartFinish(void)
x = ((vid.width<<FRACBITS)/vid.dupx); x = ((vid.width<<FRACBITS)/vid.dupx);
xval = (SHORT(kp_racefinish[pnum]->width)<<FRACBITS); xval = (SHORT(kp_racefinish[pnum]->width)<<FRACBITS);
x = ((TICRATE - stplyr->karthud[khud_cardanimation])*(xval > x ? xval : x))/TICRATE; x = ((TICRATE - stplyr->karthud[khud_cardanimation])*(xval > x ? xval : x))/TICRATE;
ox = ((TICRATE - (stplyr->karthud[khud_cardanimation] - 1))*(xval > x ? xval : x))/TICRATE;
interpx = ox + FixedMul(rendertimefrac, x - ox);
if (r_splitscreen && stplyr == &players[displayplayers[1]]) if (r_splitscreen && stplyr == &players[displayplayers[1]])
x = -x; interpx = -interpx;
V_DrawFixedPatch(x + (STCD_X<<FRACBITS) - (xval>>1), V_DrawFixedPatch(interpx + (STCD_X<<FRACBITS) - (xval>>1),
(STCD_Y<<FRACBITS) - (SHORT(kp_racefinish[pnum]->height)<<(FRACBITS-1)), (STCD_Y<<FRACBITS) - (SHORT(kp_racefinish[pnum]->height)<<(FRACBITS-1)),
FRACUNIT, FRACUNIT,
splitflags, kp_racefinish[pnum], NULL); splitflags, kp_racefinish[pnum], NULL);
@ -3909,33 +3959,63 @@ static void K_drawChallengerScreen(void)
static void K_drawLapStartAnim(void) static void K_drawLapStartAnim(void)
{ {
// This is an EVEN MORE insanely complicated animation. // This is an EVEN MORE insanely complicated animation.
const UINT8 progress = 80-stplyr->karthud[khud_lapanimation]; const UINT8 t = stplyr->karthud[khud_lapanimation];
const UINT8 progress = 80 - t;
const UINT8 tOld = t - 1;
const UINT8 progressOld = 80 - tOld;
const tic_t leveltimeOld = leveltime - 1;
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, stplyr->skincolor, GTC_CACHE); UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, stplyr->skincolor, GTC_CACHE);
V_DrawFixedPatch((BASEVIDWIDTH/2 + (32*max(0, stplyr->karthud[khud_lapanimation]-76)))*FRACUNIT, fixed_t interpx, interpy, newval, oldval;
(48 - (32*max(0, progress-76)))*FRACUNIT,
newval = (BASEVIDWIDTH/2 + (32 * max(0, t - 76))) * FRACUNIT;
oldval = (BASEVIDWIDTH/2 + (32 * max(0, tOld - 76))) * FRACUNIT;
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
newval = (48 - (32 * max(0, progress - 76))) * FRACUNIT;
oldval = (48 - (32 * max(0, progressOld - 76))) * FRACUNIT;
interpy = oldval + FixedMul(rendertimefrac, newval - oldval);
V_DrawFixedPatch(
interpx, interpy,
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
(modeattacking ? kp_lapanim_emblem[1] : kp_lapanim_emblem[0]), colormap); (modeattacking ? kp_lapanim_emblem[1] : kp_lapanim_emblem[0]), colormap);
if (stplyr->karthud[khud_laphand] >= 1 && stplyr->karthud[khud_laphand] <= 3) if (stplyr->karthud[khud_laphand] >= 1 && stplyr->karthud[khud_laphand] <= 3)
{ {
V_DrawFixedPatch((BASEVIDWIDTH/2 + (32*max(0, stplyr->karthud[khud_lapanimation]-76)))*FRACUNIT, newval = (4 - abs((signed)((leveltime % 8) - 4))) * FRACUNIT;
(48 - (32*max(0, progress-76)) oldval = (4 - abs((signed)((leveltimeOld % 8) - 4))) * FRACUNIT;
+ 4 - abs((signed)((leveltime % 8) - 4)))*FRACUNIT, interpy += oldval + FixedMul(rendertimefrac, newval - oldval);
V_DrawFixedPatch(
interpx, interpy,
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
kp_lapanim_hand[stplyr->karthud[khud_laphand]-1], NULL); kp_lapanim_hand[stplyr->karthud[khud_laphand]-1], NULL);
} }
if (stplyr->laps == (UINT8)(cv_numlaps.value)) if (stplyr->laps == (UINT8)(cv_numlaps.value))
{ {
V_DrawFixedPatch((62 - (32*max(0, progress-76)))*FRACUNIT, // 27 newval = (62 - (32 * max(0, progress - 76))) * FRACUNIT;
oldval = (62 - (32 * max(0, progressOld - 76))) * FRACUNIT;
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
V_DrawFixedPatch(
interpx, // 27
30*FRACUNIT, // 24 30*FRACUNIT, // 24
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
kp_lapanim_final[min(progress/2, 10)], NULL); kp_lapanim_final[min(progress/2, 10)], NULL);
if (progress/2-12 >= 0) if (progress/2-12 >= 0)
{ {
V_DrawFixedPatch((188 + (32*max(0, progress-76)))*FRACUNIT, // 194 newval = (188 + (32 * max(0, progress - 76))) * FRACUNIT;
oldval = (188 + (32 * max(0, progressOld - 76))) * FRACUNIT;
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
V_DrawFixedPatch(
interpx, // 194
30*FRACUNIT, // 24 30*FRACUNIT, // 24
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
kp_lapanim_lap[min(progress/2-12, 6)], NULL); kp_lapanim_lap[min(progress/2-12, 6)], NULL);
@ -3943,21 +4023,36 @@ static void K_drawLapStartAnim(void)
} }
else else
{ {
V_DrawFixedPatch((82 - (32*max(0, progress-76)))*FRACUNIT, // 61 newval = (82 - (32 * max(0, progress - 76))) * FRACUNIT;
oldval = (82 - (32 * max(0, progressOld - 76))) * FRACUNIT;
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
V_DrawFixedPatch(
interpx, // 61
30*FRACUNIT, // 24 30*FRACUNIT, // 24
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
kp_lapanim_lap[min(progress/2, 6)], NULL); kp_lapanim_lap[min(progress/2, 6)], NULL);
if (progress/2-8 >= 0) if (progress/2-8 >= 0)
{ {
V_DrawFixedPatch((188 + (32*max(0, progress-76)))*FRACUNIT, // 194 newval = (188 + (32 * max(0, progress - 76))) * FRACUNIT;
oldval = (188 + (32 * max(0, progressOld - 76))) * FRACUNIT;
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
V_DrawFixedPatch(
interpx, // 194
30*FRACUNIT, // 24 30*FRACUNIT, // 24
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
kp_lapanim_number[(((UINT32)stplyr->laps) / 10)][min(progress/2-8, 2)], NULL); kp_lapanim_number[(((UINT32)stplyr->laps) / 10)][min(progress/2-8, 2)], NULL);
if (progress/2-10 >= 0) if (progress/2-10 >= 0)
{ {
V_DrawFixedPatch((208 + (32*max(0, progress-76)))*FRACUNIT, // 221 newval = (208 + (32 * max(0, progress - 76))) * FRACUNIT;
oldval = (208 + (32 * max(0, progressOld - 76))) * FRACUNIT;
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
V_DrawFixedPatch(
interpx, // 221
30*FRACUNIT, // 24 30*FRACUNIT, // 24
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
kp_lapanim_number[(((UINT32)stplyr->laps) % 10)][min(progress/2-10, 2)], NULL); kp_lapanim_number[(((UINT32)stplyr->laps) % 10)][min(progress/2-10, 2)], NULL);

View file

@ -3754,7 +3754,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I
{ {
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn // floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
// This should set it for FOFs // This should set it for FOFs
P_TeleportMove(th, th->x, th->y, th->z); P_SetOrigin(th, th->x, th->y, th->z);
// spawn on the ground if the player is on the ground // spawn on the ground if the player is on the ground
if (P_MobjFlip(source) < 0) if (P_MobjFlip(source) < 0)
{ {
@ -4717,7 +4717,7 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing,
{ {
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn // floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
// This should set it for FOFs // This should set it for FOFs
P_TeleportMove(mo, mo->x, mo->y, mo->z); // however, THIS can fuck up your day. just absolutely ruin you. P_SetOrigin(mo, mo->x, mo->y, mo->z); // however, THIS can fuck up your day. just absolutely ruin you.
if (P_MobjWasRemoved(mo)) if (P_MobjWasRemoved(mo))
return NULL; return NULL;
@ -5347,7 +5347,7 @@ void K_DropHnextList(player_t *player, boolean keepshields)
{ {
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn // floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
// This should set it for FOFs // This should set it for FOFs
//P_TeleportMove(dropwork, dropwork->x, dropwork->y, dropwork->z); -- handled better by above floorz/ceilingz passing //P_SetOrigin(dropwork, dropwork->x, dropwork->y, dropwork->z); -- handled better by above floorz/ceilingz passing
if (flip == 1) if (flip == 1)
{ {
@ -5873,7 +5873,7 @@ static void K_MoveHeldObjects(player_t *player)
z = player->mo->z + player->mo->height - cur->height; z = player->mo->z + player->mo->height - cur->height;
cur->flags |= MF_NOCLIPTHING; // temporarily make them noclip other objects so they can't hit anyone while in the player cur->flags |= MF_NOCLIPTHING; // temporarily make them noclip other objects so they can't hit anyone while in the player
P_TeleportMove(cur, player->mo->x, player->mo->y, z); P_MoveOrigin(cur, player->mo->x, player->mo->y, z);
cur->momx = FixedMul(FINECOSINE(cur->angle>>ANGLETOFINESHIFT), cur->extravalue1); cur->momx = FixedMul(FINECOSINE(cur->angle>>ANGLETOFINESHIFT), cur->extravalue1);
cur->momy = FixedMul(FINESINE(cur->angle>>ANGLETOFINESHIFT), cur->extravalue1); cur->momy = FixedMul(FINESINE(cur->angle>>ANGLETOFINESHIFT), cur->extravalue1);
cur->flags &= ~MF_NOCLIPTHING; cur->flags &= ~MF_NOCLIPTHING;
@ -5986,7 +5986,7 @@ static void K_MoveHeldObjects(player_t *player)
P_SetObjectMomZ(cur, FixedMul(targz - cur->z, 7*FRACUNIT/8) - gravity, false); P_SetObjectMomZ(cur, FixedMul(targz - cur->z, 7*FRACUNIT/8) - gravity, false);
if (R_PointToDist2(cur->x, cur->y, targx, targy) > 768*FRACUNIT) if (R_PointToDist2(cur->x, cur->y, targx, targy) > 768*FRACUNIT)
P_TeleportMove(cur, targx, targy, cur->z); P_MoveOrigin(cur, targx, targy, cur->z);
if (P_IsObjectOnGround(cur)) if (P_IsObjectOnGround(cur))
{ {
@ -6076,12 +6076,12 @@ static void K_MoveHeldObjects(player_t *player)
diffy = targy - cur->y; diffy = targy - cur->y;
diffz = targz - cur->z; diffz = targz - cur->z;
P_TeleportMove(cur->tracer, cur->tracer->x + diffx + P_ReturnThrustX(cur, cur->angle + angoffset, 6*cur->scale), P_MoveOrigin(cur->tracer, cur->tracer->x + diffx + P_ReturnThrustX(cur, cur->angle + angoffset, 6*cur->scale),
cur->tracer->y + diffy + P_ReturnThrustY(cur, cur->angle + angoffset, 6*cur->scale), cur->tracer->z + diffz); cur->tracer->y + diffy + P_ReturnThrustY(cur, cur->angle + angoffset, 6*cur->scale), cur->tracer->z + diffz);
P_SetScale(cur->tracer, (cur->tracer->destscale = 3*cur->scale/4)); P_SetScale(cur->tracer, (cur->tracer->destscale = 3*cur->scale/4));
} }
P_TeleportMove(cur, targx, targy, targz); P_MoveOrigin(cur, targx, targy, targz);
K_FlipFromObject(cur, player->mo); // Update graviflip in real time thanks. K_FlipFromObject(cur, player->mo); // Update graviflip in real time thanks.
cur->roll = player->mo->roll; cur->roll = player->mo->roll;
@ -8480,7 +8480,12 @@ static void K_trickPanelTimingVisual(player_t *player, fixed_t momz)
flame->frame = i|FF_FULLBRIGHT; flame->frame = i|FF_FULLBRIGHT;
if (player->trickpanel <= 1 && !player->tumbleBounces) if (player->trickpanel <= 1 && !player->tumbleBounces)
{
flame->tics = 2; flame->tics = 2;
flame->momx = player->mo->momx;
flame->momy = player->mo->momy;
flame->momz = player->mo->momz;
}
else else
{ {
flame->tics = TICRATE; flame->tics = TICRATE;

View file

@ -1415,7 +1415,42 @@ static int lib_pTeleportMove(lua_State *L)
INLEVEL INLEVEL
if (!thing) if (!thing)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, P_TeleportMove(thing, x, y, z)); LUA_Deprecated(L, "P_TeleportMove", "P_SetOrigin or P_MoveOrigin");
lua_pushboolean(L, P_SetOrigin(thing, x, y, z));
LUA_PushUserdata(L, tmthing, META_MOBJ);
P_SetTarget(&tmthing, ptmthing);
return 2;
}
static int lib_pSetOrigin(lua_State *L)
{
mobj_t *ptmthing = tmthing;
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t x = luaL_checkfixed(L, 2);
fixed_t y = luaL_checkfixed(L, 3);
fixed_t z = luaL_checkfixed(L, 4);
NOHUD
INLEVEL
if (!thing)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, P_SetOrigin(thing, x, y, z));
LUA_PushUserdata(L, tmthing, META_MOBJ);
P_SetTarget(&tmthing, ptmthing);
return 2;
}
static int lib_pMoveOrigin(lua_State *L)
{
mobj_t *ptmthing = tmthing;
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t x = luaL_checkfixed(L, 2);
fixed_t y = luaL_checkfixed(L, 3);
fixed_t z = luaL_checkfixed(L, 4);
NOHUD
INLEVEL
if (!thing)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, P_MoveOrigin(thing, x, y, z));
LUA_PushUserdata(L, tmthing, META_MOBJ); LUA_PushUserdata(L, tmthing, META_MOBJ);
P_SetTarget(&tmthing, ptmthing); P_SetTarget(&tmthing, ptmthing);
return 2; return 2;
@ -3835,6 +3870,8 @@ static luaL_Reg lib[] = {
{"P_TryMove",lib_pTryMove}, {"P_TryMove",lib_pTryMove},
{"P_Move",lib_pMove}, {"P_Move",lib_pMove},
{"P_TeleportMove",lib_pTeleportMove}, {"P_TeleportMove",lib_pTeleportMove},
{"P_SetOrigin",lib_pSetOrigin},
{"P_MoveOrigin",lib_pMoveOrigin},
{"P_SlideMove",lib_pSlideMove}, {"P_SlideMove",lib_pSlideMove},
{"P_BounceMove",lib_pBounceMove}, {"P_BounceMove",lib_pBounceMove},
{"P_CheckSight", lib_pCheckSight}, {"P_CheckSight", lib_pCheckSight},

View file

@ -477,7 +477,7 @@ static int mobj_get(lua_State *L)
} }
#define NOSET luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly.", mobj_opt[field]) #define NOSET luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly.", mobj_opt[field])
#define NOSETPOS luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly. Use " LUA_QL("P_Move") ", " LUA_QL("P_TryMove") ", or " LUA_QL("P_TeleportMove") " instead.", mobj_opt[field]) #define NOSETPOS luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly. Use " LUA_QL("P_Move") ", " LUA_QL("P_TryMove") ", or " LUA_QL("P_SetOrigin") ", or " LUA_QL("P_MoveOrigin") " instead.", mobj_opt[field])
static int mobj_set(lua_State *L) static int mobj_set(lua_State *L)
{ {
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));

View file

@ -420,7 +420,7 @@ void Command_RTeleport_f(void)
CONS_Printf(M_GetText("Teleporting by %d, %d, %d...\n"), intx, inty, FixedInt((intz-p->mo->z))); CONS_Printf(M_GetText("Teleporting by %d, %d, %d...\n"), intx, inty, FixedInt((intz-p->mo->z)));
P_MapStart(); P_MapStart();
if (!P_TeleportMove(p->mo, p->mo->x+intx*FRACUNIT, p->mo->y+inty*FRACUNIT, intz)) if (!P_SetOrigin(p->mo, p->mo->x+intx*FRACUNIT, p->mo->y+inty*FRACUNIT, intz))
CONS_Alert(CONS_WARNING, M_GetText("Unable to teleport to that spot!\n")); CONS_Alert(CONS_WARNING, M_GetText("Unable to teleport to that spot!\n"));
else else
S_StartSound(p->mo, sfx_mixup); S_StartSound(p->mo, sfx_mixup);
@ -641,7 +641,7 @@ void Command_Teleport_f(void)
} }
P_MapStart(); P_MapStart();
if (!P_TeleportMove(p->mo, intx, inty, intz)) if (!P_SetOrigin(p->mo, intx, inty, intz))
CONS_Alert(CONS_WARNING, M_GetText("Unable to teleport to that spot!\n")); CONS_Alert(CONS_WARNING, M_GetText("Unable to teleport to that spot!\n"));
else else
S_StartSound(p->mo, sfx_mixup); S_StartSound(p->mo, sfx_mixup);
@ -1039,7 +1039,7 @@ void OP_ObjectplaceMovement(player_t *player)
if (cmd->forwardmove != 0) if (cmd->forwardmove != 0)
{ {
P_Thrust(player->mo, player->mo->angle, (cmd->forwardmove*player->mo->scale/MAXPLMOVE)*cv_speed.value); P_Thrust(player->mo, player->mo->angle, (cmd->forwardmove*player->mo->scale/MAXPLMOVE)*cv_speed.value);
P_TeleportMove(player->mo, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, player->mo->z); P_MoveOrigin(player->mo, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, player->mo->z);
player->mo->momx = player->mo->momy = 0; player->mo->momx = player->mo->momy = 0;
} }

View file

@ -1145,7 +1145,7 @@ void A_FaceStabHurl(mobj_t *actor)
hwork->destscale = FixedSqrt(step*basesize); hwork->destscale = FixedSqrt(step*basesize);
P_SetScale(hwork, hwork->destscale); P_SetScale(hwork, hwork->destscale);
hwork->fuse = 2; hwork->fuse = 2;
P_TeleportMove(hwork, actor->x + xo*(15-step), actor->y + yo*(15-step), actor->z + (actor->height - hwork->height)/2 + (P_MobjFlip(actor)*(8<<FRACBITS))); P_MoveOrigin(hwork, actor->x + xo*(15-step), actor->y + yo*(15-step), actor->z + (actor->height - hwork->height)/2 + (P_MobjFlip(actor)*(8<<FRACBITS)));
step -= NUMGRADS; step -= NUMGRADS;
} }
@ -1905,7 +1905,7 @@ void A_CrushclawAim(mobj_t *actor)
#undef anglimit #undef anglimit
#undef angfactor #undef angfactor
P_TeleportMove(actor, P_MoveOrigin(actor,
crab->x + P_ReturnThrustX(actor, actor->angle, locvar1*crab->scale), crab->x + P_ReturnThrustX(actor, actor->angle, locvar1*crab->scale),
crab->y + P_ReturnThrustY(actor, actor->angle, locvar1*crab->scale), crab->y + P_ReturnThrustY(actor, actor->angle, locvar1*crab->scale),
crab->z + locvar2*crab->scale); crab->z + locvar2*crab->scale);
@ -2043,7 +2043,7 @@ void A_CrushclawLaunch(mobj_t *actor)
fixed_t idx = dx, idy = dy, idz = dz; fixed_t idx = dx, idy = dy, idz = dz;
while (chain) while (chain)
{ {
P_TeleportMove(chain, actor->target->x + idx, actor->target->y + idy, actor->target->z + idz); P_MoveOrigin(chain, actor->target->x + idx, actor->target->y + idy, actor->target->z + idz);
chain->movefactor = chain->z; chain->movefactor = chain->z;
idx += dx; idx += dx;
idy += dy; idy += dy;
@ -4023,7 +4023,7 @@ void A_AttractChase(mobj_t *actor)
//P_SetScale(actor, (actor->destscale = actor->target->scale)); //P_SetScale(actor, (actor->destscale = actor->target->scale));
actor->z = actor->target->z; actor->z = actor->target->z;
K_MatchGenericExtraFlags(actor, actor->target); K_MatchGenericExtraFlags(actor, actor->target);
P_TeleportMove(actor, actor->target->x, actor->target->y, P_MoveOrigin(actor, actor->target->x, actor->target->y,
actor->z + actor->z +
( actor->target->height + offz )* P_MobjFlip(actor)); ( actor->target->height + offz )* P_MobjFlip(actor));
actor->extravalue1++; actor->extravalue1++;
@ -4052,7 +4052,7 @@ void A_AttractChase(mobj_t *actor)
P_SetScale(actor, (actor->destscale = actor->target->scale - ((actor->target->scale/14) * actor->extravalue1))); P_SetScale(actor, (actor->destscale = actor->target->scale - ((actor->target->scale/14) * actor->extravalue1)));
actor->z = actor->target->z; actor->z = actor->target->z;
K_MatchGenericExtraFlags(actor, actor->target); K_MatchGenericExtraFlags(actor, actor->target);
P_TeleportMove(actor, P_MoveOrigin(actor,
actor->target->x + FixedMul(dist, FINECOSINE(actor->angle >> ANGLETOFINESHIFT)), actor->target->x + FixedMul(dist, FINECOSINE(actor->angle >> ANGLETOFINESHIFT)),
actor->target->y + FixedMul(dist, FINESINE(actor->angle >> ANGLETOFINESHIFT)), actor->target->y + FixedMul(dist, FINESINE(actor->angle >> ANGLETOFINESHIFT)),
actor->z + actor->target->scale * 24 * P_MobjFlip(actor)); actor->z + actor->target->scale * 24 * P_MobjFlip(actor));
@ -9911,7 +9911,7 @@ void A_VileAttack(mobj_t *actor)
// move the fire between the vile and the player // move the fire between the vile and the player
//fire->x = actor->target->x - FixedMul (24*FRACUNIT, finecosine[an]); //fire->x = actor->target->x - FixedMul (24*FRACUNIT, finecosine[an]);
//fire->y = actor->target->y - FixedMul (24*FRACUNIT, finesine[an]); //fire->y = actor->target->y - FixedMul (24*FRACUNIT, finesine[an]);
P_TeleportMove(fire, P_MoveOrigin(fire,
actor->target->x - P_ReturnThrustX(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)), actor->target->x - P_ReturnThrustX(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
actor->target->y - P_ReturnThrustY(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)), actor->target->y - P_ReturnThrustY(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
fire->z); fire->z);
@ -9956,7 +9956,7 @@ void A_VileAttack(mobj_t *actor)
// move the fire between the vile and the player // move the fire between the vile and the player
//fire->x = actor->target->x - FixedMul (24*FRACUNIT, finecosine[an]); //fire->x = actor->target->x - FixedMul (24*FRACUNIT, finecosine[an]);
//fire->y = actor->target->y - FixedMul (24*FRACUNIT, finesine[an]); //fire->y = actor->target->y - FixedMul (24*FRACUNIT, finesine[an]);
P_TeleportMove(fire, P_MoveOrigin(fire,
actor->target->x - P_ReturnThrustX(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)), actor->target->x - P_ReturnThrustX(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
actor->target->y - P_ReturnThrustY(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)), actor->target->y - P_ReturnThrustY(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
fire->z); fire->z);
@ -10629,13 +10629,13 @@ void A_FlickyCenter(mobj_t *actor)
if (actor->target && P_AproxDistance(actor->target->x - originx, actor->target->y - originy) < actor->extravalue1) if (actor->target && P_AproxDistance(actor->target->x - originx, actor->target->y - originy) < actor->extravalue1)
{ {
actor->extravalue2 = 1; actor->extravalue2 = 1;
P_TeleportMove(actor, actor->target->x, actor->target->y, actor->target->z); P_SetOrigin(actor, actor->target->x, actor->target->y, actor->target->z);
tmthing = NULL; tmthing = NULL;
} }
else if(actor->extravalue2) else if(actor->extravalue2)
{ {
actor->extravalue2 = 0; actor->extravalue2 = 0;
P_TeleportMove(actor, originx, originy, originz); P_SetOrigin(actor, originx, originy, originz);
tmthing = NULL; tmthing = NULL;
} }
} }
@ -11172,7 +11172,7 @@ void A_LightBeamReset(mobj_t *actor)
actor->momy = (P_SignedRandom()*FINECOSINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/128; actor->momy = (P_SignedRandom()*FINECOSINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/128;
actor->momz = (P_SignedRandom()*FRACUNIT)/128; actor->momz = (P_SignedRandom()*FRACUNIT)/128;
P_TeleportMove(actor, P_SetOrigin(actor,
actor->spawnpoint->x*FRACUNIT - (P_SignedRandom()*FINESINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/2, actor->spawnpoint->x*FRACUNIT - (P_SignedRandom()*FINESINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/2,
actor->spawnpoint->y*FRACUNIT + (P_SignedRandom()*FINECOSINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/2, actor->spawnpoint->y*FRACUNIT + (P_SignedRandom()*FINECOSINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/2,
actor->spawnpoint->z*FRACUNIT + (P_SignedRandom()*FRACUNIT)/2); actor->spawnpoint->z*FRACUNIT + (P_SignedRandom()*FRACUNIT)/2);
@ -11757,7 +11757,7 @@ void A_DoNPCSkid(mobj_t *actor)
actor->momy = (2*actor->momy)/3; actor->momy = (2*actor->momy)/3;
} }
P_TeleportMove(actor, x, y, z); P_MoveOrigin(actor, x, y, z);
// Spawn a particle every 3 tics. // Spawn a particle every 3 tics.
if (!(leveltime % 3)) if (!(leveltime % 3))
@ -12098,7 +12098,7 @@ void A_Boss5MakeJunk(mobj_t *actor)
if (locvar1 > 0) if (locvar1 > 0)
P_SetMobjState(broked, locvar1); P_SetMobjState(broked, locvar1);
if (!P_MobjWasRemoved(broked)) if (!P_MobjWasRemoved(broked))
P_TeleportMove(broked, broked->x + broked->momx, broked->y + broked->momy, broked->z); P_MoveOrigin(broked, broked->x + broked->momx, broked->y + broked->momy, broked->z);
ang += ANGLE_45; ang += ANGLE_45;
} }
@ -13161,7 +13161,7 @@ void A_DragonWing(mobj_t *actor)
actor->angle = target->angle + actor->movedir; actor->angle = target->angle + actor->movedir;
x = target->x + P_ReturnThrustX(actor, actor->angle, -target->radius); x = target->x + P_ReturnThrustX(actor, actor->angle, -target->radius);
y = target->y + P_ReturnThrustY(actor, actor->angle, -target->radius); y = target->y + P_ReturnThrustY(actor, actor->angle, -target->radius);
P_TeleportMove(actor, x, y, target->z); P_MoveOrigin(actor, x, y, target->z);
} }
// Function: A_DragonSegment // Function: A_DragonSegment
@ -13202,7 +13202,7 @@ void A_DragonSegment(mobj_t *actor)
zdist = P_ReturnThrustY(target, zangle, radius); zdist = P_ReturnThrustY(target, zangle, radius);
actor->angle = hangle; actor->angle = hangle;
P_TeleportMove(actor, target->x + xdist, target->y + ydist, target->z + zdist); P_MoveOrigin(actor, target->x + xdist, target->y + ydist, target->z + zdist);
} }
// Function: A_ChangeHeight // Function: A_ChangeHeight
@ -14164,10 +14164,10 @@ void A_LightningFollowPlayer(mobj_t *actor)
{ {
sx = actor->target->x + FixedMul((actor->target->scale*actor->extravalue1), FINECOSINE((actor->angle)>>ANGLETOFINESHIFT)); sx = actor->target->x + FixedMul((actor->target->scale*actor->extravalue1), FINECOSINE((actor->angle)>>ANGLETOFINESHIFT));
sy = actor->target->y + FixedMul((actor->target->scale*actor->extravalue1), FINESINE((actor->angle)>>ANGLETOFINESHIFT)); sy = actor->target->y + FixedMul((actor->target->scale*actor->extravalue1), FINESINE((actor->angle)>>ANGLETOFINESHIFT));
P_TeleportMove(actor, sx, sy, actor->target->z); P_MoveOrigin(actor, sx, sy, actor->target->z);
} }
else // else just teleport to player directly else // else just teleport to player directly
P_TeleportMove(actor, actor->target->x, actor->target->y, actor->target->z); P_MoveOrigin(actor, actor->target->x, actor->target->y, actor->target->z);
K_MatchGenericExtraFlags(actor, actor->target); // copy our target for graviflip K_MatchGenericExtraFlags(actor, actor->target); // copy our target for graviflip
actor->momx = actor->target->momx; actor->momx = actor->target->momx;
@ -14644,7 +14644,7 @@ void A_InvincSparkleRotate(mobj_t *actor)
sx = actor->target->x + FixedMul((actor->movefactor), FINECOSINE((actor->angle)>>ANGLETOFINESHIFT)); sx = actor->target->x + FixedMul((actor->movefactor), FINECOSINE((actor->angle)>>ANGLETOFINESHIFT));
sy = actor->target->y + FixedMul((actor->movefactor), FINESINE((actor->angle)>>ANGLETOFINESHIFT)); sy = actor->target->y + FixedMul((actor->movefactor), FINESINE((actor->angle)>>ANGLETOFINESHIFT));
sz = actor->target->z + (actor->extravalue1) + FixedMul((actor->cvmem), FINECOSINE((leveltime*ANG1*10 + actor->angle)>>ANGLETOFINESHIFT)); sz = actor->target->z + (actor->extravalue1) + FixedMul((actor->cvmem), FINECOSINE((leveltime*ANG1*10 + actor->angle)>>ANGLETOFINESHIFT));
P_TeleportMove(actor, sx, sy, sz); P_MoveOrigin(actor, sx, sy, sz);
actor->momx = actor->target->momx; actor->momx = actor->target->momx;
actor->momy = actor->target->momy; actor->momy = actor->target->momy;

View file

@ -237,7 +237,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (!special->target) if (!special->target)
return; // foolproof crash prevention check!!!!! return; // foolproof crash prevention check!!!!!
P_TeleportMove(player->mo, special->target->x, special->target->y, special->target->z + (48<<FRACBITS)); P_SetOrigin(player->mo, special->target->x, special->target->y, special->target->z + (48<<FRACBITS));
player->mo->angle = special->target->angle; player->mo->angle = special->target->angle;
P_SetObjectMomZ(player->mo, 12<<FRACBITS, false); P_SetObjectMomZ(player->mo, 12<<FRACBITS, false);
P_InstaThrust(player->mo, player->mo->angle, 20<<FRACBITS); P_InstaThrust(player->mo, player->mo->angle, 20<<FRACBITS);

View file

@ -403,7 +403,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y);
boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam); boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam);
boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff); boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff);
boolean P_Move(mobj_t *actor, fixed_t speed); boolean P_Move(mobj_t *actor, fixed_t speed);
boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z); boolean P_SetOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z);
boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z);
void P_SlideMove(mobj_t *mo); void P_SlideMove(mobj_t *mo);
void P_BouncePlayerMove(mobj_t *mo); void P_BouncePlayerMove(mobj_t *mo);
void P_BounceMove(mobj_t *mo); void P_BounceMove(mobj_t *mo);

View file

@ -96,7 +96,7 @@ camera_t *mapcampointer;
// //
// P_TeleportMove // P_TeleportMove
// //
boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z) static boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
{ {
numspechit = 0U; numspechit = 0U;
@ -130,6 +130,31 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
return true; return true;
} }
//
// P_SetOrigin - P_TeleportMove which RESETS interpolation values.
//
boolean P_SetOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
{
boolean result = P_TeleportMove(thing, x, y, z);
if (result == true)
{
thing->old_x = thing->x;
thing->old_y = thing->y;
thing->old_z = thing->z;
}
return result;
}
//
// P_MoveOrigin - P_TeleportMove which KEEPS interpolation values.
//
boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
{
return P_TeleportMove(thing, x, y, z);
}
// ========================================================================= // =========================================================================
// MOVEMENT ITERATOR FUNCTIONS // MOVEMENT ITERATOR FUNCTIONS
// ========================================================================= // =========================================================================
@ -1598,7 +1623,7 @@ static boolean PIT_CheckLine(line_t *ld)
cosradius = FixedMul(dist, FINECOSINE(langle>>ANGLETOFINESHIFT)); cosradius = FixedMul(dist, FINECOSINE(langle>>ANGLETOFINESHIFT));
sinradius = FixedMul(dist, FINESINE(langle>>ANGLETOFINESHIFT)); sinradius = FixedMul(dist, FINESINE(langle>>ANGLETOFINESHIFT));
tmthing->flags |= MF_NOCLIP; tmthing->flags |= MF_NOCLIP;
P_TeleportMove(tmthing, result.x + cosradius - tmthing->momx, result.y + sinradius - tmthing->momy, tmthing->z); P_MoveOrigin(tmthing, result.x + cosradius - tmthing->momx, result.y + sinradius - tmthing->momy, tmthing->z);
tmthing->flags &= ~MF_NOCLIP; tmthing->flags &= ~MF_NOCLIP;
} }
#endif #endif

View file

@ -3636,6 +3636,11 @@ void P_NullPrecipThinker(precipmobj_t *mobj)
void P_PrecipThinker(precipmobj_t *mobj) void P_PrecipThinker(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); P_CycleStateAnimation((mobj_t *)mobj);
if (mobj->state == &states[S_RAINRETURN]) if (mobj->state == &states[S_RAINRETURN])
@ -3790,9 +3795,9 @@ static void P_ItemCapsulePartThinker(mobj_t *mobj)
// rotate & move to capsule // rotate & move to capsule
mobj->angle += mobj->movedir; mobj->angle += mobj->movedir;
if (mobj->flags2 & MF2_CLASSICPUSH) // centered if (mobj->flags2 & MF2_CLASSICPUSH) // centered
P_TeleportMove(mobj, target->x, target->y, z); P_MoveOrigin(mobj, target->x, target->y, z);
else else
P_TeleportMove(mobj, P_MoveOrigin(mobj,
target->x + P_ReturnThrustX(mobj, mobj->angle + ANGLE_90, mobj->radius), target->x + P_ReturnThrustX(mobj, mobj->angle + ANGLE_90, mobj->radius),
target->y + P_ReturnThrustY(mobj, mobj->angle + ANGLE_90, mobj->radius), target->y + P_ReturnThrustY(mobj, mobj->angle + ANGLE_90, mobj->radius),
z); z);
@ -4211,7 +4216,7 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y
if (dist < source->movefactor) if (dist < source->movefactor)
{ {
source->momx = source->momy = source->momz = 0; source->momx = source->momy = source->momz = 0;
P_TeleportMove(source, tx, ty, tz); P_MoveOrigin(source, tx, ty, tz);
} }
else else
{ {
@ -6542,7 +6547,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
mobj->angle += ANGLE_90; mobj->angle += ANGLE_90;
} }
P_TeleportMove(mobj, P_MoveOrigin(mobj,
mobj->target->x + P_ReturnThrustX(mobj, angle + ANGLE_180, nudge), mobj->target->x + P_ReturnThrustX(mobj, angle + ANGLE_180, nudge),
mobj->target->y + P_ReturnThrustY(mobj, angle + ANGLE_180, nudge), mobj->target->y + P_ReturnThrustY(mobj, angle + ANGLE_180, nudge),
mobj->target->z); mobj->target->z);
@ -6621,7 +6626,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
} }
mobj->angle = mobj->target->angle; mobj->angle = mobj->target->angle;
P_TeleportMove(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius), P_MoveOrigin(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius),
mobj->target->y + P_ReturnThrustY(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->z); mobj->target->y + P_ReturnThrustY(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->z);
P_SetScale(mobj, mobj->target->scale); P_SetScale(mobj, mobj->target->scale);
@ -6673,7 +6678,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
P_RemoveMobj(mobj); P_RemoveMobj(mobj);
return false; return false;
} }
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
break; break;
case MT_BRAKEDRIFT: case MT_BRAKEDRIFT:
if ((!mobj->target || !mobj->target->health || !mobj->target->player || !P_IsObjectOnGround(mobj->target)) if ((!mobj->target || !mobj->target->health || !mobj->target->player || !P_IsObjectOnGround(mobj->target))
@ -6694,7 +6699,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
newx = mobj->target->x + P_ReturnThrustX(mobj->target, travelangle+ANGLE_180, 24*mobj->target->scale); newx = mobj->target->x + P_ReturnThrustX(mobj->target, travelangle+ANGLE_180, 24*mobj->target->scale);
newy = mobj->target->y + P_ReturnThrustY(mobj->target, travelangle+ANGLE_180, 24*mobj->target->scale); newy = mobj->target->y + P_ReturnThrustY(mobj->target, travelangle+ANGLE_180, 24*mobj->target->scale);
P_TeleportMove(mobj, newx, newy, mobj->target->z); P_MoveOrigin(mobj, newx, newy, mobj->target->z);
mobj->angle = travelangle - ((ANGLE_90/5)*mobj->target->player->drift); mobj->angle = travelangle - ((ANGLE_90/5)*mobj->target->player->drift);
P_SetScale(mobj, (mobj->destscale = mobj->target->scale)); P_SetScale(mobj, (mobj->destscale = mobj->target->scale));
@ -6723,7 +6728,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
{ {
mobj->fuse = 9; mobj->fuse = 9;
} }
P_TeleportMove(mobj, mobj->target->x, P_MoveOrigin(mobj, mobj->target->x,
mobj->target->y, mobj->target->z); mobj->target->y, mobj->target->z);
mobj->angle = mobj->target->angle + mobj->cusval; mobj->angle = mobj->target->angle + mobj->cusval;
break; break;
@ -6733,7 +6738,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
P_RemoveMobj(mobj); P_RemoveMobj(mobj);
return false; return false;
} }
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
break; break;
case MT_INSTASHIELDB: case MT_INSTASHIELDB:
mobj->renderflags ^= RF_DONTDRAW; mobj->renderflags ^= RF_DONTDRAW;
@ -6745,7 +6750,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
P_RemoveMobj(mobj); P_RemoveMobj(mobj);
return false; return false;
} }
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
K_MatchGenericExtraFlags(mobj, mobj->target); K_MatchGenericExtraFlags(mobj, mobj->target);
break; break;
case MT_BATTLEPOINT: case MT_BATTLEPOINT:
@ -6768,7 +6773,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
mobj->movefactor = mobj->target->height; mobj->movefactor = mobj->target->height;
} }
K_MatchGenericExtraFlags(mobj, mobj->target); K_MatchGenericExtraFlags(mobj, mobj->target);
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z + (mobj->target->height/2) + mobj->movefactor); P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z + (mobj->target->height/2) + mobj->movefactor);
break; break;
case MT_RINGSPARKS: case MT_RINGSPARKS:
if (!mobj->target || P_MobjWasRemoved(mobj->target)) if (!mobj->target || P_MobjWasRemoved(mobj->target))
@ -6781,7 +6786,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
K_MatchGenericExtraFlags(mobj, mobj->target); K_MatchGenericExtraFlags(mobj, mobj->target);
P_TeleportMove(mobj, mobj->target->x + FINECOSINE(mobj->angle >> ANGLETOFINESHIFT), P_MoveOrigin(mobj, mobj->target->x + FINECOSINE(mobj->angle >> ANGLETOFINESHIFT),
mobj->target->y + FINESINE(mobj->angle >> ANGLETOFINESHIFT), mobj->target->y + FINESINE(mobj->angle >> ANGLETOFINESHIFT),
mobj->z + (mobj->target->height * P_MobjFlip(mobj))); mobj->z + (mobj->target->height * P_MobjFlip(mobj)));
break; break;
@ -6802,7 +6807,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
K_MatchGenericExtraFlags(mobj, mobj->target); K_MatchGenericExtraFlags(mobj, mobj->target);
mobj->renderflags = (mobj->renderflags & ~RF_DONTDRAW)|K_GetPlayerDontDrawFlag(mobj->target->player); mobj->renderflags = (mobj->renderflags & ~RF_DONTDRAW)|K_GetPlayerDontDrawFlag(mobj->target->player);
P_TeleportMove(mobj, mobj->target->x + FixedMul(34 * mapobjectscale, FINECOSINE((mobj->angle + mobj->movedir) >> ANGLETOFINESHIFT)), P_MoveOrigin(mobj, mobj->target->x + FixedMul(34 * mapobjectscale, FINECOSINE((mobj->angle + mobj->movedir) >> ANGLETOFINESHIFT)),
mobj->target->y + FixedMul(34 * mapobjectscale, FINESINE((mobj->angle + mobj->movedir) >> ANGLETOFINESHIFT)), mobj->target->y + FixedMul(34 * mapobjectscale, FINESINE((mobj->angle + mobj->movedir) >> ANGLETOFINESHIFT)),
mobj->z + (32 * mapobjectscale * P_MobjFlip(mobj))); mobj->z + (32 * mapobjectscale * P_MobjFlip(mobj)));
@ -6845,7 +6850,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
fixed_t newx = mobj->target->x + P_ReturnThrustX(NULL, mobj->target->angle + perpendicular, 8*mobj->target->scale); fixed_t newx = mobj->target->x + P_ReturnThrustX(NULL, mobj->target->angle + perpendicular, 8*mobj->target->scale);
fixed_t newy = mobj->target->y + P_ReturnThrustY(NULL, mobj->target->angle + perpendicular, 8*mobj->target->scale); fixed_t newy = mobj->target->y + P_ReturnThrustY(NULL, mobj->target->angle + perpendicular, 8*mobj->target->scale);
P_TeleportMove(mobj, newx, newy, mobj->target->z); P_MoveOrigin(mobj, newx, newy, mobj->target->z);
if (mobj->extravalue1 & 1) if (mobj->extravalue1 & 1)
mobj->angle = mobj->target->angle - ANGLE_45; mobj->angle = mobj->target->angle - ANGLE_45;
@ -6883,7 +6888,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
else else
ang = (signed)(ang + off); ang = (signed)(ang + off);
P_TeleportMove(mobj, P_MoveOrigin(mobj,
mobj->target->x - FixedMul(mobj->target->radius, FINECOSINE(ang >> ANGLETOFINESHIFT)), mobj->target->x - FixedMul(mobj->target->radius, FINECOSINE(ang >> ANGLETOFINESHIFT)),
mobj->target->y - FixedMul(mobj->target->radius, FINESINE(ang >> ANGLETOFINESHIFT)), mobj->target->y - FixedMul(mobj->target->radius, FINESINE(ang >> ANGLETOFINESHIFT)),
z); z);
@ -6938,7 +6943,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
desty = mobj->target->y; desty = mobj->target->y;
} }
P_TeleportMove(mobj, destx, desty, mobj->target->z); P_MoveOrigin(mobj, destx, desty, mobj->target->z);
break; break;
} }
case MT_BUBBLESHIELD: case MT_BUBBLESHIELD:
@ -7066,7 +7071,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
desty = mobj->target->y; desty = mobj->target->y;
} }
P_TeleportMove(mobj, destx, desty, mobj->target->z); P_MoveOrigin(mobj, destx, desty, mobj->target->z);
break; break;
} }
case MT_FLAMESHIELD: case MT_FLAMESHIELD:
@ -7174,7 +7179,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
desty = mobj->target->y; desty = mobj->target->y;
} }
P_TeleportMove(mobj, destx, desty, mobj->target->z); P_MoveOrigin(mobj, destx, desty, mobj->target->z);
mobj->angle = K_MomentumAngle(mobj->target); mobj->angle = K_MomentumAngle(mobj->target);
if (underlayst != S_NULL) if (underlayst != S_NULL)
@ -7218,7 +7223,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
return false; return false;
} }
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
mobj->angle = mobj->target->angle; mobj->angle = mobj->target->angle;
mobj->scalespeed = mobj->target->scalespeed; mobj->scalespeed = mobj->target->scalespeed;
mobj->destscale = mobj->target->destscale; mobj->destscale = mobj->target->destscale;
@ -7268,7 +7273,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (cur->lastlook == 2 || cur->lastlook == 3) if (cur->lastlook == 2 || cur->lastlook == 3)
offy *= -1; offy *= -1;
P_TeleportMove(cur, mobj->x + offx, mobj->y + offy, mobj->z); P_MoveOrigin(cur, mobj->x + offx, mobj->y + offy, mobj->z);
cur->scalespeed = mobj->target->scalespeed; cur->scalespeed = mobj->target->scalespeed;
cur->destscale = mobj->target->destscale; cur->destscale = mobj->target->destscale;
P_SetScale(cur, mobj->target->scale); P_SetScale(cur, mobj->target->scale);
@ -7407,7 +7412,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
amt += 1; amt += 1;
} }
P_TeleportMove( P_MoveOrigin(
cur, cur,
mobj->x + FixedMul(amt, FINECOSINE(dir >> ANGLETOFINESHIFT)), mobj->x + FixedMul(amt, FINECOSINE(dir >> ANGLETOFINESHIFT)),
mobj->y + FixedMul(amt, FINESINE(dir >> ANGLETOFINESHIFT)), mobj->y + FixedMul(amt, FINESINE(dir >> ANGLETOFINESHIFT)),
@ -7497,7 +7502,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
while (cur && !P_MobjWasRemoved(cur)) while (cur && !P_MobjWasRemoved(cur))
{ {
cur->angle += FixedAngle(mobj->info->speed); cur->angle += FixedAngle(mobj->info->speed);
P_TeleportMove(cur, mobj->x + FINECOSINE((cur->angle*8)>>ANGLETOFINESHIFT), P_MoveOrigin(cur, mobj->x + FINECOSINE((cur->angle*8)>>ANGLETOFINESHIFT),
mobj->y + FINESINE((cur->angle*8)>>ANGLETOFINESHIFT), mobj->z); mobj->y + FINESINE((cur->angle*8)>>ANGLETOFINESHIFT), mobj->z);
//P_SpawnGhostMobj(cur)->tics = 2; //P_SpawnGhostMobj(cur)->tics = 2;
@ -7630,7 +7635,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
fixed_t wz = mobj->tracer->z + (joint * ((mobj->z + (mobj->height/2)) - mobj->tracer->z) / (numjoints+1)); fixed_t wz = mobj->tracer->z + (joint * ((mobj->z + (mobj->height/2)) - mobj->tracer->z) / (numjoints+1));
if (cur && !P_MobjWasRemoved(cur)) if (cur && !P_MobjWasRemoved(cur))
P_TeleportMove(cur, wx, wy, wz); P_MoveOrigin(cur, wx, wy, wz);
else else
cur = P_SpawnMobj(wx, wy, wz, MT_FROGTONGUE_JOINT); cur = P_SpawnMobj(wx, wy, wz, MT_FROGTONGUE_JOINT);
@ -7741,7 +7746,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
continue; continue;
} }
else // Move into place else // Move into place
P_TeleportMove(cur, mobj->x, mobj->y, segz); P_MoveOrigin(cur, mobj->x, mobj->y, segz);
} }
else else
{ {
@ -7815,7 +7820,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
mobj->extravalue1 = 1; mobj->extravalue1 = 1;
player->offroad += 2<<FRACBITS; player->offroad += 2<<FRACBITS;
P_TeleportMove(mobj, P_MoveOrigin(mobj,
player->mo->x + P_ReturnThrustX(NULL, player->mo->angle, player->mo->radius) player->mo->x + P_ReturnThrustX(NULL, player->mo->angle, player->mo->radius)
+ P_ReturnThrustX(NULL, player->mo->angle+ANGLE_90, (mobj->threshold)<<FRACBITS), + P_ReturnThrustX(NULL, player->mo->angle+ANGLE_90, (mobj->threshold)<<FRACBITS),
player->mo->y + P_ReturnThrustY(NULL, player->mo->angle, player->mo->radius) player->mo->y + P_ReturnThrustY(NULL, player->mo->angle, player->mo->radius)
@ -7976,7 +7981,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
mobj->tracer->momx = mobj->tracer->momy = 0; mobj->tracer->momx = mobj->tracer->momy = 0;
} }
P_TeleportMove(mobj, P_MoveOrigin(mobj,
mobj->tracer->x + P_ReturnThrustX(NULL, mobj->tracer->angle+ANGLE_90, (mobj->cvmem)<<FRACBITS), mobj->tracer->x + P_ReturnThrustX(NULL, mobj->tracer->angle+ANGLE_90, (mobj->cvmem)<<FRACBITS),
mobj->tracer->y + P_ReturnThrustY(NULL, mobj->tracer->angle+ANGLE_90, (mobj->cvmem)<<FRACBITS), mobj->tracer->y + P_ReturnThrustY(NULL, mobj->tracer->angle+ANGLE_90, (mobj->cvmem)<<FRACBITS),
mobj->tracer->z - (4*mobj->tracer->scale) + (P_RandomRange(-abs(mobj->cvmem), abs(mobj->cvmem))<<FRACBITS)); mobj->tracer->z - (4*mobj->tracer->scale) + (P_RandomRange(-abs(mobj->cvmem), abs(mobj->cvmem))<<FRACBITS));
@ -8319,7 +8324,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
cur->angle = angle + ANGLE_90; cur->angle = angle + ANGLE_90;
} }
P_TeleportMove(cur, newx, newy, newz); P_MoveOrigin(cur, newx, newy, newz);
cur = cur->hnext; cur = cur->hnext;
} }
@ -8345,7 +8350,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
mobj->extravalue1++; mobj->extravalue1++;
dist = mobj->extravalue1 * mapobjectscale; dist = mobj->extravalue1 * mapobjectscale;
P_TeleportMove(mobj, battleovertime.x + P_ReturnThrustX(NULL, ang, dist), P_MoveOrigin(mobj, battleovertime.x + P_ReturnThrustX(NULL, ang, dist),
battleovertime.y + P_ReturnThrustY(NULL, ang, dist), z); battleovertime.y + P_ReturnThrustY(NULL, ang, dist), z);
ghost = P_SpawnGhostMobj(mobj); ghost = P_SpawnGhostMobj(mobj);
@ -8593,6 +8598,11 @@ void P_MobjThinker(mobj_t *mobj)
I_Assert(mobj != NULL); I_Assert(mobj != NULL);
I_Assert(!P_MobjWasRemoved(mobj)); 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;
// Remove dead target/tracer. // Remove dead target/tracer.
if (mobj->target && P_MobjWasRemoved(mobj->target)) if (mobj->target && P_MobjWasRemoved(mobj->target))
P_SetTarget(&mobj->target, NULL); P_SetTarget(&mobj->target, NULL);
@ -9670,7 +9680,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
cur = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMK_ICEBLOCK_SIDE); cur = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMK_ICEBLOCK_SIDE);
P_SetTarget(&cur->target, mobj); P_SetTarget(&cur->target, mobj);
cur->threshold = i; cur->threshold = i;
P_TeleportMove(cur, cur->x + ((cur->radius>>FRACBITS) * FINECOSINE((FixedAngle((90*cur->threshold)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK)), P_MoveOrigin(cur, cur->x + ((cur->radius>>FRACBITS) * FINECOSINE((FixedAngle((90*cur->threshold)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK)),
cur->y + ((cur->radius>>FRACBITS) * FINESINE((FixedAngle((90*cur->threshold)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK)), cur->z); cur->y + ((cur->radius>>FRACBITS) * FINESINE((FixedAngle((90*cur->threshold)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK)), cur->z);
cur->angle = ANGLE_90*(cur->threshold+1); cur->angle = ANGLE_90*(cur->threshold+1);
@ -9743,6 +9753,11 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
if (CheckForReverseGravity && !(mobj->flags & MF_NOBLOCKMAP)) if (CheckForReverseGravity && !(mobj->flags & MF_NOBLOCKMAP))
P_CheckGravity(mobj, false); P_CheckGravity(mobj, false);
// set initial old positions (for interpolation)
mobj->old_x = mobj->x;
mobj->old_y = mobj->y;
mobj->old_z = mobj->z;
return mobj; return mobj;
} }
@ -9794,6 +9809,11 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
|| mobj->subsector->sector->floorpic == skyflatnum) || mobj->subsector->sector->floorpic == skyflatnum)
mobj->precipflags |= PCF_PIT; 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; return mobj;
} }

View file

@ -275,6 +275,7 @@ typedef struct mobj_s
// Info for drawing: position. // Info for drawing: position.
fixed_t x, y, z; fixed_t x, y, z;
fixed_t old_x, old_y, old_z; // position interpolation
// More list: links in sector (if needed) // More list: links in sector (if needed)
struct mobj_s *snext; struct mobj_s *snext;
@ -412,6 +413,7 @@ typedef struct precipmobj_s
// Info for drawing: position. // Info for drawing: position.
fixed_t x, y, z; fixed_t x, y, z;
fixed_t old_x, old_y, old_z; // position interpolation
// More list: links in sector (if needed) // More list: links in sector (if needed)
struct precipmobj_s *snext; struct precipmobj_s *snext;

View file

@ -120,7 +120,7 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle
{ {
UINT8 i; UINT8 i;
if (!P_TeleportMove(thing, x, y, z)) if (!P_SetOrigin(thing, x, y, z))
return false; return false;
if (!dontstopmove) if (!dontstopmove)

View file

@ -24,6 +24,7 @@
#include "lua_hook.h" #include "lua_hook.h"
#include "m_perfstats.h" #include "m_perfstats.h"
#include "i_system.h" // I_GetPreciseTime #include "i_system.h" // I_GetPreciseTime
#include "r_fps.h"
// Object place // Object place
#include "m_cheat.h" #include "m_cheat.h"

View file

@ -1138,6 +1138,11 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
ghost2->flags2 |= (mobj->player->followmobj->flags2 & MF2_LINKDRAW); ghost2->flags2 |= (mobj->player->followmobj->flags2 & MF2_LINKDRAW);
} }
// Copy interpolation data :)
ghost->old_x = mobj->old_x;
ghost->old_y = mobj->old_y;
ghost->old_z = mobj->old_z;
return ghost; return ghost;
} }
@ -2115,6 +2120,9 @@ void P_MovePlayer(player_t *player)
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAILUNDERLAY); ((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAILUNDERLAY);
water->angle = forwardangle - ANGLE_180 - ANGLE_22h; water->angle = forwardangle - ANGLE_180 - ANGLE_22h;
water->destscale = trailScale; water->destscale = trailScale;
water->momx = player->mo->momx;
water->momy = player->mo->momy;
water->momz = player->mo->momz;
P_SetScale(water, trailScale); P_SetScale(water, trailScale);
P_SetMobjState(water, curUnderlayFrame); P_SetMobjState(water, curUnderlayFrame);
@ -2123,6 +2131,9 @@ void P_MovePlayer(player_t *player)
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAIL); ((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAIL);
water->angle = forwardangle - ANGLE_180 - ANGLE_22h; water->angle = forwardangle - ANGLE_180 - ANGLE_22h;
water->destscale = trailScale; water->destscale = trailScale;
water->momx = player->mo->momx;
water->momy = player->mo->momy;
water->momz = player->mo->momz;
P_SetScale(water, trailScale); P_SetScale(water, trailScale);
P_SetMobjState(water, curOverlayFrame); P_SetMobjState(water, curOverlayFrame);
@ -2132,6 +2143,9 @@ void P_MovePlayer(player_t *player)
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAILUNDERLAY); ((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAILUNDERLAY);
water->angle = forwardangle - ANGLE_180 + ANGLE_22h; water->angle = forwardangle - ANGLE_180 + ANGLE_22h;
water->destscale = trailScale; water->destscale = trailScale;
water->momx = player->mo->momx;
water->momy = player->mo->momy;
water->momz = player->mo->momz;
P_SetScale(water, trailScale); P_SetScale(water, trailScale);
P_SetMobjState(water, curUnderlayFrame); P_SetMobjState(water, curUnderlayFrame);
@ -2140,6 +2154,9 @@ void P_MovePlayer(player_t *player)
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAIL); ((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAIL);
water->angle = forwardangle - ANGLE_180 + ANGLE_22h; water->angle = forwardangle - ANGLE_180 + ANGLE_22h;
water->destscale = trailScale; water->destscale = trailScale;
water->momx = player->mo->momx;
water->momy = player->mo->momy;
water->momz = player->mo->momz;
P_SetScale(water, trailScale); P_SetScale(water, trailScale);
P_SetMobjState(water, curOverlayFrame); P_SetMobjState(water, curOverlayFrame);

163
src/r_fps.c Normal file
View file

@ -0,0 +1,163 @@
// 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 pview_old[MAXSPLITSCREENPLAYERS];
static viewvars_t pview_new[MAXSPLITSCREENPLAYERS];
static viewvars_t skyview_old[MAXSPLITSCREENPLAYERS];
static viewvars_t skyview_new[MAXSPLITSCREENPLAYERS];
static viewvars_t *oldview = &pview_old[0];
viewvars_t *newview = &pview_new[0];
enum viewcontext_e viewcontext = VIEWCONTEXT_PLAYER1;
static fixed_t R_LerpFixed(fixed_t from, fixed_t to, fixed_t frac)
{
return FixedMul(frac, to - from);
}
static angle_t R_LerpAngle(angle_t from, angle_t to, fixed_t frac)
{
return FixedMul(frac, to - from);
}
// 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[viewssnum][viewheight*8 - centery];
}
#undef AIMINGTODY
void R_InterpolateView(fixed_t frac)
{
boolean skybox = false;
INT32 i;
if (FIXED_TO_FLOAT(frac) < 0)
frac = 0;
if (frac > FRACUNIT)
frac = FRACUNIT;
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...
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);
}
void R_UpdateViewInterpolation(void)
{
INT32 i;
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
pview_old[i] = pview_new[i];
skyview_old[i] = skyview_new[i];
}
}
void R_SetViewContext(enum viewcontext_e _viewcontext)
{
INT32 i;
I_Assert(_viewcontext >= VIEWCONTEXT_PLAYER1
&& _viewcontext <= VIEWCONTEXT_SKY4);
viewcontext = _viewcontext;
switch (viewcontext)
{
case VIEWCONTEXT_PLAYER1:
case VIEWCONTEXT_PLAYER2:
case VIEWCONTEXT_PLAYER3:
case VIEWCONTEXT_PLAYER4:
i = viewcontext - VIEWCONTEXT_PLAYER1;
oldview = &pview_old[i];
newview = &pview_new[i];
break;
case VIEWCONTEXT_SKY1:
case VIEWCONTEXT_SKY2:
case VIEWCONTEXT_SKY3:
case VIEWCONTEXT_SKY4:
i = viewcontext - VIEWCONTEXT_SKY1;
oldview = &skyview_old[i];
newview = &skyview_new[i];
break;
default:
I_Error("viewcontext value is invalid: we should never get here without an assert!!");
break;
}
}

58
src/r_fps.h Normal file
View file

@ -0,0 +1,58 @@
// 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_PLAYER3,
VIEWCONTEXT_PLAYER4,
VIEWCONTEXT_SKY1,
VIEWCONTEXT_SKY2,
VIEWCONTEXT_SKY3,
VIEWCONTEXT_SKY4
};
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);
#endif

View file

@ -36,6 +36,7 @@
#include "r_main.h" #include "r_main.h"
#include "i_system.h" // I_GetPreciseTime #include "i_system.h" // I_GetPreciseTime
#include "doomstat.h" // MAXSPLITSCREENPLAYERS #include "doomstat.h" // MAXSPLITSCREENPLAYERS
#include "r_fps.h" // Frame interpolation/uncapped
#ifdef HWRENDER #ifdef HWRENDER
#include "hardware/hw_main.h" #include "hardware/hw_main.h"
@ -79,6 +80,9 @@ mobj_t *r_viewmobj;
int r_splitscreen; int r_splitscreen;
fixed_t rendertimefrac;
fixed_t renderdeltatics;
// //
// precalculated math tables // precalculated math tables
// //
@ -100,6 +104,9 @@ lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
lighttable_t *scalelightfixed[MAXLIGHTSCALE]; lighttable_t *scalelightfixed[MAXLIGHTSCALE];
lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
// Frame interpolation/uncapped
tic_t prev_tics;
// Hack to support extra boom colormaps. // Hack to support extra boom colormaps.
extracolormap_t *extra_colormaps = NULL; extracolormap_t *extra_colormaps = NULL;
@ -172,6 +179,9 @@ consvar_t cv_fov[MAXSPLITSCREENPLAYERS] = {
CVAR_INIT ("fov4", "90", CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange) CVAR_INIT ("fov4", "90", CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange)
}; };
// Frame interpolation/uncapped
consvar_t cv_frameinterpolation = CVAR_INIT ("frameinterpolation", "On", CV_SAVE, CV_OnOff, NULL);
// Okay, whoever said homremoval causes a performance hit should be shot. // Okay, whoever said homremoval causes a performance hit should be shot.
consvar_t cv_homremoval = CVAR_INIT ("homremoval", "Yes", CV_SAVE, homremoval_cons_t, NULL); consvar_t cv_homremoval = CVAR_INIT ("homremoval", "Yes", CV_SAVE, homremoval_cons_t, NULL);
@ -1193,40 +1203,6 @@ subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y)
// R_SetupFrame // 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[viewssnum][viewheight*8 - centery];
}
void R_SetupFrame(player_t *player) void R_SetupFrame(player_t *player)
{ {
camera_t *thiscam = &camera[0]; camera_t *thiscam = &camera[0];
@ -1239,6 +1215,7 @@ void R_SetupFrame(player_t *player)
{ {
thiscam = &camera[i]; thiscam = &camera[i];
chasecam = (cv_chasecam[i].value != 0); chasecam = (cv_chasecam[i].value != 0);
R_SetViewContext(VIEWCONTEXT_PLAYER1 + i);
break; break;
} }
} }
@ -1257,73 +1234,75 @@ void R_SetupFrame(player_t *player)
else if (!chasecam) else if (!chasecam)
thiscam->chase = false; thiscam->chase = false;
newview->sky = false;
if (player->awayviewtics) if (player->awayviewtics)
{ {
// cut-away view stuff // cut-away view stuff
r_viewmobj = player->awayviewmobj; // should be a MT_ALTVIEWMAN r_viewmobj = player->awayviewmobj; // should be a MT_ALTVIEWMAN
I_Assert(r_viewmobj != NULL); I_Assert(r_viewmobj != NULL);
viewz = r_viewmobj->z + 20*FRACUNIT; newview->z = r_viewmobj->z + 20*FRACUNIT;
aimingangle = player->awayviewaiming; newview->aim = player->awayviewaiming;
viewangle = r_viewmobj->angle; newview->angle = r_viewmobj->angle;
} }
else if (!player->spectator && chasecam) else if (!player->spectator && chasecam)
// use outside cam view // use outside cam view
{ {
r_viewmobj = NULL; r_viewmobj = NULL;
viewz = thiscam->z + (thiscam->height>>1); newview->z = thiscam->z + (thiscam->height>>1);
aimingangle = thiscam->aiming; newview->aim = thiscam->aiming;
viewangle = thiscam->angle; newview->angle = thiscam->angle;
} }
else else
// use the player's eyes view // use the player's eyes view
{ {
viewz = player->viewz; newview->z = player->viewz;
r_viewmobj = player->mo; r_viewmobj = player->mo;
I_Assert(r_viewmobj != NULL); I_Assert(r_viewmobj != NULL);
aimingangle = player->aiming; newview->aim = player->aiming;
viewangle = r_viewmobj->angle; newview->angle = r_viewmobj->angle;
if (!demo.playback && player->playerstate != PST_DEAD) if (!demo.playback && player->playerstate != PST_DEAD)
{ {
viewangle = localangle[i]; // WARNING: camera uses this newview->angle = localangle[i]; // WARNING: camera uses this
aimingangle = localaiming[i]; newview->aim = localaiming[i];
} }
} }
viewz += quake.z; newview->z += quake.z;
viewplayer = player; newview->player = player;
if (chasecam && !player->awayviewtics && !player->spectator) if (chasecam && !player->awayviewtics && !player->spectator)
{ {
viewx = thiscam->x; newview->x = thiscam->x;
viewy = thiscam->y; newview->y = thiscam->y;
viewx += quake.x; newview->x += quake.x;
viewy += quake.y; newview->y += quake.y;
if (thiscam->subsector) if (thiscam->subsector)
viewsector = thiscam->subsector->sector; newview->sector = thiscam->subsector->sector;
else else
viewsector = R_PointInSubsector(viewx, viewy)->sector; newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;
} }
else else
{ {
viewx = r_viewmobj->x; newview->x = r_viewmobj->x;
viewy = r_viewmobj->y; newview->y = r_viewmobj->y;
viewx += quake.x; newview->x += quake.x;
viewy += quake.y; newview->y += quake.y;
if (r_viewmobj->subsector) if (r_viewmobj->subsector)
viewsector = r_viewmobj->subsector->sector; newview->sector = r_viewmobj->subsector->sector;
else else
viewsector = R_PointInSubsector(viewx, viewy)->sector; newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;
} }
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); // newview->sin = FINESINE(viewangle>>ANGLETOFINESHIFT);
viewcos = FINECOSINE(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) void R_SkyboxFrame(player_t *player)
@ -1338,6 +1317,7 @@ void R_SkyboxFrame(player_t *player)
if (player == &players[displayplayers[i]]) if (player == &players[displayplayers[i]])
{ {
thiscam = &camera[i]; thiscam = &camera[i];
R_SetViewContext(VIEWCONTEXT_SKY1 + i);
break; break;
} }
} }
@ -1349,6 +1329,7 @@ void R_SkyboxFrame(player_t *player)
} }
// cut-away view stuff // cut-away view stuff
newview->sky = true;
r_viewmobj = skyboxmo[0]; r_viewmobj = skyboxmo[0];
#ifdef PARANOIA #ifdef PARANOIA
if (!r_viewmobj) if (!r_viewmobj)
@ -1359,31 +1340,31 @@ void R_SkyboxFrame(player_t *player)
#endif #endif
if (player->awayviewtics) if (player->awayviewtics)
{ {
aimingangle = player->awayviewaiming; newview->aim = player->awayviewaiming;
viewangle = player->awayviewmobj->angle; newview->angle = player->awayviewmobj->angle;
} }
else if (thiscam->chase) else if (thiscam->chase)
{ {
aimingangle = thiscam->aiming; newview->aim = thiscam->aiming;
viewangle = thiscam->angle; newview->angle = thiscam->angle;
} }
else else
{ {
aimingangle = player->aiming; newview->aim = player->aiming;
viewangle = player->mo->angle; newview->angle = player->mo->angle;
if (/*!demo.playback && */player->playerstate != PST_DEAD) if (/*!demo.playback && */player->playerstate != PST_DEAD)
{ {
viewangle = localangle[i]; newview->angle = localangle[i];
aimingangle = localaiming[i]; newview->aim = localaiming[i];
} }
} }
viewangle += r_viewmobj->angle; newview->angle += r_viewmobj->angle;
viewplayer = player; newview->player = player;
viewx = r_viewmobj->x; newview->x = r_viewmobj->x;
viewy = r_viewmobj->y; newview->y = r_viewmobj->y;
viewz = r_viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle! newview->z = r_viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle!
if (mapheaderinfo[gamemap-1]) if (mapheaderinfo[gamemap-1])
{ {
@ -1425,46 +1406,46 @@ void R_SkyboxFrame(player_t *player)
if (r_viewmobj->angle == 0) if (r_viewmobj->angle == 0)
{ {
viewx += x; newview->x += x;
viewy += y; newview->y += y;
} }
else if (r_viewmobj->angle == ANGLE_90) else if (r_viewmobj->angle == ANGLE_90)
{ {
viewx -= y; newview->x -= y;
viewy += x; newview->y += x;
} }
else if (r_viewmobj->angle == ANGLE_180) else if (r_viewmobj->angle == ANGLE_180)
{ {
viewx -= x; newview->x -= x;
viewy -= y; newview->y -= y;
} }
else if (r_viewmobj->angle == ANGLE_270) else if (r_viewmobj->angle == ANGLE_270)
{ {
viewx += y; newview->x += y;
viewy -= x; newview->y -= x;
} }
else else
{ {
angle_t ang = r_viewmobj->angle>>ANGLETOFINESHIFT; angle_t ang = r_viewmobj->angle>>ANGLETOFINESHIFT;
viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang)); newview->x += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang)); newview->y += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang));
} }
} }
if (mh->skybox_scalez > 0) if (mh->skybox_scalez > 0)
viewz += campos.z / mh->skybox_scalez; newview->z += campos.z / mh->skybox_scalez;
else if (mh->skybox_scalez < 0) else if (mh->skybox_scalez < 0)
viewz += campos.z * -mh->skybox_scalez; newview->z += campos.z * -mh->skybox_scalez;
} }
if (r_viewmobj->subsector) if (r_viewmobj->subsector)
viewsector = r_viewmobj->subsector->sector; newview->sector = r_viewmobj->subsector->sector;
else else
viewsector = R_PointInSubsector(viewx, viewy)->sector; newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); // newview->sin = FINESINE(viewangle>>ANGLETOFINESHIFT);
viewcos = FINECOSINE(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) boolean R_ViewpointHasChasecam(player_t *player)
@ -1737,4 +1718,7 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_maxportals); CV_RegisterVar(&cv_maxportals);
CV_RegisterVar(&cv_movebob); CV_RegisterVar(&cv_movebob);
// Frame interpolation/uncapped
CV_RegisterVar(&cv_frameinterpolation);
} }

View file

@ -33,6 +33,11 @@ extern fixed_t fovtan[MAXSPLITSCREENPLAYERS];
extern size_t validcount, linecount, loopcount, framecount; extern size_t validcount, linecount, loopcount, framecount;
// The fraction of a tic being drawn (for interpolation between two tics)
extern fixed_t rendertimefrac;
// Evaluated delta tics for this frame (how many tics since the last frame)
extern fixed_t renderdeltatics;;
// //
// Lighting LUT. // Lighting LUT.
// Used for z-depth cuing per column/row, // Used for z-depth cuing per column/row,
@ -111,6 +116,10 @@ extern consvar_t cv_fov[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_skybox; extern consvar_t cv_skybox;
extern consvar_t cv_tailspickup; extern consvar_t cv_tailspickup;
// Frame interpolation (uncapped framerate)
extern tic_t prev_tics;
extern consvar_t cv_frameinterpolation;
// Called by startup code. // Called by startup code.
void R_Init(void); void R_Init(void);

View file

@ -1361,16 +1361,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
// //
static void R_ProjectSprite(mobj_t *thing) static void R_ProjectSprite(mobj_t *thing)
{ {
fixed_t thingxpos = thing->x + thing->sprxoff;
fixed_t thingypos = thing->y + thing->spryoff;
fixed_t thingzpos = thing->z + thing->sprzoff;
mobj_t *oldthing = thing; mobj_t *oldthing = thing;
//const fixed_t oldthingxpos = oldthing->x + oldthing->sprxoff;
//const fixed_t oldthingypos = oldthing->y + oldthing->spryoff;
const fixed_t oldthingzpos = oldthing->z + oldthing->sprzoff;
fixed_t tr_x, tr_y; fixed_t tr_x, tr_y;
fixed_t tx, tz; fixed_t tx, tz;
fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!!
@ -1435,7 +1427,32 @@ static void R_ProjectSprite(mobj_t *thing)
angle_t spriterotangle = 0; angle_t spriterotangle = 0;
#endif #endif
// hitlag vibrating // 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;
}
}
// hitlag vibrating (todo: interp somehow?)
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG)) if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
{ {
fixed_t mul = thing->hitlag * (FRACUNIT / 10); fixed_t mul = thing->hitlag * (FRACUNIT / 10);
@ -1445,14 +1462,19 @@ static void R_ProjectSprite(mobj_t *thing)
mul = -mul; mul = -mul;
} }
thingxpos += FixedMul(thing->momx, mul); interpx += FixedMul(thing->momx, mul);
thingypos += FixedMul(thing->momy, mul); interpy += FixedMul(thing->momy, mul);
thingzpos += FixedMul(thing->momz, mul); interpz += FixedMul(thing->momz, mul);
} }
// sprite offset
interpx += thing->sprxoff;
interpy += thing->spryoff;
interpz += thing->sprzoff;
// transform the origin point // transform the origin point
tr_x = thingxpos - viewx; tr_x = interpx - viewx;
tr_y = thingypos - viewy; tr_y = interpy - viewy;
basetz = tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance basetz = tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance
@ -1529,7 +1551,7 @@ static void R_ProjectSprite(mobj_t *thing)
if (sprframe->rotate != SRF_SINGLE || papersprite) if (sprframe->rotate != SRF_SINGLE || papersprite)
{ {
ang = R_PointToAngle (thingxpos, thingypos) - (thing->player ? thing->player->drawangle : thing->angle); ang = R_PointToAngle (interpx, interpy) - interpangle;
if (mirrored) if (mirrored)
ang = InvAngle(ang); ang = InvAngle(ang);
} }
@ -1544,7 +1566,7 @@ static void R_ProjectSprite(mobj_t *thing)
else else
{ {
// choose a different rotation based on player view // choose a different rotation based on player view
//ang = R_PointToAngle (thingxpos, thingypos) - thing->angle; //ang = R_PointToAngle (interpx, interpy) - interpangle;
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
rot = 6; // F7 slot rot = 6; // F7 slot
@ -1755,12 +1777,37 @@ static void R_ProjectSprite(mobj_t *thing)
fixed_t linkscale; fixed_t linkscale;
thing = thing->tracer; 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);
}
// hitlag vibrating (todo: interp somehow?)
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
{
fixed_t mul = thing->hitlag * (FRACUNIT / 10);
if (leveltime & 1)
{
mul = -mul;
}
interpx += FixedMul(thing->momx, mul);
interpy += FixedMul(thing->momy, mul);
interpz += FixedMul(thing->momz, mul);
}
// sprite offset
interpx += thing->sprxoff;
interpy += thing->spryoff;
interpz += thing->sprzoff;
if (! R_ThingVisible(thing)) if (! R_ThingVisible(thing))
return; return;
tr_x = (thingxpos + sort_x) - viewx; tr_x = (interpx + sort_x) - viewx;
tr_y = (thingypos + sort_y) - viewy; tr_y = (interpy + sort_y) - viewy;
tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
linkscale = FixedDiv(projectiony[viewssnum], tz); linkscale = FixedDiv(projectiony[viewssnum], tz);
@ -1775,8 +1822,8 @@ static void R_ProjectSprite(mobj_t *thing)
} }
else if (splat) else if (splat)
{ {
tr_x = (thingxpos + sort_x) - viewx; tr_x = (interpx + sort_x) - viewx;
tr_y = (thingypos + sort_y) - viewy; tr_y = (interpy + sort_y) - viewy;
sort_z = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); sort_z = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
sortscale = FixedDiv(projectiony[viewssnum], sort_z); sortscale = FixedDiv(projectiony[viewssnum], sort_z);
} }
@ -1796,7 +1843,7 @@ static void R_ProjectSprite(mobj_t *thing)
if (x2 < portalclipstart || x1 >= portalclipend) if (x2 < portalclipstart || x1 >= portalclipend)
return; return;
if (P_PointOnLineSide(thingxpos, thingypos, portalclipline) != 0) if (P_PointOnLineSide(interpx, interpy, portalclipline) != 0)
return; return;
} }
@ -1865,12 +1912,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. // 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. // 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! // remember gz and gzt should be seperated by sprite height, not thing height - thing height can be shorter than the sprite itself sometimes!
gz = oldthingzpos + 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)); gzt = gz + FixedMul(spr_height, FixedMul(spriteyscale, this_scale));
} }
else else
{ {
gzt = oldthingzpos + 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)); gz = gzt - FixedMul(spr_height, FixedMul(spriteyscale, this_scale));
} }
} }
@ -1889,7 +1936,7 @@ static void R_ProjectSprite(mobj_t *thing)
// R_GetPlaneLight won't work on sloped lights! // R_GetPlaneLight won't work on sloped lights!
for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) { for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) {
fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], thingxpos, thingypos); fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], interpx, interpy);
if (h <= top) { if (h <= top) {
light = lightnum - 1; light = lightnum - 1;
break; break;
@ -1907,7 +1954,7 @@ static void R_ProjectSprite(mobj_t *thing)
} }
heightsec = thing->subsector->sector->heightsec; heightsec = thing->subsector->sector->heightsec;
if (viewplayer->mo && viewplayer->mo->subsector) if (viewplayer && viewplayer->mo && viewplayer->mo->subsector)
phs = viewplayer->mo->subsector->sector->heightsec; phs = viewplayer->mo->subsector->sector->heightsec;
else else
phs = -1; phs = -1;
@ -1915,12 +1962,12 @@ static void R_ProjectSprite(mobj_t *thing)
if (heightsec != -1 && phs != -1) // only clip things which are in special sectors if (heightsec != -1 && phs != -1) // only clip things which are in special sectors
{ {
if (viewz < sectors[phs].floorheight ? if (viewz < sectors[phs].floorheight ?
thingzpos >= sectors[heightsec].floorheight : interpz >= sectors[heightsec].floorheight :
gzt < sectors[heightsec].floorheight) gzt < sectors[heightsec].floorheight)
return; return;
if (viewz > sectors[phs].ceilingheight ? if (viewz > sectors[phs].ceilingheight ?
gzt < sectors[heightsec].ceilingheight && viewz >= sectors[heightsec].ceilingheight : gzt < sectors[heightsec].ceilingheight && viewz >= sectors[heightsec].ceilingheight :
thingzpos >= sectors[heightsec].ceilingheight) interpz >= sectors[heightsec].ceilingheight)
return; return;
} }
@ -1933,12 +1980,12 @@ static void R_ProjectSprite(mobj_t *thing)
vis->sortscale = sortscale; vis->sortscale = sortscale;
vis->sortsplat = sortsplat; vis->sortsplat = sortsplat;
vis->dispoffset = dispoffset; // Monster Iestyn: 23/11/15 vis->dispoffset = dispoffset; // Monster Iestyn: 23/11/15
vis->gx = thingxpos; vis->gx = interpx;
vis->gy = thingypos; vis->gy = interpy;
vis->gz = gz; vis->gz = gz;
vis->gzt = gzt; vis->gzt = gzt;
vis->thingheight = thing->height; vis->thingheight = thing->height;
vis->pz = thingzpos; vis->pz = interpz;
vis->pzt = vis->pz + vis->thingheight; vis->pzt = vis->pz + vis->thingheight;
vis->texturemid = FixedDiv(gzt - viewz, spriteyscale); vis->texturemid = FixedDiv(gzt - viewz, spriteyscale);
vis->scalestep = scalestep; vis->scalestep = scalestep;
@ -2073,9 +2120,22 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
//SoM: 3/17/2000 //SoM: 3/17/2000
fixed_t gz, gzt; 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 // transform the origin point
tr_x = thing->x - viewx; tr_x = interpx - viewx;
tr_y = thing->y - viewy; tr_y = interpy - viewy;
tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance
@ -2139,12 +2199,12 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
if (x2 < portalclipstart || x1 >= portalclipend) if (x2 < portalclipstart || x1 >= portalclipend)
return; return;
if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0) if (P_PointOnLineSide(interpx, interpy, portalclipline) != 0)
return; return;
} }
//SoM: 3/17/2000: Disregard sprites that are out of view.. //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; gz = gzt - spritecachedinfo[lump].height;
if (thing->subsector->sector->cullheight) if (thing->subsector->sector->cullheight)
@ -2157,10 +2217,13 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
vis = R_NewVisSprite(); vis = R_NewVisSprite();
vis->scale = vis->sortscale = yscale; //<<detailshift; vis->scale = vis->sortscale = yscale; //<<detailshift;
vis->dispoffset = 0; // Monster Iestyn: 23/11/15 vis->dispoffset = 0; // Monster Iestyn: 23/11/15
vis->gx = thing->x; vis->gx = interpx;
vis->gy = thing->y; vis->gy = interpy;
vis->gz = gz; vis->gz = gz;
vis->gzt = gzt; vis->gzt = gzt;
vis->thingheight = 4*FRACUNIT;
vis->pz = interpz;
vis->pzt = vis->pz + vis->thingheight;
vis->texturemid = vis->gzt - viewz; vis->texturemid = vis->gzt - viewz;
vis->scalestep = 0; vis->scalestep = 0;
vis->paperdistance = 0; vis->paperdistance = 0;

View file

@ -181,7 +181,7 @@ static char returnWadPath[256];
#include "../m_argv.h" #include "../m_argv.h"
#include "../m_menu.h" #include "../r_main.h" // Frame interpolation/uncapped
#ifdef MAC_ALERT #ifdef MAC_ALERT
#include "macosx/mac_alert.h" #include "macosx/mac_alert.h"
@ -1640,17 +1640,29 @@ static Uint64 timer_frequency;
static double tic_frequency; static double tic_frequency;
static Uint64 tic_epoch; 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) tic_t I_GetTime(void)
{ {
static double elapsed; double f = 0.0;
UpdateElapsedTics();
f = floor(elapsed_tics);
return (tic_t)f;
}
const Uint64 now = SDL_GetPerformanceCounter(); fixed_t I_GetTimeFrac(void)
{
elapsed += (now - tic_epoch) / tic_frequency; UpdateElapsedTics();
tic_epoch = now; // moving epoch
return FLOAT_TO_FIXED((float) (elapsed_tics - floor(elapsed_tics)));
return (tic_t)elapsed;
} }
precise_t I_GetPreciseTime(void) precise_t I_GetPreciseTime(void)
@ -1672,6 +1684,7 @@ void I_StartupTimer(void)
tic_epoch = SDL_GetPerformanceCounter(); tic_epoch = SDL_GetPerformanceCounter();
tic_frequency = timer_frequency / (double)NEWTICRATE; tic_frequency = timer_frequency / (double)NEWTICRATE;
elapsed_tics = 0.0;
} }
void I_Sleep(void) void I_Sleep(void)

View file

@ -1260,6 +1260,7 @@ void ST_Drawer(void)
if (rendermode != render_none) ST_doPaletteStuff(); if (rendermode != render_none) ST_doPaletteStuff();
{ {
#if 0
const tic_t length = TICRATE/2; const tic_t length = TICRATE/2;
if (lt_exitticker) if (lt_exitticker)
@ -1270,6 +1271,9 @@ void ST_Drawer(void)
} }
else else
st_translucency = 0; st_translucency = 0;
#else
st_translucency = cv_translucenthud.value;
#endif
} }
// Check for a valid level title // Check for a valid level title

View file

@ -45,6 +45,7 @@
#include "../d_main.h" #include "../d_main.h"
#include "../m_argv.h" #include "../m_argv.h"
#include "../m_fixed.h"
#include "../w_wad.h" #include "../w_wad.h"
#include "../z_zone.h" #include "../z_zone.h"
@ -261,6 +262,11 @@ tic_t I_GetTime(void)
return newtics; return newtics;
} }
fixed_t I_GetTimeFrac(void)
{
return 0;
}
void I_Sleep(void) void I_Sleep(void)
{ {
if (cv_sleep.value > 0) if (cv_sleep.value > 0)