Annotation of quake2/client/cl_ents.c, revision 1.1.1.1

1.1       root        1: // cl_ents.c -- entity parsing and management
                      2: #include "client.h"
                      3: 
                      4: extern struct model_s  *cl_mod_powerscreen;
                      5: /*
                      6: =========================================================================
                      7: FRAME PARSING
                      8: =========================================================================
                      9: */
                     10: /*
                     11: =================
                     12: CL_ParseEntityBits
                     13: 
                     14: Returns the entity number and the header bits
                     15: =================
                     16: */
                     17: int    bitcounts[32];  /// just for protocol profiling
                     18: int CL_ParseEntityBits (unsigned *bits)
                     19: {
                     20:        unsigned        b, total;
                     21:        int                     i;
                     22:        int                     number;
                     23: 
                     24:        total = MSG_ReadByte (&net_message);
                     25:        if (total & U_MOREBITS1)
                     26:        {
                     27:                b = MSG_ReadByte (&net_message);
                     28:                total |= b<<8;
                     29:        }
                     30:        if (total & U_MOREBITS2)
                     31:        {
                     32:                b = MSG_ReadByte (&net_message);
                     33:                total |= b<<16;
                     34:        }
                     35:        if (total & U_MOREBITS3)
                     36:        {
                     37:                b = MSG_ReadByte (&net_message);
                     38:                total |= b<<24;
                     39:        }
                     40: 
                     41:        // count the bits for net profiling
                     42:        for (i=0 ; i<32 ; i++)
                     43:                if (total&(1<<i))
                     44:                        bitcounts[i]++;
                     45: 
                     46:        if (total & U_NUMBER16)
                     47:                number = MSG_ReadShort (&net_message);
                     48:        else
                     49:                number = MSG_ReadByte (&net_message);
                     50: 
                     51:        *bits = total;
                     52: 
                     53:        return number;
                     54: }
                     55: /*
                     56: ==================
                     57: CL_ParseDelta
                     58: Can go from either a baseline or a previous packet_entity
                     59: ==================
                     60: */
                     61: void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int number, int bits)
                     62: {
                     63:        // set everything to the state we are delta'ing from
                     64:        *to = *from;
                     65: //     VectorCopy (from->origin, to->old_origin);
                     66:        to->number = number;
                     67:        if (bits & U_MODEL)
                     68:                to->modelindex = MSG_ReadByte (&net_message);
                     69:        if (bits & U_MODEL2)
                     70:                to->modelindex2 = MSG_ReadByte (&net_message);
                     71:        if (bits & U_MODEL3)
                     72:                to->modelindex3 = MSG_ReadByte (&net_message);
                     73:        if (bits & U_MODEL4)
                     74:                to->modelindex4 = MSG_ReadByte (&net_message);
                     75:                
                     76:        if (bits & U_FRAME8)
                     77:                to->frame = MSG_ReadByte (&net_message);
                     78:        if (bits & U_FRAME16)
                     79:                to->frame = MSG_ReadShort (&net_message);
                     80:        if ((bits & U_SKIN8) && (bits & U_SKIN16))              //used for laser colors
                     81:                to->skinnum = MSG_ReadLong(&net_message);
                     82:        else if (bits & U_SKIN8)
                     83:                to->skinnum = MSG_ReadByte(&net_message);
                     84:        else if (bits & U_SKIN16)
                     85:                to->skinnum = MSG_ReadShort(&net_message);
                     86: 
                     87:        if ( (bits & (U_EFFECTS8|U_EFFECTS16)) == (U_EFFECTS8|U_EFFECTS16) )
                     88:                to->effects = MSG_ReadLong(&net_message);
                     89:        else if (bits & U_EFFECTS8)
                     90:                to->effects = MSG_ReadByte(&net_message);
                     91:        else if (bits & U_EFFECTS16)
                     92:                to->effects = MSG_ReadShort(&net_message);
                     93:        if ( (bits & (U_RENDERFX8|U_RENDERFX16)) == (U_RENDERFX8|U_RENDERFX16) )
                     94:                to->renderfx = MSG_ReadLong(&net_message);
                     95:        else if (bits & U_RENDERFX8)
                     96:                to->renderfx = MSG_ReadByte(&net_message);
                     97:        else if (bits & U_RENDERFX16)
                     98:                to->renderfx = MSG_ReadShort(&net_message);
                     99:        if (bits & U_ORIGIN1)
                    100:                to->origin[0] = MSG_ReadCoord (&net_message);
                    101:        if (bits & U_ORIGIN2)
                    102:                to->origin[1] = MSG_ReadCoord (&net_message);
                    103:        if (bits & U_ORIGIN3)
                    104:                to->origin[2] = MSG_ReadCoord (&net_message);
                    105:                
                    106:        if (bits & U_ANGLE1)
                    107:                to->angles[0] = MSG_ReadAngle(&net_message);
                    108:        if (bits & U_ANGLE2)
                    109:                to->angles[1] = MSG_ReadAngle(&net_message);
                    110:        if (bits & U_ANGLE3)
                    111:                to->angles[2] = MSG_ReadAngle(&net_message);
                    112:        if (bits & U_OLDORIGIN)
                    113:                MSG_ReadPos (&net_message, to->old_origin);
                    114:        if (bits & U_SOUND)
                    115:                to->sound = MSG_ReadByte (&net_message);
                    116: 
                    117:        if (bits & U_EVENT)
                    118:                to->event = MSG_ReadByte (&net_message);
                    119:        else
                    120:                to->event = 0;
                    121: 
                    122:        if (bits & U_SOLID)
                    123:                to->solid = MSG_ReadShort (&net_message);
                    124: }
                    125: 
                    126: /*
                    127: ==================
                    128: CL_DeltaEntity
                    129: 
                    130: Parses deltas from the given base and adds the resulting entity
                    131: to the current frame
                    132: ==================
                    133: */
                    134: void CL_DeltaEntity (frame_t *frame, int newnum, entity_state_t *old, int bits)
                    135: {
                    136:        centity_t       *ent;
                    137:        entity_state_t  *state;
                    138: 
                    139:        ent = &cl_entities[newnum];
                    140: 
                    141:        state = &cl_parse_entities[cl.parse_entities & (MAX_PARSE_ENTITIES-1)];
                    142:        cl.parse_entities++;
                    143:        frame->num_entities++;
                    144: 
                    145:        CL_ParseDelta (old, state, newnum, bits);
                    146: 
                    147:        // some data changes will force no lerping
                    148:        if (state->modelindex != ent->current.modelindex
                    149:                || state->modelindex2 != ent->current.modelindex2
                    150:                || state->modelindex3 != ent->current.modelindex3
                    151:                || state->modelindex4 != ent->current.modelindex4
                    152:                || abs(state->origin[0] - ent->current.origin[0]) > 512
                    153:                || abs(state->origin[1] - ent->current.origin[1]) > 512
                    154:                || abs(state->origin[2] - ent->current.origin[2]) > 512
                    155:                || state->event == EV_PLAYER_TELEPORT
                    156:                )
                    157:        {
                    158:                ent->serverframe = -99;
                    159:        }
                    160: 
                    161:        if (ent->serverframe != cl.frame.serverframe - 1)
                    162:        {       // wasn't in last update, so initialize some things
                    163:                ent->trailcount = 1024;         // for diminishing rocket / grenade trails
                    164:                // duplicate the current state so lerping doesn't hurt anything
                    165:                ent->prev = *state;
                    166:                VectorCopy (state->old_origin, ent->prev.origin);
                    167:                VectorCopy (state->old_origin, ent->lerp_origin);
                    168:        }
                    169:        else
                    170:        {       // shuffle the last state to previous
                    171:                ent->prev = ent->current;
                    172:        }
                    173: 
                    174:        ent->serverframe = cl.frame.serverframe;
                    175:        ent->current = *state;
                    176: }
                    177: /*
                    178: ==================
                    179: CL_ParsePacketEntities
                    180: An svc_packetentities has just been parsed, deal with the
                    181: rest of the data stream.
                    182: ==================
                    183: */
                    184: void CL_ParsePacketEntities (frame_t *oldframe, frame_t *newframe)
                    185: {
                    186:        int                     newnum;
                    187:        int                     bits;
                    188:        entity_state_t  *oldstate;
                    189:        int                     oldindex, oldnum;
                    190: 
                    191:        newframe->parse_entities = cl.parse_entities;
                    192:        newframe->num_entities = 0;
                    193: 
                    194:        // delta from the entities present in oldframe
                    195:        oldindex = 0;
                    196:        if (!oldframe)
                    197:                oldnum = 99999;
                    198:        else
                    199:        {
                    200:                if (oldindex >= oldframe->num_entities)
                    201:                        oldnum = 99999;
                    202:                else
                    203:                {
                    204:                        oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
                    205:                        oldnum = oldstate->number;
                    206:                }
                    207:        }
                    208:        while (1)
                    209:        {
                    210:                newnum = CL_ParseEntityBits (&bits);
                    211:                if (newnum >= MAX_EDICTS)
                    212:                        Com_Error (ERR_DROP,"CL_ParsePacketEntities: bad number:%i", newnum);
                    213: 
                    214:                if (net_message.readcount > net_message.cursize)
                    215:                        Com_Error (ERR_DROP,"CL_ParsePacketEntities: end of message");
                    216: 
                    217:                if (!newnum)
                    218:                        break;
                    219: 
                    220:                while (oldnum < newnum)
                    221:                {       // one or more entities from the old packet are unchanged
                    222:                        if (cl_shownet->value == 3)
                    223:                                Com_Printf ("   unchanged: %i\n", oldnum);
                    224:                        CL_DeltaEntity (newframe, oldnum, oldstate, 0);
                    225:                        
                    226:                        oldindex++;
                    227: 
                    228:                        if (oldindex >= oldframe->num_entities)
                    229:                                oldnum = 99999;
                    230:                        else
                    231:                        {
                    232:                                oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
                    233:                                oldnum = oldstate->number;
                    234:                        }
                    235:                }
                    236: 
                    237:                if (bits & U_REMOVE)
                    238:                {       // the entity present in oldframe is not in the current frame
                    239:                        if (cl_shownet->value == 3)
                    240:                                Com_Printf ("   remove: %i\n", newnum);
                    241:                        if (oldnum != newnum)
                    242:                                Com_Printf ("U_REMOVE: oldnum != newnum\n");
                    243: 
                    244:                        oldindex++;
                    245: 
                    246:                        if (oldindex >= oldframe->num_entities)
                    247:                                oldnum = 99999;
                    248:                        else
                    249:                        {
                    250:                                oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
                    251:                                oldnum = oldstate->number;
                    252:                        }
                    253:                        continue;
                    254:                }
                    255: 
                    256:                if (oldnum == newnum)
                    257:                {       // delta from previous state
                    258:                        if (cl_shownet->value == 3)
                    259:                                Com_Printf ("   delta: %i\n", newnum);
                    260:                        CL_DeltaEntity (newframe, newnum, oldstate, bits);
                    261: 
                    262:                        oldindex++;
                    263: 
                    264:                        if (oldindex >= oldframe->num_entities)
                    265:                                oldnum = 99999;
                    266:                        else
                    267:                        {
                    268:                                oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
                    269:                                oldnum = oldstate->number;
                    270:                        }
                    271:                        continue;
                    272:                }
                    273: 
                    274:                if (oldnum > newnum)
                    275:                {       // delta from baseline
                    276:                        if (cl_shownet->value == 3)
                    277:                                Com_Printf ("   baseline: %i\n", newnum);
                    278:                        CL_DeltaEntity (newframe, newnum, &cl_entities[newnum].baseline, bits);
                    279:                        continue;
                    280:                }
                    281: 
                    282:        }
                    283: 
                    284:        // any remaining entities in the old frame are copied over
                    285:        while (oldnum != 99999)
                    286:        {       // one or more entities from the old packet are unchanged
                    287:                if (cl_shownet->value == 3)
                    288:                        Com_Printf ("   unchanged: %i\n", oldnum);
                    289:                CL_DeltaEntity (newframe, oldnum, oldstate, 0);
                    290:                
                    291:                oldindex++;
                    292: 
                    293:                if (oldindex >= oldframe->num_entities)
                    294:                        oldnum = 99999;
                    295:                else
                    296:                {
                    297:                        oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
                    298:                        oldnum = oldstate->number;
                    299:                }
                    300:        }
                    301: }
                    302: /*
                    303: ===================
                    304: CL_ParsePlayerstate
                    305: ===================
                    306: */
                    307: void CL_ParsePlayerstate (frame_t *oldframe, frame_t *newframe)
                    308: {
                    309:        int                     flags;
                    310:        player_state_t  *state;
                    311:        int                     i;
                    312:        int                     statbits;
                    313:        state = &newframe->playerstate;
                    314: 
                    315:        // clear to old value before delta parsing
                    316:        if (oldframe)
                    317:                *state = oldframe->playerstate;
                    318:        else
                    319:                memset (state, 0, sizeof(*state));
                    320:        flags = MSG_ReadShort (&net_message);
                    321: 
                    322:        //
                    323:        // parse the pmove_state_t
                    324:        //
                    325:        if (flags & PS_M_TYPE)
                    326:                state->pmove.pm_type = MSG_ReadByte (&net_message);
                    327: 
                    328:        if (flags & PS_M_ORIGIN)
                    329:        {
                    330:                state->pmove.origin[0] = MSG_ReadShort (&net_message);
                    331:                state->pmove.origin[1] = MSG_ReadShort (&net_message);
                    332:                state->pmove.origin[2] = MSG_ReadShort (&net_message);
                    333:        }
                    334: 
                    335:        if (flags & PS_M_VELOCITY)
                    336:        {
                    337:                state->pmove.velocity[0] = MSG_ReadShort (&net_message);
                    338:                state->pmove.velocity[1] = MSG_ReadShort (&net_message);
                    339:                state->pmove.velocity[2] = MSG_ReadShort (&net_message);
                    340:        }
                    341: 
                    342:        if (flags & PS_M_TIME)
                    343:                state->pmove.pm_time = MSG_ReadByte (&net_message);
                    344: 
                    345:        if (flags & PS_M_FLAGS)
                    346:                state->pmove.pm_flags = MSG_ReadByte (&net_message);
                    347: 
                    348:        if (flags & PS_M_GRAVITY)
                    349:                state->pmove.gravity = MSG_ReadShort (&net_message);
                    350: 
                    351:        if (flags & PS_M_DELTA_ANGLES)
                    352:        {
                    353:                state->pmove.delta_angles[0] = MSG_ReadShort (&net_message);
                    354:                state->pmove.delta_angles[1] = MSG_ReadShort (&net_message);
                    355:                state->pmove.delta_angles[2] = MSG_ReadShort (&net_message);
                    356:        }
                    357: 
                    358:        if (cl.attractloop)
                    359:                state->pmove.pm_type = PM_FREEZE;               // demo playback
                    360: 
                    361:        //
                    362:        // parse the rest of the player_state_t
                    363:        //
                    364:        if (flags & PS_VIEWOFFSET)
                    365:        {
                    366:                state->viewoffset[0] = MSG_ReadChar (&net_message) * 0.25;
                    367:                state->viewoffset[1] = MSG_ReadChar (&net_message) * 0.25;
                    368:                state->viewoffset[2] = MSG_ReadChar (&net_message) * 0.25;
                    369:        }
                    370: 
                    371:        if (flags & PS_VIEWANGLES)
                    372:        {
                    373:                state->viewangles[0] = MSG_ReadAngle16 (&net_message);
                    374:                state->viewangles[1] = MSG_ReadAngle16 (&net_message);
                    375:                state->viewangles[2] = MSG_ReadAngle16 (&net_message);
                    376:        }
                    377: 
                    378:        if (flags & PS_KICKANGLES)
                    379:        {
                    380:                state->kick_angles[0] = MSG_ReadChar (&net_message) * 0.25;
                    381:                state->kick_angles[1] = MSG_ReadChar (&net_message) * 0.25;
                    382:                state->kick_angles[2] = MSG_ReadChar (&net_message) * 0.25;
                    383:        }
                    384:        if (flags & PS_WEAPONINDEX)
                    385:        {
                    386:                state->gunindex = MSG_ReadByte (&net_message);
                    387:        }
                    388:        if (flags & PS_WEAPONFRAME)
                    389:        {
                    390:                state->gunframe = MSG_ReadByte (&net_message);
                    391:                state->gunoffset[0] = MSG_ReadChar (&net_message)*0.25;
                    392:                state->gunoffset[1] = MSG_ReadChar (&net_message)*0.25;
                    393:                state->gunoffset[2] = MSG_ReadChar (&net_message)*0.25;
                    394:                state->gunangles[0] = MSG_ReadChar (&net_message)*0.25;
                    395:                state->gunangles[1] = MSG_ReadChar (&net_message)*0.25;
                    396:                state->gunangles[2] = MSG_ReadChar (&net_message)*0.25;
                    397:        }
                    398:        if (flags & PS_BLEND)
                    399:        {
                    400:                state->blend[0] = MSG_ReadByte (&net_message)/255.0;
                    401:                state->blend[1] = MSG_ReadByte (&net_message)/255.0;
                    402:                state->blend[2] = MSG_ReadByte (&net_message)/255.0;
                    403:                state->blend[3] = MSG_ReadByte (&net_message)/255.0;
                    404:        }
                    405:        if (flags & PS_FOV)
                    406:                state->fov = MSG_ReadByte (&net_message);
                    407:        if (flags & PS_RDFLAGS)
                    408:                state->rdflags = MSG_ReadByte (&net_message);
                    409:        // parse stats
                    410:        statbits = MSG_ReadLong (&net_message);
                    411:        for (i=0 ; i<MAX_STATS ; i++)
                    412:                if (statbits & (1<<i) )
                    413:                        state->stats[i] = MSG_ReadShort(&net_message);
                    414: }
                    415: /*
                    416: ==================
                    417: CL_FireEntityEvents
                    418: 
                    419: ==================
                    420: */
                    421: void CL_FireEntityEvents (frame_t *frame)
                    422: {
                    423:        entity_state_t          *s1;
                    424:        int                                     pnum, num;
                    425: 
                    426:        for (pnum = 0 ; pnum<frame->num_entities ; pnum++)
                    427:        {
                    428:                num = (frame->parse_entities + pnum)&(MAX_PARSE_ENTITIES-1);
                    429:                s1 = &cl_parse_entities[num];
                    430:                if (s1->event)
                    431:                        CL_EntityEvent (s1);
                    432: 
                    433:                // EF_TELEPORTER acts like an event, but is not cleared each frame
                    434:                if (s1->effects & EF_TELEPORTER)
                    435:                        CL_TeleporterParticles (s1);
                    436:        }
                    437: }
                    438: 
                    439: 
                    440: /*
                    441: ================
                    442: CL_ParseFrame
                    443: ================
                    444: */
                    445: void CL_ParseFrame (void)
                    446: {
                    447:        int                     cmd;
                    448:        int                     len;
                    449:        frame_t         *old;
                    450:        memset (&cl.frame, 0, sizeof(cl.frame));
                    451:        cl.frame.serverframe = MSG_ReadLong (&net_message);
                    452:        cl.frame.deltaframe = MSG_ReadLong (&net_message);
                    453:        cl.frame.servertime = cl.frame.serverframe*100;
                    454: 
                    455:        // BIG HACK to let old demos continue to work
                    456:        if (cls.serverProtocol != 26)
                    457:                cl.surpressCount = MSG_ReadByte (&net_message);
                    458: 
                    459:        if (cl_shownet->value == 3)
                    460:                Com_Printf ("   frame:%i  delta:%i\n", cl.frame.serverframe,
                    461:                cl.frame.deltaframe);
                    462: 
                    463:        // If the frame is delta compressed from data that we
                    464:        // no longer have available, we must suck up the rest of
                    465:        // the frame, but not use it, then ask for a non-compressed
                    466:        // message 
                    467:        if (cl.frame.deltaframe <= 0)
                    468:        {
                    469:                cl.frame.valid = true;          // uncompressed frame
                    470:                old = NULL;
                    471:                cls.demowaiting = false;        // we can start recording now
                    472:        }
                    473:        else
                    474:        {
                    475:                old = &cl.frames[cl.frame.deltaframe & UPDATE_MASK];
                    476:                if (!old->valid)
                    477:                {       // should never happen
                    478:                        Com_Printf ("Delta from invalid frame (not supposed to happen!).\n");
                    479:                }
                    480:                if (old->serverframe != cl.frame.deltaframe)
                    481:                {       // The frame that the server did the delta from
                    482:                        // is too old, so we can't reconstruct it properly.
                    483:                        Com_Printf ("Delta frame too old.\n");
                    484:                }
                    485:                else if (cl.parse_entities - old->parse_entities > MAX_PARSE_ENTITIES-128)
                    486:                {
                    487:                        Com_Printf ("Delta parse_entities too old.\n");
                    488:                }
                    489:                else
                    490:                        cl.frame.valid = true;  // valid delta parse
                    491:        }
                    492:        // clamp time 
                    493:        if (cl.time > cl.frame.servertime)
                    494:                cl.time = cl.frame.servertime;
                    495:        else if (cl.time < cl.frame.servertime - 100)
                    496:                cl.time = cl.frame.servertime - 100;
                    497: 
                    498:        // read areabits
                    499:        len = MSG_ReadByte (&net_message);
                    500:        MSG_ReadData (&net_message, &cl.frame.areabits, len);
                    501: 
                    502:        // read playerinfo
                    503:        cmd = MSG_ReadByte (&net_message);
                    504:        SHOWNET(svc_strings[cmd]);
                    505:        if (cmd != svc_playerinfo)
                    506:                Com_Error (ERR_DROP, "CL_ParseFrame: not playerinfo");
                    507:        CL_ParsePlayerstate (old, &cl.frame);
                    508: 
                    509:        // read packet entities
                    510:        cmd = MSG_ReadByte (&net_message);
                    511:        SHOWNET(svc_strings[cmd]);
                    512:        if (cmd != svc_packetentities)
                    513:                Com_Error (ERR_DROP, "CL_ParseFrame: not packetentities");
                    514:        CL_ParsePacketEntities (old, &cl.frame);
                    515: 
                    516:        // save the frame off in the backup array for later delta comparisons
                    517:        cl.frames[cl.frame.serverframe & UPDATE_MASK] = cl.frame;
                    518: 
                    519:        if (cl.frame.valid)
                    520:        {
                    521:                // getting a valid frame message ends the connection process
                    522:                if (cls.state != ca_active)
                    523:                {
                    524:                        cls.state = ca_active;
                    525:                        cl.force_refdef = true;
                    526:                        cl.predicted_origin[0] = cl.frame.playerstate.pmove.origin[0]*0.125;
                    527:                        cl.predicted_origin[1] = cl.frame.playerstate.pmove.origin[1]*0.125;
                    528:                        cl.predicted_origin[2] = cl.frame.playerstate.pmove.origin[2]*0.125;
                    529:                        VectorCopy (cl.frame.playerstate.viewangles, cl.predicted_angles);
                    530:                        if (cls.disable_servercount != cl.servercount
                    531:                                && cl.refresh_prepped)
                    532:                                SCR_EndLoadingPlaque ();        // get rid of loading plaque
                    533:                }
                    534:                cl.sound_prepped = true;        // can start mixing ambient sounds
                    535:        
                    536:                // fire entity events
                    537:                CL_FireEntityEvents (&cl.frame);
                    538:                CL_CheckPredictionError ();
                    539:        }
                    540: }
                    541: /*
                    542: ==========================================================================
                    543: 
                    544: INTERPOLATE BETWEEN FRAMES TO GET RENDERING PARMS
                    545: 
                    546: ==========================================================================
                    547: */
                    548: 
                    549: /*
                    550: ===============
                    551: CL_AddPacketEntities
                    552: 
                    553: ===============
                    554: */
                    555: void CL_AddPacketEntities (frame_t *frame)
                    556: {
                    557:        entity_t                        ent;
                    558:        entity_state_t          *s1;
                    559:        float                           autorotate;
                    560:        int                                     i;
                    561:        int                                     pnum;
                    562:        centity_t                       *cent;
                    563:        int                                     autoanim;
                    564:        clientinfo_t            *ci;
                    565:        int                                     effects, renderfx;
                    566: 
                    567:        // bonus items rotate at a fixed rate
                    568:        autorotate = anglemod(cl.time/10);
                    569: 
                    570:        // brush models can auto animate their frames
                    571:        autoanim = 2*cl.time/1000;
                    572: 
                    573:        memset (&ent, 0, sizeof(ent));
                    574: 
                    575:        for (pnum = 0 ; pnum<frame->num_entities ; pnum++)
                    576:        {
                    577:                s1 = &cl_parse_entities[(frame->parse_entities+pnum)&(MAX_PARSE_ENTITIES-1)];
                    578: 
                    579:                cent = &cl_entities[s1->number];
                    580: 
                    581:                effects = s1->effects;
                    582:                renderfx = s1->renderfx;
                    583: 
                    584:                        // set frame
                    585:                if (effects & EF_ANIM01)
                    586:                        ent.frame = autoanim & 1;
                    587:                else if (effects & EF_ANIM23)
                    588:                        ent.frame = 2 + (autoanim & 1);
                    589:                else if (effects & EF_ANIM_ALL)
                    590:                        ent.frame = autoanim;
                    591:                else if (effects & EF_ANIM_ALLFAST)
                    592:                        ent.frame = cl.time / 100;
                    593:                else
                    594:                        ent.frame = s1->frame;
                    595: 
                    596: 
                    597:                // quad and pent can do different things on client
                    598:                if (effects & EF_PENT)
                    599:                {
                    600:                        effects &= ~EF_PENT;
                    601:                        effects |= EF_COLOR_SHELL;
                    602:                        renderfx |= RF_SHELL_RED;
                    603:                }
                    604: 
                    605:                if (effects & EF_QUAD)
                    606:                {
                    607:                        effects &= ~EF_QUAD;
                    608:                        effects |= EF_COLOR_SHELL;
                    609:                        renderfx |= RF_SHELL_BLUE;
                    610:                }
                    611: 
                    612:                ent.oldframe = cent->prev.frame;
                    613:                ent.backlerp = 1.0 - cl.lerpfrac;
                    614: 
                    615:                if (renderfx & (RF_FRAMELERP|RF_BEAM))
                    616:                {       // step origin discretely, because the frames
                    617:                        // do the animation properly
                    618:                        VectorCopy (cent->current.origin, ent.origin);
                    619:                        VectorCopy (cent->current.old_origin, ent.oldorigin);
                    620:                }
                    621:                else
                    622:                {       // interpolate origin
                    623:                        for (i=0 ; i<3 ; i++)
                    624:                        {
                    625:                                ent.origin[i] = ent.oldorigin[i] = cent->prev.origin[i] + cl.lerpfrac * 
                    626:                                        (cent->current.origin[i] - cent->prev.origin[i]);
                    627:                        }
                    628:                }
                    629: 
                    630:                // create a new entity
                    631:        
                    632:                // tweak the color of beams
                    633:                if ( renderfx & RF_BEAM )
                    634:                {       // the four beam colors are encoded in 32 bits of skinnum (hack)
                    635:                        ent.alpha = 0.30;
                    636:                        ent.skinnum = (s1->skinnum >> ((rand() % 4)*8)) & 0xff;
                    637:                        ent.model = NULL;
                    638:                }
                    639:                else
                    640:                {
                    641:                        // set skin
                    642:                        if (s1->modelindex == 255)
                    643:                        {       // use custom player skin
                    644:                                ent.skinnum = 0;
                    645:                                ci = &cl.clientinfo[s1->skinnum];
                    646:                                ent.skin = ci->skin;
                    647:                                ent.model = ci->model;
                    648:                                if (!ent.skin || !ent.model)
                    649:                                {
                    650:                                        ent.skin = cl.baseclientinfo.skin;
                    651:                                        ent.model = cl.baseclientinfo.model;
                    652:                                }
                    653:                        }
                    654:                        else
                    655:                        {
                    656:                                ent.skinnum = s1->skinnum;
                    657:                                ent.skin = NULL;
                    658:                                ent.model = cl.model_draw[s1->modelindex];
                    659:                        }
                    660:                }
                    661: 
                    662:                // only used for black hole model right now, FIXME: do better
                    663:                if (renderfx == RF_TRANSLUCENT)
                    664:                        ent.alpha = 0.70;
                    665: 
                    666:                // render effects (fullbright, translucent, etc)
                    667:                if ((effects & EF_COLOR_SHELL))
                    668:                        ent.flags = 0;  // renderfx go on color shell entity
                    669:                else
                    670:                        ent.flags = renderfx;
                    671: 
                    672:                // calculate angles
                    673:                if (effects & EF_ROTATE)
                    674:                {       // some bonus items auto-rotate
                    675:                        ent.angles[0] = 0;
                    676:                        ent.angles[1] = autorotate;
                    677:                        ent.angles[2] = 0;
                    678:                }
                    679:                else
                    680:                {       // interpolate angles
                    681:                        float   a1, a2;
                    682: 
                    683:                        for (i=0 ; i<3 ; i++)
                    684:                        {
                    685:                                a1 = cent->current.angles[i];
                    686:                                a2 = cent->prev.angles[i];
                    687:                                ent.angles[i] = LerpAngle (a2, a1, cl.lerpfrac);
                    688:                        }
                    689:                }
                    690: 
                    691:                if (s1->number == cl.playernum+1)
                    692:                {
                    693:                        ent.flags |= RF_VIEWERMODEL;    // only draw from mirrors
                    694:                        // FIXME: still pass to refresh
                    695: 
                    696:                        if (effects & EF_FLAG1)
                    697:                                V_AddLight (ent.origin, 225, 1.0, 0.1, 0.1);
                    698:                        else if (effects & EF_FLAG2)
                    699:                                V_AddLight (ent.origin, 225, 0.1, 0.1, 1.0);
                    700: 
                    701:                        continue;
                    702:                }
                    703: 
                    704:                // if set to invisible, skip
                    705:                if (!s1->modelindex)
                    706:                        continue;
                    707: 
                    708:                if (effects & EF_BFG)
                    709:                {
                    710:                        ent.flags |= RF_TRANSLUCENT;
                    711:                        ent.alpha = 0.30;
                    712:                }
                    713: 
                    714:                // add to refresh list
                    715:                V_AddEntity (&ent);
                    716: 
                    717:                // color shells generate a seperate entity for the main model
                    718:                if (effects & EF_COLOR_SHELL)
                    719:                {
                    720:                        ent.flags = renderfx | RF_TRANSLUCENT;
                    721:                        ent.alpha = 0.30;
                    722:                        V_AddEntity (&ent);
                    723:                }
                    724: 
                    725:                ent.skin = NULL;                // never use a custom skin on others
                    726:                ent.skinnum = 0;
                    727:                ent.flags = 0;
                    728:                ent.alpha = 0;
                    729: 
                    730:                // duplicate for linked models
                    731:                if (s1->modelindex2)
                    732:                {
                    733:                        if (s1->modelindex2 == 255)
                    734:                        {       // custom weapon
                    735:                                ci = &cl.clientinfo[s1->skinnum];
                    736:                                ent.model = ci->weaponmodel;
                    737:                                if (!ent.model)
                    738:                                        ent.model = cl.baseclientinfo.weaponmodel;
                    739:                        }
                    740:                        else
                    741:                                ent.model = cl.model_draw[s1->modelindex2];
                    742:                        V_AddEntity (&ent);
                    743:                }
                    744:                if (s1->modelindex3)
                    745:                {
                    746:                        ent.model = cl.model_draw[s1->modelindex3];
                    747:                        V_AddEntity (&ent);
                    748:                }
                    749:                if (s1->modelindex4)
                    750:                {
                    751:                        ent.model = cl.model_draw[s1->modelindex4];
                    752:                        V_AddEntity (&ent);
                    753:                }
                    754: 
                    755:                if ( effects & EF_POWERSCREEN )
                    756:                {
                    757:                        ent.model = cl_mod_powerscreen;
                    758:                        ent.oldframe = 0;
                    759:                        ent.frame = 0;
                    760:                        ent.flags |= (RF_TRANSLUCENT | RF_SHELL_GREEN);
                    761:                        ent.alpha = 0.30;
                    762:                        V_AddEntity (&ent);
                    763:                }
                    764: 
                    765:                // add automatic particle trails
                    766:                if ( (effects&~EF_ROTATE) )
                    767:                {
                    768:                        if (effects & EF_ROCKET)
                    769:                        {
                    770:                                CL_RocketTrail (cent->lerp_origin, ent.origin, cent);
                    771:                                V_AddLight (ent.origin, 200, 1, 1, 0);
                    772:                        }
                    773:                        else if (effects & EF_BLASTER)
                    774:                        {
                    775:                                CL_BlasterTrail (cent->lerp_origin, ent.origin);
                    776:                                V_AddLight (ent.origin, 200, 1, 1, 0);
                    777:                        }
                    778:                        else if (effects & EF_HYPERBLASTER)
                    779:                        {
                    780:                                V_AddLight (ent.origin, 200, 1, 1, 0);
                    781:                        }
                    782:                        else if (effects & EF_GIB)
                    783:                        {
                    784:                                CL_DiminishingTrail (cent->lerp_origin, ent.origin, cent, effects);
                    785:                        }
                    786:                        else if (effects & EF_GRENADE)
                    787:                        {
                    788:                                CL_DiminishingTrail (cent->lerp_origin, ent.origin, cent, effects);
                    789:                        }
                    790:                        else if (effects & EF_FLIES)
                    791:                        {
                    792:                                CL_FlyEffect (cent, ent.origin);
                    793:                        }
                    794:                        else if (effects & EF_BFG)
                    795:                        {
                    796:                                static int bfg_lightramp[6] = {300, 400, 600, 300, 150, 75};
                    797: 
                    798:                                if (effects & EF_ANIM_ALLFAST)
                    799:                                {
                    800:                                        CL_BfgParticles (&ent);
                    801:                                        i = 200;
                    802:                                }
                    803:                                else
                    804:                                {
                    805:                                        i = bfg_lightramp[s1->frame];
                    806:                                }
                    807:                                V_AddLight (ent.origin, i, 0, 1, 0);
                    808:                        }
                    809:                        else if (effects & EF_FLAG1)
                    810:                        {
                    811:                                CL_FlagTrail (cent->lerp_origin, ent.origin, 242);
                    812:                                V_AddLight (ent.origin, 225, 1, 0.1, 0.1);
                    813:                        }
                    814:                        else if (effects & EF_FLAG2)
                    815:                        {
                    816:                                CL_FlagTrail (cent->lerp_origin, ent.origin, 115);
                    817:                                V_AddLight (ent.origin, 225, 0.1, 0.1, 1);
                    818:                        }
                    819:                        else if (effects & EF_GREENGIB)
                    820:                        {
                    821:                                CL_DiminishingTrail (cent->lerp_origin, ent.origin, cent, effects);                             
                    822:                        }
                    823:                        else if (effects & EF_BOOMER)
                    824:                        {
                    825:                                CL_BoomerTrail (cent->lerp_origin, ent.origin);
                    826:                                V_AddLight (ent.origin, 100, 1, 0.5, 0.5);
                    827:                        }
                    828:                }
                    829: 
                    830:                VectorCopy (ent.origin, cent->lerp_origin);
                    831:        }
                    832: }
                    833: 
                    834: 
                    835: 
                    836: /*
                    837: ==============
                    838: CL_AddViewWeapon
                    839: ==============
                    840: */
                    841: void CL_AddViewWeapon (player_state_t *ps, player_state_t *ops)
                    842: {
                    843:        entity_t        gun;            // view model
                    844:        int                     i;
                    845: 
                    846:        // allow the gun to be completely removed
                    847:        if (!cl_gun->value)
                    848:                return;
                    849: 
                    850:        // don't draw gun if in wide angle view
                    851:        if (ps->fov > 90)
                    852:                return;
                    853: 
                    854:        memset (&gun, 0, sizeof(gun));
                    855: 
                    856:        if (gun_model)
                    857:                gun.model = gun_model;  // development tool
                    858:        else
                    859:                gun.model = cl.model_draw[ps->gunindex];
                    860:        if (!gun.model)
                    861:                return;
                    862: 
                    863:        // set up gun position
                    864:        for (i=0 ; i<3 ; i++)
                    865:        {
                    866:                gun.origin[i] = cl.refdef.vieworg[i] + ops->gunoffset[i]
                    867:                        + cl.lerpfrac * (ps->gunoffset[i] - ops->gunoffset[i]);
                    868:                gun.angles[i] = cl.refdef.viewangles[i] + LerpAngle (ops->gunangles[i],
                    869:                        ps->gunangles[i], cl.lerpfrac);
                    870:        }
                    871: 
                    872:        if (gun_frame)
                    873:        {
                    874:                gun.frame = gun_frame;  // development tool
                    875:                gun.oldframe = gun_frame;       // development tool
                    876:        }
                    877:        else
                    878:        {
                    879:                gun.frame = ps->gunframe;
                    880:                if (gun.frame == 0)
                    881:                        gun.oldframe = 0;       // just changed weapons, don't lerp from old
                    882:                else
                    883:                        gun.oldframe = ops->gunframe;
                    884:        }
                    885: 
                    886:        gun.flags = RF_MINLIGHT | RF_DEPTHHACK | RF_WEAPONMODEL;
                    887:        gun.backlerp = 1.0 - cl.lerpfrac;
                    888:        VectorCopy (gun.origin, gun.oldorigin); // don't lerp at all
                    889:        V_AddEntity (&gun);
                    890: }
                    891: 
                    892: /*
                    893: ===============
                    894: CL_CalcViewValues
                    895: Sets cl.refdef view values
                    896: ===============
                    897: */
                    898: void CL_CalcViewValues (void)
                    899: {
                    900:        int                     i;
                    901:        float           lerp, backlerp;
                    902:        centity_t       *ent;
                    903:        frame_t         *oldframe;
                    904:        player_state_t  *ps, *ops;
                    905: 
                    906:        // find the previous frame to interpolate from
                    907:        ps = &cl.frame.playerstate;
                    908:        i = (cl.frame.serverframe - 1) & UPDATE_MASK;
                    909:        oldframe = &cl.frames[i];
                    910:        if (oldframe->serverframe != cl.frame.serverframe-1 || !oldframe->valid)
                    911:                oldframe = &cl.frame;           // previous frame was dropped or involid
                    912:        ops = &oldframe->playerstate;
                    913:        // see if the player entity was teleported this frame
                    914:        if ( fabs(ops->pmove.origin[0] - ps->pmove.origin[0]) > 256*8
                    915:                || abs(ops->pmove.origin[1] - ps->pmove.origin[1]) > 256*8
                    916:                || abs(ops->pmove.origin[2] - ps->pmove.origin[2]) > 256*8)
                    917:                ops = ps;               // don't interpolate
                    918: 
                    919:        ent = &cl_entities[cl.playernum+1];
                    920:        lerp = cl.lerpfrac;
                    921: 
                    922:        // calculate the origin
                    923:        if ((cl_predict->value) && !(cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION))
                    924:        {       // use predicted values
                    925:                unsigned        delta;
                    926: 
                    927:                backlerp = 1.0 - lerp;
                    928:                for (i=0 ; i<3 ; i++)
                    929:                {
                    930:                        cl.refdef.vieworg[i] = cl.predicted_origin[i] + ops->viewoffset[i] 
                    931:                                + cl.lerpfrac * (ps->viewoffset[i] - ops->viewoffset[i])
                    932:                                - backlerp * cl.prediction_error[i];
                    933:                }
                    934: 
                    935:                // smooth out stair climbing
                    936:                delta = cls.realtime - cl.predicted_step_time;
                    937:                if (delta < 100)
                    938:                        cl.refdef.vieworg[2] -= cl.predicted_step * (100 - delta) * 0.01;
                    939:        }
                    940:        else
                    941:        {       // just use interpolated values
                    942:                for (i=0 ; i<3 ; i++)
                    943:                        cl.refdef.vieworg[i] = ops->pmove.origin[i]*0.125 + ops->viewoffset[i] 
                    944:                                + lerp * (ps->pmove.origin[i]*0.125 + ps->viewoffset[i] 
                    945:                                - (ops->pmove.origin[i]*0.125 + ops->viewoffset[i]) );
                    946:        }
                    947: 
                    948:        // if not running a demo or on a locked frame, add the local angle movement
                    949:        if ( cl.frame.playerstate.pmove.pm_type < PM_DEAD )
                    950:        {       // use predicted values
                    951:                for (i=0 ; i<3 ; i++)
                    952:                        cl.refdef.viewangles[i] = cl.predicted_angles[i];
                    953:        }
                    954:        else
                    955:        {       // just use interpolated values
                    956:                for (i=0 ; i<3 ; i++)
                    957:                        cl.refdef.viewangles[i] = LerpAngle (ops->viewangles[i], ps->viewangles[i], lerp);
                    958:        }
                    959: 
                    960:        for (i=0 ; i<3 ; i++)
                    961:                cl.refdef.viewangles[i] += LerpAngle (ops->kick_angles[i], ps->kick_angles[i], lerp);
                    962:        AngleVectors (cl.refdef.viewangles, cl.v_forward, cl.v_right, cl.v_up);
                    963: 
                    964:        // interpolate field of view
                    965:        cl.refdef.fov_x = ops->fov + lerp * (ps->fov - ops->fov);
                    966:        // don't interpolate blend color
                    967:        for (i=0 ; i<4 ; i++)
                    968:                cl.refdef.blend[i] = ps->blend[i];
                    969: 
                    970:        // add the weapon
                    971:        CL_AddViewWeapon (ps, ops);
                    972: }
                    973: /*
                    974: ===============
                    975: CL_AddEntities
                    976: Emits all entities, particles, and lights to the refresh
                    977: ===============
                    978: */
                    979: void CL_AddEntities (void)
                    980: {
                    981:        if (cls.state != ca_active)
                    982:                return;
                    983:        if (cl.time > cl.frame.servertime)
                    984:        {
                    985:                if (cl_showclamp->value)
                    986:                        Com_Printf ("high clamp %i\n", cl.time - cl.frame.servertime);
                    987:                cl.time = cl.frame.servertime;
                    988:                cl.lerpfrac = 1.0;
                    989:        }
                    990:        else if (cl.time < cl.frame.servertime - 100)
                    991:        {
                    992:                if (cl_showclamp->value)
                    993:                        Com_Printf ("low clamp %i\n", cl.frame.servertime-100 - cl.time);
                    994:                cl.time = cl.frame.servertime - 100;
                    995:                cl.lerpfrac = 0;
                    996:        }
                    997:        else
                    998:                cl.lerpfrac = 1.0 - (cl.frame.servertime - cl.time) * 0.01;
                    999: 
                   1000:        if (cl_timedemo->value)
                   1001:                cl.lerpfrac = 1.0;
                   1002: 
                   1003:        CL_AddPacketEntities (&cl.frame);
                   1004:        CL_AddTEnts ();
                   1005:        CL_AddParticles ();
                   1006:        CL_AddDLights ();
                   1007:        CL_AddLightStyles ();
                   1008:        CL_CalcViewValues ();
                   1009: }
                   1010: /*
                   1011: ===============
                   1012: CL_GetEntitySoundOrigin
                   1013: Called to get the sound spatialization origin
                   1014: ===============
                   1015: */
                   1016: void CL_GetEntitySoundOrigin (int ent, vec3_t org)
                   1017: {
                   1018:        centity_t       *old;
                   1019:        if (ent < 0 || ent >= MAX_EDICTS)
                   1020:                Com_Error (ERR_DROP, "CL_GetEntitySoundOrigin: bad ent");
                   1021:        old = &cl_entities[ent];
                   1022:        VectorCopy (old->lerp_origin, org);
                   1023:        // FIXME: bmodel issues...
                   1024: }

unix.superglobalmegacorp.com

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