This repository has been archived on 2022-06-27. You can view files and clone it, but cannot push or open issues or pull requests.
Xash3DArchive/engine/client/cl_move.c

136 lines
3.3 KiB
C

//=======================================================================
// Copyright XashXT Group 2008 ©
// cl_physics.c - client physic and prediction
//=======================================================================
#include "common.h"
#include "client.h"
#include "matrix_lib.h"
#include "const.h"
#include "pm_defs.h"
/*
===================
CL_CheckPredictionError
===================
*/
void CL_CheckPredictionError( void )
{
int frame;
vec3_t delta;
edict_t *player;
if( !cl_predict->integer ) return;
player = CL_GetLocalPlayer();
// calculate the last usercmd_t we sent that the server has processed
frame = cls.netchan.incoming_acknowledged;
frame &= CMD_MASK;
// compare what the server returned with what we had predicted it to be
VectorSubtract( player->v.origin, cl.predicted_origins[frame], delta );
if( player->pvClientData->current.ed_flags & ESF_NO_PREDICTION )
{
// a teleport or something
VectorClear( cl.prediction_error );
}
else
{
if( cl_showmiss->integer && ( delta[0] || delta[1] || delta[2] ))
Msg( "prediction miss on %i: %g\n", cl.frame.serverframe, delta[0] + delta[1] + delta[2]);
VectorCopy( player->v.origin, cl.predicted_origins[frame] );
// save for error itnerpolation
VectorCopy( delta, cl.prediction_error );
}
}
/*
=================
CL_PredictMovement
Sets cl.predicted_origin and cl.predicted_angles
=================
*/
void CL_PredictMovement( void )
{
int ack, current;
int frame;
int oldframe;
usercmd_t *cmd;
edict_t *player, *viewent;
int i;
float step;
float oldz;
if( cls.state != ca_active ) return;
if( cl.refdef.paused ) return;
player = CL_GetLocalPlayer ();
viewent = CL_GetEdictByIndex( cl.refdef.viewentity );
if( cls.demoplayback )
{
// interpolate server values
for( i = 0; viewent && i < 3; i++ )
cl.refdef.cl_viewangles[i] = viewent->v.viewangles[i];
}
// unpredicted pure angled values converted into axis
AngleVectors( cl.refdef.cl_viewangles, cl.refdef.forward, cl.refdef.right, cl.refdef.up );
if( !cl_predict->value || player->pvClientData->current.ed_flags & ESF_NO_PREDICTION )
{
// just set angles
for( i = 0; i < 3; i++ )
cl.predicted_angles[i] = cl.refdef.cl_viewangles[i];
return;
}
ack = cls.netchan.incoming_acknowledged;
current = cls.netchan.outgoing_sequence;
// if we are too far out of date, just freeze
if( current - ack >= CMD_BACKUP )
{
if( cl_showmiss->value )
Msg( "exceeded CMD_BACKUP\n" );
return;
}
frame = 0;
// run frames
while( ++ack < current )
{
frame = ack & CMD_MASK;
cmd = &cl.cmds[frame];
// call pfnPM_Move here
// save for debug checking
VectorCopy( clgame.pmove->origin, cl.predicted_origins[frame] );
}
oldframe = (ack- 2 ) & CMD_MASK;
if( player->v.flags & FL_ONGROUND )
{
oldz = cl.predicted_origins[oldframe][2];
step = clgame.pmove->origin[2] - oldz;
if( step > 63 && step < 160 )
{
cl.predicted_step = step;
cl.predicted_step_time = cls.realtime - cls.frametime * 500;
}
}
// copy results out for rendering
VectorCopy( clgame.pmove->origin, cl.predicted_origin );
VectorCopy( clgame.pmove->angles, cl.predicted_angles );
}