- a TODO item

- converted svc_packetentities and svc_deltapacketentities
- added some convenience defines for U_foo grouping
- tweaked Host_NetError's "please report this" print, but it still
  doesn't work
This commit is contained in:
Adam Olsen 2001-11-04 21:23:22 +00:00
parent a856cbc413
commit 87a0a4d7d6
6 changed files with 256 additions and 73 deletions

2
TODO
View file

@ -46,6 +46,8 @@ M software targets should mix color at 16/16 or 24/32 color
? client-only commands (rejected if done via a server stuffcmd)
X ~/.quakeforgerc should support all commands, not just set and setrom
o clean up TODO ;)
o add a U_PHYSICAL field to entities. it should include a solid bit,
a rotated bbox bit, and mins/maxs for the bbos
These are explained better in doc/ideas/rhamph.txt:
? portal vis system

View file

@ -245,9 +245,13 @@ net_status_t NET_SVC_Modellist_Parse (net_svc_modellist_t *block, msg_t *msg);
net_status_t NET_SVC_Soundlist_Emit (net_svc_soundlist_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_Soundlist_Parse (net_svc_soundlist_t *block, msg_t *msg);
net_status_t NET_SVC_PacketEntities_Emit (net_svc_packetentities_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_PacketEntities_Parse (net_svc_packetentities_t *block,
msg_t *msg);
msg_t *msg);
net_status_t NET_SVC_DeltaPacketEntities_Emit (net_svc_deltapacketentities_t *block,
sizebuf_t *buf);
net_status_t NET_SVC_DeltaPacketEntities_Parse (net_svc_deltapacketentities_t *block,
msg_t *msg);
msg_t *msg);
#endif // NET_SVC_H

View file

@ -214,6 +214,22 @@
#define U_UNUSED30 (1<<30) // future expansion
#define U_EXTEND3 (1<<31) // another byte to follow, future expansion
#define U_GROUP_ORIG (U_ORIGIN1 | U_ORIGIN2 | U_ORIGIN3 | \
U_ANGLE2 | U_FRAME | U_REMOVE | U_MOREBITS)
#define U_GROUP_MOREBITS (U_ANGLE1 | U_ANGLE3 | U_MODEL | \
U_COLORMAP | U_SKIN | U_EFFECTS | \
U_SOLID | U_EXTEND1)
#define U_GROUP_EXTEND1 (U_ALPHA | U_SCALE | U_EFFECTS2 | \
U_GLOWSIZE | U_GLOWCOLOR | U_COLORMOD | \
U_EXTEND2)
#define U_GROUP_EXTEND2 (U_GLOWTRAIL | U_VIEWMODEL | U_FRAME2)
// I skip the UNISED and EXTEND3 bits because although they exist in
// QSG2, they're not usable
#define U_VERSION_ID ((U_GROUP_ORIG | U_GROUP_MOREBITS) & ~U_EXTEND1)
#define U_VERSION_QSG2 (U_VERSION_ID | U_EXTEND1 | U_GROUP_EXTEND1 | \
U_GROUP_EFFECTS2)
//==============================================
// a sound with no channel is a local only sound

View file

@ -1335,8 +1335,9 @@ Host_NetError (const char *message, ...)
va_start (argptr, message);
Host_EndGame (message, argptr);
Sys_Printf ("Please report this to quake-devel@lists.sourceforge.net, "
"including the packet log printed out above\n");
Con_Printf ("%s", "Please report this to "
"quake-devel@lists.sourceforge.net, including the "
"packet log printed out above\n");
va_end (argptr);
}

View file

@ -705,6 +705,65 @@ NET_SVC_Soundlist_Parse (net_svc_soundlist_t *block, msg_t *msg)
return msg->badread;
}
// this is a sub-block, not a real block
void
NET_SVC_Delta_Emit (entity_state_t *es, unsigned int bits, sizebuf_t *buf)
{
// bytes of bits: [EXT2][EXT1][ORIG][MORE]
bits = es->flags;
if (bits & U_MOREBITS)
MSG_WriteByte (buf, bits & 255);
if (bits & U_EXTEND1) {
MSG_WriteByte (buf, (bits >> 16) & 255);
if (bits & U_EXTEND2)
MSG_WriteByte (buf, (bits >> 24) & 255);
}
if (bits & U_MODEL)
MSG_WriteByte (buf, es->modelindex);
if (bits & U_FRAME)
MSG_WriteByte (buf, es->frame);
if (bits & U_COLORMAP)
MSG_WriteByte (buf, es->colormap);
if (bits & U_SKIN)
MSG_WriteByte (buf, es->skinnum);
if (bits & U_EFFECTS)
MSG_WriteByte (buf, es->effects);
if (bits & U_ORIGIN1)
MSG_WriteCoord (buf, es->origin[0]);
if (bits & U_ANGLE1)
MSG_WriteAngle (buf, es->angles[0]);
if (bits & U_ORIGIN2)
MSG_WriteCoord (buf, es->origin[1]);
if (bits & U_ANGLE2)
MSG_WriteAngle (buf, es->angles[1]);
if (bits & U_ORIGIN3)
MSG_WriteCoord (buf, es->origin[2]);
if (bits & U_ANGLE3)
MSG_WriteAngle (buf, es->angles[2]);
if (bits & U_ALPHA)
MSG_WriteByte (buf, es->alpha);
if (bits & U_SCALE)
MSG_WriteByte (buf, es->scale);
if (bits & U_EFFECTS2)
MSG_WriteByte (buf, es->effects >> 8);
if (bits & U_GLOWSIZE)
MSG_WriteByte (buf, es->glow_size);
if (bits & U_GLOWCOLOR)
MSG_WriteByte (buf, es->glow_color);
if (bits & U_COLORMOD)
MSG_WriteByte (buf, es->colormod);
if (bits & U_FRAME2)
MSG_WriteByte (buf, es->frame >> 8);
if (bits & U_SOLID) {
// FIXME
}
}
// this is a sub-block, not a real block
void
NET_SVC_Delta_Parse (entity_state_t *es, unsigned int bits, msg_t *msg)
@ -778,6 +837,29 @@ NET_SVC_Delta_Parse (entity_state_t *es, unsigned int bits, msg_t *msg)
}
}
net_status_t
NET_SVC_PacketEntities_Emit (net_svc_packetentities_t *block, sizebuf_t *buf)
{
int word, delta;
unsigned short bits;
for (word = 0, delta = 0; !buf->overflowed; word++) {
if (word > MAX_PACKET_ENTITIES * 2)
return NET_ERROR;
bits = block->words[word];
MSG_WriteShort (buf, bits);
if (!bits)
break;
if (!(bits & U_REMOVE)) {
if (delta >= MAX_PACKET_ENTITIES)
return NET_ERROR;
NET_SVC_Delta_Emit (&block->deltas[delta], bits, buf);
delta++;
}
}
return buf->overflowed;
}
net_status_t
NET_SVC_PacketEntities_Parse (net_svc_packetentities_t *block, msg_t *msg)
@ -786,7 +868,7 @@ NET_SVC_PacketEntities_Parse (net_svc_packetentities_t *block, msg_t *msg)
unsigned short bits;
for (word = 0, delta = 0; !msg->badread; word++) {
if (word >= MAX_PACKET_ENTITIES * 2)
if (word > MAX_PACKET_ENTITIES * 2)
return NET_ERROR;
bits = (unsigned short) MSG_ReadShort (msg);
block->words[word] = bits;
@ -806,6 +888,32 @@ NET_SVC_PacketEntities_Parse (net_svc_packetentities_t *block, msg_t *msg)
return msg->badread;
}
net_status_t
NET_SVC_DeltaPacketEntities_Emit (net_svc_deltapacketentities_t *block,
sizebuf_t *buf)
{
int word, delta;
unsigned short bits;
MSG_WriteByte (buf, block->from);
for (word = 0, delta = 0; !buf->overflowed; word++) {
if (word > MAX_PACKET_ENTITIES * 2)
return NET_ERROR;
bits = block->words[word];
MSG_WriteShort (buf, bits);
if (!bits)
break;
if (!(bits & U_REMOVE)) {
if (delta >= MAX_PACKET_ENTITIES)
return NET_ERROR;
NET_SVC_Delta_Emit (&block->deltas[delta], bits, buf);
delta++;
}
}
return buf->overflowed;
}
net_status_t
NET_SVC_DeltaPacketEntities_Parse (net_svc_deltapacketentities_t *block,
msg_t *msg)
@ -815,7 +923,7 @@ NET_SVC_DeltaPacketEntities_Parse (net_svc_deltapacketentities_t *block,
block->from = MSG_ReadByte (msg);
for (word = 0, delta = 0; !msg->badread; word++) {
if (word >= MAX_PACKET_ENTITIES * 2)
if (word > MAX_PACKET_ENTITIES * 2)
return NET_ERROR;
bits = (unsigned short) MSG_ReadShort (msg);
block->words[word] = bits;

View file

@ -143,21 +143,12 @@ SV_EmitNailUpdate (sizebuf_t *msg)
NET_SVC_Nails_Emit (&block, msg);
}
/*
SV_WriteDelta
Writes part of a packetentities message.
Can delta from either a baseline or a previous packet_entity
*/
void
SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg,
qboolean force, int stdver)
unsigned int
SV_EntityState_Diff (entity_state_t *from, entity_state_t *to)
{
int bits, i;
float miss;
// send an update
bits = 0;
int i;
float miss;
unsigned int bits = 0;
for (i = 0; i < 3; i++) {
miss = to->origin[i] - from->origin[i];
@ -191,7 +182,7 @@ SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg,
// LordHavoc: cleaned up Endy's coding style, and added missing effects
// Ender (QSG - Begin)
if (stdver > 1) {
// if (stdver > 1) {
if (to->alpha != from->alpha)
bits |= U_ALPHA;
@ -206,20 +197,44 @@ SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg,
if (to->colormod != from->colormod)
bits |= U_COLORMOD;
}
// }
if (bits >= 16777216)
// if (bits >= 16777216)
if (bits & U_GROUP_EXTEND2)
bits |= U_EXTEND2;
if (bits >= 65536)
// if (bits >= 65536)
if (bits & U_GROUP_EXTEND1)
bits |= U_EXTEND1;
// Ender (QSG - End)
if (bits & 511)
// if (bits & 511)
if (bits & U_GROUP_MOREBITS)
bits |= U_MOREBITS;
if (to->flags & U_SOLID)
bits |= U_SOLID;
return bits;
}
/*
SV_WriteDelta
Writes part of a packetentities message.
Can delta from either a baseline or a previous packet_entity
*/
void
SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg,
qboolean force, int stdver)
{
unsigned int bits;
// send an update
bits = SV_EntityState_Diff (from, to);
if (stdver <= 1)
bits &= U_VERSION_ID; // use old the original fields, no extensions
// write the message
if (!to->number)
SV_Error ("Unset entity number");
@ -228,10 +243,7 @@ SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg,
if (!bits && !force)
return; // nothing to send!
i = to->number | (bits & ~511);
if (i & U_REMOVE)
Sys_Error ("U_REMOVE");
MSG_WriteShort (msg, i);
MSG_WriteShort (msg, to->number | (bits & ~511));
if (bits & U_MOREBITS)
MSG_WriteByte (msg, bits & 255);
@ -290,70 +302,108 @@ SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg,
/*
SV_EmitPacketEntities
Writes a delta update of a packet_entities_t to the message.
Writes an update of a packet_entities_t to the message.
*/
void
SV_EmitPacketEntities (client_t *client, packet_entities_t *to, sizebuf_t *msg)
{
int newindex, oldindex, newnum, oldnum, oldmax;
edict_t *ent;
client_frame_t *fromframe;
int index;
entity_state_t *baseline;
net_svc_packetentities_t block;
block.numwords = block.numdeltas = to->num_entities;
for (index = 0; index < to->num_entities; index++) {
baseline = EDICT_NUM (&sv_pr_state,
to->entities[index].number)->data;
block.deltas[index] = to->entities[index];
block.deltas[index].flags =
SV_EntityState_Diff (baseline, &to->entities[index]);
// check if it's a client that doesn't support QSG2
if (client->stdver <= 1)
block.deltas[index].flags &= U_VERSION_ID;
block.words[index] = to->entities[index].number |
(block.deltas[index].flags & ~511);
}
block.words[index] = 0;
MSG_WriteByte (msg, svc_packetentities);
NET_SVC_PacketEntities_Emit (&block, msg);
}
/*
SV_EmitDeltaPacketEntities
Writes a delta update of a packet_entities_t to the message.
*/
void
SV_EmitDeltaPacketEntities (client_t *client, packet_entities_t *to,
sizebuf_t *msg)
{
int newindex, oldindex, newnum, oldnum;
int word;
entity_state_t *baseline;
packet_entities_t *from;
net_svc_deltapacketentities_t block;
// this is the frame that we are going to delta update from
if (client->delta_sequence != -1) {
fromframe = &client->frames[client->delta_sequence & UPDATE_MASK];
from = &fromframe->entities;
oldmax = from->num_entities;
from = &client->frames[client->delta_sequence & UPDATE_MASK].entities;
MSG_WriteByte (msg, svc_deltapacketentities);
MSG_WriteByte (msg, client->delta_sequence);
} else {
oldmax = 0; // no delta update
from = NULL;
block.from = client->delta_sequence;
MSG_WriteByte (msg, svc_packetentities);
}
newindex = 0;
oldindex = 0;
// SV_Printf ("---%i to %i ----\n", client->delta_sequence & UPDATE_MASK,
// client->netchan.outgoing_sequence & UPDATE_MASK);
while (newindex < to->num_entities || oldindex < oldmax) {
newnum =
newindex >= to->num_entities ? 9999 :
to->entities[newindex].number;
oldnum = oldindex >= oldmax ? 9999 : from->entities[oldindex].number;
for (newindex = 0, oldindex = 0, word = 0;
newindex < to->num_entities || oldindex < from->num_entities;
word++) {
newnum = newindex >= to->num_entities ?
9999 : to->entities[newindex].number;
oldnum = oldindex >= from->num_entities ?
9999 : from->entities[oldindex].number;
if (newnum == oldnum) { // delta update from old position
if (newnum == oldnum) { // delta update from old position
// SV_Printf ("delta %i\n", newnum);
SV_WriteDelta (&from->entities[oldindex], &to->entities[newindex],
msg, false, client->stdver);
block.deltas[newindex] = to->entities[newindex];
block.deltas[newindex].flags =
SV_EntityState_Diff (&from->entities[oldindex],
&to->entities[newindex]);
// check if it's a client that doesn't support QSG2
if (client->stdver <= 1)
block.deltas[newindex].flags &= U_VERSION_ID;
block.words[word] = newnum | (block.deltas[newindex].flags & ~511);
oldindex++;
newindex++;
continue;
}
if (newnum < oldnum) { // this is a new entity, send it from
// the baseline
ent = EDICT_NUM (&sv_pr_state, newnum);
} else if (newnum < oldnum) { // this is a new entity, send
// it from the baseline
baseline = EDICT_NUM (&sv_pr_state, newnum)->data;
// SV_Printf ("baseline %i\n", newnum);
SV_WriteDelta (ent->data, &to->entities[newindex], msg, true,
client->stdver);
newindex++;
continue;
}
block.deltas[newindex] = to->entities[newindex];
block.deltas[newindex].flags =
SV_EntityState_Diff (baseline, &to->entities[newindex]);
if (newnum > oldnum) { // the old entity isn't present in
// the new message
// check if it's a client that doesn't support QSG2
if (client->stdver <= 1)
block.deltas[newindex].flags &= U_VERSION_ID;
block.words[word] = newnum | (block.deltas[newindex].flags & ~511);
newindex++;
} else if (newnum > oldnum) { // the old entity isn't
// present in the new message
// SV_Printf ("remove %i\n", oldnum);
MSG_WriteShort (msg, oldnum | U_REMOVE);
block.words[word] = oldnum | U_REMOVE;
oldindex++;
continue;
}
}
MSG_WriteShort (msg, 0); // end of packetentities
block.words[word] = 0;
MSG_WriteByte (msg, svc_deltapacketentities);
NET_SVC_DeltaPacketEntities_Emit (&block, msg);
}
void
@ -560,8 +610,10 @@ SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg)
// encode the packet entities as a delta from the
// last packetentities acknowledged by the client
SV_EmitPacketEntities (client, pack, msg);
if (client->delta_sequence != -1)
SV_EmitDeltaPacketEntities (client, pack, msg);
else
SV_EmitPacketEntities (client, pack, msg);
// now add the specialized nail update
SV_EmitNailUpdate (msg);