mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-22 20:51:31 +00:00
Entity-Parsing nach cl_parse.c verschoben
This commit is contained in:
parent
ca2e9c48e7
commit
600c232d1c
3 changed files with 561 additions and 553 deletions
|
@ -1,24 +1,30 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 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 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.
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* This file implements the .cin video codec and the corresponding .pcx
|
||||
* bitmap decoder. .cin files are just a bunch of .pcx images.
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
||||
|
||||
#include "header/client.h"
|
||||
|
||||
typedef struct {
|
||||
|
@ -503,3 +509,4 @@ SCR_PlayCinematic(char *arg) {
|
|||
cin.pic = SCR_ReadNextFrame();
|
||||
cl.cinematictime = Sys_Milliseconds();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,548 +22,6 @@
|
|||
|
||||
extern struct model_s *cl_mod_powerscreen;
|
||||
int vidref_val;
|
||||
int bitcounts[32]; /* just for protocol profiling */
|
||||
|
||||
int CL_ParseEntityBits (unsigned *bits) {
|
||||
unsigned b, total;
|
||||
int i;
|
||||
int number;
|
||||
|
||||
total = MSG_ReadByte (&net_message);
|
||||
|
||||
if (total & U_MOREBITS1) {
|
||||
b = MSG_ReadByte (&net_message);
|
||||
total |= b<<8;
|
||||
}
|
||||
|
||||
if (total & U_MOREBITS2) {
|
||||
b = MSG_ReadByte (&net_message);
|
||||
total |= b<<16;
|
||||
}
|
||||
|
||||
if (total & U_MOREBITS3) {
|
||||
b = MSG_ReadByte (&net_message);
|
||||
total |= b<<24;
|
||||
}
|
||||
|
||||
/* count the bits for net profiling */
|
||||
for (i=0 ; i<32 ; i++)
|
||||
if (total&(1<<i))
|
||||
bitcounts[i]++;
|
||||
|
||||
if (total & U_NUMBER16)
|
||||
number = MSG_ReadShort (&net_message);
|
||||
|
||||
else
|
||||
number = MSG_ReadByte (&net_message);
|
||||
|
||||
*bits = total;
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
/* used for laser colors */
|
||||
if ((bits & U_SKIN8) && (bits & U_SKIN16))
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses deltas from the given base and adds the resulting entity to
|
||||
* the current frame
|
||||
*/
|
||||
void CL_DeltaEntity (frame_t *frame, int newnum, entity_state_t *old,
|
||||
int bits) {
|
||||
centity_t *ent;
|
||||
entity_state_t *state;
|
||||
|
||||
ent = &cl_entities[newnum];
|
||||
|
||||
state = &cl_parse_entities[cl.parse_entities & (MAX_PARSE_ENTITIES-1)];
|
||||
cl.parse_entities++;
|
||||
frame->num_entities++;
|
||||
|
||||
CL_ParseDelta (old, state, newnum, bits);
|
||||
|
||||
/* some data changes will force no lerping */
|
||||
if (state->modelindex != ent->current.modelindex
|
||||
|| state->modelindex2 != ent->current.modelindex2
|
||||
|| state->modelindex3 != ent->current.modelindex3
|
||||
|| state->modelindex4 != ent->current.modelindex4
|
||||
|| state->event == EV_PLAYER_TELEPORT
|
||||
|| state->event == EV_OTHER_TELEPORT
|
||||
|| abs((int)(state->origin[0] - ent->current.origin[0])) > 512
|
||||
|| abs((int)(state->origin[1] - ent->current.origin[1])) > 512
|
||||
|| abs((int)(state->origin[2] - ent->current.origin[2])) > 512
|
||||
) {
|
||||
ent->serverframe = -99;
|
||||
}
|
||||
/* wasn't in last update, so initialize some things */
|
||||
if (ent->serverframe != cl.frame.serverframe - 1) {
|
||||
ent->trailcount = 1024; /* for diminishing rocket / grenade trails */
|
||||
|
||||
/* duplicate the current state so
|
||||
* lerping doesn't hurt anything */
|
||||
ent->prev = *state;
|
||||
|
||||
if (state->event == EV_OTHER_TELEPORT) {
|
||||
VectorCopy (state->origin, ent->prev.origin);
|
||||
VectorCopy (state->origin, ent->lerp_origin);
|
||||
|
||||
} else {
|
||||
VectorCopy (state->old_origin, ent->prev.origin);
|
||||
VectorCopy (state->old_origin, ent->lerp_origin);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* shuffle the last state to previous */
|
||||
ent->prev = ent->current;
|
||||
}
|
||||
|
||||
ent->serverframe = cl.frame.serverframe;
|
||||
ent->current = *state;
|
||||
}
|
||||
|
||||
/*
|
||||
* An svc_packetentities has just been parsed, deal with the rest of the
|
||||
* data stream.
|
||||
*/
|
||||
void CL_ParsePacketEntities (frame_t *oldframe, frame_t *newframe) {
|
||||
unsigned int newnum;
|
||||
unsigned bits;
|
||||
entity_state_t
|
||||
*oldstate = NULL;
|
||||
int oldindex, oldnum;
|
||||
|
||||
newframe->parse_entities = cl.parse_entities;
|
||||
newframe->num_entities = 0;
|
||||
|
||||
/* delta from the entities present in oldframe */
|
||||
oldindex = 0;
|
||||
|
||||
if (!oldframe)
|
||||
oldnum = 99999;
|
||||
|
||||
else {
|
||||
if (oldindex >= oldframe->num_entities)
|
||||
oldnum = 99999;
|
||||
|
||||
else {
|
||||
oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
|
||||
oldnum = oldstate->number;
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
newnum = CL_ParseEntityBits (&bits);
|
||||
|
||||
if (newnum >= MAX_EDICTS)
|
||||
Com_Error (ERR_DROP,"CL_ParsePacketEntities: bad number:%i", newnum);
|
||||
|
||||
if (net_message.readcount > net_message.cursize)
|
||||
Com_Error (ERR_DROP,"CL_ParsePacketEntities: end of message");
|
||||
|
||||
if (!newnum)
|
||||
break;
|
||||
|
||||
while (oldnum < newnum) {
|
||||
/* one or more entities from the old packet are unchanged */
|
||||
if (cl_shownet->value == 3)
|
||||
Com_Printf (" unchanged: %i\n", oldnum);
|
||||
|
||||
CL_DeltaEntity (newframe, oldnum, oldstate, 0);
|
||||
|
||||
oldindex++;
|
||||
|
||||
if (oldindex >= oldframe->num_entities)
|
||||
oldnum = 99999;
|
||||
|
||||
else {
|
||||
oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
|
||||
oldnum = oldstate->number;
|
||||
}
|
||||
}
|
||||
|
||||
if (bits & U_REMOVE) {
|
||||
/* the entity present in oldframe is not in the current frame */
|
||||
if (cl_shownet->value == 3)
|
||||
Com_Printf (" remove: %i\n", newnum);
|
||||
|
||||
if (oldnum != newnum)
|
||||
Com_Printf ("U_REMOVE: oldnum != newnum\n");
|
||||
|
||||
oldindex++;
|
||||
|
||||
if (oldindex >= oldframe->num_entities)
|
||||
oldnum = 99999;
|
||||
|
||||
else {
|
||||
oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
|
||||
oldnum = oldstate->number;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (oldnum == newnum) {
|
||||
/* delta from previous state */
|
||||
if (cl_shownet->value == 3)
|
||||
Com_Printf (" delta: %i\n", newnum);
|
||||
|
||||
CL_DeltaEntity (newframe, newnum, oldstate, bits);
|
||||
|
||||
oldindex++;
|
||||
|
||||
if (oldindex >= oldframe->num_entities)
|
||||
oldnum = 99999;
|
||||
|
||||
else {
|
||||
oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
|
||||
oldnum = oldstate->number;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (oldnum > newnum) {
|
||||
/* delta from baseline */
|
||||
if (cl_shownet->value == 3)
|
||||
Com_Printf (" baseline: %i\n", newnum);
|
||||
|
||||
CL_DeltaEntity (newframe, newnum, &cl_entities[newnum].baseline, bits);
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* any remaining entities in the old frame are copied over */
|
||||
while (oldnum != 99999) {
|
||||
/* one or more entities from the old packet are unchanged */
|
||||
if (cl_shownet->value == 3)
|
||||
Com_Printf (" unchanged: %i\n", oldnum);
|
||||
|
||||
CL_DeltaEntity (newframe, oldnum, oldstate, 0);
|
||||
|
||||
oldindex++;
|
||||
|
||||
if (oldindex >= oldframe->num_entities)
|
||||
oldnum = 99999;
|
||||
|
||||
else {
|
||||
oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
|
||||
oldnum = oldstate->number;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CL_ParsePlayerstate (frame_t *oldframe, frame_t *newframe) {
|
||||
int flags;
|
||||
player_state_t *state;
|
||||
int i;
|
||||
int statbits;
|
||||
|
||||
state = &newframe->playerstate;
|
||||
|
||||
/* clear to old value before delta parsing */
|
||||
if (oldframe)
|
||||
*state = oldframe->playerstate;
|
||||
|
||||
else
|
||||
memset (state, 0, sizeof(*state));
|
||||
|
||||
flags = MSG_ReadShort (&net_message);
|
||||
|
||||
/* parse the pmove_state_t */
|
||||
if (flags & PS_M_TYPE)
|
||||
state->pmove.pm_type = MSG_ReadByte (&net_message);
|
||||
|
||||
if (flags & PS_M_ORIGIN) {
|
||||
state->pmove.origin[0] = MSG_ReadShort (&net_message);
|
||||
state->pmove.origin[1] = MSG_ReadShort (&net_message);
|
||||
state->pmove.origin[2] = MSG_ReadShort (&net_message);
|
||||
}
|
||||
|
||||
if (flags & PS_M_VELOCITY) {
|
||||
state->pmove.velocity[0] = MSG_ReadShort (&net_message);
|
||||
state->pmove.velocity[1] = MSG_ReadShort (&net_message);
|
||||
state->pmove.velocity[2] = MSG_ReadShort (&net_message);
|
||||
}
|
||||
|
||||
if (flags & PS_M_TIME)
|
||||
state->pmove.pm_time = MSG_ReadByte (&net_message);
|
||||
|
||||
if (flags & PS_M_FLAGS)
|
||||
state->pmove.pm_flags = MSG_ReadByte (&net_message);
|
||||
|
||||
if (flags & PS_M_GRAVITY)
|
||||
state->pmove.gravity = MSG_ReadShort (&net_message);
|
||||
|
||||
if (flags & PS_M_DELTA_ANGLES) {
|
||||
state->pmove.delta_angles[0] = MSG_ReadShort (&net_message);
|
||||
state->pmove.delta_angles[1] = MSG_ReadShort (&net_message);
|
||||
state->pmove.delta_angles[2] = MSG_ReadShort (&net_message);
|
||||
}
|
||||
|
||||
if (cl.attractloop)
|
||||
state->pmove.pm_type = PM_FREEZE; /* demo playback */
|
||||
|
||||
/* parse the rest of the player_state_t */
|
||||
if (flags & PS_VIEWOFFSET) {
|
||||
state->viewoffset[0] = MSG_ReadChar (&net_message) * 0.25f;
|
||||
state->viewoffset[1] = MSG_ReadChar (&net_message) * 0.25f;
|
||||
state->viewoffset[2] = MSG_ReadChar (&net_message) * 0.25f;
|
||||
}
|
||||
|
||||
if (flags & PS_VIEWANGLES) {
|
||||
state->viewangles[0] = MSG_ReadAngle16 (&net_message);
|
||||
state->viewangles[1] = MSG_ReadAngle16 (&net_message);
|
||||
state->viewangles[2] = MSG_ReadAngle16 (&net_message);
|
||||
}
|
||||
|
||||
if (flags & PS_KICKANGLES) {
|
||||
state->kick_angles[0] = MSG_ReadChar (&net_message) * 0.25f;
|
||||
state->kick_angles[1] = MSG_ReadChar (&net_message) * 0.25f;
|
||||
state->kick_angles[2] = MSG_ReadChar (&net_message) * 0.25f;
|
||||
}
|
||||
|
||||
if (flags & PS_WEAPONINDEX) {
|
||||
state->gunindex = MSG_ReadByte (&net_message);
|
||||
}
|
||||
|
||||
if (flags & PS_WEAPONFRAME) {
|
||||
state->gunframe = MSG_ReadByte (&net_message);
|
||||
state->gunoffset[0] = MSG_ReadChar (&net_message)*0.25f;
|
||||
state->gunoffset[1] = MSG_ReadChar (&net_message)*0.25f;
|
||||
state->gunoffset[2] = MSG_ReadChar (&net_message)*0.25f;
|
||||
state->gunangles[0] = MSG_ReadChar (&net_message)*0.25f;
|
||||
state->gunangles[1] = MSG_ReadChar (&net_message)*0.25f;
|
||||
state->gunangles[2] = MSG_ReadChar (&net_message)*0.25f;
|
||||
}
|
||||
|
||||
if (flags & PS_BLEND) {
|
||||
state->blend[0] = MSG_ReadByte (&net_message)/255.0f;
|
||||
state->blend[1] = MSG_ReadByte (&net_message)/255.0f;
|
||||
state->blend[2] = MSG_ReadByte (&net_message)/255.0f;
|
||||
state->blend[3] = MSG_ReadByte (&net_message)/255.0f;
|
||||
}
|
||||
|
||||
if (flags & PS_FOV)
|
||||
state->fov = (float)MSG_ReadByte (&net_message);
|
||||
|
||||
if (flags & PS_RDFLAGS)
|
||||
state->rdflags = MSG_ReadByte (&net_message);
|
||||
|
||||
/* parse stats */
|
||||
statbits = MSG_ReadLong (&net_message);
|
||||
|
||||
for (i=0 ; i<MAX_STATS ; i++)
|
||||
if (statbits & (1<<i) )
|
||||
state->stats[i] = MSG_ReadShort(&net_message);
|
||||
}
|
||||
|
||||
void CL_FireEntityEvents (frame_t *frame) {
|
||||
entity_state_t *s1;
|
||||
int pnum, num;
|
||||
|
||||
for (pnum = 0 ; pnum<frame->num_entities ; pnum++) {
|
||||
num = (frame->parse_entities + pnum)&(MAX_PARSE_ENTITIES-1);
|
||||
s1 = &cl_parse_entities[num];
|
||||
|
||||
if (s1->event)
|
||||
CL_EntityEvent (s1);
|
||||
|
||||
if (s1->effects & EF_TELEPORTER)
|
||||
CL_TeleporterParticles (s1);
|
||||
}
|
||||
}
|
||||
|
||||
void CL_ParseFrame (void) {
|
||||
int cmd;
|
||||
int len;
|
||||
frame_t *old;
|
||||
|
||||
memset (&cl.frame, 0, sizeof(cl.frame));
|
||||
|
||||
cl.frame.serverframe = MSG_ReadLong (&net_message);
|
||||
cl.frame.deltaframe = MSG_ReadLong (&net_message);
|
||||
cl.frame.servertime = cl.frame.serverframe*100;
|
||||
|
||||
/* BIG HACK to let old demos continue to work */
|
||||
if (cls.serverProtocol != 26)
|
||||
cl.surpressCount = MSG_ReadByte (&net_message);
|
||||
|
||||
if (cl_shownet->value == 3)
|
||||
Com_Printf (" frame:%i delta:%i\n", cl.frame.serverframe,
|
||||
cl.frame.deltaframe);
|
||||
|
||||
/*
|
||||
* If the frame is delta compressed from data that we
|
||||
* no longer have available, we must suck up the rest of
|
||||
* the frame, but not use it, then ask for a non-compressed
|
||||
* message
|
||||
*/
|
||||
if (cl.frame.deltaframe <= 0) {
|
||||
cl.frame.valid = true; /* uncompressed frame */
|
||||
old = NULL;
|
||||
cls.demowaiting = false; /* we can start recording now */
|
||||
|
||||
} else {
|
||||
old = &cl.frames[cl.frame.deltaframe & UPDATE_MASK];
|
||||
|
||||
if (!old->valid) {
|
||||
/* should never happen */
|
||||
Com_Printf ("Delta from invalid frame (not supposed to happen!).\n");
|
||||
}
|
||||
|
||||
if (old->serverframe != cl.frame.deltaframe) {
|
||||
/* The frame that the server did the delta from
|
||||
* is too old, so we can't reconstruct it properly. */
|
||||
Com_Printf ("Delta frame too old.\n");
|
||||
|
||||
} else if (cl.parse_entities - old->parse_entities > MAX_PARSE_ENTITIES-128) {
|
||||
Com_Printf ("Delta parse_entities too old.\n");
|
||||
|
||||
} else
|
||||
cl.frame.valid = true; /* valid delta parse */
|
||||
}
|
||||
|
||||
/* clamp time */
|
||||
if (cl.time > cl.frame.servertime)
|
||||
cl.time = cl.frame.servertime;
|
||||
|
||||
else if (cl.time < cl.frame.servertime - 100)
|
||||
cl.time = cl.frame.servertime - 100;
|
||||
|
||||
/* read areabits */
|
||||
len = MSG_ReadByte (&net_message);
|
||||
MSG_ReadData (&net_message, &cl.frame.areabits, len);
|
||||
|
||||
/* read playerinfo */
|
||||
cmd = MSG_ReadByte (&net_message);
|
||||
SHOWNET(svc_strings[cmd]);
|
||||
|
||||
if (cmd != svc_playerinfo)
|
||||
Com_Error (ERR_DROP, "CL_ParseFrame: 0x%X not playerinfo", cmd);
|
||||
|
||||
CL_ParsePlayerstate (old, &cl.frame);
|
||||
|
||||
/* read packet entities */
|
||||
cmd = MSG_ReadByte (&net_message);
|
||||
SHOWNET(svc_strings[cmd]);
|
||||
|
||||
if (cmd != svc_packetentities)
|
||||
Com_Error (ERR_DROP, "CL_ParseFrame: 0x%X not packetentities", cmd);
|
||||
|
||||
CL_ParsePacketEntities (old, &cl.frame);
|
||||
|
||||
/* save the frame off in the backup array for later delta comparisons */
|
||||
cl.frames[cl.frame.serverframe & UPDATE_MASK] = cl.frame;
|
||||
|
||||
if (cl.frame.valid) {
|
||||
/* getting a valid frame message ends the connection process */
|
||||
if (cls.state != ca_active) {
|
||||
cls.state = ca_active;
|
||||
cl.force_refdef = true;
|
||||
cl.predicted_origin[0] = cl.frame.playerstate.pmove.origin[0]*0.125f;
|
||||
cl.predicted_origin[1] = cl.frame.playerstate.pmove.origin[1]*0.125f;
|
||||
cl.predicted_origin[2] = cl.frame.playerstate.pmove.origin[2]*0.125f;
|
||||
VectorCopy (cl.frame.playerstate.viewangles, cl.predicted_angles);
|
||||
|
||||
if (cls.disable_servercount != cl.servercount
|
||||
&& cl.refresh_prepped)
|
||||
SCR_EndLoadingPlaque (); /* get rid of loading plaque */
|
||||
|
||||
cl.sound_prepped = true;
|
||||
}
|
||||
|
||||
/* fire entity events */
|
||||
CL_FireEntityEvents (&cl.frame);
|
||||
|
||||
if (!(!cl_predict->value || (cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION)))
|
||||
CL_CheckPredictionError();
|
||||
}
|
||||
}
|
||||
|
||||
struct model_s *S_RegisterSexedModel (entity_state_t *ent, char *base) {
|
||||
int n;
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include "header/client.h"
|
||||
|
||||
int bitcounts[32]; /* just for protocol profiling */
|
||||
|
||||
char *svc_strings[256] = {
|
||||
"svc_bad",
|
||||
|
||||
|
@ -249,6 +251,547 @@ void CL_ParseDownload (void) {
|
|||
}
|
||||
}
|
||||
|
||||
int CL_ParseEntityBits (unsigned *bits) {
|
||||
unsigned b, total;
|
||||
int i;
|
||||
int number;
|
||||
|
||||
total = MSG_ReadByte (&net_message);
|
||||
|
||||
if (total & U_MOREBITS1) {
|
||||
b = MSG_ReadByte (&net_message);
|
||||
total |= b<<8;
|
||||
}
|
||||
|
||||
if (total & U_MOREBITS2) {
|
||||
b = MSG_ReadByte (&net_message);
|
||||
total |= b<<16;
|
||||
}
|
||||
|
||||
if (total & U_MOREBITS3) {
|
||||
b = MSG_ReadByte (&net_message);
|
||||
total |= b<<24;
|
||||
}
|
||||
|
||||
/* count the bits for net profiling */
|
||||
for (i=0 ; i<32 ; i++)
|
||||
if (total&(1<<i))
|
||||
bitcounts[i]++;
|
||||
|
||||
if (total & U_NUMBER16)
|
||||
number = MSG_ReadShort (&net_message);
|
||||
|
||||
else
|
||||
number = MSG_ReadByte (&net_message);
|
||||
|
||||
*bits = total;
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
/* used for laser colors */
|
||||
if ((bits & U_SKIN8) && (bits & U_SKIN16))
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses deltas from the given base and adds the resulting entity to
|
||||
* the current frame
|
||||
*/
|
||||
void CL_DeltaEntity (frame_t *frame, int newnum, entity_state_t *old,
|
||||
int bits) {
|
||||
centity_t *ent;
|
||||
entity_state_t *state;
|
||||
|
||||
ent = &cl_entities[newnum];
|
||||
|
||||
state = &cl_parse_entities[cl.parse_entities & (MAX_PARSE_ENTITIES-1)];
|
||||
cl.parse_entities++;
|
||||
frame->num_entities++;
|
||||
|
||||
CL_ParseDelta (old, state, newnum, bits);
|
||||
|
||||
/* some data changes will force no lerping */
|
||||
if (state->modelindex != ent->current.modelindex
|
||||
|| state->modelindex2 != ent->current.modelindex2
|
||||
|| state->modelindex3 != ent->current.modelindex3
|
||||
|| state->modelindex4 != ent->current.modelindex4
|
||||
|| state->event == EV_PLAYER_TELEPORT
|
||||
|| state->event == EV_OTHER_TELEPORT
|
||||
|| abs((int)(state->origin[0] - ent->current.origin[0])) > 512
|
||||
|| abs((int)(state->origin[1] - ent->current.origin[1])) > 512
|
||||
|| abs((int)(state->origin[2] - ent->current.origin[2])) > 512
|
||||
) {
|
||||
ent->serverframe = -99;
|
||||
}
|
||||
/* wasn't in last update, so initialize some things */
|
||||
if (ent->serverframe != cl.frame.serverframe - 1) {
|
||||
ent->trailcount = 1024; /* for diminishing rocket / grenade trails */
|
||||
|
||||
/* duplicate the current state so
|
||||
* lerping doesn't hurt anything */
|
||||
ent->prev = *state;
|
||||
|
||||
if (state->event == EV_OTHER_TELEPORT) {
|
||||
VectorCopy (state->origin, ent->prev.origin);
|
||||
VectorCopy (state->origin, ent->lerp_origin);
|
||||
|
||||
} else {
|
||||
VectorCopy (state->old_origin, ent->prev.origin);
|
||||
VectorCopy (state->old_origin, ent->lerp_origin);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* shuffle the last state to previous */
|
||||
ent->prev = ent->current;
|
||||
}
|
||||
|
||||
ent->serverframe = cl.frame.serverframe;
|
||||
ent->current = *state;
|
||||
}
|
||||
|
||||
/*
|
||||
* An svc_packetentities has just been parsed, deal with the rest of the
|
||||
* data stream.
|
||||
*/
|
||||
void CL_ParsePacketEntities (frame_t *oldframe, frame_t *newframe) {
|
||||
unsigned int newnum;
|
||||
unsigned bits;
|
||||
entity_state_t
|
||||
*oldstate = NULL;
|
||||
int oldindex, oldnum;
|
||||
|
||||
newframe->parse_entities = cl.parse_entities;
|
||||
newframe->num_entities = 0;
|
||||
|
||||
/* delta from the entities present in oldframe */
|
||||
oldindex = 0;
|
||||
|
||||
if (!oldframe)
|
||||
oldnum = 99999;
|
||||
|
||||
else {
|
||||
if (oldindex >= oldframe->num_entities)
|
||||
oldnum = 99999;
|
||||
|
||||
else {
|
||||
oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
|
||||
oldnum = oldstate->number;
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
newnum = CL_ParseEntityBits (&bits);
|
||||
|
||||
if (newnum >= MAX_EDICTS)
|
||||
Com_Error (ERR_DROP,"CL_ParsePacketEntities: bad number:%i", newnum);
|
||||
|
||||
if (net_message.readcount > net_message.cursize)
|
||||
Com_Error (ERR_DROP,"CL_ParsePacketEntities: end of message");
|
||||
|
||||
if (!newnum)
|
||||
break;
|
||||
|
||||
while (oldnum < newnum) {
|
||||
/* one or more entities from the old packet are unchanged */
|
||||
if (cl_shownet->value == 3)
|
||||
Com_Printf (" unchanged: %i\n", oldnum);
|
||||
|
||||
CL_DeltaEntity (newframe, oldnum, oldstate, 0);
|
||||
|
||||
oldindex++;
|
||||
|
||||
if (oldindex >= oldframe->num_entities)
|
||||
oldnum = 99999;
|
||||
|
||||
else {
|
||||
oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
|
||||
oldnum = oldstate->number;
|
||||
}
|
||||
}
|
||||
|
||||
if (bits & U_REMOVE) {
|
||||
/* the entity present in oldframe is not in the current frame */
|
||||
if (cl_shownet->value == 3)
|
||||
Com_Printf (" remove: %i\n", newnum);
|
||||
|
||||
if (oldnum != newnum)
|
||||
Com_Printf ("U_REMOVE: oldnum != newnum\n");
|
||||
|
||||
oldindex++;
|
||||
|
||||
if (oldindex >= oldframe->num_entities)
|
||||
oldnum = 99999;
|
||||
|
||||
else {
|
||||
oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
|
||||
oldnum = oldstate->number;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (oldnum == newnum) {
|
||||
/* delta from previous state */
|
||||
if (cl_shownet->value == 3)
|
||||
Com_Printf (" delta: %i\n", newnum);
|
||||
|
||||
CL_DeltaEntity (newframe, newnum, oldstate, bits);
|
||||
|
||||
oldindex++;
|
||||
|
||||
if (oldindex >= oldframe->num_entities)
|
||||
oldnum = 99999;
|
||||
|
||||
else {
|
||||
oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
|
||||
oldnum = oldstate->number;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (oldnum > newnum) {
|
||||
/* delta from baseline */
|
||||
if (cl_shownet->value == 3)
|
||||
Com_Printf (" baseline: %i\n", newnum);
|
||||
|
||||
CL_DeltaEntity (newframe, newnum, &cl_entities[newnum].baseline, bits);
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* any remaining entities in the old frame are copied over */
|
||||
while (oldnum != 99999) {
|
||||
/* one or more entities from the old packet are unchanged */
|
||||
if (cl_shownet->value == 3)
|
||||
Com_Printf (" unchanged: %i\n", oldnum);
|
||||
|
||||
CL_DeltaEntity (newframe, oldnum, oldstate, 0);
|
||||
|
||||
oldindex++;
|
||||
|
||||
if (oldindex >= oldframe->num_entities)
|
||||
oldnum = 99999;
|
||||
|
||||
else {
|
||||
oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
|
||||
oldnum = oldstate->number;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CL_ParsePlayerstate (frame_t *oldframe, frame_t *newframe) {
|
||||
int flags;
|
||||
player_state_t *state;
|
||||
int i;
|
||||
int statbits;
|
||||
|
||||
state = &newframe->playerstate;
|
||||
|
||||
/* clear to old value before delta parsing */
|
||||
if (oldframe)
|
||||
*state = oldframe->playerstate;
|
||||
|
||||
else
|
||||
memset (state, 0, sizeof(*state));
|
||||
|
||||
flags = MSG_ReadShort (&net_message);
|
||||
|
||||
/* parse the pmove_state_t */
|
||||
if (flags & PS_M_TYPE)
|
||||
state->pmove.pm_type = MSG_ReadByte (&net_message);
|
||||
|
||||
if (flags & PS_M_ORIGIN) {
|
||||
state->pmove.origin[0] = MSG_ReadShort (&net_message);
|
||||
state->pmove.origin[1] = MSG_ReadShort (&net_message);
|
||||
state->pmove.origin[2] = MSG_ReadShort (&net_message);
|
||||
}
|
||||
|
||||
if (flags & PS_M_VELOCITY) {
|
||||
state->pmove.velocity[0] = MSG_ReadShort (&net_message);
|
||||
state->pmove.velocity[1] = MSG_ReadShort (&net_message);
|
||||
state->pmove.velocity[2] = MSG_ReadShort (&net_message);
|
||||
}
|
||||
|
||||
if (flags & PS_M_TIME)
|
||||
state->pmove.pm_time = MSG_ReadByte (&net_message);
|
||||
|
||||
if (flags & PS_M_FLAGS)
|
||||
state->pmove.pm_flags = MSG_ReadByte (&net_message);
|
||||
|
||||
if (flags & PS_M_GRAVITY)
|
||||
state->pmove.gravity = MSG_ReadShort (&net_message);
|
||||
|
||||
if (flags & PS_M_DELTA_ANGLES) {
|
||||
state->pmove.delta_angles[0] = MSG_ReadShort (&net_message);
|
||||
state->pmove.delta_angles[1] = MSG_ReadShort (&net_message);
|
||||
state->pmove.delta_angles[2] = MSG_ReadShort (&net_message);
|
||||
}
|
||||
|
||||
if (cl.attractloop)
|
||||
state->pmove.pm_type = PM_FREEZE; /* demo playback */
|
||||
|
||||
/* parse the rest of the player_state_t */
|
||||
if (flags & PS_VIEWOFFSET) {
|
||||
state->viewoffset[0] = MSG_ReadChar (&net_message) * 0.25f;
|
||||
state->viewoffset[1] = MSG_ReadChar (&net_message) * 0.25f;
|
||||
state->viewoffset[2] = MSG_ReadChar (&net_message) * 0.25f;
|
||||
}
|
||||
|
||||
if (flags & PS_VIEWANGLES) {
|
||||
state->viewangles[0] = MSG_ReadAngle16 (&net_message);
|
||||
state->viewangles[1] = MSG_ReadAngle16 (&net_message);
|
||||
state->viewangles[2] = MSG_ReadAngle16 (&net_message);
|
||||
}
|
||||
|
||||
if (flags & PS_KICKANGLES) {
|
||||
state->kick_angles[0] = MSG_ReadChar (&net_message) * 0.25f;
|
||||
state->kick_angles[1] = MSG_ReadChar (&net_message) * 0.25f;
|
||||
state->kick_angles[2] = MSG_ReadChar (&net_message) * 0.25f;
|
||||
}
|
||||
|
||||
if (flags & PS_WEAPONINDEX) {
|
||||
state->gunindex = MSG_ReadByte (&net_message);
|
||||
}
|
||||
|
||||
if (flags & PS_WEAPONFRAME) {
|
||||
state->gunframe = MSG_ReadByte (&net_message);
|
||||
state->gunoffset[0] = MSG_ReadChar (&net_message)*0.25f;
|
||||
state->gunoffset[1] = MSG_ReadChar (&net_message)*0.25f;
|
||||
state->gunoffset[2] = MSG_ReadChar (&net_message)*0.25f;
|
||||
state->gunangles[0] = MSG_ReadChar (&net_message)*0.25f;
|
||||
state->gunangles[1] = MSG_ReadChar (&net_message)*0.25f;
|
||||
state->gunangles[2] = MSG_ReadChar (&net_message)*0.25f;
|
||||
}
|
||||
|
||||
if (flags & PS_BLEND) {
|
||||
state->blend[0] = MSG_ReadByte (&net_message)/255.0f;
|
||||
state->blend[1] = MSG_ReadByte (&net_message)/255.0f;
|
||||
state->blend[2] = MSG_ReadByte (&net_message)/255.0f;
|
||||
state->blend[3] = MSG_ReadByte (&net_message)/255.0f;
|
||||
}
|
||||
|
||||
if (flags & PS_FOV)
|
||||
state->fov = (float)MSG_ReadByte (&net_message);
|
||||
|
||||
if (flags & PS_RDFLAGS)
|
||||
state->rdflags = MSG_ReadByte (&net_message);
|
||||
|
||||
/* parse stats */
|
||||
statbits = MSG_ReadLong (&net_message);
|
||||
|
||||
for (i=0 ; i<MAX_STATS ; i++)
|
||||
if (statbits & (1<<i) )
|
||||
state->stats[i] = MSG_ReadShort(&net_message);
|
||||
}
|
||||
|
||||
void CL_FireEntityEvents (frame_t *frame) {
|
||||
entity_state_t *s1;
|
||||
int pnum, num;
|
||||
|
||||
for (pnum = 0 ; pnum<frame->num_entities ; pnum++) {
|
||||
num = (frame->parse_entities + pnum)&(MAX_PARSE_ENTITIES-1);
|
||||
s1 = &cl_parse_entities[num];
|
||||
|
||||
if (s1->event)
|
||||
CL_EntityEvent (s1);
|
||||
|
||||
if (s1->effects & EF_TELEPORTER)
|
||||
CL_TeleporterParticles (s1);
|
||||
}
|
||||
}
|
||||
|
||||
void CL_ParseFrame (void) {
|
||||
int cmd;
|
||||
int len;
|
||||
frame_t *old;
|
||||
|
||||
memset (&cl.frame, 0, sizeof(cl.frame));
|
||||
|
||||
cl.frame.serverframe = MSG_ReadLong (&net_message);
|
||||
cl.frame.deltaframe = MSG_ReadLong (&net_message);
|
||||
cl.frame.servertime = cl.frame.serverframe*100;
|
||||
|
||||
/* BIG HACK to let old demos continue to work */
|
||||
if (cls.serverProtocol != 26)
|
||||
cl.surpressCount = MSG_ReadByte (&net_message);
|
||||
|
||||
if (cl_shownet->value == 3)
|
||||
Com_Printf (" frame:%i delta:%i\n", cl.frame.serverframe,
|
||||
cl.frame.deltaframe);
|
||||
|
||||
/*
|
||||
* If the frame is delta compressed from data that we
|
||||
* no longer have available, we must suck up the rest of
|
||||
* the frame, but not use it, then ask for a non-compressed
|
||||
* message
|
||||
*/
|
||||
if (cl.frame.deltaframe <= 0) {
|
||||
cl.frame.valid = true; /* uncompressed frame */
|
||||
old = NULL;
|
||||
cls.demowaiting = false; /* we can start recording now */
|
||||
|
||||
} else {
|
||||
old = &cl.frames[cl.frame.deltaframe & UPDATE_MASK];
|
||||
|
||||
if (!old->valid) {
|
||||
/* should never happen */
|
||||
Com_Printf ("Delta from invalid frame (not supposed to happen!).\n");
|
||||
}
|
||||
|
||||
if (old->serverframe != cl.frame.deltaframe) {
|
||||
/* The frame that the server did the delta from
|
||||
* is too old, so we can't reconstruct it properly. */
|
||||
Com_Printf ("Delta frame too old.\n");
|
||||
|
||||
} else if (cl.parse_entities - old->parse_entities > MAX_PARSE_ENTITIES-128) {
|
||||
Com_Printf ("Delta parse_entities too old.\n");
|
||||
|
||||
} else
|
||||
cl.frame.valid = true; /* valid delta parse */
|
||||
}
|
||||
|
||||
/* clamp time */
|
||||
if (cl.time > cl.frame.servertime)
|
||||
cl.time = cl.frame.servertime;
|
||||
|
||||
else if (cl.time < cl.frame.servertime - 100)
|
||||
cl.time = cl.frame.servertime - 100;
|
||||
|
||||
/* read areabits */
|
||||
len = MSG_ReadByte (&net_message);
|
||||
MSG_ReadData (&net_message, &cl.frame.areabits, len);
|
||||
|
||||
/* read playerinfo */
|
||||
cmd = MSG_ReadByte (&net_message);
|
||||
SHOWNET(svc_strings[cmd]);
|
||||
|
||||
if (cmd != svc_playerinfo)
|
||||
Com_Error (ERR_DROP, "CL_ParseFrame: 0x%X not playerinfo", cmd);
|
||||
|
||||
CL_ParsePlayerstate (old, &cl.frame);
|
||||
|
||||
/* read packet entities */
|
||||
cmd = MSG_ReadByte (&net_message);
|
||||
SHOWNET(svc_strings[cmd]);
|
||||
|
||||
if (cmd != svc_packetentities)
|
||||
Com_Error (ERR_DROP, "CL_ParseFrame: 0x%X not packetentities", cmd);
|
||||
|
||||
CL_ParsePacketEntities (old, &cl.frame);
|
||||
|
||||
/* save the frame off in the backup array for later delta comparisons */
|
||||
cl.frames[cl.frame.serverframe & UPDATE_MASK] = cl.frame;
|
||||
|
||||
if (cl.frame.valid) {
|
||||
/* getting a valid frame message ends the connection process */
|
||||
if (cls.state != ca_active) {
|
||||
cls.state = ca_active;
|
||||
cl.force_refdef = true;
|
||||
cl.predicted_origin[0] = cl.frame.playerstate.pmove.origin[0]*0.125f;
|
||||
cl.predicted_origin[1] = cl.frame.playerstate.pmove.origin[1]*0.125f;
|
||||
cl.predicted_origin[2] = cl.frame.playerstate.pmove.origin[2]*0.125f;
|
||||
VectorCopy (cl.frame.playerstate.viewangles, cl.predicted_angles);
|
||||
|
||||
if (cls.disable_servercount != cl.servercount
|
||||
&& cl.refresh_prepped)
|
||||
SCR_EndLoadingPlaque (); /* get rid of loading plaque */
|
||||
|
||||
cl.sound_prepped = true;
|
||||
}
|
||||
|
||||
/* fire entity events */
|
||||
CL_FireEntityEvents (&cl.frame);
|
||||
|
||||
if (!(!cl_predict->value || (cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION)))
|
||||
CL_CheckPredictionError();
|
||||
}
|
||||
}
|
||||
|
||||
void CL_ParseServerData (void) {
|
||||
extern cvar_t *fs_gamedirvar;
|
||||
char *str;
|
||||
|
|
Loading…
Reference in a new issue