Added silent line teleport prediction

- Allow activation of line teleport specials during prediction
- Moved prediction functions to improve uncapped framerates
This commit is contained in:
Edward Richardson 2014-08-23 15:17:11 +12:00
parent ad0a1ad865
commit 53b6e7d4d5
7 changed files with 107 additions and 13 deletions

View file

@ -756,9 +756,9 @@ void D_Display ()
} }
screen->SetBlendingRect(viewwindowx, viewwindowy, screen->SetBlendingRect(viewwindowx, viewwindowy,
viewwindowx + viewwidth, viewwindowy + viewheight); viewwindowx + viewwidth, viewwindowy + viewheight);
P_PredictPlayer(&players[consoleplayer]); //P_PredictPlayer(&players[consoleplayer]);
Renderer->RenderView(&players[consoleplayer]); Renderer->RenderView(&players[consoleplayer]);
P_UnPredictPlayer(); //P_UnPredictPlayer();
if ((hw2d = screen->Begin2D(viewactive))) if ((hw2d = screen->Begin2D(viewactive)))
{ {
// Redraw everything every frame when using 2D accel // Redraw everything every frame when using 2D accel

View file

@ -380,7 +380,9 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra
// ... and some items can never be telefragged while others will be telefragged by everything that teleports upon them. // ... and some items can never be telefragged while others will be telefragged by everything that teleports upon them.
if ((StompAlwaysFrags && !(th->flags6 & MF6_NOTELEFRAG)) || (th->flags7 & MF7_ALWAYSTELEFRAG)) if ((StompAlwaysFrags && !(th->flags6 & MF6_NOTELEFRAG)) || (th->flags7 & MF7_ALWAYSTELEFRAG))
{ {
P_DamageMobj(th, thing, thing, TELEFRAG_DAMAGE, NAME_Telefrag, DMG_THRUSTLESS); // Don't actually damage if predicting a teleport
if (thing->player == NULL || !(thing->player->cheats & CF_PREDICTING))
P_DamageMobj(th, thing, thing, TELEFRAG_DAMAGE, NAME_Telefrag, DMG_THRUSTLESS);
continue; continue;
} }
return false; return false;
@ -1981,13 +1983,6 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
thing->AdjustFloorClip(); thing->AdjustFloorClip();
} }
// [RH] Don't activate anything if just predicting
if (thing->player && (thing->player->cheats & CF_PREDICTING))
{
thing->flags6 &= ~MF6_INTRYMOVE;
return true;
}
// if any special lines were hit, do the effect // if any special lines were hit, do the effect
if (!(thing->flags & (MF_TELEPORT | MF_NOCLIP))) if (!(thing->flags & (MF_TELEPORT | MF_NOCLIP)))
{ {
@ -1998,7 +1993,11 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
oldside = P_PointOnLineSide(oldx, oldy, ld); oldside = P_PointOnLineSide(oldx, oldy, ld);
if (side != oldside && ld->special && !(thing->flags6 & MF6_NOTRIGGER)) if (side != oldside && ld->special && !(thing->flags6 & MF6_NOTRIGGER))
{ {
if (thing->player) if (thing->player && (thing->player->cheats & CF_PREDICTING))
{
P_PredictLine(ld, thing, oldside, SPAC_Cross);
}
else if (thing->player)
{ {
P_ActivateLine(ld, thing, oldside, SPAC_Cross); P_ActivateLine(ld, thing, oldside, SPAC_Cross);
} }
@ -2024,6 +2023,13 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
} }
} }
// [RH] Don't activate anything if just predicting
if (thing->player && (thing->player->cheats & CF_PREDICTING))
{
thing->flags6 &= ~MF6_INTRYMOVE;
return true;
}
// [RH] Check for crossing fake floor/ceiling // [RH] Check for crossing fake floor/ceiling
newsec = thing->Sector; newsec = thing->Sector;
if (newsec->heightsec && oldsec->heightsec && newsec->SecActTarget) if (newsec->heightsec && oldsec->heightsec && newsec->SecActTarget)

View file

@ -73,6 +73,7 @@
static FRandom pr_playerinspecialsector ("PlayerInSpecialSector"); static FRandom pr_playerinspecialsector ("PlayerInSpecialSector");
void P_SetupPortals(); void P_SetupPortals();
EXTERN_CVAR(Bool, cl_predict_specials)
IMPLEMENT_POINTY_CLASS (DScroller) IMPLEMENT_POINTY_CLASS (DScroller)
DECLARE_POINTER (m_Interpolations[0]) DECLARE_POINTER (m_Interpolations[0])
@ -408,6 +409,47 @@ bool P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType)
return true; return true;
} }
//============================================================================
//
// P_PredictLine
//
//============================================================================
bool P_PredictLine(line_t *line, AActor *mo, int side, int activationType)
{
int lineActivation;
INTBOOL buttonSuccess;
BYTE special;
// Only predict a very specifc section of specials
if (line->special != Teleport_Line)
{
return false;
}
if (!P_TestActivateLine(line, mo, side, activationType) || !cl_predict_specials)
{
return false;
}
if (line->locknumber > 0) return false;
lineActivation = line->activation;
buttonSuccess = false;
buttonSuccess = P_ExecuteSpecial(line->special,
line, mo, side == 1, line->args[0],
line->args[1], line->args[2],
line->args[3], line->args[4]);
special = line->special;
// end of changed code
if (developer && buttonSuccess)
{
Printf("Line special %d predicted on line %i\n", special, int(line - lines));
}
return true;
}
// //
// P_PlayerInSpecialSector // P_PlayerInSpecialSector
// Called every tic frame // Called every tic frame

View file

@ -166,6 +166,7 @@ void P_UpdateSpecials (void);
// when needed // when needed
bool P_ActivateLine (line_t *ld, AActor *mo, int side, int activationType); bool P_ActivateLine (line_t *ld, AActor *mo, int side, int activationType);
bool P_TestActivateLine (line_t *ld, AActor *mo, int side, int activationType); bool P_TestActivateLine (line_t *ld, AActor *mo, int side, int activationType);
bool P_PredictLine (line_t *ld, AActor *mo, int side, int activationType);
void P_PlayerInSpecialSector (player_t *player, sector_t * sector=NULL); void P_PlayerInSpecialSector (player_t *player, sector_t * sector=NULL);
void P_PlayerOnSpecialFlat (player_t *player, int floorType); void P_PlayerOnSpecialFlat (player_t *player, int floorType);

View file

@ -62,6 +62,7 @@ static FRandom pr_skullpop ("SkullPop");
// Variables for prediction // Variables for prediction
CVAR (Bool, cl_noprediction, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, cl_noprediction, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR(Bool, cl_predict_specials, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
static player_t PredictionPlayerBackup; static player_t PredictionPlayerBackup;
static BYTE PredictionActorBackup[sizeof(AActor)]; static BYTE PredictionActorBackup[sizeof(AActor)];
static TArray<sector_t *> PredictionTouchingSectorsBackup; static TArray<sector_t *> PredictionTouchingSectorsBackup;
@ -2722,14 +2723,16 @@ void P_PredictPlayer (player_t *player)
} }
act->BlockNode = NULL; act->BlockNode = NULL;
bool NoInterpolateOld = R_GetViewInterpolationStatus();
for (int i = gametic; i < maxtic; ++i) for (int i = gametic; i < maxtic; ++i)
{ {
if (!NoInterpolateOld)
R_RebuildViewInterpolation(player);
player->cmd = localcmds[i % LOCALCMDTICS]; player->cmd = localcmds[i % LOCALCMDTICS];
P_PlayerThink (player); P_PlayerThink (player);
player->mo->Tick (); player->mo->Tick ();
} }
S_UpdateSounds(players[consoleplayer].camera); // move positional sounds
} }
extern msecnode_t *P_AddSecnode (sector_t *s, AActor *thing, msecnode_t *nextnode); extern msecnode_t *P_AddSecnode (sector_t *s, AActor *thing, msecnode_t *nextnode);

View file

@ -729,6 +729,46 @@ void R_ClearPastViewer (AActor *actor)
} }
} }
//==========================================================================
//
// R_RebuildViewInterpolation
//
//==========================================================================
void R_RebuildViewInterpolation(player_t *player)
{
InterpolationViewer *iview;
if (NoInterpolateView)
{
if (player != NULL && player->camera != NULL)
{
iview = FindPastViewer(player->camera);
}
if (iview == NULL)
return;
NoInterpolateView = false;
iview->oviewx = iview->nviewx;
iview->oviewy = iview->nviewy;
iview->oviewz = iview->nviewz;
iview->oviewpitch = iview->nviewpitch;
iview->oviewangle = iview->nviewangle;
}
}
//==========================================================================
//
// R_GetViewInterpolationStatus
//
//==========================================================================
bool R_GetViewInterpolationStatus()
{
return NoInterpolateView;
}
//========================================================================== //==========================================================================
// //
// R_SetupFrame // R_SetupFrame

View file

@ -61,6 +61,8 @@ inline angle_t R_PointToAngle (fixed_t x, fixed_t y) { return R_PointToAngle2 (v
subsector_t *R_PointInSubsector (fixed_t x, fixed_t y); subsector_t *R_PointInSubsector (fixed_t x, fixed_t y);
fixed_t R_PointToDist2 (fixed_t dx, fixed_t dy); fixed_t R_PointToDist2 (fixed_t dx, fixed_t dy);
void R_ResetViewInterpolation (); void R_ResetViewInterpolation ();
void R_RebuildViewInterpolation(player_t *player);
bool R_GetViewInterpolationStatus();
void R_SetViewSize (int blocks); void R_SetViewSize (int blocks);
void R_SetFOV (float fov); void R_SetFOV (float fov);
float R_GetFOV (); float R_GetFOV ();