ScummVM API documentation
script.h
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 modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (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, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#ifndef ASYLUM_RESOURCES_SCRIPT_H
23#define ASYLUM_RESOURCES_SCRIPT_H
24
25#include "common/array.h"
26#include "common/func.h"
27#include "common/serializer.h"
28#include "common/stack.h"
29#include "common/stream.h"
30
31#include "asylum/shared.h"
32
33namespace Asylum {
34
35#define MAX_ACTION_COMMANDS 161
36
37#define DECLARE_OPCODE(name) \
38 void Op##name(ScriptEntry *cmd)
39
40#define IMPLEMENT_OPCODE(name) \
41 void ScriptManager::Op##name(ScriptEntry *cmd) { \
42 if (!_currentScript) error("[" #name "] No current script set"); \
43 if (!_currentQueueEntry) error("[" #name "] Invalid current queue entry"); \
44 if (!cmd) error("[" #name "] Invalid command parameter");
45
46#define END_OPCODE }
47
48
49#define ADD_OPCODE(name) { \
50 Opcode *func = new Opcode(#name, new Common::Functor1Mem<ScriptEntry *, void, ScriptManager>(this, &ScriptManager::Op##name)); \
51 _opcodes.push_back(func); \
52}
53
54class Actor;
55class AsylumEngine;
56class Scene;
57
59 char name[52];
60 int32 id;
61 int32 field01;
62 int32 field02;
63 int32 field_40;
64 int32 field_44;
65 int32 flags;
66 int32 scriptIndex;
67 int32 scriptIndex2;
68 int32 actionType;
69 int32 flagNums[10];
70 int32 field_7C;
71 uint32 polygonIndex;
72 ResourceId walkingSounds[4];
73 ResourceId paletteResourceId;
74 int32 paths[5];
75 int32 volume;
76
77 ActionArea() {
78 memset(&name, 0, sizeof(name));
79 id = 0;
80 field01 = 0;
81 field02 = 0;
82 field_40 = 0;
83 field_44 = 0;
84 flags = 0;
85 scriptIndex = 0;
86 scriptIndex2 = 0;
87 actionType = 0;
88 memset(&flagNums, 0, sizeof(flagNums));
89 field_7C = 0;
90 polygonIndex = 0;
91 memset(&walkingSounds, 0, sizeof(walkingSounds));
92 paletteResourceId = kResourceNone;
93 memset(&paths, 0, sizeof(paths));
94 volume = 0;
95 }
96
97 void load(Common::SeekableReadStream *stream);
98
99 Common::String toString() {
100 Common::String output;
101
102 output += Common::String::format("Action %d: %s\n", id, name);
103 output += Common::String::format(" flags=%d scriptIndex=%d scriptIndex2=%d type=%d\n", flags, scriptIndex, scriptIndex2, actionType);
104 output += Common::String::format(" sound=%d polygon=%d palette=%d volume=%d\n", walkingSounds[2], polygonIndex, paletteResourceId, volume);
105 output += Common::String::format(" field01=%d field02=%d field40=%d field44=%d\n", field01, field02, field_40, field_44);
106 output += Common::String::format(" field7C=%d field84=%d field88=%d field90=%d\n", field_7C, walkingSounds[0], walkingSounds[1], walkingSounds[3]);
107
108 return output;
109 }
110
111 // Serializable
112 void saveLoadWithSerializer(Common::Serializer &s);
113};
114
116public:
118 virtual ~ScriptManager();
119
126
130 bool process();
131
135 void resetAll();
136
140 void reset(uint32 count = 0);
141
146 void queueScript(int32 scriptIndex, ActorIndex actorIndex);
147
155 bool isInQueue(int32 scriptIndex) const;
156
160 void removeFromQueue(uint32 entryIndex);
161
166
167 // Serializable
168 void saveLoadWithSerializer(Common::Serializer &s);
169 void saveQueue(Common::Serializer &s);
170
171private:
172 enum ObjectTransparency {
173 kObjectEnableType0,
174 kObjectEnableType1,
175 kObjectTransparencyOpaque
176 };
177
179 // Script Queue
181 struct ScriptQueueEntry : public Common::Serializable {
182 int32 scriptIndex;
183 int32 currentLine;
184 ActorIndex actorIndex;
185 uint32 next;
186 uint32 prev;
187
188 ScriptQueueEntry() {
189 reset();
190 }
191
192 void reset() {
193 scriptIndex = -1;
194 currentLine = 0;
195 actorIndex = 0;
196 next = 0;
197 prev = 0;
198 }
199
200 void saveLoadWithSerializer(Common::Serializer &s) {
201 s.syncAsSint32LE(scriptIndex);
202 s.syncAsSint32LE(currentLine);
203 s.syncAsUint32LE(actorIndex);
204 s.syncAsUint32LE(next);
205 s.syncAsUint32LE(prev);
206 }
207 };
208
209 struct ScriptQueue : public Common::Serializable {
210 ScriptQueueEntry entries[10];
211 uint32 first;
212 uint32 last;
213
214 ScriptQueue() {
215 reset();
216 }
217
218 void reset() {
219 for (uint32 i = 0; i < ARRAYSIZE(entries); i++)
220 entries[i].reset();
221
222 first = 0;
223 last = 0;
224 }
225
226 void saveLoadWithSerializer(Common::Serializer &s) {
227 for (uint32 i = 0; i < ARRAYSIZE(entries); i++)
228 entries[i].saveLoadWithSerializer(s);
229
230 s.syncAsUint32LE(first);
231 s.syncAsUint32LE(last);
232 }
233 };
234
236 // Scripts
238 struct ScriptEntry : public Common::Serializable {
239 int32 numLines; // Only set on the first line of each script
240 OpcodeType opcode;
241 int32 param1;
242 int32 param2;
243 int32 param3;
244 int32 param4;
245 int32 param5;
246 int32 param6;
247 int32 param7;
248 int32 param8;
249 int32 param9;
250
251 ScriptEntry() {
252 numLines = 0;
253 opcode = kOpcodeReturn;
254 param1 = 0;
255 param2 = 0;
256 param3 = 0;
257 param4 = 0;
258 param5 = 0;
259 param6 = 0;
260 param7 = 0;
261 param8 = 0;
262 param9 = 0;
263 }
264
265 void saveLoadWithSerializer(Common::Serializer &s) {
266 s.syncAsSint32LE(numLines);
267 s.syncAsSint32LE(opcode);
268 s.syncAsSint32LE(param1);
269 s.syncAsSint32LE(param2);
270 s.syncAsSint32LE(param3);
271 s.syncAsSint32LE(param4);
272 s.syncAsSint32LE(param5);
273 s.syncAsSint32LE(param6);
274 s.syncAsSint32LE(param7);
275 s.syncAsSint32LE(param8);
276 s.syncAsSint32LE(param9);
277 }
278 };
279
280 struct Script : public Common::Serializable {
281 ScriptEntry commands[MAX_ACTION_COMMANDS];
282 int32 field_1BAC;
283 int32 field_1BB0;
284 int32 counter;
285
286 Script() {
287 field_1BAC = 0;
288 field_1BB0 = 0;
289 counter = 0;
290 }
291
292 void saveLoadWithSerializer(Common::Serializer &s) {
293 for (int32 i = 0; i < ARRAYSIZE(commands); i++)
294 commands[i].saveLoadWithSerializer(s);
295
296 s.syncAsSint32LE(field_1BAC);
297 s.syncAsSint32LE(field_1BB0);
298 s.syncAsSint32LE(counter);
299 }
300 };
301
303 // Opcodes
305 typedef Common::Functor1<ScriptEntry *, void> OpcodeFunctor;
306
307 struct Opcode {
308 const char *name;
309 OpcodeFunctor *func;
310
311 Opcode(const char *opcodeName, OpcodeFunctor *functor) {
312 name = opcodeName;
313 func = functor;
314 }
315
316 ~Opcode() {
317 delete func;
318 }
319 };
320
321 // Engine
322 AsylumEngine *_vm;
323
324 // Script queue and data
325 ScriptQueue _queue;
327 Common::Array<Script> _scripts;
328
329 bool _done;
330 bool _exit;
331 bool _processNextEntry;
332 ScriptEntry *_lastProcessedCmd; // DEBUGGING
333 Script *_currentScript;
334 ScriptQueueEntry *_currentQueueEntry;
335
336 void patchScriptData();
337
338 // Opcode helper functions
339 void enableObject(ScriptEntry *cmd, ObjectTransparency type);
340 void setActionFlag(ScriptEntry *cmd, ActionType flag); //|
341 void clearActionFlag(ScriptEntry *cmd, ActionType flag); //&
342 void jumpIfActionFlag(ScriptEntry *cmd, ActionType flag);
343 void setNextLine(int32 line);
344
346 // Opcode functions
347 DECLARE_OPCODE(Return);
348 DECLARE_OPCODE(SetGameFlag);
349 DECLARE_OPCODE(ClearGameFlag);
350 DECLARE_OPCODE(ToggleGameFlag);
351 DECLARE_OPCODE(JumpIfGameFlag);
352 DECLARE_OPCODE(HideCursor);
353 DECLARE_OPCODE(ShowCursor);
354 DECLARE_OPCODE(PlayAnimation);
355 DECLARE_OPCODE(MoveScenePosition);
356 DECLARE_OPCODE(HideActor);
357 DECLARE_OPCODE(ShowActor);
358 DECLARE_OPCODE(SetActorPosition);
359 DECLARE_OPCODE(SetSceneMotionStatus);
360 DECLARE_OPCODE(DisableActor);
361 DECLARE_OPCODE(EnableActor);
362 DECLARE_OPCODE(EnableObjects);
363 DECLARE_OPCODE(RemoveObject);
364 DECLARE_OPCODE(JumpActorSpeech);
365 DECLARE_OPCODE(JumpAndSetDirection);
366 DECLARE_OPCODE(JumpIfActorCoordinates);
367 DECLARE_OPCODE(Nop);
368 DECLARE_OPCODE(ResetAnimation);
369 DECLARE_OPCODE(DisableObject);
370 DECLARE_OPCODE(JumpIfSoundPlayingAndPlaySound);
371 DECLARE_OPCODE(JumpIfActionFind);
372 DECLARE_OPCODE(SetActionFind);
373 DECLARE_OPCODE(ClearActionFind);
374 DECLARE_OPCODE(JumpIfActionGrab);
375 DECLARE_OPCODE(SetActionGrab);
376 DECLARE_OPCODE(ClearActionGrab);
377 DECLARE_OPCODE(JumpIfActionTalk);
378 DECLARE_OPCODE(SetActionTalk);
379 DECLARE_OPCODE(ClearActionTalk);
380 DECLARE_OPCODE(AddToInventory);
381 DECLARE_OPCODE(RemoveFromInventory);
382 DECLARE_OPCODE(JumpIfInventoryOmits);
383 DECLARE_OPCODE(RunEncounter);
384 DECLARE_OPCODE(JumpIfAction16);
385 DECLARE_OPCODE(SetAction16);
386 DECLARE_OPCODE(ClearAction16);
387 DECLARE_OPCODE(SelectInventoryItem);
388 DECLARE_OPCODE(JumpIfInventoryItemNotSelected);
389 DECLARE_OPCODE(ChangeScene);
390 DECLARE_OPCODE(Interact);
391 DECLARE_OPCODE(PlayMovie);
392 DECLARE_OPCODE(StopAllObjectsSounds);
393 DECLARE_OPCODE(StopProcessing);
394 DECLARE_OPCODE(ResumeProcessing);
395 DECLARE_OPCODE(ResetSceneRect);
396 DECLARE_OPCODE(ChangeMusicById);
397 DECLARE_OPCODE(StopMusic);
398 DECLARE_OPCODE(IncrementParam1);
399 DECLARE_OPCODE(SetVolume);
400 DECLARE_OPCODE(Jump);
401 DECLARE_OPCODE(RunPuzzle);
402 DECLARE_OPCODE(JumpIfAction8);
403 DECLARE_OPCODE(SetAction8);
404 DECLARE_OPCODE(ClearAction8);
405 DECLARE_OPCODE(CreatePalette);
406 DECLARE_OPCODE(IncrementParam2);
407 DECLARE_OPCODE(WaitUntilFramePlayed);
408 DECLARE_OPCODE(UpdateWideScreen);
409 DECLARE_OPCODE(JumpIfActor);
410 DECLARE_OPCODE(PlaySpeechScene);
411 DECLARE_OPCODE(PlaySpeech);
412 DECLARE_OPCODE(PlaySpeechScene2);
413 DECLARE_OPCODE(MoveScenePositionFromActor);
414 DECLARE_OPCODE(PaletteFade);
415 DECLARE_OPCODE(QueuePaletteFade);
416 DECLARE_OPCODE(PlaySoundUpdateObject);
417 DECLARE_OPCODE(ActorFaceTarget);
418 DECLARE_OPCODE(HideMatteBars);
419 DECLARE_OPCODE(ShowMatteBars);
420 DECLARE_OPCODE(JumpIfSoundPlaying);
421 DECLARE_OPCODE(ChangePlayer);
422 DECLARE_OPCODE(ChangeActorStatus);
423 DECLARE_OPCODE(StopSound);
424 DECLARE_OPCODE(JumpRandom);
425 DECLARE_OPCODE(ClearScreen);
426 DECLARE_OPCODE(Quit);
427 DECLARE_OPCODE(JumpObjectFrame);
428 DECLARE_OPCODE(DeleteGraphics);
429 DECLARE_OPCODE(SetActorField944);
430 DECLARE_OPCODE(SetScriptField1BB0);
431 DECLARE_OPCODE(OnScriptField1BB0);
432 DECLARE_OPCODE(WalkToActor);
433 DECLARE_OPCODE(SetResourcePalette);
434 DECLARE_OPCODE(SetObjectFrameIndexAndFlags);
435 DECLARE_OPCODE(SetObjectFlags);
436 DECLARE_OPCODE(SetActorActionIndex2);
437 DECLARE_OPCODE(UpdateTransparency);
438 DECLARE_OPCODE(QueueScript);
439 DECLARE_OPCODE(ProcessActor);
440 DECLARE_OPCODE(ClearActorFields);
441 DECLARE_OPCODE(SetObjectLastFrameIndex);
442 DECLARE_OPCODE(SetActionAreaFlags);
443 DECLARE_OPCODE(MorphActor);
444 DECLARE_OPCODE(ShowMenu);
445 DECLARE_OPCODE(UpdateGlobalFlags);
446
447 friend class Console;
448}; // end of class ActionList
449
450} // end of namespace Asylum
451
452#endif // ASYLUM_RESOURCES_SCRIPT_H
Definition: asylum.h:73
Definition: script.h:115
bool isInQueue(int32 scriptIndex) const
void queueScript(int32 scriptIndex, ActorIndex actorIndex)
void removeFromQueue(uint32 entryIndex)
void load(Common::SeekableReadStream *stream)
void reset(uint32 count=0)
Definition: stream.h:745
Definition: serializer.h:352
Definition: serializer.h:80
Definition: str.h:59
static String format(MSVC_PRINTF const char *fmt,...) GCC_PRINTF(1
#define ARRAYSIZE(x)
Definition: util.h:114
Definition: script.h:58
int32 actionType
flag (see ActionType enumeration)
Definition: script.h:68
Definition: func.h:437