Skip to content

Instantly share code, notes, and snippets.

@jaimefjorge
Created December 1, 2011 20:36
Show Gist options
  • Save jaimefjorge/1419655 to your computer and use it in GitHub Desktop.
Save jaimefjorge/1419655 to your computer and use it in GitHub Desktop.
Kamino Largest Clone detected in Doom 3
// This code fragment exists in two separate files:
// 1- neo/game/script/Script_Interpreter.cpp
// 2- neo/d3xp/script/Script_Interpreter.cpp
//
while( !doneProcessing && !threadDying ) {
instructionPointer++;
if ( !--runaway ) {
Error( "runaway loop error" );
}
// next statement
st = &gameLocal.program.GetStatement( instructionPointer );
switch( st->op ) {
case OP_RETURN:
LeaveFunction( st->a );
break;
case OP_THREAD:
newThread = new idThread( this, st->a->value.functionPtr, st->b->value.argSize );
newThread->Start();
// return the thread number to the script
gameLocal.program.ReturnFloat( newThread->GetThreadNum() );
PopParms( st->b->value.argSize );
break;
case OP_OBJTHREAD:
var_a = GetVariable( st->a );
obj = GetScriptObject( *var_a.entityNumberPtr );
if ( obj ) {
func = obj->GetTypeDef()->GetFunction( st->b->value.virtualFunction );
assert( st->c->value.argSize == func->parmTotal );
newThread = new idThread( this, GetEntity( *var_a.entityNumberPtr ), func, func->parmTotal );
newThread->Start();
// return the thread number to the script
gameLocal.program.ReturnFloat( newThread->GetThreadNum() );
} else {
// return a null thread to the script
gameLocal.program.ReturnFloat( 0.0f );
}
PopParms( st->c->value.argSize );
break;
case OP_CALL:
EnterFunction( st->a->value.functionPtr, false );
break;
case OP_EVENTCALL:
CallEvent( st->a->value.functionPtr, st->b->value.argSize );
break;
case OP_OBJECTCALL:
var_a = GetVariable( st->a );
obj = GetScriptObject( *var_a.entityNumberPtr );
if ( obj ) {
func = obj->GetTypeDef()->GetFunction( st->b->value.virtualFunction );
EnterFunction( func, false );
} else {
// return a 'safe' value
gameLocal.program.ReturnVector( vec3_zero );
gameLocal.program.ReturnString( "" );
PopParms( st->c->value.argSize );
}
break;
case OP_SYSCALL:
CallSysEvent( st->a->value.functionPtr, st->b->value.argSize );
break;
case OP_IFNOT:
var_a = GetVariable( st->a );
if ( *var_a.intPtr == 0 ) {
NextInstruction( instructionPointer + st->b->value.jumpOffset );
}
break;
case OP_IF:
var_a = GetVariable( st->a );
if ( *var_a.intPtr != 0 ) {
NextInstruction( instructionPointer + st->b->value.jumpOffset );
}
break;
case OP_GOTO:
NextInstruction( instructionPointer + st->a->value.jumpOffset );
break;
case OP_ADD_F:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = *var_a.floatPtr + *var_b.floatPtr;
break;
case OP_ADD_V:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.vectorPtr = *var_a.vectorPtr + *var_b.vectorPtr;
break;
case OP_ADD_S:
SetString( st->c, GetString( st->a ) );
AppendString( st->c, GetString( st->b ) );
break;
case OP_ADD_FS:
var_a = GetVariable( st->a );
SetString( st->c, FloatToString( *var_a.floatPtr ) );
AppendString( st->c, GetString( st->b ) );
break;
case OP_ADD_SF:
var_b = GetVariable( st->b );
SetString( st->c, GetString( st->a ) );
AppendString( st->c, FloatToString( *var_b.floatPtr ) );
break;
case OP_ADD_VS:
var_a = GetVariable( st->a );
SetString( st->c, var_a.vectorPtr->ToString() );
AppendString( st->c, GetString( st->b ) );
break;
case OP_ADD_SV:
var_b = GetVariable( st->b );
SetString( st->c, GetString( st->a ) );
AppendString( st->c, var_b.vectorPtr->ToString() );
break;
case OP_SUB_F:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = *var_a.floatPtr - *var_b.floatPtr;
break;
case OP_SUB_V:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.vectorPtr = *var_a.vectorPtr - *var_b.vectorPtr;
break;
case OP_MUL_F:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = *var_a.floatPtr * *var_b.floatPtr;
break;
case OP_MUL_V:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = *var_a.vectorPtr * *var_b.vectorPtr;
break;
case OP_MUL_FV:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.vectorPtr = *var_a.floatPtr * *var_b.vectorPtr;
break;
case OP_MUL_VF:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.vectorPtr = *var_a.vectorPtr * *var_b.floatPtr;
break;
case OP_DIV_F:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
if ( *var_b.floatPtr == 0.0f ) {
Warning( "Divide by zero" );
*var_c.floatPtr = idMath::INFINITY;
} else {
*var_c.floatPtr = *var_a.floatPtr / *var_b.floatPtr;
}
break;
case OP_MOD_F:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable ( st->c );
if ( *var_b.floatPtr == 0.0f ) {
Warning( "Divide by zero" );
*var_c.floatPtr = *var_a.floatPtr;
} else {
*var_c.floatPtr = static_cast<int>( *var_a.floatPtr ) % static_cast<int>( *var_b.floatPtr );
}
break;
case OP_BITAND:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = static_cast<int>( *var_a.floatPtr ) & static_cast<int>( *var_b.floatPtr );
break;
case OP_BITOR:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = static_cast<int>( *var_a.floatPtr ) | static_cast<int>( *var_b.floatPtr );
break;
case OP_GE:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.floatPtr >= *var_b.floatPtr );
break;
case OP_LE:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.floatPtr <= *var_b.floatPtr );
break;
case OP_GT:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.floatPtr > *var_b.floatPtr );
break;
case OP_LT:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.floatPtr < *var_b.floatPtr );
break;
case OP_AND:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.floatPtr != 0.0f ) && ( *var_b.floatPtr != 0.0f );
break;
case OP_AND_BOOLF:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.intPtr != 0 ) && ( *var_b.floatPtr != 0.0f );
break;
case OP_AND_FBOOL:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.floatPtr != 0.0f ) && ( *var_b.intPtr != 0 );
break;
case OP_AND_BOOLBOOL:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.intPtr != 0 ) && ( *var_b.intPtr != 0 );
break;
case OP_OR:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.floatPtr != 0.0f ) || ( *var_b.floatPtr != 0.0f );
break;
case OP_OR_BOOLF:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.intPtr != 0 ) || ( *var_b.floatPtr != 0.0f );
break;
case OP_OR_FBOOL:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.floatPtr != 0.0f ) || ( *var_b.intPtr != 0 );
break;
case OP_OR_BOOLBOOL:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.intPtr != 0 ) || ( *var_b.intPtr != 0 );
break;
case OP_NOT_BOOL:
var_a = GetVariable( st->a );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.intPtr == 0 );
break;
case OP_NOT_F:
var_a = GetVariable( st->a );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.floatPtr == 0.0f );
break;
case OP_NOT_V:
var_a = GetVariable( st->a );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.vectorPtr == vec3_zero );
break;
case OP_NOT_S:
var_c = GetVariable( st->c );
*var_c.floatPtr = ( strlen( GetString( st->a ) ) == 0 );
break;
case OP_NOT_ENT:
var_a = GetVariable( st->a );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( GetEntity( *var_a.entityNumberPtr ) == NULL );
break;
case OP_NEG_F:
var_a = GetVariable( st->a );
var_c = GetVariable( st->c );
*var_c.floatPtr = -*var_a.floatPtr;
break;
case OP_NEG_V:
var_a = GetVariable( st->a );
var_c = GetVariable( st->c );
*var_c.vectorPtr = -*var_a.vectorPtr;
break;
case OP_INT_F:
var_a = GetVariable( st->a );
var_c = GetVariable( st->c );
*var_c.floatPtr = static_cast<int>( *var_a.floatPtr );
break;
case OP_EQ_F:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.floatPtr == *var_b.floatPtr );
break;
case OP_EQ_V:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.vectorPtr == *var_b.vectorPtr );
break;
case OP_EQ_S:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( idStr::Cmp( GetString( st->a ), GetString( st->b ) ) == 0 );
break;
case OP_EQ_E:
case OP_EQ_EO:
case OP_EQ_OE:
case OP_EQ_OO:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.entityNumberPtr == *var_b.entityNumberPtr );
break;
case OP_NE_F:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.floatPtr != *var_b.floatPtr );
break;
case OP_NE_V:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.vectorPtr != *var_b.vectorPtr );
break;
case OP_NE_S:
var_c = GetVariable( st->c );
*var_c.floatPtr = ( idStr::Cmp( GetString( st->a ), GetString( st->b ) ) != 0 );
break;
case OP_NE_E:
case OP_NE_EO:
case OP_NE_OE:
case OP_NE_OO:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
var_c = GetVariable( st->c );
*var_c.floatPtr = ( *var_a.entityNumberPtr != *var_b.entityNumberPtr );
break;
case OP_UADD_F:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
*var_b.floatPtr += *var_a.floatPtr;
break;
case OP_UADD_V:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
*var_b.vectorPtr += *var_a.vectorPtr;
break;
case OP_USUB_F:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
*var_b.floatPtr -= *var_a.floatPtr;
break;
case OP_USUB_V:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
*var_b.vectorPtr -= *var_a.vectorPtr;
break;
case OP_UMUL_F:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
*var_b.floatPtr *= *var_a.floatPtr;
break;
case OP_UMUL_V:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
*var_b.vectorPtr *= *var_a.floatPtr;
break;
case OP_UDIV_F:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
if ( *var_a.floatPtr == 0.0f ) {
Warning( "Divide by zero" );
*var_b.floatPtr = idMath::INFINITY;
} else {
*var_b.floatPtr = *var_b.floatPtr / *var_a.floatPtr;
}
break;
case OP_UDIV_V:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
if ( *var_a.floatPtr == 0.0f ) {
Warning( "Divide by zero" );
var_b.vectorPtr->Set( idMath::INFINITY, idMath::INFINITY, idMath::INFINITY );
} else {
*var_b.vectorPtr = *var_b.vectorPtr / *var_a.floatPtr;
}
break;
case OP_UMOD_F:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
if ( *var_a.floatPtr == 0.0f ) {
Warning( "Divide by zero" );
*var_b.floatPtr = *var_a.floatPtr;
} else {
*var_b.floatPtr = static_cast<int>( *var_b.floatPtr ) % static_cast<int>( *var_a.floatPtr );
}
break;
case OP_UOR_F:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
*var_b.floatPtr = static_cast<int>( *var_b.floatPtr ) | static_cast<int>( *var_a.floatPtr );
break;
case OP_UAND_F:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
*var_b.floatPtr = static_cast<int>( *var_b.floatPtr ) & static_cast<int>( *var_a.floatPtr );
break;
case OP_UINC_F:
var_a = GetVariable( st->a );
( *var_a.floatPtr )++;
break;
case OP_UINCP_F:
var_a = GetVariable( st->a );
obj = GetScriptObject( *var_a.entityNumberPtr );
if ( obj ) {
var.bytePtr = &obj->data[ st->b->value.ptrOffset ];
( *var.floatPtr )++;
}
break;
case OP_UDEC_F:
var_a = GetVariable( st->a );
( *var_a.floatPtr )--;
break;
case OP_UDECP_F:
var_a = GetVariable( st->a );
obj = GetScriptObject( *var_a.entityNumberPtr );
if ( obj ) {
var.bytePtr = &obj->data[ st->b->value.ptrOffset ];
( *var.floatPtr )--;
}
break;
case OP_COMP_F:
var_a = GetVariable( st->a );
var_c = GetVariable( st->c );
*var_c.floatPtr = ~static_cast<int>( *var_a.floatPtr );
break;
case OP_STORE_F:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
*var_b.floatPtr = *var_a.floatPtr;
break;
case OP_STORE_ENT:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
*var_b.entityNumberPtr = *var_a.entityNumberPtr;
break;
case OP_STORE_BOOL:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
*var_b.intPtr = *var_a.intPtr;
break;
case OP_STORE_OBJENT:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
obj = GetScriptObject( *var_a.entityNumberPtr );
if ( !obj ) {
*var_b.entityNumberPtr = 0;
} else if ( !obj->GetTypeDef()->Inherits( st->b->TypeDef() ) ) {
//Warning( "object '%s' cannot be converted to '%s'", obj->GetTypeName(), st->b->TypeDef()->Name() );
*var_b.entityNumberPtr = 0;
} else {
*var_b.entityNumberPtr = *var_a.entityNumberPtr;
}
break;
case OP_STORE_OBJ:
case OP_STORE_ENTOBJ:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
*var_b.entityNumberPtr = *var_a.entityNumberPtr;
break;
case OP_STORE_S:
SetString( st->b, GetString( st->a ) );
break;
case OP_STORE_V:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
*var_b.vectorPtr = *var_a.vectorPtr;
break;
case OP_STORE_FTOS:
var_a = GetVariable( st->a );
SetString( st->b, FloatToString( *var_a.floatPtr ) );
break;
case OP_STORE_BTOS:
var_a = GetVariable( st->a );
SetString( st->b, *var_a.intPtr ? "true" : "false" );
break;
case OP_STORE_VTOS:
var_a = GetVariable( st->a );
SetString( st->b, var_a.vectorPtr->ToString() );
break;
case OP_STORE_FTOBOOL:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
if ( *var_a.floatPtr != 0.0f ) {
*var_b.intPtr = 1;
} else {
*var_b.intPtr = 0;
}
break;
case OP_STORE_BOOLTOF:
var_a = GetVariable( st->a );
var_b = GetVariable( st->b );
*var_b.floatPtr = static_cast<float>( *var_a.intPtr );
break;
case OP_STOREP_F:
var_b = GetVariable( st->b );
if ( var_b.evalPtr && var_b.evalPtr->floatPtr ) {
var_a = GetVariable( st->a );
*var_b.evalPtr->floatPtr = *var_a.floatPtr;
}
break;
case OP_STOREP_ENT:
var_b = GetVariable( st->b );
if ( var_b.evalPtr && var_b.evalPtr->entityNumberPtr ) {
var_a = GetVariable( st->a );
*var_b.evalPtr->entityNumberPtr = *var_a.entityNumberPtr;
}
break;
case OP_STOREP_FLD:
var_b = GetVariable( st->b );
if ( var_b.evalPtr && var_b.evalPtr->intPtr ) {
var_a = GetVariable( st->a );
*var_b.evalPtr->intPtr = *var_a.intPtr;
}
break;
case OP_STOREP_BOOL:
var_b = GetVariable( st->b );
if ( var_b.evalPtr && var_b.evalPtr->intPtr ) {
var_a = GetVariable( st->a );
*var_b.evalPtr->intPtr = *var_a.intPtr;
}
break;
case OP_STOREP_S:
var_b = GetVariable( st->b );
if ( var_b.evalPtr && var_b.evalPtr->stringPtr ) {
idStr::Copynz( var_b.evalPtr->stringPtr, GetString( st->a ), MAX_STRING_LEN );
}
break;
case OP_STOREP_V:
var_b = GetVariable( st->b );
if ( var_b.evalPtr && var_b.evalPtr->vectorPtr ) {
var_a = GetVariable( st->a );
*var_b.evalPtr->vectorPtr = *var_a.vectorPtr;
}
break;
case OP_STOREP_FTOS:
var_b = GetVariable( st->b );
if ( var_b.evalPtr && var_b.evalPtr->stringPtr ) {
var_a = GetVariable( st->a );
idStr::Copynz( var_b.evalPtr->stringPtr, FloatToString( *var_a.floatPtr ), MAX_STRING_LEN );
}
break;
case OP_STOREP_BTOS:
var_b = GetVariable( st->b );
if ( var_b.evalPtr && var_b.evalPtr->stringPtr ) {
var_a = GetVariable( st->a );
if ( *var_a.floatPtr != 0.0f ) {
idStr::Copynz( var_b.evalPtr->stringPtr, "true", MAX_STRING_LEN );
} else {
idStr::Copynz( var_b.evalPtr->stringPtr, "false", MAX_STRING_LEN );
}
}
break;
case OP_STOREP_VTOS:
var_b = GetVariable( st->b );
if ( var_b.evalPtr && var_b.evalPtr->stringPtr ) {
var_a = GetVariable( st->a );
idStr::Copynz( var_b.evalPtr->stringPtr, var_a.vectorPtr->ToString(), MAX_STRING_LEN );
}
break;
case OP_STOREP_FTOBOOL:
var_b = GetVariable( st->b );
if ( var_b.evalPtr && var_b.evalPtr->intPtr ) {
var_a = GetVariable( st->a );
if ( *var_a.floatPtr != 0.0f ) {
*var_b.evalPtr->intPtr = 1;
} else {
*var_b.evalPtr->intPtr = 0;
}
}
break;
case OP_STOREP_BOOLTOF:
var_b = GetVariable( st->b );
if ( var_b.evalPtr && var_b.evalPtr->floatPtr ) {
var_a = GetVariable( st->a );
*var_b.evalPtr->floatPtr = static_cast<float>( *var_a.intPtr );
}
break;
case OP_STOREP_OBJ:
var_b = GetVariable( st->b );
if ( var_b.evalPtr && var_b.evalPtr->entityNumberPtr ) {
var_a = GetVariable( st->a );
*var_b.evalPtr->entityNumberPtr = *var_a.entityNumberPtr;
}
break;
case OP_STOREP_OBJENT:
var_b = GetVariable( st->b );
if ( var_b.evalPtr && var_b.evalPtr->entityNumberPtr ) {
var_a = GetVariable( st->a );
obj = GetScriptObject( *var_a.entityNumberPtr );
if ( !obj ) {
*var_b.evalPtr->entityNumberPtr = 0;
// st->b points to type_pointer, which is just a temporary that gets its type reassigned, so we store the real type in st->c
// so that we can do a type check during run time since we don't know what type the script object is at compile time because it
// comes from an entity
} else if ( !obj->GetTypeDef()->Inherits( st->c->TypeDef() ) ) {
//Warning( "object '%s' cannot be converted to '%s'", obj->GetTypeName(), st->c->TypeDef()->Name() );
*var_b.evalPtr->entityNumberPtr = 0;
} else {
*var_b.evalPtr->entityNumberPtr = *var_a.entityNumberPtr;
}
}
break;
case OP_ADDRESS:
var_a = GetVariable( st->a );
var_c = GetVariable( st->c );
obj = GetScriptObject( *var_a.entityNumberPtr );
if ( obj ) {
var_c.evalPtr->bytePtr = &obj->data[ st->b->value.ptrOffset ];
} else {
var_c.evalPtr->bytePtr = NULL;
}
break;
case OP_INDIRECT_F:
var_a = GetVariable( st->a );
var_c = GetVariable( st->c );
obj = GetScriptObject( *var_a.entityNumberPtr );
if ( obj ) {
var.bytePtr = &obj->data[ st->b->value.ptrOffset ];
*var_c.floatPtr = *var.floatPtr;
} else {
*var_c.floatPtr = 0.0f;
}
break;
case OP_INDIRECT_ENT:
var_a = GetVariable( st->a );
var_c = GetVariable( st->c );
obj = GetScriptObject( *var_a.entityNumberPtr );
if ( obj ) {
var.bytePtr = &obj->data[ st->b->value.ptrOffset ];
*var_c.entityNumberPtr = *var.entityNumberPtr;
} else {
*var_c.entityNumberPtr = 0;
}
break;
case OP_INDIRECT_BOOL:
var_a = GetVariable( st->a );
var_c = GetVariable( st->c );
obj = GetScriptObject( *var_a.entityNumberPtr );
if ( obj ) {
var.bytePtr = &obj->data[ st->b->value.ptrOffset ];
*var_c.intPtr = *var.intPtr;
} else {
*var_c.intPtr = 0;
}
break;
case OP_INDIRECT_S:
var_a = GetVariable( st->a );
obj = GetScriptObject( *var_a.entityNumberPtr );
if ( obj ) {
var.bytePtr = &obj->data[ st->b->value.ptrOffset ];
SetString( st->c, var.stringPtr );
} else {
SetString( st->c, "" );
}
break;
case OP_INDIRECT_V:
var_a = GetVariable( st->a );
var_c = GetVariable( st->c );
obj = GetScriptObject( *var_a.entityNumberPtr );
if ( obj ) {
var.bytePtr = &obj->data[ st->b->value.ptrOffset ];
*var_c.vectorPtr = *var.vectorPtr;
} else {
var_c.vectorPtr->Zero();
}
break;
case OP_INDIRECT_OBJ:
var_a = GetVariable( st->a );
var_c = GetVariable( st->c );
obj = GetScriptObject( *var_a.entityNumberPtr );
if ( !obj ) {
*var_c.entityNumberPtr = 0;
} else {
var.bytePtr = &obj->data[ st->b->value.ptrOffset ];
*var_c.entityNumberPtr = *var.entityNumberPtr;
}
break;
case OP_PUSH_F:
var_a = GetVariable( st->a );
Push( *var_a.intPtr );
break;
case OP_PUSH_FTOS:
var_a = GetVariable( st->a );
PushString( FloatToString( *var_a.floatPtr ) );
break;
case OP_PUSH_BTOF:
var_a = GetVariable( st->a );
floatVal = *var_a.intPtr;
Push( *reinterpret_cast<int *>( &floatVal ) );
break;
case OP_PUSH_FTOB:
var_a = GetVariable( st->a );
if ( *var_a.floatPtr != 0.0f ) {
Push( 1 );
} else {
Push( 0 );
}
break;
case OP_PUSH_VTOS:
var_a = GetVariable( st->a );
PushString( var_a.vectorPtr->ToString() );
break;
case OP_PUSH_BTOS:
var_a = GetVariable( st->a );
PushString( *var_a.intPtr ? "true" : "false" );
break;
case OP_PUSH_ENT:
var_a = GetVariable( st->a );
Push( *var_a.entityNumberPtr );
break;
case OP_PUSH_S:
PushString( GetString( st->a ) );
break;
case OP_PUSH_V:
var_a = GetVariable( st->a );
Push( *reinterpret_cast<int *>( &var_a.vectorPtr->x ) );
Push( *reinterpret_cast<int *>( &var_a.vectorPtr->y ) );
Push( *reinterpret_cast<int *>( &var_a.vectorPtr->z ) );
break;
case OP_PUSH_OBJ:
var_a = GetVariable( st->a );
Push( *var_a.entityNumberPtr );
break;
case OP_PUSH_OBJENT:
var_a = GetVariable( st->a );
Push( *var_a.entityNumberPtr );
break;
case OP_BREAK:
case OP_CONTINUE:
default:
Error( "Bad opcode %i", st->op );
break;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment