From: havoc Date: Wed, 17 Sep 2003 17:51:31 +0000 (+0000) Subject: the new partial-update entity compression protocol now works for the first time ever X-Git-Tag: xonotic-v0.1.0preview~6378 X-Git-Url: http://git.xonotic.org/?a=commitdiff_plain;h=14a72d7a9ed9d10b3c47e7ff4b4b38664c4ac17a;hp=e1ec645e2d59310561f997421f9ecd98f5832d8d;p=xonotic%2Fdarkplaces.git the new partial-update entity compression protocol now works for the first time ever git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@3466 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/cl_input.c b/cl_input.c index 19630109..84687da6 100644 --- a/cl_input.c +++ b/cl_input.c @@ -448,7 +448,7 @@ void CL_SendMove(usercmd_t *cmd) i = cl.entitydatabase4->ackframenum; if (cl_nodelta.integer) i = -1; - if (developer_networkentities.integer) + if (developer_networkentities.integer >= 1) Con_Printf("send clc_ackentities %i\n", i); MSG_WriteByte(&buf, clc_ackentities); MSG_WriteLong(&buf, i); diff --git a/protocol.c b/protocol.c index 1c95bdb1..86e760a5 100644 --- a/protocol.c +++ b/protocol.c @@ -295,7 +295,7 @@ void EntityState_ReadUpdate(entity_state_t *e, int number) e->tagindex = MSG_ReadByte(); } - if (developer_networkentities.integer) + if (developer_networkentities.integer >= 2) { Con_Printf("ReadUpdate e%i", number); @@ -601,24 +601,6 @@ int EntityFrame_MostRecentlyRecievedFrameNum(entity_database_t *d) -int EntityFrame4_SV_ChooseCommitToReplace(entity_database4_t *d) -{ - int i, best, bestframenum; - best = 0; - bestframenum = d->commit[0].framenum; - for (i = 0;i < MAX_ENTITY_HISTORY;i++) - { - if (!d->commit[i].numentities) - return i; - if (bestframenum > d->commit[i].framenum) - { - bestframenum = d->commit[i].framenum; - best = i; - } - } - return best; -} - entity_state_t *EntityFrame4_GetReferenceEntity(entity_database4_t *d, int number) { if (d->maxreferenceentities <= number) @@ -690,60 +672,48 @@ void EntityFrame4_ResetDatabase(entity_database4_t *d) d->referenceentity[i] = defaultstate; } -void EntityFrame4_AckFrame(entity_database4_t *d, int framenum) +int EntityFrame4_AckFrame(entity_database4_t *d, int framenum) { - int i, j; + int i, j, found = false; entity_database4_commit_t *commit; - // check if the peer is requesting no delta compression + if (d->referenceframenum == framenum) + return true; if (framenum == -1) { EntityFrame4_ResetDatabase(d); - return; + return true; } - // return early if this is already the reference frame - if (d->referenceframenum == framenum) - return; - // find the frame in the database for (i = 0, commit = d->commit;i < MAX_ENTITY_HISTORY;i++, commit++) - if (commit->numentities && commit->framenum == framenum) - break; - // check if the frame was found - if (i == MAX_ENTITY_HISTORY) { - Con_Printf("EntityFrame4_AckFrame: frame %i not found in database, expect glitches! (VERY BAD ERROR)\n", framenum); - d->ackframenum = -1; - EntityFrame4_ResetDatabase(d); - return; - } - // apply commit to database - d->referenceframenum = framenum; - for (j = 0;j < commit->numentities;j++) - { - //*EntityFrame4_GetReferenceEntity(d, commit->entity[j].number) = commit->entity[j]; - entity_state_t *s = EntityFrame4_GetReferenceEntity(d, commit->entity[j].number); - if (developer_networkentities.integer && commit->entity[j].active != s->active) + if (commit->numentities && commit->framenum <= framenum) { - if (commit->entity[j].active) - Con_Printf("commit entity %i has become active (modelindex %i)\n", commit->entity[j].number, commit->entity[j].modelindex); - else - Con_Printf("commit entity %i has become inactive (modelindex %i)\n", commit->entity[j].number, commit->entity[j].modelindex); + if (commit->framenum == framenum) + { + found = true; + d->referenceframenum = framenum; + if (developer_networkentities.integer >= 3) + { + for (j = 0;j < commit->numentities;j++) + { + entity_state_t *s = EntityFrame4_GetReferenceEntity(d, commit->entity[j].number); + if (commit->entity[j].active != s->active) + { + if (commit->entity[j].active) + Con_Printf("commit entity %i has become active (modelindex %i)\n", commit->entity[j].number, commit->entity[j].modelindex); + else + Con_Printf("commit entity %i has become inactive (modelindex %i)\n", commit->entity[j].number, commit->entity[j].modelindex); + } + *s = commit->entity[j]; + } + } + else + for (j = 0;j < commit->numentities;j++) + *EntityFrame4_GetReferenceEntity(d, commit->entity[j].number) = commit->entity[j]; + } + commit->numentities = 0; } - *s = commit->entity[j]; } - // purge the now-obsolete updates - for (i = 0;i < MAX_ENTITY_HISTORY;i++) - if (d->commit[i].framenum <= framenum) - d->commit[i].numentities = 0; -} - -void EntityFrame4_SV_WriteFrame_Begin(entity_database4_t *d, sizebuf_t *msg, int framenum) -{ - d->currentcommit = d->commit + EntityFrame4_SV_ChooseCommitToReplace(d); - d->currentcommit->numentities = 0; - d->currentcommit->framenum = framenum; - MSG_WriteByte(msg, svc_entities); - MSG_WriteLong(msg, d->referenceframenum); - MSG_WriteLong(msg, d->currentcommit->framenum); + return found; } int EntityFrame4_SV_WriteFrame_Entity(entity_database4_t *d, sizebuf_t *msg, int maxbytes, entity_state_t *s) @@ -773,14 +743,6 @@ int EntityFrame4_SV_WriteFrame_Entity(entity_database4_t *d, sizebuf_t *msg, int return true; } -void EntityFrame4_SV_WriteFrame_End(entity_database4_t *d, sizebuf_t *msg) -{ - // remove world message (invalid, and thus a good terminator) - MSG_WriteShort(msg, 0x8000); - // just to be sure - d->currentcommit = NULL; -} - extern void CL_MoveLerpEntityStates(entity_t *ent); void EntityFrame4_CL_ReadFrame(entity_database4_t *d) { @@ -791,22 +753,32 @@ void EntityFrame4_CL_ReadFrame(entity_database4_t *d) framenum = MSG_ReadLong(); // read the start number enumber = MSG_ReadShort(); + if (developer_networkentities.integer >= 1) + { + Con_Printf("recv svc_entities ref:%i num:%i (database: ref:%i commits:", referenceframenum, framenum, d->referenceframenum); + for (i = 0;i < MAX_ENTITY_HISTORY;i++) + if (d->commit[i].numentities) + Con_Printf(" %i", d->commit[i].framenum); + Con_Printf("\n"); + } + if (!EntityFrame4_AckFrame(d, referenceframenum)) + { + Con_Printf("EntityFrame4_CL_ReadFrame: reference frame invalid (VERY BAD ERROR), this update will be skipped\n"); + skip = true; + d->ackframenum = -1; + EntityFrame4_ResetDatabase(d); + } + d->currentcommit = NULL; for (i = 0;i < MAX_ENTITY_HISTORY;i++) - if (!d->commit[i].numentities) - break; - if (i < MAX_ENTITY_HISTORY) { - d->currentcommit = d->commit + i; - d->currentcommit->framenum = d->ackframenum = framenum; - d->currentcommit->numentities = 0; - EntityFrame4_AckFrame(d, referenceframenum); - if (d->ackframenum == -1) + if (!d->commit[i].numentities) { - Con_Printf("EntityFrame4_CL_ReadFrame: reference frame invalid, this update will be skipped\n"); - skip = true; + d->currentcommit = d->commit + i; + d->currentcommit->framenum = d->ackframenum = framenum; + d->currentcommit->numentities = 0; } } - else + if (d->currentcommit == NULL) { Con_Printf("EntityFrame4_CL_ReadFrame: error while decoding frame %i: database full, reading but not storing this update\n", framenum); skip = true; @@ -851,20 +823,20 @@ void EntityFrame4_CL_ReadFrame(entity_database4_t *d) if (n & 0x8000) { // simply removed - if (developer_networkentities.integer) + if (developer_networkentities.integer >= 2) Con_Printf("entity %i: remove\n", enumber); cl_entities[enumber].state_current = defaultstate; } else { // read the changes - if (developer_networkentities.integer) + if (developer_networkentities.integer >= 2) Con_Printf("entity %i: update\n", enumber); EntityState_ReadUpdate(&cl_entities[enumber].state_current, enumber); } } - //else if (developer_networkentities.integer) - // Con_Printf("entity %i: copy\n", enumber); + else if (developer_networkentities.integer >= 4) + Con_Printf("entity %i: copy\n", enumber); // fix the number (it gets wiped occasionally by copying from defaultstate) cl_entities[enumber].state_current.number = enumber; // check if we need to update the lerp stuff @@ -877,7 +849,7 @@ void EntityFrame4_CL_ReadFrame(entity_database4_t *d) if (d->currentcommit) EntityFrame4_AddCommitEntity(d, &cl_entities[enumber].state_current); // print extra messages if desired - if (developer_networkentities.integer && cl_entities[enumber].state_current.active != cl_entities[enumber].state_previous.active) + if (developer_networkentities.integer >= 2 && cl_entities[enumber].state_current.active != cl_entities[enumber].state_previous.active) { if (cl_entities[enumber].state_current.active) Con_Printf("entity #%i has become active\n", enumber); diff --git a/protocol.h b/protocol.h index 3c12d09e..67417b3d 100644 --- a/protocol.h +++ b/protocol.h @@ -547,7 +547,6 @@ typedef struct entity_database4_s entity_database4_t; // should-be-private functions that aren't -int EntityFrame4_SV_ChooseCommitToReplace(entity_database4_t *d); entity_state_t *EntityFrame4_GetReferenceEntity(entity_database4_t *d, int number); void EntityFrame4_AddCommitEntity(entity_database4_t *d, entity_state_t *s); @@ -558,15 +557,11 @@ void EntityFrame4_FreeDatabase(entity_database4_t *d); // reset a database (resets compression but does not reallocate anything) void EntityFrame4_ResetDatabase(entity_database4_t *d); // updates database to account for a frame-received acknowledgment -void EntityFrame4_AckFrame(entity_database4_t *d, int framenum); +int EntityFrame4_AckFrame(entity_database4_t *d, int framenum); -// begin writing a frame -void EntityFrame4_SV_WriteFrame_Begin(entity_database4_t *d, sizebuf_t *msg, int framenum); // write an entity in the frame // returns false if full int EntityFrame4_SV_WriteFrame_Entity(entity_database4_t *d, sizebuf_t *msg, int maxbytes, entity_state_t *s); -// end writing a frame -void EntityFrame4_SV_WriteFrame_End(entity_database4_t *d, sizebuf_t *msg); // reads a frame from the network stream void EntityFrame4_CL_ReadFrame(entity_database4_t *d); diff --git a/sv_main.c b/sv_main.c index 109f87ff..8f4eb831 100644 --- a/sv_main.c +++ b/sv_main.c @@ -985,6 +985,16 @@ void SV_WriteEntitiesToClient(client_t *client, edict_t *clent, sizebuf_t *msg) buf.data = data; buf.maxsize = sizeof(data); + d = client->entitydatabase4; + + for (i = 0;i < MAX_ENTITY_HISTORY;i++) + if (!d->commit[i].numentities) + break; + // if commit buffer full, just don't bother writing an update this frame + if (i == MAX_ENTITY_HISTORY) + return; + d->currentcommit = d->commit + i; + // this state's number gets played around with later ClearStateToDefault(&inactiveentitystate); //inactiveentitystate = defaultstate; @@ -1021,17 +1031,23 @@ void SV_WriteEntitiesToClient(client_t *client, edict_t *clent, sizebuf_t *msg) for (i = 0;i < numsendentities;i++) SV_MarkWriteEntityStateToClient(sendentities + i); - d = client->entitydatabase4; // calculate maximum bytes to allow in this packet // deduct 4 to account for the end data maxbytes = min(msg->maxsize, MAX_PACKETFRAGMENT) - 4; - d->currentcommit = d->commit + EntityFrame4_SV_ChooseCommitToReplace(d); d->currentcommit->numentities = 0; d->currentcommit->framenum = ++client->entityframenumber; MSG_WriteByte(msg, svc_entities); MSG_WriteLong(msg, d->referenceframenum); MSG_WriteLong(msg, d->currentcommit->framenum); + if (developer_networkentities.integer >= 1) + { + Con_Printf("send svc_entities ref:%i num:%i (database: ref:%i commits:", d->referenceframenum, d->currentcommit->framenum, d->referenceframenum); + for (i = 0;i < MAX_ENTITY_HISTORY;i++) + if (d->commit[i].numentities) + Con_Printf(" %i", d->commit[i].framenum); + Con_Printf(")\n"); + } if (d->currententitynumber >= sv.max_edicts) startnumber = 1; else diff --git a/sv_user.c b/sv_user.c index 6dbed501..372b09bd 100644 --- a/sv_user.c +++ b/sv_user.c @@ -744,7 +744,7 @@ void SV_ReadClientMessage(void) case clc_ackentities: host_client->entitydatabase4->ackframenum = MSG_ReadLong(); - if (developer_networkentities.integer) + if (developer_networkentities.integer >= 1) Con_Printf("recv clc_ackentities %i\n", host_client->entitydatabase4->ackframenum); EntityFrame4_AckFrame(host_client->entitydatabase4, host_client->entitydatabase4->ackframenum); break; diff --git a/todo b/todo index 217da6f2..0b50644f 100644 --- a/todo +++ b/todo @@ -4,6 +4,10 @@ -n darkplaces: make LHNET_Read print out the names of read errors (yummyluv) -n darkplaces: revert noclip movement to match nq for compatibility with mods that trap movement as input (MauveBib) -n dpmod: make grapple off-hand (joe hill) +0 darkplaces: add Draw2D function to model struct to make it easy to draw models without an entity (Tomaz) +0 darkplaces: fix "game speed" menu option, it's too far left (Tomaz) +4 darkplaces: add crude DML model loading with animation list (ask Riot for dml library) (Mitchell) +5 darkplaces: add crude SKM model loading with animation list (Vermeulen) 2 darkplaces: should support corona-model shaders somehow (equation: pow(normalizationcubemap(transform(eye, vertexmatrix)) dot3 '0 0 1', 8)), which are normally used around unusually shaped lights instead of flat coronas (Mitchell) 0 lhfire: make a lhfire.txt and move the scripting info to it, add some more general explanation and tips 0 darkplaces: add sv_gameplayfix_grenadebouncedownslopes cvar (default 1)