Ejemplo n.º 1
0
/*
==================
SV_WriteEntitiesToClient

==================
*/
void SV_WriteEntitiesToClient( sv_client_t *cl, sizebuf_t *msg )
{
	edict_t		*clent;
	edict_t		*viewent;	// may be NULL
	client_frame_t	*frame;
	entity_state_t	*state;
	static sv_ents_t	frame_ents;
	int		i, send_pings;

	clent = cl->edict;
	if(	!SV_IsValidEdict( clent ) )
	{
		SV_DropClient ( cl );
		return;
	}
	viewent = cl->pViewEntity;	// himself or trigger_camera

	frame = &cl->frames[cl->netchan.outgoing_sequence & SV_UPDATE_MASK];

	send_pings = SV_ShouldUpdatePing( cl );

	sv.net_framenum++;	// now all portal-through entities are invalidate
	sv.hostflags &= ~SVF_PORTALPASS;

	// clear everything in this snapshot
	frame_ents.num_entities = c_fullsend = 0;

	// add all the entities directly visible to the eye, which
	// may include portal entities that merge other viewpoints
	SV_AddEntitiesToPacket( viewent, clent, frame, &frame_ents );
   
	// if there were portals visible, there may be out of order entities
	// in the list which will need to be resorted for the delta compression
	// to work correctly.  This also catches the error condition
	// of an entity being included twice.
	qsort( frame_ents.entities, frame_ents.num_entities, sizeof( frame_ents.entities[0] ), SV_EntityNumbers );

	// copy the entity states out
	frame->num_entities = 0;
	frame->first_entity = svs.next_client_entities;

	for( i = 0; i < frame_ents.num_entities; i++ )
	{
		// add it to the circular packet_entities array
		state = &svs.packet_entities[svs.next_client_entities % svs.num_client_entities];
		*state = frame_ents.entities[i];
		svs.next_client_entities++;

		// this should never hit, map should always be restarted first in SV_Frame
		if( svs.next_client_entities >= 0x7FFFFFFE )
			Host_Error( "svs.next_client_entities wrapped\n" );
		frame->num_entities++;
	}

	SV_EmitPacketEntities( cl, frame, msg );
	SV_EmitEvents( cl, frame, msg );
	if( send_pings ) SV_EmitPings( msg );
}
Ejemplo n.º 2
0
/*
==================
SV_WriteFrameToClient
==================
*/
void SV_WriteFrameToClient( sv_client_t *cl, sizebuf_t *msg )
{
	client_frame_t	*frame, *oldframe;
	int		lastframe;

	// this is the frame we are creating
	frame = &cl->frames[sv.framenum & SV_UPDATE_MASK];

	if( cl->lastframe <= 0 )
	{	
		// client is asking for a retransmit
		oldframe = NULL;
		lastframe = -1;
	}
	else if( sv.framenum - cl->lastframe >= (SV_UPDATE_BACKUP - 3))
	{
		// client hasn't gotten a good message through in a long time
		oldframe = NULL;
		lastframe = -1;
	}
	else
	{	// we have a valid message to delta from
		oldframe = &cl->frames[cl->lastframe & SV_UPDATE_MASK];
		lastframe = cl->lastframe;

		// the snapshot's entities may still have rolled off the buffer, though
		if( oldframe->first_entity <= svs.next_client_entities - svs.num_client_entities )
		{
			MsgDev( D_WARN, "%s: ^7delta request from out of date entities.\n", cl->name );
			oldframe = NULL;
			lastframe = 0;
		}
	}

	// refresh physinfo if needs
	if( cl->physinfo_modified )
	{
		cl->physinfo_modified = false;
		MSG_WriteByte( msg, svc_physinfo );
		MSG_WriteString( msg, cl->physinfo );
	}

	// delta encode the events
	SV_EmitEvents( cl, frame, msg );

	MSG_WriteByte( msg, svc_frame );
	MSG_WriteLong( msg, sv.framenum );
	MSG_WriteLong( msg, sv.time );		// send a servertime each frame
	MSG_WriteLong( msg, sv.frametime );
	MSG_WriteLong( msg, lastframe );		// what we are delta'ing from
	MSG_WriteByte( msg, cl->surpressCount );	// rate dropped packets
	MSG_WriteByte( msg, frame->index );		// send a client index
	cl->surpressCount = 0;

	// send over the areabits
	MSG_WriteByte( msg, frame->areabits_size );	// never more than 255 bytes
	MSG_WriteData( msg, frame->areabits, frame->areabits_size );

	// delta encode the entities
	SV_EmitPacketEntities( oldframe, frame, msg );
}