From 9258d245f283b37f30d3ff362abfbcfdb4109d8e Mon Sep 17 00:00:00 2001 From: havoc Date: Thu, 16 Feb 2006 10:28:15 +0000 Subject: [PATCH] reworked input timing a bit more, now cl_movement 1 mode syncs client packets to the incoming server packets (because the server does not trust the client's timing, only the history of server frames sent to the client, and thus the client has to sync exactly to the server timing to work) moved CL_SendCmd() call into CL_ReadFromServer right after CL_ReadDemoMessage(), this fixes the prediction jitters that recently appeared with the cl_netinputpacketspersecond feature, however it might add a slight delay in local games (I haven't noticed a delay however) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5990 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_input.c | 35 ++++++++++++++++++++++------------- cl_main.c | 1 + cl_parse.c | 1 + client.h | 3 +++ host.c | 10 +++++----- 5 files changed, 32 insertions(+), 18 deletions(-) diff --git a/cl_input.c b/cl_input.c index d1af6899..c3fd63ac 100644 --- a/cl_input.c +++ b/cl_input.c @@ -534,7 +534,7 @@ void CL_ClientMovement_Input(qboolean buttonjump, qboolean buttoncrouch) cl.movement_queue[cl.movement_numqueue++] = cl.movement_queue[i]; } // add to input queue if there is room - if (cl_movement.integer && cl.movement_numqueue < (int)(sizeof(cl.movement_queue)/sizeof(cl.movement_queue[0])) && cl.mtime[0] > cl.mtime[1]) + if (cl.movement_numqueue < (int)(sizeof(cl.movement_queue)/sizeof(cl.movement_queue[0])) && cl.mtime[0] > cl.mtime[1]) { // add to input queue cl.movement_queue[cl.movement_numqueue].sequence = cl.movesequence; @@ -548,10 +548,6 @@ void CL_ClientMovement_Input(qboolean buttonjump, qboolean buttoncrouch) cl.movement_queue[cl.movement_numqueue].crouch = buttoncrouch; cl.movement_numqueue++; } - cl.movement = cl_movement.integer && cl.stats[STAT_HEALTH] > 0 && !cls.demoplayback && !cl.intermission; - // clear queue if client movement is disabled - if (!cl.movement) - cl.movement_numqueue = 0; cl.movement_replay = true; } @@ -585,6 +581,7 @@ void CL_ClientMovement_Replay(void) trace_t trace; trace_t trace2; trace_t trace3; + if (!cl.movement_replay) return; cl.movement_replay = false; @@ -608,7 +605,7 @@ void CL_ClientMovement_Replay(void) // replay the input queue to predict current location // note: this relies on the fact there's always one queue item at the end - for (i = 0;i < cl.movement_numqueue;i++) + for (i = 0;cl.movement && i < cl.movement_numqueue;i++) { client_movementqueue_t *q = cl.movement_queue + bound(0, i, cl.movement_numqueue - 1); frametime = q->frametime; @@ -822,13 +819,23 @@ void CL_SendMove(void) upmove += cl.cmd.upmove; total++; #endif - if (cls.signon != SIGNONS) - return; - if (realtime < lastsendtime + 1.0 / bound(10, cl_netinputpacketspersecond.value, 100)) - 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 + 1.0 / bound(10, cl_netinputpacketspersecond.value, 100), realtime); + + if (cl_movement.integer) + { + if (!cl.movement_needupdate) + return; + cl.movement_needupdate = false; + cl.movement = cl.stats[STAT_HEALTH] > 0 && !cls.demoplayback && !cl.intermission; + } + else + { + cl.movement = false; + if (realtime < lastsendtime + 1.0 / bound(10, cl_netinputpacketspersecond.value, 100)) + 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 + 1.0 / bound(10, cl_netinputpacketspersecond.value, 100), realtime); + } #if MOVEAVERAGING // average the accumulated changes total = 1.0f / total; @@ -1009,6 +1016,8 @@ void CL_SendMove(void) // nothing to send if (!buf.cursize) return; + if (cls.signon != SIGNONS) + return; // FIXME: bits & 16 is +button5, Nexuiz specific CL_ClientMovement_Input((bits & 2) != 0, (bits & 16) != 0); diff --git a/cl_main.c b/cl_main.c index f32a2281..4509dedb 100644 --- a/cl_main.c +++ b/cl_main.c @@ -1480,6 +1480,7 @@ extern void CL_ClientMovement_Replay(); int CL_ReadFromServer(void) { CL_ReadDemoMessage(); + CL_SendCmd(); r_refdef.time = cl.time; r_refdef.extraupdate = !r_speeds.integer; diff --git a/cl_parse.c b/cl_parse.c index 063d6bb5..74f2c15f 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -1465,6 +1465,7 @@ void CL_ParseServerMessage(void) case svc_time: cl.mtime[1] = cl.mtime[0]; cl.mtime[0] = MSG_ReadFloat (); + cl.movement_needupdate = true; break; case svc_clientdata: diff --git a/client.h b/client.h index 7efd028c..262c2ec2 100644 --- a/client.h +++ b/client.h @@ -534,6 +534,9 @@ typedef struct client_state_s // client movement simulation // these fields are only updated by CL_ClientMovement (called by CL_SendMove after parsing each network packet) qboolean movement; + // this is set true by svc_time parsing and causes a new movement to be + // queued for prediction purposes + qboolean movement_needupdate; // indicates the queue has been updated and should be replayed qboolean movement_replay; // simulated data (this is valid even if cl.movement is false) diff --git a/host.c b/host.c index e4ec53df..e63a7f7c 100644 --- a/host.c +++ b/host.c @@ -761,8 +761,8 @@ void _Host_Frame (float time) Cbuf_Execute(); // if running the server locally, make intentions now - if (cls.state == ca_connected && sv.active) - CL_SendCmd(); + //if (cl.islocalgame) + // CL_SendCmd(); //------------------- // @@ -789,11 +789,11 @@ void _Host_Frame (float time) if (cls.state == ca_connected) { + CL_ReadFromServer(); // if running the server remotely, send intentions now after // the incoming messages have been read - if (!sv.active) - CL_SendCmd(); - CL_ReadFromServer(); + //if (!cl.islocalgame) + // CL_SendCmd(); } //ui_update(); -- 2.39.2