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

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

unix.superglobalmegacorp.com

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