1 /*
2 * Copyright(c) 1997-2001 Id Software, Inc.
3 * Copyright(c) 2002 The Quakeforge Project.
4 * Copyright(c) 2006 Quetoo.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or(at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 *
15 * See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 */
21 
22 #include "client.h"
23 
24 extern struct model_s *cl_mod_powerscreen;
25 
26 extern cvar_t *fov;
27 extern cvar_t *cl_forcefov;
28 
29 /*
30 
31 FRAME PARSING
32 
33 */
34 
35 /*
36 CL_ParseEntityBits
37 
38 Returns the entity number and the header bits
39 */
CL_ParseEntityBits(unsigned int * bits)40 unsigned int CL_ParseEntityBits(unsigned int *bits){
41 	unsigned int b, total;
42 	unsigned int number;
43 
44 	total = MSG_ReadByte(&net_message);
45 	if(total & U_MOREBITS1){
46 		b = MSG_ReadByte(&net_message);
47 		total |= b << 8;
48 	}
49 	if(total & U_MOREBITS2){
50 		b = MSG_ReadByte(&net_message);
51 		total |= b << 16;
52 	}
53 	if(total & U_MOREBITS3){
54 		b = MSG_ReadByte(&net_message);
55 		total |= b << 24;
56 	}
57 
58 	if(total & U_NUMBER16)
59 		number = MSG_ReadShort(&net_message);
60 	else
61 		number = MSG_ReadByte(&net_message);
62 
63 	*bits = total;
64 
65 	return number;
66 }
67 
68 /*
69 CL_ParseDelta
70 
71 Can go from either a baseline or a previous packet_entity
72 */
CL_ParseDelta(entity_state_t * from,entity_state_t * to,int number,int bits)73 void CL_ParseDelta(entity_state_t *from, entity_state_t *to, int number, int bits){
74 	// set everything to the state we are delta'ing from
75 	*to = *from;
76 
77 	if(cls.protocol != PROTOCOL_R1Q2) // protocol 35 deltas beams
78 		VectorCopy(from->origin, to->old_origin);
79 	else if(!(bits & U_OLDORIGIN) && !(from->renderfx & RF_BEAM))
80 		VectorCopy(from->origin, to->old_origin);
81 
82 	to->number = number;
83 
84 	if(bits & U_MODEL)
85 		to->modelindex = MSG_ReadByte(&net_message);
86 	if(bits & U_MODEL2)
87 		to->modelindex2 = MSG_ReadByte(&net_message);
88 	if(bits & U_MODEL3)
89 		to->modelindex3 = MSG_ReadByte(&net_message);
90 	if(bits & U_MODEL4)
91 		to->modelindex4 = MSG_ReadByte(&net_message);
92 
93 	if(bits & U_FRAME8)
94 		to->frame = MSG_ReadByte(&net_message);
95 	if(bits & U_FRAME16)
96 		to->frame = MSG_ReadShort(&net_message);
97 
98 	if((bits & U_SKIN8) && (bits & U_SKIN16))  //used for laser colors
99 		to->skinnum = MSG_ReadLong(&net_message);
100 	else if(bits & U_SKIN8)
101 		to->skinnum = MSG_ReadByte(&net_message);
102 	else if(bits & U_SKIN16)
103 		to->skinnum = MSG_ReadShort(&net_message);
104 
105 	if((bits & (U_EFFECTS8 | U_EFFECTS16)) == (U_EFFECTS8 | U_EFFECTS16))
106 		to->effects = MSG_ReadLong(&net_message);
107 	else if(bits & U_EFFECTS8)
108 		to->effects = MSG_ReadByte(&net_message);
109 	else if(bits & U_EFFECTS16)
110 		to->effects = MSG_ReadShort(&net_message);
111 
112 	if((bits & (U_RENDERFX8 | U_RENDERFX16)) == (U_RENDERFX8 | U_RENDERFX16))
113 		to->renderfx = MSG_ReadLong(&net_message);
114 	else if(bits & U_RENDERFX8)
115 		to->renderfx = MSG_ReadByte(&net_message);
116 	else if(bits & U_RENDERFX16)
117 		to->renderfx = MSG_ReadShort(&net_message);
118 
119 	if(bits & U_ORIGIN1)
120 		to->origin[0] = MSG_ReadCoord(&net_message);
121 	if(bits & U_ORIGIN2)
122 		to->origin[1] = MSG_ReadCoord(&net_message);
123 	if(bits & U_ORIGIN3)
124 		to->origin[2] = MSG_ReadCoord(&net_message);
125 
126 	if(bits & U_ANGLE1)
127 		to->angles[0] = MSG_ReadAngle(&net_message);
128 	if(bits & U_ANGLE2)
129 		to->angles[1] = MSG_ReadAngle(&net_message);
130 	if(bits & U_ANGLE3)
131 		to->angles[2] = MSG_ReadAngle(&net_message);
132 
133 	if(bits & U_OLDORIGIN)
134 		MSG_ReadPos(&net_message, to->old_origin);
135 
136 	if(bits & U_SOUND)
137 		to->sound = MSG_ReadByte(&net_message);
138 
139 	if(bits & U_EVENT)
140 		to->event = MSG_ReadByte(&net_message);
141 	else
142 		to->event = 0;
143 
144 	if(bits & U_SOLID)
145 		to->solid = MSG_ReadShort(&net_message);
146 }
147 
148 /*
149 CL_DeltaEntity
150 
151 Parses deltas from the given base and adds the resulting entity
152 to the current frame
153 */
CL_DeltaEntity(frame_t * frame,int newnum,entity_state_t * old,int bits)154 void CL_DeltaEntity(frame_t *frame, int newnum, entity_state_t *old, int bits){
155 	centity_t *ent;
156 	entity_state_t *state;
157 
158 	ent = &cl_entities[newnum];
159 
160 	state = &cl_parse_entities[cl.parse_entities &(MAX_PARSE_ENTITIES - 1)];
161 	cl.parse_entities++;
162 	frame->num_entities++;
163 
164 	CL_ParseDelta(old, state, newnum, bits);
165 
166 	// some data changes will force no lerping
167 	if(state->modelindex != ent->current.modelindex
168 			|| state->modelindex2 != ent->current.modelindex2
169 			|| state->modelindex3 != ent->current.modelindex3
170 			|| state->modelindex4 != ent->current.modelindex4
171 			|| fabsf(state->origin[0] - ent->current.origin[0]) > 512
172 			|| fabsf(state->origin[1] - ent->current.origin[1]) > 512
173 			|| fabsf(state->origin[2] - ent->current.origin[2]) > 512
174 			|| state->event == EV_PLAYER_TELEPORT
175 			|| state->event == EV_OTHER_TELEPORT
176 	  ){
177 		ent->serverframe = -99;
178 	}
179 
180 	if(ent->serverframe != cl.frame.serverframe - 1){  // wasn't in last update, so initialize some things
181 		ent->trailcount = 1024;  // for diminishing rocket / grenade trails
182 		// duplicate the current state so lerping doesn't hurt anything
183 		ent->prev = *state;
184 		if(state->event == EV_OTHER_TELEPORT){
185 			VectorCopy(state->origin, ent->prev.origin);
186 			VectorCopy(state->origin, ent->lerp_origin);
187 		} else {
188 			VectorCopy(state->old_origin, ent->prev.origin);
189 			VectorCopy(state->old_origin, ent->lerp_origin);
190 		}
191 	} else {  // shuffle the last state to previous
192 		ent->prev = ent->current;
193 	}
194 
195 	ent->serverframe = cl.frame.serverframe;
196 	ent->current = *state;
197 }
198 
199 /*
200 CL_ParsePacketEntities
201 
202 An svc_packetentities has just been parsed, deal with the
203 rest of the data stream.
204 */
CL_ParsePacketEntities(frame_t * oldframe,frame_t * newframe)205 void CL_ParsePacketEntities(frame_t *oldframe, frame_t *newframe){
206 	int newnum;
207 	unsigned int bits;
208 	entity_state_t *oldstate = NULL;
209 	int oldindex, oldnum;
210 
211 	newframe->parse_entities = cl.parse_entities;
212 	newframe->num_entities = 0;
213 
214 	// delta from the entities present in oldframe
215 	oldindex = 0;
216 	if(!oldframe)
217 		oldnum = 99999;
218 	else {
219 		if(oldindex >= oldframe->num_entities)
220 			oldnum = 99999;
221 		else {
222 			oldstate = &cl_parse_entities[(oldframe->parse_entities + oldindex) &(MAX_PARSE_ENTITIES - 1)];
223 			oldnum = oldstate->number;
224 		}
225 	}
226 
227 	while(1){
228 		newnum = CL_ParseEntityBits(&bits);
229 		if(newnum >= MAX_EDICTS)
230 			Com_Error(ERR_DROP, "CL_ParsePacketEntities: bad number:%i", newnum);
231 
232 		if(net_message.readcount > net_message.cursize)
233 			Com_Error(ERR_DROP, "CL_ParsePacketEntities: end of message");
234 
235 		if(!newnum)
236 			break;
237 
238 		while(oldnum < newnum){  // one or more entities from the old packet are unchanged
239 			if(cl_shownet->value == 3)
240 				Com_Printf("   unchanged: %i\n", oldnum);
241 			CL_DeltaEntity(newframe, oldnum, oldstate, 0);
242 
243 			oldindex++;
244 
245 			if(oldindex >= oldframe->num_entities)
246 				oldnum = 99999;
247 			else {
248 				oldstate = &cl_parse_entities[(oldframe->parse_entities + oldindex) & (MAX_PARSE_ENTITIES - 1)];
249 				oldnum = oldstate->number;
250 			}
251 		}
252 
253 		if(bits & U_REMOVE){  // the entity present in oldframe is not in the current frame
254 			if(cl_shownet->value == 3)
255 				Com_Printf("   remove: %i\n", newnum);
256 			if(oldnum != newnum)
257 				Com_Printf("U_REMOVE: oldnum != newnum\n");
258 
259 			oldindex++;
260 
261 			if(oldindex >= oldframe->num_entities)
262 				oldnum = 99999;
263 			else {
264 				oldstate = &cl_parse_entities[(oldframe->parse_entities + oldindex) & (MAX_PARSE_ENTITIES - 1)];
265 				oldnum = oldstate->number;
266 			}
267 			continue;
268 		}
269 
270 		if(oldnum == newnum){  // delta from previous state
271 			if(cl_shownet->value == 3)
272 				Com_Printf("   delta: %i\n", newnum);
273 			CL_DeltaEntity(newframe, newnum, oldstate, bits);
274 
275 			oldindex++;
276 
277 			if(oldindex >= oldframe->num_entities)
278 				oldnum = 99999;
279 			else {
280 				oldstate = &cl_parse_entities[(oldframe->parse_entities + oldindex) &(MAX_PARSE_ENTITIES - 1)];
281 				oldnum = oldstate->number;
282 			}
283 			continue;
284 		}
285 
286 		if(oldnum > newnum){  // delta from baseline
287 			if(cl_shownet->value == 3)
288 				Com_Printf("   baseline: %i\n", newnum);
289 			CL_DeltaEntity(newframe, newnum, &cl_entities[newnum].baseline, bits);
290 			continue;
291 		}
292 
293 	}
294 
295 	// any remaining entities in the old frame are copied over
296 	while(oldnum != 99999){  // one or more entities from the old packet are unchanged
297 		if(cl_shownet->value == 3)
298 			Com_Printf("   unchanged: %i\n", oldnum);
299 		CL_DeltaEntity(newframe, oldnum, oldstate, 0);
300 
301 		oldindex++;
302 
303 		if(oldindex >= oldframe->num_entities)
304 			oldnum = 99999;
305 		else {
306 			oldstate = &cl_parse_entities[(oldframe->parse_entities + oldindex) &(MAX_PARSE_ENTITIES - 1)];
307 			oldnum = oldstate->number;
308 		}
309 	}
310 }
311 
312 
313 
314 /*
315 CL_ParsePlayerstate
316 */
CL_ParsePlayerstate(frame_t * oldframe,frame_t * newframe,int extraflags)317 void CL_ParsePlayerstate(frame_t *oldframe, frame_t *newframe, int extraflags){
318 	int flags;
319 	player_state_t *state;
320 	int i;
321 	int statbits;
322 	qboolean enhanced;
323 
324 	state = &newframe->playerstate;
325 	enhanced = cls.protocol == PROTOCOL_R1Q2;
326 
327 	// clear to old value before delta parsing
328 	if(oldframe)
329 		*state = oldframe->playerstate;
330 	else
331 		memset(state, 0, sizeof(*state));
332 
333 	flags = MSG_ReadShort(&net_message);
334 
335 	// parse the pmove_state_t
336 	if(flags & PS_M_TYPE)
337 		state->pmove.pm_type = MSG_ReadByte(&net_message);
338 
339 	if(flags & PS_M_ORIGIN){
340 		if(!enhanced)
341 			extraflags |= EPS_PMOVE_ORIGIN2;
342 		state->pmove.origin[0] = MSG_ReadShort(&net_message);
343 		state->pmove.origin[1] = MSG_ReadShort(&net_message);
344 	}
345 
346 	if(extraflags & EPS_PMOVE_ORIGIN2)
347 		state->pmove.origin[2] = MSG_ReadShort(&net_message);
348 
349 	if(flags & PS_M_VELOCITY){
350 		if(!enhanced)
351 			extraflags |= EPS_PMOVE_VELOCITY2;
352 		state->pmove.velocity[0] = MSG_ReadShort(&net_message);
353 		state->pmove.velocity[1] = MSG_ReadShort(&net_message);
354 	}
355 
356 	if(extraflags & EPS_PMOVE_VELOCITY2)
357 		state->pmove.velocity[2] = MSG_ReadShort(&net_message);
358 
359 	if(flags & PS_M_TIME)
360 		state->pmove.pm_time = MSG_ReadByte(&net_message);
361 
362 	if(flags & PS_M_FLAGS)
363 		state->pmove.pm_flags = MSG_ReadByte(&net_message);
364 
365 	if(flags & PS_M_GRAVITY)
366 		state->pmove.gravity = MSG_ReadShort(&net_message);
367 
368 	if(flags & PS_M_DELTA_ANGLES){
369 		state->pmove.delta_angles[0] = MSG_ReadShort(&net_message);
370 		state->pmove.delta_angles[1] = MSG_ReadShort(&net_message);
371 		state->pmove.delta_angles[2] = MSG_ReadShort(&net_message);
372 	}
373 
374 	if(cl.demoserver) // demo playback
375 		state->pmove.pm_type = PM_FREEZE;
376 
377 	// parse the rest of the player_state_t
378 	if(flags & PS_VIEWOFFSET){
379 		state->viewoffset[0] = MSG_ReadChar(&net_message) * 0.25f;
380 		state->viewoffset[1] = MSG_ReadChar(&net_message) * 0.25f;
381 		state->viewoffset[2] = MSG_ReadChar(&net_message) * 0.25f;
382 	}
383 
384 	if(flags & PS_VIEWANGLES){
385 		if(!enhanced)
386 			extraflags |= EPS_VIEWANGLE2;
387 		state->viewangles[0] = MSG_ReadAngle16(&net_message);
388 		state->viewangles[1] = MSG_ReadAngle16(&net_message);
389 	}
390 
391 	if(extraflags & EPS_VIEWANGLE2)
392 		state->viewangles[2] = MSG_ReadAngle16(&net_message);
393 
394 	if(flags & PS_KICKANGLES){
395 		state->kick_angles[0] = MSG_ReadChar(&net_message) * 0.25f;
396 		state->kick_angles[1] = MSG_ReadChar(&net_message) * 0.25f;
397 		state->kick_angles[2] = MSG_ReadChar(&net_message) * 0.25f;
398 	}
399 
400 	if(flags & PS_WEAPONINDEX)
401 		state->gunindex = MSG_ReadByte(&net_message);
402 
403 	if(flags & PS_WEAPONFRAME){  // we'll only see this on legacy servers
404 		if(!enhanced)
405 			extraflags |= EPS_GUNOFFSET | EPS_GUNANGLES;
406 		state->gunframe = MSG_ReadByte(&net_message);
407 	}
408 
409 	if(extraflags & EPS_GUNOFFSET){  // same for this
410 		state->gunoffset[0] = MSG_ReadChar(&net_message) * 0.25f;
411 		state->gunoffset[1] = MSG_ReadChar(&net_message) * 0.25f;
412 		state->gunoffset[2] = MSG_ReadChar(&net_message) * 0.25f;
413 	}
414 
415 	if(extraflags & EPS_GUNANGLES){  // and this
416 		state->gunangles[0] = MSG_ReadChar(&net_message) * 0.25f;
417 		state->gunangles[1] = MSG_ReadChar(&net_message) * 0.25f;
418 		state->gunangles[2] = MSG_ReadChar(&net_message) * 0.25f;
419 	}
420 
421 	if(flags & PS_BLEND){  // this is read but ignored
422 		state->blend[0] = MSG_ReadByte(&net_message) / 255.0f;
423 		state->blend[1] = MSG_ReadByte(&net_message) / 255.0f;
424 		state->blend[2] = MSG_ReadByte(&net_message) / 255.0f;
425 		state->blend[3] = MSG_ReadByte(&net_message) / 255.0f;
426 	}
427 
428 	if(flags & PS_FOV){
429 		state->fov = (float)MSG_ReadByte(&net_message);
430 		if(cl_forcefov->value)  // client may opt to ignore
431 			state->fov = fov->value;
432 	}
433 
434 	if(flags & PS_RDFLAGS)
435 		cl.viewdef.rdflags = MSG_ReadByte(&net_message);
436 
437 	if(enhanced){  // r1q2 bbox extension
438 		if(flags & PS_BBOX){
439 			int x, zd, zu;
440 			int solid;
441 
442 			solid = MSG_ReadShort(&net_message);
443 
444 			x = 8 * (solid & 31);
445 			zd = 8 * ((solid >> 5) & 31);
446 			zu = 8 * ((solid >> 10) & 63) - 32;
447 
448 			state->mins[0] = state->mins[1] = -(float)x;
449 			state->maxs[0] = state->maxs[1] = (float)x;
450 			state->mins[2] = -(float)zd;
451 			state->maxs[2] = (float)zu;
452 
453 			Com_DPrintf ("received bbox from server: (%f, %f, %f), (%f, %f, %f)\n",
454 					state->mins[0], state->mins[1], state->mins[2],
455 					state->maxs[0], state->maxs[1], state->maxs[2]);
456 		}
457 	}
458 
459 	if(!enhanced)
460 		extraflags |= EPS_STATS;
461 
462 	if(extraflags & EPS_STATS){ // parse stats
463 		statbits = MSG_ReadLong(&net_message);
464 
465 		if(statbits){
466 			for(i = 0; i < MAX_STATS; i++)
467 				if(statbits & (1 << i))
468 					state->stats[i] = MSG_ReadShort(&net_message);
469 		}
470 	}
471 }
472 
473 
474 /*
475 CL_FireEntityEvents
476 
477 */
CL_FireEntityEvents(frame_t * frame)478 void CL_FireEntityEvents(frame_t *frame){
479 	entity_state_t *s1;
480 	int pnum, num;
481 
482 	for(pnum = 0; pnum < frame->num_entities; pnum++){
483 		num = (frame->parse_entities + pnum) & (MAX_PARSE_ENTITIES - 1);
484 		s1 = &cl_parse_entities[num];
485 		if(s1->event)
486 			CL_EntityEvent(s1);
487 
488 		if(s1->effects & EF_TELEPORTER)
489 			CL_TeleporterParticles(s1);
490 	}
491 }
492 
493 
494 /*
495 CL_ParseFrame
496 */
CL_ParseFrame(int extrabits)497 void CL_ParseFrame(int extrabits){
498 	int cmd;
499 	int len;
500 	int extraflags;
501 	unsigned int serverframe;
502 	frame_t *old;
503 
504 	//r1: we steal last bits of this int for the offset
505 	//if serverframe gets that high then the server has been on the same map
506 	//for over 19 days... how often will this legitimately happen, and do we
507 	//really need the possibility of the server running same map for 13 years...
508 	serverframe = MSG_ReadLong(&net_message);
509 
510 	if(cls.protocol != PROTOCOL_R1Q2){
511 		cl.frame.serverframe = serverframe;
512 		cl.frame.deltaframe = MSG_ReadLong(&net_message);
513 	}
514 	else {
515 		unsigned int offset;
516 
517 		offset = serverframe & 0xF8000000;
518 		offset >>= 27;
519 
520 		serverframe &= 0x07FFFFFF;
521 
522 		cl.frame.serverframe = serverframe;
523 
524 		if(offset == 31) cl.frame.deltaframe = -1;
525 		else cl.frame.deltaframe = serverframe - offset;
526 	}
527 
528 	//r1: fix for precision loss for high serverframes
529 	if(cls.state != ca_active) cl.frame.servertime = 0;
530 	else cl.frame.servertime = (cl.frame.serverframe - cl.initial_server_frame) * 100;
531 
532 	//moving the extrabits from cmd over so that the 4 that come from
533 	//extraflags (surpressCount) don't conflict
534 	extraflags = extrabits >> 1;
535 
536 	// BIG HACK to let old demos continue to work
537 	if(cls.protocol != 26){
538 		byte data = MSG_ReadByte(&net_message);
539 
540 		//r1: HACK to get extra 4 bits of otherwise unused data
541 		if(cls.protocol == PROTOCOL_R1Q2){
542 			cl.surpressCount = (data & 0x0F);
543 			extraflags |= (data & 0xF0) >> 4;
544 		}
545 		else cl.surpressCount = data;
546 	}
547 
548 	if(cl_shownet->value == 3)
549 		Com_Printf ("   frame:%i  delta:%i\n", cl.frame.serverframe, cl.frame.deltaframe);
550 
551 	// If the frame is delta compressed from data that we
552 	// no longer have available, we must suck up the rest of
553 	// the frame, but not use it, then ask for a non-compressed
554 	// message
555 	if(cl.frame.deltaframe <= 0){
556 		cl.frame.valid = true; // uncompressed frame
557 		old = NULL;
558 		cls.demowaiting = false; // we can start recording now
559 	}
560 	else {
561 		old = &cl.frames[cl.frame.deltaframe & UPDATE_MASK];
562 		if(!old->valid)  // should never happen
563 			Com_Printf("Delta from invalid frame\n");
564 		if(old->serverframe != cl.frame.deltaframe)
565 			Com_DPrintf("Delta frame too old\n");
566 		else if(cl.parse_entities - old->parse_entities > MAX_PARSE_ENTITIES-128)
567 			Com_DPrintf("Delta parse_entities too old\n");
568 		else
569 			cl.frame.valid = true;	// valid delta parse
570 	}
571 
572 	if(cl.time > cl.frame.servertime) // clamp time
573 		cl.time = cl.frame.servertime;
574 	else if(cl.time < cl.frame.servertime - 100)
575 		cl.time = cl.frame.servertime - 100;
576 
577 	len = MSG_ReadByte(&net_message); // read areabits
578 	MSG_ReadData(&net_message, &cl.frame.areabits, len);
579 
580 	if(cls.protocol != PROTOCOL_R1Q2){ // read playerinfo
581 		cmd = MSG_ReadByte(&net_message);
582 		if(cmd != svc_playerinfo)
583 			Com_Error(ERR_DROP, "CL_ParseFrame: 0x%.2x not playerinfo", cmd);
584 	}
585 
586 	CL_ParsePlayerstate(old, &cl.frame, extraflags);
587 
588 	if(cls.protocol != PROTOCOL_R1Q2){ // read packet entities
589 		cmd = MSG_ReadByte(&net_message);
590 		if(cmd != svc_packetentities)
591 			Com_Error (ERR_DROP, "CL_ParseFrame: 0x%.2x not packetentities", cmd);
592 	}
593 
594 	CL_ParsePacketEntities(old, &cl.frame);
595 
596 	// save the frame off in the backup array for later delta comparisons
597 	cl.frames[cl.frame.serverframe & UPDATE_MASK] = cl.frame;
598 
599 	if(cl.frame.valid){
600 		// getting a valid frame message ends the connection process
601 		if(cls.state != ca_active){
602 			cls.state = ca_active;
603 
604 			//r1: fix for precision loss with high serverframes (when map runs for over several hours)
605 			cl.initial_server_frame = cl.frame.serverframe;
606 			cl.frame.servertime = (cl.frame.serverframe - cl.initial_server_frame) * 100;
607 
608 			cl.predicted_origin[0] = cl.frame.playerstate.pmove.origin[0] * 0.125f;
609 			cl.predicted_origin[1] = cl.frame.playerstate.pmove.origin[1] * 0.125f;
610 			cl.predicted_origin[2] = cl.frame.playerstate.pmove.origin[2] * 0.125f;
611 			VectorCopy(cl.frame.playerstate.viewangles, cl.predicted_angles);
612 		}
613 
614 		CL_FireEntityEvents(&cl.frame); // fire entity events
615 
616 		CL_CheckPredictionError();
617 	}
618 }
619 
620 
621 /*
622 
623 INTERPOLATE BETWEEN FRAMES TO GET RENDERING PARMS
624 
625 */
626 
S_RegisterSexedModel(entity_state_t * ent,char * base)627 struct model_s *S_RegisterSexedModel(entity_state_t *ent, char *base){
628 	int n;
629 	char *p;
630 	struct model_s *mdl;
631 	char model[MAX_QPATH];
632 	char buffer[MAX_QPATH];
633 
634 	// determine what model the client is using
635 	model[0] = 0;
636 	n = CS_PLAYERSKINS + ent->number - 1;
637 	if(cl.configstrings[n][0]){
638 		p = strchr(cl.configstrings[n], '\\');
639 		if(p){
640 			p += 1;
641 			strcpy(model, p);
642 			p = strchr(model, '/');
643 			if(p)
644 				*p = 0;
645 		}
646 	}
647 	// if we can't figure it out, they're male
648 	if(!model[0])
649 		strcpy(model, "male");
650 
651 	Com_sprintf(buffer, sizeof(buffer), "players/%s/%s", model, base + 1);
652 	mdl = GL_RegisterModel(buffer);
653 	if(!mdl){
654 		// not found, try default weapon model
655 		Com_sprintf(buffer, sizeof(buffer), "players/%s/weapon.md2", model);
656 		mdl = GL_RegisterModel(buffer);
657 		if(!mdl){
658 			// no, revert to the male model
659 			Com_sprintf(buffer, sizeof(buffer), "players/%s/%s", "male", base + 1);
660 			mdl = GL_RegisterModel(buffer);
661 			if(!mdl){
662 				// last try, default male weapon.md2
663 				Com_sprintf(buffer, sizeof(buffer), "players/male/weapon.md2");
664 				mdl = GL_RegisterModel(buffer);
665 			}
666 		}
667 	}
668 	return mdl;
669 }
670 
671 
672 /*
673 CL_AddPacketEntities
674 
675 */
CL_AddPacketEntities(frame_t * frame)676 void CL_AddPacketEntities(frame_t *frame){
677 	entity_t ent;
678 	entity_state_t *s1;
679 	float autorotate;
680 	int i;
681 	int pnum;
682 	centity_t *cent;
683 	int autoanim;
684 	clientinfo_t *ci;
685 	unsigned int effects, renderfx;
686 
687 	// bonus items rotate at a fixed rate
688 	autorotate = anglemod(cl.time / 10);
689 
690 	// brush models can auto animate their frames
691 	autoanim = 2 * cl.time / 1000;
692 
693 	for(pnum = 0; pnum < frame->num_entities; pnum++){
694 		s1 = &cl_parse_entities[(frame->parse_entities + pnum) & (MAX_PARSE_ENTITIES - 1)];
695 
696 		cent = &cl_entities[s1->number];
697 
698 		effects = s1->effects;
699 		renderfx = s1->renderfx;
700 
701 		// set frame
702 		if(effects & EF_ANIM01)
703 			ent.frame = autoanim & 1;
704 		else if(effects & EF_ANIM23)
705 			ent.frame = 2 + (autoanim & 1);
706 		else if(effects & EF_ANIM_ALL)
707 			ent.frame = autoanim;
708 		else if(effects & EF_ANIM_ALLFAST)
709 			ent.frame = cl.time / 100;
710 		else
711 			ent.frame = s1->frame;
712 
713 		// quad and pent can do different things on client
714 		if(effects & EF_PENT){
715 			effects &= ~EF_PENT;
716 			effects |= EF_COLOR_SHELL;
717 			renderfx |= RF_SHELL_RED;
718 		}
719 
720 		if(effects & EF_QUAD){
721 			effects &= ~EF_QUAD;
722 			effects |= EF_COLOR_SHELL;
723 			renderfx |= RF_SHELL_BLUE;
724 		}
725 
726 		ent.oldframe = cent->prev.frame;
727 		ent.backlerp = 1.0 - cl.lerpfrac;
728 
729 		if(renderfx & (RF_FRAMELERP | RF_BEAM)){  // step origin discretely
730 			if(renderfx & RF_BEAM){  // beam lerp
731 				for(i = 0; i < 3; i++){
732 					ent.oldorigin[i] = cent->prev.old_origin[i] + cl.lerpfrac *
733 						(cent->current.old_origin[i] - cent->prev.old_origin[i]);
734 					ent.origin[i] = cent->prev.origin[i] + cl.lerpfrac *
735 						(cent->current.origin[i] - cent->prev.origin[i]);
736 				}
737 			}
738 			else {  // just framelerp
739 				VectorCopy(cent->current.origin, ent.origin);
740 				VectorCopy(cent->current.old_origin, ent.oldorigin);
741 			}
742 		} else {  // interpolate origin
743 			for(i = 0; i < 3; i++){
744 				ent.origin[i] = ent.oldorigin[i] = cent->prev.origin[i] + cl.lerpfrac *
745 					(cent->current.origin[i] - cent->prev.origin[i]);
746 			}
747 		}
748 
749 		// create a new entity
750 
751 		// tweak the color of beams
752 		if(renderfx & RF_BEAM){  // the four beam colors are encoded in 32 bits of skinnum (hack)
753 			ent.alpha = 0.30;
754 			ent.skinnum = (s1->skinnum >> ((rand() % 4) * 8)) & 0xff;
755 			ent.model = NULL;
756 		} else {
757 			// set skin
758 			if(s1->modelindex == 255){  // use custom player skin
759 				ent.skinnum = 0;
760 				ci = &cl.clientinfo[s1->skinnum & 0xff];
761 				ent.skin = ci->skin;
762 				ent.model = ci->model;
763 				if(!ent.skin || !ent.model){
764 					ent.skin = cl.baseclientinfo.skin;
765 					ent.model = cl.baseclientinfo.model;
766 				}
767 			} else {
768 				ent.skinnum = s1->skinnum;
769 				ent.skin = NULL;
770 				ent.model = cl.model_draw[s1->modelindex];
771 			}
772 		}
773 
774 		// only used for black hole model right now, FIXME: do better
775 		if(renderfx & RF_TRANSLUCENT && !(renderfx & RF_BEAM))
776 			ent.alpha = 0.70f;
777 
778 		// render effects (fullbright, translucent, etc)
779 		if((effects & EF_COLOR_SHELL))
780 			ent.flags = 0;  // renderfx go on color shell entity
781 		else
782 			ent.flags = renderfx;
783 
784 		// calculate angles
785 		if(effects & EF_ROTATE){  // some bonus items auto-rotate
786 			ent.angles[0] = 0;
787 			ent.angles[1] = autorotate;
788 			ent.angles[2] = 0;
789 		}
790 		else {  // interpolate angles
791 			float a1, a2;
792 
793 			for(i = 0; i < 3; i++){
794 				a1 = cent->current.angles[i];
795 				a2 = cent->prev.angles[i];
796 				ent.angles[i] = LerpAngle(a2, a1, cl.lerpfrac);
797 			}
798 		}
799 
800 		if(s1->number == cl.playernum + 1){
801 			ent.flags |= RF_VIEWERMODEL;  // only draw from mirrors
802 			continue;
803 		}
804 
805 		// if set to invisible, skip
806 		if(!s1->modelindex)
807 			continue;
808 
809 		//  skip ugly 2d explosion
810 		if(effects & EF_BFG)
811 			goto trails;
812 
813 		// add to view list
814 		V_AddEntity(&ent);
815 
816 		// color shells generate a seperate entity for the main model
817 		if(effects & EF_COLOR_SHELL){
818 			ent.flags = renderfx | RF_TRANSLUCENT;
819 			ent.alpha = 0.30;
820 			V_AddEntity(&ent);
821 		}
822 
823 		ent.skin = NULL;  // never use a custom skin on others
824 		ent.skinnum = 0;
825 		ent.flags = 0;
826 		ent.alpha = 0;
827 
828 		// duplicate for linked models
829 		if(s1->modelindex2){
830 			if(s1->modelindex2 == 255){  // custom weapon
831 				ci = &cl.clientinfo[s1->skinnum & 0xff];
832 				i =(s1->skinnum >> 8); // 0 is default weapon model
833 				if(!cl_vwep->value || i > MAX_CLIENTWEAPONMODELS - 1)
834 					i = 0;
835 				ent.model = ci->weaponmodel[i];
836 				if(!ent.model){
837 					if(i != 0)
838 						ent.model = ci->weaponmodel[0];
839 					if(!ent.model)
840 						ent.model = cl.baseclientinfo.weaponmodel[0];
841 				}
842 			} else
843 				ent.model = cl.model_draw[s1->modelindex2];
844 
845 			V_AddEntity(&ent);
846 
847 			ent.flags = 0;
848 			ent.alpha = 0;
849 		}
850 		if(s1->modelindex3){
851 			ent.model = cl.model_draw[s1->modelindex3];
852 			V_AddEntity(&ent);
853 		}
854 		if(s1->modelindex4){
855 			ent.model = cl.model_draw[s1->modelindex4];
856 			V_AddEntity(&ent);
857 		}
858 
859 		if(effects & EF_POWERSCREEN){
860 			ent.model = cl_mod_powerscreen;
861 			ent.oldframe = 0;
862 			ent.frame = 0;
863 			ent.flags |=(RF_TRANSLUCENT | RF_SHELL_GREEN);
864 			ent.alpha = 0.30;
865 			V_AddEntity(&ent);
866 		}
867 
868 		trails:
869 		// add automatic particle trails
870 		if((effects&~EF_ROTATE)){
871 			if(effects & EF_ROCKET){
872 				CL_RocketTrail(cent->lerp_origin, ent.origin, cent);
873 			}else if(effects & EF_BLASTER){
874 				CL_BlasterTrail(cent->lerp_origin, ent.origin);
875 			} else if(effects & EF_GIB){
876 				CL_DiminishingTrail(cent->lerp_origin, ent.origin, cent, effects);
877 			} else if(effects & EF_GRENADE){
878 				CL_DiminishingTrail(cent->lerp_origin, ent.origin, cent, effects);
879 			} else if(effects & EF_FLIES){
880 				CL_FlyEffect(cent, ent.origin);
881 			} else if(effects & EF_BFG){
882 				CL_BFGParticles(&ent);
883 			} else if(effects & EF_FLAG1){
884 				CL_FlagTrail(cent->lerp_origin, ent.origin, 242);
885 			} else if(effects & EF_FLAG2){
886 				CL_FlagTrail(cent->lerp_origin, ent.origin, 115);
887 			}
888 		}
889 
890 		VectorCopy(ent.origin, cent->lerp_origin);
891 	}
892 }
893 
894 
895 /*
896 CL_CalcViewValues
897 
898 Sets cl.viewdef view values
899 */
CL_CalcViewValues(void)900 void CL_CalcViewValues(void){
901 	int i;
902 	float lerp, backlerp;
903 	frame_t *oldframe;
904 	player_state_t *ps, *ops;
905 
906 	// find the previous frame to interpolate from
907 	ps = &cl.frame.playerstate;
908 	i = (cl.frame.serverframe - 1) & UPDATE_MASK;
909 	oldframe = &cl.frames[i];
910 	if(oldframe->serverframe != cl.frame.serverframe - 1 || !oldframe->valid)
911 		oldframe = &cl.frame;  // previous frame was dropped or involid
912 	ops = &oldframe->playerstate;
913 
914 	// see if the player entity was teleported this frame
915 	if(abs(ops->pmove.origin[0] - ps->pmove.origin[0]) > 256 * 8
916 			|| abs(ops->pmove.origin[1] - ps->pmove.origin[1]) > 256 * 8
917 			|| abs(ops->pmove.origin[2] - ps->pmove.origin[2]) > 256 * 8)
918 		ops = ps;  // don't interpolate
919 
920 	lerp = cl.lerpfrac;
921 
922 	// calculate the origin
923 	if((cl_predict->value) && !(cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION)){  // use predicted values
924 		unsigned delta;
925 
926 		backlerp = 1.0 - lerp;
927 		for(i = 0; i < 3; i++){
928 			cl.viewdef.vieworg[i] = cl.predicted_origin[i] + ops->viewoffset[i]
929 				+ cl.lerpfrac * (ps->viewoffset[i] - ops->viewoffset[i])
930 				- backlerp * cl.prediction_error[i];
931 		}
932 
933 		// smooth out stair climbing
934 		delta = cls.realtime - cl.predicted_step_time;
935 		if(delta < 100)
936 			cl.viewdef.vieworg[2] -= cl.predicted_step * (100 - delta) * 0.01;
937 	} else {  // just use interpolated values
938 		for(i = 0; i < 3; i++)
939 			cl.viewdef.vieworg[i] = ops->pmove.origin[i] * 0.125 + ops->viewoffset[i]
940 				+ lerp *(ps->pmove.origin[i] * 0.125 + ps->viewoffset[i]
941 				- (ops->pmove.origin[i] * 0.125 + ops->viewoffset[i]));
942 	}
943 
944 	// if not running a demo or on a locked frame, add the local angle movement
945 	if(cl.frame.playerstate.pmove.pm_type < PM_DEAD){  // use predicted values
946 		for(i = 0; i < 3; i++)
947 			cl.viewdef.viewangles[i] = cl.predicted_angles[i];
948 	} else {  // just use interpolated values
949 		if(cl.frame.playerstate.pmove.pm_type >= PM_DEAD && ops->pmove.pm_type < PM_DEAD){
950 			//r1: fix for server no longer sending viewangles every frame.
951 			for(i = 0; i < 3; i++)
952 				cl.viewdef.viewangles[i] = LerpAngle(cl.predicted_angles[i], ps->viewangles[i], lerp);
953 		}
954 		else {
955 			for(i = 0; i < 3; i++)
956 				cl.viewdef.viewangles[i] = LerpAngle(ops->viewangles[i], ps->viewangles[i], lerp);
957 		}
958 	}
959 
960 	for(i = 0; i < 3; i++)
961 		cl.viewdef.viewangles[i] += LerpAngle(ops->kick_angles[i], ps->kick_angles[i], lerp);
962 
963 	AngleVectors(cl.viewdef.viewangles, cl.v_forward, cl.v_right, cl.v_up);
964 
965 	// interpolate field of view
966 	cl.viewdef.fov_x = ops->fov + lerp * (ps->fov - ops->fov);
967 }
968 
969 /*
970 CL_AddEntities
971 
972 Emits all entities, particles, and lights to the view
973 */
CL_AddEntities(void)974 void CL_AddEntities(void){
975 
976 	if(cls.state != ca_active)
977 		return;
978 
979 	if(cl.time > cl.frame.servertime){
980 		if(cl_showclamp->value)
981 			Com_Printf("high clamp %i\n", cl.time - cl.frame.servertime);
982 		cl.time = cl.frame.servertime;
983 		cl.lerpfrac = 1.0;
984 	} else if(cl.time < cl.frame.servertime - 100){
985 		if(cl_showclamp->value)
986 			Com_Printf("low clamp %i\n", cl.frame.servertime - 100 - cl.time);
987 		cl.time = cl.frame.servertime - 100;
988 		cl.lerpfrac = 0;
989 	} else
990 		cl.lerpfrac = 1.0 - (cl.frame.servertime - cl.time) * 0.01;
991 
992 
993 	if(timedemo->value)
994 		cl.lerpfrac = 1.0;
995 
996 	CL_CalcViewValues();
997 
998 	CL_AddPacketEntities(&cl.frame);
999 	CL_AddParticles();
1000 	CL_AddTEnts();
1001 }
1002 
1003 
1004 /*
1005 CL_GetEntitySoundOrigin
1006 
1007 Called to get the sound spatialization origin
1008 */
CL_GetEntitySoundOrigin(int ent,vec3_t org)1009 void CL_GetEntitySoundOrigin(int ent, vec3_t org){
1010 	centity_t *old;
1011 
1012 	if(ent < 0 || ent >= MAX_EDICTS)
1013 		Com_Error(ERR_DROP, "CL_GetEntitySoundOrigin: bad ent");
1014 	old = &cl_entities[ent];
1015 	VectorCopy(old->lerp_origin, org);
1016 
1017 	// FIXME: bmodel issues...
1018 }
1019