#include "quakedef.h"
-#define ENTITYSIZEPROFILING_START(msg, num) \
+#define ENTITYSIZEPROFILING_START(msg, num, flags) \
int entityprofiling_startsize = msg->cursize
-#define ENTITYSIZEPROFILING_END(msg, num) \
+#define ENTITYSIZEPROFILING_END(msg, num, flags) \
if(developer_networkentities.integer >= 2) \
{ \
- prvm_edict_t *ed = prog->edicts + num; \
- Con_Printf("sent entity update of size %d for a %s\n", (msg->cursize - entityprofiling_startsize), PRVM_serveredictstring(ed, classname) ? PRVM_GetString(prog, PRVM_serveredictstring(ed, classname)) : "(no classname)"); \
+ prvm_edict_t *edict = prog->edicts + num; \
+ Con_Printf("sent entity update of size %u for %d classname %s flags %d\n", (msg->cursize - entityprofiling_startsize), num, PRVM_serveredictstring(edict, classname) ? PRVM_GetString(prog, PRVM_serveredictstring(edict, classname)) : "(no classname)", flags); \
}
+// CSQC entity scope values. Bitflags!
+#define SCOPE_WANTREMOVE 1 // Set if a remove has been scheduled. Never set together with WANTUPDATE.
+#define SCOPE_WANTUPDATE 2 // Set if an update has been scheduled.
+#define SCOPE_WANTSEND (SCOPE_WANTREMOVE | SCOPE_WANTUPDATE)
+#define SCOPE_EXISTED_ONCE 4 // Set if the entity once existed. All these get resent on a full loss.
+#define SCOPE_ASSUMED_EXISTING 8 // Set if the entity is currently assumed existing and therefore needs removes.
+
// this is 88 bytes (must match entity_state_t in protocol.h)
entity_state_t defaultstate =
{
n = client->csqcnumedicts;
for(i = 0; i < n; ++i)
{
- if(client->csqcentityglobalhistory[i])
+ if(client->csqcentityscope[i] & SCOPE_EXISTED_ONCE)
{
ed = prog->edicts + i;
- if (PRVM_serveredictfunction(ed, SendEntity))
- client->csqcentitysendflags[i] |= 0xFFFFFF; // FULL RESEND
- else // if it was ever sent to that client as a CSQC entity
- {
- client->csqcentityscope[i] = 1; // REMOVE
- client->csqcentitysendflags[i] |= 0xFFFFFF;
- }
+ client->csqcentitysendflags[i] |= 0xFFFFFF; // FULL RESEND. We can't clear SCOPE_ASSUMED_EXISTING yet as this would cancel removes on a rejected send attempt.
+ if (!PRVM_serveredictfunction(ed, SendEntity)) // If it was ever sent to that client as a CSQC entity...
+ client->csqcentityscope[i] |= SCOPE_ASSUMED_EXISTING; // FORCE REMOVE.
}
}
}
for(i = 0; i < client->csqcnumedicts; ++i)
{
if(recoversendflags[i] < 0)
- {
- // a remove got lost, then either send a remove or - if it was
- // recreated later - a FULL update to make totally sure
- client->csqcentityscope[i] = 1;
- client->csqcentitysendflags[i] = 0xFFFFFF;
- }
+ client->csqcentityscope[i] |= SCOPE_ASSUMED_EXISTING; // FORCE REMOVE.
else
client->csqcentitysendflags[i] |= recoversendflags[i];
}
end = *n;
for (;number < end;number++)
{
- if (client->csqcentityscope[number])
- {
- client->csqcentityscope[number] = 1;
- client->csqcentitysendflags[number] = 0xFFFFFF;
- }
+ client->csqcentityscope[number] &= ~SCOPE_WANTSEND;
+ if (client->csqcentityscope[number] & SCOPE_ASSUMED_EXISTING)
+ client->csqcentityscope[number] |= SCOPE_WANTREMOVE;
+ client->csqcentitysendflags[number] = 0xFFFFFF;
}
ed = prog->edicts + number;
+ client->csqcentityscope[number] &= ~SCOPE_WANTSEND;
if (PRVM_serveredictfunction(ed, SendEntity))
- client->csqcentityscope[number] = 2;
- else if (client->csqcentityscope[number])
+ client->csqcentityscope[number] |= SCOPE_WANTUPDATE;
+ else
{
- client->csqcentityscope[number] = 1;
+ if (client->csqcentityscope[number] & SCOPE_ASSUMED_EXISTING)
+ client->csqcentityscope[number] |= SCOPE_WANTREMOVE;
client->csqcentitysendflags[number] = 0xFFFFFF;
}
number++;
end = client->csqcnumedicts;
for (;number < end;number++)
{
- if (client->csqcentityscope[number])
- {
- client->csqcentityscope[number] = 1;
- client->csqcentitysendflags[number] = 0xFFFFFF;
- }
+ client->csqcentityscope[number] &= ~SCOPE_WANTSEND;
+ if (client->csqcentityscope[number] & SCOPE_ASSUMED_EXISTING)
+ client->csqcentityscope[number] |= SCOPE_WANTREMOVE;
+ client->csqcentitysendflags[number] = 0xFFFFFF;
}
- /*
- // mark all scope entities as remove
- for (number = 1;number < client->csqcnumedicts;number++)
- if (client->csqcentityscope[number])
- client->csqcentityscope[number] = 1;
- // keep visible entities
- for (i = 0, n = numbers;i < numnumbers;i++, n++)
- {
- number = *n;
- ed = prog->edicts + number;
- if (PRVM_serveredictfunction(ed, SendEntity))
- client->csqcentityscope[number] = 2;
- }
- */
-
// now try to emit the entity updates
// (FIXME: prioritize by distance?)
end = client->csqcnumedicts;
for (number = 1;number < end;number++)
{
- if (!client->csqcentityscope[number])
- continue;
- sendflags = client->csqcentitysendflags[number];
- if (!sendflags)
+ if (!(client->csqcentityscope[number] & SCOPE_WANTSEND))
continue;
if(db->num >= NUM_CSQCENTITIES_PER_FRAME)
break;
ed = prog->edicts + number;
- // entity scope is either update (2) or remove (1)
- if (client->csqcentityscope[number] == 1)
+ if (client->csqcentityscope[number] & SCOPE_WANTREMOVE) // Also implies ASSUMED_EXISTING.
{
+ // A removal. SendFlags have no power here.
// write a remove message
// first write the message identifier if needed
if(!sectionstarted)
}
// write the remove message
{
- ENTITYSIZEPROFILING_START(msg, number);
+ ENTITYSIZEPROFILING_START(msg, number, 0);
MSG_WriteShort(msg, (unsigned short)number | 0x8000);
- client->csqcentityscope[number] = 0;
+ client->csqcentityscope[number] &= ~(SCOPE_WANTSEND | SCOPE_ASSUMED_EXISTING);
client->csqcentitysendflags[number] = 0xFFFFFF; // resend completely if it becomes active again
db->entno[db->num] = number;
db->sendflags[db->num] = -1;
db->num += 1;
- client->csqcentityglobalhistory[number] = 1;
- ENTITYSIZEPROFILING_END(msg, number);
+ ENTITYSIZEPROFILING_END(msg, number, 0);
}
if (msg->cursize + 17 >= maxsize)
break;
}
else
{
- // write an update
// save the cursize value in case we overflow and have to rollback
int oldcursize = msg->cursize;
- client->csqcentityscope[number] = 1;
+
+ // An update.
+ sendflags = client->csqcentitysendflags[number];
+ // Nothing to send? FINE.
+ if (!sendflags)
+ continue;
+ // If it's a new entity, always assume sendflags 0xFFFFFF.
+ if (!(client->csqcentityscope[number] & SCOPE_ASSUMED_EXISTING))
+ sendflags = 0xFFFFFF;
+
+ // write an update
if (PRVM_serveredictfunction(ed, SendEntity))
{
if(!sectionstarted)
MSG_WriteByte(msg, svc_csqcentities);
{
- ENTITYSIZEPROFILING_START(msg, number);
+ int oldcursize2 = msg->cursize;
+ ENTITYSIZEPROFILING_START(msg, number, sendflags);
MSG_WriteShort(msg, number);
msg->allowoverflow = true;
PRVM_G_INT(OFS_PARM0) = sv.writeentitiestoclient_cliententitynumber;
PRVM_serverglobaledict(self) = number;
prog->ExecuteProgram(prog, PRVM_serveredictfunction(ed, SendEntity), "Null SendEntity\n");
msg->allowoverflow = false;
- if(PRVM_G_FLOAT(OFS_RETURN) && msg->cursize + 2 <= maxsize)
+ if(!PRVM_G_FLOAT(OFS_RETURN))
+ {
+ // Send rejected by CSQC. This means we want to remove it.
+ // CSQC requests we remove this one.
+ if (client->csqcentityscope[number] & SCOPE_ASSUMED_EXISTING)
+ {
+ msg->cursize = oldcursize2;
+ msg->overflowed = false;
+ MSG_WriteShort(msg, (unsigned short)number | 0x8000);
+ client->csqcentityscope[number] &= ~(SCOPE_WANTSEND | SCOPE_ASSUMED_EXISTING);
+ client->csqcentitysendflags[number] = 0;
+ db->entno[db->num] = number;
+ db->sendflags[db->num] = -1;
+ db->num += 1;
+ // and take note that we have begun the svc_csqcentities
+ // section of the packet
+ sectionstarted = 1;
+ ENTITYSIZEPROFILING_END(msg, number, 0);
+ if (msg->cursize + 17 >= maxsize)
+ break;
+ }
+ else
+ {
+ // Nothing to do. Just don't do it again.
+ msg->cursize = oldcursize;
+ msg->overflowed = false;
+ client->csqcentityscope[number] &= ~SCOPE_WANTSEND;
+ client->csqcentitysendflags[number] = 0;
+ }
+ continue;
+ }
+ else if(PRVM_G_FLOAT(OFS_RETURN) && msg->cursize + 2 <= maxsize)
{
// an update has been successfully written
client->csqcentitysendflags[number] = 0;
db->entno[db->num] = number;
db->sendflags[db->num] = sendflags;
db->num += 1;
- client->csqcentityglobalhistory[number] = 1;
+ client->csqcentityscope[number] &= ~SCOPE_WANTSEND;
+ client->csqcentityscope[number] |= SCOPE_EXISTED_ONCE | SCOPE_ASSUMED_EXISTING;
// and take note that we have begun the svc_csqcentities
// section of the packet
sectionstarted = 1;
- ENTITYSIZEPROFILING_END(msg, number);
+ ENTITYSIZEPROFILING_END(msg, number, sendflags);
if (msg->cursize + 17 >= maxsize)
break;
continue;
for (i = 0;i < numstates;i++)
{
- ENTITYSIZEPROFILING_START(msg, states[i]->number);
s = states[i];
if(PRVM_serveredictfunction((&prog->edicts[s->number]), SendEntity))
continue;
bits |= U_MOREBITS;
bits |= U_SIGNAL;
- MSG_WriteByte (&buf, bits);
- if (bits & U_MOREBITS) MSG_WriteByte(&buf, bits>>8);
- if (sv.protocol != PROTOCOL_NEHAHRAMOVIE)
{
- if (bits & U_EXTEND1) MSG_WriteByte(&buf, bits>>16);
- if (bits & U_EXTEND2) MSG_WriteByte(&buf, bits>>24);
- }
- if (bits & U_LONGENTITY) MSG_WriteShort(&buf, s->number);
- else MSG_WriteByte(&buf, s->number);
+ ENTITYSIZEPROFILING_START(msg, states[i]->number, bits);
- if (bits & U_MODEL)
- {
- if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
- MSG_WriteShort(&buf, s->modelindex);
- else
- MSG_WriteByte(&buf, s->modelindex);
- }
- if (bits & U_FRAME) MSG_WriteByte(&buf, s->frame);
- if (bits & U_COLORMAP) MSG_WriteByte(&buf, s->colormap);
- if (bits & U_SKIN) MSG_WriteByte(&buf, s->skin);
- if (bits & U_EFFECTS) MSG_WriteByte(&buf, s->effects);
- if (bits & U_ORIGIN1) MSG_WriteCoord(&buf, s->origin[0], sv.protocol);
- if (bits & U_ANGLE1) MSG_WriteAngle(&buf, s->angles[0], sv.protocol);
- if (bits & U_ORIGIN2) MSG_WriteCoord(&buf, s->origin[1], sv.protocol);
- if (bits & U_ANGLE2) MSG_WriteAngle(&buf, s->angles[1], sv.protocol);
- if (bits & U_ORIGIN3) MSG_WriteCoord(&buf, s->origin[2], sv.protocol);
- if (bits & U_ANGLE3) MSG_WriteAngle(&buf, s->angles[2], sv.protocol);
- if (bits & U_ALPHA) MSG_WriteByte(&buf, s->alpha);
- if (bits & U_SCALE) MSG_WriteByte(&buf, s->scale);
- if (bits & U_EFFECTS2) MSG_WriteByte(&buf, s->effects >> 8);
- if (bits & U_GLOWSIZE) MSG_WriteByte(&buf, s->glowsize);
- if (bits & U_GLOWCOLOR) MSG_WriteByte(&buf, s->glowcolor);
- if (bits & U_COLORMOD) {int c = ((int)bound(0, s->colormod[0] * (7.0f / 32.0f), 7) << 5) | ((int)bound(0, s->colormod[1] * (7.0f / 32.0f), 7) << 2) | ((int)bound(0, s->colormod[2] * (3.0f / 32.0f), 3) << 0);MSG_WriteByte(&buf, c);}
- if (bits & U_FRAME2) MSG_WriteByte(&buf, s->frame >> 8);
- if (bits & U_MODEL2) MSG_WriteByte(&buf, s->modelindex >> 8);
-
- // the nasty protocol
- if ((bits & U_EXTEND1) && sv.protocol == PROTOCOL_NEHAHRAMOVIE)
- {
- if (s->effects & EF_FULLBRIGHT)
+ MSG_WriteByte (&buf, bits);
+ if (bits & U_MOREBITS) MSG_WriteByte(&buf, bits>>8);
+ if (sv.protocol != PROTOCOL_NEHAHRAMOVIE)
{
- MSG_WriteFloat(&buf, 2); // QSG protocol version
- MSG_WriteFloat(&buf, s->alpha <= 0 ? 0 : (s->alpha >= 255 ? 1 : s->alpha * (1.0f / 255.0f))); // alpha
- MSG_WriteFloat(&buf, 1); // fullbright
+ if (bits & U_EXTEND1) MSG_WriteByte(&buf, bits>>16);
+ if (bits & U_EXTEND2) MSG_WriteByte(&buf, bits>>24);
}
- else
+ if (bits & U_LONGENTITY) MSG_WriteShort(&buf, s->number);
+ else MSG_WriteByte(&buf, s->number);
+
+ if (bits & U_MODEL)
{
- MSG_WriteFloat(&buf, 1); // QSG protocol version
- MSG_WriteFloat(&buf, s->alpha <= 0 ? 0 : (s->alpha >= 255 ? 1 : s->alpha * (1.0f / 255.0f))); // alpha
+ if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
+ MSG_WriteShort(&buf, s->modelindex);
+ else
+ MSG_WriteByte(&buf, s->modelindex);
+ }
+ if (bits & U_FRAME) MSG_WriteByte(&buf, s->frame);
+ if (bits & U_COLORMAP) MSG_WriteByte(&buf, s->colormap);
+ if (bits & U_SKIN) MSG_WriteByte(&buf, s->skin);
+ if (bits & U_EFFECTS) MSG_WriteByte(&buf, s->effects);
+ if (bits & U_ORIGIN1) MSG_WriteCoord(&buf, s->origin[0], sv.protocol);
+ if (bits & U_ANGLE1) MSG_WriteAngle(&buf, s->angles[0], sv.protocol);
+ if (bits & U_ORIGIN2) MSG_WriteCoord(&buf, s->origin[1], sv.protocol);
+ if (bits & U_ANGLE2) MSG_WriteAngle(&buf, s->angles[1], sv.protocol);
+ if (bits & U_ORIGIN3) MSG_WriteCoord(&buf, s->origin[2], sv.protocol);
+ if (bits & U_ANGLE3) MSG_WriteAngle(&buf, s->angles[2], sv.protocol);
+ if (bits & U_ALPHA) MSG_WriteByte(&buf, s->alpha);
+ if (bits & U_SCALE) MSG_WriteByte(&buf, s->scale);
+ if (bits & U_EFFECTS2) MSG_WriteByte(&buf, s->effects >> 8);
+ if (bits & U_GLOWSIZE) MSG_WriteByte(&buf, s->glowsize);
+ if (bits & U_GLOWCOLOR) MSG_WriteByte(&buf, s->glowcolor);
+ if (bits & U_COLORMOD) {int c = ((int)bound(0, s->colormod[0] * (7.0f / 32.0f), 7) << 5) | ((int)bound(0, s->colormod[1] * (7.0f / 32.0f), 7) << 2) | ((int)bound(0, s->colormod[2] * (3.0f / 32.0f), 3) << 0);MSG_WriteByte(&buf, c);}
+ if (bits & U_FRAME2) MSG_WriteByte(&buf, s->frame >> 8);
+ if (bits & U_MODEL2) MSG_WriteByte(&buf, s->modelindex >> 8);
+
+ // the nasty protocol
+ if ((bits & U_EXTEND1) && sv.protocol == PROTOCOL_NEHAHRAMOVIE)
+ {
+ if (s->effects & EF_FULLBRIGHT)
+ {
+ MSG_WriteFloat(&buf, 2); // QSG protocol version
+ MSG_WriteFloat(&buf, s->alpha <= 0 ? 0 : (s->alpha >= 255 ? 1 : s->alpha * (1.0f / 255.0f))); // alpha
+ MSG_WriteFloat(&buf, 1); // fullbright
+ }
+ else
+ {
+ MSG_WriteFloat(&buf, 1); // QSG protocol version
+ MSG_WriteFloat(&buf, s->alpha <= 0 ? 0 : (s->alpha >= 255 ? 1 : s->alpha * (1.0f / 255.0f))); // alpha
+ }
}
- }
- // if the commit is full, we're done this frame
- if (msg->cursize + buf.cursize > maxsize)
- {
- // next frame we will continue where we left off
- break;
+ // if the commit is full, we're done this frame
+ if (msg->cursize + buf.cursize > maxsize)
+ {
+ // next frame we will continue where we left off
+ break;
+ }
+ // write the message to the packet
+ SZ_Write(msg, buf.data, buf.cursize);
+ success = true;
+ ENTITYSIZEPROFILING_END(msg, s->number, bits);
}
- // write the message to the packet
- SZ_Write(msg, buf.data, buf.cursize);
- success = true;
- ENTITYSIZEPROFILING_END(msg, s->number);
}
return success;
}
{
prvm_prog_t *prog = SVVM_prog;
unsigned int bits;
- ENTITYSIZEPROFILING_START(msg, ent->number);
if (ent->active == ACTIVE_NETWORK)
{
// entity is active, check for changes from the delta
if ((bits = EntityState_DeltaBits(delta, ent)))
{
// write the update number, bits, and fields
+ ENTITYSIZEPROFILING_START(msg, ent->number, bits);
MSG_WriteShort(msg, ent->number);
EntityState_WriteExtendBits(msg, bits);
EntityState_WriteFields(ent, msg, bits);
+ ENTITYSIZEPROFILING_END(msg, ent->number, bits);
}
}
else
if (delta->active == ACTIVE_NETWORK)
{
// write the remove number
+ ENTITYSIZEPROFILING_START(msg, ent->number, 0);
MSG_WriteShort(msg, ent->number | 0x8000);
+ ENTITYSIZEPROFILING_END(msg, ent->number, 0);
}
}
- ENTITYSIZEPROFILING_END(msg, ent->number);
}
int EntityState_ReadExtendBits(void)
prvm_prog_t *prog = SVVM_prog;
unsigned int bits = 0;
//dp_model_t *model;
- ENTITYSIZEPROFILING_START(msg, s->number);
if (s->active != ACTIVE_NETWORK)
+ {
+ ENTITYSIZEPROFILING_START(msg, s->number, 0);
MSG_WriteShort(msg, number | 0x8000);
+ ENTITYSIZEPROFILING_END(msg, s->number, 0);
+ }
else
{
if (PRVM_serveredictfunction((&prog->edicts[s->number]), SendEntity))
bits |= E5_EXTEND2;
if (bits >= 16777216)
bits |= E5_EXTEND3;
- MSG_WriteShort(msg, number);
- MSG_WriteByte(msg, bits & 0xFF);
- if (bits & E5_EXTEND1)
- MSG_WriteByte(msg, (bits >> 8) & 0xFF);
- if (bits & E5_EXTEND2)
- MSG_WriteByte(msg, (bits >> 16) & 0xFF);
- if (bits & E5_EXTEND3)
- MSG_WriteByte(msg, (bits >> 24) & 0xFF);
- if (bits & E5_FLAGS)
- MSG_WriteByte(msg, s->flags);
- if (bits & E5_ORIGIN)
{
- if (bits & E5_ORIGIN32)
+ ENTITYSIZEPROFILING_START(msg, s->number, bits);
+ MSG_WriteShort(msg, number);
+ MSG_WriteByte(msg, bits & 0xFF);
+ if (bits & E5_EXTEND1)
+ MSG_WriteByte(msg, (bits >> 8) & 0xFF);
+ if (bits & E5_EXTEND2)
+ MSG_WriteByte(msg, (bits >> 16) & 0xFF);
+ if (bits & E5_EXTEND3)
+ MSG_WriteByte(msg, (bits >> 24) & 0xFF);
+ if (bits & E5_FLAGS)
+ MSG_WriteByte(msg, s->flags);
+ if (bits & E5_ORIGIN)
{
- MSG_WriteCoord32f(msg, s->origin[0]);
- MSG_WriteCoord32f(msg, s->origin[1]);
- MSG_WriteCoord32f(msg, s->origin[2]);
+ if (bits & E5_ORIGIN32)
+ {
+ MSG_WriteCoord32f(msg, s->origin[0]);
+ MSG_WriteCoord32f(msg, s->origin[1]);
+ MSG_WriteCoord32f(msg, s->origin[2]);
+ }
+ else
+ {
+ MSG_WriteCoord13i(msg, s->origin[0]);
+ MSG_WriteCoord13i(msg, s->origin[1]);
+ MSG_WriteCoord13i(msg, s->origin[2]);
+ }
}
- else
+ if (bits & E5_ANGLES)
+ {
+ if (bits & E5_ANGLES16)
+ {
+ MSG_WriteAngle16i(msg, s->angles[0]);
+ MSG_WriteAngle16i(msg, s->angles[1]);
+ MSG_WriteAngle16i(msg, s->angles[2]);
+ }
+ else
+ {
+ MSG_WriteAngle8i(msg, s->angles[0]);
+ MSG_WriteAngle8i(msg, s->angles[1]);
+ MSG_WriteAngle8i(msg, s->angles[2]);
+ }
+ }
+ if (bits & E5_MODEL)
{
- MSG_WriteCoord13i(msg, s->origin[0]);
- MSG_WriteCoord13i(msg, s->origin[1]);
- MSG_WriteCoord13i(msg, s->origin[2]);
+ if (bits & E5_MODEL16)
+ MSG_WriteShort(msg, s->modelindex);
+ else
+ MSG_WriteByte(msg, s->modelindex);
}
- }
- if (bits & E5_ANGLES)
- {
- if (bits & E5_ANGLES16)
+ if (bits & E5_FRAME)
{
- MSG_WriteAngle16i(msg, s->angles[0]);
- MSG_WriteAngle16i(msg, s->angles[1]);
- MSG_WriteAngle16i(msg, s->angles[2]);
+ if (bits & E5_FRAME16)
+ MSG_WriteShort(msg, s->frame);
+ else
+ MSG_WriteByte(msg, s->frame);
}
- else
+ if (bits & E5_SKIN)
+ MSG_WriteByte(msg, s->skin);
+ if (bits & E5_EFFECTS)
{
- MSG_WriteAngle8i(msg, s->angles[0]);
- MSG_WriteAngle8i(msg, s->angles[1]);
- MSG_WriteAngle8i(msg, s->angles[2]);
+ if (bits & E5_EFFECTS32)
+ MSG_WriteLong(msg, s->effects);
+ else if (bits & E5_EFFECTS16)
+ MSG_WriteShort(msg, s->effects);
+ else
+ MSG_WriteByte(msg, s->effects);
}
- }
- if (bits & E5_MODEL)
- {
- if (bits & E5_MODEL16)
- MSG_WriteShort(msg, s->modelindex);
- else
- MSG_WriteByte(msg, s->modelindex);
- }
- if (bits & E5_FRAME)
- {
- if (bits & E5_FRAME16)
- MSG_WriteShort(msg, s->frame);
- else
- MSG_WriteByte(msg, s->frame);
- }
- if (bits & E5_SKIN)
- MSG_WriteByte(msg, s->skin);
- if (bits & E5_EFFECTS)
- {
- if (bits & E5_EFFECTS32)
- MSG_WriteLong(msg, s->effects);
- else if (bits & E5_EFFECTS16)
- MSG_WriteShort(msg, s->effects);
- else
- MSG_WriteByte(msg, s->effects);
- }
- if (bits & E5_ALPHA)
- MSG_WriteByte(msg, s->alpha);
- if (bits & E5_SCALE)
- MSG_WriteByte(msg, s->scale);
- if (bits & E5_COLORMAP)
- MSG_WriteByte(msg, s->colormap);
- if (bits & E5_ATTACHMENT)
- {
- MSG_WriteShort(msg, s->tagentity);
- MSG_WriteByte(msg, s->tagindex);
- }
- if (bits & E5_LIGHT)
- {
- MSG_WriteShort(msg, s->light[0]);
- MSG_WriteShort(msg, s->light[1]);
- MSG_WriteShort(msg, s->light[2]);
- MSG_WriteShort(msg, s->light[3]);
- MSG_WriteByte(msg, s->lightstyle);
- MSG_WriteByte(msg, s->lightpflags);
- }
- if (bits & E5_GLOW)
- {
- MSG_WriteByte(msg, s->glowsize);
- MSG_WriteByte(msg, s->glowcolor);
- }
- if (bits & E5_COLORMOD)
- {
- MSG_WriteByte(msg, s->colormod[0]);
- MSG_WriteByte(msg, s->colormod[1]);
- MSG_WriteByte(msg, s->colormod[2]);
- }
- if (bits & E5_GLOWMOD)
- {
- MSG_WriteByte(msg, s->glowmod[0]);
- MSG_WriteByte(msg, s->glowmod[1]);
- MSG_WriteByte(msg, s->glowmod[2]);
- }
- if (bits & E5_COMPLEXANIMATION)
- {
- if (s->skeletonobject.model && s->skeletonobject.relativetransforms)
+ if (bits & E5_ALPHA)
+ MSG_WriteByte(msg, s->alpha);
+ if (bits & E5_SCALE)
+ MSG_WriteByte(msg, s->scale);
+ if (bits & E5_COLORMAP)
+ MSG_WriteByte(msg, s->colormap);
+ if (bits & E5_ATTACHMENT)
{
- int numbones = s->skeletonobject.model->num_bones;
- int bonenum;
- short pose6s[6];
- MSG_WriteByte(msg, 4);
- MSG_WriteShort(msg, s->modelindex);
- MSG_WriteByte(msg, numbones);
- for (bonenum = 0;bonenum < numbones;bonenum++)
- {
- Matrix4x4_ToBonePose6s(s->skeletonobject.relativetransforms + bonenum, 64, pose6s);
- MSG_WriteShort(msg, pose6s[0]);
- MSG_WriteShort(msg, pose6s[1]);
- MSG_WriteShort(msg, pose6s[2]);
- MSG_WriteShort(msg, pose6s[3]);
- MSG_WriteShort(msg, pose6s[4]);
- MSG_WriteShort(msg, pose6s[5]);
- }
+ MSG_WriteShort(msg, s->tagentity);
+ MSG_WriteByte(msg, s->tagindex);
}
- else
+ if (bits & E5_LIGHT)
{
- dp_model_t *model = SV_GetModelByIndex(s->modelindex);
- if (s->framegroupblend[3].lerp > 0)
- {
- MSG_WriteByte(msg, 3);
- MSG_WriteShort(msg, s->framegroupblend[0].frame);
- MSG_WriteShort(msg, s->framegroupblend[1].frame);
- MSG_WriteShort(msg, s->framegroupblend[2].frame);
- MSG_WriteShort(msg, s->framegroupblend[3].frame);
- MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[0].start, anim_frameduration(model, s->framegroupblend[0].frame), 65.535) * 1000.0));
- MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[1].start, anim_frameduration(model, s->framegroupblend[1].frame), 65.535) * 1000.0));
- MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[2].start, anim_frameduration(model, s->framegroupblend[2].frame), 65.535) * 1000.0));
- MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[3].start, anim_frameduration(model, s->framegroupblend[3].frame), 65.535) * 1000.0));
- MSG_WriteByte(msg, s->framegroupblend[0].lerp * 255.0f);
- MSG_WriteByte(msg, s->framegroupblend[1].lerp * 255.0f);
- MSG_WriteByte(msg, s->framegroupblend[2].lerp * 255.0f);
- MSG_WriteByte(msg, s->framegroupblend[3].lerp * 255.0f);
- }
- else if (s->framegroupblend[2].lerp > 0)
- {
- MSG_WriteByte(msg, 2);
- MSG_WriteShort(msg, s->framegroupblend[0].frame);
- MSG_WriteShort(msg, s->framegroupblend[1].frame);
- MSG_WriteShort(msg, s->framegroupblend[2].frame);
- MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[0].start, anim_frameduration(model, s->framegroupblend[0].frame), 65.535) * 1000.0));
- MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[1].start, anim_frameduration(model, s->framegroupblend[1].frame), 65.535) * 1000.0));
- MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[2].start, anim_frameduration(model, s->framegroupblend[2].frame), 65.535) * 1000.0));
- MSG_WriteByte(msg, s->framegroupblend[0].lerp * 255.0f);
- MSG_WriteByte(msg, s->framegroupblend[1].lerp * 255.0f);
- MSG_WriteByte(msg, s->framegroupblend[2].lerp * 255.0f);
- }
- else if (s->framegroupblend[1].lerp > 0)
+ MSG_WriteShort(msg, s->light[0]);
+ MSG_WriteShort(msg, s->light[1]);
+ MSG_WriteShort(msg, s->light[2]);
+ MSG_WriteShort(msg, s->light[3]);
+ MSG_WriteByte(msg, s->lightstyle);
+ MSG_WriteByte(msg, s->lightpflags);
+ }
+ if (bits & E5_GLOW)
+ {
+ MSG_WriteByte(msg, s->glowsize);
+ MSG_WriteByte(msg, s->glowcolor);
+ }
+ if (bits & E5_COLORMOD)
+ {
+ MSG_WriteByte(msg, s->colormod[0]);
+ MSG_WriteByte(msg, s->colormod[1]);
+ MSG_WriteByte(msg, s->colormod[2]);
+ }
+ if (bits & E5_GLOWMOD)
+ {
+ MSG_WriteByte(msg, s->glowmod[0]);
+ MSG_WriteByte(msg, s->glowmod[1]);
+ MSG_WriteByte(msg, s->glowmod[2]);
+ }
+ if (bits & E5_COMPLEXANIMATION)
+ {
+ if (s->skeletonobject.model && s->skeletonobject.relativetransforms)
{
- MSG_WriteByte(msg, 1);
- MSG_WriteShort(msg, s->framegroupblend[0].frame);
- MSG_WriteShort(msg, s->framegroupblend[1].frame);
- MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[0].start, anim_frameduration(model, s->framegroupblend[0].frame), 65.535) * 1000.0));
- MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[1].start, anim_frameduration(model, s->framegroupblend[1].frame), 65.535) * 1000.0));
- MSG_WriteByte(msg, s->framegroupblend[0].lerp * 255.0f);
- MSG_WriteByte(msg, s->framegroupblend[1].lerp * 255.0f);
+ int numbones = s->skeletonobject.model->num_bones;
+ int bonenum;
+ short pose7s[7];
+ MSG_WriteByte(msg, 4);
+ MSG_WriteShort(msg, s->modelindex);
+ MSG_WriteByte(msg, numbones);
+ for (bonenum = 0;bonenum < numbones;bonenum++)
+ {
+ Matrix4x4_ToBonePose7s(s->skeletonobject.relativetransforms + bonenum, 64, pose7s);
+ MSG_WriteShort(msg, pose7s[0]);
+ MSG_WriteShort(msg, pose7s[1]);
+ MSG_WriteShort(msg, pose7s[2]);
+ MSG_WriteShort(msg, pose7s[3]);
+ MSG_WriteShort(msg, pose7s[4]);
+ MSG_WriteShort(msg, pose7s[5]);
+ MSG_WriteShort(msg, pose7s[6]);
+ }
}
else
{
- MSG_WriteByte(msg, 0);
- MSG_WriteShort(msg, s->framegroupblend[0].frame);
- MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[0].start, anim_frameduration(model, s->framegroupblend[0].frame), 65.535) * 1000.0));
+ dp_model_t *model = SV_GetModelByIndex(s->modelindex);
+ if (s->framegroupblend[3].lerp > 0)
+ {
+ MSG_WriteByte(msg, 3);
+ MSG_WriteShort(msg, s->framegroupblend[0].frame);
+ MSG_WriteShort(msg, s->framegroupblend[1].frame);
+ MSG_WriteShort(msg, s->framegroupblend[2].frame);
+ MSG_WriteShort(msg, s->framegroupblend[3].frame);
+ MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[0].start, anim_frameduration(model, s->framegroupblend[0].frame), 65.535) * 1000.0));
+ MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[1].start, anim_frameduration(model, s->framegroupblend[1].frame), 65.535) * 1000.0));
+ MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[2].start, anim_frameduration(model, s->framegroupblend[2].frame), 65.535) * 1000.0));
+ MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[3].start, anim_frameduration(model, s->framegroupblend[3].frame), 65.535) * 1000.0));
+ MSG_WriteByte(msg, s->framegroupblend[0].lerp * 255.0f);
+ MSG_WriteByte(msg, s->framegroupblend[1].lerp * 255.0f);
+ MSG_WriteByte(msg, s->framegroupblend[2].lerp * 255.0f);
+ MSG_WriteByte(msg, s->framegroupblend[3].lerp * 255.0f);
+ }
+ else if (s->framegroupblend[2].lerp > 0)
+ {
+ MSG_WriteByte(msg, 2);
+ MSG_WriteShort(msg, s->framegroupblend[0].frame);
+ MSG_WriteShort(msg, s->framegroupblend[1].frame);
+ MSG_WriteShort(msg, s->framegroupblend[2].frame);
+ MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[0].start, anim_frameduration(model, s->framegroupblend[0].frame), 65.535) * 1000.0));
+ MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[1].start, anim_frameduration(model, s->framegroupblend[1].frame), 65.535) * 1000.0));
+ MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[2].start, anim_frameduration(model, s->framegroupblend[2].frame), 65.535) * 1000.0));
+ MSG_WriteByte(msg, s->framegroupblend[0].lerp * 255.0f);
+ MSG_WriteByte(msg, s->framegroupblend[1].lerp * 255.0f);
+ MSG_WriteByte(msg, s->framegroupblend[2].lerp * 255.0f);
+ }
+ else if (s->framegroupblend[1].lerp > 0)
+ {
+ MSG_WriteByte(msg, 1);
+ MSG_WriteShort(msg, s->framegroupblend[0].frame);
+ MSG_WriteShort(msg, s->framegroupblend[1].frame);
+ MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[0].start, anim_frameduration(model, s->framegroupblend[0].frame), 65.535) * 1000.0));
+ MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[1].start, anim_frameduration(model, s->framegroupblend[1].frame), 65.535) * 1000.0));
+ MSG_WriteByte(msg, s->framegroupblend[0].lerp * 255.0f);
+ MSG_WriteByte(msg, s->framegroupblend[1].lerp * 255.0f);
+ }
+ else
+ {
+ MSG_WriteByte(msg, 0);
+ MSG_WriteShort(msg, s->framegroupblend[0].frame);
+ MSG_WriteShort(msg, (int)(anim_reducetime(sv.time - s->framegroupblend[0].start, anim_frameduration(model, s->framegroupblend[0].frame), 65.535) * 1000.0));
+ }
}
}
+ if (bits & E5_TRAILEFFECTNUM)
+ MSG_WriteShort(msg, s->traileffectnum);
+ ENTITYSIZEPROFILING_END(msg, s->number, bits);
}
- if (bits & E5_TRAILEFFECTNUM)
- MSG_WriteShort(msg, s->traileffectnum);
}
-
- ENTITYSIZEPROFILING_END(msg, s->number);
}
static void EntityState5_ReadUpdate(entity_state_t *s, int number)
int type;
int bonenum;
int numbones;
- short pose6s[6];
+ short pose7s[7];
type = MSG_ReadByte(&cl_message);
switch(type)
{
if (!skeleton->relativetransforms || skeleton->model != model)
{
skeleton->model = model;
- skeleton->relativetransforms = (matrix4x4_t *) Mem_Realloc(cls.levelmempool, skeleton->relativetransforms, sizeof(*skeleton->relativetransforms) * skeleton->model->num_bones);
- for (bonenum = 0;bonenum < model->num_bones;bonenum++)
+ skeleton->relativetransforms = (matrix4x4_t *) Mem_Realloc(cls.levelmempool, skeleton->relativetransforms, sizeof(*skeleton->relativetransforms) * numbones);
+ for (bonenum = 0;bonenum < numbones;bonenum++)
skeleton->relativetransforms[bonenum] = identitymatrix;
}
for (bonenum = 0;bonenum < numbones;bonenum++)
{
- pose6s[0] = (short)MSG_ReadShort(&cl_message);
- pose6s[1] = (short)MSG_ReadShort(&cl_message);
- pose6s[2] = (short)MSG_ReadShort(&cl_message);
- pose6s[3] = (short)MSG_ReadShort(&cl_message);
- pose6s[4] = (short)MSG_ReadShort(&cl_message);
- pose6s[5] = (short)MSG_ReadShort(&cl_message);
- Matrix4x4_FromBonePose6s(skeleton->relativetransforms + bonenum, 1.0f / 64.0f, pose6s);
+ pose7s[0] = (short)MSG_ReadShort(&cl_message);
+ pose7s[1] = (short)MSG_ReadShort(&cl_message);
+ pose7s[2] = (short)MSG_ReadShort(&cl_message);
+ pose7s[3] = (short)MSG_ReadShort(&cl_message);
+ pose7s[4] = (short)MSG_ReadShort(&cl_message);
+ pose7s[5] = (short)MSG_ReadShort(&cl_message);
+ pose7s[6] = (short)MSG_ReadShort(&cl_message);
+ Matrix4x4_FromBonePose7s(skeleton->relativetransforms + bonenum, 1.0f / 64.0f, pose7s);
}
s->skeletonobject = *skeleton;
break;
d->packetlog[i].packetnumber = 0;
}
-qboolean EntityFrame5_WriteFrame(sizebuf_t *msg, int maxsize, entityframe5_database_t *d, int numstates, const entity_state_t **states, int viewentnum, int movesequence, qboolean need_empty)
+qboolean EntityFrame5_WriteFrame(sizebuf_t *msg, int maxsize, entityframe5_database_t *d, int numstates, const entity_state_t **states, int viewentnum, unsigned int movesequence, qboolean need_empty)
{
prvm_prog_t *prog = SVVM_prog;
const entity_state_t *n;
newsnapindex = cl.qw_validsequence & QW_UPDATE_MASK;
newsnap = d->snapshot + newsnapindex;
memset(newsnap, 0, sizeof(*newsnap));
- oldsnapindex = -1;
oldsnap = NULL;
if (delta)
{