예제 #1
0
/*
============
idScriptObject::GetVariable
============
*/
byte *idScriptObject::GetVariable( const char *name, etype_t etype ) const
{
	int				i;
	int				pos;
	const idTypeDef	*t;
	const idTypeDef	*parm;
	
	if( type == &type_object )
	{
		return NULL;
	}
	
	t = type;
	do
	{
		if( t->SuperClass() != &type_object )
		{
			pos = t->SuperClass()->Size();
		}
		else
		{
			pos = 0;
		}
		for( i = 0; i < t->NumParameters(); i++ )
		{
			parm = t->GetParmType( i );
			if( !strcmp( t->GetParmName( i ), name ) )
			{
				if( etype != parm->FieldType()->Type() )
				{
					return NULL;
				}
				return &data[ pos ];
			}
			
			if( parm->FieldType()->Inherits( &type_object ) )
			{
				pos += type_object.Size();
			}
			else
			{
				pos += parm->FieldType()->Size();
			}
		}
		t = t->SuperClass();
	}
	while( t && ( t != &type_object ) );
	
	return NULL;
}
예제 #2
0
/*
================
idTypeDef::AddField

Adds a new field to an object type.
================
*/
void idTypeDef::AddField( idTypeDef *fieldtype, const char *name ) {
	if ( type != ev_object ) {
		throw idCompileError( "idTypeDef::AddField : tried to add field to non-object type" );
	}

	parmTypes.Append( fieldtype );
	idStr &parmName = parmNames.Alloc();
	parmName = name;

	if ( fieldtype->FieldType()->Inherits( &type_object ) ) {
		size += type_object.Size();
	} else {
		size += fieldtype->FieldType()->Size();
	}
}
예제 #3
0
/*
============
idProgram::AllocDef
============
*/
idVarDef *idProgram::AllocDef( idTypeDef *type, const char *name, idVarDef *scope, bool constant )
{
	idVarDef	*def;
	idStr		element;
	idVarDef	*def_x;
	idVarDef	*def_y;
	idVarDef	*def_z;
	
	// allocate a new def
	def = new idVarDef( type );
	def->scope		= scope;
	def->numUsers	= 1;
	def->num		= varDefs.Append( def );
	
	// add the def to the list with defs with this name and set the name pointer
	AddDefToNameList( def, name );
	
	if( ( type->Type() == ev_vector ) || ( ( type->Type() == ev_field ) && ( type->FieldType()->Type() == ev_vector ) ) )
	{
		//
		// vector
		//
		if( !strcmp( name, RESULT_STRING ) )
		{
			// <RESULT> vector defs don't need the _x, _y and _z components
			assert( scope->Type() == ev_function );
			def->value.stackOffset	= scope->value.functionPtr->locals;
			def->initialized		= idVarDef::stackVariable;
			scope->value.functionPtr->locals += type->Size();
		}
		else if( scope->TypeDef()->Inherits( &type_object ) )
		{
			idTypeDef	newtype( ev_field, NULL, "float field", 0, &type_float );
			idTypeDef	*type = GetType( newtype, true );
			
			// set the value to the variable's position in the object
			def->value.ptrOffset = scope->TypeDef()->Size();
			
			// make automatic defs for the vectors elements
			// origin can be accessed as origin_x, origin_y, and origin_z
			sprintf( element, "%s_x", def->Name() );
			def_x = AllocDef( type, element, scope, constant );
			
			sprintf( element, "%s_y", def->Name() );
			def_y = AllocDef( type, element, scope, constant );
			def_y->value.ptrOffset = def_x->value.ptrOffset + type_float.Size();
			
			sprintf( element, "%s_z", def->Name() );
			def_z = AllocDef( type, element, scope, constant );
			def_z->value.ptrOffset = def_y->value.ptrOffset + type_float.Size();
		}
		else
		{
			// make automatic defs for the vectors elements
			// origin can be accessed as origin_x, origin_y, and origin_z
			sprintf( element, "%s_x", def->Name() );
			def_x = AllocDef( &type_float, element, scope, constant );
			
			sprintf( element, "%s_y", def->Name() );
			def_y = AllocDef( &type_float, element, scope, constant );
			
			sprintf( element, "%s_z", def->Name() );
			def_z = AllocDef( &type_float, element, scope, constant );
			
			// point the vector def to the x coordinate
			def->value			= def_x->value;
			def->initialized	= def_x->initialized;
		}
	}
	else if( scope->TypeDef()->Inherits( &type_object ) )
	{
		//
		// object variable
		//
		// set the value to the variable's position in the object
		def->value.ptrOffset = scope->TypeDef()->Size();
	}
	else if( scope->Type() == ev_function )
	{
		//
		// stack variable
		//
		// since we don't know how many local variables there are,
		// we have to have them go backwards on the stack
		def->value.stackOffset	= scope->value.functionPtr->locals;
		def->initialized		= idVarDef::stackVariable;
		
		if( type->Inherits( &type_object ) )
		{
			// objects only have their entity number on the stack, not the entire object
			scope->value.functionPtr->locals += type_object.Size();
		}
		else
		{
			scope->value.functionPtr->locals += type->Size();
		}
	}
	else
	{
		//
		// global variable
		//
		def->value.bytePtr = &variables[ numVariables ];
		numVariables += def->TypeDef()->Size();
		if( numVariables > sizeof( variables ) )
		{
			throw idCompileError( va( "Exceeded global memory size (%d bytes)", sizeof( variables ) ) );
		}
		
		memset( def->value.bytePtr, 0, def->TypeDef()->Size() );
	}
	
	return def;
}