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 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 
116 public:
117  ScriptManager(AsylumEngine *engine);
118  virtual ~ScriptManager();
119 
125  void load(Common::SeekableReadStream *stream);
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 
165  void resetQueue();
166 
167  // Serializable
168  void saveLoadWithSerializer(Common::Serializer &s);
169  void saveQueue(Common::Serializer &s);
170 
171 private:
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
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;
326  Common::Array<Opcode *> _opcodes;
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
#define ARRAYSIZE(x)
Definition: util.h:114
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:80
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:352
Definition: script.h:115
Definition: func.h:437