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

movevars_t communication

=============================================================================
*/
qboolean MSG_WriteDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to )
{
	delta_t		*pField;
	delta_info_t	*dt;
	int		i, startBit;
	int		numChanges = 0;

	dt = Delta_FindStruct( "movevars_t" );
	ASSERT( dt && dt->bInitialized );

	pField = dt->pFields;
	ASSERT( pField );

	startBit = msg->iCurBit;

	// activate fields and call custom encode func
	Delta_CustomEncode( dt, from, to );

	BF_WriteByte( msg, svc_deltamovevars );

	// process fields
	for( i = 0; i < dt->numFields; i++, pField++ )
	{
		if( Delta_WriteField( msg, pField, from, to, 0.0f ))
			numChanges++;
	}

	// if we have no changes - kill the message
	if( !numChanges )
	{
		BF_SeekToBit( msg, startBit );
		return false;
	}
	return true;
}
Ejemplo n.º 2
0
/*
==================
MSG_WriteWeaponData

Writes current client data only for local client
Other clients can grab the client state from entity_state_t
==================
*/
void MSG_WriteWeaponData( sizebuf_t *msg, weapon_data_t *from, weapon_data_t *to, float timebase, int index )
{
	delta_t		*pField;
	delta_info_t	*dt;
	int		i, startBit;
	int		numChanges = 0;

	dt = Delta_FindStruct( "weapon_data_t" );
	if( !dt || !dt->bInitialized )
	{
		Host_Error( "MSG_WriteWeaponData: delta not initialized!\n" );
	}

	pField = dt->pFields;
	ASSERT( pField );

	// activate fields and call custom encode func
	Delta_CustomEncode( dt, from, to );

	startBit = msg->iCurBit;

	BF_WriteOneBit( msg, 1 );
	BF_WriteUBitLong( msg, index, MAX_WEAPON_BITS );
               
	// process fields
	for( i = 0; i < dt->numFields; i++, pField++ )
	{
		if( Delta_WriteField( msg, pField, from, to, timebase ))
			numChanges++;
	}

	// if we have no changes - kill the message
	if( !numChanges ) BF_SeekToBit( msg, startBit );
}
Ejemplo n.º 3
0
void Delta_Init( void )
{
	delta_info_t	*dt;

	// shutdown it first
	if( delta_init ) Delta_Shutdown ();

	Delta_InitFields ();	// initialize fields
	delta_init = true;

	dt = Delta_FindStruct( "movevars_t" );

	ASSERT( dt != NULL );
	if( dt->bInitialized ) return;	// "movevars_t" already specified by user

	// create movevars_t delta internal
	Delta_AddField( "movevars_t", "gravity", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
	Delta_AddField( "movevars_t", "stopspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
	Delta_AddField( "movevars_t", "maxspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
	Delta_AddField( "movevars_t", "spectatormaxspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
	Delta_AddField( "movevars_t", "accelerate", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
	Delta_AddField( "movevars_t", "airaccelerate", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
	Delta_AddField( "movevars_t", "wateraccelerate", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
	Delta_AddField( "movevars_t", "friction", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
	Delta_AddField( "movevars_t", "edgefriction", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
	Delta_AddField( "movevars_t", "waterfriction", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
	Delta_AddField( "movevars_t", "bounce", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
	Delta_AddField( "movevars_t", "stepsize", DT_FLOAT|DT_SIGNED, 16, 16.0f, 1.0f );
	Delta_AddField( "movevars_t", "maxvelocity", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
	if( host.features & ENGINE_WRITE_LARGE_COORD )
		Delta_AddField( "movevars_t", "zmax", DT_FLOAT|DT_SIGNED, 18, 1.0f, 1.0f );	// no fractional part
	else
		Delta_AddField( "movevars_t", "zmax", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f );	// no fractional part
	Delta_AddField( "movevars_t", "waveHeight", DT_FLOAT|DT_SIGNED, 16, 16.0f, 8.0f );
	Delta_AddField( "movevars_t", "skyName", DT_STRING, 1, 1.0f, 1.0f ); 
	Delta_AddField( "movevars_t", "footsteps", DT_INTEGER, 1, 1.0f, 1.0f );
	Delta_AddField( "movevars_t", "rollangle", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
	Delta_AddField( "movevars_t", "rollspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
	Delta_AddField( "movevars_t", "skycolor_r", DT_FLOAT|DT_SIGNED, 12, 1.0f, 1.0f ); // 0 - 264
	Delta_AddField( "movevars_t", "skycolor_g", DT_FLOAT|DT_SIGNED, 12, 1.0f, 1.0f );
	Delta_AddField( "movevars_t", "skycolor_b", DT_FLOAT|DT_SIGNED, 12, 1.0f, 1.0f );
	Delta_AddField( "movevars_t", "skyvec_x", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f ); // 0 - 1
	Delta_AddField( "movevars_t", "skyvec_y", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
	Delta_AddField( "movevars_t", "skyvec_z", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
	Delta_AddField( "movevars_t", "skydir_x", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f ); // 0 - 1
	Delta_AddField( "movevars_t", "skydir_y", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
	Delta_AddField( "movevars_t", "skydir_z", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
	Delta_AddField( "movevars_t", "skyangle", DT_ANGLE, 16, 1.0f, 1.0f ); // 0 - 360
	Delta_AddField( "movevars_t", "wateralpha", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
	Delta_AddField( "movevars_t", "fog_settings", DT_INTEGER, 32, 1.0f, 1.0f );
	// now done
	dt->bInitialized = true;
}
Ejemplo n.º 4
0
qboolean Delta_AddField( const char *pStructName, const char *pName, int flags, int bits, float mul, float post_mul )
{
	delta_info_t	*dt;
	delta_field_t	*pFieldInfo;
	delta_t		*pField;
	int		i;

	// get the delta struct
	dt = Delta_FindStruct( pStructName );
	ASSERT( dt != NULL );

	// check for coexisting field
	for( i = 0, pField = dt->pFields; i < dt->numFields; i++, pField++ )
	{
		if( !Q_strcmp( pField->name, pName ))
		{
			MsgDev( D_NOTE, "Delta_Add: %s->%s already existing\n", pStructName, pName );
			return false; // field already exist		
		}
	}

	// find field description
	pFieldInfo = Delta_FindFieldInfo( dt->pInfo, pName );
	if( !pFieldInfo )
	{
		MsgDev( D_ERROR, "Delta_Add: couldn't find description for %s->%s\n", pStructName, pName );
		return false;
	}

	if( dt->numFields + 1 > dt->maxFields )
	{
		MsgDev( D_WARN, "Delta_Add: can't add %s->%s encoder list is full\n", pStructName, pName );
		return false; // too many fields specified (duplicated ?)
	}

	// allocate a new one
	dt->pFields = Z_Realloc( dt->pFields, (dt->numFields + 1) * sizeof( delta_t ));	
	for( i = 0, pField = dt->pFields; i < dt->numFields; i++, pField++ );

	// copy info to new field
	pField->name = pFieldInfo->name;
	pField->offset = pFieldInfo->offset;
	pField->size = pFieldInfo->size;
	pField->flags = flags;
	pField->bits = bits;
	pField->multiplier = mul;
	pField->post_multiplier = post_mul;
	dt->numFields++;

	return true;
}
Ejemplo n.º 5
0
void Delta_InitFields( void )
{
	char		*afile, *pfile;
	string		encodeDll, encodeFunc, token;
	delta_info_t	*dt;

	afile = FS_LoadFile( DELTA_PATH, NULL, false );
	if( !afile )
	{
		static string	errormsg;

		Q_snprintf( errormsg, sizeof( errormsg ), "DELTA_Load: couldn't load file %s\n", DELTA_PATH );
		Sys_Error( errormsg );
	}

	pfile = afile;

	while(( pfile = COM_ParseFile( pfile, token )) != NULL )
	{
		dt = Delta_FindStruct( token );
		if( dt == NULL )
		{
			Sys_Error( "delta.lst: unknown struct %s\n", token );
		}

		pfile = COM_ParseFile( pfile, encodeDll );

		if( !Q_stricmp( encodeDll, "none" ))
			Q_strcpy( encodeFunc, "null" );
		else pfile = COM_ParseFile( pfile, encodeFunc );

		// jump to '{'
		pfile = COM_ParseFile( pfile, token );
		if( token[0] != '{' )
		{
			Sys_Error( "delta.lst: missing '{' in section %s\n", dt->pName );
		}

		Delta_ParseTable( &pfile, dt, encodeDll, encodeFunc );
	}
	Mem_Free( afile );

	// adding some requrid fields fields that user may forget or don't know how to specified
	Delta_AddField( "event_t", "velocity[0]", DT_SIGNED | DT_FLOAT, 16, 8.0f, 1.0f );
	Delta_AddField( "event_t", "velocity[1]", DT_SIGNED | DT_FLOAT, 16, 8.0f, 1.0f );
	Delta_AddField( "event_t", "velocity[2]", DT_SIGNED | DT_FLOAT, 16, 8.0f, 1.0f );
}
Ejemplo n.º 6
0
/*
==================
MSG_ReadWeaponData

Read the clientdata
==================
*/
void MSG_ReadWeaponData( sizebuf_t *msg, weapon_data_t *from, weapon_data_t *to, float timebase )
{
	delta_t		*pField;
	delta_info_t	*dt;
	int		i;

	dt = Delta_FindStruct( "weapon_data_t" );
	ASSERT( dt && dt->bInitialized );

	pField = dt->pFields;
	ASSERT( pField );

	*to = *from;

	// process fields
	for( i = 0; i < dt->numFields; i++, pField++ )
	{
		Delta_ReadField( msg, pField, from, to, timebase );
	}
}
Ejemplo n.º 7
0
void MSG_ReadDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to )
{
	delta_t		*pField;
	delta_info_t	*dt;
	int		i;

	dt = Delta_FindStruct( "movevars_t" );
	ASSERT( dt && dt->bInitialized );

	pField = dt->pFields;
	ASSERT( pField );

	*to = *from;

	// process fields
	for( i = 0; i < dt->numFields; i++, pField++ )
	{
		Delta_ReadField( msg, pField, from, to, 0.0f );
	}
}
Ejemplo n.º 8
0
/*
==================
MSG_WriteClientData

Writes current client data only for local client
Other clients can grab the client state from entity_state_t
==================
*/
void MSG_WriteClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, float timebase )
{
	delta_t		*pField;
	delta_info_t	*dt;
	int		i;

	dt = Delta_FindStruct( "clientdata_t" );
	ASSERT( dt && dt->bInitialized );

	pField = dt->pFields;
	ASSERT( pField );

	// activate fields and call custom encode func
	Delta_CustomEncode( dt, from, to );

	// process fields
	for( i = 0; i < dt->numFields; i++, pField++ )
	{
		 Delta_WriteField( msg, pField, from, to, timebase );
	}
}
Ejemplo n.º 9
0
/*
=====================
MSG_WriteDeltaEvent
=====================
*/
void MSG_WriteDeltaEvent( sizebuf_t *msg, event_args_t *from, event_args_t *to )
{
	delta_t		*pField;
	delta_info_t	*dt;
	int		i;

	dt = Delta_FindStruct( "event_t" );
	ASSERT( dt && dt->bInitialized );

	pField = dt->pFields;
	ASSERT( pField );

	// activate fields and call custom encode func
	Delta_CustomEncode( dt, from, to );

	// process fields
	for( i = 0; i < dt->numFields; i++, pField++ )
	{
		Delta_WriteField( msg, pField, from, to, 0.0f );
	}
}
Ejemplo n.º 10
0
/*
==================
MSG_ReadClientData

Read the clientdata
==================
*/
void MSG_ReadClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, float timebase )
{
	delta_t		*pField;
	delta_info_t	*dt;
	int		i;

	dt = Delta_FindStruct( "clientdata_t" );
	if( !dt || !dt->bInitialized )
	{
		Host_Error( "MSG_ReadClientData: delta not initialized!\n" );
	}

	pField = dt->pFields;
	ASSERT( pField );

	*to = *from;

	// process fields
	for( i = 0; i < dt->numFields; i++, pField++ )
	{
		Delta_ReadField( msg, pField, from, to, timebase );
	}
}
Ejemplo n.º 11
0
/*
=====================
MSG_ReadDeltaEvent
=====================
*/
void MSG_ReadDeltaEvent( sizebuf_t *msg, event_args_t *from, event_args_t *to )
{
	delta_t		*pField;
	delta_info_t	*dt;
	int		i;

	dt = Delta_FindStruct( "event_t" );
	if( !dt || !dt->bInitialized )
	{
		Host_Error( "MSG_ReadDeltaEvent: delta not initialized!\n" );
	}

	pField = dt->pFields;
	ASSERT( pField );

	*to = *from;

	// process fields
	for( i = 0; i < dt->numFields; i++, pField++ )
	{
		Delta_ReadField( msg, pField, from, to, 0.0f );
	}
}
Ejemplo n.º 12
0
/*
=====================
MSG_WriteDeltaUsercmd
=====================
*/
void MSG_WriteDeltaUsercmd( sizebuf_t *msg, usercmd_t *from, usercmd_t *to )
{
	delta_t		*pField;
	delta_info_t	*dt;
	int		i;

	dt = Delta_FindStruct( "usercmd_t" );
	if( !dt || !dt->bInitialized )
	{
		Host_Error( "MSG_WriteDeltaUsercmd: delta not initialized!\n" );
	}

	pField = dt->pFields;
	ASSERT( pField );

	// activate fields and call custom encode func
	Delta_CustomEncode( dt, from, to );

	// process fields
	for( i = 0; i < dt->numFields; i++, pField++ )
	{
		Delta_WriteField( msg, pField, from, to, 0.0f );
	}
}
Ejemplo n.º 13
0
/*
==================
MSG_ReadDeltaEntity

The entity number has already been read from the message, which
is how the from state is identified.
                             
If the delta removes the entity, entity_state_t->number will be set to MAX_EDICTS
Can go from either a baseline or a previous packet_entity
==================
*/
qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state_t *to, int number, qboolean player, float timebase )
{
	delta_info_t	*dt = NULL;
	delta_t		*pField;
	int		i, fRemoveType;
#ifndef XASH_DEDICATED
	if( number < 0 || number >= clgame.maxEntities )
	{
		// broken packet, try to skip it
		MsgDev( D_ERROR, "MSG_ReadDeltaEntity: bad delta entity number: %i\n", number );
		return false;
	}

	*to = *from;
	to->number = number;
	fRemoveType = BF_ReadUBitLong( msg, 2 );

	if( fRemoveType )
	{
		// check for a remove
		Q_memset( to, 0, sizeof( *to ));

		if( fRemoveType & 1 )
		{
			// removed from delta-message
			return false;
                    }

		if( fRemoveType & 2 )
		{	
			// entity was removed from server
			to->number = -1;
			return false;
		}

		MsgDev( D_ERROR, "MSG_ReadDeltaEntity: unknown update type %i\n", fRemoveType );
		return false;
	}

	if( BF_ReadOneBit( msg ))
		to->entityType = BF_ReadUBitLong( msg, 2 );


	if( to->entityType == ENTITY_BEAM )
	{
		dt = Delta_FindStruct( "custom_entity_state_t" );
	}
	else //  ENTITY_NORMAL or other (try predict type)
	{
		/* Omit connection drop on wromg data from server.
		 * I know that it is very dirty,
		 * but i don't know how to do it better.*/
		if( to->entityType != ENTITY_NORMAL )
			MsgDev( D_NOTE, "MSG_ReadDeltaEntity: broken delta: entityType = %d\n", to->entityType );
		if( player )
		{
			dt = Delta_FindStruct( "entity_state_player_t" );
		}
		else
		{
			dt = Delta_FindStruct( "entity_state_t" );
		}
	}

	if( !(dt && dt->bInitialized) ) // Broken  delta?
	{
		MsgDev( D_ERROR, "MSG_ReadDeltaEntity: broken delta\n");
		return true;
	}
	pField = dt->pFields;
	ASSERT( pField );

	// process fields
	for( i = 0; i < dt->numFields; i++, pField++ )
	{
		Delta_ReadField( msg, pField, from, to, timebase );
	}
#endif
	// message parsed
	return true;
}
Ejemplo n.º 14
0
/*
==================
MSG_WriteDeltaEntity

Writes part of a packetentities message, including the entity number.
Can delta from either a baseline or a previous packet_entity
If to is NULL, a remove entity update will be sent
If force is not set, then nothing at all will be generated if the entity is
identical, under the assumption that the in-order delta code will catch it.
==================
*/
void MSG_WriteDeltaEntity( entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qboolean force, qboolean player, float timebase ) 
{
	delta_info_t	*dt = NULL;
	delta_t		*pField;
	int		i, startBit;
	int		numChanges = 0;

	if( to == NULL )
	{
		int	fRemoveType;

		if( from == NULL ) return;

		// a NULL to is a delta remove message
		BF_WriteWord( msg, from->number );

		// fRemoveType:
		// 0 - keep alive, has delta-update
		// 1 - remove from delta message (but keep states)
		// 2 - completely remove from server
		if( force ) fRemoveType = 2;
		else fRemoveType = 1;

		BF_WriteUBitLong( msg, fRemoveType, 2 );
		return;
	}

	startBit = msg->iCurBit;

	if( to->number < 0 || to->number >= GI->max_edicts )
	{
		MsgDev( D_ERROR, "MSG_WriteDeltaEntity: Bad entity number: %i\n", to->number );
		return;
	}

	BF_WriteWord( msg, to->number );
	BF_WriteUBitLong( msg, 0, 2 ); // alive

	if( to->entityType != from->entityType )
	{
		BF_WriteOneBit( msg, 1 );
		BF_WriteUBitLong( msg, to->entityType, 2 );
	}
	else BF_WriteOneBit( msg, 0 ); 

	if( to->entityType == ENTITY_NORMAL )
	{
		if( player )
		{
			dt = Delta_FindStruct( "entity_state_player_t" );
		}
		else
		{
			dt = Delta_FindStruct( "entity_state_t" );
		}
	}
	else if( to->entityType == ENTITY_BEAM )
	{
		dt = Delta_FindStruct( "custom_entity_state_t" );
	}

	ASSERT( dt && dt->bInitialized );
		
	pField = dt->pFields;
	ASSERT( pField );

	// activate fields and call custom encode func
	Delta_CustomEncode( dt, from, to );

	// process fields
	for( i = 0; i < dt->numFields; i++, pField++ )
	{
		if( Delta_WriteField( msg, pField, from, to, timebase ))
			numChanges++;
	}

	// if we have no changes - kill the message
	if( !numChanges && !force ) BF_SeekToBit( msg, startBit );
}
Ejemplo n.º 15
0
/*
==================
MSG_ReadDeltaEntity

The entity number has already been read from the message, which
is how the from state is identified.

If the delta removes the entity, entity_state_t->number will be set to MAX_EDICTS
Can go from either a baseline or a previous packet_entity
==================
*/
qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state_t *to, int number, qboolean player, float timebase )
{
	delta_info_t	*dt = NULL;
	delta_t		*pField;
	int		i, fRemoveType;

#ifndef _DEDICATED
	if( number < 0 || number >= clgame.maxEntities )
		Host_Error( "MSG_ReadDeltaEntity: bad delta entity number: %i\n", number );
#endif

	*to = *from;
	to->number = number;
	fRemoveType = BF_ReadUBitLong( msg, 2 );

	if( fRemoveType )
	{
		// check for a remove
		Q_memset( to, 0, sizeof( *to ));

		if( fRemoveType & 1 )
		{
			// removed from delta-message
			return false;
                    }

		if( fRemoveType & 2 )
		{
			// entity was removed from server
			to->number = -1;
			return false;
		}

		Host_Error( "MSG_ReadDeltaEntity: unknown update type %i\n", fRemoveType );
	}

	if( BF_ReadOneBit( msg ))
		to->entityType = BF_ReadUBitLong( msg, 2 );

	if( to->entityType == ENTITY_NORMAL )
	{
		if( player )
		{
			dt = Delta_FindStruct( "entity_state_player_t" );
		}
		else
		{
			dt = Delta_FindStruct( "entity_state_t" );
		}
	}
	else if( to->entityType == ENTITY_BEAM )
	{
		dt = Delta_FindStruct( "custom_entity_state_t" );
	}

	ASSERT( dt && dt->bInitialized );

	pField = dt->pFields;
	ASSERT( pField );

	// process fields
	for( i = 0; i < dt->numFields; i++, pField++ )
	{
		Delta_ReadField( msg, pField, from, to, timebase );
	}

	// message parsed
	return true;
}