Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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