OpenMoHAA 0.82.0
Loading...
Searching...
No Matches
scriptvm.h
1/*
2===========================================================================
3Copyright (C) 2023 the OpenMoHAA team
4
5This file is part of OpenMoHAA source code.
6
7OpenMoHAA source code is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 2 of the License,
10or (at your option) any later version.
11
12OpenMoHAA source code is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with OpenMoHAA source code; if not, write to the Free Software
19Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20===========================================================================
21*/
22
23// scriptvm.h: Script virtual machine interpreter.
24
25#pragma once
26
27#include "listener.h"
28
29#include "../fgame/gamescript.h"
30
31#include "scriptvariable.h"
32#include "scriptopcodes.h"
33#include "../qcommon/con_set.h"
34
35#define MAX_STACK_DEPTH 20 // 9 in mohaa
36//#define LOCALSTACK_SIZE 255 // pre-allocated localstack size for each VM
37#define MAX_SCRIPTCYCLES 9999 // max cmds
38
39enum eVMState {
40 STATE_RUNNING, // Running
41 STATE_SUSPENDED, // Suspended
42 STATE_WAITING, // Waiting for something
43 STATE_EXECUTION, // Resume to execution
44 STATE_DESTROYED // Pending deletion
45};
46
47enum eThreadState {
48 THREAD_RUNNING,
49 THREAD_WAITING,
50 THREAD_SUSPENDED
51};
52
53class ScriptException;
54class ScriptThread;
55class ScriptVM;
56
58{
59public:
60 // opcode variable
61 unsigned char *codePos; // opcode will be restored once a DONE was hit
62
63 // stack variables
64 ScriptVariable *localStack;
65 ScriptVariable *pTop;
66
67 // return variable
68 ScriptVariable returnValue;
69
70 // OLD self value
71 SafePtr<Listener> m_Self;
72};
73
75{
76public:
77 ScriptVariable *m_Array;
78 int m_Count;
79};
80
81class ScriptVMStack
82{
83public:
84 ScriptVMStack();
85 ScriptVMStack(size_t stackSize);
86 ~ScriptVMStack();
87
88 ScriptVMStack(const ScriptVMStack& other) = delete;
89 ScriptVMStack& operator=(const ScriptVMStack& other) = delete;
90 ScriptVMStack(ScriptVMStack&& other);
91 ScriptVMStack& operator=(ScriptVMStack&& other);
92
93 size_t GetStackSize() const;
94 ScriptVariable& SetTop(ScriptVariable& newTop);
95 ScriptVariable& GetTop() const;
96 ScriptVariable& GetTop(size_t offset) const;
97 ScriptVariable *GetTopPtr() const;
98 ScriptVariable *GetTopPtr(size_t offset) const;
99 ScriptVariable *GetTopArray(size_t offset = 0) const;
100 uintptr_t GetIndex() const;
101 void MoveTop(ScriptVariable&& other);
102
105 ScriptVariable& Pop(size_t offset);
106 ScriptVariable& PopAndGet();
107 ScriptVariable& PopAndGet(size_t offset);
110 ScriptVariable& Push(size_t offset);
111 ScriptVariable& PushAndGet();
112 ScriptVariable& PushAndGet(size_t offset);
113
114 void Archive(Archiver& arc);
115
116private:
117 void Allocate(size_t stackSize);
118 void Free();
119
120private:
122 ScriptVariable *localStack;
124 ScriptVariable *stackBottom;
126 ScriptVariable* pTop;
127
128public:
132};
133
134class ScriptVM
135{
136 friend class ScriptThread;
137
138public:
139 // important thread variables
140 ScriptVM *next; // next VM in the current ScriptClass
141
142 ScriptThread *m_Thread; // script thread
143 ScriptClass *m_ScriptClass; // current group of threads
144
145public:
146 // return variables
147 ScriptStack *m_Stack; // Currently unused
148 ScriptVMStack m_VMStack;
149 ScriptVariable m_ReturnValue; // VM return value
150
151 // opcode variables
152 unsigned char *m_PrevCodePos; // previous opcode, for use with script exceptions
153 unsigned char *m_CodePos; // check compiler.h for the list of all opcodes
154
155public:
156 // states
157 unsigned char state; // current VM state
158 unsigned char m_ThreadState; // current thread state
159
160 // stack variables
161 Container<ScriptCallStack *> callStack; // thread's call stack
162 ScriptVariable *m_StackPos; // marked stack position
163
164 // parameters variables
165 ScriptVariable *m_pOldData; // old fastEvent data, to cleanup
166 int m_OldDataSize;
167 //bool m_bMarkStack; // changed by OP_MARK_STACK_POS and OP_RESTORE_STACK_POS
168 Event fastEvent; // parameter list, set when the VM is executed
169
170private:
171 void error(const char *format, ...);
172
173 template<bool bMethod = false, bool bReturn = false>
174 void executeCommand(Listener *listener, op_parmNum_t iParamCount, op_evName_t eventnum);
175 template<bool bReturn>
176 void executeCommandInternal(Event& ev, Listener *listener, ScriptVariable *fromVar, op_parmNum_t iParamCount);
177 bool executeGetter(Listener *listener, op_evName_t eventName);
178 bool executeSetter(Listener *listener, op_evName_t eventName);
179 void transferVarsToEvent(Event& ev, ScriptVariable *fromVar, op_parmNum_t count);
180 void checkValidEvent(Event& ev, Listener *listener);
181
182 void loadTopInternal(Listener *listener);
183 ScriptVariable *storeTopInternal(Listener *listener);
184 template<bool noTop = false>
185 void loadTop(Listener *listener);
186 template<bool noTop = false>
187 ScriptVariable *storeTop(Listener *listener);
188 void loadStoreTop(Listener *listener);
189 void skipField();
190
191 void SetFastData(ScriptVariable *data, int dataSize);
192
193 bool Switch(StateScript *stateScript, ScriptVariable& var);
194
195 unsigned char *ProgBuffer();
196 void HandleScriptException(ScriptException& exc);
197
198public:
199 void *operator new(size_t size);
200 void operator delete(void *ptr);
201
202 ScriptVM();
203 ScriptVM(ScriptClass *scriptClass, unsigned char *pCodePos, ScriptThread *thread);
204 ~ScriptVM();
205
206 void Archive(Archiver& arc);
207
208 void EnterFunction(Container<ScriptVariable>&&);
209 void LeaveFunction();
210
211 void End(const ScriptVariable& returnValue);
212 void End(void);
213
214 void Execute(ScriptVariable *data = NULL, int dataSize = 0, str label = "");
215 void NotifyDelete(void);
216 void Resume(qboolean bForce = false);
217 void Suspend(void);
218
219 str Filename(void) const;
220 str Label(void) const;
221 ScriptClass *GetScriptClass(void) const;
222 GameScript *GetScript() const;
223
224 bool IsSuspended(void);
225 int State(void);
226 int ThreadState(void);
227
228 void EventGoto(Event *ev);
229 bool EventThrow(Event *ev);
230
231 bool CanScriptTracePrint(void);
232 void ScriptTrace1() const;
233 void ScriptTrace2() const;
234 const char *GetSourcePos() const;
235
236private:
237 void jump(unsigned int offset);
238 void jumpBack(unsigned int offset);
239 void jumpBool(unsigned int offset, bool booleanValue);
240 bool jumpVar(unsigned int offset, bool booleanValue);
241 void doJumpIf(bool booleanValue);
242 bool doJumpVarIf(bool booleanValue);
243
244 void fetchOpcodeValue(void *outValue, size_t size);
245 void fetchActualOpcodeValue(void *outValue, size_t size);
246
247 template<typename T>
248 T fetchOpcodeValue()
249 {
250 T value;
251 fetchOpcodeValue(&value, sizeof(T));
252 return value;
253 }
254
255 template<typename T>
256 T fetchOpcodeValue(size_t offset)
257 {
258 T value;
259 fetchOpcodeValue(&value, sizeof(T));
260 return value;
261 }
262
263 template<typename T>
264 T fetchActualOpcodeValue()
265 {
266 T value;
267 fetchActualOpcodeValue(&value, sizeof(T));
268 return value;
269 }
270
271 void execCmdCommon(op_parmNum_t param);
272 void execCmdMethodCommon(op_parmNum_t param);
273 void execMethodCommon(op_parmNum_t param);
274 void execFunction(ScriptMaster& Director);
275};
276
277extern MEM_BlockAlloc<ScriptClass> ScriptClass_allocator;
Definition archive.h:86
Definition container.h:85
Definition listener.h:246
Definition gamescript.h:118
Definition listener.h:450
Definition mem_blockalloc.h:172
Definition safeptr.h:160
Definition scriptvm.h:58
Definition scriptclass.h:35
Definition scriptexception.h:30
Definition scriptmaster.h:42
Definition scriptvm.h:75
Definition scriptthread.h:28
Definition scriptvm.h:82
bool m_bMarkStack
Definition scriptvm.h:131
ScriptVariable & Push()
Definition scriptvm.cpp:214
ScriptVariable & Pop()
Definition scriptvm.cpp:191
Definition scriptvm.h:135
Definition scriptvariable.h:75
Definition gamescript.h:83
Definition str.h:77