]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/d3xp/script/Script_Interpreter.h
hello world
[icculus/iodoom3.git] / neo / d3xp / script / Script_Interpreter.h
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
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.
13
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.
18
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/>.
21
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.
23
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.
25
26 ===========================================================================
27 */
28
29 #ifndef __SCRIPT_INTERPRETER_H__
30 #define __SCRIPT_INTERPRETER_H__
31
32 #define MAX_STACK_DEPTH         64
33 #define LOCALSTACK_SIZE         6144
34
35 typedef struct prstack_s {
36         int                             s;
37         const function_t        *f;
38         int                             stackbase;
39 } prstack_t;
40
41 class idInterpreter {
42 private:
43         prstack_t                       callStack[ MAX_STACK_DEPTH ];
44         int                             callStackDepth;
45         int                             maxStackDepth;
46
47         byte                            localstack[ LOCALSTACK_SIZE ];
48         int                             localstackUsed;
49         int                             localstackBase;
50         int                             maxLocalstackUsed;
51
52         const function_t        *currentFunction;
53         int                             instructionPointer;
54
55         int                                     popParms;
56         const idEventDef        *multiFrameEvent;
57         idEntity                        *eventEntity;
58
59         idThread                        *thread;
60
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 );
72
73         void                            LeaveFunction( idVarDef *returnDef );
74         void                            CallEvent( const function_t *func, int argsize );
75         void                            CallSysEvent( const function_t *func, int argsize );
76
77 public:
78         bool                            doneProcessing;
79         bool                            threadDying;
80         bool                            terminateOnExit;
81         bool                            debug;
82
83                                                 idInterpreter();
84
85         // save games
86         void                            Save( idSaveGame *savefile ) const;                             // archives object for save game file
87         void                            Restore( idRestoreGame *savefile );                             // unarchives object from save game file
88
89         void                            SetThread( idThread *pThread );
90
91         void                            StackTrace( void ) const;
92
93         int                                     CurrentLine( void ) const;
94         const char                      *CurrentFile( void ) const;
95
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;
99
100         bool                            BeginMultiFrameEvent( idEntity *ent, const idEventDef *event );
101         void                            EndMultiFrameEvent( idEntity *ent, const idEventDef *event );
102         bool                            MultiFrameEventInProgress( void ) const;
103
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 );
107
108         bool                            Execute( void );
109         void                            Reset( void );
110
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;
116
117 };
118
119 /*
120 ====================
121 idInterpreter::PopParms
122 ====================
123 */
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" );
128         }
129
130         localstackUsed -= numParms;
131 }
132
133 /*
134 ====================
135 idInterpreter::Push
136 ====================
137 */
138 ID_INLINE void idInterpreter::Push( int value ) {
139         if ( localstackUsed + sizeof( int ) > LOCALSTACK_SIZE ) {
140                 Error( "Push: locals stack overflow\n" );
141         }
142         *( int * )&localstack[ localstackUsed ] = value;
143         localstackUsed += sizeof( int );
144 }
145
146 /*
147 ====================
148 idInterpreter::PushString
149 ====================
150 */
151 ID_INLINE void idInterpreter::PushString( const char *string ) {
152         if ( localstackUsed + MAX_STRING_LEN > LOCALSTACK_SIZE ) {
153                 Error( "PushString: locals stack overflow\n" );
154         }
155         idStr::Copynz( ( char * )&localstack[ localstackUsed ], string, MAX_STRING_LEN );
156         localstackUsed += MAX_STRING_LEN;
157 }
158
159 /*
160 ====================
161 idInterpreter::FloatToString
162 ====================
163 */
164 ID_INLINE const char *idInterpreter::FloatToString( float value ) {
165         static char     text[ 32 ];
166
167         if ( value == ( float )( int )value ) {
168                 sprintf( text, "%d", ( int )value );
169         } else {
170                 sprintf( text, "%f", value );
171         }
172         return text;
173 }
174
175 /*
176 ====================
177 idInterpreter::AppendString
178 ====================
179 */
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 );
183         } else {
184                 idStr::Append( def->value.stringPtr, MAX_STRING_LEN, from );
185         }
186 }
187
188 /*
189 ====================
190 idInterpreter::SetString
191 ====================
192 */
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 );
196         } else {
197                 idStr::Copynz( def->value.stringPtr, from, MAX_STRING_LEN );
198         }
199 }
200
201 /*
202 ====================
203 idInterpreter::GetString
204 ====================
205 */
206 ID_INLINE const char *idInterpreter::GetString( idVarDef *def ) {
207         if ( def->initialized == idVarDef::stackVariable ) {
208                 return ( char * )&localstack[ localstackBase + def->value.stackOffset ];
209         } else {
210                 return def->value.stringPtr;
211         }
212 }
213
214 /*
215 ====================
216 idInterpreter::GetVariable
217 ====================
218 */
219 ID_INLINE varEval_t idInterpreter::GetVariable( idVarDef *def ) {
220         if ( def->initialized == idVarDef::stackVariable ) {
221                 varEval_t val;
222                 val.intPtr = ( int * )&localstack[ localstackBase + def->value.stackOffset ];
223                 return val;
224         } else {
225                 return def->value;
226         }
227 }
228
229 /*
230 ================
231 idInterpreter::GetEntity
232 ================
233 */
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 ];
238         }
239         return NULL;
240 }
241
242 /*
243 ================
244 idInterpreter::GetScriptObject
245 ================
246 */
247 ID_INLINE idScriptObject *idInterpreter::GetScriptObject( int entnum ) const {
248         idEntity *ent;
249
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;
255                 }
256         }
257         return NULL;
258 }
259
260 /*
261 ====================
262 idInterpreter::NextInstruction
263 ====================
264 */
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;
269 }
270
271 #endif /* !__SCRIPT_INTERPRETER_H__ */