17 Sep 2009
This commit is contained in:
parent
c5728bf91e
commit
9cc19b4eec
|
@ -95,7 +95,6 @@ typedef struct entity_state_s
|
|||
float maxspeed; // min( pev->maxspeed, sv_maxspeed->value )
|
||||
float health; // client health (other parms can be send by custom messages)
|
||||
int weapons; // weapon flags
|
||||
float cmdtime; // prediction stuff
|
||||
float fov; // horizontal field of view
|
||||
} entity_state_t;
|
||||
|
||||
|
|
|
@ -191,11 +191,11 @@ void CL_LevelShot_f( void )
|
|||
{
|
||||
string checkname;
|
||||
|
||||
if( !clgame.need_levelshot ) return;
|
||||
if( !cl.need_levelshot ) return;
|
||||
// check for exist
|
||||
com.sprintf( checkname, "levelshots/%s.jpg", cl.configstrings[CS_NAME] );
|
||||
if( !FS_FileExists( checkname )) re->ScrShot( checkname, VID_LEVELSHOT );
|
||||
clgame.need_levelshot = false; // done
|
||||
cl.need_levelshot = false; // done
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -58,6 +58,7 @@ void CL_WriteDemoHeader( const char *name )
|
|||
MSG_WriteByte( &buf, svc_serverdata );
|
||||
MSG_WriteLong( &buf, PROTOCOL_VERSION );
|
||||
MSG_WriteLong( &buf, cl.servercount );
|
||||
MSG_WriteLong( &buf, cl.serverframetime );
|
||||
MSG_WriteShort( &buf, cl.playernum );
|
||||
MSG_WriteString( &buf, cl.configstrings[CS_NAME] );
|
||||
|
||||
|
|
|
@ -60,10 +60,10 @@ void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t
|
|||
// some data changes will force no lerping
|
||||
if( state->ed_flags & ESF_NODELTA )
|
||||
{
|
||||
ent->pvClientData->msgnum = -1;
|
||||
ent->pvClientData->serverframe = -99;
|
||||
}
|
||||
|
||||
if( ent->pvClientData->msgnum != cl.frame.msgnum - 1 )
|
||||
if( ent->pvClientData->serverframe != cl.frame.serverframe - 1 )
|
||||
{
|
||||
// duplicate the current state so lerping doesn't hurt anything
|
||||
ent->pvClientData->prev = *state;
|
||||
|
@ -73,10 +73,10 @@ void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t
|
|||
ent->pvClientData->prev = ent->pvClientData->current;
|
||||
}
|
||||
|
||||
ent->pvClientData->msgnum = cl.frame.msgnum;
|
||||
ent->pvClientData->serverframe = cl.frame.serverframe;
|
||||
ent->pvClientData->current = *state;
|
||||
|
||||
// update edict fields
|
||||
// update prvm fields
|
||||
CL_UpdateEntityFields( ent );
|
||||
}
|
||||
|
||||
|
@ -200,209 +200,45 @@ Determines the fraction between the last two messages that the objects
|
|||
should be put at.
|
||||
===============
|
||||
*/
|
||||
static float CL_LerpPoint1( void )
|
||||
static float CL_LerpPoint( void )
|
||||
{
|
||||
float f, frac;
|
||||
|
||||
f = cl.time - cl.oldtime;
|
||||
f = cl.mtime[0] - cl.mtime[1];
|
||||
|
||||
if( !f || SV_Active())
|
||||
if( !f )
|
||||
{
|
||||
cl.time = cl.mtime[0];
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
if( f > 0.1 )
|
||||
{
|
||||
// dropped packet, or start of demo
|
||||
// cl.mtime[1] = cl.mtime[0] - 0.1f;
|
||||
cl.mtime[1] = cl.mtime[0] - 0.1f;
|
||||
f = 0.1f;
|
||||
}
|
||||
|
||||
frac = (cl.time - cl.oldtime) / f;
|
||||
frac = (cl.time - cl.mtime[1]) / f;
|
||||
if( frac < 0 )
|
||||
{
|
||||
if( frac < -0.01f )
|
||||
{
|
||||
// cl.time = cl.mtime[1];
|
||||
cl.time = cl.mtime[1];
|
||||
}
|
||||
frac = 0.0f;
|
||||
frac = 0;
|
||||
}
|
||||
else if( frac > 1.0f )
|
||||
{
|
||||
if( frac > 1.01f )
|
||||
{
|
||||
// cl.time = cl.mtime[0];
|
||||
cl.time = cl.mtime[0];
|
||||
}
|
||||
frac = 1.0f;
|
||||
}
|
||||
return frac;
|
||||
}
|
||||
|
||||
static float CL_LerpPoint2( void )
|
||||
{
|
||||
float lerpfrac;
|
||||
|
||||
// clamp time
|
||||
if( cl.time > cl.frame.servertime )
|
||||
{
|
||||
if( cl_showclamp->integer ) Msg( "cl highclamp\n" );
|
||||
// cl.time = cl.frame.servertime;
|
||||
lerpfrac = 1.0f;
|
||||
}
|
||||
else if( cl.time < cl.frame.servertime - cl.frametime )
|
||||
{
|
||||
if( cl_showclamp->integer ) Msg( "cl lowclamp\n" );
|
||||
// cl.time = cl.frame.servertime - cl.frametime;
|
||||
lerpfrac = 0.0f;
|
||||
}
|
||||
else lerpfrac = 1.0f - (cl.frame.servertime - cl.time) / cl.frametime;
|
||||
|
||||
if( cl_paused->integer )
|
||||
lerpfrac = 1.0f;
|
||||
|
||||
return lerpfrac;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_FirstSnapshot
|
||||
==================
|
||||
*/
|
||||
void CL_FirstSnapshot( void )
|
||||
{
|
||||
cls.state = ca_active;
|
||||
|
||||
// set the timedelta so we are exactly on this first frame
|
||||
cl.time_delta = cl.frame.servertime - cls.realtime;
|
||||
cl.oldtime = cl.frame.servertime;
|
||||
|
||||
// getting a valid frame message ends the connection process
|
||||
VectorCopy( cl.frame.ps.origin, cl.predicted_origin );
|
||||
VectorCopy( cl.frame.ps.viewangles, cl.predicted_angles );
|
||||
}
|
||||
|
||||
void CL_AdjustTimeDelta( void )
|
||||
{
|
||||
float newDelta;
|
||||
float deltaDelta;
|
||||
|
||||
cl.has_newframe = false;
|
||||
|
||||
// the delta never drifts when replaying a demo
|
||||
if( cls.demoplayback ) return;
|
||||
|
||||
newDelta = cl.frame.servertime - cls.realtime;
|
||||
deltaDelta = fabs( newDelta - cl.time_delta );
|
||||
|
||||
if( deltaDelta > 0.5f )
|
||||
{
|
||||
cl.time_delta = newDelta;
|
||||
cl.oldtime = cl.frame.servertime; // FIXME: is this a problem for cgame?
|
||||
cl.time = cl.frame.servertime;
|
||||
Msg( "<RESET> " );
|
||||
}
|
||||
else if( deltaDelta > 0.1f )
|
||||
{
|
||||
// fast adjust, cut the difference in half
|
||||
cl.time_delta = ( cl.time_delta + newDelta ) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// slow drift adjust, only move 1 or 2 msec
|
||||
|
||||
// if any of the frames between this and the previous snapshot
|
||||
// had to be extrapolated, nudge our sense of time back a little
|
||||
// the granularity of +1 / -2 is too high for timescale modified frametimes
|
||||
if( cl.frame_extrapolate )
|
||||
{
|
||||
cl.frame_extrapolate = false;
|
||||
cl.time_delta -= 0.002f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise, move our sense of time forward to minimize total latency
|
||||
cl.time_delta += 0.001f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_SetClientTime
|
||||
|
||||
set right client time and calc lerp value
|
||||
================
|
||||
*/
|
||||
void CL_SetClientTime( void )
|
||||
{
|
||||
float tn;
|
||||
|
||||
// getting a valid frame message ends the connection process
|
||||
if( cls.state != ca_active )
|
||||
{
|
||||
if( cls.state != ca_connected ) return;
|
||||
|
||||
if( cls.demoplayback )
|
||||
{
|
||||
CL_ReadDemoMessage();
|
||||
}
|
||||
if( cl.has_newframe )
|
||||
{
|
||||
cl.has_newframe = false;
|
||||
CL_FirstSnapshot();
|
||||
}
|
||||
if( cls.state != ca_active ) return;
|
||||
}
|
||||
|
||||
// if we have gotten to this point, cl.snap is guaranteed to be valid
|
||||
Com_Assert( !cl.frame.valid );
|
||||
|
||||
// allow pause in single player
|
||||
if( SV_Active() && cl_paused->integer ) return;
|
||||
|
||||
// cl_timeNudge is a user adjustable cvar that allows more
|
||||
// or less latency to be added in the interest of better
|
||||
// smoothness or better responsiveness.
|
||||
tn = cl_timenudge->integer * 0.001f;
|
||||
if( tn < -0.03f ) tn = -0.03f;
|
||||
else if( tn > 0.03f ) tn = 0.03f;
|
||||
|
||||
cl.time = cls.realtime + cl.time_delta - tn;
|
||||
|
||||
cl.frametime = cl.time - cl.oldtime;
|
||||
if( cl.frametime < 0 ) cl.frametime = 0;
|
||||
|
||||
// guarantee that time will never flow backwards, even if
|
||||
// serverTimeDelta made an adjustment or cl_timeNudge was changed
|
||||
if( cl.time < cl.oldtime ) cl.time = cl.oldtime;
|
||||
cl.oldtime = cl.time;
|
||||
|
||||
// note if we are almost past the latest frame (without timeNudge),
|
||||
// so we will try and adjust back a bit when the next snapshot arrives
|
||||
if( cls.realtime + cl.time_delta >= cl.frame.servertime - 0.005f )
|
||||
cl.frame_extrapolate = true;
|
||||
|
||||
// if we have gotten new snapshots, drift serverTimeDelta
|
||||
// don't do this every frame, or a period of packet loss would
|
||||
// make a huge adjustment
|
||||
if( cl.has_newframe ) CL_AdjustTimeDelta();
|
||||
|
||||
#if 1
|
||||
cl.refdef.lerpfrac = CL_LerpPoint1();
|
||||
#else
|
||||
// set cl.refdef.lerpfrac
|
||||
if( cl.oldframe )
|
||||
{
|
||||
float delta;
|
||||
|
||||
delta = (cl.frame.servertime - cl.oldframe->servertime);
|
||||
if( delta == 0.0f ) cl.refdef.lerpfrac = 0.0f;
|
||||
else cl.refdef.lerpfrac = (cl.time - cl.oldframe->servertime) / delta;
|
||||
}
|
||||
else cl.refdef.lerpfrac = 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_ParseFrame
|
||||
|
@ -411,23 +247,20 @@ CL_ParseFrame
|
|||
void CL_ParseFrame( sizebuf_t *msg )
|
||||
{
|
||||
int cmd, len, idx;
|
||||
int delta_num;
|
||||
int old_msgnum;
|
||||
int packet_num;
|
||||
edict_t *clent;
|
||||
|
||||
Mem_Set( &cl.frame, 0, sizeof( cl.frame ));
|
||||
|
||||
cl.frame.msgnum = cls.netchan.incoming_sequence;
|
||||
cl.frame.servertime = MSG_ReadFloat( msg );
|
||||
delta_num = MSG_ReadByte( msg );
|
||||
cl.frame.serverframe = MSG_ReadLong( msg );
|
||||
cl.serverframetime = MSG_ReadFloat( msg );
|
||||
cl.frame.deltaframe = MSG_ReadLong( msg );
|
||||
cl.surpressCount = MSG_ReadByte( msg );
|
||||
cl.frame.servertime = cl.mtime[0]; // same as servertime
|
||||
|
||||
if( !delta_num ) cl.frame.deltaframe = -1;
|
||||
else cl.frame.deltaframe = cl.frame.msgnum - delta_num;
|
||||
|
||||
// If the frame is delta compressed from data that we no longer
|
||||
// have available, we must suck up the rest of the frame,
|
||||
// but not use it, then ask for a non-compressed message
|
||||
// If the frame is delta compressed from data that we
|
||||
// no longer have available, we must suck up the rest of
|
||||
// the frame, but not use it, then ask for a non-compressed
|
||||
// message
|
||||
if( cl.frame.deltaframe <= 0 )
|
||||
{
|
||||
cl.frame.valid = true; // uncompressed frame
|
||||
|
@ -442,11 +275,11 @@ void CL_ParseFrame( sizebuf_t *msg )
|
|||
// should never happen
|
||||
MsgDev( D_INFO, "delta from invalid frame (not supposed to happen!).\n" );
|
||||
}
|
||||
if( cl.oldframe->msgnum != cl.frame.deltaframe )
|
||||
if( cl.oldframe->serverframe != cl.frame.deltaframe )
|
||||
{
|
||||
// The frame that the server did the delta from
|
||||
// is too old, so we can't reconstruct it properly.
|
||||
MsgDev( D_INFO, "delta frame too old.\n" );
|
||||
MsgDev( D_INFO, "Delta frame too old.\n" );
|
||||
}
|
||||
else if( cl.parse_entities - cl.oldframe->parse_entities > MAX_PARSE_ENTITIES - 128 )
|
||||
{
|
||||
|
@ -455,14 +288,12 @@ void CL_ParseFrame( sizebuf_t *msg )
|
|||
else cl.frame.valid = true; // valid delta parse
|
||||
}
|
||||
|
||||
cl.time = bound( cl.frame.servertime - cl.serverframetime, cl.time, cl.frame.servertime );
|
||||
|
||||
// read areabits
|
||||
len = MSG_ReadByte( msg );
|
||||
MSG_ReadData( msg, &cl.frame.areabits, len );
|
||||
|
||||
if( cl.oldframe && !memcmp( cl.oldframe->areabits, cl.frame.areabits, sizeof( cl.frame.areabits )))
|
||||
cl.render_flags |= RDF_OLDAREABITS;
|
||||
else cl.render_flags &= ~RDF_OLDAREABITS;
|
||||
|
||||
// read clientindex
|
||||
cmd = MSG_ReadByte( msg );
|
||||
if( cmd != svc_playerinfo ) Host_Error( "CL_ParseFrame: not clientindex\n" );
|
||||
|
@ -480,40 +311,20 @@ void CL_ParseFrame( sizebuf_t *msg )
|
|||
if( cl.oldframe ) cl.frame.ps = MSG_ParseDeltaPlayer( &cl.oldframe->ps, &clent->pvClientData->current );
|
||||
else cl.frame.ps = MSG_ParseDeltaPlayer( NULL, &clent->pvClientData->current );
|
||||
|
||||
// if not valid, dump the entire thing now that it has been properly read
|
||||
if( !cl.frame.valid ) return;
|
||||
|
||||
// clear the valid flags of any snapshots between the last
|
||||
// received and this one, so if there was a dropped packet
|
||||
// it won't look like something valid to delta from next
|
||||
// time we wrap around in the buffer
|
||||
old_msgnum = cl.frame.msgnum + 1;
|
||||
cl.frame.ping = 999;
|
||||
|
||||
if( cl.frame.msgnum - old_msgnum >= UPDATE_BACKUP )
|
||||
old_msgnum = cl.frame.msgnum - UPDATE_MASK;
|
||||
for( ; old_msgnum < cl.frame.msgnum; old_msgnum++ )
|
||||
cl.frames[old_msgnum & UPDATE_MASK].valid = false;
|
||||
|
||||
// calculate ping time
|
||||
for ( idx = 0; idx < UPDATE_BACKUP; idx++ )
|
||||
{
|
||||
packet_num = ( cls.netchan.outgoing_sequence - 1 - idx ) & UPDATE_MASK;
|
||||
if( cl.frame.ps.cmdtime >= cl.outframes[packet_num].servertime )
|
||||
{
|
||||
cl.frame.ping = cls.realtime - cl.outframes[packet_num].realtime;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( cl_shownet->integer == 3 )
|
||||
Msg( " snapshot:%i delta:%i ping:%i\n", cl.frame.msgnum, cl.frame.deltaframe, cl.frame.ping );
|
||||
|
||||
// save the frame off in the backup array for later delta comparisons
|
||||
cl.frames[cl.frame.msgnum & UPDATE_MASK] = cl.frame;
|
||||
cl.has_newframe = true;
|
||||
cl.frames[cl.frame.serverframe & UPDATE_MASK] = cl.frame;
|
||||
|
||||
if( cl.frame.valid )
|
||||
{
|
||||
if( cls.state != ca_active )
|
||||
{
|
||||
cls.state = ca_active;
|
||||
// getting a valid frame message ends the connection process
|
||||
VectorCopy( cl.frame.ps.origin, cl.predicted_origin );
|
||||
VectorCopy( cl.frame.ps.viewangles, cl.predicted_angles );
|
||||
}
|
||||
CL_CheckPredictionError();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -535,6 +346,11 @@ void CL_AddPacketEntities( frame_t *frame )
|
|||
edict_t *ent;
|
||||
int pnum;
|
||||
|
||||
if( cl_paused->integer )
|
||||
cl.refdef.lerpfrac = 1.0f;
|
||||
else cl.refdef.lerpfrac = 1.0 - (cl.frame.servertime - cl.time) / (float)cl.serverframetime;
|
||||
// Msg( "cl.refdef.lerpfrac %g\n", cl.refdef.lerpfrac );
|
||||
|
||||
for( pnum = 0; pnum < frame->num_entities; pnum++ )
|
||||
{
|
||||
s1 = &cl_parse_entities[(frame->parse_entities + pnum)&(MAX_PARSE_ENTITIES-1)];
|
||||
|
@ -549,6 +365,9 @@ void CL_AddPacketEntities( frame_t *frame )
|
|||
// NOTE: skyportal entity never added to rendering
|
||||
if( s1->ed_type == ED_SKYPORTAL ) cl.render_flags |= RDF_SKYPORTALINVIEW;
|
||||
}
|
||||
|
||||
if( cl.oldframe && !memcmp( cl.oldframe->areabits, cl.frame.areabits, sizeof( cl.frame.areabits )))
|
||||
cl.render_flags |= RDF_OLDAREABITS;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -563,6 +382,8 @@ void CL_AddEntities( void )
|
|||
if( cls.state != ca_active )
|
||||
return;
|
||||
|
||||
cl.render_flags = 0;
|
||||
|
||||
CL_AddPacketEntities( &cl.frame );
|
||||
clgame.dllFuncs.pfnCreateEntities();
|
||||
|
||||
|
|
|
@ -725,18 +725,18 @@ void pfnDrawCenterPrint( void )
|
|||
int l, x, y, w;
|
||||
rgba_t color;
|
||||
|
||||
if( !clgame.centerPrintTime ) return;
|
||||
CL_FadeAlpha( clgame.centerPrintTime, scr_centertime->value, color );
|
||||
if( !cl.centerPrintTime ) return;
|
||||
CL_FadeAlpha( cl.centerPrintTime, scr_centertime->value, color );
|
||||
|
||||
if( *( int *)color == 0xFFFFFFFF )
|
||||
{
|
||||
clgame.centerPrintTime = 0;
|
||||
cl.centerPrintTime = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
re->SetColor( color );
|
||||
start = clgame.centerPrint;
|
||||
y = clgame.centerPrintY - clgame.centerPrintLines * BIGCHAR_HEIGHT / 2;
|
||||
start = cl.centerPrint;
|
||||
y = cl.centerPrintY - cl.centerPrintLines * BIGCHAR_HEIGHT / 2;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
|
@ -750,12 +750,12 @@ void pfnDrawCenterPrint( void )
|
|||
}
|
||||
linebuffer[l] = 0;
|
||||
|
||||
w = clgame.centerPrintCharWidth * com.cstrlen( linebuffer );
|
||||
w = cl.centerPrintCharWidth * com.cstrlen( linebuffer );
|
||||
x = ( SCREEN_WIDTH - w )>>1;
|
||||
|
||||
SCR_DrawStringExt( x, y, clgame.centerPrintCharWidth, BIGCHAR_HEIGHT, linebuffer, color, false );
|
||||
SCR_DrawStringExt( x, y, cl.centerPrintCharWidth, BIGCHAR_HEIGHT, linebuffer, color, false );
|
||||
|
||||
y += clgame.centerPrintCharWidth * 1.5;
|
||||
y += cl.centerPrintCharWidth * 1.5;
|
||||
while( *start && ( *start != '\n' )) start++;
|
||||
if( !*start ) break;
|
||||
start++;
|
||||
|
@ -774,18 +774,18 @@ void pfnCenterPrint( const char *text, int y, int charWidth )
|
|||
{
|
||||
char *s;
|
||||
|
||||
com.strncpy( clgame.centerPrint, text, sizeof( clgame.centerPrint ));
|
||||
clgame.centerPrintTime = cls.realtime;
|
||||
clgame.centerPrintY = y;
|
||||
clgame.centerPrintCharWidth = charWidth;
|
||||
com.strncpy( cl.centerPrint, text, sizeof( cl.centerPrint ));
|
||||
cl.centerPrintTime = cls.realtime;
|
||||
cl.centerPrintY = y;
|
||||
cl.centerPrintCharWidth = charWidth;
|
||||
|
||||
// count the number of lines for centering
|
||||
clgame.centerPrintLines = 1;
|
||||
s = clgame.centerPrint;
|
||||
cl.centerPrintLines = 1;
|
||||
s = cl.centerPrint;
|
||||
while( *s )
|
||||
{
|
||||
if( *s == '\n' )
|
||||
clgame.centerPrintLines++;
|
||||
cl.centerPrintLines++;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
@ -921,7 +921,7 @@ force to make levelshot
|
|||
*/
|
||||
void pfnMakeLevelShot( void )
|
||||
{
|
||||
if( !clgame.need_levelshot ) return;
|
||||
if( !cl.need_levelshot ) return;
|
||||
|
||||
Con_ClearNotify();
|
||||
|
||||
|
@ -1424,7 +1424,7 @@ bool CL_LoadProgs( const char *name )
|
|||
// 65535 unique strings should be enough ...
|
||||
clgame.hStringTable = StringTable_Create( "Client", 0x10000 );
|
||||
clgame.maxEntities = host.max_edicts; // FIXME: must come from CS_MAXENTITIES
|
||||
clgame.maxClients = CL_GetMaxClients();
|
||||
clgame.maxClients = Host_MaxClients();
|
||||
clgame.edicts = Mem_Alloc( cls.mempool, sizeof( edict_t ) * clgame.maxEntities );
|
||||
|
||||
// register svc_bad message
|
||||
|
|
|
@ -58,16 +58,8 @@ CL_MouseEvent
|
|||
*/
|
||||
void CL_MouseEvent( int mx, int my )
|
||||
{
|
||||
if( UI_IsVisible( ))
|
||||
{
|
||||
// if the menu is visible, move the menu cursor
|
||||
UI_MouseMove( mx, my );
|
||||
}
|
||||
else
|
||||
{
|
||||
cl.mouse_x[cl.mouse_step] += mx;
|
||||
cl.mouse_y[cl.mouse_step] += my;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -97,10 +89,17 @@ void CL_MouseMove( usercmd_t *cmd )
|
|||
|
||||
rate = com.sqrt( mx * mx + my * my ) / 0.5f;
|
||||
|
||||
if( UI_IsVisible( ))
|
||||
{
|
||||
// if the menu is visible, move the menu cursor
|
||||
UI_MouseMove( mx, my );
|
||||
}
|
||||
else if( cls.key_dest != key_menu )
|
||||
{
|
||||
if( cl.frame.ps.health <= 0 ) return;
|
||||
if( cl.data.mouse_sensitivity == 0.0f ) cl.data.mouse_sensitivity = 1.0f;
|
||||
if( cl.mouse_sens == 0.0f ) cl.mouse_sens = 1.0f;
|
||||
accel_sensitivity = m_sensitivity->value + rate * cl_mouseaccel->value;
|
||||
accel_sensitivity *= cl.data.mouse_sensitivity; // scale by fov
|
||||
accel_sensitivity *= cl.mouse_sens; // scale by fov
|
||||
mx *= accel_sensitivity;
|
||||
my *= accel_sensitivity;
|
||||
|
||||
|
@ -122,6 +121,7 @@ void CL_MouseMove( usercmd_t *cmd )
|
|||
cmd->upmove -= m_forward->value * my;
|
||||
else cmd->forwardmove -= m_forward->value * my;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -497,21 +497,14 @@ CL_FinishMove
|
|||
*/
|
||||
void CL_FinishMove( usercmd_t *cmd )
|
||||
{
|
||||
static double extramsec = 0;
|
||||
int ms;
|
||||
|
||||
// send milliseconds of time to apply the move
|
||||
extramsec += cls.frametime * 1000;
|
||||
ms = extramsec;
|
||||
extramsec -= ms; // fractional part is left for next frame
|
||||
ms = cls.frametime * 1000;
|
||||
if( ms > 250 ) ms = 100; // time was unreasonable
|
||||
|
||||
cmd->msec = ms;
|
||||
|
||||
// send the current server time so the amount of movement
|
||||
// can be determined without allowing cheating
|
||||
cmd->servertime = cl.time;
|
||||
|
||||
if( cls.key_dest == key_game )
|
||||
cmd->buttons = CL_ButtonBits( 1 );
|
||||
|
||||
|
@ -520,6 +513,8 @@ void CL_FinishMove( usercmd_t *cmd )
|
|||
cl.data.iKeyBits = CL_ButtonBits( 0 );
|
||||
|
||||
cl.data.iWeaponBits = cl.frame.ps.weapons;
|
||||
cl.data.mouse_sensitivity = cl.mouse_sens;
|
||||
|
||||
VectorCopy( cl.refdef.cl_viewangles, cmd->angles );
|
||||
VectorCopy( cl.refdef.cl_viewangles, cl.data.angles );
|
||||
VectorCopy( cl.refdef.origin, cl.data.origin );
|
||||
|
@ -528,6 +523,7 @@ void CL_FinishMove( usercmd_t *cmd )
|
|||
|
||||
CL_ResetButtonBits( cl.data.iKeyBits );
|
||||
cl.refdef.fov_x = cl.data.fov;
|
||||
cl.mouse_sens = cl.data.mouse_sensitivity;
|
||||
|
||||
in_cancel = 0;
|
||||
}
|
||||
|
@ -550,200 +546,6 @@ usercmd_t CL_CreateCmd( void )
|
|||
return cmd;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_CreateNewCommands
|
||||
|
||||
Create a new usercmd_t structure for this frame
|
||||
=================
|
||||
*/
|
||||
void CL_CreateNewCommands( void )
|
||||
{
|
||||
int cmdnum;
|
||||
|
||||
// no need to create usercmds until we have a gamestate
|
||||
if( cls.state < ca_connected ) return;
|
||||
|
||||
// reset render flags here, to can add RDF_OLDAREABITS without temp variables
|
||||
cl.render_flags = 0;
|
||||
|
||||
// generate a command for this frame
|
||||
cl.cmd_number++;
|
||||
cmdnum = cl.cmd_number & CMD_MASK;
|
||||
cl.cmds[cmdnum] = CL_CreateCmd();
|
||||
|
||||
if( freelook->modified )
|
||||
{
|
||||
if( !mlook_active && lookspring->value )
|
||||
clgame.dllFuncs.pfnStartPitchDrift();
|
||||
}
|
||||
|
||||
if( cls.state == ca_connected )
|
||||
{
|
||||
// jsut update reliable
|
||||
if( cls.netchan.message.cursize || cls.realtime - cls.netchan.last_sent > 1.0f )
|
||||
Netchan_Transmit( &cls.netchan, 0, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_ReadyToSendPacket
|
||||
|
||||
Returns qfalse if we are over the maxpackets limit
|
||||
and should choke back the bandwidth a bit by not sending
|
||||
a packet this frame. All the commands will still get
|
||||
delivered in the next packet, but saving a header and
|
||||
getting more delta compression will reduce total bandwidth.
|
||||
=================
|
||||
*/
|
||||
bool CL_ReadyToSendPacket( void )
|
||||
{
|
||||
int old_packetnum;
|
||||
float delta;
|
||||
|
||||
// don't send anything if playing back a demo
|
||||
if( cls.demoplayback || cls.state == ca_cinematic )
|
||||
return false;
|
||||
|
||||
// if we are downloading, we send no less than 50ms between packets
|
||||
if( cls.downloadtempname[0] && cls.realtime - cls.netchan.last_sent < 0.05f )
|
||||
return false;
|
||||
|
||||
// if we don't have a valid gamestate yet, only send
|
||||
// one packet a second
|
||||
if( cls.state < ca_connected && !cls.downloadtempname[0] && cls.realtime - cls.netchan.last_sent < 1.0f )
|
||||
return false;
|
||||
|
||||
// send every frame for loopbacks
|
||||
if( NET_IsLocalAddress( cls.netchan.remote_address ))
|
||||
return true;
|
||||
|
||||
// check for exceeding cl_maxpackets
|
||||
if( cl_maxpackets->modified )
|
||||
{
|
||||
if( cl_maxpackets->integer < 15 )
|
||||
Cvar_Set( "cl_maxpackets", "15" );
|
||||
else if( cl_maxpackets->integer > 125 )
|
||||
Cvar_Set( "cl_maxpackets", "125" );
|
||||
cl_maxpackets->modified = false;
|
||||
}
|
||||
|
||||
old_packetnum = (cls.netchan.outgoing_sequence - 1) & UPDATE_MASK;
|
||||
delta = cls.realtime - cl.outframes[old_packetnum].realtime;
|
||||
|
||||
if( delta < (cl_maxpackets->integer * 0.001))
|
||||
{
|
||||
// the accumulated commands will go out in the next packet
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
CL_WritePacket
|
||||
|
||||
Create and send the command packet to the server
|
||||
Including both the reliable commands and the usercmds
|
||||
|
||||
During normal gameplay, a client packet will contain something like:
|
||||
|
||||
1 clc_move
|
||||
1 command count
|
||||
<count * usercmds>
|
||||
===================
|
||||
*/
|
||||
void CL_WritePacket( void )
|
||||
{
|
||||
sizebuf_t buf;
|
||||
byte data[MAX_MSGLEN];
|
||||
usercmd_t *oldcmd;
|
||||
usercmd_t nullcmd;
|
||||
int packetnum, old_packetnum;
|
||||
int i, j, count, key;
|
||||
|
||||
// don't send anything if playing back a demo
|
||||
if( cls.demoplayback || cls.state == ca_cinematic )
|
||||
return;
|
||||
|
||||
Mem_Set( &nullcmd, 0, sizeof( nullcmd ));
|
||||
oldcmd = &nullcmd;
|
||||
|
||||
// send a userinfo update if needed
|
||||
if( userinfo_modified )
|
||||
{
|
||||
userinfo_modified = false;
|
||||
MSG_WriteByte( &cls.netchan.message, clc_userinfo );
|
||||
MSG_WriteString( &cls.netchan.message, Cvar_Userinfo( ));
|
||||
}
|
||||
|
||||
MSG_Init( &buf, data, sizeof( data ));
|
||||
|
||||
// we want to send all the usercmds that were generated in the last
|
||||
// few packet, so even if a couple packets are dropped in a row,
|
||||
// all the cmds will make it to the server
|
||||
if( cl_packetdup->modified )
|
||||
{
|
||||
if( cl_packetdup->integer < 0 )
|
||||
Cvar_Set( "cl_packetdup", "0" );
|
||||
else if( cl_packetdup->integer > 5 )
|
||||
Cvar_Set( "cl_packetdup", "5" );
|
||||
cl_packetdup->modified = false;
|
||||
}
|
||||
old_packetnum = (cls.netchan.outgoing_sequence - 1 - cl_packetdup->integer ) & UPDATE_MASK;
|
||||
count = cl.cmd_number - cl.outframes[old_packetnum].cmd_number;
|
||||
if( count > UPDATE_BACKUP )
|
||||
{
|
||||
count = UPDATE_BACKUP;
|
||||
MsgDev( D_WARN, "MAX_USERCMDS limit exceeded\n" );
|
||||
}
|
||||
|
||||
if( count >= 1 )
|
||||
{
|
||||
bool noDelta = false;
|
||||
|
||||
if( cl_nodelta->integer ) noDelta = true;
|
||||
if( !cl.frame.valid || cls.demowaiting || cls.netchan.incoming_sequence != cl.frame.msgnum )
|
||||
noDelta = true;
|
||||
|
||||
// begin a client move command
|
||||
if( noDelta ) MSG_WriteByte( &buf, clc_move );
|
||||
else MSG_WriteByte( &buf, clc_deltamove );
|
||||
|
||||
// save the position for a checksum byte
|
||||
key = buf.cursize;
|
||||
MSG_WriteByte( &buf, 0 );
|
||||
|
||||
// write the command count
|
||||
MSG_WriteByte( &buf, count );
|
||||
|
||||
if( cl_shownet->integer == 4 )
|
||||
Msg( " packet: %i %scmds\n", count, noDelta ? "" : "delta" );
|
||||
|
||||
// write all the commands, including the predicted command
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
j = (cl.cmd_number - count + i + 1) & CMD_MASK;
|
||||
cl.refdef.cmd = &cl.cmds[j];
|
||||
MSG_WriteDeltaUsercmd( &buf, oldcmd, cl.refdef.cmd );
|
||||
oldcmd = cl.refdef.cmd;
|
||||
}
|
||||
|
||||
// calculate a checksum over the move commands
|
||||
buf.data[key] = CRC_Sequence( buf.data + key + 1, buf.cursize - key - 1, cls.netchan.outgoing_sequence );
|
||||
}
|
||||
|
||||
// save out frames for ping calculation
|
||||
packetnum = cls.netchan.outgoing_sequence & UPDATE_MASK;
|
||||
cl.outframes[packetnum].realtime = cls.realtime;
|
||||
cl.outframes[packetnum].servertime = oldcmd->servertime;
|
||||
cl.outframes[packetnum].cmd_number = cl.cmd_number;
|
||||
|
||||
// deliver the message
|
||||
Netchan_Transmit( &cls.netchan, buf.cursize, buf.data );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_SendCmd
|
||||
|
@ -753,17 +555,86 @@ Called every frame to builds and sends a command packet to the server.
|
|||
*/
|
||||
void CL_SendCmd( void )
|
||||
{
|
||||
// don't send any message if not connected
|
||||
if( cls.state < ca_connected ) return;
|
||||
sizebuf_t buf;
|
||||
byte data[128];
|
||||
usercmd_t *oldcmd;
|
||||
usercmd_t nullcmd;
|
||||
int checksumIndex;
|
||||
|
||||
// don't send commands if paused
|
||||
if( cl_paused->integer ) return;
|
||||
// build a command even if not connected
|
||||
|
||||
// we create commands even if a demo is playing,
|
||||
CL_CreateNewCommands();
|
||||
// save this command off for prediction
|
||||
cl.refdef.cmd = &cl.cmds[cls.netchan.outgoing_sequence & (CMD_BACKUP-1)];
|
||||
cl.cmd_time[cls.netchan.outgoing_sequence & (CMD_BACKUP-1)] = cls.realtime;
|
||||
*cl.refdef.cmd = CL_CreateCmd ();
|
||||
|
||||
// don't send a packet if the last packet was sent too recently
|
||||
if( CL_ReadyToSendPacket( )) CL_WritePacket();
|
||||
if( cls.state == ca_disconnected || cls.state == ca_connecting )
|
||||
return;
|
||||
|
||||
// ignore commands for demo mode
|
||||
if( cls.state == ca_cinematic || cls.demoplayback )
|
||||
return;
|
||||
|
||||
if( cls.state == ca_connected )
|
||||
{
|
||||
// jsut update reliable
|
||||
if( cls.netchan.message.cursize || cls.realtime - cls.netchan.last_sent > 1.0f )
|
||||
Netchan_Transmit( &cls.netchan, 0, NULL );
|
||||
return;
|
||||
}
|
||||
|
||||
if( freelook->modified )
|
||||
{
|
||||
if( !mlook_active && lookspring->value )
|
||||
clgame.dllFuncs.pfnStartPitchDrift();
|
||||
}
|
||||
|
||||
// send a userinfo update if needed
|
||||
if( userinfo_modified )
|
||||
{
|
||||
userinfo_modified = false;
|
||||
MSG_WriteByte (&cls.netchan.message, clc_userinfo);
|
||||
MSG_WriteString (&cls.netchan.message, Cvar_Userinfo());
|
||||
}
|
||||
|
||||
// begin a client move command
|
||||
MSG_Init( &buf, data, sizeof( data ));
|
||||
MSG_WriteByte( &buf, clc_move );
|
||||
|
||||
// save the position for a checksum byte
|
||||
checksumIndex = buf.cursize;
|
||||
MSG_WriteByte( &buf, 0 );
|
||||
|
||||
// let the server know what the last frame we
|
||||
// got was, so the next message can be delta compressed
|
||||
if (cl_nodelta->value || !cl.frame.valid || cls.demowaiting)
|
||||
{
|
||||
MSG_WriteLong( &buf, -1 ); // no compression
|
||||
}
|
||||
else
|
||||
{
|
||||
MSG_WriteLong( &buf, cl.frame.serverframe );
|
||||
}
|
||||
|
||||
// send this and the previous cmds in the message, so
|
||||
// if the last packet was dropped, it can be recovered
|
||||
cl.refdef.cmd = &cl.cmds[(cls.netchan.outgoing_sequence-2) & (CMD_BACKUP-1)];
|
||||
Mem_Set( &nullcmd, 0, sizeof( nullcmd ));
|
||||
MSG_WriteDeltaUsercmd( &buf, &nullcmd, cl.refdef.cmd );
|
||||
oldcmd = cl.refdef.cmd;
|
||||
|
||||
cl.refdef.cmd = &cl.cmds[(cls.netchan.outgoing_sequence-1) & (CMD_BACKUP-1)];
|
||||
MSG_WriteDeltaUsercmd( &buf, oldcmd, cl.refdef.cmd );
|
||||
oldcmd = cl.refdef.cmd;
|
||||
|
||||
cl.refdef.cmd = &cl.cmds[(cls.netchan.outgoing_sequence) & (CMD_BACKUP-1)];
|
||||
MSG_WriteDeltaUsercmd( &buf, oldcmd, cl.refdef.cmd );
|
||||
|
||||
// calculate a checksum over the move commands
|
||||
buf.data[checksumIndex] = CRC_Sequence( buf.data + checksumIndex + 1, buf.cursize - checksumIndex - 1, cls.netchan.outgoing_sequence);
|
||||
|
||||
// deliver the message
|
||||
Netchan_Transmit( &cls.netchan, buf.cursize, buf.data );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -774,88 +645,86 @@ CL_InitInput
|
|||
void CL_InitInput( void )
|
||||
{
|
||||
// mouse variables
|
||||
m_filter = Cvar_Get( "m_filter", "0", 0, "enable mouse filter" );
|
||||
m_filter = Cvar_Get("m_filter", "0", 0, "enable mouse filter" );
|
||||
m_sensitivity = Cvar_Get( "m_sensitivity", "3", CVAR_ARCHIVE, "mouse in-game sensitivity" );
|
||||
cl_mouseaccel = Cvar_Get( "cl_mouseaccelerate", "0", CVAR_ARCHIVE, "mouse accelerate factor" );
|
||||
|
||||
// centering
|
||||
v_centermove = Cvar_Get( "v_centermove", "0.15", 0, "client center moving" );
|
||||
v_centerspeed = Cvar_Get( "v_centerspeed", "500", 0, "client center speed" );
|
||||
cl_nodelta = Cvar_Get( "cl_nodelta", "0", 0, "disable delta-compression for usercommnds" );
|
||||
v_centermove = Cvar_Get ("v_centermove", "0.15", 0, "client center moving" );
|
||||
v_centerspeed = Cvar_Get ("v_centerspeed", "500", 0, "client center speed" );
|
||||
cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0, "disable delta-compression for usercommnds" );
|
||||
|
||||
freelook = Cvar_Get( "freelook", "1", CVAR_ARCHIVE, "enables mouse look" );
|
||||
lookspring = Cvar_Get( "lookspring", "0", CVAR_ARCHIVE, "allow look spring" );
|
||||
lookstrafe = Cvar_Get( "lookstrafe", "0", CVAR_ARCHIVE, "allow look strafe" );
|
||||
|
||||
m_pitch = Cvar_Get( "m_pitch", "0.022", CVAR_ARCHIVE, "mouse pitch value" );
|
||||
m_yaw = Cvar_Get( "m_yaw", "0.022", 0, "mouse yaw value" );
|
||||
m_forward = Cvar_Get( "m_forward", "1", 0, "mouse forward speed" );
|
||||
m_side = Cvar_Get( "m_side", "1", 0, "mouse side speed" );
|
||||
m_pitch = Cvar_Get ("m_pitch", "0.022", CVAR_ARCHIVE, "mouse pitch value" );
|
||||
m_yaw = Cvar_Get ("m_yaw", "0.022", 0, "mouse yaw value" );
|
||||
m_forward = Cvar_Get ("m_forward", "1", 0, "mouse forward speed" );
|
||||
m_side = Cvar_Get ("m_side", "1", 0, "mouse side speed" );
|
||||
|
||||
Cmd_AddCommand( "centerview", IN_CenterView, "gradually recenter view (stop looking up/down)" );
|
||||
Cmd_AddCommand ("centerview", IN_CenterView, "gradually recenter view (stop looking up/down)" );
|
||||
|
||||
// input commands
|
||||
Cmd_AddCommand( "+moveup", IN_UpDown, "swim upward" );
|
||||
Cmd_AddCommand( "-moveup",IN_UpUp, "stop swimming upward" );
|
||||
Cmd_AddCommand( "+movedown",IN_DownDown, "swim downward" );
|
||||
Cmd_AddCommand( "-movedown",IN_DownUp, "stop swimming downward" );
|
||||
Cmd_AddCommand( "+left",IN_LeftDown, "turn left" );
|
||||
Cmd_AddCommand( "-left",IN_LeftUp, "stop turning left" );
|
||||
Cmd_AddCommand( "+right",IN_RightDown, "turn right" );
|
||||
Cmd_AddCommand( "-right",IN_RightUp, "stop turning right" );
|
||||
Cmd_AddCommand( "+forward",IN_ForwardDown, "move forward" );
|
||||
Cmd_AddCommand( "-forward",IN_ForwardUp, "stop moving forward" );
|
||||
Cmd_AddCommand( "+back",IN_BackDown, "move backward" );
|
||||
Cmd_AddCommand( "-back",IN_BackUp, "stop moving backward" );
|
||||
Cmd_AddCommand( "+lookup", IN_LookupDown, "look upward" );
|
||||
Cmd_AddCommand( "-lookup", IN_LookupUp, "stop looking upward" );
|
||||
Cmd_AddCommand( "+lookdown", IN_LookdownDown, "look downward" );
|
||||
Cmd_AddCommand( "-lookdown", IN_LookdownUp, "stop looking downward" );
|
||||
Cmd_AddCommand( "+strafe", IN_StrafeDown, "activate strafing mode (move instead of turn)\n" );
|
||||
Cmd_AddCommand( "-strafe", IN_StrafeUp, "deactivate strafing mode" );
|
||||
Cmd_AddCommand( "+moveleft", IN_MoveleftDown, "strafe left" );
|
||||
Cmd_AddCommand( "-moveleft", IN_MoveleftUp, "stop strafing left" );
|
||||
Cmd_AddCommand( "+moveright", IN_MoverightDown, "strafe right" );
|
||||
Cmd_AddCommand( "-moveright", IN_MoverightUp, "stop strafing right" );
|
||||
Cmd_AddCommand( "+speed", IN_SpeedDown, "activate run mode (faster movement and turning)" );
|
||||
Cmd_AddCommand( "-speed", IN_SpeedUp, "deactivate run mode" );
|
||||
Cmd_AddCommand( "+attack", IN_AttackDown, "begin firing" );
|
||||
Cmd_AddCommand( "-attack", IN_AttackUp, "stop firing" );
|
||||
Cmd_AddCommand( "+attack2", IN_Attack2Down, "begin alternate firing" );
|
||||
Cmd_AddCommand( "-attack2", IN_Attack2Up, "stop alternate firing" );
|
||||
Cmd_AddCommand( "+use", IN_UseDown, "use item (doors, monsters, inventory, etc)" );
|
||||
Cmd_AddCommand( "-use", IN_UseUp, "stop using item" );
|
||||
Cmd_AddCommand( "+jump", IN_JumpDown, "jump" );
|
||||
Cmd_AddCommand( "-jump", IN_JumpUp, "end jump (so you can jump again)" );
|
||||
Cmd_AddCommand( "+duck", IN_DuckDown, "duck" );
|
||||
Cmd_AddCommand( "-duck", IN_DuckUp, "end duck (so you can duck again)" );
|
||||
Cmd_AddCommand( "+klook", IN_KLookDown, "activate keyboard looking mode, do not recenter view" );
|
||||
Cmd_AddCommand( "-klook", IN_KLookUp, "deactivate keyboard looking mode" );
|
||||
Cmd_AddCommand( "+reload", IN_ReloadDown, "reload current weapon" );
|
||||
Cmd_AddCommand( "-reload", IN_ReloadUp, "continue reload weapon" );
|
||||
Cmd_AddCommand( "+mlook", IN_MLookDown, "activate mouse looking mode, do not recenter view" );
|
||||
Cmd_AddCommand( "-mlook", IN_MLookUp, "deactivate mouse looking mode" );
|
||||
Cmd_AddCommand( "+alt1", IN_Alt1Down, "hold modyifycator" );
|
||||
Cmd_AddCommand( "-alt1", IN_Alt1Up, "release modifycator" );
|
||||
Cmd_AddCommand( "+break",IN_BreakDown, "cancel" );
|
||||
Cmd_AddCommand( "-break",IN_BreakUp, "stop cancel" );
|
||||
Cmd_AddCommand ("+moveup",IN_UpDown, "swim upward");
|
||||
Cmd_AddCommand ("-moveup",IN_UpUp, "stop swimming upward");
|
||||
Cmd_AddCommand ("+movedown",IN_DownDown, "swim downward");
|
||||
Cmd_AddCommand ("-movedown",IN_DownUp, "stop swimming downward");
|
||||
Cmd_AddCommand ("+left",IN_LeftDown, "turn left");
|
||||
Cmd_AddCommand ("-left",IN_LeftUp, "stop turning left");
|
||||
Cmd_AddCommand ("+right",IN_RightDown, "turn right");
|
||||
Cmd_AddCommand ("-right",IN_RightUp, "stop turning right");
|
||||
Cmd_AddCommand ("+forward",IN_ForwardDown, "move forward");
|
||||
Cmd_AddCommand ("-forward",IN_ForwardUp, "stop moving forward");
|
||||
Cmd_AddCommand ("+back",IN_BackDown, "move backward");
|
||||
Cmd_AddCommand ("-back",IN_BackUp, "stop moving backward");
|
||||
Cmd_AddCommand ("+lookup", IN_LookupDown, "look upward");
|
||||
Cmd_AddCommand ("-lookup", IN_LookupUp, "stop looking upward");
|
||||
Cmd_AddCommand ("+lookdown", IN_LookdownDown, "look downward");
|
||||
Cmd_AddCommand ("-lookdown", IN_LookdownUp, "stop looking downward");
|
||||
Cmd_AddCommand ("+strafe", IN_StrafeDown, "activate strafing mode (move instead of turn)\n");
|
||||
Cmd_AddCommand ("-strafe", IN_StrafeUp, "deactivate strafing mode");
|
||||
Cmd_AddCommand ("+moveleft", IN_MoveleftDown, "strafe left");
|
||||
Cmd_AddCommand ("-moveleft", IN_MoveleftUp, "stop strafing left");
|
||||
Cmd_AddCommand ("+moveright", IN_MoverightDown, "strafe right");
|
||||
Cmd_AddCommand ("-moveright", IN_MoverightUp, "stop strafing right");
|
||||
Cmd_AddCommand ("+speed", IN_SpeedDown, "activate run mode (faster movement and turning)");
|
||||
Cmd_AddCommand ("-speed", IN_SpeedUp, "deactivate run mode");
|
||||
Cmd_AddCommand ("+attack", IN_AttackDown, "begin firing");
|
||||
Cmd_AddCommand ("-attack", IN_AttackUp, "stop firing");
|
||||
Cmd_AddCommand ("+attack2", IN_Attack2Down, "begin alternate firing");
|
||||
Cmd_AddCommand ("-attack2", IN_Attack2Up, "stop alternate firing");
|
||||
Cmd_AddCommand ("+use", IN_UseDown, "use item (doors, monsters, inventory, etc)" );
|
||||
Cmd_AddCommand ("-use", IN_UseUp, "stop using item" );
|
||||
Cmd_AddCommand ("+jump", IN_JumpDown, "jump" );
|
||||
Cmd_AddCommand ("-jump", IN_JumpUp, "end jump (so you can jump again)");
|
||||
Cmd_AddCommand ("+duck", IN_DuckDown, "duck" );
|
||||
Cmd_AddCommand ("-duck", IN_DuckUp, "end duck (so you can duck again)");
|
||||
Cmd_AddCommand ("+klook", IN_KLookDown, "activate keyboard looking mode, do not recenter view");
|
||||
Cmd_AddCommand ("-klook", IN_KLookUp, "deactivate keyboard looking mode");
|
||||
Cmd_AddCommand ("+reload", IN_ReloadDown, "reload current weapon" );
|
||||
Cmd_AddCommand ("-reload", IN_ReloadUp, "continue reload weapon" );
|
||||
Cmd_AddCommand ("+mlook", IN_MLookDown, "activate mouse looking mode, do not recenter view" );
|
||||
Cmd_AddCommand ("-mlook", IN_MLookUp, "deactivate mouse looking mode" );
|
||||
Cmd_AddCommand ("+alt1", IN_Alt1Down, "hold modyifycator" );
|
||||
Cmd_AddCommand ("-alt1", IN_Alt1Up, "release modifycator" );
|
||||
Cmd_AddCommand ("+break",IN_BreakDown, "cancel" );
|
||||
Cmd_AddCommand ("-break",IN_BreakUp, "stop cancel" );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_InitServerCommands
|
||||
|
||||
FIXME: move this stuff into client.dll
|
||||
============
|
||||
*/
|
||||
void CL_InitServerCommands( void )
|
||||
{
|
||||
Cmd_AddCommand( "impulse", NULL, "send impulse to a client" );
|
||||
Cmd_AddCommand( "noclip", NULL, "enable or disable no clipping mode" );
|
||||
Cmd_AddCommand( "fullupdate", NULL, "re-init HUD on start demo recording" );
|
||||
Cmd_AddCommand( "give", NULL, "give specified item or weapon" );
|
||||
Cmd_AddCommand( "intermission", NULL, "go to intermission" );
|
||||
Cmd_AddCommand( "god", NULL, "classic cheat" );
|
||||
Cmd_AddCommand ("impulse", NULL, "send impulse to a client" );
|
||||
Cmd_AddCommand ("noclip", NULL, "enable or disable no clipping mode" );
|
||||
Cmd_AddCommand ("fullupdate", NULL, "re-init HUD on start demo recording" );
|
||||
Cmd_AddCommand ("give", NULL, "give specified item or weapon" );
|
||||
Cmd_AddCommand ("intermission", NULL, "go to intermission" );
|
||||
Cmd_AddCommand ("god", NULL, "classic cheat" );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -865,45 +734,41 @@ CL_ShutdownInput
|
|||
*/
|
||||
void CL_ShutdownInput( void )
|
||||
{
|
||||
Cmd_RemoveCommand( "centerview" );
|
||||
Cmd_RemoveCommand ("centerview" );
|
||||
|
||||
// input commands
|
||||
Cmd_RemoveCommand( "+moveup" );
|
||||
Cmd_RemoveCommand( "-moveup" );
|
||||
Cmd_RemoveCommand( "+movedown" );
|
||||
Cmd_RemoveCommand( "-movedown" );
|
||||
Cmd_RemoveCommand( "+left" );
|
||||
Cmd_RemoveCommand( "-left" );
|
||||
Cmd_RemoveCommand( "+right" );
|
||||
Cmd_RemoveCommand( "-right" );
|
||||
Cmd_RemoveCommand( "+forward" );
|
||||
Cmd_RemoveCommand( "-forward" );
|
||||
Cmd_RemoveCommand( "+back" );
|
||||
Cmd_RemoveCommand( "-back" );
|
||||
Cmd_RemoveCommand( "+lookup" );
|
||||
Cmd_RemoveCommand( "-lookup" );
|
||||
Cmd_RemoveCommand( "+lookdown" );
|
||||
Cmd_RemoveCommand( "-lookdown" );
|
||||
Cmd_RemoveCommand( "+strafe" );
|
||||
Cmd_RemoveCommand( "-strafe" );
|
||||
Cmd_RemoveCommand( "+moveleft" );
|
||||
Cmd_RemoveCommand( "-moveleft" );
|
||||
Cmd_RemoveCommand( "+moveright" );
|
||||
Cmd_RemoveCommand( "-moveright" );
|
||||
Cmd_RemoveCommand( "+speed" );
|
||||
Cmd_RemoveCommand( "-speed" );
|
||||
Cmd_RemoveCommand( "+attack" );
|
||||
Cmd_RemoveCommand( "-attack" );
|
||||
Cmd_RemoveCommand( "+attack2" );
|
||||
Cmd_RemoveCommand( "-attack2" );
|
||||
Cmd_RemoveCommand( "+reload" );
|
||||
Cmd_RemoveCommand( "-reload" );
|
||||
Cmd_RemoveCommand( "+use" );
|
||||
Cmd_RemoveCommand( "-use" );
|
||||
Cmd_RemoveCommand( "+mlook" );
|
||||
Cmd_RemoveCommand( "-mlook" );
|
||||
Cmd_RemoveCommand( "+alt1" );
|
||||
Cmd_RemoveCommand( "-alt1" );
|
||||
Cmd_RemoveCommand( "+break" );
|
||||
Cmd_RemoveCommand( "-break" );
|
||||
Cmd_RemoveCommand ("+moveup" );
|
||||
Cmd_RemoveCommand ("-moveup" );
|
||||
Cmd_RemoveCommand ("+movedown" );
|
||||
Cmd_RemoveCommand ("-movedown" );
|
||||
Cmd_RemoveCommand ("+left" );
|
||||
Cmd_RemoveCommand ("-left" );
|
||||
Cmd_RemoveCommand ("+right" );
|
||||
Cmd_RemoveCommand ("-right" );
|
||||
Cmd_RemoveCommand ("+forward" );
|
||||
Cmd_RemoveCommand ("-forward" );
|
||||
Cmd_RemoveCommand ("+back" );
|
||||
Cmd_RemoveCommand ("-back" );
|
||||
Cmd_RemoveCommand ("+lookup" );
|
||||
Cmd_RemoveCommand ("-lookup" );
|
||||
Cmd_RemoveCommand ("+lookdown" );
|
||||
Cmd_RemoveCommand ("-lookdown" );
|
||||
Cmd_RemoveCommand ("+strafe" );
|
||||
Cmd_RemoveCommand ("-strafe" );
|
||||
Cmd_RemoveCommand ("+moveleft" );
|
||||
Cmd_RemoveCommand ("-moveleft" );
|
||||
Cmd_RemoveCommand ("+moveright" );
|
||||
Cmd_RemoveCommand ("-moveright" );
|
||||
Cmd_RemoveCommand ("+speed" );
|
||||
Cmd_RemoveCommand ("-speed" );
|
||||
Cmd_RemoveCommand ("+attack" );
|
||||
Cmd_RemoveCommand ("-attack" );
|
||||
Cmd_RemoveCommand ("+attack2" );
|
||||
Cmd_RemoveCommand ("-attack2" );
|
||||
Cmd_RemoveCommand ("+reload" );
|
||||
Cmd_RemoveCommand ("-reload" );
|
||||
Cmd_RemoveCommand ("+use" );
|
||||
Cmd_RemoveCommand ("-use" );
|
||||
Cmd_RemoveCommand ("+mlook" );
|
||||
Cmd_RemoveCommand ("-mlook" );
|
||||
}
|
|
@ -26,8 +26,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
cvar_t *rcon_client_password;
|
||||
cvar_t *rcon_address;
|
||||
|
||||
cvar_t *cl_maxpackets;
|
||||
cvar_t *cl_packetdup;
|
||||
cvar_t *cl_footsteps;
|
||||
cvar_t *cl_timeout;
|
||||
cvar_t *cl_predict;
|
||||
|
@ -37,7 +35,6 @@ cvar_t *cl_maxfps;
|
|||
cvar_t *cl_particles;
|
||||
cvar_t *cl_particlelod;
|
||||
|
||||
cvar_t *cl_timenudge;
|
||||
cvar_t *cl_shownet;
|
||||
cvar_t *cl_showmiss;
|
||||
cvar_t *cl_showclamp;
|
||||
|
@ -459,16 +456,15 @@ CL_Reconnect_f
|
|||
The server is changing levels
|
||||
=================
|
||||
*/
|
||||
void CL_Reconnect_f( void )
|
||||
void CL_Reconnect_f (void)
|
||||
{
|
||||
// if we are downloading, we don't change!
|
||||
// this so we don't suddenly stop downloading a map
|
||||
// if we are downloading, we don't change! This so we don't suddenly stop downloading a map
|
||||
if( cls.download ) return;
|
||||
|
||||
S_StopAllSounds ();
|
||||
if( cls.state == ca_connected )
|
||||
{
|
||||
Msg ("reconnecting...\n");
|
||||
Msg( "reconnecting...\n" );
|
||||
cls.state = ca_connected;
|
||||
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
MSG_Print( &cls.netchan.message, "new" );
|
||||
|
@ -665,9 +661,8 @@ void CL_ParseStatusMessage( netadr_t from, sizebuf_t *msg )
|
|||
|
||||
s = MSG_ReadString( msg );
|
||||
|
||||
Msg( "%s\n", s );
|
||||
UI_AddServerToList( from, s );
|
||||
// CL_ParseServerStatus( NET_AdrToString(from), s );
|
||||
Msg ("%s\n", s);
|
||||
CL_ParseServerStatus( NET_AdrToString(from), s );
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
|
@ -918,7 +913,7 @@ void CL_ReadPackets( void )
|
|||
{
|
||||
if( ++cl.timeoutcount > 5 ) // timeoutcount saves debugger
|
||||
{
|
||||
Msg( "\nServer connection timed out.\n" );
|
||||
Msg ("\nServer connection timed out.\n");
|
||||
CL_Disconnect();
|
||||
return;
|
||||
}
|
||||
|
@ -1079,11 +1074,9 @@ void CL_InitLocal( void )
|
|||
// register our variables
|
||||
cl_footsteps = Cvar_Get( "cl_footsteps", "1", 0, "disables player footsteps" );
|
||||
cl_predict = Cvar_Get( "cl_predict", "1", CVAR_ARCHIVE, "disables client movement prediction" );
|
||||
cl_maxfps = Cvar_Get( "cl_maxfps", "100", CVAR_ARCHIVE, "maximum client fps (refresh framerate too)" );
|
||||
cl_maxfps = Cvar_Get( "cl_maxfps", "1000", 0, "maximum client fps" );
|
||||
cl_particles = Cvar_Get( "cl_particles", "1", CVAR_ARCHIVE, "disables particle effects" );
|
||||
cl_particlelod = Cvar_Get( "cl_lod_particle", "0", CVAR_ARCHIVE, "enables particle LOD (1, 2, 3)" );
|
||||
cl_maxpackets = Cvar_Get( "cl_maxpackets", "30", CVAR_ARCHIVE, "usercmds sending frequency rate" );
|
||||
cl_packetdup = Cvar_Get( "cl_packetdup", "2", CVAR_ARCHIVE, "number of repeating packets (2 is Q2 default value)" );
|
||||
|
||||
cl_upspeed = Cvar_Get( "cl_upspeed", "200", 0, "client upspeed limit" );
|
||||
cl_forwardspeed = Cvar_Get( "cl_forwardspeed", "200", 0, "client forward speed limit" );
|
||||
|
@ -1096,9 +1089,8 @@ void CL_InitLocal( void )
|
|||
|
||||
cl_shownet = Cvar_Get( "cl_shownet", "0", 0, "client show network packets" );
|
||||
cl_showmiss = Cvar_Get( "cl_showmiss", "0", 0, "client show network errors" );
|
||||
cl_showclamp = Cvar_Get( "cl_showclamp", "1", 0, "show client clamping" );
|
||||
cl_showclamp = Cvar_Get( "cl_showclamp", "0", CVAR_ARCHIVE, "show client clamping" );
|
||||
cl_timeout = Cvar_Get( "cl_timeout", "120", 0, "connect timeout (in-seconds)" );
|
||||
cl_timenudge = Cvar_Get( "cl_timenudge", "0", CVAR_TEMP, "nudge server time to specified value" );
|
||||
|
||||
rcon_client_password = Cvar_Get( "rcon_password", "", 0, "remote control client password" );
|
||||
rcon_address = Cvar_Get( "rcon_address", "", 0, "remote control address" );
|
||||
|
@ -1165,22 +1157,6 @@ void CL_SendCommand( void )
|
|||
|
||||
// resend a connection request if necessary
|
||||
CL_CheckForResend ();
|
||||
|
||||
CL_SetClientTime ();
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_CalcFrameTime
|
||||
==================
|
||||
*/
|
||||
double CL_CalcFrameTime( void )
|
||||
{
|
||||
if( cls.state == ca_connected )
|
||||
return 0.1f; // don't flood packets out while connecting
|
||||
if( cl_maxfps->value )
|
||||
return 1.0 / (double)cl_maxfps->value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1191,29 +1167,17 @@ CL_Frame
|
|||
*/
|
||||
void CL_Frame( double time )
|
||||
{
|
||||
static double extratime = 0.001;
|
||||
static double frametime;
|
||||
double minframetime;
|
||||
|
||||
if( host.type == HOST_DEDICATED )
|
||||
return;
|
||||
|
||||
extratime += time;
|
||||
|
||||
minframetime = CL_CalcFrameTime();
|
||||
if( extratime < minframetime )
|
||||
return;
|
||||
|
||||
// decide the simulation time
|
||||
frametime = extratime - 0.001;
|
||||
if( frametime < minframetime ) frametime = minframetime;
|
||||
extratime -= frametime;
|
||||
|
||||
// decide the simulation time
|
||||
cl.oldtime = cl.time;
|
||||
cl.time += time; // can be merged by cl.frame.servertime
|
||||
cls.realtime += time;
|
||||
cls.realframetime = cls.frametime = frametime;
|
||||
cls.frametime = time;
|
||||
|
||||
if( cls.frametime > (1.0f / 5)) cls.frametime = (1.0f / 5);
|
||||
cl.time = bound( cl.frame.servertime - cl.serverframetime, cl.time, cl.frame.servertime );
|
||||
if( cls.frametime > 0.2f ) cls.frametime = 0.2f;
|
||||
|
||||
// if in the debugger last frame, don't timeout
|
||||
if( time > 5.0f ) cls.netchan.last_received = Sys_DoubleTime ();
|
||||
|
|
|
@ -248,6 +248,7 @@ void CL_ParseServerData( sizebuf_t *msg )
|
|||
Host_Error( "Server use invalid protocol (%i should be %i)\n", i, PROTOCOL_VERSION );
|
||||
|
||||
cl.servercount = MSG_ReadLong( msg );
|
||||
cl.serverframetime = MSG_ReadFloat( msg );
|
||||
cl.playernum = MSG_ReadShort( msg );
|
||||
str = MSG_ReadString( msg );
|
||||
|
||||
|
@ -261,7 +262,7 @@ void CL_ParseServerData( sizebuf_t *msg )
|
|||
if( i == 3 )
|
||||
{
|
||||
Cvar_Set( "cl_levelshot_name", MAP_DEFAULT_SHADER ); // render a black screen
|
||||
clgame.need_levelshot = true; // make levelshot
|
||||
cl.need_levelshot = true; // make levelshot
|
||||
}
|
||||
// seperate the printfs so the server message can have a color
|
||||
Msg("\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n");
|
||||
|
|
|
@ -37,7 +37,7 @@ void CL_CheckPredictionError( void )
|
|||
else
|
||||
{
|
||||
if (cl_showmiss->value && (delta[0] || delta[1] || delta[2]))
|
||||
Msg ("prediction miss on %i: %i\n", cl.frame.msgnum, delta[0] + delta[1] + delta[2]);
|
||||
Msg ("prediction miss on %i: %i\n", cl.frame.serverframe, delta[0] + delta[1] + delta[2]);
|
||||
|
||||
VectorCopy (cl.frame.ps.origin, cl.predicted_origins[frame]);
|
||||
|
||||
|
|
|
@ -323,7 +323,7 @@ void SCR_DrawFPS( void )
|
|||
|
||||
if( cls.state != ca_active ) return;
|
||||
if( !cl_showfps->integer ) return;
|
||||
if( clgame.need_levelshot ) return;
|
||||
if( cl.need_levelshot ) return;
|
||||
|
||||
newtime = Sys_DoubleTime();
|
||||
if (newtime >= nexttime)
|
||||
|
|
|
@ -73,9 +73,9 @@ void V_SetupRefDef( void )
|
|||
|
||||
// find the previous frame to interpolate from
|
||||
ps = &cl.frame.ps;
|
||||
i = (cl.frame.msgnum - 1) & UPDATE_MASK;
|
||||
i = (cl.frame.serverframe - 1) & UPDATE_MASK;
|
||||
oldframe = &cl.frames[i];
|
||||
if( oldframe->msgnum != cl.frame.msgnum - 1 || !oldframe->valid )
|
||||
if( oldframe->serverframe != cl.frame.serverframe-1 || !oldframe->valid )
|
||||
oldframe = &cl.frame; // previous frame was dropped or invalid
|
||||
ops = &oldframe->ps;
|
||||
|
||||
|
@ -144,7 +144,7 @@ void V_SetupRefDef( void )
|
|||
|
||||
// smooth out stair climbing
|
||||
delta = cls.realtime - cl.predicted_step_time;
|
||||
if( delta < cl.frametime ) cl.refdef.vieworg[2] -= cl.predicted_step * (cl.frametime - delta) * 0.01f;
|
||||
if( delta < cl.serverframetime ) cl.refdef.vieworg[2] -= cl.predicted_step * (cl.serverframetime - delta) * 0.01f;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,23 +42,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
typedef struct frame_s
|
||||
{
|
||||
bool valid; // cleared if delta parsing was invalid
|
||||
int ping; // frame ping
|
||||
int msgnum; // server message number
|
||||
float servertime; // server time
|
||||
int deltaframe; // message number the delta is from
|
||||
int serverframe;
|
||||
double servertime;
|
||||
int deltaframe;
|
||||
byte areabits[MAX_MAP_AREA_BYTES]; // portalarea visibility bits
|
||||
int num_entities;
|
||||
int parse_entities; // non-masked index into cl_parse_entities array
|
||||
entity_state_t ps; // player state
|
||||
} frame_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int cmd_number; // cl.cmd_number when packet was sent
|
||||
float servertime; // usercmd->servertime when packet was sent
|
||||
float realtime; // cls.realtime when packet was sent
|
||||
} outframe_t;
|
||||
|
||||
// console stuff
|
||||
typedef struct field_s
|
||||
{
|
||||
|
@ -66,6 +58,7 @@ typedef struct field_s
|
|||
int scroll;
|
||||
int widthInChars;
|
||||
char buffer[MAX_EDIT_LINE];
|
||||
int maxchars; // menu stuff
|
||||
} field_t;
|
||||
|
||||
#define CMD_BACKUP 64 // allow a lot of command backups for very fast systems
|
||||
|
@ -81,54 +74,13 @@ typedef struct
|
|||
|
||||
bool video_prepped; // false if on new level or new ref dll
|
||||
bool audio_prepped; // false if on new level or new snd dll
|
||||
bool has_newframe; // client has new frame from server
|
||||
bool frame_extrapolate;
|
||||
|
||||
int parse_entities; // index (not anded off) into cl_parse_entities[]
|
||||
|
||||
frame_t frame; // received from server
|
||||
frame_t *oldframe; // old frame to interpolate from
|
||||
frame_t frames[UPDATE_BACKUP];
|
||||
|
||||
int cmd_number;
|
||||
usercmd_t cmds[CMD_BACKUP]; // each mesage will send several old cmds
|
||||
outframe_t outframes[UPDATE_BACKUP]; // information about each packet we have sent out
|
||||
|
||||
// mouse current position
|
||||
int mouse_x[2];
|
||||
int mouse_y[2];
|
||||
int mouse_step;
|
||||
|
||||
int render_flags; // accumulated renderflags (will be clearing at end of frame)
|
||||
ref_params_t refdef; // shared refdef
|
||||
edict_t viewent; // viewmodel
|
||||
client_data_t data; // hud data
|
||||
|
||||
double time; // matched with sv.time
|
||||
double oldtime; // to prevent time from flowing bakcwards
|
||||
float time_delta; // cl.time = cls.realtime + cl.time_delta
|
||||
float frametime; // cl.frametime = cl.time - cl.oldtime
|
||||
|
||||
//
|
||||
// server state information
|
||||
//
|
||||
int playernum;
|
||||
int servercount; // server identification for prespawns
|
||||
char configstrings[MAX_CONFIGSTRINGS][CS_SIZE];
|
||||
|
||||
//
|
||||
// locally derived information from server state
|
||||
//
|
||||
cmodel_t *worldmodel;
|
||||
cmodel_t *models[MAX_MODELS];
|
||||
string_t edict_classnames[MAX_CLASSNAMES];
|
||||
sound_t sound_precache[MAX_SOUNDS];
|
||||
shader_t decal_shaders[MAX_DECALS];
|
||||
|
||||
// old stuff attempt to be removed
|
||||
|
||||
double mtime[2]; // the timestamp of the last two messages
|
||||
vec3_t predicted_origins[CMD_BACKUP];// for debug comparing against server
|
||||
float cmd_time[CMD_BACKUP]; // for netgraph ping calculation
|
||||
int predicted_origins[CMD_BACKUP][3];// for debug comparing against server
|
||||
|
||||
float predicted_step; // for stair up smoothing
|
||||
uint predicted_step_time;
|
||||
|
@ -136,6 +88,49 @@ typedef struct
|
|||
vec3_t predicted_origin; // generated by CL_PredictMovement
|
||||
vec3_t predicted_angles;
|
||||
vec3_t prediction_error;
|
||||
|
||||
frame_t frame; // received from server
|
||||
frame_t *oldframe; // previous frame to lerping from
|
||||
int surpressCount; // number of messages rate supressed
|
||||
frame_t frames[UPDATE_BACKUP];
|
||||
|
||||
// mouse current position
|
||||
int mouse_x[2];
|
||||
int mouse_y[2];
|
||||
int mouse_step;
|
||||
float mouse_sens;
|
||||
|
||||
double mtime[2]; // the timestamp of the last two messages
|
||||
double time; // this is the time value that the client
|
||||
double oldtime; // cl.oldtime
|
||||
// is rendering at. always <= cls.realtime
|
||||
int render_flags; // clearing at end of frame
|
||||
ref_params_t refdef; // shared refdef
|
||||
edict_t viewent; // viewmodel
|
||||
client_data_t data; // hud data
|
||||
|
||||
// misc 2d drawing stuff
|
||||
float centerPrintTime;
|
||||
int centerPrintCharWidth;
|
||||
int centerPrintY;
|
||||
char centerPrint[1024];
|
||||
int centerPrintLines;
|
||||
bool need_levelshot;
|
||||
|
||||
//
|
||||
// server state information
|
||||
//
|
||||
int playernum;
|
||||
int servercount; // server identification for prespawns
|
||||
float serverframetime; // server frametime
|
||||
char configstrings[MAX_CONFIGSTRINGS][CS_SIZE];
|
||||
|
||||
// locally derived information from server state
|
||||
cmodel_t *models[MAX_MODELS];
|
||||
cmodel_t *worldmodel;
|
||||
string_t edict_classnames[MAX_CLASSNAMES];
|
||||
sound_t sound_precache[MAX_SOUNDS];
|
||||
shader_t decal_shaders[MAX_DECALS];
|
||||
} client_t;
|
||||
|
||||
extern client_t cl;
|
||||
|
@ -170,7 +165,8 @@ typedef enum
|
|||
// cl_private_edict_t
|
||||
struct cl_priv_s
|
||||
{
|
||||
int msgnum; // if not current, this ent isn't in the frame
|
||||
int serverframe; // if not current, this ent isn't in the frame
|
||||
|
||||
entity_state_t baseline; // delta from this if not from a previous frame
|
||||
entity_state_t current;
|
||||
entity_state_t prev; // will always be valid, but might just be a copy of current
|
||||
|
@ -223,14 +219,6 @@ typedef struct
|
|||
int numMessages; // actual count of user messages
|
||||
int hStringTable; // stringtable handle
|
||||
|
||||
// misc 2d drawing stuff
|
||||
float centerPrintTime;
|
||||
int centerPrintCharWidth;
|
||||
int centerPrintY;
|
||||
char centerPrint[1024];
|
||||
int centerPrintLines;
|
||||
bool need_levelshot;
|
||||
|
||||
// movement values from server
|
||||
movevars_t movevars;
|
||||
} clgame_static_t;
|
||||
|
@ -246,7 +234,6 @@ typedef struct
|
|||
|
||||
int framecount;
|
||||
double frametime; // seconds since last frame
|
||||
double realframetime; // console and other things
|
||||
double realtime;
|
||||
|
||||
int quakePort; // a 16 bit value that allows quake servers
|
||||
|
@ -314,9 +301,6 @@ extern cvar_t *cl_font;
|
|||
|
||||
extern cvar_t *cl_anglespeedkey;
|
||||
|
||||
extern cvar_t *cl_timenudge;
|
||||
extern cvar_t *cl_packetdup;
|
||||
extern cvar_t *cl_maxpackets;
|
||||
extern cvar_t *cl_showmiss;
|
||||
extern cvar_t *cl_showclamp;
|
||||
extern cvar_t *cl_particles;
|
||||
|
@ -571,11 +555,10 @@ int CL_ContentsMask( const edict_t *passedict );
|
|||
trace_t CL_Trace( const vec3_t s1, const vec3_t m1, const vec3_t m2, const vec3_t s2, int type, edict_t *e, int mask );
|
||||
|
||||
//
|
||||
// cl_frame.c
|
||||
// cl_ents.c
|
||||
//
|
||||
void CL_GetEntitySoundSpatialization( int ent, vec3_t origin, vec3_t velocity );
|
||||
void CL_AddLoopingSounds( void );
|
||||
void CL_SetClientTime( void );
|
||||
|
||||
//
|
||||
// cl_fx.c
|
||||
|
|
|
@ -95,10 +95,14 @@ typedef struct host_parm_s
|
|||
dword errorframe; // to avoid each-frame host error
|
||||
string finalmsg; // server shutdown final message
|
||||
|
||||
double time;
|
||||
double oldtime;
|
||||
double frametime; // time between engine frames
|
||||
|
||||
dword framecount; // global framecount
|
||||
HWND hWnd; // main window
|
||||
int developer; // show all developer's message
|
||||
word max_edicts; // FIXME
|
||||
word max_edicts;
|
||||
} host_parm_t;
|
||||
|
||||
extern host_parm_t host;
|
||||
|
|
|
@ -611,13 +611,13 @@ void Con_RunConsole( void )
|
|||
|
||||
if (con.finalFrac < con.displayFrac)
|
||||
{
|
||||
con.displayFrac -= con_speed->value * cls.realframetime;
|
||||
con.displayFrac -= con_speed->value * cls.frametime;
|
||||
if( con.finalFrac > con.displayFrac )
|
||||
con.displayFrac = con.finalFrac;
|
||||
}
|
||||
else if( con.finalFrac > con.displayFrac )
|
||||
{
|
||||
con.displayFrac += con_speed->value * cls.realframetime;
|
||||
con.displayFrac += con_speed->value * cls.frametime;
|
||||
if( con.finalFrac < con.displayFrac )
|
||||
con.displayFrac = con.finalFrac;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ static net_field_t ent_fields[] =
|
|||
{ ES_FIELD(ed_flags), NET_BYTE, true }, // stateflags_t #0 (4 bytes)
|
||||
{ ES_FIELD(classname), NET_WORD, false },
|
||||
{ ES_FIELD(soundindex), NET_WORD, false }, // 512 sounds ( OpenAL software limit is 255 )
|
||||
{ ES_FIELD(cmdtime), NET_FLOAT, true }, // client only stuff
|
||||
{ ES_FIELD(origin[0]), NET_FLOAT, false },
|
||||
{ ES_FIELD(origin[1]), NET_FLOAT, false },
|
||||
{ ES_FIELD(origin[2]), NET_FLOAT, false },
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
--------------------Configuration: engine - Win32 Debug--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP7BE7.tmp" with contents
|
||||
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP7FB0.tmp" with contents
|
||||
[
|
||||
/nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "./" /I "common" /I "server" /I "client" /I "uimenu" /I "../public" /I "../common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"..\temp\engine\!debug/" /Fo"..\temp\engine\!debug/" /Fd"..\temp\engine\!debug/" /FD /c
|
||||
"D:\Xash3D\src_main\engine\client\cl_frame.c"
|
||||
]
|
||||
Creating command line "cl.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP7BE7.tmp"
|
||||
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP7BE8.tmp" with contents
|
||||
Creating command line "cl.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP7FB0.tmp"
|
||||
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP7FB1.tmp" with contents
|
||||
[
|
||||
user32.lib msvcrtd.lib /nologo /subsystem:windows /dll /incremental:yes /pdb:"..\temp\engine\!debug/engine.pdb" /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"..\temp\engine\!debug/engine.dll" /implib:"..\temp\engine\!debug/engine.lib" /pdbtype:sept
|
||||
"\Xash3D\src_main\temp\engine\!debug\cinematic.obj"
|
||||
|
@ -73,13 +73,13 @@ user32.lib msvcrtd.lib /nologo /subsystem:windows /dll /incremental:yes /pdb:"..
|
|||
"\Xash3D\src_main\temp\engine\!debug\ui_singleplayer.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_video.obj"
|
||||
]
|
||||
Creating command line "link.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP7BE8.tmp"
|
||||
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP7BE9.bat" with contents
|
||||
Creating command line "link.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP7FB1.tmp"
|
||||
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP7FB2.bat" with contents
|
||||
[
|
||||
@echo off
|
||||
copy \Xash3D\src_main\temp\engine\!debug\engine.dll "D:\Xash3D\bin\engine.dll"
|
||||
]
|
||||
Creating command line "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP7BE9.bat"
|
||||
Creating command line "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP7FB2.bat"
|
||||
Compiling...
|
||||
cl_frame.c
|
||||
Linking...
|
||||
|
|
|
@ -24,8 +24,12 @@ dll_info_t render_dll = { "render.dll", NULL, "CreateAPI", NULL, NULL, 0, sizeof
|
|||
dll_info_t vprogs_dll = { "vprogs.dll", NULL, "CreateAPI", NULL, NULL, 1, sizeof(vprogs_exp_t), sizeof(stdlib_api_t) };
|
||||
dll_info_t vsound_dll = { "vsound.dll", NULL, "CreateAPI", NULL, NULL, 0, sizeof(vsound_exp_t), sizeof(stdlib_api_t) };
|
||||
|
||||
cvar_t *timescale;
|
||||
cvar_t *host_serverstate;
|
||||
cvar_t *host_cheats;
|
||||
cvar_t *host_maxfps;
|
||||
cvar_t *host_minfps;
|
||||
cvar_t *host_ticrate;
|
||||
cvar_t *host_framerate;
|
||||
cvar_t *host_maxclients;
|
||||
cvar_t *host_registered;
|
||||
|
@ -308,6 +312,40 @@ void Host_EventLoop( void )
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
Host_FilterTime
|
||||
|
||||
Returns false if the time is too short to run a frame
|
||||
===================
|
||||
*/
|
||||
bool Host_FilterTime( double time )
|
||||
{
|
||||
host.time += time;
|
||||
|
||||
if( host_maxfps->modified )
|
||||
{
|
||||
if( host_maxfps->integer < 10 )
|
||||
Cvar_Set( "host_maxfps", "10" );
|
||||
else if( host_maxfps->integer > 1000 )
|
||||
Cvar_Set( "host_maxfps", "1000" );
|
||||
host_maxfps->modified = false;
|
||||
}
|
||||
|
||||
if( host.time - host.oldtime < (1.0 / host_maxfps->value))
|
||||
return false; // framerate is too high
|
||||
|
||||
host.frametime = host.time - host.oldtime;
|
||||
host.oldtime = host.time;
|
||||
|
||||
if( host_framerate->value > 0 )
|
||||
host.frametime = host_framerate->value;
|
||||
host.frametime = bound( 0.001, host.frametime, 0.1 );
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Host_Frame
|
||||
|
@ -318,16 +356,18 @@ void Host_Frame( double time )
|
|||
if( setjmp( host.abortframe ))
|
||||
return;
|
||||
|
||||
rand(); // keep the random time dependent
|
||||
|
||||
// decide the simulation time
|
||||
if( !Host_FilterTime( time ))
|
||||
return;
|
||||
|
||||
Host_EventLoop (); // process all system events
|
||||
Cbuf_Execute (); // execute commands
|
||||
|
||||
|
||||
if( host_framerate->value )
|
||||
time = bound( 0.001, host_framerate->value, 1 );
|
||||
|
||||
SV_Frame ( time ); // server frame
|
||||
CL_Frame ( time ); // client frame
|
||||
VM_Frame ( time ); // vprogs frame
|
||||
SV_Frame ( host.frametime ); // server frame
|
||||
CL_Frame ( host.frametime ); // client frame
|
||||
VM_Frame ( host.frametime ); // vprogs frame
|
||||
|
||||
host.framecount++;
|
||||
}
|
||||
|
@ -476,12 +516,16 @@ void Host_Init( const int argc, const char **argv )
|
|||
}
|
||||
|
||||
host_cheats = Cvar_Get( "sv_cheats", "1", CVAR_SYSTEMINFO, "allow cheat variables to enable" );
|
||||
host_minfps = Cvar_Get( "host_minfps", "10", CVAR_ARCHIVE, "host fps lower limit" );
|
||||
host_maxfps = Cvar_Get( "host_maxfps", "100", CVAR_ARCHIVE, "host fps upper limit" );
|
||||
host_ticrate = Cvar_Get( "sys_ticrate", "0.0138889", CVAR_SYSTEMINFO, "how long a server frame is in seconds" );
|
||||
host_framerate = Cvar_Get( "host_framerate", "0", 0, "locks frame timing to this value in seconds" );
|
||||
host_maxclients = Cvar_Get("host_maxclients", "1", CVAR_SERVERINFO|CVAR_LATCH, "server maxplayers limit" );
|
||||
host_serverstate = Cvar_Get("host_serverstate", "0", CVAR_SERVERINFO, "displays current server state" );
|
||||
host_registered = Cvar_Get( "registered", "1", CVAR_SYSTEMINFO, "indicate shareware version of game" );
|
||||
timescale = Cvar_Get( "timescale", "1.0", 0, "slow-mo timescale" );
|
||||
|
||||
s = va( "^1Xash %g ^3%s", GI->version, buildstring );
|
||||
s = va("^1Xash %g ^3%s", GI->version, buildstring );
|
||||
Cvar_Get( "version", s, CVAR_SERVERINFO|CVAR_INIT, "engine current version" );
|
||||
|
||||
NET_Init();
|
||||
|
@ -529,7 +573,6 @@ void Host_Main( void )
|
|||
} while( time < 0.001 );
|
||||
|
||||
Host_Frame( time );
|
||||
|
||||
oldtime = newtime;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,6 @@ typedef struct server_s
|
|||
bool loadgame; // client begins should reuse existing entity
|
||||
|
||||
double time; // always sv.framenum * 50 msec
|
||||
double oldtime; // prev.frame time
|
||||
double frametime;
|
||||
int framenum;
|
||||
int net_framenum;
|
||||
|
@ -93,17 +92,13 @@ typedef struct server_s
|
|||
typedef struct
|
||||
{
|
||||
entity_state_t ps; // player state
|
||||
int index; // client edict index
|
||||
|
||||
byte areabits[MAX_MAP_AREA_BYTES]; // portalarea visibility bits
|
||||
int areabits_size;
|
||||
int num_entities;
|
||||
int first_entity; // into the circular sv_packet_entities[]
|
||||
double senttime; // time the message was transmitted
|
||||
|
||||
float message_sent; // time the message was transmitted
|
||||
float message_acked; // time the message was acked
|
||||
size_t message_size; // used to rate drop packets
|
||||
|
||||
int index; // client edict index
|
||||
} client_frame_t;
|
||||
|
||||
typedef struct sv_client_s
|
||||
|
@ -111,15 +106,22 @@ typedef struct sv_client_s
|
|||
cl_state_t state;
|
||||
|
||||
char userinfo[MAX_INFO_STRING]; // name, etc
|
||||
int lastframe; // for delta compression
|
||||
int skipframes; // client synchronyze with phys frame
|
||||
usercmd_t lastcmd; // for filling in big drops
|
||||
|
||||
int spectator; // non-interactive (FIXME: make cs_spectator)
|
||||
int spectator; // non-interactive
|
||||
|
||||
int commandMsec; // every seconds this is reset, if user
|
||||
// commands exhaust it, assume time cheating
|
||||
|
||||
int frame_latency[LATENCY_COUNTS];
|
||||
int ping;
|
||||
int rate;
|
||||
|
||||
int message_size[RATE_MESSAGES]; // used to rate drop packets
|
||||
float rate;
|
||||
|
||||
int surpressCount; // number of messages rate supressed
|
||||
|
||||
edict_t *edict; // EDICT_NUM(clientnum+1)
|
||||
char name[32]; // extracted from userinfo, color string allowed
|
||||
|
@ -136,11 +138,8 @@ typedef struct sv_client_s
|
|||
int downloadsize; // total bytes (can't use EOF because of paks)
|
||||
int downloadcount; // bytes sent
|
||||
|
||||
int deltamessage; // frame last client usercmd message
|
||||
double lastmessage; // sv.framenum when packet was last received
|
||||
double lastconnect;
|
||||
double nextsnapshot; // send another snapshot when svs.realtime >= nextsnapshot
|
||||
float snapshot_time; // requests a snapshot every snapshot_time unless rate choked
|
||||
|
||||
int challenge; // challenge of this user, randomly generated
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ void SV_DirectConnect( netadr_t from )
|
|||
for( i = 0, cl = svs.clients; i < Host_MaxClients(); i++, cl++ )
|
||||
{
|
||||
if( cl->state == cs_free ) continue;
|
||||
if( NET_CompareBaseAdr( from, cl->netchan.remote_address ) && (cl->netchan.qport == qport || from.port == cl->netchan.remote_address.port))
|
||||
if( NET_CompareBaseAdr(from, cl->netchan.remote_address) && (cl->netchan.qport == qport || from.port == cl->netchan.remote_address.port))
|
||||
{
|
||||
if(!NET_IsLocalAddress( from ) && (svs.realtime - cl->lastconnect) < sv_reconnect_limit->value )
|
||||
{
|
||||
|
@ -203,7 +203,6 @@ gotnewcl:
|
|||
newcl->state = cs_connected;
|
||||
newcl->lastmessage = svs.realtime;
|
||||
newcl->lastconnect = svs.realtime;
|
||||
newcl->nextsnapshot = svs.realtime;
|
||||
|
||||
// if this was the first client on the server, or the last client
|
||||
// the server can hold, send a heartbeat to the master.
|
||||
|
@ -539,8 +538,9 @@ void SV_New_f( sv_client_t *cl )
|
|||
|
||||
// send the serverdata
|
||||
MSG_WriteByte( &cl->netchan.message, svc_serverdata );
|
||||
MSG_WriteLong( &cl->netchan.message, PROTOCOL_VERSION );
|
||||
MSG_WriteLong( &cl->netchan.message, PROTOCOL_VERSION);
|
||||
MSG_WriteLong( &cl->netchan.message, svs.spawncount );
|
||||
MSG_WriteFloat( &cl->netchan.message, sv.frametime );
|
||||
MSG_WriteShort( &cl->netchan.message, playernum );
|
||||
MSG_WriteString( &cl->netchan.message, sv.configstrings[CS_NAME] );
|
||||
|
||||
|
@ -555,7 +555,7 @@ void SV_New_f( sv_client_t *cl )
|
|||
|
||||
// begin fetching configstrings
|
||||
MSG_WriteByte( &cl->netchan.message, svc_stufftext );
|
||||
MSG_WriteString( &cl->netchan.message, va( "cmd configstrings %i %i\n", svs.spawncount, 0 ));
|
||||
MSG_WriteString( &cl->netchan.message, va("cmd configstrings %i %i\n", svs.spawncount, 0 ));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -629,9 +629,9 @@ void SV_Baselines_f( sv_client_t *cl )
|
|||
return;
|
||||
}
|
||||
|
||||
start = com.atoi( Cmd_Argv( 2 ));
|
||||
start = com.atoi(Cmd_Argv(2));
|
||||
|
||||
Mem_Set( &nullstate, 0, sizeof( nullstate ));
|
||||
Mem_Set( &nullstate, 0, sizeof(nullstate));
|
||||
|
||||
// write a packet full of data
|
||||
while( cl->netchan.message.cursize < MAX_MSGLEN / 2 && start < host.max_edicts )
|
||||
|
@ -646,7 +646,7 @@ void SV_Baselines_f( sv_client_t *cl )
|
|||
}
|
||||
|
||||
if( start == host.max_edicts ) com.snprintf( baseline, MAX_STRING, "precache %i\n", svs.spawncount );
|
||||
else com.snprintf( baseline, MAX_STRING, "cmd baselines %i %i\n", svs.spawncount, start );
|
||||
else com.snprintf( baseline, MAX_STRING, "cmd baselines %i %i\n",svs.spawncount, start );
|
||||
|
||||
// send next command
|
||||
MSG_WriteByte( &cl->netchan.message, svc_stufftext );
|
||||
|
@ -668,7 +668,6 @@ void SV_Begin_f( sv_client_t *cl )
|
|||
return;
|
||||
}
|
||||
cl->state = cs_spawned;
|
||||
cl->nextsnapshot = svs.realtime; // generate a snapshot immediately
|
||||
SV_PutClientInServer( cl->edict );
|
||||
}
|
||||
|
||||
|
@ -790,18 +789,10 @@ void SV_UserinfoChanged( sv_client_t *cl )
|
|||
if( com.strlen( val ))
|
||||
{
|
||||
i = com.atoi( val );
|
||||
cl->rate = bound ( 2500, i, 25000 );
|
||||
cl->rate = i;
|
||||
cl->rate = bound ( 100, cl->rate, 15000 );
|
||||
}
|
||||
else cl->rate = 5000; // default value (ISDN)
|
||||
|
||||
// snaps command
|
||||
val = Info_ValueForKey( cl->userinfo, "snaps" );
|
||||
if( com.strlen( val ))
|
||||
{
|
||||
i = com.atoi( val );
|
||||
cl->snapshot_time = (1.0f / bound( 1, i, 30 ));
|
||||
}
|
||||
else cl->snapshot_time = 0.02f;
|
||||
else cl->rate = 5000;
|
||||
|
||||
// msg command
|
||||
val = Info_ValueForKey( cl->userinfo, "msg" );
|
||||
|
@ -1420,71 +1411,63 @@ On very fast clients, there may be multiple usercmd packed into
|
|||
each of the backup packets.
|
||||
==================
|
||||
*/
|
||||
static void SV_ReadClientMove( sv_client_t *cl, sizebuf_t *msg, bool noDelta )
|
||||
static void SV_ReadClientMove( sv_client_t *cl, sizebuf_t *msg )
|
||||
{
|
||||
int i, key, cmd_count;
|
||||
int checksum1, checksum2;
|
||||
usercmd_t cmds[UPDATE_BACKUP];
|
||||
usercmd_t *cmd, *oldcmd;
|
||||
usercmd_t nullcmd;
|
||||
int checksumIndex, lastframe;
|
||||
int checksum, calculatedChecksum;
|
||||
usercmd_t nullcmd, oldest, oldcmd, newcmd;
|
||||
int net_drop;
|
||||
double latency;
|
||||
|
||||
if( noDelta ) cl->deltamessage = -1;
|
||||
else cl->deltamessage = cl->netchan.incoming_acknowledged;
|
||||
|
||||
key = msg->readcount;
|
||||
checksum1 = MSG_ReadByte( msg );
|
||||
cmd_count = MSG_ReadByte( msg );
|
||||
|
||||
if( cmd_count < 1 ) return;
|
||||
if( cmd_count > UPDATE_BACKUP )
|
||||
checksumIndex = msg->readcount;
|
||||
checksum = MSG_ReadByte( msg );
|
||||
lastframe = MSG_ReadLong( msg );
|
||||
if( lastframe != cl->lastframe )
|
||||
{
|
||||
// force to server will be crashed
|
||||
MsgDev( D_ERROR, "too many usercmds received\n" );
|
||||
return;
|
||||
cl->lastframe = lastframe;
|
||||
if( cl->lastframe > 0 )
|
||||
{
|
||||
latency = svs.realtime - cl->frames[cl->lastframe & UPDATE_MASK].senttime;
|
||||
cl->frame_latency[cl->lastframe & (LATENCY_COUNTS-1)] = latency;
|
||||
}
|
||||
}
|
||||
|
||||
Mem_Set( &nullcmd, 0, sizeof( nullcmd ));
|
||||
|
||||
for( i = 0, oldcmd = &nullcmd; i < cmd_count; i++ )
|
||||
{
|
||||
cmd = &cmds[i];
|
||||
MSG_ReadDeltaUsercmd( msg, oldcmd, cmd );
|
||||
oldcmd = cmd;
|
||||
}
|
||||
|
||||
// save time for ping calculation
|
||||
cl->frames[cl->netchan.incoming_acknowledged & UPDATE_MASK].message_acked = svs.realtime;
|
||||
MSG_ReadDeltaUsercmd( msg, &nullcmd, &oldest );
|
||||
MSG_ReadDeltaUsercmd( msg, &oldest, &oldcmd );
|
||||
MSG_ReadDeltaUsercmd( msg, &oldcmd, &newcmd );
|
||||
|
||||
if( cl->state != cs_spawned )
|
||||
{
|
||||
cl->deltamessage = -1;
|
||||
cl->lastframe = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
// if the checksum fails, ignore the rest of the packet
|
||||
checksum2 = CRC_Sequence( msg->data + key + 1, msg->readcount - key - 1, cl->netchan.incoming_sequence );
|
||||
if( checksum2 != checksum1 )
|
||||
calculatedChecksum = CRC_Sequence( msg->data + checksumIndex + 1, msg->readcount - checksumIndex - 1, cl->netchan.incoming_sequence );
|
||||
if( calculatedChecksum != checksum )
|
||||
{
|
||||
MsgDev( D_ERROR, "SV_UserMove: failed command checksum for %s (%d != %d)\n", cl->name, checksum2, checksum1 );
|
||||
MsgDev( D_ERROR, "SV_UserMove: failed command checksum for %s (%d != %d)\n", cl->name, calculatedChecksum, checksum );
|
||||
return;
|
||||
}
|
||||
|
||||
// usually, the first couple commands will be duplicates
|
||||
// of ones we have previously received, but the servertimes
|
||||
// in the commands will cause them to be immediately discarded
|
||||
for( i = 0; i < cmd_count; i++ )
|
||||
if( !sv_paused->integer )
|
||||
{
|
||||
// if this is a cmd from before a map_restart ignore it
|
||||
if( cmds[i].servertime > cmds[cmd_count-1].servertime )
|
||||
continue;
|
||||
|
||||
// don't execute if this is an old cmd which is already executed
|
||||
// these old cmds are included when cl_packetdup > 0
|
||||
if( cmds[i].servertime <= cl->lastcmd.servertime )
|
||||
continue;
|
||||
|
||||
SV_Physics_ClientMove( cl, &cmds[i] );
|
||||
net_drop = cl->netchan.dropped;
|
||||
if( net_drop < 20 )
|
||||
{
|
||||
while( net_drop > 2 )
|
||||
{
|
||||
SV_Physics_ClientMove( cl, &cl->lastcmd );
|
||||
net_drop--;
|
||||
}
|
||||
if( net_drop > 1 ) SV_Physics_ClientMove( cl, &oldest );
|
||||
if( net_drop > 0 ) SV_Physics_ClientMove( cl, &oldcmd );
|
||||
|
||||
}
|
||||
SV_Physics_ClientMove( cl, &newcmd );
|
||||
}
|
||||
cl->lastcmd = newcmd;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1527,12 +1510,7 @@ void SV_ExecuteClientMessage( sv_client_t *cl, sizebuf_t *msg )
|
|||
case clc_move:
|
||||
if( move_issued ) return; // someone is trying to cheat...
|
||||
move_issued = true;
|
||||
SV_ReadClientMove( cl, msg, true );
|
||||
break;
|
||||
case clc_deltamove:
|
||||
if( move_issued ) return; // someone is trying to cheat...
|
||||
move_issued = true;
|
||||
SV_ReadClientMove( cl, msg, false );
|
||||
SV_ReadClientMove( cl, msg );
|
||||
break;
|
||||
case clc_stringcmd:
|
||||
s = MSG_ReadString( msg );
|
||||
|
|
|
@ -431,8 +431,8 @@ void SV_Status_f( void )
|
|||
|
||||
if( !cl->state ) continue;
|
||||
|
||||
Msg( "%3i ", i);
|
||||
Msg( "%5i ", (int)cl->edict->v.frags );
|
||||
Msg( "%3i ", i );
|
||||
Msg( "%5i ", cl->edict->v.frags );
|
||||
|
||||
if( cl->state == cs_connected ) Msg( "Connect" );
|
||||
else if( cl->state == cs_zombie ) Msg( "Zombie " );
|
||||
|
@ -444,7 +444,7 @@ void SV_Status_f( void )
|
|||
|
||||
Msg( "%s", cl->name );
|
||||
l = 24 - com.strlen( cl->name );
|
||||
for( j = 0; j < l; j++ ) Msg (" ");
|
||||
for( j = 0; j < l; j++ ) Msg( " " );
|
||||
Msg( "%g ", svs.realtime - cl->lastmessage );
|
||||
s = NET_AdrToString( cl->netchan.remote_address );
|
||||
Msg( "%s", s );
|
||||
|
@ -467,7 +467,7 @@ void SV_ConSay_f( void )
|
|||
sv_client_t *client;
|
||||
int i;
|
||||
|
||||
if( Cmd_Argc() < 2 ) return;
|
||||
if(Cmd_Argc() < 2) return;
|
||||
|
||||
com.strncpy( text, "console: ", MAX_SYSPATH );
|
||||
p = Cmd_Args();
|
||||
|
@ -491,7 +491,7 @@ void SV_ConSay_f( void )
|
|||
SV_Heartbeat_f
|
||||
==================
|
||||
*/
|
||||
void SV_Heartbeat_f( void )
|
||||
void SV_Heartbeat_f (void)
|
||||
{
|
||||
svs.last_heartbeat = MAX_HEARTBEAT;
|
||||
}
|
||||
|
@ -505,7 +505,7 @@ Examine serverinfo string
|
|||
*/
|
||||
void SV_ServerInfo_f( void )
|
||||
{
|
||||
Msg( "Server info settings:\n" );
|
||||
Msg("Server info settings:\n");
|
||||
Info_Print( Cvar_Serverinfo());
|
||||
}
|
||||
|
||||
|
|
|
@ -325,38 +325,43 @@ void SV_WriteFrameToClient( sv_client_t *cl, sizebuf_t *msg )
|
|||
int lastframe;
|
||||
|
||||
// this is the frame we are creating
|
||||
frame = &cl->frames[cl->netchan.outgoing_sequence & UPDATE_MASK];
|
||||
frame = &cl->frames[sv.framenum & UPDATE_MASK];
|
||||
|
||||
if( cl->deltamessage <= 0 || cl->state != cs_spawned )
|
||||
if( cl->lastframe <= 0 )
|
||||
{
|
||||
// client is asking for a retransmit
|
||||
oldframe = NULL;
|
||||
lastframe = 0;
|
||||
lastframe = -1;
|
||||
}
|
||||
else if( cl->netchan.outgoing_sequence - cl->deltamessage >= (UPDATE_BACKUP - 3))
|
||||
else if( sv.framenum - cl->lastframe >= (UPDATE_BACKUP - 3))
|
||||
{
|
||||
// client hasn't gotten a good message through in a long time
|
||||
MsgDev( D_WARN, "%s: Delta request from out of date packet\n", cl->name );
|
||||
oldframe = NULL;
|
||||
lastframe = 0;
|
||||
lastframe = -1;
|
||||
}
|
||||
else
|
||||
{ // we have a valid message to delta from
|
||||
oldframe = &cl->frames[cl->deltamessage & UPDATE_MASK];
|
||||
lastframe = cl->netchan.outgoing_sequence - cl->deltamessage;
|
||||
oldframe = &cl->frames[cl->lastframe & UPDATE_MASK];
|
||||
lastframe = cl->lastframe;
|
||||
|
||||
// the snapshot's entities may still have rolled off the buffer, though
|
||||
if( oldframe->first_entity <= svs.next_client_entities - svs.num_client_entities )
|
||||
{
|
||||
MsgDev( D_WARN, "%s: delta request from out of date entities\n", cl->name );
|
||||
MsgDev( D_WARN, "%s: delta request from out of date entities.\n", cl->name );
|
||||
oldframe = NULL;
|
||||
lastframe = 0;
|
||||
}
|
||||
}
|
||||
|
||||
MSG_WriteByte( msg, svc_time );
|
||||
MSG_WriteFloat( msg, sv.time ); // send a servertime before each frame
|
||||
|
||||
MSG_WriteByte( msg, svc_frame );
|
||||
MSG_WriteFloat( msg, sv.time ); // send a servertime for each frame
|
||||
MSG_WriteByte( msg, lastframe ); // what we are delta'ing from
|
||||
MSG_WriteLong( msg, sv.framenum );
|
||||
MSG_WriteFloat( msg, sv.frametime );
|
||||
MSG_WriteLong( msg, lastframe ); // what we are delta'ing from
|
||||
MSG_WriteByte( msg, cl->surpressCount ); // rate dropped packets
|
||||
cl->surpressCount = 0;
|
||||
|
||||
// send over the areabits
|
||||
MSG_WriteByte( msg, frame->areabits_size ); // never more than 255 bytes
|
||||
|
@ -402,8 +407,8 @@ void SV_BuildClientFrame( sv_client_t *cl )
|
|||
sv.net_framenum++;
|
||||
|
||||
// this is the frame we are creating
|
||||
frame = &cl->frames[cl->netchan.outgoing_sequence & UPDATE_MASK];
|
||||
frame->message_sent = svs.realtime; // save it for ping calc later
|
||||
frame = &cl->frames[sv.framenum & UPDATE_MASK];
|
||||
frame->senttime = svs.realtime; // save it for ping calc later
|
||||
|
||||
// clear everything in this snapshot
|
||||
frame_ents.num_entities = c_fullsend = 0;
|
||||
|
@ -454,75 +459,6 @@ FRAME UPDATES
|
|||
|
||||
===============================================================================
|
||||
*/
|
||||
/*
|
||||
====================
|
||||
SV_RateMsec
|
||||
|
||||
Return the number of msec a given size message is supposed
|
||||
to take to clear, based on the current rate
|
||||
====================
|
||||
*/
|
||||
#define HEADER_RATE_BYTES 10 // sequence, qport etc
|
||||
|
||||
static float SV_RateTime( sv_client_t *cl, size_t msg_size )
|
||||
{
|
||||
float rate_time;
|
||||
|
||||
// individual messages will never be larger than fragment size
|
||||
if( msg_size > MAX_MSGLEN ) msg_size = MAX_MSGLEN;
|
||||
|
||||
rate_time = (msg_size + HEADER_RATE_BYTES) / cl->rate;
|
||||
|
||||
return rate_time;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
SV_SendMessageToClient
|
||||
|
||||
Called by SV_SendClientDatagram
|
||||
=======================
|
||||
*/
|
||||
void SV_SendMessageToClient( sizebuf_t *msg, sv_client_t *cl )
|
||||
{
|
||||
float rate_time;
|
||||
|
||||
// record information about the message
|
||||
cl->frames[cl->netchan.outgoing_sequence & UPDATE_MASK].message_size = msg->cursize;
|
||||
cl->frames[cl->netchan.outgoing_sequence & UPDATE_MASK].message_sent = svs.realtime;
|
||||
cl->frames[cl->netchan.outgoing_sequence & UPDATE_MASK].message_acked = -1;
|
||||
|
||||
// send the datagram
|
||||
Netchan_Transmit( &cl->netchan, msg->cursize, msg->data );
|
||||
|
||||
// set nextsnapshot based on rate and requested number of updates
|
||||
|
||||
// local clients get snapshots every frame
|
||||
if( NET_IsLocalAddress( cl->netchan.remote_address ))
|
||||
{
|
||||
cl->nextsnapshot = svs.realtime + 0.1f; // FIXME: tune this value
|
||||
return;
|
||||
}
|
||||
|
||||
// normal rate / snapshotMsec calculation
|
||||
rate_time = SV_RateTime( cl, msg->cursize );
|
||||
|
||||
// never send more packets than this, no matter what the rate is at
|
||||
if( rate_time < cl->snapshot_time ) rate_time = cl->snapshot_time;
|
||||
|
||||
cl->nextsnapshot = svs.realtime + rate_time;
|
||||
|
||||
// don't pile up empty snapshots while connecting
|
||||
if ( cl->state != cs_spawned )
|
||||
{
|
||||
// a gigantic connection message may have already put the nextsnapshot
|
||||
// more than a second away, so don't shorten it
|
||||
// do shorten if client is downloading
|
||||
if( !cl->download && cl->nextsnapshot < svs.realtime + 1.0f )
|
||||
cl->nextsnapshot = svs.realtime + 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
SV_SendClientDatagram
|
||||
|
@ -556,11 +492,43 @@ bool SV_SendClientDatagram( sv_client_t *cl )
|
|||
MSG_Clear( &msg );
|
||||
}
|
||||
|
||||
SV_SendMessageToClient( &msg, cl );
|
||||
// send the datagram
|
||||
Netchan_Transmit( &cl->netchan, msg.cursize, msg.data );
|
||||
|
||||
// record the size for rate estimation
|
||||
cl->message_size[sv.framenum % RATE_MESSAGES] = msg.cursize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
SV_RateDrop
|
||||
|
||||
Returns true if the client is over its current
|
||||
bandwidth estimation and should not be sent another packet
|
||||
=======================
|
||||
*/
|
||||
bool SV_RateDrop( sv_client_t *cl )
|
||||
{
|
||||
int i, total = 0;
|
||||
|
||||
// never drop over the loopback
|
||||
if( NET_IsLocalAddress( cl->netchan.remote_address ))
|
||||
return false;
|
||||
|
||||
for( i = 0; i < RATE_MESSAGES; i++ )
|
||||
total += cl->message_size[i];
|
||||
|
||||
if( total > cl->rate )
|
||||
{
|
||||
cl->surpressCount++;
|
||||
cl->message_size[sv.framenum % RATE_MESSAGES] = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
SV_SendClientMessages
|
||||
|
@ -590,8 +558,8 @@ void SV_SendClientMessages( void )
|
|||
|
||||
if( cl->state == cs_spawned )
|
||||
{
|
||||
if( svs.realtime < cl->nextsnapshot )
|
||||
continue;
|
||||
// don't overrun bandwidth
|
||||
if( SV_RateDrop( cl )) continue;
|
||||
SV_SendClientDatagram( cl );
|
||||
}
|
||||
else
|
||||
|
|
|
@ -167,7 +167,6 @@ void SV_SpawnServer( const char *server, const char *savename )
|
|||
|
||||
// wipe the entire per-level structure
|
||||
Mem_Set( &sv, 0, sizeof( sv ));
|
||||
svs.realtime = 0.0f;
|
||||
|
||||
// save name for levels that don't set message
|
||||
com.strncpy( sv.configstrings[CS_NAME], server, CS_SIZE );
|
||||
|
@ -180,12 +179,10 @@ void SV_SpawnServer( const char *server, const char *savename )
|
|||
// needs to reconnect
|
||||
if( svs.clients[i].state > cs_connected )
|
||||
svs.clients[i].state = cs_connected;
|
||||
svs.clients[i].deltamessage = -1;
|
||||
svs.clients[i].nextsnapshot = svs.realtime; // generate a snapshot immediately
|
||||
svs.clients[i].lastframe = -1;
|
||||
}
|
||||
|
||||
sv.time = 1.0;
|
||||
sv.frametime = 0.1f;
|
||||
|
||||
com.strncpy( sv.name, server, MAX_STRING );
|
||||
FS_FileBase(server, sv.configstrings[CS_NAME]);
|
||||
|
@ -222,7 +219,11 @@ void SV_SpawnServer( const char *server, const char *savename )
|
|||
svgame.dllFuncs.pfnServerActivate( EDICT_NUM( 0 ), svgame.globals->numEntities, svgame.globals->maxClients );
|
||||
|
||||
// run two frames to allow everything to settle
|
||||
for( i = 0; i < 2; i++ ) SV_Physics();
|
||||
for( i = 0; i < 2; i++ )
|
||||
{
|
||||
sv.frametime = svgame.globals->frametime = host.frametime = 0.1;
|
||||
SV_Physics();
|
||||
}
|
||||
|
||||
// all precaches are complete
|
||||
sv.state = ss_active;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// sv_main.c - server frame code
|
||||
// sv_utils.c - server vm utils
|
||||
//=======================================================================
|
||||
|
||||
#include "common.h"
|
||||
|
@ -50,44 +50,24 @@ void SV_CalcPings( void )
|
|||
int i, j;
|
||||
sv_client_t *cl;
|
||||
int total, count;
|
||||
int delta;
|
||||
|
||||
// clamp fps counter
|
||||
for( i = 0; i < Host_MaxClients(); i++ )
|
||||
{
|
||||
cl = &svs.clients[i];
|
||||
if( cl->state != cs_spawned )
|
||||
{
|
||||
cl->ping = 999;
|
||||
continue;
|
||||
}
|
||||
if( !cl->edict )
|
||||
{
|
||||
cl->ping = 999;
|
||||
continue;
|
||||
}
|
||||
if( cl->edict->v.flags & FL_FAKECLIENT )
|
||||
{
|
||||
cl->ping = 0;
|
||||
continue;
|
||||
}
|
||||
if( cl->state != cs_spawned ) continue;
|
||||
|
||||
total = 0;
|
||||
count = 0;
|
||||
for( j = 0; j < UPDATE_BACKUP; j++ )
|
||||
total = count = 0;
|
||||
for( j = 0; j < LATENCY_COUNTS; j++ )
|
||||
{
|
||||
if( cl->frame_latency > 0 )
|
||||
{
|
||||
if( cl->frames[j].message_acked <= 0 )
|
||||
continue;
|
||||
delta = cl->frames[j].message_acked - cl->frames[j].message_sent;
|
||||
count++;
|
||||
total += delta;
|
||||
total += cl->frame_latency[j];
|
||||
}
|
||||
|
||||
if( count )
|
||||
{
|
||||
cl->ping = total / count;
|
||||
if( cl->ping > 999 ) cl->ping = 999;
|
||||
}
|
||||
else cl->ping = 999;
|
||||
if( !count ) cl->ping = 0;
|
||||
else cl->ping = total / count;
|
||||
|
||||
// let the game dll know about the ping
|
||||
cl->edict->pvServerData->client->ping = cl->ping;
|
||||
|
@ -194,6 +174,16 @@ void SV_CheckTimeouts( void )
|
|||
float droppoint;
|
||||
float zombiepoint;
|
||||
|
||||
if( sv_fps->modified )
|
||||
{
|
||||
if( sv_fps->value < 10 ) Cvar_Set( "sv_fps", "10" ); // too slow, also, netcode uses a byte
|
||||
else if( sv_fps->value > 90 ) Cvar_Set( "sv_fps", "90" ); // abusive
|
||||
sv_fps->modified = false;
|
||||
}
|
||||
|
||||
// calc sv.frametime
|
||||
sv.frametime = ( 1.0f / sv_fps->value );
|
||||
|
||||
droppoint = svs.realtime - timeout->value;
|
||||
zombiepoint = svs.realtime - zombietime->value;
|
||||
|
||||
|
@ -263,12 +253,12 @@ bool SV_CheckPaused( void )
|
|||
{
|
||||
// don't pause
|
||||
if( sv_paused->integer )
|
||||
Cvar_Set( "sv_paused", "0" );
|
||||
Cvar_Set( "paused", "0" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !sv_paused->integer )
|
||||
Cvar_Set( "sv_paused", "1" );
|
||||
Cvar_Set( "paused", "1" );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -279,17 +269,11 @@ SV_RunGameFrame
|
|||
*/
|
||||
void SV_RunGameFrame( void )
|
||||
{
|
||||
// we always need to bump framenum, even if we
|
||||
// don't run the world, otherwise the delta
|
||||
// compression can get confused when a client
|
||||
// has the "current" frame
|
||||
|
||||
// don't run if paused
|
||||
if( !sv_paused->integer || Host_MaxClients() > 1 )
|
||||
{
|
||||
if( SV_CheckPaused( )) return;
|
||||
|
||||
sv.framenum++;
|
||||
sv.time = sv.framenum * sv.frametime;
|
||||
SV_Physics();
|
||||
if( sv.frametime ) SV_Physics();
|
||||
|
||||
// never get more than one tic behind
|
||||
if( sv.time < svs.realtime )
|
||||
|
@ -298,7 +282,6 @@ void SV_RunGameFrame( void )
|
|||
MsgDev( D_INFO, "sv highclamp\n" );
|
||||
svs.realtime = sv.time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -309,13 +292,10 @@ SV_Frame
|
|||
*/
|
||||
void SV_Frame( double time )
|
||||
{
|
||||
static double timeResidual = 0.0f;
|
||||
|
||||
// if server is not active, do nothing
|
||||
if( !svs.initialized ) return;
|
||||
|
||||
// allow pause if only the local client is connected
|
||||
if( SV_CheckPaused()) return;
|
||||
svs.realtime += time;
|
||||
|
||||
// keep the random time dependent
|
||||
rand ();
|
||||
|
@ -326,41 +306,29 @@ void SV_Frame( double time )
|
|||
// read packets from clients
|
||||
SV_ReadPackets ();
|
||||
|
||||
if( sv_fps->modified )
|
||||
// move autonomous things around if enough time has passed
|
||||
if( svs.realtime < sv.time )
|
||||
{
|
||||
if( sv_fps->value < 10 ) Cvar_Set( "sv_fps", "10" ); // too slow, also, netcode uses a byte
|
||||
else if( sv_fps->value > 100 ) Cvar_Set( "sv_fps", "100" ); // abusive
|
||||
sv_fps->modified = false;
|
||||
// never let the time get too far off
|
||||
if( sv.time - svs.realtime > sv.frametime )
|
||||
{
|
||||
if( sv_showclamp->integer )
|
||||
MsgDev( D_INFO, "sv lowclamp\n" );
|
||||
svs.realtime = sv.time - sv.frametime;
|
||||
}
|
||||
|
||||
sv.frametime = (1.0f / sv_fps->value);
|
||||
timeResidual += time;
|
||||
|
||||
if( host.type == HOST_DEDICATED && timeResidual < sv.frametime )
|
||||
{
|
||||
// NET_Sleep will give the OS time slices until either get a packet
|
||||
// or time enough for a server frame has gone by
|
||||
NET_Sleep( sv.frametime - timeResidual );
|
||||
NET_Sleep( sv.time - svs.realtime );
|
||||
return;
|
||||
}
|
||||
|
||||
// update ping based on the last known frame from all clients
|
||||
SV_CalcPings ();
|
||||
|
||||
// let everything in the world think and move
|
||||
while( timeResidual >= sv.frametime )
|
||||
{
|
||||
timeResidual -= sv.frametime;
|
||||
svs.realtime += sv.frametime;
|
||||
sv.time += sv.frametime;
|
||||
|
||||
SV_Physics();
|
||||
sv.framenum++;
|
||||
}
|
||||
|
||||
// give the clients some timeslices
|
||||
SV_GiveMsec ();
|
||||
|
||||
// let everything in the world think and move
|
||||
SV_RunGameFrame ();
|
||||
|
||||
// send messages back to the clients that had packets read this frame
|
||||
SV_SendClientMessages ();
|
||||
|
||||
|
@ -470,7 +438,7 @@ void SV_Init( void )
|
|||
Cvar_Get ("protocol", va("%i", PROTOCOL_VERSION), CVAR_SERVERINFO|CVAR_INIT, "displays server protocol version" );
|
||||
Cvar_Get ("sv_aim", "1", 0, "enable auto-aiming" );
|
||||
|
||||
sv_fps = Cvar_Get( "sv_fps", "60", CVAR_ARCHIVE, "running physics engine at" );
|
||||
sv_fps = Cvar_Get( "sv_fps", "72.1", CVAR_ARCHIVE, "running server physics at" );
|
||||
sv_stepheight = Cvar_Get( "sv_stepheight", DEFAULT_STEPHEIGHT, CVAR_ARCHIVE|CVAR_LATCH, "how high you can step up" );
|
||||
sv_playersonly = Cvar_Get( "playersonly", "0", 0, "freezes time, except for players" );
|
||||
hostname = Cvar_Get ("sv_hostname", "unnamed", CVAR_SERVERINFO | CVAR_ARCHIVE, "host name" );
|
||||
|
|
|
@ -1676,15 +1676,12 @@ void SV_Physics_ClientMove( sv_client_t *client, usercmd_t *cmd )
|
|||
{
|
||||
edict_t *ent = client->edict;
|
||||
|
||||
// save current cmd
|
||||
client->lastcmd = *cmd;
|
||||
|
||||
// call player physics, this needs the proper frametime
|
||||
svgame.globals->frametime = sv.frametime;
|
||||
SV_ClientThink( client, cmd );
|
||||
|
||||
// call standard client pre-think, with frametime = 0
|
||||
svgame.globals->time = sv.time = cmd->servertime;
|
||||
svgame.globals->time = sv.time;
|
||||
svgame.globals->frametime = 0;
|
||||
svgame.dllFuncs.pfnPlayerPreThink( ent );
|
||||
svgame.globals->frametime = sv.frametime;
|
||||
|
@ -1721,7 +1718,7 @@ void SV_Physics_ClientMove( sv_client_t *client, usercmd_t *cmd )
|
|||
SV_TouchTriggers( ent );
|
||||
|
||||
// call standard player post-think, with frametime = 0
|
||||
svgame.globals->time = sv.time = svs.realtime;
|
||||
svgame.globals->time = sv.time;
|
||||
svgame.globals->frametime = 0;
|
||||
svgame.dllFuncs.pfnPlayerPostThink( ent );
|
||||
svgame.globals->frametime = sv.frametime;
|
||||
|
@ -1774,4 +1771,6 @@ void SV_Physics( void )
|
|||
|
||||
// decrement svgame.globals->numEntities if the highest number entities died
|
||||
for( ; EDICT_NUM( svgame.globals->numEntities - 1)->free; svgame.globals->numEntities-- );
|
||||
|
||||
if( !sv_playersonly->integer ) sv.time += sv.frametime;
|
||||
}
|
2
todo.log
2
todo.log
|
@ -78,7 +78,7 @@ Beta 13.12.09
|
|||
47. fixup slowly rendering OK
|
||||
48. implement uimenu into engine.dll OK
|
||||
49. implement new timers OK
|
||||
50. fixup network packets rate OK
|
||||
50. fixup network packets rate
|
||||
51. fixup stair climbing OK
|
||||
52. implement new user move system OK
|
||||
53. finish RenderMode for shaders OK
|
||||
|
|
Reference in New Issue