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