Annotation of quake1/cl_parse.c, revision 1.1.1.3

1.1       root        1: // cl_parse.c  -- parse a message received from the server
                      2: 
                      3: #include "quakedef.h"
                      4: 
                      5: char *svc_strings[] =
                      6: {
                      7:        "svc_bad",
                      8:        "svc_nop",
                      9:        "svc_disconnect",
                     10:        "svc_updatestat",
                     11:        "svc_version",          // [long] server version
                     12:        "svc_setview",          // [short] entity number
                     13:        "svc_sound",                    // <see code>
                     14:        "svc_time",                     // [float] server time
                     15:        "svc_print",                    // [string] null terminated string
                     16:        "svc_stufftext",                // [string] stuffed into client's console buffer
                     17:                                                // the string should be \n terminated
                     18:        "svc_setangle",         // [vec3] set the view angle to this absolute value
                     19:        
                     20:        "svc_serverinfo",               // [long] version
                     21:                                                // [string] signon string
                     22:                                                // [string]..[0]model cache [string]...[0]sounds cache
                     23:                                                // [string]..[0]item cache
                     24:        "svc_lightstyle",               // [byte] [string]
                     25:        "svc_updatename",               // [byte] [string]
                     26:        "svc_updatefrags",      // [byte] [short]
                     27:        "svc_clientdata",               // <shortbits + data>
                     28:        "svc_stopsound",                // <see code>
                     29:        "svc_updatecolors",     // [byte] [byte]
                     30:        "svc_particle",         // [vec3] <variable>
                     31:        "svc_damage",                   // [byte] impact [byte] blood [vec3] from
                     32:        
                     33:        "svc_spawnstatic",
                     34:        "OBSOLETE svc_spawnbinary",
                     35:        "svc_spawnbaseline",
                     36:        
                     37:        "svc_temp_entity",              // <variable>
                     38:        "svc_setpause",
                     39:        "svc_signonnum",
                     40:        "svc_centerprint",
                     41:        "svc_killedmonster",
                     42:        "svc_foundsecret",
                     43:        "svc_spawnstaticsound",
1.1.1.3 ! root       44:        "svc_intermission",
        !            45:        "svc_finale",                   // [string] music [string] text
        !            46:        "svc_cdtrack",                  // [byte] track [byte] looptrack
        !            47:        "svc_sellscreen",
        !            48:        "svc_cutscene"
1.1       root       49: };
                     50: 
                     51: //=============================================================================
                     52: 
                     53: /*
                     54: ===============
                     55: CL_EntityNum
                     56: 
                     57: This error checks and tracks the total number of entities
                     58: ===============
                     59: */
                     60: entity_t       *CL_EntityNum (int num)
                     61: {
                     62:        if (num >= cl.num_entities)
                     63:        {
                     64:                if (num >= MAX_EDICTS)
                     65:                        Host_Error ("CL_EntityNum: %i is an invalid number",num);
                     66:                while (cl.num_entities<=num)
                     67:                {
                     68:                        cl_entities[cl.num_entities].colormap = vid.colormap;
                     69:                        cl.num_entities++;
                     70:                }
                     71:        }
                     72:                
                     73:        return &cl_entities[num];
                     74: }
                     75: 
                     76: 
                     77: /*
                     78: ==================
                     79: CL_ParseStartSoundPacket
                     80: ==================
                     81: */
                     82: void CL_ParseStartSoundPacket(void)
                     83: {
                     84:     vec3_t  pos;
                     85:     int        channel, ent;
                     86:     int        sound_num;
                     87:     int        volume;
                     88:     int        field_mask;
                     89:     float      attenuation;  
                     90:        int             i;
                     91:                   
                     92:     field_mask = MSG_ReadByte(); 
                     93: 
                     94:     if (field_mask & SND_VOLUME)
                     95:                volume = MSG_ReadByte ();
                     96:        else
                     97:                volume = DEFAULT_SOUND_PACKET_VOLUME;
                     98:        
                     99:     if (field_mask & SND_ATTENUATION)
                    100:                attenuation = MSG_ReadByte () / 64.0;
                    101:        else
                    102:                attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
                    103:        
                    104:        channel = MSG_ReadShort ();
                    105:        sound_num = MSG_ReadByte ();
                    106: 
                    107:        ent = channel >> 3;
                    108:        channel &= 7;
                    109: 
                    110:        if (ent > MAX_EDICTS)
                    111:                Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
                    112:        
                    113:        for (i=0 ; i<3 ; i++)
                    114:                pos[i] = MSG_ReadCoord ();
                    115:  
                    116:     S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
                    117: }       
                    118: 
                    119: /*
                    120: ==================
                    121: CL_KeepaliveMessage
                    122: 
                    123: When the client is taking a long time to load stuff, send keepalive messages
                    124: so the server doesn't disconnect.
                    125: ==================
                    126: */
                    127: void CL_KeepaliveMessage (void)
                    128: {
                    129:        float   time;
                    130:        static float lastmsg;
                    131:        int             ret;
                    132:        sizebuf_t       old;
                    133:        byte            olddata[8192];
                    134:        
                    135:        if (sv.active)
                    136:                return;         // no need if server is local
                    137:        if (cls.demoplayback)
                    138:                return;
                    139: 
                    140: // read messages from server, should just be nops
                    141:        old = net_message;
                    142:        memcpy (olddata, net_message.data, net_message.cursize);
                    143:        
                    144:        do
                    145:        {
                    146:                ret = CL_GetMessage ();
                    147:                switch (ret)
                    148:                {
                    149:                default:
                    150:                        Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");               
                    151:                case 0:
                    152:                        break;  // nothing waiting
                    153:                case 1:
                    154:                        Host_Error ("CL_KeepaliveMessage: received a message");
                    155:                        break;
                    156:                case 2:
                    157:                        if (MSG_ReadByte() != svc_nop)
                    158:                                Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
                    159:                        break;
                    160:                }
                    161:        } while (ret);
                    162: 
                    163:        net_message = old;
                    164:        memcpy (net_message.data, olddata, net_message.cursize);
                    165: 
                    166: // check time
                    167:        time = Sys_FloatTime ();
                    168:        if (time - lastmsg < 5)
                    169:                return;
                    170:        lastmsg = time;
                    171: 
                    172: // write out a nop
                    173:        Con_Printf ("--> client to server keepalive\n");
                    174: 
                    175:        MSG_WriteByte (&cls.message, clc_nop);
                    176:        NET_SendMessage (cls.netcon, &cls.message);
                    177:        SZ_Clear (&cls.message);
                    178: }
                    179: 
                    180: /*
                    181: ==================
                    182: CL_ParseServerInfo
                    183: ==================
                    184: */
                    185: void CL_ParseServerInfo (void)
                    186: {
                    187:        char    *str;
                    188:        int             i;
                    189:        int             nummodels, numsounds;
                    190:        char    model_precache[MAX_MODELS][MAX_QPATH];
                    191:        char    sound_precache[MAX_SOUNDS][MAX_QPATH];
                    192:        
                    193:        Con_DPrintf ("Serverinfo packet received.\n");
                    194: //
                    195: // wipe the client_state_t struct
                    196: //
                    197:        CL_ClearState ();
                    198: 
                    199: // parse protocol version number
                    200:        i = MSG_ReadLong ();
                    201:        if (i != PROTOCOL_VERSION)
1.1.1.3 ! root      202:        {
        !           203:                Con_Printf ("Server returned version %i, not %i", i, PROTOCOL_VERSION);
        !           204:                return;
        !           205:        }
1.1       root      206: 
                    207: // parse maxclients
                    208:        cl.maxclients = MSG_ReadByte ();
1.1.1.3 ! root      209:        if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
        !           210:        {
        !           211:                Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
        !           212:                return;
        !           213:        }
1.1       root      214:        cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");
                    215: 
                    216: // parse gametype
                    217:        cl.gametype = MSG_ReadByte ();
                    218: 
                    219: // parse signon message
                    220:        str = MSG_ReadString ();
                    221:        strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
                    222: 
                    223: // seperate the printfs so the server message can have a color
                    224:        Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n");
                    225:        Con_Printf ("%c%s\n", 2, str);
                    226: 
                    227: //
                    228: // first we go through and touch all of the precache data that still
                    229: // happens to be in the cache, so precaching something else doesn't
                    230: // needlessly purge it
                    231: //
                    232: 
                    233: // precache models
                    234:        memset (cl.model_precache, 0, sizeof(cl.model_precache));
                    235:        for (nummodels=1 ; ; nummodels++)
                    236:        {
                    237:                str = MSG_ReadString ();
                    238:                if (!str[0])
                    239:                        break;
                    240:                if (nummodels==MAX_MODELS)
1.1.1.3 ! root      241:                {
        !           242:                        Con_Printf ("Server sent too many model precaches\n");
        !           243:                        return;
        !           244:                }
1.1       root      245:                strcpy (model_precache[nummodels], str);
                    246:                Mod_TouchModel (str);
                    247:        }
                    248: 
                    249: // precache sounds
                    250:        memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
                    251:        for (numsounds=1 ; ; numsounds++)
                    252:        {
                    253:                str = MSG_ReadString ();
                    254:                if (!str[0])
                    255:                        break;
                    256:                if (numsounds==MAX_SOUNDS)
1.1.1.3 ! root      257:                {
        !           258:                        Con_Printf ("Server sent too many sound precaches\n");
        !           259:                        return;
        !           260:                }
1.1       root      261:                strcpy (sound_precache[numsounds], str);
                    262:                S_TouchSound (str);
                    263:        }
                    264: 
                    265: //
                    266: // now we try to load everything else until a cache allocation fails
                    267: //
                    268:        for (i=1 ; i<nummodels ; i++)
                    269:        {
1.1.1.3 ! root      270:                cl.model_precache[i] = Mod_ForName (model_precache[i], false);
        !           271:                if (cl.model_precache[i] == NULL)
        !           272:                {
        !           273:                        Con_Printf("Model %s not found\n", model_precache[i]);
        !           274:                        return;
        !           275:                }
1.1       root      276:                CL_KeepaliveMessage ();
                    277:        }
                    278: 
1.1.1.3 ! root      279:        S_BeginPrecaching ();
1.1       root      280:        for (i=1 ; i<numsounds ; i++)
                    281:        {
                    282:                cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
                    283:                CL_KeepaliveMessage ();
                    284:        }
1.1.1.3 ! root      285:        S_EndPrecaching ();
1.1       root      286: 
                    287: 
                    288: // local state
                    289:        cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
                    290:        
                    291:        R_NewMap ();
                    292: 
                    293:        Hunk_Check ();          // make sure nothing is hurt
                    294:        
                    295:        noclip_anglehack = false;               // noclip is turned off at start        
                    296: }
                    297: 
                    298: 
                    299: /*
                    300: ==================
                    301: CL_ParseUpdate
                    302: 
                    303: Parse an entity update message from the server
                    304: If an entities model or origin changes from frame to frame, it must be
                    305: relinked.  Other attributes can change without relinking.
                    306: ==================
                    307: */
                    308: int    bitcounts[16];
                    309: 
                    310: void CL_ParseUpdate (int bits)
                    311: {
                    312:        int                     i;
                    313:        model_t         *model;
                    314:        int                     modnum;
                    315:        qboolean        forcelink;
                    316:        entity_t        *ent;
                    317:        int                     num;
                    318: 
                    319:        if (cls.signon == SIGNONS - 1)
                    320:        {       // first update is the final signon stage
                    321:                cls.signon = SIGNONS;
                    322:                CL_SignonReply ();
                    323:        }
                    324: 
                    325:        if (bits & U_MOREBITS)
                    326:        {
                    327:                i = MSG_ReadByte ();
                    328:                bits |= (i<<8);
                    329:        }
                    330: 
                    331:        if (bits & U_LONGENTITY)        
                    332:                num = MSG_ReadShort ();
                    333:        else
                    334:                num = MSG_ReadByte ();
                    335: 
                    336:        ent = CL_EntityNum (num);
                    337: 
                    338: for (i=0 ; i<16 ; i++)
                    339: if (bits&(1<<i))
                    340:        bitcounts[i]++;
                    341: 
                    342:        if (ent->msgtime != cl.mtime[1])
                    343:                forcelink = true;       // no previous frame to lerp from
                    344:        else
                    345:                forcelink = false;
                    346: 
                    347:        ent->msgtime = cl.mtime[0];
                    348:        
                    349:        if (bits & U_MODEL)
                    350:        {
                    351:                modnum = MSG_ReadByte ();
                    352:                if (modnum >= MAX_MODELS)
                    353:                        Host_Error ("CL_ParseModel: bad modnum");
                    354:        }
                    355:        else
                    356:                modnum = ent->baseline.modelindex;
                    357:                
                    358:        model = cl.model_precache[modnum];
                    359:        if (model != ent->model)
                    360:        {
                    361:                ent->model = model;
                    362:        // automatic animation (torches, etc) can be either all together
                    363:        // or randomized
                    364:                if (model)
                    365:                {
                    366:                        if (model->synctype == ST_RAND)
                    367:                                ent->syncbase = (float)(rand()&0x7fff) / 0x7fff;
                    368:                        else
                    369:                                ent->syncbase = 0.0;
                    370:                }
                    371:                else
                    372:                        forcelink = true;       // hack to make null model players work
1.1.1.3 ! root      373: #ifdef GLQUAKE
        !           374:                if (num > 0 && num <= cl.maxclients)
        !           375:                        R_TranslatePlayerSkin (num - 1);
        !           376: #endif
1.1       root      377:        }
                    378:        
                    379:        if (bits & U_FRAME)
                    380:                ent->frame = MSG_ReadByte ();
                    381:        else
                    382:                ent->frame = ent->baseline.frame;
                    383: 
                    384:        if (bits & U_COLORMAP)
                    385:                i = MSG_ReadByte();
                    386:        else
                    387:                i = ent->baseline.colormap;
                    388:        if (!i)
                    389:                ent->colormap = vid.colormap;
                    390:        else
                    391:        {
                    392:                if (i > cl.maxclients)
                    393:                        Sys_Error ("i >= cl.maxclients");
                    394:                ent->colormap = cl.scores[i-1].translations;
                    395:        }
                    396: 
                    397:        if (bits & U_SKIN)
                    398:                ent->skinnum = MSG_ReadByte();
                    399:        else
                    400:                ent->skinnum = ent->baseline.skin;
                    401: 
                    402:        if (bits & U_EFFECTS)
                    403:                ent->effects = MSG_ReadByte();
                    404:        else
                    405:                ent->effects = ent->baseline.effects;
                    406: 
                    407: // shift the known values for interpolation
                    408:        VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
                    409:        VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
                    410: 
                    411:        if (bits & U_ORIGIN1)
                    412:                ent->msg_origins[0][0] = MSG_ReadCoord ();
                    413:        else
                    414:                ent->msg_origins[0][0] = ent->baseline.origin[0];
                    415:        if (bits & U_ANGLE1)
                    416:                ent->msg_angles[0][0] = MSG_ReadAngle();
                    417:        else
                    418:                ent->msg_angles[0][0] = ent->baseline.angles[0];
                    419: 
                    420:        if (bits & U_ORIGIN2)
                    421:                ent->msg_origins[0][1] = MSG_ReadCoord ();
                    422:        else
                    423:                ent->msg_origins[0][1] = ent->baseline.origin[1];
                    424:        if (bits & U_ANGLE2)
                    425:                ent->msg_angles[0][1] = MSG_ReadAngle();
                    426:        else
                    427:                ent->msg_angles[0][1] = ent->baseline.angles[1];
                    428: 
                    429:        if (bits & U_ORIGIN3)
                    430:                ent->msg_origins[0][2] = MSG_ReadCoord ();
                    431:        else
                    432:                ent->msg_origins[0][2] = ent->baseline.origin[2];
                    433:        if (bits & U_ANGLE3)
                    434:                ent->msg_angles[0][2] = MSG_ReadAngle();
                    435:        else
                    436:                ent->msg_angles[0][2] = ent->baseline.angles[2];
                    437: 
                    438:        if ( bits & U_NOLERP )
                    439:                ent->forcelink = true;
                    440: 
                    441:        if ( forcelink )
                    442:        {       // didn't have an update last message
                    443:                VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
                    444:                VectorCopy (ent->msg_origins[0], ent->origin);
                    445:                VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
                    446:                VectorCopy (ent->msg_angles[0], ent->angles);
                    447:                ent->forcelink = true;
                    448:        }
                    449: }
                    450: 
                    451: /*
                    452: ==================
                    453: CL_ParseBaseline
                    454: ==================
                    455: */
                    456: void CL_ParseBaseline (entity_t *ent)
                    457: {
                    458:        int                     i;
                    459:        
                    460:        ent->baseline.modelindex = MSG_ReadByte ();
                    461:        ent->baseline.frame = MSG_ReadByte ();
                    462:        ent->baseline.colormap = MSG_ReadByte();
                    463:        ent->baseline.skin = MSG_ReadByte();
                    464:        for (i=0 ; i<3 ; i++)
                    465:        {
                    466:                ent->baseline.origin[i] = MSG_ReadCoord ();
                    467:                ent->baseline.angles[i] = MSG_ReadAngle ();
                    468:        }
                    469: }
                    470: 
                    471: 
                    472: /*
                    473: ==================
                    474: CL_ParseClientdata
                    475: 
                    476: Server information pertaining to this client only
                    477: ==================
                    478: */
                    479: void CL_ParseClientdata (int bits)
                    480: {
                    481:        int             i, j;
                    482:        
                    483:        if (bits & SU_VIEWHEIGHT)
                    484:                cl.viewheight = MSG_ReadChar ();
                    485:        else
                    486:                cl.viewheight = DEFAULT_VIEWHEIGHT;
                    487: 
                    488:        if (bits & SU_IDEALPITCH)
                    489:                cl.idealpitch = MSG_ReadChar ();
                    490:        else
                    491:                cl.idealpitch = 0;
                    492:        
                    493:        VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
                    494:        for (i=0 ; i<3 ; i++)
                    495:        {
                    496:                if (bits & (SU_PUNCH1<<i) )
                    497:                        cl.punchangle[i] = MSG_ReadChar();
                    498:                else
                    499:                        cl.punchangle[i] = 0;
                    500:                if (bits & (SU_VELOCITY1<<i) )
                    501:                        cl.mvelocity[0][i] = MSG_ReadChar()*16;
                    502:                else
                    503:                        cl.mvelocity[0][i] = 0;
                    504:        }
                    505: 
1.1.1.3 ! root      506: // [always sent]       if (bits & SU_ITEMS)
1.1       root      507:                i = MSG_ReadLong ();
1.1.1.3 ! root      508: 
1.1       root      509:        if (cl.items != i)
                    510:        {       // set flash times
                    511:                Sbar_Changed ();
                    512:                for (j=0 ; j<32 ; j++)
                    513:                        if ( (i & (1<<j)) && !(cl.items & (1<<j)))
                    514:                                cl.item_gettime[j] = cl.time;
                    515:                cl.items = i;
                    516:        }
                    517:                
                    518:        cl.onground = (bits & SU_ONGROUND) != 0;
                    519:        cl.inwater = (bits & SU_INWATER) != 0;
                    520: 
                    521:        if (bits & SU_WEAPONFRAME)
                    522:                cl.stats[STAT_WEAPONFRAME] = MSG_ReadByte ();
                    523:        else
                    524:                cl.stats[STAT_WEAPONFRAME] = 0;
                    525: 
                    526:        if (bits & SU_ARMOR)
                    527:                i = MSG_ReadByte ();
                    528:        else
                    529:                i = 0;
                    530:        if (cl.stats[STAT_ARMOR] != i)
                    531:        {
                    532:                cl.stats[STAT_ARMOR] = i;
                    533:                Sbar_Changed ();
                    534:        }
                    535: 
                    536:        if (bits & SU_WEAPON)
                    537:                i = MSG_ReadByte ();
                    538:        else
                    539:                i = 0;
                    540:        if (cl.stats[STAT_WEAPON] != i)
                    541:        {
                    542:                cl.stats[STAT_WEAPON] = i;
                    543:                Sbar_Changed ();
                    544:        }
                    545:        
                    546:        i = MSG_ReadShort ();
                    547:        if (cl.stats[STAT_HEALTH] != i)
                    548:        {
                    549:                cl.stats[STAT_HEALTH] = i;
                    550:                Sbar_Changed ();
                    551:        }
                    552: 
                    553:        i = MSG_ReadByte ();
                    554:        if (cl.stats[STAT_AMMO] != i)
                    555:        {
                    556:                cl.stats[STAT_AMMO] = i;
                    557:                Sbar_Changed ();
                    558:        }
                    559: 
                    560:        for (i=0 ; i<4 ; i++)
                    561:        {
                    562:                j = MSG_ReadByte ();
                    563:                if (cl.stats[STAT_SHELLS+i] != j)
                    564:                {
                    565:                        cl.stats[STAT_SHELLS+i] = j;
                    566:                        Sbar_Changed ();
                    567:                }
                    568:        }
                    569: 
                    570:        i = MSG_ReadByte ();
1.1.1.3 ! root      571: 
        !           572:        if (standard_quake)
1.1       root      573:        {
1.1.1.3 ! root      574:                if (cl.stats[STAT_ACTIVEWEAPON] != i)
        !           575:                {
        !           576:                        cl.stats[STAT_ACTIVEWEAPON] = i;
        !           577:                        Sbar_Changed ();
        !           578:                }
        !           579:        }
        !           580:        else
        !           581:        {
        !           582:                if (cl.stats[STAT_ACTIVEWEAPON] != (1<<i))
        !           583:                {
        !           584:                        cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
        !           585:                        Sbar_Changed ();
        !           586:                }
1.1       root      587:        }
                    588: }
                    589: 
                    590: /*
                    591: =====================
                    592: CL_NewTranslation
                    593: =====================
                    594: */
                    595: void CL_NewTranslation (int slot)
                    596: {
                    597:        int             i, j;
                    598:        int             top, bottom;
                    599:        byte    *dest, *source;
                    600:        
                    601:        if (slot > cl.maxclients)
                    602:                Sys_Error ("CL_NewTranslation: slot > cl.maxclients");
                    603:        dest = cl.scores[slot].translations;
                    604:        source = vid.colormap;
                    605:        memcpy (dest, vid.colormap, sizeof(cl.scores[slot].translations));
                    606:        top = cl.scores[slot].colors & 0xf0;
                    607:        bottom = (cl.scores[slot].colors &15)<<4;
1.1.1.3 ! root      608: #ifdef GLQUAKE
        !           609:        R_TranslatePlayerSkin (slot);
        !           610: #endif
1.1       root      611: 
                    612:        for (i=0 ; i<VID_GRADES ; i++, dest += 256, source+=256)
                    613:        {
                    614:                if (top < 128)  // the artists made some backwards ranges.  sigh.
                    615:                        memcpy (dest + TOP_RANGE, source + top, 16);
                    616:                else
                    617:                        for (j=0 ; j<16 ; j++)
                    618:                                dest[TOP_RANGE+j] = source[top+15-j];
                    619:                                
                    620:                if (bottom < 128)
                    621:                        memcpy (dest + BOTTOM_RANGE, source + bottom, 16);
                    622:                else
                    623:                        for (j=0 ; j<16 ; j++)
                    624:                                dest[BOTTOM_RANGE+j] = source[bottom+15-j];             
                    625:        }
                    626: }
                    627: 
                    628: /*
                    629: =====================
                    630: CL_ParseStatic
                    631: =====================
                    632: */
                    633: void CL_ParseStatic (void)
                    634: {
                    635:        entity_t *ent;
                    636:        int             i;
                    637:                
                    638:        i = cl.num_statics;
                    639:        if (i >= MAX_STATIC_ENTITIES)
                    640:                Host_Error ("Too many static entities");
                    641:        ent = &cl_static_entities[i];
                    642:        cl.num_statics++;
                    643:        CL_ParseBaseline (ent);
                    644: 
                    645: // copy it to the current state
                    646:        ent->model = cl.model_precache[ent->baseline.modelindex];
                    647:        ent->frame = ent->baseline.frame;
                    648:        ent->colormap = vid.colormap;
                    649:        ent->skinnum = ent->baseline.skin;
                    650:        ent->effects = ent->baseline.effects;
                    651: 
                    652:        VectorCopy (ent->baseline.origin, ent->origin);
                    653:        VectorCopy (ent->baseline.angles, ent->angles); 
                    654:        R_AddEfrags (ent);
                    655: }
                    656: 
                    657: /*
                    658: ===================
                    659: CL_ParseStaticSound
                    660: ===================
                    661: */
                    662: void CL_ParseStaticSound (void)
                    663: {
                    664:        vec3_t          org;
                    665:        int                     sound_num, vol, atten;
                    666:        int                     i;
                    667:        
                    668:        for (i=0 ; i<3 ; i++)
                    669:                org[i] = MSG_ReadCoord ();
                    670:        sound_num = MSG_ReadByte ();
                    671:        vol = MSG_ReadByte ();
                    672:        atten = MSG_ReadByte ();
                    673:        
                    674:        S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
                    675: }
                    676: 
                    677: 
                    678: #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
                    679: 
                    680: /*
                    681: =====================
                    682: CL_ParseServerMessage
                    683: =====================
                    684: */
                    685: void CL_ParseServerMessage (void)
                    686: {
                    687:        int                     cmd;
                    688:        int                     i;
                    689:        
                    690: //
                    691: // if recording demos, copy the message out
                    692: //
                    693:        if (cl_shownet.value == 1)
                    694:                Con_Printf ("%i ",net_message.cursize);
                    695:        else if (cl_shownet.value == 2)
                    696:                Con_Printf ("------------------\n");
                    697:        
                    698:        cl.onground = false;    // unless the server says otherwise     
                    699: //
                    700: // parse the message
                    701: //
                    702:        MSG_BeginReading ();
                    703:        
                    704:        while (1)
                    705:        {
                    706:                if (msg_badread)
                    707:                        Host_Error ("CL_ParseServerMessage: Bad server message");
                    708: 
                    709:                cmd = MSG_ReadByte ();
                    710: 
                    711:                if (cmd == -1)
                    712:                {
                    713:                        SHOWNET("END OF MESSAGE");
                    714:                        return;         // end of message
                    715:                }
                    716: 
                    717:        // if the high bit of the command byte is set, it is a fast update
                    718:                if (cmd & 128)
                    719:                {
                    720:                        SHOWNET("fast update");
                    721:                        CL_ParseUpdate (cmd&127);
                    722:                        continue;
                    723:                }
                    724: 
                    725:                SHOWNET(svc_strings[cmd]);
                    726:        
                    727:        // other commands
                    728:                switch (cmd)
                    729:                {
                    730:                default:
                    731:                        Host_Error ("CL_ParseServerMessage: Illegible server message\n");
                    732:                        break;
                    733:                        
                    734:                case svc_nop:
                    735: //                     Con_Printf ("svc_nop\n");
                    736:                        break;
                    737:                        
                    738:                case svc_time:
                    739:                        cl.mtime[1] = cl.mtime[0];
                    740:                        cl.mtime[0] = MSG_ReadFloat ();                 
                    741:                        break;
                    742:                        
                    743:                case svc_clientdata:
                    744:                        i = MSG_ReadShort ();
                    745:                        CL_ParseClientdata (i);
                    746:                        break;
                    747:                
                    748:                case svc_version:
                    749:                        i = MSG_ReadLong ();
                    750:                        if (i != PROTOCOL_VERSION)
                    751:                                Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, PROTOCOL_VERSION);
                    752:                        break;
                    753:                        
                    754:                case svc_disconnect:
                    755:                        Host_EndGame ("Server disconnected\n");
                    756: 
                    757:                case svc_print:
1.1.1.3 ! root      758:                        Con_Printf ("%s", MSG_ReadString ());
1.1       root      759:                        break;
                    760:                        
                    761:                case svc_centerprint:
                    762:                        SCR_CenterPrint (MSG_ReadString ());
                    763:                        break;
                    764:                        
                    765:                case svc_stufftext:
                    766:                        Cbuf_AddText (MSG_ReadString ());
                    767:                        break;
                    768:                        
                    769:                case svc_damage:
                    770:                        V_ParseDamage ();
                    771:                        break;
                    772:                        
                    773:                case svc_serverinfo:
                    774:                        CL_ParseServerInfo ();
                    775:                        vid.recalc_refdef = true;       // leave intermission full screen
                    776:                        break;
                    777:                        
                    778:                case svc_setangle:
                    779:                        for (i=0 ; i<3 ; i++)
                    780:                                cl.viewangles[i] = MSG_ReadAngle ();
                    781:                        break;
                    782:                        
                    783:                case svc_setview:
                    784:                        cl.viewentity = MSG_ReadShort ();
                    785:                        break;
                    786:                                        
                    787:                case svc_lightstyle:
                    788:                        i = MSG_ReadByte ();
                    789:                        if (i >= MAX_LIGHTSTYLES)
                    790:                                Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
                    791:                        Q_strcpy (cl_lightstyle[i].map,  MSG_ReadString());
                    792:                        cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map);
                    793:                        break;
                    794:                        
                    795:                case svc_sound:
                    796:                        CL_ParseStartSoundPacket();
                    797:                        break;
                    798:                        
                    799:                case svc_stopsound:
                    800:                        i = MSG_ReadShort();
                    801:                        S_StopSound(i>>3, i&7);
                    802:                        break;
                    803:                
                    804:                case svc_updatename:
                    805:                        Sbar_Changed ();
                    806:                        i = MSG_ReadByte ();
                    807:                        if (i >= cl.maxclients)
                    808:                                Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD");
                    809:                        strcpy (cl.scores[i].name, MSG_ReadString ());
                    810:                        break;
                    811:                        
                    812:                case svc_updatefrags:
                    813:                        Sbar_Changed ();
                    814:                        i = MSG_ReadByte ();
                    815:                        if (i >= cl.maxclients)
                    816:                                Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD");
                    817:                        cl.scores[i].frags = MSG_ReadShort ();
                    818:                        break;                  
                    819: 
                    820:                case svc_updatecolors:
                    821:                        Sbar_Changed ();
                    822:                        i = MSG_ReadByte ();
                    823:                        if (i >= cl.maxclients)
                    824:                                Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD");
                    825:                        cl.scores[i].colors = MSG_ReadByte ();
                    826:                        CL_NewTranslation (i);
                    827:                        break;
                    828:                        
                    829:                case svc_particle:
                    830:                        R_ParseParticleEffect ();
                    831:                        break;
                    832: 
                    833:                case svc_spawnbaseline:
                    834:                        i = MSG_ReadShort ();
                    835:                        // must use CL_EntityNum() to force cl.num_entities up
                    836:                        CL_ParseBaseline (CL_EntityNum(i));
                    837:                        break;
                    838:                case svc_spawnstatic:
                    839:                        CL_ParseStatic ();
                    840:                        break;                  
                    841:                case svc_temp_entity:
                    842:                        CL_ParseTEnt ();
                    843:                        break;
                    844: 
                    845:                case svc_setpause:
1.1.1.3 ! root      846:                        {
        !           847:                                cl.paused = MSG_ReadByte ();
        !           848: 
        !           849:                                if (cl.paused)
        !           850:                                {
        !           851:                                        CDAudio_Pause ();
        !           852: #ifdef _WIN32
        !           853:                                        VID_HandlePause (true);
        !           854: #endif
        !           855:                                }
        !           856:                                else
        !           857:                                {
        !           858:                                        CDAudio_Resume ();
        !           859: #ifdef _WIN32
        !           860:                                        VID_HandlePause (false);
        !           861: #endif
        !           862:                                }
        !           863:                        }
1.1       root      864:                        break;
                    865:                        
                    866:                case svc_signonnum:
                    867:                        i = MSG_ReadByte ();
                    868:                        if (i <= cls.signon)
                    869:                                Host_Error ("Received signon %i when at %i", i, cls.signon);
                    870:                        cls.signon = i;
                    871:                        CL_SignonReply ();
                    872:                        break;
                    873: 
                    874:                case svc_killedmonster:
                    875:                        cl.stats[STAT_MONSTERS]++;
                    876:                        break;
                    877: 
                    878:                case svc_foundsecret:
                    879:                        cl.stats[STAT_SECRETS]++;
                    880:                        break;
                    881: 
                    882:                case svc_updatestat:
                    883:                        i = MSG_ReadByte ();
                    884:                        if (i < 0 || i >= MAX_CL_STATS)
                    885:                                Sys_Error ("svc_updatestat: %i is invalid", i);
                    886:                        cl.stats[i] = MSG_ReadLong ();;
                    887:                        break;
                    888:                        
                    889:                case svc_spawnstaticsound:
                    890:                        CL_ParseStaticSound ();
                    891:                        break;
                    892: 
                    893:                case svc_cdtrack:
                    894:                        cl.cdtrack = MSG_ReadByte ();
                    895:                        cl.looptrack = MSG_ReadByte ();
                    896:                        if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
                    897:                                CDAudio_Play ((byte)cls.forcetrack, true);
                    898:                        else
                    899:                                CDAudio_Play ((byte)cl.cdtrack, true);
                    900:                        break;
                    901: 
                    902:                case svc_intermission:
                    903:                        cl.intermission = 1;
                    904:                        cl.completed_time = cl.time;
                    905:                        vid.recalc_refdef = true;       // go to full screen
                    906:                        break;
                    907: 
                    908:                case svc_finale:
                    909:                        cl.intermission = 2;
                    910:                        cl.completed_time = cl.time;
                    911:                        vid.recalc_refdef = true;       // go to full screen
                    912:                        SCR_CenterPrint (MSG_ReadString ());                    
                    913:                        break;
1.1.1.3 ! root      914: 
        !           915:                case svc_cutscene:
        !           916:                        cl.intermission = 3;
        !           917:                        cl.completed_time = cl.time;
        !           918:                        vid.recalc_refdef = true;       // go to full screen
        !           919:                        SCR_CenterPrint (MSG_ReadString ());                    
        !           920:                        break;
        !           921: 
1.1       root      922:                case svc_sellscreen:
                    923:                        Cmd_ExecuteString ("help", src_command);
                    924:                        break;
                    925:                }
                    926:        }
                    927: }
                    928: 

unix.superglobalmegacorp.com

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