From 847e005ddceb274eb237d5529d58482f40e2c880 Mon Sep 17 00:00:00 2001 From: havoc Date: Mon, 16 May 2005 05:04:46 +0000 Subject: [PATCH] split SV_ReadClientMove into two functions, SV_ReadClientMove and SV_ApplyClientMove 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 | 6 +++ host.c | 3 -- server.h | 2 +- sv_phys.c | 28 ++++++++++- sv_user.c | 147 ++++++++++++++++++++---------------------------------- 5 files changed, 88 insertions(+), 98 deletions(-) diff --git a/client.h b/client.h index 9cdc2c5d..0f528aab 100644 --- 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 da6cfc11..c076d67c 100644 --- 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(); diff --git a/server.h b/server.h index 91fc3b87..a62603c7 100644 --- 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); diff --git a/sv_phys.c b/sv_phys.c index f5162852..24513b06 100644 --- 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"); diff --git a/sv_user.c b/sv_user.c index ff18ccf4..a3c73b42 100644 --- 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); - } - } -} - -- 2.39.2