/* ================== CL_ParseDelta Can go from either a baseline or a previous packet_entity ================== */ static void CL_ParseDelta(entity_state_t *from, entity_state_t *to, int bits) { int i; // set everything to the state we are delta'ing from *to = *from; to->number = bits & 511; bits &= ~511; if (bits & U_MOREBITS) { // read in the low order bits i = MSG_ReadByte(); bits |= i; } to->flags = bits; if (bits & U_MODEL) to->modelindex = MSG_ReadByte(); if (bits & U_FRAME) to->frame = MSG_ReadByte(); if (bits & U_COLORMAP) to->colormap = MSG_ReadByte(); if (bits & U_SKIN) to->skinnum = MSG_ReadByte(); if (bits & U_EFFECTS) to->effects = MSG_ReadByte(); if (bits & U_ORIGIN1) to->origin[0] = MSG_ReadCoord(); if (bits & U_ANGLE1) to->angles[0] = MSG_ReadAngle(); if (bits & U_ORIGIN2) to->origin[1] = MSG_ReadCoord(); if (bits & U_ANGLE2) to->angles[1] = MSG_ReadAngle(); if (bits & U_ORIGIN3) to->origin[2] = MSG_ReadCoord(); if (bits & U_ANGLE3) to->angles[2] = MSG_ReadAngle(); if (bits & U_SOLID) { // FIXME } }
void Parse_Static(void){ MSG_ReadByte(); MSG_ReadByte(); MSG_ReadByte(); MSG_ReadByte(); MSG_ReadCoord(); MSG_ReadAngle(); MSG_ReadCoord(); MSG_ReadAngle(); MSG_ReadCoord(); MSG_ReadAngle(); }
void Parse_Spawnbaseline(void){ MSG_ReadShort(); MSG_ReadByte(); MSG_ReadByte(); MSG_ReadByte(); MSG_ReadByte(); MSG_ReadCoord(); MSG_ReadAngle(); MSG_ReadCoord(); MSG_ReadAngle(); MSG_ReadCoord(); MSG_ReadAngle(); }
/* =================== SV_ReadClientMove =================== */ static void SV_ReadClientMove(client_t *client, usercmd_t *move) { edict_t *player = client->edict; int i, ping, buttonbits, impulse; /* read ping time */ ping = client->num_pings % NUM_PING_TIMES; client->ping_times[ping] = sv.time - MSG_ReadFloat(); client->num_pings++; /* read current angles */ for (i = 0; i < 3; i++) { if (sv.protocol == PROTOCOL_VERSION_FITZ) player->v.v_angle[i] = MSG_ReadAngle16(); else player->v.v_angle[i] = MSG_ReadAngle(); } /* read movement */ move->forwardmove = MSG_ReadShort(); move->sidemove = MSG_ReadShort(); move->upmove = MSG_ReadShort(); /* read buttons */ buttonbits = MSG_ReadByte(); player->v.button0 = buttonbits & 1; player->v.button2 = (buttonbits & 2) >> 1; impulse = MSG_ReadByte(); if (impulse) player->v.impulse = impulse; }
/* =================== SV_ReadClientMove =================== */ void SV_ReadClientMove (usercmd_t *move) { int i; vec3_t angle; int bits; // read ping time host_client->ping_times[host_client->num_pings%NUM_PING_TIMES] = sv.time - MSG_ReadFloat (); host_client->num_pings++; // read current angles for (i=0 ; i<3 ; i++) angle[i] = MSG_ReadAngle (); VectorCopy (angle, host_client->edict->v.v_angle); // read movement move->forwardmove = MSG_ReadShort (); move->sidemove = MSG_ReadShort (); move->upmove = MSG_ReadShort (); // read buttons bits = MSG_ReadByte (); host_client->edict->v.button0 = bits & 1; host_client->edict->v.button2 = (bits & 2)>>1; i = MSG_ReadByte (); if (i) host_client->edict->v.impulse = i; }
/* =================== SV_ReadClientMove =================== */ void SV_ReadClientMove (usercmd_t *move) { int i; vec3_t angle; int bits; // read ping time host_client->ping_times[host_client->num_pings%NUM_PING_TIMES] = sv.time - MSG_ReadFloat (); host_client->num_pings++; // read current angles if (host_client->netconnection->proquake_connection == MOD_PROQUAKE) { for (i = 0; i<3; i++) angle[i] = MSG_ReadPreciseAngle(); } else { for (i = 0; i<3; i++) angle[i] = MSG_ReadAngle(); } // ProQuake - server-side fullpitch fix if (!pq_fullpitch.value) { if (angle[PITCH] > 80 || angle[PITCH] < -70) { angle[PITCH] = COM_Clamp(angle[PITCH], -70, 80); MSG_WriteByte (&host_client->message, svc_setangle); for (i=0 ; i < 3 ; i++) MSG_WriteAngle (&host_client->message, angle[i] ); } } VectorCopy (angle, host_client->edict->v.v_angle); // read movement move->forwardmove = MSG_ReadShort (); move->sidemove = MSG_ReadShort (); move->upmove = MSG_ReadShort (); // read buttons bits = MSG_ReadByte (); host_client->edict->v.button0 = bits & 1; host_client->edict->v.button2 = (bits & 2)>>1; i = MSG_ReadByte (); if (i) host_client->edict->v.impulse = i; #ifdef QUAKE2 // read light level host_client->edict->v.light_level = MSG_ReadByte (); #endif }
/* ======================= CL_ParseAngleInterpolate (Hexen II) ======================= */ void CL_ParseAngleInterpolate (void) { float compangles[2][3]; int i, j; vec3_t deltaangles; compangles[0][0] = MSG_ReadAngle(); compangles[0][1] = MSG_ReadAngle(); compangles[0][2] = MSG_ReadAngle(); for (i=0 ; i<3 ; i++) { compangles[1][i] = cl.viewangles[i]; for (j=0 ; j<2 ; j++) {//standardize both old and new angles to +-180 if(compangles[j][i]>=360) compangles[j][i] -= 360*((int)(compangles[j][i]/360)); else if(compangles[j][i]<=360) compangles[j][i] += 360*(1+(int)(-compangles[j][i]/360)); if(compangles[j][i]>180) compangles[j][i]=-360 + compangles[j][i]; else if(compangles[j][i]<-180) compangles[j][i]=360 + compangles[j][i]; } //get delta deltaangles[i] = compangles[0][i] - compangles[1][i]; //cap delta to <=180,>=-180 if(deltaangles[i]>180) deltaangles[i]+=-360; else if(deltaangles[i]<-180) deltaangles[i]+=360; //add the delta cl.viewangles[i]+=(deltaangles[i]/8);//8 step interpolation //cap newangles to +-180 if(cl.viewangles[i]>=360) cl.viewangles[i] -= 360*((int)(cl.viewangles[i]/360)); else if(cl.viewangles[i]<=360) cl.viewangles[i] += 360*(1+(int)(-cl.viewangles[i]/360)); if(cl.viewangles[i]>180) cl.viewangles[i]+=-360; else if(cl.viewangles[i]<-180) cl.viewangles[i]+=360; } }
/* ======================= CL_ParseRainEffect (Hexen II) ======================= */ void CL_ParseRainEffect(void) { vec3_t org, e_size; short color,count; int x_dir, y_dir; org[0] = MSG_ReadCoord(); org[1] = MSG_ReadCoord(); org[2] = MSG_ReadCoord(); e_size[0] = MSG_ReadCoord(); e_size[1] = MSG_ReadCoord(); e_size[2] = MSG_ReadCoord(); x_dir = MSG_ReadAngle(); y_dir = MSG_ReadAngle(); color = MSG_ReadShort(); count = MSG_ReadShort(); R_RainEffect(org, e_size, x_dir, y_dir, color, count); }
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_ParseBaseline ================== */ static void CL_ParseBaseline (entity_t *ent) { int i; ent->baseline.modelindex = MSG_ReadShort (); ent->baseline.frame = MSG_ReadByte (); ent->baseline.colormap = MSG_ReadByte(); ent->baseline.skin = MSG_ReadByte(); ent->baseline.scale = MSG_ReadByte(); ent->baseline.drawflags = MSG_ReadByte(); ent->baseline.abslight = MSG_ReadByte(); for (i = 0; i < 3; i++) { ent->baseline.origin[i] = MSG_ReadCoord (); ent->baseline.angles[i] = MSG_ReadAngle (); } }
/* ================== CL_ParseBaseline ================== */ static void CL_ParseBaseline(entity_t *ent, unsigned int bits) { int i; ent->baseline.modelindex = CL_ReadModelIndex(bits); ent->baseline.frame = CL_ReadModelFrame(bits); ent->baseline.colormap = MSG_ReadByte(); ent->baseline.skinnum = MSG_ReadByte(); for (i = 0; i < 3; i++) { ent->baseline.origin[i] = MSG_ReadCoord(); ent->baseline.angles[i] = MSG_ReadAngle(); } if (cl.protocol == PROTOCOL_VERSION_FITZ && (bits & B_FITZ_ALPHA)) { MSG_ReadByte(); // FIXME - TODO } }
/* =================== SV_ReadClientMove =================== */ void SV_ReadClientMove (usercmd_t *move) { int i; vec3_t angle; int bits; // read ping time host_client->ping_times[host_client->num_pings%NUM_PING_TIMES] = sv.time - MSG_ReadFloat (net_message); host_client->num_pings++; // read current angles if ((host_client->netconnection->mod == MOD_PROQUAKE) && (sv.protocol == PROTOCOL_NETQUAKE)) // precise aim for ProQuake { for (i=0 ; i<3 ; i++) angle[i] = MSG_ReadPreciseAngle (net_message); } else if (sv.protocol == PROTOCOL_FITZQUAKE || sv.protocol == PROTOCOL_FITZQUAKE_PLUS) //johnfitz -- 16-bit angles for PROTOCOL_FITZQUAKE { for (i=0 ; i<3 ; i++) angle[i] = MSG_ReadAngle16 (net_message); } else { for (i=0 ; i<3 ; i++) angle[i] = MSG_ReadAngle (net_message); } VectorCopy (angle, host_client->edict->v.v_angle); // read movement move->forwardmove = MSG_ReadShort (net_message); move->sidemove = MSG_ReadShort (net_message); move->upmove = MSG_ReadShort (net_message); // read buttons bits = MSG_ReadByte (net_message); host_client->edict->v.button0 = bits & 1; host_client->edict->v.button2 = (bits & 2)>>1; i = MSG_ReadByte (net_message); if (i) host_client->edict->v.impulse = i; }
/* =================== SV_ReadClientMove =================== */ void SV_ReadClientMove (usercmd_t *move) { int i; vec3_t angle; int bits; // read ping time host_client->ping_times[host_client->num_pings%NUM_PING_TIMES] = sv.time - MSG_ReadFloat (); host_client->num_pings++; // read current angles // 2000-05-01 NVS CLC_move precise aiming by Maddes start if (host_client->nvs_cclc >= 0.50) { for (i=0 ; i<3 ; i++) { angle[i] = MSG_ReadFloat (); } } else { // 2000-05-01 NVS CLC_move precise aiming by Maddes end for (i=0 ; i<3 ; i++) angle[i] = MSG_ReadAngle (); } // 2000-05-01 NVS CLC precise_move aiming by Maddes VectorCopy (angle, host_client->edict->v.v_angle); // read movement move->forwardmove = MSG_ReadShort (); move->sidemove = MSG_ReadShort (); move->upmove = MSG_ReadShort (); // read buttons bits = MSG_ReadByte (); host_client->edict->v.button0 = bits & 1; // 1999-10-29 +USE fix by Maddes start if (!nouse) { host_client->edict->v.button1 = (bits & 4)>>2; }
/* ================== CL_ParseBaseline ================== */ void CL_ParseBaseline (entity_t *ent, int version) //johnfitz -- added argument { int i; int bits; //johnfitz //johnfitz -- PROTOCOL_FITZQUAKE bits = (version == 2) ? MSG_ReadByte() : 0; ent->baseline.modelindex = (bits & B_LARGEMODEL) ? MSG_ReadShort() : MSG_ReadByte(); ent->baseline.frame = (bits & B_LARGEFRAME) ? MSG_ReadShort() : MSG_ReadByte(); //johnfitz 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 (); } ent->baseline.alpha = (bits & B_ALPHA) ? MSG_ReadByte() : ENTALPHA_DEFAULT; //johnfitz -- PROTOCOL_FITZQUAKE }
/* =================== SV_ReadClientMove =================== */ void SV_ReadClientMove (usercmd_t *move) { int i; vec3_t angle; int bits; // read ping time host_client->ping_times[host_client->num_pings%NUM_PING_TIMES] = sv.time - MSG_ReadFloat (); host_client->num_pings++; // read current angles for (i=0 ; i<3 ; i++) //johnfitz -- 16-bit angles for PROTOCOL_FITZQUAKE if (sv.protocol == PROTOCOL_NETQUAKE) angle[i] = MSG_ReadAngle (sv.protocolflags); else angle[i] = MSG_ReadAngle16 (sv.protocolflags); //johnfitz VectorCopy (angle, host_client->edict->v.v_angle); // read movement move->forwardmove = MSG_ReadShort (); move->sidemove = MSG_ReadShort (); move->upmove = MSG_ReadShort (); // read buttons bits = MSG_ReadByte (); host_client->edict->v.button0 = bits & 1; host_client->edict->v.button2 = (bits & 2)>>1; i = MSG_ReadByte (); if (i) host_client->edict->v.impulse = i; }
void Split_Incoming(packet_struct_t *packet, bool record) { int old_readcount = 0; extern int msg_readcount; byte *dptr; int type; extern message_t net_message; unsigned sequence, sequence_ack; unsigned reliable_ack, reliable_message; int i = 0; net_message.cursize = packet->payload_size; net_message.data = packet->payload; MSG_BeginReading(); if (record) { sequence = MSG_ReadLong(); sequence_ack = MSG_ReadLong(); //MSG_ReadShort(); reliable_message = sequence >> 31; reliable_ack = sequence_ack >> 31; sequence &= ~(1 << 31); sequence_ack &= ~(1 << 31); packet->sequence = sequence; packet->sequence_ack = sequence_ack; packet->reliable_message = reliable_message; packet->reliable_ack = reliable_ack; //printf("TEST !%i\n",(unsigned int *)net_message.data[0]); //printf("%i %i %i %i\n", sequence, reliable_message, sequence_ack, reliable_ack); //printf("%i %i %i %i\n", packet->sequence, packet->reliable_message, packet->sequence_ack, packet->reliable_ack); //printf ("%i %i %i %i\n",(int)((char *)packet->sequence),(int)((char *)packet->sequence)+1,(int)((char *)packet->sequence)+2,(int)((char *)packet->sequence)+3); Dprintf(1,"IN --> s=%i(%i) a=%i(%i) %i\n",packet->sequence,packet->reliable_message,packet->sequence_ack,\ packet->reliable_ack, net_message.cursize); } while (1) { old_readcount = msg_readcount; type = MSG_ReadByte(); if (type == -1) break; i++; switch (type) { case svc_serverdata: Dprintf(1,"%s\n", svc_strings[type]); Parse_Serverdata(); break; case svc_updatestat: Dprintf(1,"%s\n", svc_strings[type]); Updatestat(); break; case svc_updatestatlong: Dprintf(1,"%s\n", svc_strings[type]); Updatestat_Long(); break; case svc_playerinfo: Dprintf(1,"%s\n", svc_strings[type]); Parse_Playerinfo(); break; case svc_packetentities: Dprintf(1,"%s\n", svc_strings[type]); Parse_Packetentities(false); break; case svc_serverinfo: Dprintf(1,"%s\n", svc_strings[type]); Parse_Serverinfo(); break; case svc_cdtrack: Dprintf(1,"%s\n", svc_strings[type]); MSG_ReadByte(); break; case svc_stufftext: Dprintf(1,"%s\n", svc_strings[type]); Dprintf(1,"%s", MSG_ReadString()); break; case svc_updatefrags: Dprintf(1,"%s\n", svc_strings[type]); //players[MSG_ReadByte()].frags = MSG_ReadShort(); MSG_ReadByte(); MSG_ReadShort(); break; case svc_print: Dprintf(1,"%s\n", svc_strings[type]); Dprintf(1,"LEVEL %i : ",MSG_ReadByte()); Dprintf(1,"%s\n",MSG_ReadString()); break; case svc_spawnstaticsound: Dprintf(1,"%s\n", svc_strings[type]); MSG_ReadCoord(); MSG_ReadCoord(); MSG_ReadCoord(); MSG_ReadByte(); MSG_ReadByte(); MSG_ReadByte(); break; case svc_updateping: Dprintf(1,"%s\n", svc_strings[type]); players[MSG_ReadByte()].ping = MSG_ReadShort(); break; case svc_updatepl: Dprintf(1,"%s\n", svc_strings[type]); players[MSG_ReadByte()].pl = MSG_ReadByte(); break; case svc_updateentertime: Dprintf(1,"%s\n", svc_strings[type]); players[MSG_ReadByte()].entertime = MSG_ReadFloat(); break; case svc_updateuserinfo: Dprintf(1,"%s\n", svc_strings[type]); Update_Userinfo(); break; case svc_setinfo: Dprintf(1,"%s\n", svc_strings[type]); Parse_Setinfo(); break; case svc_centerprint: Dprintf(1,"%s\n", svc_strings[type]); Dprintf(1,"%s\n", MSG_ReadString()); break; case svc_soundlist: Dprintf(1,"%s\n", svc_strings[type]); Parse_Soundlist(); break; case svc_modellist: Dprintf(1,"%s\n", svc_strings[type]); Parse_Modellist(); break; case svc_smallkick: Dprintf(1,"%s\n", svc_strings[type]); break; case svc_bigkick: Dprintf(1,"%s\n", svc_strings[type]); break; case svc_chokecount: Dprintf(1,"%s\n", svc_strings[type]); Dprintf(1,"%i\n", MSG_ReadByte()); break; case svc_stopsound: Dprintf(1,"%s\n", svc_strings[type]); Dprintf(1,"%i\n", MSG_ReadShort()); break; case svc_setangle: Dprintf(1,"%s\n", svc_strings[type]); MSG_ReadAngle(); MSG_ReadAngle(); MSG_ReadAngle(); break; case svc_lightstyle: Dprintf(1,"%s\n", svc_strings[type]); // Dprintf(1,"%4i: %s\n",MSG_ReadByte(),MSG_ReadString()); // msg_readcount++; MSG_ReadByte(); MSG_ReadString(); break; case svc_muzzleflash: Dprintf(1,"%s\n", svc_strings[type]); Dprintf(1,"%4i\n", MSG_ReadShort()); break; case svc_damage: Dprintf(1,"%s\n", svc_strings[type]); Parse_Damage(); break; case svc_spawnstatic: Dprintf(1,"%s\n", svc_strings[type]); Parse_Static(); break; case svc_spawnbaseline: Dprintf(1,"%s\n", svc_strings[type]); Parse_Spawnbaseline(); break; case svc_deltapacketentities: Dprintf(1,"%s\n", svc_strings[type]); Parse_Packetentities(true); break; case svc_sound: Dprintf(1,"%s\n", svc_strings[type]); Parse_Sound(); break; case svc_disconnect: Dprintf(1,"%s\n", svc_strings[type]); break; case svc_entgravity: Dprintf(1,"%s\n", svc_strings[type]); MSG_ReadFloat(); break; case svc_maxspeed: Dprintf(1,"%s\n", svc_strings[type]); MSG_ReadFloat(); break; case svc_setview: Dprintf(1,"%s\n", svc_strings[type]); break; case svc_nop: Dprintf(1,"%s\n", svc_strings[type]); break; case svc_temp_entity: Dprintf(1,"%s\n", svc_strings[type]); Parse_TEnt(); break; case svc_nails: Dprintf(1,"%s\n", svc_strings[type]); MSG_ReadByte(); MSG_ReadByte(); MSG_ReadByte(); MSG_ReadByte(); MSG_ReadByte(); MSG_ReadByte(); MSG_ReadByte(); break; /*case svc_time: Dprintf(1,"%s\n", svc_strings[type]); MSG_ReadFloat(); break; */ case nq_svc_signonnum: Dprintf(1,"%s\n", svc_strings[type]); MSG_ReadByte(); break; default: Dprintf(1,"unknown type %i\n", type); packet->has_unknown_types = 1; debug_unknown(packet,msg_readcount); return; } if (record) { dptr = malloc(sizeof(char) * (msg_readcount - old_readcount)); memcpy(dptr, &net_message.data[old_readcount], msg_readcount - old_readcount); Create_Packet_Struct(packet, type, dptr, msg_readcount - old_readcount); } } Dprintf(1,"%3i - recorded messages\n",i); }
/* ===================== CL_ParseServerMessage ===================== */ void CL_ParseServerMessage(void) { unsigned int bits; int i, cmd, prevcmd; int playernum, version, stylenum, signon, statnum; int stopsound, entitynum, channel; byte colors; player_info_t *player; lightstyle_t *style; const char *stylemap, *name; // // 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 // prevcmd = svc_bad; MSG_BeginReading(); while (1) { if (msg_badread) Host_Error("%s: Bad server message", __func__); 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) { case svc_nop: break; case svc_time: cl.mtime[1] = cl.mtime[0]; cl.mtime[0] = MSG_ReadFloat(); break; case svc_clientdata: CL_ParseClientdata(); break; case svc_version: version = MSG_ReadLong(); if (!Protocol_Known(version)) Host_Error("%s: Server returned unknown protocol version %i", __func__, version); cl.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("%s", 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: stylenum = MSG_ReadByte(); if (stylenum >= MAX_LIGHTSTYLES) Sys_Error("svc_lightstyle > MAX_LIGHTSTYLES"); stylemap = MSG_ReadString(); style = cl_lightstyle + stylenum; snprintf(style->map, MAX_STYLESTRING, "%s", stylemap); style->length = strlen(style->map); break; case svc_sound: CL_ParseStartSoundPacket(); break; case svc_stopsound: stopsound = MSG_ReadShort(); /* 3-bit channel encoded in lsb */ entitynum = stopsound >> 3; channel = stopsound & 7; S_StopSound(entitynum, channel); break; case svc_updatename: Sbar_Changed(); playernum = MSG_ReadByte(); if (playernum >= cl.maxclients) Host_Error("%s: svc_updatename > MAX_SCOREBOARD", __func__); name = MSG_ReadString(); player = cl.players + playernum; snprintf(player->name, MAX_SCOREBOARDNAME, "%s", name); break; case svc_updatefrags: Sbar_Changed(); playernum = MSG_ReadByte(); if (playernum >= cl.maxclients) Host_Error("%s: svc_updatefrags > MAX_SCOREBOARD", __func__); player = cl.players + playernum; player->frags = MSG_ReadShort(); break; case svc_updatecolors: Sbar_Changed(); playernum = MSG_ReadByte(); if (playernum >= cl.maxclients) Host_Error("%s: svc_updatecolors > MAX_SCOREBOARD", __func__); colors = MSG_ReadByte(); player = cl.players + playernum; player->topcolor = (colors & 0xf0) >> 4; player->bottomcolor = colors & 0x0f; /* FIXME - is this the right check for current player? */ if (playernum == cl.viewentity) cl_color.value = colors; CL_NewTranslation(playernum); break; case svc_particle: R_ParseParticleEffect(); break; case svc_spawnbaseline: entitynum = MSG_ReadShort(); // must use CL_EntityNum() to force cl.num_entities up CL_ParseBaseline(CL_EntityNum(entitynum), 0); break; case svc_fitz_spawnbaseline2: /* FIXME - check here that protocol is FITZ? => Host_Error() */ entitynum = MSG_ReadShort(); bits = MSG_ReadByte(); // must use CL_EntityNum() to force cl.num_entities up CL_ParseBaseline(CL_EntityNum(entitynum), bits); break; case svc_spawnstatic: CL_ParseStatic(0); break; case svc_fitz_spawnstatic2: /* FIXME - check here that protocol is FITZ? => Host_Error() */ bits = MSG_ReadByte(); CL_ParseStatic(bits); break; case svc_temp_entity: CL_ParseTEnt(); break; case svc_setpause: cl.paused = MSG_ReadByte(); if (cl.paused) CDAudio_Pause(); else CDAudio_Resume(); break; case svc_signonnum: signon = MSG_ReadByte(); if (signon <= cls.signon) Host_Error("Received signon %d when at %d", signon, cls.signon); cls.signon = signon; CL_SignonReply(); break; case svc_killedmonster: cl.stats[STAT_MONSTERS]++; break; case svc_foundsecret: cl.stats[STAT_SECRETS]++; break; case svc_updatestat: statnum = MSG_ReadByte(); if (statnum < 0 || statnum >= MAX_CL_STATS) Sys_Error("svc_updatestat: %d is invalid", statnum); cl.stats[statnum] = MSG_ReadLong(); break; case svc_spawnstaticsound: CL_ParseStaticSound(); break; case svc_fitz_spawnstaticsound2: /* FIXME - check here that protocol is FITZ? => Host_Error() */ CL_ParseFitzStaticSound2(); 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 = cl.time; vid.recalc_refdef = true; // go to full screen break; case svc_finale: cl.intermission = 2; cl.completed_time = cl.time; vid.recalc_refdef = true; // go to full screen SCR_CenterPrint(MSG_ReadString()); break; case svc_cutscene: cl.intermission = 3; cl.completed_time = cl.time; vid.recalc_refdef = true; // go to full screen SCR_CenterPrint(MSG_ReadString()); break; case svc_sellscreen: Cmd_ExecuteString("help", src_command); break; /* Various FITZ protocol messages - FIXME - !protocol => Host_Error */ case svc_fitz_skybox: MSG_ReadString(); // FIXME - TODO break; case svc_fitz_bf: Cmd_ExecuteString("bf", src_command); break; case svc_fitz_fog: /* FIXME - TODO */ MSG_ReadByte(); // density MSG_ReadByte(); // red MSG_ReadByte(); // green MSG_ReadByte(); // blue MSG_ReadShort(); // time break; default: Host_Error("%s: Illegible server message. Previous was %s", __func__, svc_strings[prevcmd]); } prevcmd = cmd; } }
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; } } }
void CL_ParseUpdate(unsigned int bits) { int i; model_t *model; int modnum; qboolean forcelink; entity_t *ent; int num; // FIXME - do this cleanly... #ifdef GLQUAKE int skin; #endif if (cls.state == ca_firstupdate) { // first update is the final signon stage cls.signon = SIGNONS; CL_SignonReply(); } if (bits & U_MOREBITS) { i = MSG_ReadByte(); bits |= (i << 8); } if (cl.protocol == PROTOCOL_VERSION_FITZ) { if (bits & U_FITZ_EXTEND1) bits |= MSG_ReadByte() << 16; if (bits & U_FITZ_EXTEND2) bits |= MSG_ReadByte() << 24; } if (bits & U_LONGENTITY) num = MSG_ReadShort(); else num = MSG_ReadByte(); ent = CL_EntityNum(num); 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 = CL_ReadModelIndex(0); if (modnum >= max_models(cl.protocol)) Host_Error("CL_ParseModel: bad modnum"); } else modnum = ent->baseline.modelindex; if (bits & U_FRAME) ent->frame = MSG_ReadByte(); else ent->frame = ent->baseline.frame; /* ANIMATION LERPING INFO */ if (ent->currentframe != ent->frame) { /* TODO: invalidate things when they fall off the currententities list or haven't been updated for a while */ ent->previousframe = ent->currentframe; ent->previousframetime = ent->currentframetime; ent->currentframe = ent->frame; ent->currentframetime = cl.time; } 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.players[i - 1].translations; } #ifdef GLQUAKE if (bits & U_SKIN) skin = MSG_ReadByte(); else skin = ent->baseline.skinnum; 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.skinnum; #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 (cl.protocol == PROTOCOL_VERSION_FITZ) { if (bits & U_NOLERP) { // FIXME - TODO (called U_STEP in FQ) } if (bits & U_FITZ_ALPHA) { MSG_ReadByte(); // FIXME - TODO } if (bits & U_FITZ_FRAME2) ent->frame = (ent->frame & 0xFF) | (MSG_ReadByte() << 8); if (bits & U_FITZ_MODEL2) modnum = (modnum & 0xFF)| (MSG_ReadByte() << 8); if (bits & U_FITZ_LERPFINISH) { MSG_ReadByte(); // FIXME - TODO } } 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 } /* MOVEMENT LERP INFO - could I just extend baseline instead? */ if (!VectorCompare(ent->msg_origins[0], ent->currentorigin)) { if (ent->currentorigintime) { VectorCopy(ent->currentorigin, ent->previousorigin); ent->previousorigintime = ent->currentorigintime; } else { VectorCopy(ent->msg_origins[0], ent->previousorigin); ent->previousorigintime = cl.mtime[0]; } VectorCopy(ent->msg_origins[0], ent->currentorigin); ent->currentorigintime = cl.mtime[0]; } if (!VectorCompare(ent->msg_angles[0], ent->currentangles)) { if (ent->currentanglestime) { VectorCopy(ent->currentangles, ent->previousangles); ent->previousanglestime = ent->currentanglestime; } else { VectorCopy(ent->msg_angles[0], ent->previousangles); ent->previousanglestime = cl.mtime[0]; } VectorCopy(ent->msg_angles[0], ent->currentangles); ent->currentanglestime = cl.mtime[0]; } 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; } }
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_ParseServerMessage ===================== */ void CL_ParseServerMessage (void) { int cmd; int i, j, k; int EntityCount = 0; int EntitySize = 0; int before; static double lasttime; static qboolean packet_loss = false; entity_t *ent; short RemovePlace, OrigPlace, NewPlace, AddedIndex; int sc1, sc2; byte test; float compangles[2][3]; vec3_t deltaangles; // // if recording demos, copy the message out // if (net_message.cursize > LastServerMessageSize) { LastServerMessageSize = net_message.cursize; } if (cl_shownet.integer == 1) { Con_Printf ("Time: %2.2f Pck: %i ", realtime - lasttime, net_message.cursize); lasttime = realtime; } else if (cl_shownet.integer == 2) Con_Printf ("------------------\n"); cl.onground = false; // unless the server says otherwise // // parse the message // MSG_BeginReading (); while (1) { if (msg_badread) Host_Error ("%s: Bad server message", __thisfunc__); cmd = MSG_ReadByte (); if (cmd == -1) { if (cl_shownet.integer == 1) Con_Printf ("Ent: %i (%i bytes)",EntityCount,EntitySize); 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) { before = msg_readcount; SHOWNET("fast update"); if (packet_loss) CL_ParseUpdate2 (cmd&127); else CL_ParseUpdate (cmd&127); EntityCount++; EntitySize += msg_readcount - before + 1; continue; } if (cmd < NUM_SVC_STRINGS) // else, it'll hit the illegible message below { SHOWNET(svc_strings[cmd]); } // other commands switch (cmd) { default: // CL_DumpPacket (); Host_Error ("%s: Illegible server message %d", __thisfunc__, cmd); 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: cl_protocol = MSG_ReadLong (); switch (cl_protocol) { case PROTOCOL_RAVEN_111: case PROTOCOL_RAVEN_112: case PROTOCOL_UQE_113: Con_Printf ("Server using protocol %i\n", cl_protocol); break; default: Host_Error ("%s: Server is protocol %i instead of %i or %i", __thisfunc__, cl_protocol, PROTOCOL_RAVEN_112, PROTOCOL_UQE_113); } break; case svc_disconnect: Host_EndGame ("Server disconnected\n"); break; case svc_print: if (intro_playing) MSG_ReadString (); else Con_Printf ("%s", MSG_ReadString ()); break; case svc_centerprint: SCR_CenterPrint (MSG_ReadString ()); break; case svc_stufftext: stufftext_frame = host_framecount; // allow full frame update // on stuff messages. Pa3PyX 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_setangle_interpolate: compangles[0][0] = MSG_ReadAngle(); compangles[0][1] = MSG_ReadAngle(); compangles[0][2] = MSG_ReadAngle(); for (i = 0; i < 3; i++) { compangles[1][i] = cl.viewangles[i]; for (j = 0; j < 2; j++) {//standardize both old and new angles to +-180 if (compangles[j][i] >= 360) compangles[j][i] -= 360*((int)(compangles[j][i]/360)); else if (compangles[j][i] <= 360) compangles[j][i] += 360*(1+(int)(-compangles[j][i]/360)); if (compangles[j][i] > 180) compangles[j][i] = -360 + compangles[j][i]; else if (compangles[j][i] < -180) compangles[j][i] = 360 + compangles[j][i]; } //get delta deltaangles[i] = compangles[0][i] - compangles[1][i]; //cap delta to <=180,>=-180 if (deltaangles[i] > 180) deltaangles[i] += -360; else if (deltaangles[i] < -180) deltaangles[i] += 360; //add the delta cl.viewangles[i]+=(deltaangles[i]/8);//8 step interpolation //cap newangles to +-180 if (cl.viewangles[i] >= 360) cl.viewangles[i] -= 360*((int)(cl.viewangles[i]/360)); else if (cl.viewangles[i] <= 360) cl.viewangles[i] += 360*(1+(int)(-cl.viewangles[i]/360)); if (cl.viewangles[i] > 180) cl.viewangles[i] += -360; else if (cl.viewangles[i] < -180) cl.viewangles[i] += 360; } 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_strlcpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING); cl_lightstyle[i].length = strlen(cl_lightstyle[i].map); break; case svc_sound: CL_ParseStartSoundPacket(); break; case svc_sound_update_pos: {//FIXME: put a field on the entity that lists the channels //it should update when it moves- if a certain flag //is on the ent, this update_channels field could //be set automatically by each sound and stopSound //called for this ent? vec3_t pos; int channel, ent_num; channel = MSG_ReadShort (); ent_num = channel >> 3; channel &= 7; if (ent_num > MAX_EDICTS) Host_Error ("svc_sound_update_pos: ent = %i", ent_num); for (i = 0; i < 3; i++) pos[i] = MSG_ReadCoord (); S_UpdateSoundPos (ent_num, channel, pos); } 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 ("%s: svc_updatename > MAX_CLIENTS", __thisfunc__); q_strlcpy (cl.scores[i].name, MSG_ReadString(), MAX_SCOREBOARDNAME); break; case svc_updateclass: Sbar_Changed(); i = MSG_ReadByte (); if (i >= cl.maxclients) Host_Error ("%s: svc_updateclass > MAX_CLIENTS", __thisfunc__); cl.scores[i].playerclass = (float)MSG_ReadByte(); CL_NewTranslation(i); // update the color break; case svc_updatefrags: Sbar_Changed(); i = MSG_ReadByte (); if (i >= cl.maxclients) Host_Error ("%s: svc_updatefrags > MAX_CLIENTS", __thisfunc__); cl.scores[i].frags = MSG_ReadShort (); break; case svc_update_kingofhill: sv_kingofhill = MSG_ReadShort() - 1; break; case svc_updatecolors: Sbar_Changed(); i = MSG_ReadByte (); if (i >= cl.maxclients) Host_Error ("%s: svc_updatecolors > MAX_CLIENTS", __thisfunc__); cl.scores[i].colors = MSG_ReadByte (); CL_NewTranslation (i); break; case svc_particle: R_ParseParticleEffect (); break; case svc_particle2: R_ParseParticleEffect2 (); break; case svc_particle3: R_ParseParticleEffect3 (); break; case svc_particle4: R_ParseParticleEffect4 (); 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_raineffect: CL_ParseRainEffect(); break; case svc_temp_entity: CL_ParseTEnt (); break; case svc_setpause: cl.paused = MSG_ReadByte (); if (cl.paused) { CDAudio_Pause (); VID_HandlePause (true); } else { CDAudio_Resume (); VID_HandlePause (false); } 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 (q_strcasecmp(bgmtype.string,"cd") == 0) { if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) ) CDAudio_Play ((byte)cls.forcetrack, true); else CDAudio_Play ((byte)cl.cdtrack, true); } else CDAudio_Stop(); break; case svc_midi_name: q_strlcpy (cl.midi_name, MSG_ReadString(), sizeof(cl.midi_name)); if (q_strcasecmp(bgmtype.string,"midi") == 0) MIDI_Play(cl.midi_name); else MIDI_Stop(); break; case svc_toggle_statbar: break; case svc_intermission: cl.intermission = MSG_ReadByte(); if (oem.integer && cl.intermission == 1) cl.intermission = 9; // skip intermissions while recording demos in single // player games, but stop recording at ending scenes. // skip intermissions when playing demos. if (cls.demorecording) { // 5: finale for the demo version // 6, 7, 8: eidolon end-1 to end-3 // 9: finale for the bundle version // 10: praevus ending if (sv.active && svs.maxclients == 1 && (cl.intermission < 5 || cl.intermission > 10)) { cl.intermission = 0; demohack = true; Cbuf_AddText("+attack\n"); // HACK !.. break; } CL_Stop_f (); } else if (cls.demoplayback) { cl.intermission = 0; break; } cl.completed_time = cl.time; vid.recalc_refdef = true; // go to full screen break; /* case svc_finale: cl.intermission = 2; cl.completed_time = cl.time; vid.recalc_refdef = true; // go to full screen SCR_CenterPrint (MSG_ReadString ()); break; case svc_cutscene: cl.intermission = 3; cl.completed_time = cl.time; vid.recalc_refdef = true; // go to full screen SCR_CenterPrint (MSG_ReadString ()); break; case svc_sellscreen: Cmd_ExecuteString ("help", src_command); break; */ case svc_set_view_flags: cl.viewent.drawflags |= MSG_ReadByte(); break; case svc_clear_view_flags: cl.viewent.drawflags &= ~MSG_ReadByte(); break; case svc_start_effect: CL_ParseEffect(); break; case svc_end_effect: CL_EndEffect(); break; case svc_plaque: CL_Plaque(); break; case svc_particle_explosion: CL_ParticleExplosion(); break; case svc_set_view_tint: i = MSG_ReadByte(); cl.viewent.colorshade = i; break; case svc_reference: packet_loss = false; cl.last_frame = cl.current_frame; cl.last_sequence = cl.current_sequence; cl.current_frame = MSG_ReadByte(); cl.current_sequence = MSG_ReadByte(); if (cl.need_build == 2) { // Con_Printf("CL: NB2 CL(%d,%d) R(%d)\n", cl.current_sequence, cl.current_frame,cl.reference_frame); cl.frames[0].count = cl.frames[1].count = cl.frames[2].count = 0; cl.need_build = 1; cl.reference_frame = cl.current_frame; } else if (cl.last_sequence != cl.current_sequence) { // Con_Printf("CL: Sequence CL(%d,%d) R(%d)\n", cl.current_sequence, cl.current_frame,cl.reference_frame); if (cl.reference_frame >= 1 && cl.reference_frame <= MAX_FRAMES) { RemovePlace = OrigPlace = NewPlace = AddedIndex = 0; for (i = 0; i < cl.num_entities; i++) { if (RemovePlace >= cl.NumToRemove || cl.RemoveList[RemovePlace] != i) { if (NewPlace < cl.frames[1].count && cl.frames[1].states[NewPlace].index == i) { cl.frames[2].states[AddedIndex] = cl.frames[1].states[NewPlace]; AddedIndex++; cl.frames[2].count++; } else if (OrigPlace < cl.frames[0].count && cl.frames[0].states[OrigPlace].index == i) { cl.frames[2].states[AddedIndex] = cl.frames[0].states[OrigPlace]; AddedIndex++; cl.frames[2].count++; } } else RemovePlace++; if (cl.frames[0].states[OrigPlace].index == i) OrigPlace++; if (cl.frames[1].states[NewPlace].index == i) NewPlace++; } cl.frames[0] = cl.frames[2]; } cl.frames[1].count = cl.frames[2].count = 0; cl.need_build = 1; cl.reference_frame = cl.current_frame; } else { // Con_Printf("CL: Normal CL(%d,%d) R(%d)\n", cl.current_sequence, cl.current_frame,cl.reference_frame); cl.need_build = 0; } for (i = 1, ent = cl_entities+1; i < cl.num_entities; i++, ent++) { ent->baseline.flags &= ~BE_ON; } for (i = 0; i < cl.frames[0].count; i++) { ent = CL_EntityNum (cl.frames[0].states[i].index); ent->model = cl.model_precache[cl.frames[0].states[i].modelindex]; ent->baseline.flags |= BE_ON; } break; case svc_clear_edicts: j = MSG_ReadByte(); if (cl.need_build) { cl.NumToRemove = j; } for (i = 0; i < j; i++) { k = MSG_ReadShort(); if (cl.need_build) cl.RemoveList[i] = k; ent = CL_EntityNum (k); ent->baseline.flags &= ~BE_ON; } break; case svc_update_inv: sc1 = sc2 = 0; test = MSG_ReadByte(); if (test & 1) sc1 |= ((int)MSG_ReadByte()); if (test & 2) sc1 |= ((int)MSG_ReadByte())<<8; if (test & 4) sc1 |= ((int)MSG_ReadByte())<<16; if (test & 8) sc1 |= ((int)MSG_ReadByte())<<24; if (test & 16) sc2 |= ((int)MSG_ReadByte()); if (test & 32) sc2 |= ((int)MSG_ReadByte())<<8; if (test & 64) sc2 |= ((int)MSG_ReadByte())<<16; if (test & 128) sc2 |= ((int)MSG_ReadByte())<<24; if (sc1 & SC1_HEALTH) cl.v.health = MSG_ReadShort(); if (sc1 & SC1_LEVEL) cl.v.level = MSG_ReadByte(); if (sc1 & SC1_INTELLIGENCE) cl.v.intelligence = MSG_ReadByte(); if (sc1 & SC1_WISDOM) cl.v.wisdom = MSG_ReadByte(); if (sc1 & SC1_STRENGTH) cl.v.strength = MSG_ReadByte(); if (sc1 & SC1_DEXTERITY) cl.v.dexterity = MSG_ReadByte(); if (sc1 & SC1_WEAPON) cl.v.weapon = MSG_ReadByte(); if (sc1 & SC1_BLUEMANA) cl.v.bluemana = MSG_ReadByte(); if (sc1 & SC1_GREENMANA) cl.v.greenmana = MSG_ReadByte(); if (sc1 & SC1_EXPERIENCE) cl.v.experience = MSG_ReadLong(); if (sc1 & SC1_CNT_TORCH) cl.v.cnt_torch = MSG_ReadByte(); if (sc1 & SC1_CNT_H_BOOST) cl.v.cnt_h_boost = MSG_ReadByte(); if (sc1 & SC1_CNT_SH_BOOST) cl.v.cnt_sh_boost = MSG_ReadByte(); if (sc1 & SC1_CNT_MANA_BOOST) cl.v.cnt_mana_boost = MSG_ReadByte(); if (sc1 & SC1_CNT_TELEPORT) cl.v.cnt_teleport = MSG_ReadByte(); if (sc1 & SC1_CNT_TOME) cl.v.cnt_tome = MSG_ReadByte(); if (sc1 & SC1_CNT_SUMMON) cl.v.cnt_summon = MSG_ReadByte(); if (sc1 & SC1_CNT_INVISIBILITY) cl.v.cnt_invisibility = MSG_ReadByte(); if (sc1 & SC1_CNT_GLYPH) cl.v.cnt_glyph = MSG_ReadByte(); if (sc1 & SC1_CNT_HASTE) cl.v.cnt_haste = MSG_ReadByte(); if (sc1 & SC1_CNT_BLAST) cl.v.cnt_blast = MSG_ReadByte(); if (sc1 & SC1_CNT_POLYMORPH) cl.v.cnt_polymorph = MSG_ReadByte(); if (sc1 & SC1_CNT_FLIGHT) cl.v.cnt_flight = MSG_ReadByte(); if (sc1 & SC1_CNT_CUBEOFFORCE) cl.v.cnt_cubeofforce = MSG_ReadByte(); if (sc1 & SC1_CNT_INVINCIBILITY) cl.v.cnt_invincibility = MSG_ReadByte(); if (sc1 & SC1_ARTIFACT_ACTIVE) cl.v.artifact_active = MSG_ReadFloat(); if (sc1 & SC1_ARTIFACT_LOW) cl.v.artifact_low = MSG_ReadFloat(); if (sc1 & SC1_MOVETYPE) cl.v.movetype = MSG_ReadByte(); if (sc1 & SC1_CAMERAMODE) cl.v.cameramode = MSG_ReadByte(); if (sc1 & SC1_HASTED) cl.v.hasted = MSG_ReadFloat(); if (sc1 & SC1_INVENTORY) cl.v.inventory = MSG_ReadByte(); if (sc1 & SC1_RINGS_ACTIVE) cl.v.rings_active = MSG_ReadFloat(); if (sc2 & SC2_RINGS_LOW) cl.v.rings_low = MSG_ReadFloat(); if (sc2 & SC2_AMULET) cl.v.armor_amulet = MSG_ReadByte(); if (sc2 & SC2_BRACER) cl.v.armor_bracer = MSG_ReadByte(); if (sc2 & SC2_BREASTPLATE) cl.v.armor_breastplate = MSG_ReadByte(); if (sc2 & SC2_HELMET) cl.v.armor_helmet = MSG_ReadByte(); if (sc2 & SC2_FLIGHT_T) cl.v.ring_flight = MSG_ReadByte(); if (sc2 & SC2_WATER_T) cl.v.ring_water = MSG_ReadByte(); if (sc2 & SC2_TURNING_T) cl.v.ring_turning = MSG_ReadByte(); if (sc2 & SC2_REGEN_T) cl.v.ring_regeneration = MSG_ReadByte(); if (sc2 & SC2_HASTE_T) cl.v.haste_time = MSG_ReadFloat(); if (sc2 & SC2_TOME_T) cl.v.tome_time = MSG_ReadFloat(); if (sc2 & SC2_PUZZLE1) q_snprintf(cl.puzzle_pieces[0], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString()); if (sc2 & SC2_PUZZLE2) q_snprintf(cl.puzzle_pieces[1], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString()); if (sc2 & SC2_PUZZLE3) q_snprintf(cl.puzzle_pieces[2], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString()); if (sc2 & SC2_PUZZLE4) q_snprintf(cl.puzzle_pieces[3], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString()); if (sc2 & SC2_PUZZLE5) q_snprintf(cl.puzzle_pieces[4], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString()); if (sc2 & SC2_PUZZLE6) q_snprintf(cl.puzzle_pieces[5], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString()); if (sc2 & SC2_PUZZLE7) q_snprintf(cl.puzzle_pieces[6], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString()); if (sc2 & SC2_PUZZLE8) q_snprintf(cl.puzzle_pieces[7], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString()); if (sc2 & SC2_MAXHEALTH) cl.v.max_health = MSG_ReadShort(); if (sc2 & SC2_MAXMANA) cl.v.max_mana = MSG_ReadByte(); if (sc2 & SC2_FLAGS) cl.v.flags = MSG_ReadFloat(); // SC2_OBJ, SC2_OBJ2: mission pack objectives // With protocol 18 (PROTOCOL_RAVEN_111), these // bits get set somehow (?!): let's avoid them. if (cl_protocol > PROTOCOL_RAVEN_111) { if (sc2 & SC2_OBJ) cl.info_mask = MSG_ReadLong(); if (sc2 & SC2_OBJ2) cl.info_mask2 = MSG_ReadLong(); } if ((sc1 & SC1_STAT_BAR) || (sc2 & SC2_STAT_BAR)) Sbar_Changed(); if ((sc1 & SC1_INV) || (sc2 & SC2_INV)) SB_InvChanged(); break; case svc_mod_name: case svc_skybox: MSG_ReadString(); Con_DPrintf ("Ignored server msg %d (%s)\n", cmd, svc_strings[cmd]); break; } } }
static void CL_ParseUpdate2 (int bits) { int i; if (bits & U_MOREBITS) { i = MSG_ReadByte (); bits |= (i<<8); } if (bits & U_MOREBITS2) { i = MSG_ReadByte (); bits |= (i<<16); } if (bits & U_LONGENTITY) MSG_ReadShort (); else MSG_ReadByte (); if (bits & U_MODEL) { MSG_ReadShort (); } if (bits & U_FRAME) MSG_ReadByte (); if (bits & U_COLORMAP) MSG_ReadByte(); if (bits & U_SKIN) { MSG_ReadByte(); MSG_ReadByte(); } if (bits & U_EFFECTS) MSG_ReadByte(); if (bits & U_ORIGIN1) MSG_ReadCoord (); if (bits & U_ANGLE1) MSG_ReadAngle(); if (bits & U_ORIGIN2) MSG_ReadCoord (); if (bits & U_ANGLE2) MSG_ReadAngle(); if (bits & U_ORIGIN3) MSG_ReadCoord (); if (bits & U_ANGLE3) MSG_ReadAngle(); if (bits&U_SCALE) { MSG_ReadByte(); MSG_ReadByte(); } }
/* ================== 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. ================== */ static void CL_ParseUpdate (int bits) { int i; model_t *model; int modnum; qboolean forcelink; entity_t *ent; int num; entity_state2_t *ref_ent,*set_ent,build_ent,dummy; 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_MOREBITS2) { i = MSG_ReadByte (); bits |= (i<<16); } if (bits & U_LONGENTITY) num = MSG_ReadShort (); else num = MSG_ReadByte (); ent = CL_EntityNum (num); ent->baseline.flags |= BE_ON; /* if (num == 2) { FH = fopen("c.txt","r+"); fseek(FH,0,SEEK_END); } */ ref_ent = NULL; for (i = 0; i < cl.frames[0].count; i++) if (cl.frames[0].states[i].index == num) { ref_ent = &cl.frames[0].states[i]; // if (num == 2) fprintf(FH,"Found Reference\n"); break; } if (!ref_ent) { ref_ent = &build_ent; build_ent.index = num; build_ent.origin[0] = ent->baseline.origin[0]; build_ent.origin[1] = ent->baseline.origin[1]; build_ent.origin[2] = ent->baseline.origin[2]; build_ent.angles[0] = ent->baseline.angles[0]; build_ent.angles[1] = ent->baseline.angles[1]; build_ent.angles[2] = ent->baseline.angles[2]; build_ent.modelindex = ent->baseline.modelindex; build_ent.frame = ent->baseline.frame; build_ent.colormap = ent->baseline.colormap; build_ent.skin = ent->baseline.skin; build_ent.effects = ent->baseline.effects; build_ent.scale = ent->baseline.scale; build_ent.drawflags = ent->baseline.drawflags; build_ent.abslight = ent->baseline.abslight; } if (cl.need_build) { // new sequence, first valid frame set_ent = &cl.frames[1].states[cl.frames[1].count]; cl.frames[1].count++; } else set_ent = &dummy; if (bits & U_CLEAR_ENT) { memset(ent, 0, sizeof(entity_t)); memset(ref_ent, 0, sizeof(*ref_ent)); ref_ent->index = num; } *set_ent = *ref_ent; 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_ReadShort (); if (modnum >= MAX_MODELS) Host_Error ("%s: bad modnum", __thisfunc__); } else modnum = ref_ent->modelindex; model = cl.model_precache[modnum]; set_ent->modelindex = 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 = rand() * (1.0 / RAND_MAX);//(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) set_ent->frame = ent->frame = MSG_ReadByte (); else ent->frame = ref_ent->frame; if (bits & U_COLORMAP) set_ent->colormap = i = MSG_ReadByte(); else i = ref_ent->colormap; if (num && num <= cl.maxclients) ent->colormap = ent->sourcecolormap = cl.scores[num-1].translations; else ent->sourcecolormap = vid.colormap; #ifdef GLQUAKE // ent->colormap = vid.colormap; #endif if (!i) { ent->colorshade = i; ent->colormap = ent->sourcecolormap; } else { ent->colorshade = i; #ifdef GLQUAKE // ent->colormap = vid.colormap; ent->colormap = globalcolormap; #else ent->colormap = globalcolormap; #endif } if (bits & U_SKIN) { set_ent->skin = ent->skinnum = MSG_ReadByte(); set_ent->drawflags = ent->drawflags = MSG_ReadByte(); } else { ent->skinnum = ref_ent->skin; ent->drawflags = ref_ent->drawflags; } if (bits & U_EFFECTS) { set_ent->effects = ent->effects = MSG_ReadByte(); // if (num == 2) // fprintf(FH,"Read effects %d\n",set_ent->effects); } else { ent->effects = ref_ent->effects; //if (num == 2) // fprintf(FH,"restored effects %d\n",ref_ent->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) { set_ent->origin[0] = ent->msg_origins[0][0] = MSG_ReadCoord (); //if (num == 2) // fprintf(FH,"Read origin[0] %f\n",set_ent->angles[0]); } else { ent->msg_origins[0][0] = ref_ent->origin[0]; //if (num == 2) // fprintf(FH,"Restored origin[0] %f\n",ref_ent->angles[0]); } if (bits & U_ANGLE1) set_ent->angles[0] = ent->msg_angles[0][0] = MSG_ReadAngle(); else ent->msg_angles[0][0] = ref_ent->angles[0]; if (bits & U_ORIGIN2) set_ent->origin[1] = ent->msg_origins[0][1] = MSG_ReadCoord (); else ent->msg_origins[0][1] = ref_ent->origin[1]; if (bits & U_ANGLE2) set_ent->angles[1] = ent->msg_angles[0][1] = MSG_ReadAngle(); else ent->msg_angles[0][1] = ref_ent->angles[1]; if (bits & U_ORIGIN3) set_ent->origin[2] = ent->msg_origins[0][2] = MSG_ReadCoord (); else ent->msg_origins[0][2] = ref_ent->origin[2]; if (bits & U_ANGLE3) set_ent->angles[2] = ent->msg_angles[0][2] = MSG_ReadAngle(); else ent->msg_angles[0][2] = ref_ent->angles[2]; if (bits & U_SCALE) { set_ent->scale = ent->scale = MSG_ReadByte(); set_ent->abslight = ent->abslight = MSG_ReadByte(); } else { ent->scale = ref_ent->scale; ent->abslight = ref_ent->abslight; } 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; } // if (sv.active || num != 2) // return; }
float EXT_FUNC MSG_ReadAngle_api() { return MSG_ReadAngle(); }
/* ================== CL_ParseUpdate_H2 ================== */ qboolean CL_ParseUpdate_H2 (entity_t *ent, int num, int bits) { entity_state_t *ref_ent, *set_ent, dummy; qboolean forcelink; int i, modnum, flag; model_t *model; ent->baseline.flags |= ENT_STATE_ON; ref_ent = NULL; for (i=0; i < cl.frames[0].count; i++) { if (cl.frames[0].states[i].index == num) { ref_ent = &cl.frames[0].states[i]; // if (entnum == 2) fprintf(FH,"Found Reference\n"); break; } } if (!ref_ent) { ref_ent = &ent->baseline; ref_ent->index = num; } if (bits & U_CLEAR_ENT) { memset(ent, 0, sizeof(entity_t)); memset(ref_ent, 0, sizeof(entity_state_t)); ref_ent->index = num; } if (cl.need_build) // new sequence, first valid frame { set_ent = &cl.frames[1].states[cl.frames[1].count]; cl.frames[1].count++; *set_ent = *ref_ent; } else set_ent = &dummy; forcelink = (ent->msgtime != cl.mtime_prev) ? true : false; ent->msgtime = cl.mtime; if (bits & U_MODEL) { modnum = MSG_ReadShort (); if (modnum >= MAX_MODELS) Host_Error ("CL_ParseModel: bad modnum"); } else modnum = ref_ent->modelindex; model = cl.model_precache[modnum]; set_ent->modelindex = 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 = rand()*(1.0/RAND_MAX);//(float)(rand()&0x7fff) / 0x7fff; else ent->syncbase = 0.0; } else forcelink = true; // hack to make null model players work if (num > 0 && num <= cl.maxclients) R_TranslatePlayerSkin (num - 1); // **** FIXME: need Hexen II-specific proc **** } if (bits & U_FRAME) set_ent->frame = ent->frame = MSG_ReadByte (); else ent->frame = ref_ent->frame; if (bits & U_COLORMAP_H2) set_ent->colormap = i = MSG_ReadByte(); else i = ref_ent->colormap; if (num && num <= cl.maxclients) ent->colormap = /*ent->sourcecolormap =*/ cl.scores[num-1].translations; /*else ent->sourcecolormap = vid.colormap;*/ ent->colorshade = i; // ent->colormap = i ? globalcolormap : ent->sourcecolormap; if (bits & U_SKIN_H2) { set_ent->skin = ent->skinnum = MSG_ReadByte(); set_ent->drawflags = ent->drawflags = MSG_ReadByte(); } else { ent->skinnum = ref_ent->skin; ent->drawflags = ref_ent->drawflags; } if (bits & U_EFFECTS_H2) { set_ent->effects = ent->effects = MSG_ReadByte(); // if (num == 2) fprintf(FH,"Read effects %d\n",set_ent->effects); } else { ent->effects = ref_ent->effects; //if (num == 2) fprintf(FH,"restored effects %d\n",ref_ent->effects); } // shift the known values for interpolation VectorCopy (ent->msg_origin, ent->msg_origin_prev); VectorCopy (ent->msg_angles, ent->msg_angles_prev); for (i = 0; i < 3; i++) { if (bits & (U_ORIGIN1 << i)) { set_ent->origin[i] = ent->msg_origin[i] = MSG_ReadCoord(); } else ent->msg_origin[i] = ref_ent->origin[i]; flag = (i == 0) ? U_ANGLE1 : (i == 1) ? U_ANGLE2 : U_ANGLE3; if (bits & flag) { set_ent->angles[i] = ent->msg_angles[i] = MSG_ReadAngle(); #ifdef _DEBUG if (ent->model && (ent->model->type == mod_brush)) i *= 1; #endif } else ent->msg_angles[i] = ref_ent->angles[i]; } // JDH: blatant hack to smooth rotating entities if (sv.active && (bits & (U_ANGLE1 | U_ANGLE2 | U_ANGLE3))) { edict_t *ed = EDICT_NUM(num); if (ed) VectorCopy (ed->v.angles, ent->msg_angles); } if (bits & U_SCALE) { set_ent->scale = ent->scale = MSG_ReadByte(); set_ent->abslight = ent->abslight = MSG_ReadByte(); } else { ent->scale = ref_ent->scale; ent->abslight = ref_ent->abslight; } return forcelink; }
/* ================== 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. ================== */ void CL_ParseUpdate (int bits) { int i; qmodel_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); } //johnfitz -- PROTOCOL_FITZQUAKE if (cl.protocol == PROTOCOL_FITZQUAKE) { if (bits & U_EXTEND1) bits |= MSG_ReadByte() << 16; if (bits & U_EXTEND2) bits |= MSG_ReadByte() << 24; } //johnfitz if (bits & U_LONGENTITY) num = MSG_ReadShort (); else num = MSG_ReadByte (); ent = CL_EntityNum (num); if (ent->msgtime != cl.mtime[1]) forcelink = true; // no previous frame to lerp from else forcelink = false; //johnfitz -- lerping if (ent->msgtime + 0.2 < cl.mtime[0]) //more than 0.2 seconds since the last message (most entities think every 0.1 sec) ent->lerpflags |= LERP_RESETANIM; //if we missed a think, we'd be lerping from the wrong frame //johnfitz 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; 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; } 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_TranslateNewPlayerSkin (num - 1); //johnfitz -- was R_TranslatePlayerSkin } 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]; //johnfitz -- lerping for movetype_step entities if (bits & U_STEP) { ent->lerpflags |= LERP_MOVESTEP; ent->forcelink = true; } else ent->lerpflags &= ~LERP_MOVESTEP; //johnfitz //johnfitz -- PROTOCOL_FITZQUAKE and PROTOCOL_NEHAHRA if (cl.protocol == PROTOCOL_FITZQUAKE) { if (bits & U_ALPHA) ent->alpha = MSG_ReadByte(); else ent->alpha = ent->baseline.alpha; if (bits & U_FRAME2) ent->frame = (ent->frame & 0x00FF) | (MSG_ReadByte() << 8); if (bits & U_MODEL2) modnum = (modnum & 0x00FF) | (MSG_ReadByte() << 8); if (bits & U_LERPFINISH) { ent->lerpfinish = ent->msgtime + ((float)(MSG_ReadByte()) / 255); ent->lerpflags |= LERP_FINISH; } else ent->lerpflags &= ~LERP_FINISH; } else if (cl.protocol == PROTOCOL_NETQUAKE) { //HACK: if this bit is set, assume this is PROTOCOL_NEHAHRA if (bits & U_TRANS) { float a, b; if (warn_about_nehahra_protocol) { Con_Warning ("nonstandard update bit, assuming Nehahra protocol\n"); warn_about_nehahra_protocol = false; } a = MSG_ReadFloat(); b = MSG_ReadFloat(); //alpha if (a == 2) MSG_ReadFloat(); //fullbright (not using this yet) ent->alpha = ENTALPHA_ENCODE(b); } else ent->alpha = ent->baseline.alpha; } //johnfitz //johnfitz -- moved here from above 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 if (num > 0 && num <= cl.maxclients) R_TranslateNewPlayerSkin (num - 1); //johnfitz -- was R_TranslatePlayerSkin ent->lerpflags |= LERP_RESETANIM; //johnfitz -- don't lerp animation across model changes } //johnfitz 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_ParseServerMessage ===================== */ void CL_ParseServerMessage (void) { int cmd; int i; const char *str; //johnfitz int total, j, lastcmd; //johnfitz // // 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 (); lastcmd = 0; 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 & U_SIGNAL) //johnfitz -- was 128, changed for clarity { SHOWNET("fast update"); CL_ParseUpdate (cmd&127); continue; } SHOWNET(svc_strings[cmd]); // other commands switch (cmd) { default: Host_Error ("Illegible server message, previous was %s\n", svc_strings[lastcmd]); //johnfitz -- added svc_strings[lastcmd] 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: CL_ParseClientdata (); //johnfitz -- removed bits parameter, we will read this inside CL_ParseClientdata() break; case svc_version: i = MSG_ReadLong (); //johnfitz -- support multiple protocols if (i != PROTOCOL_NETQUAKE && i != PROTOCOL_FITZQUAKE) Host_Error ("Server returned version %i, not %i or %i\n", i, PROTOCOL_NETQUAKE, PROTOCOL_FITZQUAKE); cl.protocol = i; //johnfitz break; case svc_disconnect: Host_EndGame ("Server disconnected\n"); case svc_print: Con_Printf ("%s", MSG_ReadString ()); break; case svc_centerprint: //johnfitz -- log centerprints to console str = MSG_ReadString (); SCR_CenterPrint (str); Con_LogCenterPrint (str); //johnfitz break; case svc_stufftext: cls.stufftext_frame = host_framecount; // allow full frame update // in demo playback -- Pa3PyX 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_strlcpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING); cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map); //johnfitz -- save extra info if (cl_lightstyle[i].length) { total = 0; cl_lightstyle[i].peak = 'a'; for (j=0; j<cl_lightstyle[i].length; j++) { total += cl_lightstyle[i].map[j] - 'a'; cl_lightstyle[i].peak = q_max(cl_lightstyle[i].peak, cl_lightstyle[i].map[j]); } cl_lightstyle[i].average = total / cl_lightstyle[i].length + 'a'; } else cl_lightstyle[i].average = cl_lightstyle[i].peak = 'm'; //johnfitz 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"); q_strlcpy (cl.scores[i].name, MSG_ReadString(), MAX_SCOREBOARDNAME); 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), 1); // johnfitz -- added second parameter break; case svc_spawnstatic: CL_ParseStatic (1); //johnfitz -- added parameter break; case svc_temp_entity: CL_ParseTEnt (); break; case svc_setpause: cl.paused = MSG_ReadByte (); if (cl.paused) { CDAudio_Pause (); BGM_Pause (); } else { CDAudio_Resume (); BGM_Resume (); } 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; //johnfitz -- if signonnum==2, signon packet has been fully parsed, so check for excessive static ents and efrags if (i == 2) { if (cl.num_statics > 128) Con_Warning ("%i static entities exceeds standard limit of 128.\n", cl.num_statics); R_CheckEfrags (); } //johnfitz 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 (1); //johnfitz -- added parameter break; case svc_cdtrack: cl.cdtrack = MSG_ReadByte (); cl.looptrack = MSG_ReadByte (); if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) ) BGM_PlayCDtrack ((byte)cls.forcetrack, true); else BGM_PlayCDtrack ((byte)cl.cdtrack, true); break; case svc_intermission: cl.intermission = 1; cl.completed_time = cl.time; vid.recalc_refdef = true; // go to full screen break; case svc_finale: cl.intermission = 2; cl.completed_time = cl.time; vid.recalc_refdef = true; // go to full screen //johnfitz -- log centerprints to console str = MSG_ReadString (); SCR_CenterPrint (str); Con_LogCenterPrint (str); //johnfitz break; case svc_cutscene: cl.intermission = 3; cl.completed_time = cl.time; vid.recalc_refdef = true; // go to full screen //johnfitz -- log centerprints to console str = MSG_ReadString (); SCR_CenterPrint (str); Con_LogCenterPrint (str); //johnfitz break; case svc_sellscreen: Cmd_ExecuteString ("help", src_command); break; //johnfitz -- new svc types case svc_skybox: Sky_LoadSkyBox (MSG_ReadString()); break; case svc_bf: Cmd_ExecuteString ("bf", src_command); break; case svc_fog: Fog_ParseServerMessage (); break; case svc_spawnbaseline2: //PROTOCOL_FITZQUAKE i = MSG_ReadShort (); // must use CL_EntityNum() to force cl.num_entities up CL_ParseBaseline (CL_EntityNum(i), 2); break; case svc_spawnstatic2: //PROTOCOL_FITZQUAKE CL_ParseStatic (2); break; case svc_spawnstaticsound2: //PROTOCOL_FITZQUAKE CL_ParseStaticSound (2); break; //johnfitz } lastcmd = cmd; //johnfitz } }
void Parse_Packetentities (bool delta){ int from; int word; int bits; int i; if (delta) { from = MSG_ReadByte (); } else { } while (1) { word = (unsigned short) MSG_ReadShort (); //printf("%i %i\n",msg_readcount,word); if (!word) { break; } if (msg_badread) { // something didn't parse right... printf ("msg_badread in packetentities\n"); break;//exit(1); } word &= ~511; bits = word; if (bits & U_MOREBITS) { i = MSG_ReadByte(); bits |= i; } if (bits & U_MODEL) MSG_ReadByte(); if (bits & U_FRAME) MSG_ReadByte(); if (bits & U_COLORMAP) MSG_ReadByte(); if (bits & U_SKIN) MSG_ReadByte(); if (bits & U_EFFECTS) MSG_ReadByte(); if (bits & U_ORIGIN1) MSG_ReadCoord(); if (bits & U_ORIGIN2) MSG_ReadCoord(); if (bits & U_ORIGIN3) MSG_ReadCoord(); if (bits & U_ANGLE1) MSG_ReadAngle(); if (bits & U_ANGLE2) MSG_ReadAngle(); if (bits & U_ANGLE3) MSG_ReadAngle(); } }
void CLNQ_ParseServerMessage (void) { int cmd; int i; qbool message_with_datagram; // hack to fix glitches when receiving a packet // without a datagram nq_player_teleported = false; // OMG, it's a hack! message_with_datagram = false; cl_entframecount++; if (cl_shownet.value == 1) Com_Printf ("%i ", net_message.cursize); else if (cl_shownet.value == 2) Com_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"); if (!message_with_datagram) { cl_entframecount--; } else { VectorCopy (nq_mviewangles[0], nq_mviewangles[1]); VectorCopy (nq_mviewangles_temp, nq_mviewangles[0]); } 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"); NQD_ParseUpdate (cmd&127); continue; } if (cmd < num_svc_strings) SHOWNET(svc_strings[cmd]); // other commands switch (cmd) { default: Host_Error ("CL_ParseServerMessage: Illegible server message"); break; case svc_nop: break; case nq_svc_time: nq_mtime[1] = nq_mtime[0]; nq_mtime[0] = MSG_ReadFloat (); cl.servertime = nq_mtime[0]; message_with_datagram = true; break; case nq_svc_clientdata: i = MSG_ReadShort (); NQD_ParseClientdata (i); break; case nq_svc_version: i = MSG_ReadLong (); if (i != NQ_PROTOCOL_VERSION) Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, NQ_PROTOCOL_VERSION); break; case svc_disconnect: Com_Printf ("\n======== End of demo ========\n\n"); CL_NextDemo (); Host_EndGame (); Host_Abort (); break; case svc_print: NQD_ParsePrint (); break; case svc_centerprint: SCR_CenterPrint (MSG_ReadString ()); break; case svc_stufftext: NQD_ParseStufftext (); break; case svc_damage: V_ParseDamage (); break; case svc_serverdata: NQD_ParseServerData (); break; case svc_setangle: for (i=0 ; i<3 ; i++) nq_last_fixangle[i] = cl.simangles[i] = cl.viewangles[i] = MSG_ReadAngle (); break; case svc_setview: nq_viewentity = MSG_ReadShort (); if (nq_viewentity <= nq_maxclients) cl.playernum = nq_viewentity - 1; else { // just let cl.playernum stay where it was } break; case svc_lightstyle: i = MSG_ReadByte (); if (i >= MAX_LIGHTSTYLES) Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES"); strlcpy (cl_lightstyle[i].map, MSG_ReadString(), sizeof(cl_lightstyle[0].map)); cl_lightstyle[i].length = strlen(cl_lightstyle[i].map); break; case svc_sound: NQD_ParseStartSoundPacket(); break; case svc_stopsound: i = MSG_ReadShort(); S_StopSound(i>>3, i&7); break; case nq_svc_updatename: Sbar_Changed (); i = MSG_ReadByte (); if (i >= nq_maxclients) Host_Error ("CL_ParseServerMessage: svc_updatename > NQ_MAX_CLIENTS"); strlcpy (cl.players[i].name, MSG_ReadString(), sizeof(cl.players[i].name)); break; case svc_updatefrags: Sbar_Changed (); i = MSG_ReadByte (); if (i >= nq_maxclients) Host_Error ("CL_ParseServerMessage: svc_updatefrags > NQ_MAX_CLIENTS"); cl.players[i].frags = MSG_ReadShort(); break; case nq_svc_updatecolors: NQD_ParseUpdatecolors (); break; case nq_svc_particle: CL_ParseParticleEffect (); break; case svc_spawnbaseline: i = MSG_ReadShort (); if (i >= NQ_MAX_EDICTS) Host_Error ("svc_spawnbaseline: ent > MAX_EDICTS"); NQD_BumpEntityCount (i); CL_ParseBaseline (&cl_entities[i].baseline); break; case svc_spawnstatic: CL_ParseStatic (); break; case svc_temp_entity: CL_ParseTEnt (); break; case svc_setpause: if (MSG_ReadByte() != 0) cl.paused |= PAUSED_SERVER; else cl.paused &= ~PAUSED_SERVER; if (cl.paused) CDAudio_Pause (); else CDAudio_Resume (); break; case nq_svc_signonnum: i = MSG_ReadByte (); if (i <= nq_signon) Host_Error ("Received signon %i when at %i", i, nq_signon); nq_signon = i; CLNQ_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 (); MSG_ReadByte(); // loop track (unused) if (nq_forcecdtrack != -1) CDAudio_Play ((byte)nq_forcecdtrack, true); else CDAudio_Play ((byte)cl.cdtrack, true); break; case svc_intermission: cl.intermission = 1; cl.completed_time = cl.time; VectorCopy (nq_last_fixangle, cl.simangles); break; case svc_finale: cl.intermission = 2; cl.completed_time = cl.time; SCR_CenterPrint (MSG_ReadString ()); VectorCopy (nq_last_fixangle, cl.simangles); break; case nq_svc_cutscene: cl.intermission = 3; cl.completed_time = cl.time; SCR_CenterPrint (MSG_ReadString ()); VectorCopy (nq_last_fixangle, cl.simangles); break; case svc_sellscreen: break; } } }
/* ================== CL_ParseDelta Can go from either a baseline or a previous packet_entity ================== */ void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int number, int bits) { // set everything to the state we are delta'ing from *to = *from; VectorCopy(from->origin, to->old_origin); to->number = number; if (bits & U_MODEL) to->modelindex = MSG_ReadByte(&net_message); if (bits & U_MODEL2) to->modelindex2 = MSG_ReadByte(&net_message); if (bits & U_MODEL3) to->modelindex3 = MSG_ReadByte(&net_message); if (bits & U_MODEL4) to->modelindex4 = MSG_ReadByte(&net_message); if (bits & U_FRAME8) to->frame = MSG_ReadByte(&net_message); if (bits & U_FRAME16) to->frame = MSG_ReadShort(&net_message); assert(to->skinnum >= 0); // jitdebug if ((bits & U_SKIN8) && (bits & U_SKIN16)) //used for laser colors to->skinnum = MSG_ReadLong(&net_message); else if (bits & U_SKIN8) to->skinnum = MSG_ReadByte(&net_message); else if (bits & U_SKIN16) to->skinnum = MSG_ReadShort(&net_message); assert(to->skinnum >= 0); if ((bits & (U_EFFECTS8|U_EFFECTS16)) == (U_EFFECTS8|U_EFFECTS16)) to->effects = MSG_ReadLong(&net_message); else if (bits & U_EFFECTS8) to->effects = MSG_ReadByte(&net_message); else if (bits & U_EFFECTS16) to->effects = MSG_ReadShort(&net_message); if ((bits & (U_RENDERFX8|U_RENDERFX16)) == (U_RENDERFX8|U_RENDERFX16)) to->renderfx = MSG_ReadLong(&net_message); else if (bits & U_RENDERFX8) to->renderfx = MSG_ReadByte(&net_message); else if (bits & U_RENDERFX16) to->renderfx = MSG_ReadShort(&net_message); if (bits & U_ORIGIN1) to->origin[0] = MSG_ReadCoord(&net_message); if (bits & U_ORIGIN2) to->origin[1] = MSG_ReadCoord(&net_message); if (bits & U_ORIGIN3) to->origin[2] = MSG_ReadCoord(&net_message); if (bits & U_ANGLE1) to->angles[0] = MSG_ReadAngle(&net_message); if (bits & U_ANGLE2) to->angles[1] = MSG_ReadAngle(&net_message); if (bits & U_ANGLE3) to->angles[2] = MSG_ReadAngle(&net_message); if (bits & U_OLDORIGIN) MSG_ReadPos(&net_message, to->old_origin); if (bits & U_SOUND) to->sound = MSG_ReadByte(&net_message); if (bits & U_EVENT) to->event = MSG_ReadByte(&net_message); else to->event = 0; if (bits & U_SOLID) to->solid = MSG_ReadShort(&net_message); }