summaryrefslogtreecommitdiff
path: root/samples/quake/jni/cl_parse.cpp
diff options
context:
space:
mode:
authorShih-wei Liao <sliao@google.com>2011-07-21 01:05:25 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-07-21 01:05:25 -0700
commitb2080cd3e724758f3437c210c04d65a413ea7f15 (patch)
treea4e48c07b9433601572c6150612ecc5e6be86c1a /samples/quake/jni/cl_parse.cpp
parent48e07cb728f03175b7668108d8eab22ea808f18d (diff)
parentdc9c7edca5025d2c3796c2ef587284c10d321fe4 (diff)
downloadgdk-b2080cd3e724758f3437c210c04d65a413ea7f15.tar.gz
Merge "Adding samples/quake; misc scripts fixes. Fixed trailing whitespace and tab as requrested."
Diffstat (limited to 'samples/quake/jni/cl_parse.cpp')
-rw-r--r--samples/quake/jni/cl_parse.cpp963
1 files changed, 963 insertions, 0 deletions
diff --git a/samples/quake/jni/cl_parse.cpp b/samples/quake/jni/cl_parse.cpp
new file mode 100644
index 0000000..68d72f2
--- /dev/null
+++ b/samples/quake/jni/cl_parse.cpp
@@ -0,0 +1,963 @@
+/*
+Copyright (C) 1996-1997 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+// cl_parse.c -- parse a message received from the server
+
+#include "quakedef.h"
+
+const char *svc_strings[] =
+{
+ "svc_bad",
+ "svc_nop",
+ "svc_disconnect",
+ "svc_updatestat",
+ "svc_version", // [long] server version
+ "svc_setview", // [short] entity number
+ "svc_sound", // <see code>
+ "svc_time", // [float] server time
+ "svc_print", // [string] null terminated string
+ "svc_stufftext", // [string] stuffed into client's console buffer
+ // the string should be \n terminated
+ "svc_setangle", // [vec3] set the view angle to this absolute value
+
+ "svc_serverinfo", // [long] version
+ // [string] signon string
+ // [string]..[0]model cache [string]...[0]sounds cache
+ // [string]..[0]item cache
+ "svc_lightstyle", // [byte] [string]
+ "svc_updatename", // [byte] [string]
+ "svc_updatefrags", // [byte] [short]
+ "svc_clientdata", // <shortbits + data>
+ "svc_stopsound", // <see code>
+ "svc_updatecolors", // [byte] [byte]
+ "svc_particle", // [vec3] <variable>
+ "svc_damage", // [byte] impact [byte] blood [vec3] from
+
+ "svc_spawnstatic",
+ "OBSOLETE svc_spawnbinary",
+ "svc_spawnbaseline",
+
+ "svc_temp_entity", // <variable>
+ "svc_setpause",
+ "svc_signonnum",
+ "svc_centerprint",
+ "svc_killedmonster",
+ "svc_foundsecret",
+ "svc_spawnstaticsound",
+ "svc_intermission",
+ "svc_finale", // [string] music [string] text
+ "svc_cdtrack", // [byte] track [byte] looptrack
+ "svc_sellscreen",
+ "svc_cutscene"
+};
+
+//=============================================================================
+
+/*
+===============
+CL_EntityNum
+
+This error checks and tracks the total number of entities
+===============
+*/
+entity_t *CL_EntityNum (int num)
+{
+ if (num >= cl.num_entities)
+ {
+ if (num >= MAX_EDICTS)
+ Host_Error ("CL_EntityNum: %i is an invalid number",num);
+ while (cl.num_entities<=num)
+ {
+ cl_entities[cl.num_entities].colormap = vid.colormap;
+ cl.num_entities++;
+ }
+ }
+
+ return &cl_entities[num];
+}
+
+
+/*
+==================
+CL_ParseStartSoundPacket
+==================
+*/
+void CL_ParseStartSoundPacket(void)
+{
+ vec3_t pos;
+ int channel, ent;
+ int sound_num;
+ int volume;
+ int field_mask;
+ float attenuation;
+ int i;
+
+ field_mask = MSG_ReadByte();
+
+ if (field_mask & SND_VOLUME)
+ volume = MSG_ReadByte ();
+ else
+ volume = DEFAULT_SOUND_PACKET_VOLUME;
+
+ if (field_mask & SND_ATTENUATION)
+ attenuation = MSG_ReadByte () / 64.0;
+ else
+ attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
+
+ channel = MSG_ReadShort ();
+ sound_num = MSG_ReadByte ();
+
+ ent = channel >> 3;
+ channel &= 7;
+
+ if (ent > MAX_EDICTS)
+ Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
+
+ for (i=0 ; i<3 ; i++)
+ pos[i] = MSG_ReadCoord ();
+
+ S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
+}
+
+/*
+==================
+CL_KeepaliveMessage
+
+When the client is taking a long time to load stuff, send keepalive messages
+so the server doesn't disconnect.
+==================
+*/
+void CL_KeepaliveMessage (void)
+{
+ float time;
+ static float lastmsg;
+ int ret;
+ sizebuf_t old;
+ byte olddata[8192];
+
+ if (sv.active)
+ return; // no need if server is local
+ if (cls.demoplayback)
+ return;
+
+// read messages from server, should just be nops
+ old = net_message;
+ memcpy (olddata, net_message.data, net_message.cursize);
+
+ do
+ {
+ ret = CL_GetMessage ();
+ switch (ret)
+ {
+ default:
+ Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
+ case 0:
+ break; // nothing waiting
+ case 1:
+ Host_Error ("CL_KeepaliveMessage: received a message");
+ break;
+ case 2:
+ if (MSG_ReadByte() != svc_nop)
+ Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
+ break;
+ }
+ } while (ret);
+
+ net_message = old;
+ memcpy (net_message.data, olddata, net_message.cursize);
+
+// check time
+ time = Sys_FloatTime ();
+ if (time - lastmsg < 5)
+ return;
+ lastmsg = time;
+
+// write out a nop
+ Con_Printf ("--> client to server keepalive\n");
+
+ MSG_WriteByte (&cls.message, clc_nop);
+ NET_SendMessage (cls.netcon, &cls.message);
+ SZ_Clear (&cls.message);
+}
+
+/*
+==================
+CL_ParseServerInfo
+==================
+*/
+void CL_ParseServerInfo (void)
+{
+ char *str;
+ int i;
+ int nummodels, numsounds;
+ char model_precache[MAX_MODELS][MAX_QPATH];
+ char sound_precache[MAX_SOUNDS][MAX_QPATH];
+
+ Con_DPrintf ("Serverinfo packet received.\n");
+//
+// wipe the client_state_t struct
+//
+ CL_ClearState ();
+
+// parse protocol version number
+ i = MSG_ReadLong ();
+ if (i != PROTOCOL_VERSION)
+ {
+ Con_Printf ("Server returned version %i, not %i", i, PROTOCOL_VERSION);
+ return;
+ }
+
+// parse maxclients
+ cl.maxclients = MSG_ReadByte ();
+ if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
+ {
+ Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
+ return;
+ }
+ cl.scores = (scoreboard_t*) Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");
+
+// parse gametype
+ cl.gametype = MSG_ReadByte ();
+
+// parse signon message
+ str = MSG_ReadString ();
+ strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
+
+// seperate the printfs so the server message can have a color
+ 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");
+ Con_Printf ("%c%s\n", 2, str);
+
+//
+// first we go through and touch all of the precache data that still
+// happens to be in the cache, so precaching something else doesn't
+// needlessly purge it
+//
+
+// precache models
+ memset (cl.model_precache, 0, sizeof(cl.model_precache));
+ for (nummodels=1 ; ; nummodels++)
+ {
+ str = MSG_ReadString ();
+ if (!str[0])
+ break;
+ if (nummodels==MAX_MODELS)
+ {
+ Con_Printf ("Server sent too many model precaches\n");
+ return;
+ }
+ strcpy (model_precache[nummodels], str);
+ Mod_TouchModel (str);
+ }
+
+// precache sounds
+ memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
+ for (numsounds=1 ; ; numsounds++)
+ {
+ str = MSG_ReadString ();
+ if (!str[0])
+ break;
+ if (numsounds==MAX_SOUNDS)
+ {
+ Con_Printf ("Server sent too many sound precaches\n");
+ return;
+ }
+ strcpy (sound_precache[numsounds], str);
+ S_TouchSound (str);
+ }
+
+//
+// now we try to load everything else until a cache allocation fails
+//
+
+ for (i=1 ; i<nummodels ; i++)
+ {
+ cl.model_precache[i] = Mod_ForName (model_precache[i], false);
+ if (cl.model_precache[i] == NULL)
+ {
+ Con_Printf("Model %s not found\n", model_precache[i]);
+ return;
+ }
+ CL_KeepaliveMessage ();
+ }
+
+ S_BeginPrecaching ();
+ for (i=1 ; i<numsounds ; i++)
+ {
+ cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
+ CL_KeepaliveMessage ();
+ }
+ S_EndPrecaching ();
+
+
+// local state
+ cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
+
+ R_NewMap ();
+
+ Hunk_Check (); // make sure nothing is hurt
+
+ noclip_anglehack = false; // noclip is turned off at start
+}
+
+
+/*
+==================
+CL_ParseUpdate
+
+Parse an entity update message from the server
+If an entities model or origin changes from frame to frame, it must be
+relinked. Other attributes can change without relinking.
+==================
+*/
+int bitcounts[16];
+
+void CL_ParseUpdate (int bits)
+{
+ int i;
+ model_t *model;
+ int modnum;
+ qboolean forcelink;
+ entity_t *ent;
+ int num;
+ int skin;
+
+ if (cls.signon == SIGNONS - 1)
+ { // first update is the final signon stage
+ cls.signon = SIGNONS;
+ CL_SignonReply ();
+ }
+
+ if (bits & U_MOREBITS)
+ {
+ i = MSG_ReadByte ();
+ bits |= (i<<8);
+ }
+
+ if (bits & U_LONGENTITY)
+ num = MSG_ReadShort ();
+ else
+ num = MSG_ReadByte ();
+
+ ent = CL_EntityNum (num);
+
+for (i=0 ; i<16 ; i++)
+if (bits&(1<<i))
+ bitcounts[i]++;
+
+ if (ent->msgtime != cl.mtime[1])
+ forcelink = true; // no previous frame to lerp from
+ else
+ forcelink = false;
+
+ ent->msgtime = cl.mtime[0];
+
+ if (bits & U_MODEL)
+ {
+ modnum = MSG_ReadByte ();
+ if (modnum >= MAX_MODELS)
+ Host_Error ("CL_ParseModel: bad modnum");
+ }
+ else
+ modnum = ent->baseline.modelindex;
+
+ model = cl.model_precache[modnum];
+ if (model != ent->model)
+ {
+ ent->model = model;
+ // automatic animation (torches, etc) can be either all together
+ // or randomized
+ if (model)
+ {
+ if (model->synctype == ST_RAND)
+ ent->syncbase = (float)(rand()&0x7fff) / 0x7fff;
+ else
+ ent->syncbase = 0.0;
+ }
+ else
+ forcelink = true; // hack to make null model players work
+#ifdef GLQUAKE
+ if (num > 0 && num <= cl.maxclients)
+ R_TranslatePlayerSkin (num - 1);
+#endif
+ }
+
+ if (bits & U_FRAME)
+ ent->frame = MSG_ReadByte ();
+ else
+ ent->frame = ent->baseline.frame;
+
+ if (bits & U_COLORMAP)
+ i = MSG_ReadByte();
+ else
+ i = ent->baseline.colormap;
+ if (!i)
+ ent->colormap = vid.colormap;
+ else
+ {
+ if (i > cl.maxclients)
+ Sys_Error ("i >= cl.maxclients");
+ ent->colormap = cl.scores[i-1].translations;
+ }
+
+#ifdef GLQUAKE
+ if (bits & U_SKIN)
+ skin = MSG_ReadByte();
+ else
+ skin = ent->baseline.skin;
+ if (skin != ent->skinnum) {
+ ent->skinnum = skin;
+ if (num > 0 && num <= cl.maxclients)
+ R_TranslatePlayerSkin (num - 1);
+ }
+
+#else
+
+ if (bits & U_SKIN)
+ ent->skinnum = MSG_ReadByte();
+ else
+ ent->skinnum = ent->baseline.skin;
+#endif
+
+ if (bits & U_EFFECTS)
+ ent->effects = MSG_ReadByte();
+ else
+ ent->effects = ent->baseline.effects;
+
+// shift the known values for interpolation
+ VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
+ VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
+
+ if (bits & U_ORIGIN1)
+ ent->msg_origins[0][0] = MSG_ReadCoord ();
+ else
+ ent->msg_origins[0][0] = ent->baseline.origin[0];
+ if (bits & U_ANGLE1)
+ ent->msg_angles[0][0] = MSG_ReadAngle();
+ else
+ ent->msg_angles[0][0] = ent->baseline.angles[0];
+
+ if (bits & U_ORIGIN2)
+ ent->msg_origins[0][1] = MSG_ReadCoord ();
+ else
+ ent->msg_origins[0][1] = ent->baseline.origin[1];
+ if (bits & U_ANGLE2)
+ ent->msg_angles[0][1] = MSG_ReadAngle();
+ else
+ ent->msg_angles[0][1] = ent->baseline.angles[1];
+
+ if (bits & U_ORIGIN3)
+ ent->msg_origins[0][2] = MSG_ReadCoord ();
+ else
+ ent->msg_origins[0][2] = ent->baseline.origin[2];
+ if (bits & U_ANGLE3)
+ ent->msg_angles[0][2] = MSG_ReadAngle();
+ else
+ ent->msg_angles[0][2] = ent->baseline.angles[2];
+
+ if ( bits & U_NOLERP )
+ ent->forcelink = true;
+
+ if ( forcelink )
+ { // didn't have an update last message
+ VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
+ VectorCopy (ent->msg_origins[0], ent->origin);
+ VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
+ VectorCopy (ent->msg_angles[0], ent->angles);
+ ent->forcelink = true;
+ }
+}
+
+/*
+==================
+CL_ParseBaseline
+==================
+*/
+void CL_ParseBaseline (entity_t *ent)
+{
+ int i;
+
+ ent->baseline.modelindex = MSG_ReadByte ();
+ ent->baseline.frame = MSG_ReadByte ();
+ ent->baseline.colormap = MSG_ReadByte();
+ ent->baseline.skin = MSG_ReadByte();
+ for (i=0 ; i<3 ; i++)
+ {
+ ent->baseline.origin[i] = MSG_ReadCoord ();
+ ent->baseline.angles[i] = MSG_ReadAngle ();
+ }
+}
+
+
+/*
+==================
+CL_ParseClientdata
+
+Server information pertaining to this client only
+==================
+*/
+void CL_ParseClientdata (int bits)
+{
+ int i, j;
+
+ if (bits & SU_VIEWHEIGHT)
+ cl.viewheight = MSG_ReadChar ();
+ else
+ cl.viewheight = DEFAULT_VIEWHEIGHT;
+
+ if (bits & SU_IDEALPITCH)
+ cl.idealpitch = MSG_ReadChar ();
+ else
+ cl.idealpitch = 0;
+
+ VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
+ for (i=0 ; i<3 ; i++)
+ {
+ if (bits & (SU_PUNCH1<<i) )
+ cl.punchangle[i] = MSG_ReadChar();
+ else
+ cl.punchangle[i] = 0;
+ if (bits & (SU_VELOCITY1<<i) )
+ cl.mvelocity[0][i] = MSG_ReadChar()*16;
+ else
+ cl.mvelocity[0][i] = 0;
+ }
+
+// [always sent] if (bits & SU_ITEMS)
+ i = MSG_ReadLong ();
+
+ if (cl.items != i)
+ { // set flash times
+ Sbar_Changed ();
+ for (j=0 ; j<32 ; j++)
+ if ( (i & (1<<j)) && !(cl.items & (1<<j)))
+ cl.item_gettime[j] = cl.time;
+ cl.items = i;
+ }
+
+ cl.onground = (bits & SU_ONGROUND) != 0;
+ cl.inwater = (bits & SU_INWATER) != 0;
+
+ if (bits & SU_WEAPONFRAME)
+ cl.stats[STAT_WEAPONFRAME] = MSG_ReadByte ();
+ else
+ cl.stats[STAT_WEAPONFRAME] = 0;
+
+ if (bits & SU_ARMOR)
+ i = MSG_ReadByte ();
+ else
+ i = 0;
+ if (cl.stats[STAT_ARMOR] != i)
+ {
+ cl.stats[STAT_ARMOR] = i;
+ Sbar_Changed ();
+ }
+
+ if (bits & SU_WEAPON)
+ i = MSG_ReadByte ();
+ else
+ i = 0;
+ if (cl.stats[STAT_WEAPON] != i)
+ {
+ cl.stats[STAT_WEAPON] = i;
+ Sbar_Changed ();
+ }
+
+ i = MSG_ReadShort ();
+ if (cl.stats[STAT_HEALTH] != i)
+ {
+ cl.stats[STAT_HEALTH] = i;
+ Sbar_Changed ();
+ }
+
+ i = MSG_ReadByte ();
+ if (cl.stats[STAT_AMMO] != i)
+ {
+ cl.stats[STAT_AMMO] = i;
+ Sbar_Changed ();
+ }
+
+ for (i=0 ; i<4 ; i++)
+ {
+ j = MSG_ReadByte ();
+ if (cl.stats[STAT_SHELLS+i] != j)
+ {
+ cl.stats[STAT_SHELLS+i] = j;
+ Sbar_Changed ();
+ }
+ }
+
+ i = MSG_ReadByte ();
+
+ if (standard_quake)
+ {
+ if (cl.stats[STAT_ACTIVEWEAPON] != i)
+ {
+ cl.stats[STAT_ACTIVEWEAPON] = i;
+ Sbar_Changed ();
+ }
+ }
+ else
+ {
+ if (cl.stats[STAT_ACTIVEWEAPON] != (1<<i))
+ {
+ cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
+ Sbar_Changed ();
+ }
+ }
+}
+
+/*
+=====================
+CL_NewTranslation
+=====================
+*/
+void CL_NewTranslation (int slot)
+{
+ int i, j;
+ int top, bottom;
+ byte *dest, *source;
+
+ if (slot > cl.maxclients)
+ Sys_Error ("CL_NewTranslation: slot > cl.maxclients");
+ dest = cl.scores[slot].translations;
+ source = vid.colormap;
+ memcpy (dest, vid.colormap, sizeof(cl.scores[slot].translations));
+ top = cl.scores[slot].colors & 0xf0;
+ bottom = (cl.scores[slot].colors &15)<<4;
+#ifdef GLQUAKE
+ R_TranslatePlayerSkin (slot);
+#endif
+
+ for (i=0 ; i<VID_GRADES ; i++, dest += 256, source+=256)
+ {
+ if (top < 128) // the artists made some backwards ranges. sigh.
+ memcpy (dest + TOP_RANGE, source + top, 16);
+ else
+ for (j=0 ; j<16 ; j++)
+ dest[TOP_RANGE+j] = source[top+15-j];
+
+ if (bottom < 128)
+ memcpy (dest + BOTTOM_RANGE, source + bottom, 16);
+ else
+ for (j=0 ; j<16 ; j++)
+ dest[BOTTOM_RANGE+j] = source[bottom+15-j];
+ }
+}
+
+/*
+=====================
+CL_ParseStatic
+=====================
+*/
+void CL_ParseStatic (void)
+{
+ entity_t *ent;
+ int i;
+
+ i = cl.num_statics;
+ if (i >= MAX_STATIC_ENTITIES)
+ Host_Error ("Too many static entities");
+ ent = &cl_static_entities[i];
+ cl.num_statics++;
+ CL_ParseBaseline (ent);
+
+// copy it to the current state
+ ent->model = cl.model_precache[ent->baseline.modelindex];
+ ent->frame = ent->baseline.frame;
+ ent->colormap = vid.colormap;
+ ent->skinnum = ent->baseline.skin;
+ ent->effects = ent->baseline.effects;
+
+ VectorCopy (ent->baseline.origin, ent->origin);
+ VectorCopy (ent->baseline.angles, ent->angles);
+ R_AddEfrags (ent);
+}
+
+/*
+===================
+CL_ParseStaticSound
+===================
+*/
+void CL_ParseStaticSound (void)
+{
+ vec3_t org;
+ int sound_num, vol, atten;
+ int i;
+
+ for (i=0 ; i<3 ; i++)
+ org[i] = MSG_ReadCoord ();
+ sound_num = MSG_ReadByte ();
+ vol = MSG_ReadByte ();
+ atten = MSG_ReadByte ();
+
+ S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
+}
+
+
+#define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
+
+/*
+=====================
+CL_ParseServerMessage
+=====================
+*/
+void CL_ParseServerMessage (void)
+{
+ int cmd;
+ int i;
+
+//
+// if recording demos, copy the message out
+//
+ if (cl_shownet.value == 1)
+ Con_Printf ("%i ",net_message.cursize);
+ else if (cl_shownet.value == 2)
+ Con_Printf ("------------------\n");
+
+ cl.onground = false; // unless the server says otherwise
+//
+// parse the message
+//
+ MSG_BeginReading ();
+
+ while (1)
+ {
+ if (msg_badread)
+ Host_Error ("CL_ParseServerMessage: Bad server message");
+
+ cmd = MSG_ReadByte ();
+
+ if (cmd == -1)
+ {
+ SHOWNET("END OF MESSAGE");
+ return; // end of message
+ }
+
+ // if the high bit of the command byte is set, it is a fast update
+ if (cmd & 128)
+ {
+ SHOWNET("fast update");
+ CL_ParseUpdate (cmd&127);
+ continue;
+ }
+
+ SHOWNET(svc_strings[cmd]);
+
+ // other commands
+ switch (cmd)
+ {
+ default:
+ Host_Error ("CL_ParseServerMessage: Illegible server message\n");
+ break;
+
+ case svc_nop:
+// Con_Printf ("svc_nop\n");
+ break;
+
+ case svc_time:
+ cl.mtime[1] = cl.mtime[0];
+ cl.mtime[0] = MSG_ReadFloat ();
+ break;
+
+ case svc_clientdata:
+ i = MSG_ReadShort ();
+ CL_ParseClientdata (i);
+ break;
+
+ case svc_version:
+ i = MSG_ReadLong ();
+ if (i != PROTOCOL_VERSION)
+ Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, PROTOCOL_VERSION);
+ break;
+
+ case svc_disconnect:
+ Host_EndGame ("Server disconnected\n");
+
+ case svc_print:
+ Con_Printf ("%s", MSG_ReadString ());
+ break;
+
+ case svc_centerprint:
+ SCR_CenterPrint (MSG_ReadString ());
+ break;
+
+ case svc_stufftext:
+ Cbuf_AddText (MSG_ReadString ());
+ break;
+
+ case svc_damage:
+ V_ParseDamage ();
+ break;
+
+ case svc_serverinfo:
+ CL_ParseServerInfo ();
+ vid.recalc_refdef = true; // leave intermission full screen
+ break;
+
+ case svc_setangle:
+ for (i=0 ; i<3 ; i++)
+ cl.viewangles[i] = MSG_ReadAngle ();
+ break;
+
+ case svc_setview:
+ cl.viewentity = MSG_ReadShort ();
+ break;
+
+ case svc_lightstyle:
+ i = MSG_ReadByte ();
+ if (i >= MAX_LIGHTSTYLES)
+ Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
+ Q_strcpy (cl_lightstyle[i].map, MSG_ReadString());
+ cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map);
+ break;
+
+ case svc_sound:
+ CL_ParseStartSoundPacket();
+ break;
+
+ case svc_stopsound:
+ i = MSG_ReadShort();
+ S_StopSound(i>>3, i&7);
+ break;
+
+ case svc_updatename:
+ Sbar_Changed ();
+ i = MSG_ReadByte ();
+ if (i >= cl.maxclients)
+ Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD");
+ strcpy (cl.scores[i].name, MSG_ReadString ());
+ break;
+
+ case svc_updatefrags:
+ Sbar_Changed ();
+ i = MSG_ReadByte ();
+ if (i >= cl.maxclients)
+ Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD");
+ cl.scores[i].frags = MSG_ReadShort ();
+ break;
+
+ case svc_updatecolors:
+ Sbar_Changed ();
+ i = MSG_ReadByte ();
+ if (i >= cl.maxclients)
+ Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD");
+ cl.scores[i].colors = MSG_ReadByte ();
+ CL_NewTranslation (i);
+ break;
+
+ case svc_particle:
+ R_ParseParticleEffect ();
+ break;
+
+ case svc_spawnbaseline:
+ i = MSG_ReadShort ();
+ // must use CL_EntityNum() to force cl.num_entities up
+ CL_ParseBaseline (CL_EntityNum(i));
+ break;
+ case svc_spawnstatic:
+ CL_ParseStatic ();
+ break;
+ case svc_temp_entity:
+ CL_ParseTEnt ();
+ break;
+
+ case svc_setpause:
+ {
+ cl.paused = MSG_ReadByte ();
+
+ if (cl.paused)
+ {
+ CDAudio_Pause ();
+#ifdef _WIN32
+ VID_HandlePause (true);
+#endif
+ }
+ else
+ {
+ CDAudio_Resume ();
+#ifdef _WIN32
+ VID_HandlePause (false);
+#endif
+ }
+ }
+ break;
+
+ case svc_signonnum:
+ i = MSG_ReadByte ();
+ if (i <= cls.signon)
+ Host_Error ("Received signon %i when at %i", i, cls.signon);
+ cls.signon = i;
+ CL_SignonReply ();
+ break;
+
+ case svc_killedmonster:
+ cl.stats[STAT_MONSTERS]++;
+ break;
+
+ case svc_foundsecret:
+ cl.stats[STAT_SECRETS]++;
+ break;
+
+ case svc_updatestat:
+ i = MSG_ReadByte ();
+ if (i < 0 || i >= MAX_CL_STATS)
+ Sys_Error ("svc_updatestat: %i is invalid", i);
+ cl.stats[i] = MSG_ReadLong ();;
+ break;
+
+ case svc_spawnstaticsound:
+ CL_ParseStaticSound ();
+ break;
+
+ case svc_cdtrack:
+ cl.cdtrack = MSG_ReadByte ();
+ cl.looptrack = MSG_ReadByte ();
+ if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
+ CDAudio_Play ((byte)cls.forcetrack, true);
+ else
+ CDAudio_Play ((byte)cl.cdtrack, true);
+ break;
+
+ case svc_intermission:
+ cl.intermission = 1;
+ cl.completed_time = (int) cl.time;
+ vid.recalc_refdef = true; // go to full screen
+ break;
+
+ case svc_finale:
+ cl.intermission = 2;
+ cl.completed_time = (int) cl.time;
+ vid.recalc_refdef = true; // go to full screen
+ SCR_CenterPrint (MSG_ReadString ());
+ break;
+
+ case svc_cutscene:
+ cl.intermission = 3;
+ cl.completed_time = (int) cl.time;
+ vid.recalc_refdef = true; // go to full screen
+ SCR_CenterPrint (MSG_ReadString ());
+ break;
+
+ case svc_sellscreen:
+ Cmd_ExecuteString2 ("help", src_command);
+ break;
+ }
+ }
+}
+