1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 *
22 * Based on the original sources
23 * Faery Tale II -- The Halls of the Dead
24 * (c) 1993-1996 The Wyrmkeep Entertainment Co.
25 */
26
27 #ifndef SAGA2_SCRIPT_H
28 #define SAGA2_SCRIPT_H
29
30 #include "saga2/objects.h"
31 #include "saga2/calender.h"
32
33 namespace Saga2 {
34
35 typedef int16 ThreadID;
36
37 // Various result codes returned from runScript
38
39 enum scriptResult {
40
41 // Code returned when attempt to run a non-existant script
42 scriptResultNoScript = 0,
43
44 // Code returned when script was aborted before completion
45 scriptResultAborted,
46
47 // Code returned when script finished
48 scriptResultFinished,
49
50 // Script spun off as async thread; no answer available.
51 scriptResultAsync
52 };
53
54 // Variables specific to a thread
55
56 struct scriptCallFrame {
57
58 // ID of object who's method is being called (which can be the same
59 // as one of the other objects below).
60 ObjectID invokedObject;
61 ActiveItemID invokedTAI;
62
63 // ID of the objects in the interaction.
64 ObjectID enactor, // actor who caused interaction
65 directObject, // the object being acted on
66 indirectObject; // the object being used
67 // with the other one
68 ActiveItemID directTAI, // the tile activity instance
69 // being used
70 indirectTAI; // the tile activity instance
71 // upon which the object is being
72 // used
73
74 int16 responseType; // used with knowledge package
75
76 int16 methodNum; // which method being invoked
77
78 // Misc fields used in passing parameters to scripts.
79 int16 idNum; // a misc. id number
80 int16 value; // a misc. parameter value
81 TilePoint coords; // a misc. tilepoint
82
83 int16 returnVal; // return value of script
84 };
85
86 // Standard return codes from scripts in the "returnVal" field
87
88 enum {
89 // Code returned by script when script decides requested
90 // action is not possible, and the calling C-code should
91 // take action to inform user
92 actionResultFailure = 0,
93
94 // Code returned by script when script completes the action
95 // successfully and C-code should not complete the action
96 actionResultSuccess,
97
98 // Code returned by script when requested action should complete
99 // the action
100 actionResultNotDone
101 };
102
103 // Method used to refer to a SAGA object
104
105 struct SegmentRef {
106 uint16 segment; // segment / resource number
107 uint16 offset; // offset within segment
108 };
109
110 // Segment numbers of "builtin" SAGA data structures,
111 // such as actors and TAGS
112
113 enum builtinTypes {
114 builtinTypeObject = -1,
115 builtinTypeTAG = -2,
116 builtinAbstract = -3,
117 builtinTypeMission = -4
118 };
119
120 /* ===================================================================== *
121 SAGA management functions
122 * ===================================================================== */
123
124 // Load the SAGA data segment from the resource file
125 void initSAGADataSeg(void);
126
127 void saveSAGADataSeg(Common::OutSaveFile *outS);
128 void loadSAGADataSeg(Common::InSaveFile *in);
129
130 // Dispose of the SAGA data segment -- do nothing
cleanupSAGADataSeg(void)131 inline void cleanupSAGADataSeg(void) {}
132
133 /* ===================================================================== *
134 Thread management functions
135 * ===================================================================== */
136
137 class Thread;
138
139 // Initialize the SAGA thread list
140 void initSAGAThreads(void);
141
142 void saveSAGAThreads(Common::OutSaveFile *outS);
143 void loadSAGAThreads(Common::InSaveFile *in, int32 chunkSize);
144
145 // Dispose of the active SAGA threads
146 void cleanupSAGAThreads(void);
147
148 // Dispose of an active SAGA thread
149 void deleteThread(Thread *p);
150
151 void newThread(Thread *p, ThreadID id);
152
153 void newThread(Thread *p);
154
155 // Return the ID of the specified SAGA thread
156 ThreadID getThreadID(Thread *thread);
157
158 // Return a pointer to a SAGA thread, given a thread ID
159 Thread *getThreadAddress(ThreadID id);
160
161 /* ===================================================================== *
162 Class Thread: An execution context of a script
163 * ===================================================================== */
164
165 // A script task is called a thread
166
167 scriptResult runMethod(
168 uint16 scriptClassID, // which script class
169 int16 bType, // builtin type
170 uint16 index, // object index
171 uint16 methodNum, // method number to call
172 scriptCallFrame &args);
173
174 class Thread {
175
176 friend char *STRING(int strNum);
177
178 friend scriptResult runScript(
179 uint16 exportEntryNum, scriptCallFrame &args);
180
181 friend void wakeUpThread(ThreadID, int16);
182
183 public:
184 SegmentRef programCounter; // current PC location
185
186 uint8 *stackPtr; // current stack location
187 byte *codeSeg; // base of current data segment
188 // *stringBase; // base of string resource
189
190 uint8 *stackBase; // base of module stack
191
192 enum threadFlags {
193 waiting = (1 << 0), // thread waiting for event
194 finished = (1 << 1), // thread finished normally
195 aborted = (1 << 2), // thread is aborted
196 extended = (1 << 3), // this is an extended sequence
197 expectResult = (1 << 4), // script is expecting result on stack
198 synchronous = (1 << 5), // when this bit is set this thread will
199 // run until it is finished or this bit
200 // is cleared
201
202 asleep = (waiting | finished | aborted)
203 };
204
205 int16 stackSize, // allocated size of stack
206 flags, // execution flags
207 framePtr, // pointer to call frame
208 returnVal; // return value from ccalls
209
210 bool _valid;
211
212 // Various signals that a script can wait upon
213 enum WaitTypes {
214 waitNone = 0, // waiting for nothing
215 waitDelay, // waiting for a timer
216 waitFrameDelay, // waiting for frame count
217 waitOther, // waiting for to be awoken
218 waitTagSemaphore // waiting for a tag semaphore
219
220 // waitSpeech, // waiting for speech to finish
221 // waitDialogEnd, // waiting for my dialog to finish
222 // waitDialogBegin, // waiting for other dialog to finish
223 // waitWalk, // waiting to finish walking
224 // waitRequest, // a request is up
225 };
226
227 enum WaitTypes waitType; // what we're waiting for
228 union {
229 Alarm waitAlarm; // for time-delay
230 FrameAlarm waitFrameAlarm; // for frame count delay
231 ActiveItem *waitParam; // for other waiting
232 };
233
234 scriptCallFrame threadArgs; // arguments from C to thread
235
236 // For 'cfunc' member functions, the address of the object who's
237 // member function is being invoked.
238 void *thisObject;
239 uint16 argCount; // number of args to cfunc
240
241 // Constructor
242 Thread(uint16 segNum, uint16 segOff, scriptCallFrame &args);
243
244 // Constructor -- reconstruct from archive buffer
245 Thread(void **buf);
246
247 Thread(Common::SeekableReadStream *stream, ThreadID id);
248
249 // Destructor
250 ~Thread();
251
252 // Return the number of bytes need to archive this thread in an
253 // arhive buffer
254 int32 archiveSize(void);
255
256 // Create an archive of this thread in an archive buffer
257 void *archive(void *buf);
258
259 void write(Common::MemoryWriteStreamDynamic *out);
260
261 // Dispatch all asynchronous threads
262 static void dispatch(void);
263
264 // Intepret a single thread
265 scriptResult run(void);
266
267 // Tells thread to wait for an event
waitForEvent(enum WaitTypes wt,ActiveItem * param)268 void waitForEvent(enum WaitTypes wt, ActiveItem *param) {
269 flags |= waiting;
270 waitType = wt;
271 waitParam = param;
272 }
273
274 // Convert to extended script, and back to synchonous script
275 void setExtended(void);
276 void clearExtended(void);
277
278 bool interpret(void);
279 private:
280 uint8 *strAddress(int strNum);
281
282 };
283
284 const int maxTimeSlice = 16, // max instructions per call
285 kStackSize = 512; // thread stack size
286
287 /* ============================================================================ *
288 C-Function dispatch table
289 * ============================================================================ */
290
291 typedef int16 C_Call(int16 *);
292
293 struct CallTable {
294 C_Call **table;
295 uint16 numEntries;
296 uint16 classID;
297 };
298
299 extern CallTable globalCFuncs,
300 actorCFuncs,
301 tagCFuncs,
302 missionCFuncs;
303
304 //extern C_Call *ccall_table[];
305 //extern int16 ccall_count;
306
307 /* ===================================================================== *
308 Externals
309 * ===================================================================== */
310
311 extern Thread *thisThread; // task queue
312
313 // Thread control
314 //void killThread( Thread *th );
315
316 /*
317 void wakeUpActorThread( enum WaitTypes wakeupType, void *obj );
318 void wakeUpThreads( enum WaitTypes wakeupType );
319 void wakeUpThreadsDelayed( enum WaitTypes wakeupType, int newdelay );
320 void abortObjectThreads( Thread *keep, uint16 id );
321 bool abortAllThreads( void );
322 */
323
324 // Run a script function
325 scriptResult runScript(uint16 exportEntryNum, scriptCallFrame &args);
326
327 // Run a script class method.
328 scriptResult runObjectMethod(
329 ObjectID id, uint16 methodNum, scriptCallFrame &args);
330
331 scriptResult runTagMethod(
332 uint16 tagNum, uint16 methodNum, scriptCallFrame &args);
333
334
335 struct ResImportTable {
336 int16 deadActorProto,
337 reserved[2];
338 int16 EXP_spellEffect_CreateFireWisp,
339 EXP_spellEffect_CreateWindWisp,
340 EXP_spellEffect_CreateWraith,
341 EXP_spellEffect_TeleportToShrine,
342 EXP_spellEffect_Rejoin,
343 EXP_spellEffect_Timequake,
344 EXP_spellEffect_CreateFood ;
345 };
346
347 extern ResImportTable *resImports;
348
349 } // end of namespace Saga2
350
351 #endif
352