2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 In addition, the Doom 3 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 Source Code. If not, please request a copy in writing from id Software at the address below.
24 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.
26 ===========================================================================
29 #ifndef __SCRIPT_INTERPRETER_H__
30 #define __SCRIPT_INTERPRETER_H__
32 #define MAX_STACK_DEPTH 64
33 #define LOCALSTACK_SIZE 6144
35 typedef struct prstack_s {
43 prstack_t callStack[ MAX_STACK_DEPTH ];
47 byte localstack[ LOCALSTACK_SIZE ];
50 int maxLocalstackUsed;
52 const function_t *currentFunction;
53 int instructionPointer;
56 const idEventDef *multiFrameEvent;
57 idEntity *eventEntity;
61 void PopParms( int numParms );
62 void PushString( const char *string );
63 void Push( int value );
64 const char *FloatToString( float value );
65 void AppendString( idVarDef *def, const char *from );
66 void SetString( idVarDef *def, const char *from );
67 const char *GetString( idVarDef *def );
68 varEval_t GetVariable( idVarDef *def );
69 idEntity *GetEntity( int entnum ) const;
70 idScriptObject *GetScriptObject( int entnum ) const;
71 void NextInstruction( int position );
73 void LeaveFunction( idVarDef *returnDef );
74 void CallEvent( const function_t *func, int argsize );
75 void CallSysEvent( const function_t *func, int argsize );
86 void Save( idSaveGame *savefile ) const; // archives object for save game file
87 void Restore( idRestoreGame *savefile ); // unarchives object from save game file
89 void SetThread( idThread *pThread );
91 void StackTrace( void ) const;
93 int CurrentLine( void ) const;
94 const char *CurrentFile( void ) const;
96 void Error( char *fmt, ... ) const id_attribute((format(printf,2,3)));
97 void Warning( char *fmt, ... ) const id_attribute((format(printf,2,3)));
98 void DisplayInfo( void ) const;
100 bool BeginMultiFrameEvent( idEntity *ent, const idEventDef *event );
101 void EndMultiFrameEvent( idEntity *ent, const idEventDef *event );
102 bool MultiFrameEventInProgress( void ) const;
104 void ThreadCall( idInterpreter *source, const function_t *func, int args );
105 void EnterFunction( const function_t *func, bool clearStack );
106 void EnterObjectFunction( idEntity *self, const function_t *func, bool clearStack );
108 bool Execute( void );
111 bool GetRegisterValue( const char *name, idStr &out, int scopeDepth );
112 int GetCallstackDepth( void ) const;
113 const prstack_t *GetCallstack( void ) const;
114 const function_t *GetCurrentFunction( void ) const;
115 idThread *GetThread( void ) const;
121 idInterpreter::PopParms
124 ID_INLINE void idInterpreter::PopParms( int numParms ) {
125 // pop our parms off the stack
126 if ( localstackUsed < numParms ) {
127 Error( "locals stack underflow\n" );
130 localstackUsed -= numParms;
138 ID_INLINE void idInterpreter::Push( int value ) {
139 if ( localstackUsed + sizeof( int ) > LOCALSTACK_SIZE ) {
140 Error( "Push: locals stack overflow\n" );
142 *( int * )&localstack[ localstackUsed ] = value;
143 localstackUsed += sizeof( int );
148 idInterpreter::PushString
151 ID_INLINE void idInterpreter::PushString( const char *string ) {
152 if ( localstackUsed + MAX_STRING_LEN > LOCALSTACK_SIZE ) {
153 Error( "PushString: locals stack overflow\n" );
155 idStr::Copynz( ( char * )&localstack[ localstackUsed ], string, MAX_STRING_LEN );
156 localstackUsed += MAX_STRING_LEN;
161 idInterpreter::FloatToString
164 ID_INLINE const char *idInterpreter::FloatToString( float value ) {
165 static char text[ 32 ];
167 if ( value == ( float )( int )value ) {
168 sprintf( text, "%d", ( int )value );
170 sprintf( text, "%f", value );
177 idInterpreter::AppendString
180 ID_INLINE void idInterpreter::AppendString( idVarDef *def, const char *from ) {
181 if ( def->initialized == idVarDef::stackVariable ) {
182 idStr::Append( ( char * )&localstack[ localstackBase + def->value.stackOffset ], MAX_STRING_LEN, from );
184 idStr::Append( def->value.stringPtr, MAX_STRING_LEN, from );
190 idInterpreter::SetString
193 ID_INLINE void idInterpreter::SetString( idVarDef *def, const char *from ) {
194 if ( def->initialized == idVarDef::stackVariable ) {
195 idStr::Copynz( ( char * )&localstack[ localstackBase + def->value.stackOffset ], from, MAX_STRING_LEN );
197 idStr::Copynz( def->value.stringPtr, from, MAX_STRING_LEN );
203 idInterpreter::GetString
206 ID_INLINE const char *idInterpreter::GetString( idVarDef *def ) {
207 if ( def->initialized == idVarDef::stackVariable ) {
208 return ( char * )&localstack[ localstackBase + def->value.stackOffset ];
210 return def->value.stringPtr;
216 idInterpreter::GetVariable
219 ID_INLINE varEval_t idInterpreter::GetVariable( idVarDef *def ) {
220 if ( def->initialized == idVarDef::stackVariable ) {
222 val.intPtr = ( int * )&localstack[ localstackBase + def->value.stackOffset ];
231 idInterpreter::GetEntity
234 ID_INLINE idEntity *idInterpreter::GetEntity( int entnum ) const{
235 assert( entnum <= MAX_GENTITIES );
236 if ( ( entnum > 0 ) && ( entnum <= MAX_GENTITIES ) ) {
237 return gameLocal.entities[ entnum - 1 ];
244 idInterpreter::GetScriptObject
247 ID_INLINE idScriptObject *idInterpreter::GetScriptObject( int entnum ) const {
250 assert( entnum <= MAX_GENTITIES );
251 if ( ( entnum > 0 ) && ( entnum <= MAX_GENTITIES ) ) {
252 ent = gameLocal.entities[ entnum - 1 ];
253 if ( ent && ent->scriptObject.data ) {
254 return &ent->scriptObject;
262 idInterpreter::NextInstruction
265 ID_INLINE void idInterpreter::NextInstruction( int position ) {
266 // Before we execute an instruction, we increment instructionPointer,
267 // therefore we need to compensate for that here.
268 instructionPointer = position - 1;
271 #endif /* !__SCRIPT_INTERPRETER_H__ */