/* ============ 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; }
/* ================ 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(); } }
/* ============ 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; }