2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Doom 3 BFG Edition GPL Source Code
2012-11-28 15:47:07 +00:00
Copyright ( C ) 1993 - 2012 id Software LLC , a ZeniMax Media company .
2012-12-07 17:29:47 +00:00
Copyright ( C ) 2012 Robert Beckebans
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
This file is part of the Doom 3 BFG Edition GPL Source Code ( " Doom 3 BFG Edition Source Code " ) .
2012-11-26 18:58:24 +00:00
Doom 3 BFG Edition Source Code is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code . If not , see < http : //www.gnu.org/licenses/>.
In addition , the Doom 3 BFG Edition Source Code is also subject to certain additional terms . You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code . If not , please request a copy in writing from id Software at the address below .
If you have questions concerning this license or the applicable additional terms , you may contact in writing id Software LLC , c / o ZeniMax Media Inc . , Suite 120 , Rockville , Maryland 20850 USA .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
# pragma hdrstop
2012-12-22 15:18:19 +00:00
# include "precompiled.h"
2012-11-26 18:58:24 +00:00
# include "../Game_local.h"
/*
= = = = = = = = = = = = = = = =
idInterpreter : : idInterpreter ( )
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idInterpreter : : idInterpreter ( )
{
2012-11-26 18:58:24 +00:00
localstackUsed = 0 ;
terminateOnExit = true ;
debug = 0 ;
memset ( localstack , 0 , sizeof ( localstack ) ) ;
memset ( callStack , 0 , sizeof ( callStack ) ) ;
Reset ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : Save
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idInterpreter : : Save ( idSaveGame * savefile ) const
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( callStackDepth ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < callStackDepth ; i + + )
{
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( callStack [ i ] . s ) ;
2012-11-28 15:47:07 +00:00
if ( callStack [ i ] . f )
{
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( gameLocal . program . GetFunctionIndex ( callStack [ i ] . f ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( - 1 ) ;
}
savefile - > WriteInt ( callStack [ i ] . stackbase ) ;
}
savefile - > WriteInt ( maxStackDepth ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( localstackUsed ) ;
savefile - > Write ( & localstack , localstackUsed ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( localstackBase ) ;
savefile - > WriteInt ( maxLocalstackUsed ) ;
2012-11-28 15:47:07 +00:00
if ( currentFunction )
{
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( gameLocal . program . GetFunctionIndex ( currentFunction ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( - 1 ) ;
}
savefile - > WriteInt ( instructionPointer ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( popParms ) ;
2012-11-28 15:47:07 +00:00
if ( multiFrameEvent )
{
2012-11-26 18:58:24 +00:00
savefile - > WriteString ( multiFrameEvent - > GetName ( ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
savefile - > WriteString ( " " ) ;
}
savefile - > WriteObject ( eventEntity ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteObject ( thread ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteBool ( doneProcessing ) ;
savefile - > WriteBool ( threadDying ) ;
savefile - > WriteBool ( terminateOnExit ) ;
savefile - > WriteBool ( debug ) ;
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : Restore
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idInterpreter : : Restore ( idRestoreGame * savefile )
{
2012-11-26 18:58:24 +00:00
int i ;
idStr funcname ;
int func_index ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( callStackDepth ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < callStackDepth ; i + + )
{
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( callStack [ i ] . s ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( func_index ) ;
2012-11-28 15:47:07 +00:00
if ( func_index > = 0 )
{
2012-11-26 18:58:24 +00:00
callStack [ i ] . f = gameLocal . program . GetFunction ( func_index ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
callStack [ i ] . f = NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( callStack [ i ] . stackbase ) ;
}
savefile - > ReadInt ( maxStackDepth ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( localstackUsed ) ;
savefile - > Read ( & localstack , localstackUsed ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( localstackBase ) ;
savefile - > ReadInt ( maxLocalstackUsed ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( func_index ) ;
2012-11-28 15:47:07 +00:00
if ( func_index > = 0 )
{
2012-11-26 18:58:24 +00:00
currentFunction = gameLocal . program . GetFunction ( func_index ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
currentFunction = NULL ;
}
savefile - > ReadInt ( instructionPointer ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( popParms ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadString ( funcname ) ;
2012-11-28 15:47:07 +00:00
if ( funcname . Length ( ) )
{
2012-11-26 18:58:24 +00:00
multiFrameEvent = idEventDef : : FindEvent ( funcname ) ;
}
2012-11-28 15:47:07 +00:00
savefile - > ReadObject ( reinterpret_cast < idClass * & > ( eventEntity ) ) ;
savefile - > ReadObject ( reinterpret_cast < idClass * & > ( thread ) ) ;
2012-11-26 18:58:24 +00:00
savefile - > ReadBool ( doneProcessing ) ;
savefile - > ReadBool ( threadDying ) ;
savefile - > ReadBool ( terminateOnExit ) ;
savefile - > ReadBool ( debug ) ;
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : Reset
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idInterpreter : : Reset ( )
{
2012-11-26 18:58:24 +00:00
callStackDepth = 0 ;
localstackUsed = 0 ;
localstackBase = 0 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
maxLocalstackUsed = 0 ;
maxStackDepth = 0 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
popParms = 0 ;
multiFrameEvent = NULL ;
eventEntity = NULL ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
currentFunction = 0 ;
NextInstruction ( 0 ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
threadDying = false ;
doneProcessing = true ;
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : GetRegisterValue
2012-11-28 15:47:07 +00:00
Returns a string representation of the value of the register . This is
2012-11-26 18:58:24 +00:00
used primarily for the debugger and debugging
//FIXME: This is pretty much wrong. won't access data in most situations.
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idInterpreter : : GetRegisterValue ( const char * name , idStr & out , int scopeDepth )
{
2012-11-26 18:58:24 +00:00
varEval_t reg ;
2012-11-28 15:47:07 +00:00
idVarDef * d ;
2012-11-26 18:58:24 +00:00
char funcObject [ 1024 ] ;
2012-11-28 15:47:07 +00:00
char * funcName ;
const idVarDef * scope ;
const idTypeDef * field ;
const idScriptObject * obj ;
const function_t * func ;
2012-11-26 18:58:24 +00:00
out . Empty ( ) ;
2012-11-28 15:47:07 +00:00
if ( scopeDepth = = - 1 )
{
2012-11-26 18:58:24 +00:00
scopeDepth = callStackDepth ;
2012-11-28 15:47:07 +00:00
}
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
if ( scopeDepth = = callStackDepth )
{
2012-11-26 18:58:24 +00:00
func = currentFunction ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
func = callStack [ scopeDepth ] . f ;
}
2012-11-28 15:47:07 +00:00
if ( ! func )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStr : : Copynz ( funcObject , func - > Name ( ) , sizeof ( funcObject ) ) ;
funcName = strstr ( funcObject , " :: " ) ;
2012-11-28 15:47:07 +00:00
if ( funcName )
{
2012-11-26 18:58:24 +00:00
* funcName = ' \0 ' ;
scope = gameLocal . program . GetDef ( NULL , funcObject , & def_namespace ) ;
funcName + = 2 ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
funcName = funcObject ;
scope = & def_namespace ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Get the function from the object
d = gameLocal . program . GetDef ( NULL , funcName , scope ) ;
2012-11-28 15:47:07 +00:00
if ( ! d )
{
2012-11-26 18:58:24 +00:00
return false ;
}
// Get the variable itself and check various namespaces
d = gameLocal . program . GetDef ( NULL , name , d ) ;
2012-11-28 15:47:07 +00:00
if ( ! d )
{
if ( scope = = & def_namespace )
{
2012-11-26 18:58:24 +00:00
return false ;
}
d = gameLocal . program . GetDef ( NULL , name , scope ) ;
2012-11-28 15:47:07 +00:00
if ( ! d )
{
2012-11-26 18:58:24 +00:00
d = gameLocal . program . GetDef ( NULL , name , & def_namespace ) ;
2012-11-28 15:47:07 +00:00
if ( ! d )
{
2012-11-26 18:58:24 +00:00
return false ;
}
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
reg = GetVariable ( d ) ;
2012-11-28 15:47:07 +00:00
switch ( d - > Type ( ) )
{
case ev_float :
if ( reg . floatPtr )
{
out = va ( " %g " , * reg . floatPtr ) ;
}
else
{
out = " 0 " ;
}
return true ;
break ;
case ev_vector :
if ( reg . vectorPtr )
{
out = va ( " %g,%g,%g " , reg . vectorPtr - > x , reg . vectorPtr - > y , reg . vectorPtr - > z ) ;
}
else
{
out = " 0,0,0 " ;
}
return true ;
break ;
2012-11-26 18:58:24 +00:00
case ev_boolean :
2012-11-28 15:47:07 +00:00
if ( reg . intPtr )
{
out = va ( " %d " , * reg . intPtr ) ;
}
else
{
out = " 0 " ;
}
2012-11-26 18:58:24 +00:00
return true ;
2012-11-28 15:47:07 +00:00
break ;
case ev_field :
if ( scope = = & def_namespace )
{
// should never happen, but handle it safely anyway
return false ;
}
field = scope - > TypeDef ( ) - > GetParmType ( reg . ptrOffset ) - > FieldType ( ) ;
obj = * reinterpret_cast < const idScriptObject * * > ( & localstack [ callStack [ callStackDepth ] . stackbase ] ) ;
if ( ! field | | ! obj )
{
return false ;
}
switch ( field - > Type ( ) )
{
case ev_boolean :
out = va ( " %d " , * ( reinterpret_cast < int * > ( & obj - > data [ reg . ptrOffset ] ) ) ) ;
return true ;
case ev_float :
out = va ( " %g " , * ( reinterpret_cast < float * > ( & obj - > data [ reg . ptrOffset ] ) ) ) ;
return true ;
default :
return false ;
}
break ;
case ev_string :
if ( reg . stringPtr )
{
out = " \" " ;
out + = reg . stringPtr ;
out + = " \" " ;
}
else
{
out = " \" \" " ;
}
2012-11-26 18:58:24 +00:00
return true ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
default :
return false ;
}
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : GetCallstackDepth
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idInterpreter : : GetCallstackDepth ( ) const
{
2012-11-26 18:58:24 +00:00
return callStackDepth ;
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : GetCallstack
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const prstack_t * idInterpreter : : GetCallstack ( ) const
{
2012-11-26 18:58:24 +00:00
return & callStack [ 0 ] ;
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : GetCurrentFunction
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const function_t * idInterpreter : : GetCurrentFunction ( ) const
{
2012-11-26 18:58:24 +00:00
return currentFunction ;
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : GetThread
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idThread * idInterpreter : : GetThread ( ) const
{
2012-11-26 18:58:24 +00:00
return thread ;
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : SetThread
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idInterpreter : : SetThread ( idThread * pThread )
{
2012-11-26 18:58:24 +00:00
thread = pThread ;
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : CurrentLine
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idInterpreter : : CurrentLine ( ) const
{
if ( instructionPointer < 0 )
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
return gameLocal . program . GetLineNumberForStatement ( instructionPointer ) ;
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : CurrentFile
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idInterpreter : : CurrentFile ( ) const
{
if ( instructionPointer < 0 )
{
2012-11-26 18:58:24 +00:00
return " " ;
}
return gameLocal . program . GetFilenameForStatement ( instructionPointer ) ;
}
/*
= = = = = = = = = = = =
idInterpreter : : StackTrace
= = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idInterpreter : : StackTrace ( ) const
{
const function_t * f ;
2012-11-26 18:58:24 +00:00
int i ;
int top ;
2012-11-28 15:47:07 +00:00
if ( callStackDepth = = 0 )
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " <NO STACK> \n " ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
top = callStackDepth ;
2012-11-28 15:47:07 +00:00
if ( top > = MAX_STACK_DEPTH )
{
2012-11-26 18:58:24 +00:00
top = MAX_STACK_DEPTH - 1 ;
}
2012-11-28 15:47:07 +00:00
if ( ! currentFunction )
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " <NO FUNCTION> \n " ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " %12s : %s \n " , gameLocal . program . GetFilename ( currentFunction - > filenum ) , currentFunction - > Name ( ) ) ;
}
2012-11-28 15:47:07 +00:00
for ( i = top ; i > = 0 ; i - - )
{
2012-11-26 18:58:24 +00:00
f = callStack [ i ] . f ;
2012-11-28 15:47:07 +00:00
if ( ! f )
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " <NO FUNCTION> \n " ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " %12s : %s \n " , gameLocal . program . GetFilename ( f - > filenum ) , f - > Name ( ) ) ;
}
}
}
/*
= = = = = = = = = = = =
idInterpreter : : Error
Aborts the currently executing function
= = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idInterpreter : : Error ( const char * fmt , . . . ) const
{
2012-11-26 18:58:24 +00:00
va_list argptr ;
char text [ 1024 ] ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
va_start ( argptr , fmt ) ;
vsprintf ( text , fmt , argptr ) ;
va_end ( argptr ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
StackTrace ( ) ;
2012-11-28 15:47:07 +00:00
if ( ( instructionPointer > = 0 ) & & ( instructionPointer < gameLocal . program . NumStatements ( ) ) )
{
statement_t & line = gameLocal . program . GetStatement ( instructionPointer ) ;
2012-11-26 18:58:24 +00:00
common - > Error ( " %s(%d): Thread '%s': %s \n " , gameLocal . program . GetFilename ( line . file ) , line . linenumber , thread - > GetThreadName ( ) , text ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
common - > Error ( " Thread '%s': %s \n " , thread - > GetThreadName ( ) , text ) ;
}
}
/*
= = = = = = = = = = = =
idInterpreter : : Warning
Prints file and line number information with warning .
= = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idInterpreter : : Warning ( const char * fmt , . . . ) const
{
2012-11-26 18:58:24 +00:00
va_list argptr ;
char text [ 1024 ] ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
va_start ( argptr , fmt ) ;
vsprintf ( text , fmt , argptr ) ;
va_end ( argptr ) ;
2012-11-28 15:47:07 +00:00
if ( ( instructionPointer > = 0 ) & & ( instructionPointer < gameLocal . program . NumStatements ( ) ) )
{
statement_t & line = gameLocal . program . GetStatement ( instructionPointer ) ;
2012-11-26 18:58:24 +00:00
common - > Warning ( " %s(%d): Thread '%s': %s " , gameLocal . program . GetFilename ( line . file ) , line . linenumber , thread - > GetThreadName ( ) , text ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
common - > Warning ( " Thread '%s' : %s " , thread - > GetThreadName ( ) , text ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : DisplayInfo
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idInterpreter : : DisplayInfo ( ) const
{
const function_t * f ;
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " Stack depth: %d bytes, %d max \n " , localstackUsed , maxLocalstackUsed ) ;
gameLocal . Printf ( " Call depth: %d, %d max \n " , callStackDepth , maxStackDepth ) ;
gameLocal . Printf ( " Call Stack: " ) ;
2012-11-28 15:47:07 +00:00
if ( callStackDepth = = 0 )
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " <NO STACK> \n " ) ;
2012-11-28 15:47:07 +00:00
}
else
{
if ( ! currentFunction )
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " <NO FUNCTION> \n " ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " %12s : %s \n " , gameLocal . program . GetFilename ( currentFunction - > filenum ) , currentFunction - > Name ( ) ) ;
}
2012-11-28 15:47:07 +00:00
for ( i = callStackDepth ; i > 0 ; i - - )
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " " ) ;
f = callStack [ i ] . f ;
2012-11-28 15:47:07 +00:00
if ( ! f )
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " <NO FUNCTION> \n " ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " %12s : %s \n " , gameLocal . program . GetFilename ( f - > filenum ) , f - > Name ( ) ) ;
}
}
}
}
/*
= = = = = = = = = = = = = = = = = = = =
idInterpreter : : ThreadCall
Copys the args from the calling thread ' s stack
= = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idInterpreter : : ThreadCall ( idInterpreter * source , const function_t * func , int args )
{
2012-11-26 18:58:24 +00:00
Reset ( ) ;
2012-11-28 15:47:07 +00:00
if ( args > LOCALSTACK_SIZE )
{
2012-11-26 18:58:24 +00:00
args = LOCALSTACK_SIZE ;
}
memcpy ( localstack , & source - > localstack [ source - > localstackUsed - args ] , args ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
localstackUsed = args ;
localstackBase = 0 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
maxLocalstackUsed = localstackUsed ;
EnterFunction ( func , false ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
thread - > SetThreadName ( currentFunction - > Name ( ) ) ;
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : EnterObjectFunction
Calls a function on a script object .
NOTE : If this is called from within a event called by this interpreter , the function arguments will be invalid after calling this function .
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idInterpreter : : EnterObjectFunction ( idEntity * self , const function_t * func , bool clearStack )
{
if ( clearStack )
{
2012-11-26 18:58:24 +00:00
Reset ( ) ;
}
2012-11-28 15:47:07 +00:00
if ( popParms )
{
2012-11-26 18:58:24 +00:00
PopParms ( popParms ) ;
popParms = 0 ;
}
Push ( self - > entityNumber + 1 ) ;
EnterFunction ( func , false ) ;
}
/*
= = = = = = = = = = = = = = = = = = = =
idInterpreter : : EnterFunction
Returns the new program statement counter
NOTE : If this is called from within a event called by this interpreter , the function arguments will be invalid after calling this function .
= = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idInterpreter : : EnterFunction ( const function_t * func , bool clearStack )
{
2012-11-26 18:58:24 +00:00
int c ;
2012-11-28 15:47:07 +00:00
prstack_t * stack ;
if ( clearStack )
{
2012-11-26 18:58:24 +00:00
Reset ( ) ;
}
2012-11-28 15:47:07 +00:00
if ( popParms )
{
2012-11-26 18:58:24 +00:00
PopParms ( popParms ) ;
popParms = 0 ;
}
2012-11-28 15:47:07 +00:00
if ( callStackDepth > = MAX_STACK_DEPTH )
{
2012-11-26 18:58:24 +00:00
Error ( " call stack overflow " ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
stack = & callStack [ callStackDepth ] ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
stack - > s = instructionPointer + 1 ; // point to the next instruction to execute
stack - > f = currentFunction ;
stack - > stackbase = localstackBase ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
callStackDepth + + ;
2012-11-28 15:47:07 +00:00
if ( callStackDepth > maxStackDepth )
{
2012-11-26 18:58:24 +00:00
maxStackDepth = callStackDepth ;
}
2012-11-28 15:47:07 +00:00
if ( func = = NULL )
{
2012-11-26 18:58:24 +00:00
Error ( " NULL function " ) ;
return ;
}
2012-11-28 15:47:07 +00:00
if ( debug )
{
if ( currentFunction )
{
gameLocal . Printf ( " %d: call '%s' from '%s'(line %d)%s \n " , gameLocal . time , func - > Name ( ) , currentFunction - > Name ( ) ,
gameLocal . program . GetStatement ( instructionPointer ) . linenumber , clearStack ? " clear stack " : " " ) ;
}
else
{
gameLocal . Printf ( " %d: call '%s'%s \n " , gameLocal . time , func - > Name ( ) , clearStack ? " clear stack " : " " ) ;
2012-11-26 18:58:24 +00:00
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
currentFunction = func ;
assert ( ! func - > eventdef ) ;
NextInstruction ( func - > firstStatement ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// allocate space on the stack for locals
// parms are already on stack
c = func - > locals - func - > parmTotal ;
assert ( c > = 0 ) ;
2012-11-28 15:47:07 +00:00
if ( localstackUsed + c > LOCALSTACK_SIZE )
{
2012-11-26 18:58:24 +00:00
Error ( " EnterFuncton: locals stack overflow \n " ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// initialize local stack variables to zero
memset ( & localstack [ localstackUsed ] , 0 , c ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
localstackUsed + = c ;
localstackBase = localstackUsed - func - > locals ;
2012-11-28 15:47:07 +00:00
if ( localstackUsed > maxLocalstackUsed )
{
2012-11-26 18:58:24 +00:00
maxLocalstackUsed = localstackUsed ;
}
}
/*
= = = = = = = = = = = = = = = = = = = =
idInterpreter : : LeaveFunction
= = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idInterpreter : : LeaveFunction ( idVarDef * returnDef )
{
prstack_t * stack ;
2012-11-26 18:58:24 +00:00
varEval_t ret ;
2012-11-28 15:47:07 +00:00
if ( callStackDepth < = 0 )
{
2012-11-26 18:58:24 +00:00
Error ( " prog stack underflow " ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// return value
2012-11-28 15:47:07 +00:00
if ( returnDef )
{
switch ( returnDef - > Type ( ) )
{
case ev_string :
gameLocal . program . ReturnString ( GetString ( returnDef ) ) ;
break ;
case ev_vector :
ret = GetVariable ( returnDef ) ;
gameLocal . program . ReturnVector ( * ret . vectorPtr ) ;
break ;
default :
ret = GetVariable ( returnDef ) ;
gameLocal . program . ReturnInteger ( * ret . intPtr ) ;
2012-11-26 18:58:24 +00:00
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// remove locals from the stack
PopParms ( currentFunction - > locals ) ;
assert ( localstackUsed = = localstackBase ) ;
2012-11-28 15:47:07 +00:00
if ( debug )
{
statement_t & line = gameLocal . program . GetStatement ( instructionPointer ) ;
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " %d: %s(%d): exit %s " , gameLocal . time , gameLocal . program . GetFilename ( line . file ) , line . linenumber , currentFunction - > Name ( ) ) ;
2012-11-28 15:47:07 +00:00
if ( callStackDepth > 1 )
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " return to %s(line %d) \n " , callStack [ callStackDepth - 1 ] . f - > Name ( ) , gameLocal . program . GetStatement ( callStack [ callStackDepth - 1 ] . s ) . linenumber ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " done \n " ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// up stack
callStackDepth - - ;
2012-11-28 15:47:07 +00:00
stack = & callStack [ callStackDepth ] ;
2012-11-26 18:58:24 +00:00
currentFunction = stack - > f ;
localstackBase = stack - > stackbase ;
NextInstruction ( stack - > s ) ;
2012-11-28 15:47:07 +00:00
if ( ! callStackDepth )
{
2012-11-26 18:58:24 +00:00
// all done
doneProcessing = true ;
threadDying = true ;
currentFunction = 0 ;
}
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : CallEvent
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idInterpreter : : CallEvent ( const function_t * func , int argsize )
{
2012-11-26 18:58:24 +00:00
int i ;
int j ;
varEval_t var ;
int pos ;
int start ;
2012-12-07 17:29:47 +00:00
// RB: 64 bit fixes, changed int to intptr_t
intptr_t data [ D_EVENT_MAXARGS ] ;
// RB end
2012-11-28 15:47:07 +00:00
const idEventDef * evdef ;
const char * format ;
if ( func = = NULL )
{
2012-11-26 18:58:24 +00:00
Error ( " NULL function " ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
assert ( func - > eventdef ) ;
evdef = func - > eventdef ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
start = localstackUsed - argsize ;
2012-11-28 15:47:07 +00:00
var . intPtr = ( int * ) & localstack [ start ] ;
2012-11-26 18:58:24 +00:00
eventEntity = GetEntity ( * var . entityNumberPtr ) ;
2012-11-28 15:47:07 +00:00
if ( eventEntity = = NULL | | ! eventEntity - > RespondsTo ( * evdef ) )
{
if ( eventEntity ! = NULL & & developer . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
// give a warning in developer mode
Warning ( " Function '%s' not supported on entity '%s' " , evdef - > GetName ( ) , eventEntity - > name . c_str ( ) ) ;
}
// always return a safe value when an object doesn't exist
2012-11-28 15:47:07 +00:00
switch ( evdef - > GetReturnType ( ) )
{
case D_EVENT_INTEGER :
gameLocal . program . ReturnInteger ( 0 ) ;
break ;
case D_EVENT_FLOAT :
gameLocal . program . ReturnFloat ( 0 ) ;
break ;
case D_EVENT_VECTOR :
gameLocal . program . ReturnVector ( vec3_zero ) ;
break ;
case D_EVENT_STRING :
gameLocal . program . ReturnString ( " " ) ;
break ;
case D_EVENT_ENTITY :
case D_EVENT_ENTITY_NULL :
gameLocal . program . ReturnEntity ( ( idEntity * ) NULL ) ;
break ;
case D_EVENT_TRACE :
default :
// unsupported data type
break ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
PopParms ( argsize ) ;
eventEntity = NULL ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
format = evdef - > GetArgFormat ( ) ;
2012-11-28 15:47:07 +00:00
for ( j = 0 , i = 0 , pos = type_object . Size ( ) ; ( pos < argsize ) | | ( format [ i ] ! = 0 ) ; i + + )
{
switch ( format [ i ] )
{
case D_EVENT_INTEGER :
var . intPtr = ( int * ) & localstack [ start + pos ] ;
2012-12-07 17:29:47 +00:00
// RB: fixed data alignment
//data[ i ] = int( *var.floatPtr );
( * ( int * ) & data [ i ] ) = int ( * var . floatPtr ) ;
// RB end
2012-11-28 15:47:07 +00:00
break ;
case D_EVENT_FLOAT :
var . intPtr = ( int * ) & localstack [ start + pos ] ;
( * ( float * ) & data [ i ] ) = * var . floatPtr ;
break ;
case D_EVENT_VECTOR :
var . intPtr = ( int * ) & localstack [ start + pos ] ;
( * ( idVec3 * * ) & data [ i ] ) = var . vectorPtr ;
break ;
case D_EVENT_STRING :
( * ( const char * * ) & data [ i ] ) = ( char * ) & localstack [ start + pos ] ;
break ;
case D_EVENT_ENTITY :
var . intPtr = ( int * ) & localstack [ start + pos ] ;
( * ( idEntity * * ) & data [ i ] ) = GetEntity ( * var . entityNumberPtr ) ;
if ( ! ( * ( idEntity * * ) & data [ i ] ) )
{
Warning ( " Entity not found for event '%s'. Terminating thread. " , evdef - > GetName ( ) ) ;
threadDying = true ;
PopParms ( argsize ) ;
return ;
}
break ;
case D_EVENT_ENTITY_NULL :
var . intPtr = ( int * ) & localstack [ start + pos ] ;
( * ( idEntity * * ) & data [ i ] ) = GetEntity ( * var . entityNumberPtr ) ;
break ;
case D_EVENT_TRACE :
Error ( " trace type not supported from script for '%s' event. " , evdef - > GetName ( ) ) ;
break ;
default :
Error ( " Invalid arg format string for '%s' event. " , evdef - > GetName ( ) ) ;
break ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
pos + = func - > parmSize [ j + + ] ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
popParms = argsize ;
eventEntity - > ProcessEventArgPtr ( evdef , data ) ;
2012-11-28 15:47:07 +00:00
if ( ! multiFrameEvent )
{
if ( popParms )
{
2012-11-26 18:58:24 +00:00
PopParms ( popParms ) ;
}
eventEntity = NULL ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
doneProcessing = true ;
}
popParms = 0 ;
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : BeginMultiFrameEvent
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idInterpreter : : BeginMultiFrameEvent ( idEntity * ent , const idEventDef * event )
{
if ( eventEntity ! = ent )
{
2012-11-26 18:58:24 +00:00
Error ( " idInterpreter::BeginMultiFrameEvent called with wrong entity " ) ;
}
2012-11-28 15:47:07 +00:00
if ( multiFrameEvent )
{
if ( multiFrameEvent ! = event )
{
2012-11-26 18:58:24 +00:00
Error ( " idInterpreter::BeginMultiFrameEvent called with wrong event " ) ;
}
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
multiFrameEvent = event ;
return true ;
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : EndMultiFrameEvent
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idInterpreter : : EndMultiFrameEvent ( idEntity * ent , const idEventDef * event )
{
if ( multiFrameEvent ! = event )
{
2012-11-26 18:58:24 +00:00
Error ( " idInterpreter::EndMultiFrameEvent called with wrong event " ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
multiFrameEvent = NULL ;
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : MultiFrameEventInProgress
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idInterpreter : : MultiFrameEventInProgress ( ) const
{
2012-11-26 18:58:24 +00:00
return multiFrameEvent ! = NULL ;
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : CallSysEvent
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idInterpreter : : CallSysEvent ( const function_t * func , int argsize )
{
2012-11-26 18:58:24 +00:00
int i ;
int j ;
varEval_t source ;
int pos ;
int start ;
2012-12-07 17:29:47 +00:00
// RB: 64 bit fixes, changed int to intptr_t
intptr_t data [ D_EVENT_MAXARGS ] ;
// RB end
2012-11-28 15:47:07 +00:00
const idEventDef * evdef ;
const char * format ;
if ( func = = NULL )
{
2012-11-26 18:58:24 +00:00
Error ( " NULL function " ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
assert ( func - > eventdef ) ;
evdef = func - > eventdef ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
start = localstackUsed - argsize ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
format = evdef - > GetArgFormat ( ) ;
2012-11-28 15:47:07 +00:00
for ( j = 0 , i = 0 , pos = 0 ; ( pos < argsize ) | | ( format [ i ] ! = 0 ) ; i + + )
{
switch ( format [ i ] )
{
case D_EVENT_INTEGER :
source . intPtr = ( int * ) & localstack [ start + pos ] ;
* ( int * ) & data [ i ] = int ( * source . floatPtr ) ;
break ;
case D_EVENT_FLOAT :
source . intPtr = ( int * ) & localstack [ start + pos ] ;
* ( float * ) & data [ i ] = * source . floatPtr ;
break ;
case D_EVENT_VECTOR :
source . intPtr = ( int * ) & localstack [ start + pos ] ;
* ( idVec3 * * ) & data [ i ] = source . vectorPtr ;
break ;
case D_EVENT_STRING :
* ( const char * * ) & data [ i ] = ( char * ) & localstack [ start + pos ] ;
break ;
case D_EVENT_ENTITY :
source . intPtr = ( int * ) & localstack [ start + pos ] ;
* ( idEntity * * ) & data [ i ] = GetEntity ( * source . entityNumberPtr ) ;
if ( ! * ( idEntity * * ) & data [ i ] )
{
Warning ( " Entity not found for event '%s'. Terminating thread. " , evdef - > GetName ( ) ) ;
threadDying = true ;
PopParms ( argsize ) ;
return ;
}
break ;
case D_EVENT_ENTITY_NULL :
source . intPtr = ( int * ) & localstack [ start + pos ] ;
* ( idEntity * * ) & data [ i ] = GetEntity ( * source . entityNumberPtr ) ;
break ;
case D_EVENT_TRACE :
Error ( " trace type not supported from script for '%s' event. " , evdef - > GetName ( ) ) ;
break ;
default :
Error ( " Invalid arg format string for '%s' event. " , evdef - > GetName ( ) ) ;
break ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
pos + = func - > parmSize [ j + + ] ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
popParms = argsize ;
thread - > ProcessEventArgPtr ( evdef , data ) ;
2012-11-28 15:47:07 +00:00
if ( popParms )
{
2012-11-26 18:58:24 +00:00
PopParms ( popParms ) ;
}
popParms = 0 ;
}
/*
= = = = = = = = = = = = = = = = = = = =
idInterpreter : : Execute
= = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idInterpreter : : Execute ( )
{
2012-11-26 18:58:24 +00:00
varEval_t var_a ;
varEval_t var_b ;
varEval_t var_c ;
varEval_t var ;
2012-11-28 15:47:07 +00:00
statement_t * st ;
2012-11-26 18:58:24 +00:00
int runaway ;
2012-11-28 15:47:07 +00:00
idThread * newThread ;
2012-11-26 18:58:24 +00:00
float floatVal ;
2012-11-28 15:47:07 +00:00
idScriptObject * obj ;
const function_t * func ;
if ( threadDying | | ! currentFunction )
{
2012-11-26 18:58:24 +00:00
return true ;
}
2012-11-28 15:47:07 +00:00
if ( multiFrameEvent )
{
2012-11-26 18:58:24 +00:00
// move to previous instruction and call it again
instructionPointer - - ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
runaway = 5000000 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
doneProcessing = false ;
2012-11-28 15:47:07 +00:00
while ( ! doneProcessing & & ! threadDying )
{
2012-11-26 18:58:24 +00:00
instructionPointer + + ;
2012-11-28 15:47:07 +00:00
if ( ! - - runaway )
{
2012-11-26 18:58:24 +00:00
Error ( " runaway loop error " ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// next statement
st = & gameLocal . program . GetStatement ( instructionPointer ) ;
2012-11-28 15:47:07 +00:00
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 ) ;
2012-11-26 18:58:24 +00:00
newThread - > Start ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// return the thread number to the script
gameLocal . program . ReturnFloat ( newThread - > GetThreadNum ( ) ) ;
2012-11-28 15:47:07 +00:00
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 ) ;
}
2012-11-26 18:58:24 +00:00
PopParms ( st - > c - > value . argSize ) ;
2012-11-28 15:47:07 +00:00
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 ) ;
2014-02-23 14:19:11 +00:00
* var_c . floatPtr = * var_a . floatPtr * * var_b . floatPtr ;
2012-11-28 15:47:07 +00:00
break ;
case OP_MUL_V :
var_a = GetVariable ( st - > a ) ;
var_b = GetVariable ( st - > b ) ;
var_c = GetVariable ( st - > c ) ;
2014-02-23 14:19:11 +00:00
* var_c . floatPtr = * var_a . vectorPtr * * var_b . vectorPtr ;
2012-11-28 15:47:07 +00:00
break ;
case OP_MUL_FV :
var_a = GetVariable ( st - > a ) ;
var_b = GetVariable ( st - > b ) ;
var_c = GetVariable ( st - > c ) ;
2014-02-23 14:19:11 +00:00
* var_c . vectorPtr = * var_a . floatPtr * * var_b . vectorPtr ;
2012-11-28 15:47:07 +00:00
break ;
case OP_MUL_VF :
var_a = GetVariable ( st - > a ) ;
var_b = GetVariable ( st - > b ) ;
var_c = GetVariable ( st - > c ) ;
2014-02-23 14:19:11 +00:00
* var_c . vectorPtr = * var_a . vectorPtr * * var_b . floatPtr ;
2012-11-28 15:47:07 +00:00
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 ) ;
2012-11-26 18:58:24 +00:00
* var_b . floatPtr = * var_a . floatPtr ;
2012-11-28 15:47:07 +00:00
break ;
case OP_STORE_ENT :
var_a = GetVariable ( st - > a ) ;
var_b = GetVariable ( st - > b ) ;
2012-11-26 18:58:24 +00:00
* var_b . entityNumberPtr = * var_a . entityNumberPtr ;
2012-11-28 15:47:07 +00:00
break ;
case OP_STORE_BOOL :
2012-11-26 18:58:24 +00:00
var_a = GetVariable ( st - > a ) ;
2012-11-28 15:47:07 +00:00
var_b = GetVariable ( st - > b ) ;
* var_b . intPtr = * var_a . intPtr ;
break ;
case OP_STORE_OBJENT :
2012-11-26 18:58:24 +00:00
var_a = GetVariable ( st - > a ) ;
2012-11-28 15:47:07 +00:00
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 :
2012-11-26 18:58:24 +00:00
var_a = GetVariable ( st - > a ) ;
2012-11-28 15:47:07 +00:00
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 :
2012-11-26 18:58:24 +00:00
var_a = GetVariable ( st - > a ) ;
2012-11-28 15:47:07 +00:00
var_b = GetVariable ( st - > b ) ;
* var_b . vectorPtr = * var_a . vectorPtr ;
break ;
case OP_STORE_FTOS :
2012-11-26 18:58:24 +00:00
var_a = GetVariable ( st - > a ) ;
2012-11-28 15:47:07 +00:00
SetString ( st - > b , FloatToString ( * var_a . floatPtr ) ) ;
break ;
case OP_STORE_BTOS :
2012-11-26 18:58:24 +00:00
var_a = GetVariable ( st - > a ) ;
2012-11-28 15:47:07 +00:00
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 ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
else
{
* var_b . intPtr = 0 ;
}
break ;
case OP_STORE_BOOLTOF :
2012-11-26 18:58:24 +00:00
var_a = GetVariable ( st - > a ) ;
2012-11-28 15:47:07 +00:00
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 ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
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 :
2012-11-26 18:58:24 +00:00
var_a = GetVariable ( st - > a ) ;
2012-11-28 15:47:07 +00:00
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 :
2012-11-26 18:58:24 +00:00
var_a = GetVariable ( st - > a ) ;
2012-11-28 15:47:07 +00:00
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 :
2012-11-26 18:58:24 +00:00
var_a = GetVariable ( st - > a ) ;
2012-11-28 15:47:07 +00:00
var_c = GetVariable ( st - > c ) ;
2012-11-26 18:58:24 +00:00
obj = GetScriptObject ( * var_a . entityNumberPtr ) ;
2012-11-28 15:47:07 +00:00
if ( obj )
{
var . bytePtr = & obj - > data [ st - > b - > value . ptrOffset ] ;
* var_c . entityNumberPtr = * var . entityNumberPtr ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
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 ) ;
2012-12-07 17:29:47 +00:00
// RB: 64 bit fix, changed individual pushes with PushVector
/*
Push ( * reinterpret_cast < int * > ( & var_a . vectorPtr - > x ) ) ;
Push ( * reinterpret_cast < int * > ( & var_a . vectorPtr - > y ) ) ;
Push ( * reinterpret_cast < int * > ( & var_a . vectorPtr - > z ) ) ;
*/
PushVector ( * var_a . vectorPtr ) ;
// RB end
2012-11-28 15:47:07 +00:00
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 ;
2012-11-26 18:58:24 +00:00
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return threadDying ;
}
2012-12-07 17:29:47 +00:00
// RB: moved from Script_Interpreter.h to avoid include problems with the script debugger
/*
= = = = = = = = = = = = = = = =
idInterpreter : : GetEntity
= = = = = = = = = = = = = = = =
*/
idEntity * idInterpreter : : GetEntity ( int entnum ) const
{
assert ( entnum < = MAX_GENTITIES ) ;
if ( ( entnum > 0 ) & & ( entnum < = MAX_GENTITIES ) )
{
return gameLocal . entities [ entnum - 1 ] ;
}
return NULL ;
}
/*
= = = = = = = = = = = = = = = =
idInterpreter : : GetScriptObject
= = = = = = = = = = = = = = = =
*/
idScriptObject * idInterpreter : : GetScriptObject ( int entnum ) const
{
idEntity * ent ;
assert ( entnum < = MAX_GENTITIES ) ;
if ( ( entnum > 0 ) & & ( entnum < = MAX_GENTITIES ) )
{
ent = gameLocal . entities [ entnum - 1 ] ;
if ( ent & & ent - > scriptObject . data )
{
return & ent - > scriptObject ;
}
}
return NULL ;
}
// RB end