split SV_ReadClientMove into two functions, SV_ReadClientMove and SV_ApplyClientMove
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 16 May 2005 05:04:46 +0000 (05:04 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 16 May 2005 05:04:46 +0000 (05:04 +0000)
merged away SV_RunClients (part of its code has been moved to SV_Physics)

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5307 d7cf8633-e32d-0410-b094-e92efae38249

client.h
host.c
server.h
sv_phys.c
sv_user.c

index 9cdc2c5..0f528aa 100644 (file)
--- a/client.h
+++ b/client.h
@@ -346,6 +346,12 @@ typedef struct
        vec3_t  cursor_normal;
        vec_t   cursor_fraction;
        int             cursor_entitynumber;
+
+       double time;
+       double receivetime;
+       double applytime;
+       int buttons;
+       int impulse;
 } usercmd_t;
 
 typedef struct
diff --git a/host.c b/host.c
index da6cfc1..c076d67 100644 (file)
--- a/host.c
+++ b/host.c
@@ -696,9 +696,6 @@ void Host_ServerFrame (void)
                // come in midframe (particularly if host is running really slow)
                NetConn_ServerFrame();
 
-               // read client messages
-               SV_RunClients();
-
                // move things around and think unless paused
                if (sv.frametime)
                        SV_Physics();
index 91fc3b8..a62603c 100644 (file)
--- a/server.h
+++ b/server.h
@@ -333,7 +333,7 @@ void SV_WriteClientdataToMessage (client_t *client, edict_t *ent, sizebuf_t *msg
 
 void SV_MoveToGoal (void);
 
-void SV_RunClients (void);
+void SV_ApplyClientMove (void);
 void SV_SaveSpawnparms (void);
 void SV_SpawnServer (const char *server);
 
index f516285..24513b0 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -1378,12 +1378,36 @@ void SV_Physics (void)
 
                if (i >= 1 && i <= svs.maxclients)
                {
+                       host_client = svs.clients + i - 1;
                        // don't do physics on disconnected clients, FrikBot relies on this
-                       if (!svs.clients[i-1].spawned)
+                       if (!host_client->spawned)
+                       {
+                               memset(&host_client->cmd, 0, sizeof(host_client->cmd));
                                continue;
+                       }
                        // connected slot
+                       // apply the latest accepted move to the entity fields
+                       SV_ApplyClientMove();
+                       // make sure the velocity is sane (not a NaN)
+                       SV_CheckVelocity(ent);
+                       // LordHavoc: QuakeC replacement for SV_ClientThink (player movement)
+                       if (SV_PlayerPhysicsQC)
+                       {
+                               pr_global_struct->time = sv.time;
+                               pr_global_struct->self = EDICT_TO_PROG(ent);
+                               PR_ExecuteProgram ((func_t)(SV_PlayerPhysicsQC - pr_functions), "QC function SV_PlayerPhysics is missing");
+                       }
+                       else
+                               SV_ClientThink ();
+                       // make sure the velocity is sane (not a NaN)
+                       SV_CheckVelocity(ent);
+                       // LordHavoc: a hack to ensure that the (rather silly) id1 quakec
+                       // player_run/player_stand1 does not horribly malfunction if the
+                       // velocity becomes a number that is both == 0 and != 0
+                       // (sounds to me like NaN but to be absolutely safe...)
+                       if (DotProduct(ent->v->velocity, ent->v->velocity) < 0.0001)
+                               VectorClear(ent->v->velocity);
                        // call standard client pre-think
-                       SV_CheckVelocity (ent);
                        pr_global_struct->time = sv.time;
                        pr_global_struct->self = EDICT_TO_PROG(ent);
                        PR_ExecuteProgram (pr_global_struct->PlayerPreThink, "QC function PlayerPreThink is missing");
index ff18ccf..a3c73b4 100644 (file)
--- a/sv_user.c
+++ b/sv_user.c
@@ -602,79 +602,55 @@ void SV_ClientThink(void)
 SV_ReadClientMove
 ===================
 */
-void SV_ReadClientMove (usercmd_t *move)
+extern cvar_t cl_movement_latency;
+void SV_ReadClientMove (void)
 {
        int i;
-       vec3_t angle;
-       int bits;
-       eval_t *val;
-       float total;
+       usercmd_t *move = &host_client->cmd;
+
+       memset(move, 0, sizeof(usercmd_t));
 
-       // read ping time
        if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
-       host_client->ping_times[host_client->num_pings % NUM_PING_TIMES] = sv.time - MSG_ReadFloat ();
+
+       // read ping time
+       move->time = MSG_ReadFloat ();
        if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
-       host_client->num_pings++;
-       for (i=0, total = 0;i < NUM_PING_TIMES;i++)
-               total += host_client->ping_times[i];
-       // can be used for prediction
-       host_client->ping = total / NUM_PING_TIMES;
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_ping)))
-               val->_float = host_client->ping * 1000.0;
+       move->receivetime = sv.time;
+       move->applytime = move->time;
+
+       // FIXME: this is only for testing!
+       move->applytime += cl_movement_latency.value;
 
        // read current angles
        for (i = 0;i < 3;i++)
        {
-               if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
                if (sv.protocol == PROTOCOL_QUAKE)
-                       angle[i] = MSG_ReadAngle8i();
+                       move->viewangles[i] = MSG_ReadAngle8i();
                else if (sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3)
-                       angle[i] = MSG_ReadAngle32f();
+                       move->viewangles[i] = MSG_ReadAngle32f();
                else if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5 || sv.protocol == PROTOCOL_DARKPLACES6)
-                       angle[i] = MSG_ReadAngle16i();
-               if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
+                       move->viewangles[i] = MSG_ReadAngle16i();
        }
-
-       VectorCopy (angle, host_client->edict->v->v_angle);
+       if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
 
        // read movement
-       if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
        move->forwardmove = MSG_ReadCoord16i ();
-       if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
        move->sidemove = MSG_ReadCoord16i ();
-       if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
        move->upmove = MSG_ReadCoord16i ();
        if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_movement)))
-       {
-               val->vector[0] = move->forwardmove;
-               val->vector[1] = move->sidemove;
-               val->vector[2] = move->upmove;
-       }
 
        // read buttons
        if (sv.protocol == PROTOCOL_DARKPLACES6)
-               bits = MSG_ReadLong ();
+               move->buttons = MSG_ReadLong ();
        else
-               bits = MSG_ReadByte ();
+               move->buttons = MSG_ReadByte ();
        if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
-       host_client->edict->v->button0 = bits & 1;
-       host_client->edict->v->button2 = (bits & 2)>>1;
-       // LordHavoc: added 6 new buttons
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button3))) val->_float = ((bits >> 2) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button4))) val->_float = ((bits >> 3) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button5))) val->_float = ((bits >> 4) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button6))) val->_float = ((bits >> 5) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button7))) val->_float = ((bits >> 6) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button8))) val->_float = ((bits >> 7) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_buttonuse))) val->_float = ((bits >> 8) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_buttonchat))) val->_float = ((bits >> 9) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_cursor_active))) val->_float = ((bits >> 10) & 1);
 
+       // read impulse
        i = MSG_ReadByte ();
-       if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
        if (i)
-               host_client->edict->v->impulse = i;
+               move->impulse = i;
+       if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
 
        // PRYDON_CLIENTCURSOR
        if (sv.protocol == PROTOCOL_DARKPLACES6)
@@ -700,10 +676,42 @@ void SV_ReadClientMove (usercmd_t *move)
                        move->cursor_entitynumber = 0;
                if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
        }
+}
+
+void SV_ApplyClientMove (void)
+{
+       int i;
+       eval_t *val;
+       float total;
+       usercmd_t *move = &host_client->cmd;
+
+       // calculate average ping time
+       host_client->ping_times[host_client->num_pings % NUM_PING_TIMES] = move->receivetime - move->time;
+       host_client->num_pings++;
+       for (i=0, total = 0;i < NUM_PING_TIMES;i++)
+               total += host_client->ping_times[i];
+       host_client->ping = total / NUM_PING_TIMES;
+
+       // set the edict fields
+       host_client->edict->v->button0 = move->buttons & 1;
+       host_client->edict->v->button2 = (move->buttons & 2)>>1;
+       host_client->edict->v->impulse = move->impulse;
+       VectorCopy(move->viewangles, host_client->edict->v->v_angle);
+       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button3))) val->_float = ((move->buttons >> 2) & 1);
+       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button4))) val->_float = ((move->buttons >> 3) & 1);
+       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button5))) val->_float = ((move->buttons >> 4) & 1);
+       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button6))) val->_float = ((move->buttons >> 5) & 1);
+       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button7))) val->_float = ((move->buttons >> 6) & 1);
+       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button8))) val->_float = ((move->buttons >> 7) & 1);
+       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_buttonuse))) val->_float = ((move->buttons >> 8) & 1);
+       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_buttonchat))) val->_float = ((move->buttons >> 9) & 1);
+       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_cursor_active))) val->_float = ((move->buttons >> 10) & 1);
+       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_movement))) VectorSet(val->vector, move->forwardmove, move->sidemove, move->upmove);
        if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_cursor_screen))) VectorCopy(move->cursor_screen, val->vector);
        if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_cursor_trace_start))) VectorCopy(move->cursor_start, val->vector);
        if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_cursor_trace_endpos))) VectorCopy(move->cursor_impact, val->vector);
        if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_cursor_trace_ent))) val->edict = EDICT_TO_PROG(EDICT_NUM(move->cursor_entitynumber));
+       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_ping))) val->_float = host_client->ping * 1000.0;
 }
 
 void SV_FrameLost(int framenum)
@@ -807,7 +815,7 @@ void SV_ReadClientMessage(void)
                        return;
 
                case clc_move:
-                       SV_ReadClientMove (&host_client->cmd);
+                       SV_ReadClientMove ();
                        break;
 
                case clc_ackframe:
@@ -829,48 +837,3 @@ void SV_ReadClientMessage(void)
        }
 }
 
-/*
-==================
-SV_RunClients
-==================
-*/
-void SV_RunClients (void)
-{
-       int i;
-
-       for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
-       {
-               if (!host_client->active)
-                       continue;
-
-               if (!host_client->spawned)
-               {
-                       // clear client movement until a new packet is received
-                       memset (&host_client->cmd, 0, sizeof(host_client->cmd));
-                       continue;
-               }
-
-               if (sv.frametime)
-               {
-                       // LordHavoc: QuakeC replacement for SV_ClientThink (player movement)
-                       if (SV_PlayerPhysicsQC)
-                       {
-                               pr_global_struct->time = sv.time;
-                               pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
-                               PR_ExecuteProgram ((func_t)(SV_PlayerPhysicsQC - pr_functions), "QC function SV_PlayerPhysics is missing");
-                       }
-                       else
-                               SV_ClientThink ();
-
-                       SV_CheckVelocity(host_client->edict);
-
-                       // LordHavoc: a hack to ensure that the (rather silly) id1 quakec
-                       // player_run/player_stand1 does not horribly malfunction if the
-                       // velocity becomes a number that is both == 0 and != 0
-                       // (sounds to me like NaN but to be absolutely safe...)
-                       if (DotProduct(host_client->edict->v->velocity, host_client->edict->v->velocity) < 0.0001)
-                               VectorClear(host_client->edict->v->velocity);
-               }
-       }
-}
-