DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
sv_ents5.c File Reference
#include "quakedef.h"
#include "protocol.h"
+ Include dependency graph for sv_ents5.c:

Go to the source code of this file.

Functions

static double anim_frameduration (model_t *model, int framenum)
 
static double anim_reducetime (double t, double frameduration, double maxtime)
 
void EntityFrame5_AckFrame (entityframe5_database_t *d, int framenum)
 
entityframe5_database_tEntityFrame5_AllocDatabase (mempool_t *pool)
 
static void EntityFrame5_ExpandEdicts (entityframe5_database_t *d, int newmax)
 
void EntityFrame5_FreeDatabase (entityframe5_database_t *d)
 
void EntityFrame5_LostFrame (entityframe5_database_t *d, int framenum)
 
qbool EntityFrame5_WriteFrame (sizebuf_t *msg, int maxsize, entityframe5_database_t *d, int numstates, const entity_state_t **states, int viewentnum, unsigned int movesequence, qbool need_empty)
 
static int EntityState5_DeltaBits (const entity_state_t *o, const entity_state_t *n)
 
static int EntityState5_Priority (entityframe5_database_t *d, int stateindex)
 
void EntityState5_WriteUpdate (int number, const entity_state_t *s, int changedbits, sizebuf_t *msg)
 
static int packetlog5cmp (const void *a_, const void *b_)
 

Function Documentation

◆ anim_frameduration()

static double anim_frameduration ( model_t * model,
int framenum )
static

Definition at line 20 of file sv_ents5.c.

21{
22 if (!model || !model->animscenes || framenum < 0 || framenum >= model->numframes)
23 return 0;
24 if(model->animscenes[framenum].framerate)
25 return model->animscenes[framenum].framecount / model->animscenes[framenum].framerate;
26 return 0;
27}
string model

References model.

Referenced by EntityState5_WriteUpdate().

◆ anim_reducetime()

static double anim_reducetime ( double t,
double frameduration,
double maxtime )
static

Definition at line 4 of file sv_ents5.c.

5{
6 if(t < 0) // clamp to non-negative
7 return 0;
8 if(t <= maxtime) // time can be represented normally
9 return t;
10 if(frameduration == 0) // don't like dividing by zero
11 return t;
12 if(maxtime <= 2 * frameduration) // if two frames don't fit, we better not do this
13 return t;
14 t -= frameduration * ceil((t - maxtime) / frameduration);
15 // now maxtime - frameduration < t <= maxtime
16 return t;
17}
float ceil(float f)

References ceil().

Referenced by EntityState5_WriteUpdate().

◆ EntityFrame5_AckFrame()

void EntityFrame5_AckFrame ( entityframe5_database_t * d,
int framenum )

Definition at line 684 of file sv_ents5.c.

685{
686 int i;
687 // scan for packets made obsolete by this ack and delete them
688 for (i = 0;i < ENTITYFRAME5_MAXPACKETLOGS;i++)
689 if (d->packetlog[i].packetnumber <= framenum)
690 d->packetlog[i].packetnumber = 0;
691}
#define ENTITYFRAME5_MAXPACKETLOGS
Definition protocol.h:826
int i
entityframe5_packetlog_t packetlog[ENTITYFRAME5_MAXPACKETLOGS]
Definition protocol.h:854

References ENTITYFRAME5_MAXPACKETLOGS, i, entityframe5_database_t::packetlog, and entityframe5_packetlog_t::packetnumber.

Referenced by SV_FrameAck().

◆ EntityFrame5_AllocDatabase()

entityframe5_database_t * EntityFrame5_AllocDatabase ( mempool_t * pool)

Definition at line 605 of file sv_ents5.c.

606{
607 int i;
609 d = (entityframe5_database_t *)Mem_Alloc(pool, sizeof(*d));
610 d->latestframenum = 0;
611 for (i = 0;i < d->maxedicts;i++)
612 d->states[i] = defaultstate;
613 return d;
614}
entity_state_t defaultstate
Definition protocol.c:4
entity_state_t * states
Definition protocol.h:868
#define Mem_Alloc(pool, size)
Definition zone.h:92

References defaultstate, i, entityframe5_database_t::latestframenum, entityframe5_database_t::maxedicts, Mem_Alloc, and entityframe5_database_t::states.

◆ EntityFrame5_ExpandEdicts()

static void EntityFrame5_ExpandEdicts ( entityframe5_database_t * d,
int newmax )
static

Definition at line 38 of file sv_ents5.c.

39{
40 if (d->maxedicts < newmax)
41 {
42 unsigned char *data;
43 int oldmaxedicts = d->maxedicts;
44 int *olddeltabits = d->deltabits;
45 unsigned char *oldpriorities = d->priorities;
46 int *oldupdateframenum = d->updateframenum;
47 entity_state_t *oldstates = d->states;
48 unsigned char *oldvisiblebits = d->visiblebits;
49 d->maxedicts = newmax;
50 data = (unsigned char *)Mem_Alloc(sv_mempool, d->maxedicts * sizeof(int) + d->maxedicts * sizeof(unsigned char) + d->maxedicts * sizeof(int) + d->maxedicts * sizeof(entity_state_t) + (d->maxedicts+7)/8 * sizeof(unsigned char));
51 d->deltabits = (int *)data;data += d->maxedicts * sizeof(int);
52 d->priorities = (unsigned char *)data;data += d->maxedicts * sizeof(unsigned char);
53 d->updateframenum = (int *)data;data += d->maxedicts * sizeof(int);
54 d->states = (entity_state_t *)data;data += d->maxedicts * sizeof(entity_state_t);
55 d->visiblebits = (unsigned char *)data;data += (d->maxedicts+7)/8 * sizeof(unsigned char);
56 if (oldmaxedicts)
57 {
58 memcpy(d->deltabits, olddeltabits, oldmaxedicts * sizeof(int));
59 memcpy(d->priorities, oldpriorities, oldmaxedicts * sizeof(unsigned char));
60 memcpy(d->updateframenum, oldupdateframenum, oldmaxedicts * sizeof(int));
61 memcpy(d->states, oldstates, oldmaxedicts * sizeof(entity_state_t));
62 memcpy(d->visiblebits, oldvisiblebits, (oldmaxedicts+7)/8 * sizeof(unsigned char));
63 // the previous buffers were a single allocation, so just one free
64 Mem_Free(olddeltabits);
65 }
66 }
67}
static int(ZEXPORT *qz_inflate)(z_stream *strm
GLsizeiptr const GLvoid * data
Definition glquake.h:639
mempool_t * sv_mempool
Definition sv_main.c:226
unsigned char * visiblebits
Definition protocol.h:872
unsigned char * priorities
Definition protocol.h:863
#define Mem_Free(mem)
Definition zone.h:96

References data, entityframe5_database_t::deltabits, int(), entityframe5_database_t::maxedicts, Mem_Alloc, Mem_Free, entityframe5_database_t::priorities, entityframe5_database_t::states, sv_mempool, entityframe5_database_t::updateframenum, and entityframe5_database_t::visiblebits.

Referenced by EntityFrame5_WriteFrame(), and EntityState5_Priority().

◆ EntityFrame5_FreeDatabase()

void EntityFrame5_FreeDatabase ( entityframe5_database_t * d)

Definition at line 29 of file sv_ents5.c.

30{
31 // all the [maxedicts] memory is allocated at once, so there's only one
32 // thing to free
33 if (d->maxedicts)
35 Mem_Free(d);
36}

References entityframe5_database_t::deltabits, entityframe5_database_t::maxedicts, and Mem_Free.

Referenced by SV_DropClient(), and SV_SendServerinfo().

◆ EntityFrame5_LostFrame()

void EntityFrame5_LostFrame ( entityframe5_database_t * d,
int framenum )

Definition at line 623 of file sv_ents5.c.

624{
625 int i, j, l, bits;
628 static unsigned char statsdeltabits[(MAX_CL_STATS+7)/8];
629 static int deltabits[MAX_EDICTS];
631
632 for (i = 0, p = d->packetlog;i < ENTITYFRAME5_MAXPACKETLOGS;i++, p++)
633 packetlogs[i] = p;
634 qsort(packetlogs, sizeof(*packetlogs), ENTITYFRAME5_MAXPACKETLOGS, packetlog5cmp);
635
636 memset(deltabits, 0, sizeof(deltabits));
637 memset(statsdeltabits, 0, sizeof(statsdeltabits));
638 for (i = 0; i < ENTITYFRAME5_MAXPACKETLOGS; i++)
639 {
640 p = packetlogs[i];
641
642 if (!p->packetnumber)
643 continue;
644
645 if (p->packetnumber <= framenum)
646 {
647 for (j = 0, s = p->states;j < p->numstates;j++, s++)
648 deltabits[s->number] |= s->bits;
649
650 for (l = 0;l < (MAX_CL_STATS+7)/8;l++)
651 statsdeltabits[l] |= p->statsdeltabits[l];
652
653 p->packetnumber = 0;
654 }
655 else
656 {
657 for (j = 0, s = p->states;j < p->numstates;j++, s++)
658 deltabits[s->number] &= ~s->bits;
659 for (l = 0;l < (MAX_CL_STATS+7)/8;l++)
660 statsdeltabits[l] &= ~p->statsdeltabits[l];
661 }
662 }
663
664 for(i = 0; i < d->maxedicts; ++i)
665 {
666 bits = deltabits[i] & ~d->deltabits[i];
667 if(bits)
668 {
669 d->deltabits[i] |= bits;
670 // if it was a very important update, set priority higher
672 d->priorities[i] = max(d->priorities[i], 4);
673 else
674 d->priorities[i] = max(d->priorities[i], 1);
675 }
676 }
677
678 for (l = 0;l < (MAX_CL_STATS+7)/8;l++)
679 host_client->statsdeltabits[l] |= statsdeltabits[l];
680 // no need to mask out the already-set bits here, as we do not
681 // do that priorities stuff
682}
#define max(A, B)
Definition mathlib.h:38
#define E5_ATTACHMENT
short = s->tagentity byte = s->tagindex
Definition protocol.h:784
#define E5_MODEL
E5_MODEL16=0: byte = s->modelindex E5_MODEL16=1: short = s->modelindex.
Definition protocol.h:751
#define E5_COLORMAP
byte = s->colormap
Definition protocol.h:778
#define E5_FULLUPDATE
reset all entity fields (typically used if status changed)
Definition protocol.h:742
#define MAX_EDICTS
max number of objects in game world at once (32768 protocol limit)
Definition qdefs.h:105
#define MAX_CL_STATS
Definition qstats.h:7
client_t * host_client
Definition sv_main.c:29
unsigned char statsdeltabits[(MAX_CL_STATS+7)/8]
Definition server.h:277
unsigned char statsdeltabits[(MAX_CL_STATS+7)/8]
Definition protocol.h:842
entityframe5_changestate_t states[ENTITYFRAME5_MAXSTATES]
Definition protocol.h:841
static int packetlog5cmp(const void *a_, const void *b_)
Definition sv_ents5.c:616

References entityframe5_changestate_t::bits, entityframe5_database_t::deltabits, E5_ATTACHMENT, E5_COLORMAP, E5_FULLUPDATE, E5_MODEL, ENTITYFRAME5_MAXPACKETLOGS, host_client, i, max, MAX_CL_STATS, MAX_EDICTS, entityframe5_database_t::maxedicts, entityframe5_changestate_t::number, entityframe5_database_t::packetlog, packetlog5cmp(), entityframe5_packetlog_t::packetnumber, entityframe5_database_t::priorities, entityframe5_packetlog_t::states, client_t::statsdeltabits, and entityframe5_packetlog_t::statsdeltabits.

Referenced by EntityFrame5_WriteFrame(), and SV_FrameLost().

◆ EntityFrame5_WriteFrame()

qbool EntityFrame5_WriteFrame ( sizebuf_t * msg,
int maxsize,
entityframe5_database_t * d,
int numstates,
const entity_state_t ** states,
int viewentnum,
unsigned int movesequence,
qbool need_empty )

Definition at line 410 of file sv_ents5.c.

411{
412 prvm_prog_t *prog = SVVM_prog;
413 const entity_state_t *n;
414 int i, num, l, framenum, packetlognumber, priority;
416 unsigned char data[128];
417 entityframe5_packetlog_t *packetlog;
418
419 if (prog->max_edicts > d->maxedicts)
421
422 framenum = d->latestframenum + 1;
423 d->viewentnum = viewentnum;
424
425 // if packet log is full, mark all frames as lost, this will cause
426 // it to send the lost data again
427 for (packetlognumber = 0;packetlognumber < ENTITYFRAME5_MAXPACKETLOGS;packetlognumber++)
428 if (d->packetlog[packetlognumber].packetnumber == 0)
429 break;
430 if (packetlognumber == ENTITYFRAME5_MAXPACKETLOGS)
431 {
432 Con_DPrintf("EntityFrame5_WriteFrame: packetlog overflow for a client, resetting\n");
433 EntityFrame5_LostFrame(d, framenum);
434 packetlognumber = 0;
435 }
436
437 // prepare the buffer
438 memset(&buf, 0, sizeof(buf));
439 buf.data = data;
440 buf.maxsize = sizeof(data);
441
442 // detect changes in states
443 num = 1;
444 for (i = 0;i < numstates;i++)
445 {
446 n = states[i];
447 // mark gaps in entity numbering as removed entities
448 for (;num < n->number;num++)
449 {
450 // if the entity used to exist, clear it
451 if (CHECKPVSBIT(d->visiblebits, num))
452 {
453 CLEARPVSBIT(d->visiblebits, num);
454 d->deltabits[num] = E5_FULLUPDATE;
455 d->priorities[num] = max(d->priorities[num], 8); // removal is cheap
456 d->states[num] = defaultstate;
457 d->states[num].number = num;
458 }
459 }
460 // update the entity state data
461 if (!CHECKPVSBIT(d->visiblebits, num))
462 {
463 // entity just spawned in, don't let it completely hog priority
464 // because of being ancient on the first frame
465 d->updateframenum[num] = framenum;
466 // initial priority is a bit high to make projectiles send on the
467 // first frame, among other things
468 d->priorities[num] = max(d->priorities[num], 4);
469 }
470 SETPVSBIT(d->visiblebits, num);
471 d->deltabits[num] |= EntityState5_DeltaBits(d->states + num, n);
472 d->priorities[num] = max(d->priorities[num], 1);
473 d->states[num] = *n;
474 d->states[num].number = num;
475 // advance to next entity so the next iteration doesn't immediately remove it
476 num++;
477 }
478 // all remaining entities are dead
479 for (;num < d->maxedicts;num++)
480 {
481 if (CHECKPVSBIT(d->visiblebits, num))
482 {
483 CLEARPVSBIT(d->visiblebits, num);
484 d->deltabits[num] = E5_FULLUPDATE;
485 d->priorities[num] = max(d->priorities[num], 8); // removal is cheap
486 d->states[num] = defaultstate;
487 d->states[num].number = num;
488 }
489 }
490
491 // if there isn't at least enough room for an empty svc_entities,
492 // don't bother trying...
493 if (buf.cursize + 11 > buf.maxsize)
494 return false;
495
496 // build lists of entities by priority level
497 memset(d->prioritychaincounts, 0, sizeof(d->prioritychaincounts));
498 l = 0;
499 for (num = 0;num < d->maxedicts;num++)
500 {
501 if (d->priorities[num])
502 {
503 if (d->deltabits[num])
504 {
505 if (d->priorities[num] < (ENTITYFRAME5_PRIORITYLEVELS - 1))
506 d->priorities[num] = EntityState5_Priority(d, num);
507 l = num;
508 priority = d->priorities[num];
510 d->prioritychains[priority][d->prioritychaincounts[priority]++] = num;
511 }
512 else
513 d->priorities[num] = 0;
514 }
515 }
516
517 packetlog = NULL;
518 // write stat updates
520 {
521 for (i = 0;i < MAX_CL_STATS && msg->cursize + 6 + 11 <= maxsize;i++)
522 {
523 if (host_client->statsdeltabits[i>>3] & (1<<(i&7)))
524 {
525 host_client->statsdeltabits[i>>3] &= ~(1<<(i&7));
526 // add packetlog entry now that we have something for it
527 if (!packetlog)
528 {
529 packetlog = d->packetlog + packetlognumber;
530 packetlog->packetnumber = framenum;
531 packetlog->numstates = 0;
532 memset(packetlog->statsdeltabits, 0, sizeof(packetlog->statsdeltabits));
533 }
534 packetlog->statsdeltabits[i>>3] |= (1<<(i&7));
535 if (host_client->stats[i] >= 0 && host_client->stats[i] < 256)
536 {
538 MSG_WriteByte(msg, i);
540 l = 1;
541 }
542 else
543 {
545 MSG_WriteByte(msg, i);
547 l = 1;
548 }
549 }
550 }
551 }
552
553 // only send empty svc_entities frame if needed
554 if(!l && !need_empty)
555 return false;
556
557 // add packetlog entry now that we have something for it
558 if (!packetlog)
559 {
560 packetlog = d->packetlog + packetlognumber;
561 packetlog->packetnumber = framenum;
562 packetlog->numstates = 0;
563 memset(packetlog->statsdeltabits, 0, sizeof(packetlog->statsdeltabits));
564 }
565
566 // write state updates
568 Con_Printf("send: svc_entities %i\n", framenum);
569 d->latestframenum = framenum;
571 MSG_WriteLong(msg, framenum);
573 MSG_WriteLong(msg, movesequence);
574 for (priority = ENTITYFRAME5_PRIORITYLEVELS - 1;priority >= 0 && packetlog->numstates < ENTITYFRAME5_MAXSTATES;priority--)
575 {
576 for (i = 0;i < d->prioritychaincounts[priority] && packetlog->numstates < ENTITYFRAME5_MAXSTATES;i++)
577 {
578 num = d->prioritychains[priority][i];
579 n = d->states + num;
580 if (d->deltabits[num] & E5_FULLUPDATE)
582 buf.cursize = 0;
583 EntityState5_WriteUpdate(num, n, d->deltabits[num], &buf);
584 // if the entity won't fit, try the next one
585 if (msg->cursize + buf.cursize + 2 > maxsize)
586 continue;
587 // write entity to the packet
588 SZ_Write(msg, buf.data, buf.cursize);
589 // mark age on entity for prioritization
590 d->updateframenum[num] = framenum;
591 // log entity so deltabits can be restored later if lost
592 packetlog->states[packetlog->numstates].number = num;
593 packetlog->states[packetlog->numstates].bits = d->deltabits[num];
594 packetlog->numstates++;
595 // clear deltabits and priority so it won't be sent again
596 d->deltabits[num] = 0;
597 d->priorities[num] = 0;
598 }
599 }
600 MSG_WriteShort(msg, 0x8000);
601
602 return true;
603}
cvar_t developer_networkentities
Definition cl_parse.c:173
void MSG_WriteShort(sizebuf_t *sb, int c)
Definition com_msg.c:138
void MSG_WriteLong(sizebuf_t *sb, int c)
Definition com_msg.c:147
void MSG_WriteByte(sizebuf_t *sb, int c)
Definition com_msg.c:130
void SZ_Write(sizebuf_t *buf, const unsigned char *data, int length)
Definition common.c:72
@ PROTOCOL_DARKPLACES2
various changes
Definition common.h:140
@ PROTOCOL_DARKPLACES4
various changes
Definition common.h:138
@ PROTOCOL_NEHAHRABJP2
same as NEHAHRABJP but with 16bit soundindex
Definition common.h:147
@ PROTOCOL_DARKPLACES3
uses EntityFrame4 entity snapshot encoder/decoder which is broken, this attempted to do partial snaps...
Definition common.h:139
@ PROTOCOL_NEHAHRABJP
same as QUAKEDP but with 16bit modelindex
Definition common.h:146
@ PROTOCOL_DARKPLACES5
uses EntityFrame5 entity snapshot encoder/decoder which is based on a Tribes networking article at ht...
Definition common.h:137
@ PROTOCOL_QUAKEDP
darkplaces extended quake protocol (used by TomazQuake and others), backwards compatible as long as n...
Definition common.h:142
@ PROTOCOL_DARKPLACES6
various changes
Definition common.h:136
@ PROTOCOL_QUAKE
quake (aka netquake/normalquake/nq) protocol
Definition common.h:144
@ PROTOCOL_NEHAHRABJP3
same as NEHAHRABJP2 but with some changes
Definition common.h:148
@ PROTOCOL_NEHAHRAMOVIE
Nehahra movie protocol, a big nasty hack dating back to early days of the Quake Standards Group (but ...
Definition common.h:143
@ PROTOCOL_DARKPLACES1
uses EntityFrame entity snapshot encoder/decoder which is a QuakeWorld-like entity snapshot delta com...
Definition common.h:141
void Con_DPrintf(const char *fmt,...)
A Con_Printf that only shows up if the "developer" cvar is set.
Definition console.c:1544
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
#define n(x, y)
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition glquake.h:657
#define CLEARPVSBIT(pvs, b)
#define CHECKPVSBIT(pvs, b)
#define SETPVSBIT(pvs, b)
#define SVVM_prog
Definition progsvm.h:766
#define svc_entities
Definition protocol.h:277
#define svc_updatestatubyte
Definition protocol.h:270
#define svc_updatestat
Definition protocol.h:217
#define ENTITYFRAME5_MAXSTATES
Definition protocol.h:827
#define ENTITYFRAME5_PRIORITYLEVELS
Definition protocol.h:828
#define NULL
Definition qtypes.h:12
server_t sv
local server
Definition sv_main.c:223
int stats[MAX_CL_STATS]
Definition server.h:278
int integer
Definition cvar.h:73
unsigned short number
Definition protocol.h:448
int prioritychaincounts[ENTITYFRAME5_PRIORITYLEVELS]
Definition protocol.h:888
unsigned short prioritychains[ENTITYFRAME5_PRIORITYLEVELS][ENTITYFRAME5_MAXSTATES]
Definition protocol.h:889
int max_edicts
number of edicts for which space has been (should be) allocated
Definition progsvm.h:673
protocolversion_t protocol
one of the PROTOCOL_ values
Definition server.h:74
int cursize
Definition common.h:54
static int EntityState5_DeltaBits(const entity_state_t *o, const entity_state_t *n)
Definition sv_ents5.c:112
static int EntityState5_Priority(entityframe5_database_t *d, int stateindex)
Definition sv_ents5.c:69
static void EntityFrame5_ExpandEdicts(entityframe5_database_t *d, int newmax)
Definition sv_ents5.c:38
void EntityState5_WriteUpdate(int number, const entity_state_t *s, int changedbits, sizebuf_t *msg)
Definition sv_ents5.c:178
void EntityFrame5_LostFrame(entityframe5_database_t *d, int framenum)
Definition sv_ents5.c:623

References entityframe5_changestate_t::bits, buf, CHECKPVSBIT, CLEARPVSBIT, Con_DPrintf(), Con_Printf(), sizebuf_t::cursize, data, defaultstate, entityframe5_database_t::deltabits, developer_networkentities, E5_FULLUPDATE, EntityFrame5_ExpandEdicts(), EntityFrame5_LostFrame(), ENTITYFRAME5_MAXPACKETLOGS, ENTITYFRAME5_MAXSTATES, ENTITYFRAME5_PRIORITYLEVELS, EntityState5_DeltaBits(), EntityState5_Priority(), EntityState5_WriteUpdate(), host_client, i, cvar_t::integer, entityframe5_database_t::latestframenum, max, MAX_CL_STATS, prvm_prog_t::max_edicts, entityframe5_database_t::maxedicts, MSG_WriteByte(), MSG_WriteLong(), MSG_WriteShort(), n, NULL, entity_state_t::number, entityframe5_changestate_t::number, entityframe5_packetlog_t::numstates, entityframe5_database_t::packetlog, entityframe5_packetlog_t::packetnumber, entityframe5_database_t::priorities, entityframe5_database_t::prioritychaincounts, entityframe5_database_t::prioritychains, server_t::protocol, PROTOCOL_DARKPLACES1, PROTOCOL_DARKPLACES2, PROTOCOL_DARKPLACES3, PROTOCOL_DARKPLACES4, PROTOCOL_DARKPLACES5, PROTOCOL_DARKPLACES6, PROTOCOL_NEHAHRABJP, PROTOCOL_NEHAHRABJP2, PROTOCOL_NEHAHRABJP3, PROTOCOL_NEHAHRAMOVIE, PROTOCOL_QUAKE, PROTOCOL_QUAKEDP, SETPVSBIT, entityframe5_database_t::states, entityframe5_packetlog_t::states, client_t::stats, client_t::statsdeltabits, entityframe5_packetlog_t::statsdeltabits, sv, svc_entities, svc_updatestat, svc_updatestatubyte, SVVM_prog, SZ_Write(), entityframe5_database_t::updateframenum, entityframe5_database_t::viewentnum, and entityframe5_database_t::visiblebits.

◆ EntityState5_DeltaBits()

static int EntityState5_DeltaBits ( const entity_state_t * o,
const entity_state_t * n )
static

Definition at line 112 of file sv_ents5.c.

113{
114 unsigned int bits = 0;
115 if (n->active == ACTIVE_NETWORK)
116 {
117 if (o->active != ACTIVE_NETWORK)
118 bits |= E5_FULLUPDATE;
119 if (!VectorCompare(o->origin, n->origin))
120 bits |= E5_ORIGIN;
121 if (!VectorCompare(o->angles, n->angles))
122 bits |= E5_ANGLES;
123 if (o->modelindex != n->modelindex)
124 bits |= E5_MODEL;
125 if (o->frame != n->frame)
126 bits |= E5_FRAME;
127 if (o->skin != n->skin)
128 bits |= E5_SKIN;
129 if (o->effects != n->effects)
130 bits |= E5_EFFECTS;
131 if (o->flags != n->flags)
132 bits |= E5_FLAGS;
133 if (o->alpha != n->alpha)
134 bits |= E5_ALPHA;
135 if (o->scale != n->scale)
136 bits |= E5_SCALE;
137 if (o->colormap != n->colormap)
138 bits |= E5_COLORMAP;
139 if (o->tagentity != n->tagentity || o->tagindex != n->tagindex)
140 bits |= E5_ATTACHMENT;
141 if (o->light[0] != n->light[0] || o->light[1] != n->light[1] || o->light[2] != n->light[2] || o->light[3] != n->light[3] || o->lightstyle != n->lightstyle || o->lightpflags != n->lightpflags)
142 bits |= E5_LIGHT;
143 if (o->glowsize != n->glowsize || o->glowcolor != n->glowcolor)
144 bits |= E5_GLOW;
145 if (o->colormod[0] != n->colormod[0] || o->colormod[1] != n->colormod[1] || o->colormod[2] != n->colormod[2])
146 bits |= E5_COLORMOD;
147 if (o->glowmod[0] != n->glowmod[0] || o->glowmod[1] != n->glowmod[1] || o->glowmod[2] != n->glowmod[2])
148 bits |= E5_GLOWMOD;
149 if (n->flags & RENDER_COMPLEXANIMATION)
150 {
151 if ((o->skeletonobject.model && o->skeletonobject.relativetransforms) != (n->skeletonobject.model && n->skeletonobject.relativetransforms))
152 {
153 bits |= E5_COMPLEXANIMATION;
154 }
156 {
157 if(o->modelindex != n->modelindex)
158 bits |= E5_COMPLEXANIMATION;
159 else if(o->skeletonobject.model->num_bones != n->skeletonobject.model->num_bones)
160 bits |= E5_COMPLEXANIMATION;
161 else if(memcmp(o->skeletonobject.relativetransforms, n->skeletonobject.relativetransforms, o->skeletonobject.model->num_bones * sizeof(*o->skeletonobject.relativetransforms)))
162 bits |= E5_COMPLEXANIMATION;
163 }
164 else if (memcmp(o->framegroupblend, n->framegroupblend, sizeof(o->framegroupblend)))
165 {
166 bits |= E5_COMPLEXANIMATION;
167 }
168 }
169 if (o->traileffectnum != n->traileffectnum)
170 bits |= E5_TRAILEFFECTNUM;
171 }
172 else
173 if (o->active == ACTIVE_NETWORK)
174 bits |= E5_FULLUPDATE;
175 return bits;
176}
#define VectorCompare(a, b)
Definition mathlib.h:113
#define E5_FLAGS
byte = s->renderflags
Definition protocol.h:766
#define E5_EFFECTS
E5_EFFECTS16=0 && E5_EFFECTS32=0: byte = s->effects E5_EFFECTS16=1 && E5_EFFECTS32=0: short = s->effe...
Definition protocol.h:761
#define E5_ORIGIN
E5_ORIGIN32=0: short[3] = s->origin[0] * 8, s->origin[1] * 8, s->origin[2] * 8 E5_ORIGIN32=1: float[3...
Definition protocol.h:745
#define E5_COLORMOD
byte[3] = s->colormod[0], s->colormod[1], s->colormod[2]
Definition protocol.h:799
#define RENDER_COMPLEXANIMATION
Definition protocol.h:363
#define E5_ANGLES
E5_ANGLES16=0: byte[3] = s->angle[0] * 256 / 360, s->angle[1] * 256 / 360, s->angle[2] * 256 / 360 E5...
Definition protocol.h:748
#define E5_SCALE
byte = bound(0, s->scale * 16, 255)
Definition protocol.h:770
#define E5_FRAME
E5_FRAME16=0: byte = s->frame E5_FRAME16=1: short = s->frame.
Definition protocol.h:754
#define E5_ALPHA
byte = bound(0, s->alpha * 255, 255)
Definition protocol.h:768
#define E5_LIGHT
short[4] = s->light[0], s->light[1], s->light[2], s->light[3] byte = s->lightstyle byte = s->lightpfl...
Definition protocol.h:788
#define E5_TRAILEFFECTNUM
ushort traileffectnum
Definition protocol.h:813
#define E5_GLOWMOD
byte[3] = s->glowmod[0], s->glowmod[1], s->glowmod[2]
Definition protocol.h:804
#define E5_SKIN
byte = s->skin
Definition protocol.h:756
@ ACTIVE_NETWORK
Definition protocol.h:433
#define E5_COMPLEXANIMATION
byte type=0 short frames[1] short times[1] byte type=1 short frames[2] short times[2] byte lerps[2] b...
Definition protocol.h:811
#define E5_GLOW
byte = s->glowsize byte = s->glowcolor
Definition protocol.h:791
unsigned char glowmod[3]
Definition protocol.h:472
framegroupblend_t framegroupblend[4]
Definition protocol.h:474
unsigned char flags
Definition protocol.h:468
unsigned char skin
Definition protocol.h:463
unsigned char glowcolor
Definition protocol.h:467
unsigned char glowsize
Definition protocol.h:466
float origin[3]
Definition protocol.h:444
unsigned short tagentity
Definition protocol.h:451
unsigned char lightstyle
Definition protocol.h:460
unsigned char colormap
Definition protocol.h:462
unsigned short modelindex
Definition protocol.h:449
unsigned char colormod[3]
Definition protocol.h:471
unsigned short traileffectnum
Definition protocol.h:457
skeleton_t skeletonobject
Definition protocol.h:475
unsigned char alpha
Definition protocol.h:464
unsigned short light[4]
Definition protocol.h:458
unsigned char tagindex
Definition protocol.h:470
float angles[3]
Definition protocol.h:445
unsigned char active
Definition protocol.h:459
unsigned short frame
Definition protocol.h:450
unsigned char scale
Definition protocol.h:465
unsigned char lightpflags
Definition protocol.h:461
const struct model_s * model
Definition protocol.h:425
struct matrix4x4_s * relativetransforms
Definition protocol.h:426

References entity_state_t::active, ACTIVE_NETWORK, entity_state_t::alpha, entity_state_t::angles, entity_state_t::colormap, entity_state_t::colormod, E5_ALPHA, E5_ANGLES, E5_ATTACHMENT, E5_COLORMAP, E5_COLORMOD, E5_COMPLEXANIMATION, E5_EFFECTS, E5_FLAGS, E5_FRAME, E5_FULLUPDATE, E5_GLOW, E5_GLOWMOD, E5_LIGHT, E5_MODEL, E5_ORIGIN, E5_SCALE, E5_SKIN, E5_TRAILEFFECTNUM, entity_state_t::effects, entity_state_t::flags, entity_state_t::frame, entity_state_t::framegroupblend, entity_state_t::glowcolor, entity_state_t::glowmod, entity_state_t::glowsize, entity_state_t::light, entity_state_t::lightpflags, entity_state_t::lightstyle, skeleton_t::model, entity_state_t::modelindex, n, entity_state_t::origin, skeleton_t::relativetransforms, RENDER_COMPLEXANIMATION, entity_state_t::scale, entity_state_t::skeletonobject, entity_state_t::skin, entity_state_t::tagentity, entity_state_t::tagindex, entity_state_t::traileffectnum, and VectorCompare.

Referenced by EntityFrame5_WriteFrame().

◆ EntityState5_Priority()

static int EntityState5_Priority ( entityframe5_database_t * d,
int stateindex )
static

Definition at line 69 of file sv_ents5.c.

70{
71 int limit, priority;
72 entity_state_t *s = NULL; // hush compiler warning by initializing this
73 // if it is the player, update urgently
74 if (stateindex == d->viewentnum)
76 // priority increases each frame no matter what happens
77 priority = d->priorities[stateindex] + 1;
78 // players get an extra priority boost
79 if (stateindex <= svs.maxclients)
80 priority++;
81 // remove dead entities very quickly because they are just 2 bytes
82 if (d->states[stateindex].active != ACTIVE_NETWORK)
83 {
84 priority++;
85 return bound(1, priority, ENTITYFRAME5_PRIORITYLEVELS - 1);
86 }
87 // certain changes are more noticable than others
89 priority++;
90 // find the root entity this one is attached to, and judge relevance by it
91 for (limit = 0;limit < 256;limit++)
92 {
93 s = d->states + stateindex;
94 if (s->flags & RENDER_VIEWMODEL)
95 stateindex = d->viewentnum;
96 else if (s->tagentity)
97 stateindex = s->tagentity;
98 else
99 break;
100 if (d->maxedicts < stateindex)
101 EntityFrame5_ExpandEdicts(d, (stateindex+256)&~255);
102 }
103 if (limit >= 256)
104 Con_DPrintf("Protocol: Runaway loop recursing tagentity links on entity %i\n", stateindex);
105 // now that we have the parent entity we can make some decisions based on
106 // distance from the player
107 if (VectorDistance(d->states[d->viewentnum].netcenter, s->netcenter) < 1024.0f)
108 priority++;
109 return bound(1, priority, ENTITYFRAME5_PRIORITYLEVELS - 1);
110}
#define bound(min, num, max)
Definition mathlib.h:34
#define VectorDistance(a, b)
Definition mathlib.h:108
#define RENDER_VIEWMODEL
Definition protocol.h:358
server_static_t svs
persistant server info
Definition sv_main.c:224
float netcenter[3]
Definition protocol.h:443
int maxclients
number of svs.clients slots (updated by maxplayers command)
Definition server.h:28

References entity_state_t::active, ACTIVE_NETWORK, bound, Con_DPrintf(), entityframe5_database_t::deltabits, E5_ATTACHMENT, E5_COLORMAP, E5_FLAGS, E5_FULLUPDATE, E5_MODEL, EntityFrame5_ExpandEdicts(), ENTITYFRAME5_PRIORITYLEVELS, entity_state_t::flags, server_static_t::maxclients, entityframe5_database_t::maxedicts, entity_state_t::netcenter, NULL, entityframe5_database_t::priorities, RENDER_VIEWMODEL, entityframe5_database_t::states, svs, entity_state_t::tagentity, VectorDistance, and entityframe5_database_t::viewentnum.

Referenced by EntityFrame5_WriteFrame().

◆ EntityState5_WriteUpdate()

void EntityState5_WriteUpdate ( int number,
const entity_state_t * s,
int changedbits,
sizebuf_t * msg )

Definition at line 178 of file sv_ents5.c.

179{
180 prvm_prog_t *prog = SVVM_prog;
181 unsigned int bits = 0;
182 //model_t *model;
183
184 if (s->active != ACTIVE_NETWORK)
185 {
187 MSG_WriteShort(msg, number | 0x8000);
189 }
190 else
191 {
192 if (PRVM_serveredictfunction((&prog->edicts[s->number]), SendEntity))
193 return;
194
195 bits = changedbits;
196 if ((bits & E5_ORIGIN) && (!(s->flags & RENDER_LOWPRECISION) || s->exteriormodelforclient || s->tagentity || s->viewmodelforclient || (s->number >= 1 && s->number <= svs.maxclients) || s->origin[0] <= -4096.0625 || s->origin[0] >= 4095.9375 || s->origin[1] <= -4096.0625 || s->origin[1] >= 4095.9375 || s->origin[2] <= -4096.0625 || s->origin[2] >= 4095.9375))
197 // maybe also add: ((model = SV_GetModelByIndex(s->modelindex)) != NULL && model->name[0] == '*')
198 bits |= E5_ORIGIN32;
199 // possible values:
200 // negative origin:
201 // (int)(f * 8 - 0.5) >= -32768
202 // (f * 8 - 0.5) > -32769
203 // f > -4096.0625
204 // positive origin:
205 // (int)(f * 8 + 0.5) <= 32767
206 // (f * 8 + 0.5) < 32768
207 // f * 8 + 0.5) < 4095.9375
208 if ((bits & E5_ANGLES) && !(s->flags & RENDER_LOWPRECISION))
209 bits |= E5_ANGLES16;
210 if ((bits & E5_MODEL) && s->modelindex >= 256)
211 bits |= E5_MODEL16;
212 if ((bits & E5_FRAME) && s->frame >= 256)
213 bits |= E5_FRAME16;
214 if (bits & E5_EFFECTS)
215 {
216 if (s->effects & 0xFFFF0000)
217 bits |= E5_EFFECTS32;
218 else if (s->effects & 0xFFFFFF00)
219 bits |= E5_EFFECTS16;
220 }
221 if (bits >= 256)
222 bits |= E5_EXTEND1;
223 if (bits >= 65536)
224 bits |= E5_EXTEND2;
225 if (bits >= 16777216)
226 bits |= E5_EXTEND3;
227 {
228 ENTITYSIZEPROFILING_START(msg, s->number, bits);
229 MSG_WriteShort(msg, number);
230 MSG_WriteByte(msg, bits & 0xFF);
231 if (bits & E5_EXTEND1)
232 MSG_WriteByte(msg, (bits >> 8) & 0xFF);
233 if (bits & E5_EXTEND2)
234 MSG_WriteByte(msg, (bits >> 16) & 0xFF);
235 if (bits & E5_EXTEND3)
236 MSG_WriteByte(msg, (bits >> 24) & 0xFF);
237 if (bits & E5_FLAGS)
238 MSG_WriteByte(msg, s->flags);
239 if (bits & E5_ORIGIN)
240 {
241 if (bits & E5_ORIGIN32)
242 {
243 MSG_WriteCoord32f(msg, s->origin[0]);
244 MSG_WriteCoord32f(msg, s->origin[1]);
245 MSG_WriteCoord32f(msg, s->origin[2]);
246 }
247 else
248 {
249 MSG_WriteCoord13i(msg, s->origin[0]);
250 MSG_WriteCoord13i(msg, s->origin[1]);
251 MSG_WriteCoord13i(msg, s->origin[2]);
252 }
253 }
254 if (bits & E5_ANGLES)
255 {
256 if (bits & E5_ANGLES16)
257 {
258 MSG_WriteAngle16i(msg, s->angles[0]);
259 MSG_WriteAngle16i(msg, s->angles[1]);
260 MSG_WriteAngle16i(msg, s->angles[2]);
261 }
262 else
263 {
264 MSG_WriteAngle8i(msg, s->angles[0]);
265 MSG_WriteAngle8i(msg, s->angles[1]);
266 MSG_WriteAngle8i(msg, s->angles[2]);
267 }
268 }
269 if (bits & E5_MODEL)
270 {
271 if (bits & E5_MODEL16)
272 MSG_WriteShort(msg, s->modelindex);
273 else
274 MSG_WriteByte(msg, s->modelindex);
275 }
276 if (bits & E5_FRAME)
277 {
278 if (bits & E5_FRAME16)
279 MSG_WriteShort(msg, s->frame);
280 else
281 MSG_WriteByte(msg, s->frame);
282 }
283 if (bits & E5_SKIN)
284 MSG_WriteByte(msg, s->skin);
285 if (bits & E5_EFFECTS)
286 {
287 if (bits & E5_EFFECTS32)
288 MSG_WriteLong(msg, s->effects);
289 else if (bits & E5_EFFECTS16)
290 MSG_WriteShort(msg, s->effects);
291 else
292 MSG_WriteByte(msg, s->effects);
293 }
294 if (bits & E5_ALPHA)
295 MSG_WriteByte(msg, s->alpha);
296 if (bits & E5_SCALE)
297 MSG_WriteByte(msg, s->scale);
298 if (bits & E5_COLORMAP)
299 MSG_WriteByte(msg, s->colormap);
300 if (bits & E5_ATTACHMENT)
301 {
302 MSG_WriteShort(msg, s->tagentity);
303 MSG_WriteByte(msg, s->tagindex);
304 }
305 if (bits & E5_LIGHT)
306 {
307 MSG_WriteShort(msg, s->light[0]);
308 MSG_WriteShort(msg, s->light[1]);
309 MSG_WriteShort(msg, s->light[2]);
310 MSG_WriteShort(msg, s->light[3]);
311 MSG_WriteByte(msg, s->lightstyle);
312 MSG_WriteByte(msg, s->lightpflags);
313 }
314 if (bits & E5_GLOW)
315 {
316 MSG_WriteByte(msg, s->glowsize);
317 MSG_WriteByte(msg, s->glowcolor);
318 }
319 if (bits & E5_COLORMOD)
320 {
321 MSG_WriteByte(msg, s->colormod[0]);
322 MSG_WriteByte(msg, s->colormod[1]);
323 MSG_WriteByte(msg, s->colormod[2]);
324 }
325 if (bits & E5_GLOWMOD)
326 {
327 MSG_WriteByte(msg, s->glowmod[0]);
328 MSG_WriteByte(msg, s->glowmod[1]);
329 MSG_WriteByte(msg, s->glowmod[2]);
330 }
331 if (bits & E5_COMPLEXANIMATION)
332 {
334 {
335 int numbones = s->skeletonobject.model->num_bones;
336 int bonenum;
337 short pose7s[7];
338 MSG_WriteByte(msg, 4);
339 MSG_WriteShort(msg, s->modelindex);
340 MSG_WriteByte(msg, numbones);
341 for (bonenum = 0;bonenum < numbones;bonenum++)
342 {
344 MSG_WriteShort(msg, pose7s[0]);
345 MSG_WriteShort(msg, pose7s[1]);
346 MSG_WriteShort(msg, pose7s[2]);
347 MSG_WriteShort(msg, pose7s[3]);
348 MSG_WriteShort(msg, pose7s[4]);
349 MSG_WriteShort(msg, pose7s[5]);
350 MSG_WriteShort(msg, pose7s[6]);
351 }
352 }
353 else
354 {
356 if (s->framegroupblend[3].lerp > 0)
357 {
358 MSG_WriteByte(msg, 3);
367 MSG_WriteByte(msg, s->framegroupblend[0].lerp * 255.0f);
368 MSG_WriteByte(msg, s->framegroupblend[1].lerp * 255.0f);
369 MSG_WriteByte(msg, s->framegroupblend[2].lerp * 255.0f);
370 MSG_WriteByte(msg, s->framegroupblend[3].lerp * 255.0f);
371 }
372 else if (s->framegroupblend[2].lerp > 0)
373 {
374 MSG_WriteByte(msg, 2);
381 MSG_WriteByte(msg, s->framegroupblend[0].lerp * 255.0f);
382 MSG_WriteByte(msg, s->framegroupblend[1].lerp * 255.0f);
383 MSG_WriteByte(msg, s->framegroupblend[2].lerp * 255.0f);
384 }
385 else if (s->framegroupblend[1].lerp > 0)
386 {
387 MSG_WriteByte(msg, 1);
392 MSG_WriteByte(msg, s->framegroupblend[0].lerp * 255.0f);
393 MSG_WriteByte(msg, s->framegroupblend[1].lerp * 255.0f);
394 }
395 else
396 {
397 MSG_WriteByte(msg, 0);
400 }
401 }
402 }
403 if (bits & E5_TRAILEFFECTNUM)
405 ENTITYSIZEPROFILING_END(msg, s->number, bits);
406 }
407 }
408}
void MSG_WriteCoord32f(sizebuf_t *sb, float f)
Definition com_msg.c:197
void MSG_WriteAngle16i(sizebuf_t *sb, float f)
Definition com_msg.c:227
void MSG_WriteCoord13i(sizebuf_t *sb, float f)
Definition com_msg.c:187
void MSG_WriteAngle8i(sizebuf_t *sb, float f)
Definition com_msg.c:222
void Matrix4x4_ToBonePose7s(const matrix4x4_t *m, float origininvscale, short *pose7s)
Definition matrixlib.c:1614
#define PRVM_serveredictfunction(ed, fieldname)
Definition progsvm.h:176
#define E5_EXTEND1
bits >= (1<<8)
Definition protocol.h:763
#define E5_EFFECTS16
short = s->effects
Definition protocol.h:793
#define ENTITYSIZEPROFILING_START(msg, num, flags)
Definition protocol.h:39
#define E5_MODEL16
flag
Definition protocol.h:776
#define E5_EFFECTS32
int = s->effects
Definition protocol.h:795
#define E5_FRAME16
flag
Definition protocol.h:797
#define E5_ORIGIN32
flag
Definition protocol.h:772
#define E5_ANGLES16
flag
Definition protocol.h:774
#define ENTITYSIZEPROFILING_END(msg, num, flags)
Definition protocol.h:42
#define RENDER_LOWPRECISION
Definition protocol.h:360
#define E5_EXTEND2
bits >= (1<<16)
Definition protocol.h:780
#define E5_EXTEND3
bits >= (1<<24)
Definition protocol.h:801
model_t * SV_GetModelByIndex(int modelindex)
Definition sv_main.c:1607
unsigned short viewmodelforclient
Definition protocol.h:453
unsigned short exteriormodelforclient
Definition protocol.h:454
prvm_edict_t * edicts
Definition progsvm.h:680
double time
Definition server.h:76
static double anim_frameduration(model_t *model, int framenum)
Definition sv_ents5.c:20
static double anim_reducetime(double t, double frameduration, double maxtime)
Definition sv_ents5.c:4

References entity_state_t::active, ACTIVE_NETWORK, entity_state_t::alpha, entity_state_t::angles, anim_frameduration(), anim_reducetime(), entity_state_t::colormap, entity_state_t::colormod, E5_ALPHA, E5_ANGLES, E5_ANGLES16, E5_ATTACHMENT, E5_COLORMAP, E5_COLORMOD, E5_COMPLEXANIMATION, E5_EFFECTS, E5_EFFECTS16, E5_EFFECTS32, E5_EXTEND1, E5_EXTEND2, E5_EXTEND3, E5_FLAGS, E5_FRAME, E5_FRAME16, E5_GLOW, E5_GLOWMOD, E5_LIGHT, E5_MODEL, E5_MODEL16, E5_ORIGIN, E5_ORIGIN32, E5_SCALE, E5_SKIN, E5_TRAILEFFECTNUM, prvm_prog_t::edicts, entity_state_t::effects, ENTITYSIZEPROFILING_END, ENTITYSIZEPROFILING_START, entity_state_t::exteriormodelforclient, entity_state_t::flags, entity_state_t::frame, framegroupblend_t::frame, entity_state_t::framegroupblend, entity_state_t::glowcolor, entity_state_t::glowmod, entity_state_t::glowsize, framegroupblend_t::lerp, entity_state_t::light, entity_state_t::lightpflags, entity_state_t::lightstyle, Matrix4x4_ToBonePose7s(), server_static_t::maxclients, model, skeleton_t::model, entity_state_t::modelindex, MSG_WriteAngle16i(), MSG_WriteAngle8i(), MSG_WriteByte(), MSG_WriteCoord13i(), MSG_WriteCoord32f(), MSG_WriteLong(), MSG_WriteShort(), entity_state_t::number, entity_state_t::origin, PRVM_serveredictfunction, skeleton_t::relativetransforms, RENDER_LOWPRECISION, entity_state_t::scale, entity_state_t::skeletonobject, entity_state_t::skin, framegroupblend_t::start, sv, SV_GetModelByIndex(), svs, SVVM_prog, entity_state_t::tagentity, entity_state_t::tagindex, server_t::time, entity_state_t::traileffectnum, and entity_state_t::viewmodelforclient.

Referenced by EntityFrame5_WriteFrame().

◆ packetlog5cmp()

static int packetlog5cmp ( const void * a_,
const void * b_ )
static

Definition at line 616 of file sv_ents5.c.

617{
620 return a->packetnumber - b->packetnumber;
621}
dp_FragColor b
ret a

References a, b, and entityframe5_packetlog_t::packetnumber.

Referenced by EntityFrame5_LostFrame().