// remove stale queue items
n = cl.movement_numqueue;
cl.movement_numqueue = 0;
- if (cl.servermovesequence)
+ if (cls.servermovesequence)
{
for (i = 0;i < n;i++)
{
- if (cl.movement_queue[i].sequence > cl.servermovesequence)
+ if (cl.movement_queue[i].sequence > cls.servermovesequence)
cl.movement_queue[cl.movement_numqueue++] = cl.movement_queue[i];
else if (i == 0)
cl.movement_replay_canjump = !cl.movement_queue[i].jump; // FIXME: this logic is quite broken
if (cl.movement_numqueue < (int)(sizeof(cl.movement_queue)/sizeof(cl.movement_queue[0])))
{
// add to input queue
- cl.movement_queue[cl.movement_numqueue].sequence = cl.movesequence;
+ cl.movement_queue[cl.movement_numqueue].sequence = cls.movesequence;
cl.movement_queue[cl.movement_numqueue].time = cl.movecmd[0].time;
cl.movement_queue[cl.movement_numqueue].frametime = bound(0, cl.movecmd[0].time - cl.movecmd[1].time, 0.1);
VectorCopy(cl.viewangles, cl.movement_queue[cl.movement_numqueue].viewangles);
s.movevars_airaccel_sideways_friction = cl_movement_airaccel_sideways_friction.value;
}
- cl.movement_predicted = (cl_movement.integer && !cls.demoplayback && cls.signon == SIGNONS && cl.stats[STAT_HEALTH] > 0 && !cl.intermission) && ((cls.protocol != PROTOCOL_DARKPLACES6 && cls.protocol != PROTOCOL_DARKPLACES7) || cl.servermovesequence);
+ cl.movement_predicted = (cl_movement.integer && !cls.demoplayback && cls.signon == SIGNONS && cl.stats[STAT_HEALTH] > 0 && !cl.intermission) && ((cls.protocol != PROTOCOL_DARKPLACES6 && cls.protocol != PROTOCOL_DARKPLACES7) || cls.servermovesequence);
if (cl.movement_predicted)
{
//Con_Printf("%f: ", cl.movecmd[0].time);
sizebuf_t buf;
unsigned char data[1024];
static double lastsendtime = 0;
+ double packettime;
double msectime;
static double oldmsectime;
if (!cls.netcon)
return;
-#if 0
- if (cl.movement_predicted && cls.signon == SIGNONS && cls.protocol != PROTOCOL_QUAKEWORLD)
+ packettime = 1.0 / bound(10, cl_netinputpacketspersecond.value, 100);
+ // on quakeworld servers the server replies to client input, so we send
+ // packets whenever we want to
+ // on non-quakeworld servers the client replies to server updates
+ if (cls.protocol == PROTOCOL_QUAKEWORLD)
{
- if (!cl.movement_needupdate)
+ // don't send too often or else network connections can get clogged by a high renderer framerate
+ if (realtime < lastsendtime + packettime)
return;
- cl.movement_needupdate = false;
+ cl.cmd.time = realtime;
}
- else
-#endif
+ else if (cl.movement_predicted || cls.signon < SIGNONS)
{
- double packettime = 1.0 / bound(10, cl_netinputpacketspersecond.value, 100);
// don't send too often or else network connections can get clogged by a high renderer framerate
if (realtime < lastsendtime + packettime)
return;
- // don't let it fall behind if CL_SendMove hasn't been called recently
- // (such is the case when framerate is too low for instance)
- lastsendtime = max(lastsendtime + packettime, realtime);
+ cl.cmd.time = cls.protocol == PROTOCOL_QUAKEWORLD ? realtime : cl.time;
+ }
+ else
+ {
+ // if not predicted, we should just reply to server packets, and
+ // report the real latest packet time rather than our interpolated
+ // time
+ if (!cl.movement_needupdate && realtime < lastsendtime + packettime)
+ return;
+ cl.cmd.time = cls.protocol == PROTOCOL_QUAKEWORLD ? realtime : cl.mtime[0];
}
+ // don't let it fall behind if CL_SendMove hasn't been called recently
+ // (such is the case when framerate is too low for instance)
+ lastsendtime = bound(realtime, lastsendtime + packettime, realtime + packettime);
+ // clear the note down that we sent a packet recently
+ cl.movement_needupdate = false;
- cl.cmd.time = cls.protocol == PROTOCOL_QUAKEWORLD ? realtime : cl.time;
buf.maxsize = sizeof(data);
buf.cursize = 0;
cl.cmd.msec = 100;
oldmsectime = msectime;
- cl.movesequence++;
+ cls.movesequence++;
if (cl_movement.integer)
- cl.cmd.sequence = cl.movesequence;
+ cl.cmd.sequence = cls.movesequence;
else
cl.cmd.sequence = 0;
CL_UpdatePrydonCursor();
// always dump the first two messages, because they may contain leftover inputs from the last level
- if (cl.movesequence > 2)
+ if (cls.movesequence > 2)
{
// update the cl.movecmd array which holds the most recent moves
for (i = CL_MAX_USERCMDS - 1;i >= 1;i--)
for (j = 0, cmd = &cl.movecmd[maxusercmds-1];j < maxusercmds;j++, cmd--)
{
// don't repeat any stale moves
- if (cmd->sequence && cmd->sequence < cl.servermovesequence)
+ if (cmd->sequence && cmd->sequence < cls.servermovesequence)
continue;
// 5/9 bytes
MSG_WriteByte (&buf, clc_move);