Annotation of quake2/server/sv_ents.c, revision 1.1.1.1

1.1       root        1: 
                      2: #include "server.h"
                      3: 
                      4: /*
                      5: =============================================================================
                      6: 
                      7: Encode a client frame onto the network channel
                      8: 
                      9: =============================================================================
                     10: */
                     11: 
                     12: 
                     13: /*
                     14: =============
                     15: SV_EmitPacketEntities
                     16: 
                     17: Writes a delta update of an entity_state_t list to the message.
                     18: =============
                     19: */
                     20: void SV_EmitPacketEntities (client_frame_t *from, client_frame_t *to, sizebuf_t *msg)
                     21: {
                     22:        entity_state_t  *oldent, *newent;
                     23:        int             oldindex, newindex;
                     24:        int             oldnum, newnum;
                     25:        int             from_num_entities;
                     26:        int             bits;
                     27: 
                     28:        MSG_WriteByte (msg, svc_packetentities);
                     29: 
                     30:        if (!from)
                     31:                from_num_entities = 0;
                     32:        else
                     33:                from_num_entities = from->num_entities;
                     34: 
                     35:        newindex = 0;
                     36:        oldindex = 0;
                     37:        while (newindex < to->num_entities || oldindex < from_num_entities)
                     38:        {
                     39:                if (newindex >= to->num_entities)
                     40:                        newnum = 9999;
                     41:                else
                     42:                {
                     43:                        newent = &svs.client_entities[(to->first_entity+newindex)%svs.num_client_entities];
                     44:                        newnum = newent->number;
                     45:                }
                     46: 
                     47:                if (oldindex >= from_num_entities)
                     48:                        oldnum = 9999;
                     49:                else
                     50:                {
                     51:                        oldent = &svs.client_entities[(from->first_entity+oldindex)%svs.num_client_entities];
                     52:                        oldnum = oldent->number;
                     53:                }
                     54: 
                     55:                if (newnum == oldnum)
                     56:                {       // delta update from old position
                     57:                        // because the force parm is false, this will not result
                     58:                        // in any bytes being emited if the entity has not changed at all
                     59:                        MSG_WriteDeltaEntity (oldent, newent, msg, false);
                     60:                        oldindex++;
                     61:                        newindex++;
                     62:                        continue;
                     63:                }
                     64: 
                     65:                if (newnum < oldnum)
                     66:                {       // this is a new entity, send it from the baseline
                     67:                        MSG_WriteDeltaEntity (&sv.baselines[newnum], newent, msg, true);
                     68:                        newindex++;
                     69:                        continue;
                     70:                }
                     71: 
                     72:                if (newnum > oldnum)
                     73:                {       // the old entity isn't present in the new message
                     74:                        bits = U_REMOVE;
                     75:                        if (oldnum >= 256)
                     76:                                bits |= U_NUMBER16 | U_MOREBITS1;
                     77: 
                     78:                        MSG_WriteByte (msg,     bits&255 );
                     79:                        if (bits & 0x0000ff00)
                     80:                                MSG_WriteByte (msg,     (bits>>8)&255 );
                     81: 
                     82:                        if (bits & U_NUMBER16)
                     83:                                MSG_WriteShort (msg, oldnum);
                     84:                        else
                     85:                                MSG_WriteByte (msg, oldnum);
                     86: 
                     87:                        oldindex++;
                     88:                        continue;
                     89:                }
                     90:        }
                     91: 
                     92:        MSG_WriteShort (msg, 0);        // end of packetentities
                     93: }
                     94: 
                     95: 
                     96: 
                     97: /*
                     98: =============
                     99: SV_WritePlayerstateToClient
                    100: 
                    101: =============
                    102: */
                    103: void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, sizebuf_t *msg)
                    104: {
                    105:        int                             i;
                    106:        int                             pflags;
                    107:        player_state_t  *ps, *ops;
                    108:        player_state_t  dummy;
                    109:        int                             statbits;
                    110: 
                    111:        ps = &to->ps;
                    112:        if (!from)
                    113:        {
                    114:                memset (&dummy, 0, sizeof(dummy));
                    115:                ops = &dummy;
                    116:        }
                    117:        else
                    118:                ops = &from->ps;
                    119: 
                    120:        //
                    121:        // determine what needs to be sent
                    122:        //
                    123:        pflags = 0;
                    124: 
                    125:        if (ps->pmove.pm_type != ops->pmove.pm_type)
                    126:                pflags |= PS_M_TYPE;
                    127: 
                    128:        if (ps->pmove.origin[0] != ops->pmove.origin[0]
                    129:                || ps->pmove.origin[1] != ops->pmove.origin[1]
                    130:                || ps->pmove.origin[2] != ops->pmove.origin[2] )
                    131:                pflags |= PS_M_ORIGIN;
                    132: 
                    133:        if (ps->pmove.velocity[0] != ops->pmove.velocity[0]
                    134:                || ps->pmove.velocity[1] != ops->pmove.velocity[1]
                    135:                || ps->pmove.velocity[2] != ops->pmove.velocity[2] )
                    136:                pflags |= PS_M_VELOCITY;
                    137: 
                    138:        if (ps->pmove.pm_time != ops->pmove.pm_time)
                    139:                pflags |= PS_M_TIME;
                    140: 
                    141:        if (ps->pmove.pm_flags != ops->pmove.pm_flags)
                    142:                pflags |= PS_M_FLAGS;
                    143: 
                    144:        if (ps->pmove.gravity != ops->pmove.gravity)
                    145:                pflags |= PS_M_GRAVITY;
                    146: 
                    147:        if (ps->pmove.delta_angles[0] != ops->pmove.delta_angles[0]
                    148:                || ps->pmove.delta_angles[1] != ops->pmove.delta_angles[1]
                    149:                || ps->pmove.delta_angles[2] != ops->pmove.delta_angles[2] )
                    150:                pflags |= PS_M_DELTA_ANGLES;
                    151: 
                    152: 
                    153:        if (ps->viewoffset[0] != ops->viewoffset[0]
                    154:                || ps->viewoffset[1] != ops->viewoffset[1]
                    155:                || ps->viewoffset[2] != ops->viewoffset[2] )
                    156:                pflags |= PS_VIEWOFFSET;
                    157: 
                    158:        if (ps->viewangles[0] != ops->viewangles[0]
                    159:                || ps->viewangles[1] != ops->viewangles[1]
                    160:                || ps->viewangles[2] != ops->viewangles[2] )
                    161:                pflags |= PS_VIEWANGLES;
                    162: 
                    163:        if (ps->kick_angles[0] != ops->kick_angles[0]
                    164:                || ps->kick_angles[1] != ops->kick_angles[1]
                    165:                || ps->kick_angles[2] != ops->kick_angles[2] )
                    166:                pflags |= PS_KICKANGLES;
                    167: 
                    168:        if (ps->blend[0] != ops->blend[0]
                    169:                || ps->blend[1] != ops->blend[1]
                    170:                || ps->blend[2] != ops->blend[2]
                    171:                || ps->blend[3] != ops->blend[3] )
                    172:                pflags |= PS_BLEND;
                    173: 
                    174:        if (ps->fov != ops->fov)
                    175:                pflags |= PS_FOV;
                    176: 
                    177:        if (ps->rdflags != ops->rdflags)
                    178:                pflags |= PS_RDFLAGS;
                    179: 
                    180:        if (ps->gunframe != ops->gunframe)
                    181:                pflags |= PS_WEAPONFRAME;
                    182: 
                    183:        pflags |= PS_WEAPONINDEX;
                    184: 
                    185:        //
                    186:        // write it
                    187:        //
                    188:        MSG_WriteByte (msg, svc_playerinfo);
                    189:        MSG_WriteShort (msg, pflags);
                    190: 
                    191:        //
                    192:        // write the pmove_state_t
                    193:        //
                    194:        if (pflags & PS_M_TYPE)
                    195:                MSG_WriteByte (msg, ps->pmove.pm_type);
                    196: 
                    197:        if (pflags & PS_M_ORIGIN)
                    198:        {
                    199:                MSG_WriteShort (msg, ps->pmove.origin[0]);
                    200:                MSG_WriteShort (msg, ps->pmove.origin[1]);
                    201:                MSG_WriteShort (msg, ps->pmove.origin[2]);
                    202:        }
                    203: 
                    204:        if (pflags & PS_M_VELOCITY)
                    205:        {
                    206:                MSG_WriteShort (msg, ps->pmove.velocity[0]);
                    207:                MSG_WriteShort (msg, ps->pmove.velocity[1]);
                    208:                MSG_WriteShort (msg, ps->pmove.velocity[2]);
                    209:        }
                    210: 
                    211:        if (pflags & PS_M_TIME)
                    212:                MSG_WriteByte (msg, ps->pmove.pm_time);
                    213: 
                    214:        if (pflags & PS_M_FLAGS)
                    215:                MSG_WriteByte (msg, ps->pmove.pm_flags);
                    216: 
                    217:        if (pflags & PS_M_GRAVITY)
                    218:                MSG_WriteShort (msg, ps->pmove.gravity);
                    219: 
                    220:        if (pflags & PS_M_DELTA_ANGLES)
                    221:        {
                    222:                MSG_WriteShort (msg, ps->pmove.delta_angles[0]);
                    223:                MSG_WriteShort (msg, ps->pmove.delta_angles[1]);
                    224:                MSG_WriteShort (msg, ps->pmove.delta_angles[2]);
                    225:        }
                    226: 
                    227:        //
                    228:        // write the rest of the player_state_t
                    229:        //
                    230:        if (pflags & PS_VIEWOFFSET)
                    231:        {
                    232:                MSG_WriteChar (msg, ps->viewoffset[0]*4);
                    233:                MSG_WriteChar (msg, ps->viewoffset[1]*4);
                    234:                MSG_WriteChar (msg, ps->viewoffset[2]*4);
                    235:        }
                    236: 
                    237:        if (pflags & PS_VIEWANGLES)
                    238:        {
                    239:                MSG_WriteAngle16 (msg, ps->viewangles[0]);
                    240:                MSG_WriteAngle16 (msg, ps->viewangles[1]);
                    241:                MSG_WriteAngle16 (msg, ps->viewangles[2]);
                    242:        }
                    243: 
                    244:        if (pflags & PS_KICKANGLES)
                    245:        {
                    246:                MSG_WriteChar (msg, ps->kick_angles[0]*4);
                    247:                MSG_WriteChar (msg, ps->kick_angles[1]*4);
                    248:                MSG_WriteChar (msg, ps->kick_angles[2]*4);
                    249:        }
                    250: 
                    251:        if (pflags & PS_WEAPONINDEX)
                    252:        {
                    253:                MSG_WriteByte (msg, ps->gunindex);
                    254:        }
                    255: 
                    256:        if (pflags & PS_WEAPONFRAME)
                    257:        {
                    258:                MSG_WriteByte (msg, ps->gunframe);
                    259:                MSG_WriteChar (msg, ps->gunoffset[0]*4);
                    260:                MSG_WriteChar (msg, ps->gunoffset[1]*4);
                    261:                MSG_WriteChar (msg, ps->gunoffset[2]*4);
                    262:                MSG_WriteChar (msg, ps->gunangles[0]*4);
                    263:                MSG_WriteChar (msg, ps->gunangles[1]*4);
                    264:                MSG_WriteChar (msg, ps->gunangles[2]*4);
                    265:        }
                    266: 
                    267:        if (pflags & PS_BLEND)
                    268:        {
                    269:                MSG_WriteByte (msg, ps->blend[0]*255);
                    270:                MSG_WriteByte (msg, ps->blend[1]*255);
                    271:                MSG_WriteByte (msg, ps->blend[2]*255);
                    272:                MSG_WriteByte (msg, ps->blend[3]*255);
                    273:        }
                    274:        if (pflags & PS_FOV)
                    275:                MSG_WriteByte (msg, ps->fov);
                    276:        if (pflags & PS_RDFLAGS)
                    277:                MSG_WriteByte (msg, ps->rdflags);
                    278: 
                    279:        // send stats
                    280:        statbits = 0;
                    281:        for (i=0 ; i<MAX_STATS ; i++)
                    282:                if (ps->stats[i] != ops->stats[i])
                    283:                        statbits |= 1<<i;
                    284:        MSG_WriteLong (msg, statbits);
                    285:        for (i=0 ; i<MAX_STATS ; i++)
                    286:                if (statbits & (1<<i) )
                    287:                        MSG_WriteShort (msg, ps->stats[i]);
                    288: }
                    289: 
                    290: 
                    291: /*
                    292: ==================
                    293: SV_WriteFrameToClient
                    294: ==================
                    295: */
                    296: void SV_WriteFrameToClient (client_t *client, sizebuf_t *msg)
                    297: {
                    298:        client_frame_t          *frame, *oldframe;
                    299:        int                                     lastframe;
                    300: 
                    301: //Com_Printf ("%i -> %i\n", client->lastframe, sv.framenum);
                    302:        // this is the frame we are creating
                    303:        frame = &client->frames[sv.framenum & UPDATE_MASK];
                    304: 
                    305:        if (client->lastframe <= 0)
                    306:        {       // client is asking for a retransmit
                    307:                oldframe = NULL;
                    308:                lastframe = -1;
                    309:        }
                    310:        else if (sv.framenum - client->lastframe >= (UPDATE_BACKUP - 3) )
                    311:        {       // client hasn't gotten a good message through in a long time
                    312: //             Com_Printf ("%s: Delta request from out-of-date packet.\n", client->name);
                    313:                oldframe = NULL;
                    314:                lastframe = -1;
                    315:        }
                    316:        else
                    317:        {       // we have a valid message to delta from
                    318:                oldframe = &client->frames[client->lastframe & UPDATE_MASK];
                    319:                lastframe = client->lastframe;
                    320:        }
                    321: 
                    322:        MSG_WriteByte (msg, svc_frame);
                    323:        MSG_WriteLong (msg, sv.framenum);
                    324:        MSG_WriteLong (msg, lastframe); // what we are delta'ing from
                    325:        MSG_WriteByte (msg, client->surpressCount);     // rate dropped packets
                    326:        client->surpressCount = 0;
                    327: 
                    328:        // send over the areabits
                    329:        MSG_WriteByte (msg, frame->areabytes);
                    330:        SZ_Write (msg, frame->areabits, frame->areabytes);
                    331: 
                    332:        // delta encode the playerstate
                    333:        SV_WritePlayerstateToClient (oldframe, frame, msg);
                    334: 
                    335:        // delta encode the entities
                    336:        SV_EmitPacketEntities (oldframe, frame, msg);
                    337: }
                    338: 
                    339: 
                    340: /*
                    341: =============================================================================
                    342: 
                    343: Build a client frame structure
                    344: 
                    345: =============================================================================
                    346: */
                    347: 
                    348: byte           fatpvs[65536/8];        // 32767 is MAX_MAP_LEAFS
                    349: 
                    350: /*
                    351: ============
                    352: SV_FatPVS
                    353: 
                    354: The client will interpolate the view position,
                    355: so we can't use a single PVS point
                    356: ===========
                    357: */
                    358: void SV_FatPVS (vec3_t org)
                    359: {
                    360:        int             leafs[64];
                    361:        int             i, j, count;
                    362:        int             longs;
                    363:        byte    *src;
                    364:        vec3_t  mins, maxs;
                    365: 
                    366:        for (i=0 ; i<3 ; i++)
                    367:        {
                    368:                mins[i] = org[i] - 8;
                    369:                maxs[i] = org[i] + 8;
                    370:        }
                    371: 
                    372:        count = CM_BoxLeafnums (mins, maxs, leafs, 64, NULL);
                    373:        if (count < 1)
                    374:                Com_Error (ERR_FATAL, "SV_FatPVS: count < 1");
                    375:        longs = (CM_NumClusters()+31)>>5;
                    376: 
                    377:        // convert leafs to clusters
                    378:        for (i=0 ; i<count ; i++)
                    379:                leafs[i] = CM_LeafCluster(leafs[i]);
                    380: 
                    381:        memcpy (fatpvs, CM_ClusterPVS(leafs[0]), longs<<2);
                    382:        // or in all the other leaf bits
                    383:        for (i=1 ; i<count ; i++)
                    384:        {
                    385:                for (j=0 ; j<i ; j++)
                    386:                        if (leafs[i] == leafs[j])
                    387:                                break;
                    388:                if (j != i)
                    389:                        continue;               // already have the cluster we want
                    390:                src = CM_ClusterPVS(leafs[i]);
                    391:                for (j=0 ; j<longs ; j++)
                    392:                        ((long *)fatpvs)[j] |= ((long *)src)[j];
                    393:        }
                    394: }
                    395: 
                    396: 
                    397: /*
                    398: =============
                    399: SV_BuildClientFrame
                    400: 
                    401: Decides which entities are going to be visible to the client, and
                    402: copies off the playerstat and areabits.
                    403: =============
                    404: */
                    405: void SV_BuildClientFrame (client_t *client)
                    406: {
                    407:        int             e, i;
                    408:        vec3_t  org;
                    409:        edict_t *ent;
                    410:        edict_t *clent;
                    411:        client_frame_t  *frame;
                    412:        entity_state_t  *state;
                    413:        int             l;
                    414:        int             clientarea, clientcluster;
                    415:        int             leafnum;
                    416:        int             c_fullsend;
                    417:        byte    *clientphs;
                    418:        byte    *bitvector;
                    419: 
                    420:        clent = client->edict;
                    421:        if (!clent->client)
                    422:                return;         // not in game yet
                    423: 
                    424:        // this is the frame we are creating
                    425:        frame = &client->frames[sv.framenum & UPDATE_MASK];
                    426: 
                    427:        // find the client's PVS
                    428:        for (i=0 ; i<3 ; i++)
                    429:                org[i] = clent->client->ps.pmove.origin[i]*0.125 + clent->client->ps.viewoffset[i];
                    430: 
                    431:        leafnum = CM_PointLeafnum (org);
                    432:        clientarea = CM_LeafArea (leafnum);
                    433:        clientcluster = CM_LeafCluster (leafnum);
                    434: 
                    435:        // calculate the visible areas
                    436:        frame->areabytes = CM_WriteAreaBits (frame->areabits, clientarea);
                    437: 
                    438:        // grab the current player_state_t
                    439:        frame->ps = clent->client->ps;
                    440: 
                    441: 
                    442:        SV_FatPVS (org);
                    443:        clientphs = CM_ClusterPHS (clientcluster);
                    444: 
                    445:        // build up the list of visible entities
                    446:        frame->num_entities = 0;
                    447:        frame->first_entity = svs.next_client_entities;
                    448: 
                    449:        c_fullsend = 0;
                    450: 
                    451:        for (e=1 ; e<ge->num_edicts ; e++)
                    452:        {
                    453:                ent = EDICT_NUM(e);
                    454: 
                    455:                // ignore ents without visible models
                    456:                if (ent->svflags & SVF_NOCLIENT)
                    457:                        continue;
                    458: 
                    459:                // ignore ents without visible models unless they have an effect
                    460:                if (!ent->s.modelindex && !ent->s.effects && !ent->s.sound
                    461:                        && !ent->s.event)
                    462:                        continue;
                    463: 
                    464:                // ignore if not touching a PV leaf
                    465:                if (ent != clent)
                    466:                {
                    467:                        // check area
                    468:                        if (!CM_AreasConnected (clientarea, ent->areanum))
                    469:                        {       // doors can legally straddle two areas, so
                    470:                                // we may need to check another one
                    471:                                if (!ent->areanum2
                    472:                                        || !CM_AreasConnected (clientarea, ent->areanum2))
                    473:                                        continue;               // blocked by a door
                    474:                        }
                    475: 
                    476:                        // beams just check one point for PHS
                    477:                        if (ent->s.renderfx & RF_BEAM)
                    478:                        {
                    479:                                l = ent->clusternums[0];
                    480:                                if ( !(clientphs[l >> 3] & (1 << (l&7) )) )
                    481:                                        continue;
                    482:                        }
                    483:                        else
                    484:                        {
                    485:                                // FIXME: if an ent has a model and a sound, but isn't
                    486:                                // in the PVS, only the PHS, clear the model
                    487:                                if (ent->s.sound)
                    488:                                {
                    489:                                        bitvector = fatpvs;     //clientphs;
                    490:                                }
                    491:                                else
                    492:                                        bitvector = fatpvs;
                    493: 
                    494:                                if (ent->num_clusters == -1)
                    495:                                {       // too many leafs for individual check, go by headnode
                    496:                                        if (!CM_HeadnodeVisible (ent->headnode, bitvector))
                    497:                                                continue;
                    498:                                        c_fullsend++;
                    499:                                }
                    500:                                else
                    501:                                {       // check individual leafs
                    502:                                        for (i=0 ; i < ent->num_clusters ; i++)
                    503:                                        {
                    504:                                                l = ent->clusternums[i];
                    505:                                                if (bitvector[l >> 3] & (1 << (l&7) ))
                    506:                                                        break;
                    507:                                        }
                    508:                                        if (i == ent->num_clusters)
                    509:                                                continue;               // not visible
                    510:                                }
                    511: 
                    512:                                if (!ent->s.modelindex)
                    513:                                {       // don't send sounds if they will be attenuated away
                    514:                                        vec3_t  delta;
                    515:                                        float   len;
                    516: 
                    517:                                        VectorSubtract (org, ent->s.origin, delta);
                    518:                                        len = VectorLength (delta);
                    519:                                        if (len > 400)
                    520:                                                continue;
                    521:                                }
                    522:                        }
                    523:                }
                    524: 
                    525:                // add it to the circular client_entities array
                    526:                state = &svs.client_entities[svs.next_client_entities%svs.num_client_entities];
                    527:                if (ent->s.number != e)
                    528:                {
                    529:                        Com_DPrintf ("FIXING ENT->S.NUMBER!!!\n");
                    530:                        ent->s.number = e;
                    531:                }
                    532:                *state = ent->s;
                    533: 
                    534:                // don't mark players missiles as solid
                    535:                if (ent->owner == client->edict)
                    536:                        state->solid = 0;
                    537: 
                    538:                svs.next_client_entities++;
                    539:                frame->num_entities++;
                    540:        }
                    541: }
                    542: 
                    543: 
                    544: /*
                    545: ==================
                    546: SV_RecordDemoMessage
                    547: 
                    548: Save everything in the world out without deltas.
                    549: Used for recording footage for merged or assembled demos
                    550: ==================
                    551: */
                    552: void SV_RecordDemoMessage (void)
                    553: {
                    554:        int                     e;
                    555:        edict_t         *ent;
                    556:        entity_state_t  nostate;
                    557:        sizebuf_t       buf;
                    558:        byte            buf_data[32768];
                    559:        int                     len;
                    560: 
                    561:        if (!svs.demofile)
                    562:                return;
                    563: 
                    564:        memset (&nostate, 0, sizeof(nostate));
                    565:        SZ_Init (&buf, buf_data, sizeof(buf_data));
                    566: 
                    567:        // write a frame message that doesn't contain a player_state_t
                    568:        MSG_WriteByte (&buf, svc_frame);
                    569:        MSG_WriteLong (&buf, sv.framenum);
                    570: 
                    571:        MSG_WriteByte (&buf, svc_packetentities);
                    572: 
                    573:        for (e=1, ent=EDICT_NUM(e) ; e<ge->num_edicts ; e++, ent++)
                    574:        {
                    575:                // invisible trigger
                    576:                if (ent->svflags & SVF_NOCLIENT)
                    577:                        continue;
                    578: 
                    579:                // ignore ents without visible models unless they have an effect
                    580:                if (!ent->s.modelindex && !ent->s.effects && !ent->s.sound
                    581:                        && !ent->s.event)
                    582:                        continue;
                    583: 
                    584:                MSG_WriteDeltaEntity (&nostate, &ent->s, &buf, false);
                    585:        }
                    586: 
                    587:        MSG_WriteShort (&buf, 0);               // end of packetentities
                    588: 
                    589:        // now add the accumulated multicast information
                    590:        SZ_Write (&buf, svs.demo_multicast.data, svs.demo_multicast.cursize);
                    591:        SZ_Clear (&svs.demo_multicast);
                    592: 
                    593:        // now write the entire message to the file, prefixed by the length
                    594:        len = LittleLong (buf.cursize);
                    595:        fwrite (&len, 4, 1, svs.demofile);
                    596:        fwrite (buf.data, buf.cursize, 1, svs.demofile);
                    597: }
                    598: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.