diff options
author | Shih-wei Liao <sliao@google.com> | 2011-07-21 01:05:25 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-07-21 01:05:25 -0700 |
commit | b2080cd3e724758f3437c210c04d65a413ea7f15 (patch) | |
tree | a4e48c07b9433601572c6150612ecc5e6be86c1a /samples/quake/jni/cl_parse.cpp | |
parent | 48e07cb728f03175b7668108d8eab22ea808f18d (diff) | |
parent | dc9c7edca5025d2c3796c2ef587284c10d321fe4 (diff) | |
download | gdk-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.cpp | 963 |
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; + } + } +} + |