Quake 4 integrated with DoomRTX

This commit is contained in:
Justin Marshall
2026-05-09 22:10:40 -07:00
parent 8c4a087aa9
commit d37f87e493
436 changed files with 277587 additions and 10254 deletions
@@ -0,0 +1,469 @@
#include "precompiled.h"
#pragma hdrstop
#include "../Game_local.h"
/*
================
rvScriptFuncUtility::rvScriptFuncUtility
================
*/
rvScriptFuncUtility::rvScriptFuncUtility() {
func = NULL;
parms.Clear();
}
/*
================
rvScriptFuncUtility::rvScriptFuncUtility
================
*/
rvScriptFuncUtility::rvScriptFuncUtility( const rvScriptFuncUtility* sfu ) {
Assign( sfu );
}
/*
================
rvScriptFuncUtility::rvScriptFuncUtility
================
*/
rvScriptFuncUtility::rvScriptFuncUtility( const rvScriptFuncUtility& sfu ) {
Assign( &sfu );
}
/*
================
rvScriptFuncUtility::rvScriptFuncUtility
================
*/
rvScriptFuncUtility::rvScriptFuncUtility( const char* source ) {
Init( source );
}
/*
================
rvScriptFuncUtility::rvScriptFuncUtility
================
*/
rvScriptFuncUtility::rvScriptFuncUtility( const idCmdArgs& args ) {
Init( args );
}
/*
================
rvScriptFuncUtility::Init
================
*/
sfuReturnType rvScriptFuncUtility::Init( const char* source ) {
Clear();
if( !source || !source[0] ) {
return SFU_NOFUNC;
}
idStr::Split( source, parms, ' ' );
return Init();
}
/*
================
rvScriptFuncUtility::Init
================
*/
sfuReturnType rvScriptFuncUtility::Init( const idCmdArgs& args ) {
Clear();
//Start at index 1 so we ignore 'call'
for( int ix = 1; ix < args.Argc(); ++ix ) {
InsertString( args.Argv(ix), ix );
}
return Init();
}
/*
================
rvScriptFuncUtility::Init
================
*/
sfuReturnType rvScriptFuncUtility::Init() {
assert( parms.Num() );
func = FindFunction( GetParm(0) );
if( func ) {
RemoveIndex( 0 );// remove Function name
returnKey.Clear();
} else if( parms.Num() >= 2 ) {
returnKey = GetParm( 0 );
RemoveIndex( 0 );// remove key name
func = FindFunction( GetParm(0) );
RemoveIndex( 0 );// remove Function name
} else {
gameLocal.Warning( "Unable to find function %s in rvScriptFuncUtility::Init\n", parms[0].c_str() );
}
return func != NULL ? SFU_OK : SFU_ERROR;
}
/*
================
rvScriptFuncUtility::Clear
================
*/
void rvScriptFuncUtility::Clear() {
func = NULL;
parms.Clear();
}
/*
================
rvScriptFuncUtility::Save
================
*/
void rvScriptFuncUtility::Save( idSaveGame *savefile ) const {
bool validFunc = GetFunc() != NULL;
savefile->WriteBool( validFunc );
if( !validFunc ) {
return;
}
savefile->WriteString( GetReturnKey() );
savefile->WriteString( GetFunc()->Name() );
savefile->WriteInt( NumParms() );
for( int ix = 0; ix < NumParms(); ++ix ) {
savefile->WriteString( func->Name() );
}
}
/*
================
rvScriptFuncUtility::Restore
================
*/
void rvScriptFuncUtility::Restore( idRestoreGame *savefile ) {
idStr value;
idStr element;
int numParms = 0;
bool validFunc = false;
savefile->ReadBool( validFunc );
if( !validFunc ) {
return;
}
savefile->ReadString( element );
if( element.Length() ) {
value += element;
value += ' ';
}
savefile->ReadString( element );
if( element.Length() ) {
value += element;
value += ' ';
}
savefile->ReadInt( numParms );
for( int ix = 0; ix < numParms; ++ix ) {
savefile->ReadString( element );
value += element;
value += ' ';
}
value.StripTrailing( ' ' );
sfuReturnType status = Init(value.c_str());
if ( status != SFU_OK ) {
assert( 0 );
}
}
/*
================
rvScriptFuncUtility::NumParms
================
*/
int rvScriptFuncUtility::NumParms() const {
return (func && func->type) ? func->type->NumParameters() : 0;
}
/*
================
rvScriptFuncUtility::ReturnsAVal
================
*/
bool rvScriptFuncUtility::ReturnsAVal() const {
return GetReturnType() != &type_void;
}
/*
================
rvScriptFuncUtility::GetParm
================
*/
idTypeDef* rvScriptFuncUtility::GetParmType( int index ) const {
return (func && func->type) ? func->type->GetParmType( index ) : NULL;
}
/*
================
rvScriptFuncUtility::GetReturnType
================
*/
idTypeDef* rvScriptFuncUtility::GetReturnType() const {
return (func && func->type) ? func->type->ReturnType() : &type_void;
}
/*
================
rvScriptFuncUtility::SetFunction
================
*/
void rvScriptFuncUtility::SetFunction( const function_t* func ) {
this->func = func;
}
/*
================
rvScriptFuncUtility::SetParms
================
*/
void rvScriptFuncUtility::SetParms( const idList<idStr>& parms ) {
this->parms = parms;
}
/*
================
rvScriptFuncUtility::GetParm
================
*/
const char* rvScriptFuncUtility::GetParm( int index ) const {
return parms[ index ].c_str();
}
/*
================
rvScriptFuncUtility::GetFuncName
================
*/
const char* rvScriptFuncUtility::GetFuncName() const {
if( !func ) {
return NULL;
}
return func->Name();
}
/*
================
rvScriptFuncUtility::InsertInt
================
*/
void rvScriptFuncUtility::InsertInt( int parm, int index ) {
InsertString( va("%d", parm), index );
}
/*
================
rvScriptFuncUtility::InsertFloat
================
*/
void rvScriptFuncUtility::InsertFloat( float parm, int index ) {
InsertString( va("%f", parm), index );
}
/*
================
rvScriptFuncUtility::InsertVec3
================
*/
void rvScriptFuncUtility::InsertVec3( const idVec3& parm, int index ) {
InsertString( parm.ToString(), index );
}
/*
================
rvScriptFuncUtility::InsertEntity
================
*/
void rvScriptFuncUtility::InsertEntity( const idEntity* parm, int index ) {
assert( parm );
InsertString( parm->GetName(), index );
}
/*
================
rvScriptFuncUtility::InsertString
================
*/
void rvScriptFuncUtility::InsertString( const char* parm, int index ) {
assert( parm );
parms.Insert( parm, index );
}
/*
================
rvScriptFuncUtility::InsertBool
================
*/
void rvScriptFuncUtility::InsertBool( bool parm, int index ) {
InsertInt( (int)parm, index );
}
/*
================
rvScriptFuncUtility::RemoveIndex
================
*/
void rvScriptFuncUtility::RemoveIndex( int index ) {
parms.RemoveIndex( index );
}
/*
================
rvScriptFuncUtility::FindFunction
================
*/
const function_t* rvScriptFuncUtility::FindFunction( const char* name ) const {
idTypeDef* type = gameLocal.program.FindType( name );
if( type ) {//Find based on type
return gameLocal.program.FindFunction( name, type );
}
//Find based on scope
return gameLocal.program.FindFunction( name );
}
/*
================
rvScriptFuncUtility::CallFunc
================
*/
void rvScriptFuncUtility::CallFunc( idDict* returnDict ) const {
idTypeDef* type = NULL;
if( !Valid() ) {
return;
}
idThread* thread = new idThread();
if( !thread ) {
return;
}
thread->ClearStack();
for( int ix = 0; ix < NumParms(); ++ix ) {
type = GetParmType( ix );
type->PushOntoStack( thread, GetParm(ix) );
}
thread->CallFunction( func, false );
if( thread->Execute() && returnDict && ReturnsAVal() ) {
returnDict->Set( GetReturnKey(), GetReturnType()->GetReturnedValAsString(gameLocal.program) );
}
}
/*
================
rvScriptFuncUtility::Valid
================
*/
bool rvScriptFuncUtility::Valid() const {
//#if _DEBUG
idTypeDef* type = NULL;
if( !GetFunc() ) {
return false;
}
if( GetFunc()->eventdef ) {
gameLocal.Warning( "Function, %s, is an event\n", GetFunc()->Name() );
return false;
}
// FIXME: designers call functions with no parms even though parms are pushed on stack
//if( NumParms() != parms.Num() ) {
// gameLocal.Warning( "Number of parms doesn't equal the num required by function %s\n", func->Name() );
// return false;
//}
for( int ix = 0; ix < NumParms(); ++ix ) {
type = GetParmType( ix );
if( !type->IsValid( GetParm(ix) ) ) {
gameLocal.Warning( "(Func: %s) Parm '%s' doesn't match expected type '%s'\n", GetFunc()->Name(), GetParm(ix), type->Name() );
return false;
}
}
if( returnKey.Length() && !ReturnsAVal() ) {
gameLocal.Warning( "Expecting return val from function %s which doesn't return one\n", func->Name() );
return false;
}
//#endif
return true;
}
/*
================
rvScriptFuncUtility::Assign
================
*/
rvScriptFuncUtility& rvScriptFuncUtility::Assign( const rvScriptFuncUtility* sfu ) {
assert( sfu );
func = sfu->func;
parms = sfu->parms;
returnKey = sfu->returnKey;
return *this;
}
/*
================
rvScriptFuncUtility::operator=
================
*/
rvScriptFuncUtility& rvScriptFuncUtility::operator=( const rvScriptFuncUtility* sfu ) {
return Assign( sfu );
}
/*
================
rvScriptFuncUtility::operator=
================
*/
rvScriptFuncUtility& rvScriptFuncUtility::operator=( const rvScriptFuncUtility& sfu ) {
return Assign( &sfu );
}
/*
================
rvScriptFuncUtility::IsEqualTo
================
*/
bool rvScriptFuncUtility::IsEqualTo( const rvScriptFuncUtility* sfu ) const {
assert( sfu );
return GetFunc() == sfu->GetFunc();
}
/*
================
rvScriptFuncUtility::operator==
================
*/
bool rvScriptFuncUtility::operator==( const rvScriptFuncUtility* sfu ) const {
return IsEqualTo( sfu );
}
/*
================
rvScriptFuncUtility::operator==
================
*/
bool rvScriptFuncUtility::operator==( const rvScriptFuncUtility& sfu ) const {
return IsEqualTo( &sfu );
}
@@ -0,0 +1,71 @@
#ifndef __RV_SCRIPT_FUNC_UTILITY_H
#define __RV_SCRIPT_FUNC_UTILITY_H
class idThread;
enum sfuReturnType {
SFU_NOFUNC = -1,
SFU_ERROR = 0,
SFU_OK = 1
};
class rvScriptFuncUtility {
public:
rvScriptFuncUtility();
explicit rvScriptFuncUtility( const rvScriptFuncUtility* sfu );
explicit rvScriptFuncUtility( const rvScriptFuncUtility& sfu );
explicit rvScriptFuncUtility( const char* source );
explicit rvScriptFuncUtility( const idCmdArgs& args );
sfuReturnType Init( const char* source );
sfuReturnType Init( const idCmdArgs& args );
void Clear();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
idTypeDef* GetParmType( int index ) const;
idTypeDef* GetReturnType() const ;
int NumParms() const;
bool ReturnsAVal() const;
void SetFunction( const function_t* func );
void SetParms( const idList<idStr>& parms );
void SetReturnKey( const char* key ) { returnKey = key; }
const char* GetFuncName() const;
const function_t* GetFunc() const { return func; }
const char* GetParm( int index ) const;
const char* GetReturnKey() const { return returnKey.c_str(); }
void InsertInt( int parm, int index );
void InsertFloat( float parm, int index );
void InsertVec3( const idVec3& parm, int index );
void InsertEntity( const idEntity* parm, int index );
void InsertString( const char* parm, int index );
void InsertBool( bool parm, int index );
void RemoveIndex( int index );
const function_t* FindFunction( const char* name ) const;
void CallFunc( idDict* returnDict ) const;
bool Valid() const;
rvScriptFuncUtility& Assign( const rvScriptFuncUtility* sfu );
rvScriptFuncUtility& operator=( const rvScriptFuncUtility* sfu );
rvScriptFuncUtility& operator=( const rvScriptFuncUtility& sfu );
bool IsEqualTo( const rvScriptFuncUtility* sfu ) const;
bool operator==( const rvScriptFuncUtility* sfu ) const;
bool operator==( const rvScriptFuncUtility& sfu ) const;
private:
sfuReturnType Init();
protected:
const function_t* func;
idList<idStr> parms;
idStr returnKey;
};
#endif
File diff suppressed because it is too large Load Diff
+251
View File
@@ -0,0 +1,251 @@
#ifndef __SCRIPT_COMPILER_H__
#define __SCRIPT_COMPILER_H__
const char * const RESULT_STRING = "<RESULT>";
typedef struct opcode_s {
char *name;
char *opname;
int priority;
bool rightAssociative;
idVarDef *type_a;
idVarDef *type_b;
idVarDef *type_c;
} opcode_t;
// These opcodes are no longer necessary:
// OP_PUSH_OBJ:
// OP_PUSH_OBJENT:
enum {
OP_RETURN,
OP_UINC_F,
OP_UINCP_F,
OP_UDEC_F,
OP_UDECP_F,
OP_COMP_F,
OP_MUL_F,
OP_MUL_V,
OP_MUL_FV,
OP_MUL_VF,
OP_DIV_F,
OP_MOD_F,
OP_ADD_F,
OP_ADD_V,
OP_ADD_S,
OP_ADD_FS,
OP_ADD_SF,
OP_ADD_VS,
OP_ADD_SV,
OP_SUB_F,
OP_SUB_V,
OP_EQ_F,
OP_EQ_V,
OP_EQ_S,
OP_EQ_E,
OP_EQ_EO,
OP_EQ_OE,
OP_EQ_OO,
OP_NE_F,
OP_NE_V,
OP_NE_S,
OP_NE_E,
OP_NE_EO,
OP_NE_OE,
OP_NE_OO,
OP_LE,
OP_GE,
OP_LT,
OP_GT,
OP_INDIRECT_F,
OP_INDIRECT_V,
OP_INDIRECT_S,
OP_INDIRECT_ENT,
OP_INDIRECT_BOOL,
OP_INDIRECT_OBJ,
OP_ADDRESS,
OP_EVENTCALL,
OP_OBJECTCALL,
OP_SYSCALL,
OP_STORE_F,
OP_STORE_V,
OP_STORE_S,
OP_STORE_ENT,
OP_STORE_BOOL,
OP_STORE_OBJENT,
OP_STORE_OBJ,
OP_STORE_ENTOBJ,
OP_STORE_FTOS,
OP_STORE_BTOS,
OP_STORE_VTOS,
OP_STORE_FTOBOOL,
OP_STORE_BOOLTOF,
OP_STOREP_F,
OP_STOREP_V,
OP_STOREP_S,
OP_STOREP_ENT,
OP_STOREP_FLD,
OP_STOREP_BOOL,
OP_STOREP_OBJ,
OP_STOREP_OBJENT,
OP_STOREP_FTOS,
OP_STOREP_BTOS,
OP_STOREP_VTOS,
OP_STOREP_FTOBOOL,
OP_STOREP_BOOLTOF,
OP_UMUL_F,
OP_UMUL_V,
OP_UDIV_F,
OP_UDIV_V,
OP_UMOD_F,
OP_UADD_F,
OP_UADD_V,
OP_USUB_F,
OP_USUB_V,
OP_UAND_F,
OP_UOR_F,
OP_NOT_BOOL,
OP_NOT_F,
OP_NOT_V,
OP_NOT_S,
OP_NOT_ENT,
OP_NEG_F,
OP_NEG_V,
OP_INT_F,
OP_IF,
OP_IFNOT,
OP_CALL,
OP_THREAD,
OP_OBJTHREAD,
OP_PUSH_F,
OP_PUSH_V,
OP_PUSH_S,
OP_PUSH_ENT,
OP_PUSH_OBJ,
OP_PUSH_OBJENT,
OP_PUSH_FTOS,
OP_PUSH_BTOF,
OP_PUSH_FTOB,
OP_PUSH_VTOS,
OP_PUSH_BTOS,
OP_GOTO,
OP_AND,
OP_AND_BOOLF,
OP_AND_FBOOL,
OP_AND_BOOLBOOL,
OP_OR,
OP_OR_BOOLF,
OP_OR_FBOOL,
OP_OR_BOOLBOOL,
OP_BITAND,
OP_BITOR,
OP_BREAK, // placeholder op. not used in final code
OP_CONTINUE, // placeholder op. not used in final code
NUM_OPCODES
};
class idCompiler {
private:
static bool punctuationValid[ 256 ];
static char *punctuation[];
idParser parser;
idParser *parserPtr;
idToken token;
idTypeDef *immediateType;
eval_t immediate;
bool eof;
bool console;
bool callthread;
int braceDepth;
int loopDepth;
int currentLineNumber;
int currentFileNumber;
int errorCount;
idVarDef *scope; // the function being parsed, or NULL
const idVarDef *basetype; // for accessing fields
float Divide( float numerator, float denominator );
void Error( const char *error, ... ) const;
void Warning( const char *message, ... ) const;
idVarDef *OptimizeOpcode( const opcode_t *op, idVarDef *var_a, idVarDef *var_b );
idVarDef *EmitOpcode( const opcode_t *op, idVarDef *var_a, idVarDef *var_b );
idVarDef *EmitOpcode( int op, idVarDef *var_a, idVarDef *var_b );
bool EmitPush( idVarDef *expression, const idTypeDef *funcArg );
void NextToken( void );
void ExpectToken( const char *string );
bool CheckToken( const char *string );
void ParseName( idStr &name );
void SkipOutOfFunction( void );
void SkipToSemicolon( void );
idTypeDef *CheckType( void );
idTypeDef *ParseType( void );
idVarDef *FindImmediate( const idTypeDef *type, const eval_t *eval, const char *string ) const;
idVarDef *GetImmediate( idTypeDef *type, const eval_t *eval, const char *string );
idVarDef *VirtualFunctionConstant( idVarDef *func );
idVarDef *SizeConstant( int size );
idVarDef *JumpConstant( int value );
idVarDef *JumpDef( int jumpfrom, int jumpto );
idVarDef *JumpTo( int jumpto );
idVarDef *JumpFrom( int jumpfrom );
idVarDef *ParseImmediate( void );
idVarDef *EmitFunctionParms( int op, idVarDef *func, int startarg, int startsize, idVarDef *object );
idVarDef *ParseFunctionCall( idVarDef *func );
idVarDef *ParseObjectCall( idVarDef *object, idVarDef *func );
idVarDef *ParseEventCall( idVarDef *object, idVarDef *func );
idVarDef *ParseSysObjectCall( idVarDef *func );
idVarDef *LookupDef( const char *name, const idVarDef *baseobj );
idVarDef *ParseValue( void );
idVarDef *GetTerm( void );
bool TypeMatches( etype_t type1, etype_t type2 ) const;
idVarDef *GetExpression( int priority );
idTypeDef *GetTypeForEventArg( char argType );
void PatchLoop( int start, int continuePos );
void ParseReturnStatement( void );
void ParseWhileStatement( void );
void ParseForStatement( void );
void ParseDoWhileStatement( void );
void ParseIfStatement( void );
void ParseStatement( void );
void ParseObjectDef( const char *objname );
idTypeDef *ParseFunction( idTypeDef *returnType, const char *name );
void ParseFunctionDef( idTypeDef *returnType, const char *name );
void ParseVariableDef( idTypeDef *type, const char *name );
void ParseEventDef( idTypeDef *type, const char *name );
void ParseDefs( void );
void ParseNamespace( idVarDef *newScope );
public :
static opcode_t opcodes[];
idCompiler();
void CompileFile( const char *text, const char *filename, bool console );
};
#endif /* !__SCRIPT_COMPILER_H__ */
File diff suppressed because it is too large Load Diff
+271
View File
@@ -0,0 +1,271 @@
#ifndef __SCRIPT_INTERPRETER_H__
#define __SCRIPT_INTERPRETER_H__
#define MAX_STACK_DEPTH 64
// RB: doubled local stack size
#define LOCALSTACK_SIZE (6144 * 2)
// RB end
typedef struct prstack_s {
int s;
const function_t *f;
int stackbase;
} prstack_t;
class idInterpreter {
private:
prstack_t callStack[ MAX_STACK_DEPTH ];
int callStackDepth;
int maxStackDepth;
byte localstack[ LOCALSTACK_SIZE ];
int localstackUsed;
int localstackBase;
int maxLocalstackUsed;
const function_t *currentFunction;
int instructionPointer;
int popParms;
const idEventDef *multiFrameEvent;
idEntity *eventEntity;
idThread *thread;
void PopParms( int numParms );
// RAVEN BEGIN
// abahr: making Push public to allow parms to be put on stack
public:
void PushString( const char *string );
void Push( intptr_t value );
void PushVector(const idVec3& vector);
private:
// RAVEN END
const char *FloatToString( float value );
void AppendString( idVarDef *def, const char *from );
void SetString( idVarDef *def, const char *from );
const char *GetString( idVarDef *def );
varEval_t GetVariable( idVarDef *def );
idEntity *GetEntity( int entnum ) const;
idScriptObject *GetScriptObject( int entnum ) const;
void NextInstruction( int position );
void LeaveFunction( idVarDef *returnDef );
void CallEvent( const function_t *func, int argsize );
void CallSysEvent( const function_t *func, int argsize );
// RAVEN BEGIN
// jshepard: last variable referenced in the script-- keep tabs on it so we can print it for warnings.
idVarDef *LastScriptVariable;
// RAVEN END
public:
bool doneProcessing;
bool threadDying;
bool terminateOnExit;
bool debug;
idInterpreter();
// save games
void Save( idSaveGame *savefile ) const; // archives object for save game file
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
void SetThread( idThread *pThread );
void StackTrace( void ) const;
int CurrentLine( void ) const;
const char *CurrentFile( void ) const;
void Error( char *fmt, ... ) const;
void Warning( char *fmt, ... ) const;
void DisplayInfo( void ) const;
bool BeginMultiFrameEvent( idEntity *ent, const idEventDef *event );
void EndMultiFrameEvent( idEntity *ent, const idEventDef *event );
bool MultiFrameEventInProgress( void ) const;
void ThreadCall( idInterpreter *source, const function_t *func, int args );
void EnterFunction( const function_t *func, bool clearStack );
void EnterObjectFunction( idEntity *self, const function_t *func, bool clearStack );
bool Execute( void );
void Reset( void );
bool GetRegisterValue( const char *name, idStr &out, int scopeDepth );
int GetCallstackDepth( void ) const;
const prstack_t *GetCallstack( void ) const;
const function_t *GetCurrentFunction( void ) const;
idThread *GetThread( void ) const;
};
/*
====================
idInterpreter::PopParms
====================
*/
ID_INLINE void idInterpreter::PopParms( int numParms ) {
// pop our parms off the stack
if ( localstackUsed < numParms ) {
Error( "locals stack underflow\n" );
}
localstackUsed -= numParms;
}
/*
====================
idInterpreter::Push
====================
*/
ID_INLINE void idInterpreter::Push( intptr_t value ) {
if ( localstackUsed + sizeof(intptr_t) > LOCALSTACK_SIZE ) {
Error( "Push: locals stack overflow\n" );
}
*(intptr_t* )&localstack[ localstackUsed ] = value;
localstackUsed += sizeof(intptr_t);
}
/*
====================
idInterpreter::PushVector
====================
*/
ID_INLINE void idInterpreter::PushVector(const idVec3& vector) {
if (localstackUsed + E_EVENT_SIZEOF_VEC > LOCALSTACK_SIZE) {
Error("Push: locals stack overflow\n");
}
*(idVec3*)&localstack[localstackUsed] = vector;
localstackUsed += E_EVENT_SIZEOF_VEC;
}
/*
====================
idInterpreter::PushString
====================
*/
ID_INLINE void idInterpreter::PushString( const char *string ) {
if ( localstackUsed + MAX_STRING_LEN > LOCALSTACK_SIZE ) {
Error( "PushString: locals stack overflow\n" );
}
idStr::Copynz( ( char * )&localstack[ localstackUsed ], string, MAX_STRING_LEN );
localstackUsed += MAX_STRING_LEN;
}
/*
====================
idInterpreter::FloatToString
====================
*/
ID_INLINE const char *idInterpreter::FloatToString( float value ) {
static char text[ 32 ];
if ( value == ( float )( int )value ) {
sprintf( text, "%d", ( int )value );
} else {
sprintf( text, "%f", value );
}
return text;
}
/*
====================
idInterpreter::AppendString
====================
*/
ID_INLINE void idInterpreter::AppendString( idVarDef *def, const char *from ) {
if ( def->initialized == idVarDef::stackVariable ) {
idStr::Append( ( char * )&localstack[ localstackBase + def->value.stackOffset ], MAX_STRING_LEN, from );
} else {
idStr::Append( def->value.stringPtr, MAX_STRING_LEN, from );
}
}
/*
====================
idInterpreter::SetString
====================
*/
ID_INLINE void idInterpreter::SetString( idVarDef *def, const char *from ) {
if ( def->initialized == idVarDef::stackVariable ) {
idStr::Copynz( ( char * )&localstack[ localstackBase + def->value.stackOffset ], from, MAX_STRING_LEN );
} else {
idStr::Copynz( def->value.stringPtr, from, MAX_STRING_LEN );
}
}
/*
====================
idInterpreter::GetString
====================
*/
ID_INLINE const char *idInterpreter::GetString( idVarDef *def ) {
if ( def->initialized == idVarDef::stackVariable ) {
return ( char * )&localstack[ localstackBase + def->value.stackOffset ];
} else {
return def->value.stringPtr;
}
}
/*
====================
idInterpreter::GetVariable
====================
*/
ID_INLINE varEval_t idInterpreter::GetVariable( idVarDef *def ) {
if ( def->initialized == idVarDef::stackVariable ) {
varEval_t val;
val.intPtr = ( int * )&localstack[ localstackBase + def->value.stackOffset ];
return val;
} else {
return def->value;
}
}
/*
================
idInterpreter::GetEntity
================
*/
ID_INLINE 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
================
*/
ID_INLINE 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;
}
/*
====================
idInterpreter::NextInstruction
====================
*/
ID_INLINE void idInterpreter::NextInstruction( int position ) {
// Before we execute an instruction, we increment instructionPointer,
// therefore we need to compensate for that here.
instructionPointer = position - 1;
}
#endif /* !__SCRIPT_INTERPRETER_H__ */
File diff suppressed because it is too large Load Diff
+797
View File
@@ -0,0 +1,797 @@
#ifndef __SCRIPT_PROGRAM_H__
#define __SCRIPT_PROGRAM_H__
class idScriptObject;
class idEventDef;
class idVarDef;
class idTypeDef;
class idEntity;
class idThread;
class idSaveGame;
class idRestoreGame;
#define MAX_STRING_LEN 128
// RAVEN BEGIN
// ddynerman: higher max limit, initially 196608
// jshepard: ... then 393216
#define MAX_GLOBALS 589824 // in bytes
// jshepard: raise the limits. Formerly 1024, 3072 and 81920.
#define MAX_STRINGS 2048
#define MAX_FUNCS 6144
#define MAX_STATEMENTS 163840 // statement_t - 18 bytes last I checked
// RAVEN END
typedef enum {
ev_error = -1, ev_void, ev_scriptevent, ev_namespace, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_virtualfunction, ev_pointer, ev_object, ev_jumpoffset, ev_argsize, ev_boolean
} etype_t;
class function_t {
public:
function_t();
size_t Allocated( void ) const;
void SetName( const char *name );
const char *Name( void ) const;
void Clear( void );
private:
idStr name;
public:
const idEventDef *eventdef;
idVarDef *def;
const idTypeDef *type;
int firstStatement;
int numStatements;
int parmTotal;
int locals; // total ints of parms + locals
int filenum; // source file defined in
idList<int> parmSize;
};
typedef union eval_s {
const char *stringPtr;
float _float;
float vector[ 3 ];
function_t *function;
int _int;
int entity;
} eval_t;
/***********************************************************************
idTypeDef
Contains type information for variables and functions.
***********************************************************************/
class idTypeDef {
private:
etype_t type;
idStr name;
int size;
// function types are more complex
idTypeDef *auxType; // return type
idList<idTypeDef *> parmTypes;
idStrList parmNames;
idList<const function_t *> functions;
public:
idVarDef *def; // a def that points to this type
idTypeDef( const idTypeDef &other );
idTypeDef( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux );
virtual ~idTypeDef( void ) { }
void operator=( const idTypeDef& other );
size_t Allocated( void ) const;
bool Inherits( const idTypeDef *basetype ) const;
bool MatchesType( const idTypeDef &matchtype ) const;
bool MatchesVirtualFunction( const idTypeDef &matchfunc ) const;
void AddFunctionParm( idTypeDef *parmtype, const char *name );
void AddField( idTypeDef *fieldtype, const char *name );
void SetName( const char *newname );
const char *Name( void ) const;
etype_t Type( void ) const;
int Size( void ) const;
idTypeDef *SuperClass( void ) const;
idTypeDef *ReturnType( void ) const;
void SetReturnType( idTypeDef *type );
idTypeDef *FieldType( void ) const;
void SetFieldType( idTypeDef *type );
idTypeDef *PointerType( void ) const;
void SetPointerType( idTypeDef *type );
int NumParameters( void ) const;
idTypeDef *GetParmType( int parmNumber ) const;
const char *GetParmName( int parmNumber ) const;
int NumFunctions( void ) const;
int GetFunctionNumber( const function_t *func ) const;
const function_t *GetFunction( int funcNumber ) const;
void AddFunction( const function_t *func );
// RAVEN BEGIN
// abahr
virtual const char* GetReturnedValAsString( idProgram& program ) { return ""; }
virtual void PushOntoStack( idThread* thread, const char* source ) { assert(0); }
virtual bool IsValid( const char* source ) const { return true; }
virtual const char* Format() const { return ""; }
// RAVEN END
};
// RAVEN BEGIN
// abahr: subclasses for overwritting helper functions
/***********************************************************************
rvTypeDefInt
***********************************************************************/
class rvTypeDefInt : public idTypeDef {
public:
rvTypeDefInt( const idTypeDef &other ) : idTypeDef( other ) {}
rvTypeDefInt( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux ) : idTypeDef( etype, edef, ename, esize, aux ) {}
const char* GetReturnedValAsString( idProgram& program );
void PushOntoStack( idThread* thread, const char* source );
bool IsValid( const char* source ) const;
protected:
const char* Format() const { return "%d"; }
int Parse( const char* source ) const;
};
/***********************************************************************
rvTypeDefFloat
***********************************************************************/
class rvTypeDefFloat : public idTypeDef {
public:
rvTypeDefFloat( const idTypeDef &other ) : idTypeDef( other ) {}
rvTypeDefFloat( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux ) : idTypeDef( etype, edef, ename, esize, aux ) {}
const char* GetReturnedValAsString( idProgram& program );
void PushOntoStack( idThread* thread, const char* source );
bool IsValid( const char* source ) const;
protected:
const char* Format() const { return "%f"; }
float Parse( const char* source ) const;
};
/***********************************************************************
rvTypeDefVec3
***********************************************************************/
class rvTypeDefVec3 : public idTypeDef {
public:
rvTypeDefVec3( const idTypeDef &other ) : idTypeDef( other ) {}
rvTypeDefVec3( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux ) : idTypeDef( etype, edef, ename, esize, aux ) {}
const char* GetReturnedValAsString( idProgram& program );
void PushOntoStack( idThread* thread, const char* source );
bool IsValid( const char* source ) const;
protected:
const char* Format() const { return "%f %f %f"; }
idVec3 Parse( const char* source ) const;
};
/***********************************************************************
rvTypeDefEntity
***********************************************************************/
class rvTypeDefEntity : public idTypeDef {
public:
rvTypeDefEntity( const idTypeDef &other ) : idTypeDef( other ) {}
rvTypeDefEntity( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux ) : idTypeDef( etype, edef, ename, esize, aux ) {}
const char* GetReturnedValAsString( idProgram& program );
void PushOntoStack( idThread* thread, const char* source );
bool IsValid( const char* source ) const;
protected:
idEntity* Parse( const char* source ) const;
};
/***********************************************************************
rvTypeDefString
***********************************************************************/
class rvTypeDefString : public idTypeDef {
public:
rvTypeDefString( const idTypeDef &other ) : idTypeDef( other ) {}
rvTypeDefString( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux ) : idTypeDef( etype, edef, ename, esize, aux ) {}
const char* GetReturnedValAsString( idProgram& program );
void PushOntoStack( idThread* thread, const char* source );
bool IsValid( const char* source ) const;
protected:
const char* Parse( const char* source ) const;
};
/***********************************************************************
rvTypeDefBool
***********************************************************************/
class rvTypeDefBool : public idTypeDef {
public:
rvTypeDefBool( const idTypeDef &other ) : idTypeDef( other ) {}
rvTypeDefBool( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux ) : idTypeDef( etype, edef, ename, esize, aux ) {}
const char* GetReturnedValAsString( idProgram& program );
void PushOntoStack( idThread* thread, const char* source );
bool IsValid( const char* source ) const;
protected:
const char* Format() const { return "%u"; }
bool Parse( const char* source ) const;
};
// RAVEN END
/***********************************************************************
idScriptObject
In-game representation of objects in scripts. Use the idScriptVariable template
(below) to access variables.
***********************************************************************/
class idScriptObject {
private:
idTypeDef *type;
public:
byte *data;
idScriptObject();
~idScriptObject();
void Save( idSaveGame *savefile ) const; // archives object for save game file
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
void Free( void );
bool SetType( const char *typeName );
void ClearObject( void );
bool HasObject( void ) const;
idTypeDef *GetTypeDef( void ) const;
const char *GetTypeName( void ) const;
const function_t *GetConstructor( void ) const;
const function_t *GetDestructor( void ) const;
const function_t *GetFunction( const char *name ) const;
byte *GetVariable( const char *name, etype_t etype ) const;
};
/***********************************************************************
idScriptVariable
Helper template that handles looking up script variables stored in objects.
If the specified variable doesn't exist, or is the wrong data type, idScriptVariable
will cause an error.
***********************************************************************/
template<class type, etype_t etype, class returnType>
class idScriptVariable {
private:
type *data;
public:
idScriptVariable();
bool IsLinked( void ) const;
void Unlink( void );
void LinkTo( idScriptObject &obj, const char *name );
idScriptVariable &operator=( const returnType &value );
operator returnType() const;
};
template<class type, etype_t etype, class returnType>
ID_INLINE idScriptVariable<type, etype, returnType>::idScriptVariable() {
data = NULL;
}
template<class type, etype_t etype, class returnType>
ID_INLINE bool idScriptVariable<type, etype, returnType>::IsLinked( void ) const {
return ( data != NULL );
}
template<class type, etype_t etype, class returnType>
ID_INLINE void idScriptVariable<type, etype, returnType>::Unlink( void ) {
data = NULL;
}
template<class type, etype_t etype, class returnType>
ID_INLINE void idScriptVariable<type, etype, returnType>::LinkTo( idScriptObject &obj, const char *name ) {
data = ( type * )obj.GetVariable( name, etype );
if ( !data ) {
gameError( "Missing '%s' field in script object '%s'", name, obj.GetTypeName() );
}
}
template<class type, etype_t etype, class returnType>
ID_INLINE idScriptVariable<type, etype, returnType> &idScriptVariable<type, etype, returnType>::operator=( const returnType &value ) {
// check if we attempt to access the object before it's been linked
assert( data );
// make sure we don't crash if we don't have a pointer
if ( data ) {
*data = ( type )value;
}
return *this;
}
template<class type, etype_t etype, class returnType>
ID_INLINE idScriptVariable<type, etype, returnType>::operator returnType() const {
// check if we attempt to access the object before it's been linked
assert( data );
// make sure we don't crash if we don't have a pointer
if ( data ) {
return ( const returnType )*data;
} else {
// reasonably safe value
return ( const returnType )0;
}
}
/***********************************************************************
Script object variable access template instantiations
These objects will automatically handle looking up of the current value
of a variable in a script object. They can be stored as part of a class
for up-to-date values of the variable, or can be used in functions to
sample the data for non-dynamic values.
***********************************************************************/
typedef idScriptVariable<bool, ev_boolean, bool> idScriptBool;
typedef idScriptVariable<float, ev_float, float> idScriptFloat;
typedef idScriptVariable<float, ev_float, int> idScriptInt;
typedef idScriptVariable<idVec3, ev_vector, idVec3> idScriptVector;
typedef idScriptVariable<idStr, ev_string, const char *> idScriptString;
/***********************************************************************
idCompileError
Causes the compiler to exit out of compiling the current function and
display an error message with line and file info.
***********************************************************************/
class idCompileError : public idException {
public:
idCompileError( const char *text ) : idException( text ) {}
};
/***********************************************************************
idVarDef
Define the name, type, and location of variables, functions, and objects
defined in script.
***********************************************************************/
typedef union varEval_s {
idScriptObject **objectPtrPtr;
char *stringPtr;
float *floatPtr;
idVec3 *vectorPtr;
function_t *functionPtr;
int *intPtr;
byte *bytePtr;
int *entityNumberPtr;
int virtualFunction;
int jumpOffset;
int stackOffset; // offset in stack for local variables
int argSize;
varEval_s *evalPtr;
int ptrOffset;
} varEval_t;
class idVarDefName;
class idVarDef {
friend class idVarDefName;
public:
int num;
varEval_t value;
idVarDef * scope; // function, namespace, or object the var was defined in
int numUsers; // number of users if this is a constant
typedef enum {
uninitialized, initializedVariable, initializedConstant, stackVariable
} initialized_t;
initialized_t initialized;
public:
idVarDef( idTypeDef *typeptr = NULL );
~idVarDef();
const char * Name( void ) const;
const char * GlobalName( void ) const;
void SetTypeDef( idTypeDef *_type ) { typeDef = _type; }
idTypeDef * TypeDef( void ) const { return typeDef; }
etype_t Type( void ) const { return ( typeDef != NULL ) ? typeDef->Type() : ev_void; }
int DepthOfScope( const idVarDef *otherScope ) const;
void SetFunction( function_t *func );
void SetObject( idScriptObject *object );
void SetValue( const eval_t &value, bool constant );
void SetString( const char *string, bool constant );
idVarDef * Next( void ) const { return next; } // next var def with same name
void PrintInfo( idFile *file, int instructionPointer ) const;
private:
idTypeDef * typeDef;
idVarDefName * name; // name of this var
idVarDef * next; // next var with the same name
};
/***********************************************************************
idVarDefName
***********************************************************************/
class idVarDefName {
public:
idVarDefName( void ) { defs = NULL; }
idVarDefName( const char *n ) { name = n; defs = NULL; }
const char * Name( void ) const { return name; }
idVarDef * GetDefs( void ) const { return defs; }
void AddDef( idVarDef *def );
void RemoveDef( idVarDef *def );
private:
idStr name;
idVarDef * defs;
};
/***********************************************************************
Variable and type defintions
***********************************************************************/
extern idTypeDef type_void;
extern idTypeDef type_scriptevent;
extern idTypeDef type_namespace;
// RAVEN BEGIN
// abahr
extern rvTypeDefString type_string;
extern rvTypeDefFloat type_float;
extern rvTypeDefVec3 type_vector;
extern rvTypeDefEntity type_entity;
// RAVEN END
extern idTypeDef type_field;
extern idTypeDef type_function;
extern idTypeDef type_virtualfunction;
extern idTypeDef type_pointer;
extern idTypeDef type_object;
extern idTypeDef type_jumpoffset; // only used for jump opcodes
extern idTypeDef type_argsize; // only used for function call and thread opcodes
// RAVEN BEGIN
// abahr
extern rvTypeDefBool type_boolean;
// RAVEN END
extern idVarDef def_void;
extern idVarDef def_scriptevent;
extern idVarDef def_namespace;
extern idVarDef def_string;
extern idVarDef def_float;
extern idVarDef def_vector;
extern idVarDef def_entity;
extern idVarDef def_field;
extern idVarDef def_function;
extern idVarDef def_virtualfunction;
extern idVarDef def_pointer;
extern idVarDef def_object;
extern idVarDef def_jumpoffset; // only used for jump opcodes
extern idVarDef def_argsize; // only used for function call and thread opcodes
extern idVarDef def_boolean;
typedef struct statement_s {
unsigned short op;
idVarDef *a;
idVarDef *b;
idVarDef *c;
unsigned short linenumber;
unsigned short file;
} statement_t;
/***********************************************************************
idProgram
Handles compiling and storage of script data. Multiple idProgram objects
would represent seperate programs with no knowledge of each other. Scripts
meant to access shared data and functions should all be compiled by a
single idProgram.
***********************************************************************/
class idProgram {
private:
idStrList fileList;
idStr filename;
int filenum;
int numVariables;
byte variables[ MAX_GLOBALS ];
idStaticList<byte,MAX_GLOBALS> variableDefaults;
idStaticList<function_t,MAX_FUNCS> functions;
idStaticList<statement_t,MAX_STATEMENTS> statements;
idList<idTypeDef *> types;
idList<idVarDefName *> varDefNames;
idHashIndex varDefNameHash;
idList<idVarDef *> varDefs;
idVarDef *sysDef;
int top_functions;
int top_statements;
int top_types;
int top_defs;
int top_files;
void CompileStats( void );
public:
idVarDef *returnDef;
idVarDef *returnStringDef;
idProgram();
~idProgram();
// save games
void Save( idSaveGame *savefile ) const;
bool Restore( idRestoreGame *savefile );
int CalculateChecksum( void ) const; // Used to insure program code has not
// changed between savegames
void Startup( const char *defaultScript );
void Restart( void );
bool CompileText( const char *source, const char *text, bool console );
const function_t *CompileFunction( const char *functionName, const char *text );
void CompileFile( const char *filename );
void BeginCompilation( void );
void FinishCompilation( void );
void DisassembleStatement( idFile *file, int instructionPointer ) const;
void Disassemble( void ) const;
void FreeData( void );
const char *GetFilename( int num );
int GetFilenum( const char *name );
int GetLineNumberForStatement( int index );
const char *GetFilenameForStatement( int index );
idTypeDef *AllocType( idTypeDef &type );
idTypeDef *AllocType( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux );
idTypeDef *GetType( idTypeDef &type, bool allocate );
idTypeDef *FindType( const char *name );
idVarDef *AllocDef( idTypeDef *type, const char *name, idVarDef *scope, bool constant );
idVarDef *GetDef( const idTypeDef *type, const char *name, const idVarDef *scope ) const;
void FreeDef( idVarDef *d, const idVarDef *scope );
idVarDef *FindFreeResultDef( idTypeDef *type, const char *name, idVarDef *scope, const idVarDef *a, const idVarDef *b );
idVarDef *GetDefList( const char *name ) const;
void AddDefToNameList( idVarDef *def, const char *name );
function_t *FindFunction( const char *name ) const; // returns NULL if function not found
function_t *FindFunction( const char *name, const idTypeDef *type ) const; // returns NULL if function not found
function_t &AllocFunction( idVarDef *def );
function_t *GetFunction( int index );
int GetFunctionIndex( const function_t *func );
void SetEntity( const char *name, idEntity *ent );
statement_t *AllocStatement( void );
statement_t &GetStatement( int index );
int NumStatements( void ) { return statements.Num(); }
int GetReturnedInteger( void );
// RAVEN BEGIN
// abahr: adding helper functions for other types
float GetReturnedFloat();
idVec3 GetReturnedVec3();
idEntity* GetReturnedEntity();
const char* GetReturnedString();
bool GetReturnedBool();
// RAVEN END
void ReturnFloat( float value );
void ReturnInteger( int value );
void ReturnVector( idVec3 const &vec );
void ReturnString( const char *string );
// RAVEN BEGIN
// abahr: added const
void ReturnEntity( const idEntity *ent );
// RAVEN END
int NumFilenames( void ) { return fileList.Num( ); }
// RAVEN BEGIN
// bdube: added
void ListStates( void );
// jscott: added for debug with inlines and memory log
void Shutdown( void );
// jscott: added for stats
size_t ScriptSummary( const idCmdArgs &args );
size_t ClassSummary( const idCmdArgs &args );
// RAVEN END
};
/*
================
idProgram::GetStatement
================
*/
ID_INLINE statement_t &idProgram::GetStatement( int index ) {
return statements[ index ];
}
/*
================
idProgram::GetFunction
================
*/
ID_INLINE function_t *idProgram::GetFunction( int index ) {
return &functions[ index ];
}
/*
================
idProgram::GetFunctionIndex
================
*/
ID_INLINE int idProgram::GetFunctionIndex( const function_t *func ) {
return func - &functions[0];
}
/*
================
idProgram::GetReturnedInteger
================
*/
ID_INLINE int idProgram::GetReturnedInteger( void ) {
// RAVEN BEGIN
// abahr: because we only return floats in idThread we need to only get floats
return (int)GetReturnedFloat();
// RAVEN END
}
// RAVEN BEGIN
// abahr: adding helper functions for other types
/*
================
idProgram::GetReturnedFloat
================
*/
ID_INLINE float idProgram::GetReturnedFloat() {
return *returnDef->value.floatPtr;
}
/*
================
idProgram::GetReturnedVec3
================
*/
ID_INLINE idVec3 idProgram::GetReturnedVec3() {
return *returnDef->value.vectorPtr;
}
/*
================
idProgram::GetReturnedString
================
*/
ID_INLINE const char* idProgram::GetReturnedString() {
return returnDef->value.stringPtr;
}
/*
================
idProgram::GetReturnedBool
================
*/
ID_INLINE bool idProgram::GetReturnedBool() {
return GetReturnedInteger() != 0;
}
// RAVEN END
/*
================
idProgram::ReturnFloat
================
*/
ID_INLINE void idProgram::ReturnFloat( float value ) {
*returnDef->value.floatPtr = value;
}
/*
================
idProgram::ReturnInteger
================
*/
ID_INLINE void idProgram::ReturnInteger( int value ) {
*returnDef->value.intPtr = value;
}
/*
================
idProgram::ReturnVector
================
*/
ID_INLINE void idProgram::ReturnVector( idVec3 const &vec ) {
*returnDef->value.vectorPtr = vec;
}
/*
================
idProgram::ReturnString
================
*/
ID_INLINE void idProgram::ReturnString( const char *string ) {
idStr::Copynz( returnStringDef->value.stringPtr, string, MAX_STRING_LEN );
}
/*
================
idProgram::GetFilename
================
*/
ID_INLINE const char *idProgram::GetFilename( int num ) {
return fileList[ num ];
}
/*
================
idProgram::GetLineNumberForStatement
================
*/
ID_INLINE int idProgram::GetLineNumberForStatement( int index ) {
return statements[ index ].linenumber;
}
/*
================
idProgram::GetFilenameForStatement
================
*/
ID_INLINE const char *idProgram::GetFilenameForStatement( int index ) {
return GetFilename( statements[ index ].file );
}
#endif /* !__SCRIPT_PROGRAM_H__ */
File diff suppressed because it is too large Load Diff
+365
View File
@@ -0,0 +1,365 @@
#ifndef __SCRIPT_THREAD_H__
#define __SCRIPT_THREAD_H__
extern const idEventDef EV_Thread_Execute;
extern const idEventDef EV_Thread_SetCallback;
extern const idEventDef EV_Thread_TerminateThread;
extern const idEventDef EV_Thread_Pause;
extern const idEventDef EV_Thread_Wait;
extern const idEventDef EV_Thread_WaitFrame;
extern const idEventDef EV_Thread_WaitFor;
extern const idEventDef EV_Thread_WaitForThread;
extern const idEventDef EV_Thread_Print;
extern const idEventDef EV_Thread_PrintLn;
extern const idEventDef EV_Thread_Say;
extern const idEventDef EV_Thread_Assert;
extern const idEventDef EV_Thread_Trigger;
extern const idEventDef EV_Thread_SetCvar;
extern const idEventDef EV_Thread_GetCvar;
extern const idEventDef EV_Thread_Random;
extern const idEventDef EV_Thread_GetTime;
extern const idEventDef EV_Thread_KillThread;
extern const idEventDef EV_Thread_SetThreadName;
extern const idEventDef EV_Thread_GetEntity;
extern const idEventDef EV_Thread_Spawn;
extern const idEventDef EV_Thread_SetSpawnArg;
extern const idEventDef EV_Thread_SpawnString;
extern const idEventDef EV_Thread_SpawnFloat;
extern const idEventDef EV_Thread_SpawnVector;
extern const idEventDef EV_Thread_AngToForward;
extern const idEventDef EV_Thread_AngToRight;
extern const idEventDef EV_Thread_AngToUp;
extern const idEventDef EV_Thread_Sine;
extern const idEventDef EV_Thread_Cosine;
extern const idEventDef EV_Thread_Normalize;
extern const idEventDef EV_Thread_VecLength;
extern const idEventDef EV_Thread_VecDotProduct;
extern const idEventDef EV_Thread_VecCrossProduct;
extern const idEventDef EV_Thread_OnSignal;
extern const idEventDef EV_Thread_ClearSignal;
extern const idEventDef EV_Thread_SetCamera;
extern const idEventDef EV_Thread_FirstPerson;
extern const idEventDef EV_Thread_TraceFraction;
extern const idEventDef EV_Thread_TracePos;
extern const idEventDef EV_Thread_FadeIn;
extern const idEventDef EV_Thread_FadeOut;
extern const idEventDef EV_Thread_FadeTo;
extern const idEventDef EV_Thread_Restart;
extern const idEventDef EV_Thread_SetMatSort;
// RAVEN BEGIN
// rjohnson: new blur special effect
extern const idEventDef EV_Thread_SetSpecialEffect;
extern const idEventDef EV_Thread_SetSpecialEffectParm;
// RAVEN END
class idThread : public idClass {
private:
static idThread *currentThread;
idThread *waitingForThread;
int waitingFor;
int waitingUntil;
idInterpreter interpreter;
idDict spawnArgs;
int threadNum;
idStr threadName;
int lastExecuteTime;
int creationTime;
bool manualControl;
static int threadIndex;
static idList<idThread *> threadList;
static trace_t trace;
void Init( void );
void Pause( void );
void Event_Execute( void );
void Event_SetThreadName( const char *name );
//
// script callable Events
//
void Event_TerminateThread( int num );
void Event_Pause( void );
void Event_Wait( float time );
void Event_WaitFrame( void );
void Event_WaitFor( idEntity *ent );
void Event_WaitForThread( int num );
void Event_Print( const char *text );
void Event_PrintLn( const char *text );
void Event_Say( const char *text );
void Event_Assert( float value );
void Event_Trigger( idEntity *ent );
void Event_SetCvar( const char *name, const char *value ) const;
void Event_GetCvar( const char *name ) const;
void Event_Random( float range ) const;
void Event_GetTime( void );
void Event_KillThread( const char *name );
void Event_GetEntity( const char *name );
void Event_Spawn( const char *classname );
void Event_CopySpawnArgs( idEntity *ent );
void Event_SetSpawnArg( const char *key, const char *value );
void Event_SpawnString( const char *key, const char *defaultvalue );
void Event_SpawnFloat( const char *key, float defaultvalue );
void Event_SpawnVector( const char *key, idVec3 &defaultvalue );
void Event_ClearPersistantArgs( void );
void Event_SetPersistantArg( const char *key, const char *value );
void Event_GetPersistantString( const char *key );
void Event_GetPersistantFloat( const char *key );
void Event_GetPersistantVector( const char *key );
void Event_AngToForward( idAngles &ang );
void Event_AngToRight( idAngles &ang );
void Event_AngToUp( idAngles &ang );
void Event_GetSine( float angle );
void Event_GetCosine( float angle );
void Event_GetSquareRoot( float theSquare );
void Event_VecNormalize( idVec3 &vec );
void Event_VecLength( idVec3 &vec );
void Event_VecDotProduct( idVec3 &vec1, idVec3 &vec2 );
void Event_VecCrossProduct( idVec3 &vec1, idVec3 &vec2 );
void Event_VecToAngles( idVec3 &vec );
void Event_OnSignal( int signal, idEntity *ent, const char *func );
void Event_ClearSignalThread( int signal, idEntity *ent );
void Event_SetCamera( idEntity *ent );
void Event_FirstPerson( void );
void Event_Trace( const idVec3 &start, const idVec3 &end, const idVec3 &mins, const idVec3 &maxs, int contents_mask, idEntity *passEntity );
void Event_TracePoint( const idVec3 &start, const idVec3 &end, int contents_mask, idEntity *passEntity );
void Event_GetTraceFraction( void );
void Event_GetTraceEndPos( void );
void Event_GetTraceNormal( void );
void Event_GetTraceEntity( void );
void Event_GetTraceJoint( void );
void Event_GetTraceBody( void );
void Event_FadeIn( idVec3 &color, float time );
void Event_FadeOut( idVec3 &color, float time );
void Event_FadeTo( idVec3 &color, float alpha, float time );
void Event_SetShaderParm( int parmnum, float value );
void Event_StartMusic( const char *name );
void Event_Warning( const char *text );
void Event_Error( const char *text );
void Event_StrLen( const char *string );
void Event_StrLeft( const char *string, int num );
void Event_StrRight( const char *string, int num );
void Event_StrSkip( const char *string, int num );
void Event_StrMid( const char *string, int start, int num );
void Event_StrToFloat( const char *string );
void Event_RadiusDamage( const idVec3 &origin, idEntity *inflictor, idEntity *attacker, idEntity *ignore, const char *damageDefName, float dmgPower );
void Event_IsClient( void );
void Event_IsMultiplayer( void );
void Event_GetFrameTime( void );
void Event_GetTicsPerSecond( void );
void Event_CacheSoundShader( const char *soundName );
void Event_DebugLine( const idVec3 &color, const idVec3 &start, const idVec3 &end, const float lifetime );
void Event_DebugArrow( const idVec3 &color, const idVec3 &start, const idVec3 &end, const int size, const float lifetime );
void Event_DebugCircle( const idVec3 &color, const idVec3 &origin, const idVec3 &dir, const float radius, const int numSteps, const float lifetime );
void Event_DebugBounds( const idVec3 &color, const idVec3 &mins, const idVec3 &maxs, const float lifetime );
void Event_DrawText( const char *text, const idVec3 &origin, float scale, const idVec3 &color, const int align, const float lifetime );
void Event_InfluenceActive( void );
// RAVEN BEGIN
// kfuller: added
void Event_SetSpawnVector( const char *key, idVec3 &vec );
void Event_GetArcSine( float sinValue );
void Event_GetArcCosine( float cosValue );
void Event_ClearSignalAllThreads( int signal, idEntity *ent );
void Event_VecRotate(idVec3 &vecToBeRotated, idVec3 &rotateHowMuch);
void Event_IsStringEmpty( const char *checkString );
void Event_AnnounceToAI( const char *announcement);
void Event_ChangeCrossings(const char *originalType, const char *newType);
// abahr: so we can fake having pure script objects
void Event_ReferenceScriptObjectProxy( const char* scriptObjectName );
void Event_ReleaseScriptObjectProxy( const char* proxyName );
void Event_ClampFloat( float min, float max, float val );
void Event_MinFloat( float val1, float val2 );
void Event_MaxFloat( float val1, float val2 );
void Event_StrFind( idStr& sourceStr, idStr& subStr );
void Event_RandomInt( float range ) const;
// rjohnson: new blur special effect
void Event_SetSpecialEffect( int Effect, int Enabled );
void Event_SetSpecialEffectParm( int Effect, int Parm, float Value );
// nmckenzie: string signaling
void Event_PlayWorldEffect( const char *effectName, idVec3 &org, idVec3 &angle );
// asalmon: achievements for Xenon
void Event_AwardAchievement( const char *name);
// twhitaker: ceil, floor and intVal
void Event_GetCeil( float val );
void Event_GetFloor( float val );
void Event_ToInt( float val );
// jdischler: send named event string to specified gui
void Event_SendNamedEvent( int guiEnum, const char *namedEvent );
void Event_BeginManualStreaming( void );
void Event_EndManualStreaming( void );
void Event_SetMatSort( const char *name, const char *val ) const;
// RAVEN END
public:
CLASS_PROTOTYPE( idThread );
idThread();
idThread( idEntity *self, const function_t *func );
idThread( const function_t *func );
idThread( idInterpreter *source, const function_t *func, int args );
idThread( idInterpreter *source, idEntity *self, const function_t *func, int args );
virtual ~idThread();
// tells the thread manager not to delete this thread when it ends
void ManualDelete( void );
// save games
void Save( idSaveGame *savefile ) const; // archives object for save game file
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
void EnableDebugInfo( void ) { interpreter.debug = true; };
void DisableDebugInfo( void ) { interpreter.debug = false; };
void WaitMS( int time );
void WaitSec( float time );
void WaitFrame( void );
// NOTE: If this is called from within a event called by this thread, the function arguments will be invalid after calling this function.
void CallFunction( const function_t *func, bool clearStack );
// NOTE: If this is called from within a event called by this thread, the function arguments will be invalid after calling this function.
void CallFunction( idEntity *obj, const function_t *func, bool clearStack );
// RAVEN BEGIN
// bgeisler: added way to list functions
void ListStates( void );
// abahr: added helper functions for pushing parms onto stack
void ClearStack( void );
void PushInt( int value );
void PushFloat( float value );
void PushVec3( const idVec3& value );
void PushEntity( const idEntity* ent );
void PushString( const char* str );
void PushBool( bool value );
// RAVEN END
void DisplayInfo( void );
static idThread *GetThread( int num );
static void ListThreads_f( const idCmdArgs &args );
static void Restart( void );
static void ObjectMoveDone( int threadnum, idEntity *obj );
static idList<idThread*>& GetThreads( void );
bool IsDoneProcessing( void );
bool IsDying ( void );
void End( void );
static void KillThread( const char *name );
static void KillThread( int num );
bool Execute( void );
void ManualControl( void ) { manualControl = true; CancelEvents( &EV_Thread_Execute ); };
void DoneProcessing( void ) { interpreter.doneProcessing = true; };
void ContinueProcessing( void ) { interpreter.doneProcessing = false; };
bool ThreadDying( void ) { return interpreter.threadDying; };
void EndThread( void ) { interpreter.threadDying = true; };
bool IsWaiting( void );
void ClearWaitFor( void );
bool IsWaitingFor( idEntity *obj );
void ObjectMoveDone( idEntity *obj );
void ThreadCallback( idThread *thread );
void DelayedStart( int delay );
bool Start( void );
idThread *WaitingOnThread( void );
void SetThreadNum( int num );
int GetThreadNum( void );
void SetThreadName( const char *name );
const char *GetThreadName( void );
void Error( const char *fmt, ... ) const;
void Warning( const char *fmt, ... ) const;
static idThread *CurrentThread( void );
static int CurrentThreadNum( void );
static bool BeginMultiFrameEvent( idEntity *ent, const idEventDef *event );
static void EndMultiFrameEvent( idEntity *ent, const idEventDef *event );
static void ReturnString( const char *text );
static void ReturnFloat( float value );
static void ReturnInt( int value );
static void ReturnVector( idVec3 const &vec );
// RAVEN BEGIN
// abahr: added const
static void ReturnEntity( const idEntity *ent );
// RAVEN END
};
/*
================
idThread::WaitingOnThread
================
*/
ID_INLINE idThread *idThread::WaitingOnThread( void ) {
return waitingForThread;
}
/*
================
idThread::SetThreadNum
================
*/
ID_INLINE void idThread::SetThreadNum( int num ) {
threadNum = num;
}
/*
================
idThread::GetThreadNum
================
*/
ID_INLINE int idThread::GetThreadNum( void ) {
return threadNum;
}
/*
================
idThread::GetThreadName
================
*/
ID_INLINE const char *idThread::GetThreadName( void ) {
return threadName.c_str();
}
/*
================
idThread::GetThreads
================
*/
ID_INLINE idList<idThread*>& idThread::GetThreads ( void ) {
return threadList;
}
/*
================
idThread::IsDoneProcessing
================
*/
ID_INLINE bool idThread::IsDoneProcessing ( void ) {
return interpreter.doneProcessing;
}
/*
================
idThread::IsDying
================
*/
ID_INLINE bool idThread::IsDying ( void ) {
return interpreter.threadDying;
}
#endif /* !__SCRIPT_THREAD_H__ */