ScummVM API documentation
scene.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 DGDS_SCENE_H
23 #define DGDS_SCENE_H
24 
25 #include "common/stream.h"
26 #include "common/array.h"
27 #include "common/serializer.h"
28 
29 #include "dgds/dialog.h"
30 #include "dgds/dgds_rect.h"
31 #include "dgds/shell_game.h"
32 
33 namespace Dgds {
34 
35 class ResourceManager;
36 class Decompressor;
37 class DgdsFont;
38 
39 enum SceneCondition {
40  kSceneCondNone = 0,
41  kSceneCondLessThan = 1,
42  kSceneCondEqual = 2,
43  kSceneCondNegate = 4,
44  kSceneCondAbsVal = 8,
45  kSceneCondOr = 0x10,
46  kSceneCondNeedItemSceneNum = 0x20,
47  kSceneCondNeedItemQuality = 0x40,
48  kSceneCondSceneState = 0x80
49 };
50 
52 public:
53  SceneConditions(uint16 num, SceneCondition cond, uint16 val) : _num(num), _flags(cond), _val(val) {}
54  Common::String dump(const Common::String &indent) const;
55 
56  uint16 getNum() const { return _num; }
57  SceneCondition getCond() const { return _flags; }
58  uint16 getVal() const { return _val; }
59 
60 private:
61  uint16 _num;
62  SceneCondition _flags; /* eg, see usage in FUN_1f1a_2106 */
63  uint16 _val;
64 };
65 
66 class HotArea {
67 public:
68  DgdsRect _rect;
69  uint16 _num; //
70  uint16 _cursorNum;
71 
72  // Used in Willy Beamish
73  uint16 _otherCursorNum;
74  uint16 _objInteractionListFlag;
75 
76  Common::Array<SceneConditions> enableConditions;
77  Common::Array<SceneOp> onRClickOps;
78  Common::Array<SceneOp> onLDownOps;
79  Common::Array<SceneOp> onLClickOps;
80 
81  virtual ~HotArea() {}
82 
83  virtual Common::String dump(const Common::String &indent) const;
84 };
85 
86 enum SceneOpCode {
87  kSceneOpNone = 0,
88  kSceneOpChangeScene = 1, // args: scene num
89  kSceneOpNoop = 2, // args: none. Maybe should close dialogue?
90  kSceneOpGlobal = 3, // args: array of uints
91  kSceneOpSegmentStateOps = 4, // args: array of uint pairs [op seg, op seg], term with 0,0 that modify segment states
92  kSceneOpSetItemAttr = 5, // args: [item num, item param 0x28, item param 0x2c]. set item attrs?
93  kSceneOpSetDragItem = 6, // args: item num. give item?
94  kSceneOpOpenInventory = 7, // args: none.
95  kSceneOpShowDlg = 8, // args: dialogue number.
96  kSceneOpShowInvButton = 9, // args: none.
97  kSceneOpHideInvButton = 10, // args: none.
98  kSceneOpEnableTrigger = 11, // args: trigger num
99  kSceneOpChangeSceneToStored = 12, // args: none. Change scene to stored number
100  kSceneOpAddFlagToDragItem = 13, // args: none.
101  kSceneOpOpenInventoryZoom = 14, // args: none.
102  kSceneOpMoveItemsBetweenScenes = 15, // args: none.
103  kSceneOpShowClock = 16, // args: none. set clock script-visible.
104  kSceneOpHideClock = 17, // args: none. set clock script-hidden.
105  kSceneOpShowMouse = 18, // args: none.
106  kSceneOpHideMouse = 19, // args: none.
107  // Op 20 onward are common, but not in dragon
108 
109  kSceneOpLoadTalkDataAndSetFlags = 20, // args: tdsnum to load, headnum
110  kSceneOpDrawVisibleTalkHeads = 21, // args: none
111  kSceneOpLoadTalkData = 22, // args: tds num to load
112  kSceneOpLoadDDSData = 24, // args: dds num to load
113  kSceneOpFreeDDSData = 25, // args: dds num to free
114  kSceneOpFreeTalkData = 26, // args: tds num to free
115 
116  // Dragon-specific opcodes
117  kSceneOpPasscode = 100, // args: none.
118  kSceneOpMeanwhile = 101, // args: none. Clears screen and displays "meanwhile".
119  kSceneOpOpenGameOverMenu = 102, // args: none.
120  kSceneOpTiredDialog = 103, // args: none. Something about "boy am I tired"?
121  kSceneOpArcadeTick = 104, // args: none. Called in arcade post-tick.
122  kSceneOpDrawDragonCountdown1 = 105, // args: none. Draw special countdown number at 141, 56
123  kSceneOpDrawDragonCountdown2 = 106, // args: none. Draw some number at 250, 42
124  kSceneOpOpenPlaySkipIntroMenu = 107, // args: none. DRAGON: Show menu 50, the "Play Introduction" / "Skip Introduction" menu.
125  kSceneOpOpenBetterSaveGameMenu = 108, // args: none. DRAGON: Show menu 46, the "Before arcade maybe you better save your game" menu.
126 
127  // China-specific opcodes
128  kSceneOpOpenChinaTankMenu = 102,
129  kSceneOpShellGameEnd = 109,
130  kSceneOpShellGameTick = 110,
131  kSceneOpOpenChinaTrainMenu = 113,
132  kSceneOpOpenChinaOpenGameOverMenu = 114, // args: none.
133  kSceneOpOpenChinaOpenSkipCreditsMenu = 115, // args: none.
134  kSceneOpOpenChinaStartIntro = 116, // args: none.
135  kSceneOpChina117 = 117, // args: none. ??
136  kSceneOpChina118 = 118, // args: none. ??
137 
138  // Beamish-specific opcodes
139  kSceneOpOpenBeamishGameOverMenu = 100,
140  kSceneOpOpenBeamishOpenSkipCreditsMenu = 101,
141 
142  kSceneOpMaxCode = 255, // for checking file load
143 };
144 
145 class SceneOp {
146 public:
147  Common::Array<SceneConditions> _conditionList;
148  Common::Array<uint16> _args;
149  SceneOpCode _opCode;
150 
151  Common::String dump(const Common::String &indent) const;
152 };
153 
155 public:
156  uint _opCode;
157  Common::Array<SceneConditions> _conditionList;
158  Common::Array<SceneOp> _opList;
159 
160  Common::String dump(const Common::String &indent) const;
161 };
162 
163 class GameItem : public HotArea {
164 public:
165  Common::Array<SceneOp> onDragFinishedOps;
166  Common::Array<SceneOp> onBothButtonsOps;
167  uint16 _altCursor;
168  uint16 _iconNum;
169 
170  // mutable values
171  uint16 _inSceneNum;
172  uint16 _flags;
173  uint16 _quality;
174 
175  Common::String dump(const Common::String &indent) const override;
176 };
177 
178 class MouseCursor {
179 public:
180  MouseCursor(uint16 hotX, uint16 hotY) : _hot(hotX, hotY) {}
181 
182  Common::String dump(const Common::String &indent) const;
183 
184  const Common::Point getHot() const { return _hot; }
185 
186 private:
187  Common::Point _hot;
188 };
189 
190 // Interactions between two objects when one is dropped on the other
192 public:
193  ObjectInteraction(uint16 dropped, uint16 target) : _droppedItemNum(dropped), _targetItemNum(target) {}
194 
195  Common::Array<SceneOp> opList;
196 
197  bool matches(uint16 droppedItemNum, uint16 targetItemNum) const {
198  return _droppedItemNum == droppedItemNum && _targetItemNum == targetItemNum;
199  }
200 
201  Common::String dump(const Common::String &indent) const;
202 
203 private:
204  uint16 _droppedItemNum;
205  uint16 _targetItemNum;
206 
207 };
208 
210 public:
211  SceneTrigger(uint16 num) : _num(num), _enabled(false), _timesToCheckBeforeRunning(0) {}
212  Common::String dump(const Common::String &indent) const;
213 
214  Common::Array<SceneConditions> conditionList;
215  Common::Array<SceneOp> sceneOpList;
216 
217  uint16 _timesToCheckBeforeRunning; // Only used in Beamish.
218  bool _enabled;
219  uint16 getNum() const { return _num; }
220 
221 private:
222  uint16 _num;
223 };
224 
225 /* A global value that only applies on a per-SDS-scene,
226  but stays with the GDS data as it sticks around during
227  the game */
229 public:
230  PerSceneGlobal(uint16 num, uint16 scene) : _num(num), _sceneNo(scene), _val(0) {}
231 
232  Common::String dump(const Common::String &indent) const;
233  bool matches(uint16 num, uint16 scene) const { return num == _num && (_sceneNo == 0 || _sceneNo == scene); }
234  bool numMatches(uint16 num) const { return num == _num; }
235 
236  int16 _val;
237 
238 private:
239  // Immutable, read from the data file
240  uint16 _num;
241  uint16 _sceneNo;
242 };
243 
244 
246 public:
247  TalkDataHeadFrame() : _xoff(0), _yoff(0), _frameNo(0) {}
248  Common::String dump(const Common::String &indent) const;
249 
250  uint16 _frameNo;
251  uint16 _xoff;
252  uint16 _yoff;
253 };
254 
255 enum HeadFlags {
256  kHeadFlagNone = 0,
257  kHeadFlag1 = 1,
258  kHeadFlag2 = 2,
259  kHeadFlag4 = 4,
260  kHeadFlag8 = 8,
261  kHeadFlag10 = 0x10,
262  kHeadFlagVisible = 0x20,
263  kHeadFlag40 = 0x40,
264  kHeadFlag80 = 0x80,
265 };
266 
268 public:
269  TalkDataHead() : _num(0), _drawType(0), _drawCol(0), _val3(0), _flags(kHeadFlagNone) {}
270  Common::String dump(const Common::String &indent) const;
271 
272  uint16 _num;
273  uint16 _drawType;
274  uint16 _drawCol;
275  DgdsRect _rect;
277  uint16 _val3;
278  HeadFlags _flags;
279 };
280 
281 class TalkData {
282 public:
283  TalkData() : _num(0), _val(0) {}
284  Common::String dump(const Common::String &indent) const;
285 
286  uint16 _num;
289  uint16 _val;
290  Common::String _bmpFile;
291 };
292 
293 
298 class Scene {
299 public:
300  Scene();
301  virtual ~Scene() {};
302 
303  virtual bool parse(Common::SeekableReadStream *s) = 0;
304 
305  bool isVersionOver(const char *version) const;
306  bool isVersionUnder(const char *version) const;
307 
308  uint32 getMagic() const { return _magic; }
309  const Common::String &getVersion() const { return _version; }
310  bool runPreTickOps() { return runOps(_preTickOps); }
311  bool runPostTickOps() { return runOps(_postTickOps); }
312 
313  bool runOps(const Common::Array<SceneOp> &ops, int16 addMinutes = 0);
314  virtual Common::Error syncState(Common::Serializer &s) = 0;
315  virtual void enableTrigger(uint16 numm, bool enable = true) {}
316 
317 protected:
318  bool readConditionList(Common::SeekableReadStream *s, Common::Array<SceneConditions> &list) const;
319  bool readHotArea(Common::SeekableReadStream *s, HotArea &dst) const;
320  bool readHotAreaList(Common::SeekableReadStream *s, Common::List<HotArea> &list) const;
321  bool readGameItemList(Common::SeekableReadStream *s, Common::Array<GameItem> &list) const;
322  bool readMouseHotspotList(Common::SeekableReadStream *s, Common::Array<MouseCursor> &list) const;
323  bool readObjInteractionList(Common::SeekableReadStream *s, Common::Array<ObjectInteraction> &list) const;
324  bool readOpList(Common::SeekableReadStream *s, Common::Array<SceneOp> &list) const;
325  bool readDialogList(Common::SeekableReadStream *s, Common::Array<Dialog> &list, int16 filenum = 0) const;
326  bool readTriggerList(Common::SeekableReadStream *s, Common::Array<SceneTrigger> &list) const;
327  bool readDialogActionList(Common::SeekableReadStream *s, Common::Array<DialogAction> &list) const;
328  bool readConditionalSceneOpList(Common::SeekableReadStream *s, Common::Array<ConditionalSceneOp> &list) const;
329 
330  bool checkConditions(const Common::Array<SceneConditions> &cond) const;
331 
332  virtual void showDialog(uint16 fileNum, uint16 dlgNum) {}
333  virtual void globalOps(const Common::Array<uint16> &args) {}
334  virtual void segmentStateOps(const Common::Array<uint16> &args);
335 
336  void setItemAttrOp(const Common::Array<uint16> &args);
337  void setDragItemOp(const Common::Array<uint16> &args);
338 
339  bool runSceneOp(const SceneOp &op);
340  bool runDragonOp(const SceneOp &op);
341  bool runChinaOp(const SceneOp &op);
342  bool runBeamishOp(const SceneOp &op);
343 
344  uint32 _magic;
345  Common::String _version;
346 
347  Common::Array<SceneOp> _preTickOps;
348  Common::Array<SceneOp> _postTickOps;
349  Common::Array<ConditionalSceneOp> _conditionalOps; // Beamish only
350 };
351 
352 
353 class GDSScene : public Scene {
354 public:
355  GDSScene();
356 
357  bool load(const Common::String &filename, ResourceManager *resourceManager, Decompressor *decompressor);
358  bool loadRestart(const Common::String &filename, ResourceManager *resourceManager, Decompressor *decompressor);
359  bool parse(Common::SeekableReadStream *s) override;
360  bool parseInf(Common::SeekableReadStream *s);
361  const Common::String &getIconFile() const { return _iconFile; }
362  bool readPerSceneGlobals(Common::SeekableReadStream *s);
363 
364  Common::String dump(const Common::String &indent) const;
365 
366  void runStartGameOps() { runOps(_startGameOps); }
367  void runQuitGameOps() { runOps(_quitGameOps); }
368  void runChangeSceneOps() { runOps(_onChangeSceneOps); }
369  void globalOps(const Common::Array<uint16> &args) override;
370  int16 getGlobal(uint16 num);
371  int16 setGlobal(uint16 num, int16 val);
372 
373  const Common::Array<MouseCursor> &getCursorList() const { return _cursorList; }
374  void drawItems(Graphics::ManagedSurface &surf);
375  Common::Array<GameItem> &getGameItems() { return _gameItems; }
376  int countItemsInScene2() const;
377 
378  const Common::Array<ObjectInteraction> &getObjInteractions1() { return _objInteractions1; }
379  const Common::Array<ObjectInteraction> &getObjInteractions2() { return _objInteractions2; }
380 
381  Common::Error syncState(Common::Serializer &s) override;
382  void initIconSizes();
383  GameItem *getActiveItem();
384 
385  uint16 getDefaultMouseCursor() const { return _defaultMouseCursor; }
386  uint16 getInvIconNum() const { return _invIconNum; }
387  uint16 getInvIconMouseCursor() const { return _invIconMouseCursor; }
388 
389 private:
390  Common::String _iconFile;
391  Common::Array<GameItem> _gameItems;
392  Common::Array<SceneOp> _startGameOps;
393  Common::Array<SceneOp> _quitGameOps;
394  Common::Array<SceneOp> _onChangeSceneOps;
395  Common::Array<MouseCursor> _cursorList;
396  Common::Array<PerSceneGlobal> _perSceneGlobals;
397  Common::Array<ObjectInteraction> _objInteractions2;
398  Common::Array<ObjectInteraction> _objInteractions1;
399 
400  // Additional fields that appear in Willy Beamish (unused in others)
401  uint16 _defaultMouseCursor;
402  uint16 _field3a;
403  uint16 _invIconNum;
404  uint16 _invIconMouseCursor;
405  uint16 _field40;
406 };
407 
408 class SDSScene : public Scene {
409 public:
410  SDSScene();
411 
412  bool load(const Common::String &filename, ResourceManager *resourceManager, Decompressor *decompressor);
413  bool parse(Common::SeekableReadStream *s) override;
414  void unload();
415 
416  const Common::String &getAdsFile() const { return _adsFile; }
417  void runEnterSceneOps() { runOps(_enterSceneOps); }
418  void runLeaveSceneOps() { runOps(_leaveSceneOps); }
419  void checkTriggers();
420 
421  int getNum() const { return _num; }
422  Common::String dump(const Common::String &indent) const;
423 
424  bool checkDialogActive();
425  void drawActiveDialogBgs(Graphics::ManagedSurface *dst);
426  bool drawAndUpdateDialogs(Graphics::ManagedSurface *dst);
427  bool checkForClearedDialogs();
428 
429  void globalOps(const Common::Array<uint16> &args) override;
430 
431  void mouseMoved(const Common::Point &pt);
432  void mouseLDown(const Common::Point &pt);
433  void mouseLUp(const Common::Point &pt);
434  void mouseRDown(const Common::Point &pt);
435  void mouseRUp(const Common::Point &pt);
436 
437  void addInvButtonToHotAreaList();
438  void removeInvButtonFromHotAreaList();
439 
440  const Common::List<HotArea> &getHotAreas() const { return _hotAreaList; }
441 
442  const GameItem *getDragItem() const { return _dragItem; }
443  GameItem *getDragItem() { return _dragItem; }
444  void setDragItem(GameItem *item) { _dragItem = item; }
445 
446  const Common::Array<ObjectInteraction> &getObjInteractions1() { return _objInteractions1; }
447  const Common::Array<ObjectInteraction> &getObjInteractions2() { return _objInteractions2; }
448 
449  bool hasVisibleDialog();
450  bool hasVisibleOrOpeningDialog() const;
451 
452  Common::Error syncState(Common::Serializer &s) override;
453 
454  void onDragFinish(const Common::Point &pt);
455  void enableTrigger(uint16 num, bool enable = true) override;
456 
457  Dialog *loadDialogData(uint16 num);
458  void freeDialogData(uint16 num);
459  bool loadTalkData(uint16 num);
460  void freeTalkData(uint16 num);
461  void updateVisibleTalkers();
462  void loadTalkDataAndSetFlags(uint16 talknum, uint16 headnum);
463  void drawVisibleHeads(Graphics::ManagedSurface *dst);
464 
465  // dragon-specific scene ops
466  void addAndShowTiredDialog();
467  void sceneOpUpdatePasscodeGlobal();
468 
469  void prevChoice();
470  void nextChoice();
471  void activateChoice();
472  bool isTriggerEnabled(uint16 num);
473 
474 protected:
475  HotArea *findAreaUnderMouse(const Common::Point &pt);
476 
477 private:
478  void showDialog(uint16 fileNum, uint16 dlgNum) override;
479  Dialog *getVisibleDialog();
480  bool readTalkData(Common::SeekableReadStream *s, TalkData &dst);
481  void updateHead(TalkDataHead &head);
482  void drawHead(Graphics::ManagedSurface *dst, const TalkData &data, const TalkDataHead &head);
483  void drawHeadType1(Graphics::ManagedSurface *dst, const TalkDataHead &head, const Image &img);
484  void drawHeadType2(Graphics::ManagedSurface *dst, const TalkDataHead &head, const Image &img);
485  void drawHeadType3(Graphics::ManagedSurface *dst, const TalkDataHead &head, const Image &img);
486 
487  int _num;
488  Common::Array<SceneOp> _enterSceneOps;
489  Common::Array<SceneOp> _leaveSceneOps;
490  //uint _field5_0x12;
491  uint _field6_0x14;
492  Common::String _adsFile;
493  //uint _field8_0x23;
494  Common::List<HotArea> _hotAreaList;
495  Common::Array<ObjectInteraction> _objInteractions1;
496  Common::Array<ObjectInteraction> _objInteractions2;
497  //uint _field12_0x2b;
498  //uint _field15_0x33;
499 
500  Common::Array<TalkData> _talkData;
501 
502  // From here on is mutable stuff that might need saving
503  Common::Array<Dialog> _dialogs;
504  Common::Array<SceneTrigger> _triggers;
505 
506  GameItem *_dragItem;
507  bool _shouldClearDlg;
508  bool _ignoreMouseUp;
509  bool _rbuttonDown;
510 
511  static bool _dlgWithFlagLo8IsClosing;
512  static DialogFlags _sceneDialogFlags;
513 };
514 
515 } // End of namespace Dgds
516 
517 #endif // DGDS_SCENE_H
Definition: managed_surface.h:51
Definition: scene.h:66
Definition: str.h:59
Definition: error.h:84
Definition: dialog.h:101
Definition: array.h:52
Definition: scene.h:178
Definition: ads.h:28
Definition: list.h:44
Definition: stream.h:745
Definition: serializer.h:79
Definition: scene.h:51
Definition: scene.h:298
Definition: scene.h:245
Definition: scene.h:281
Definition: scene.h:154
Definition: scene.h:228
Definition: dgds_rect.h:32
Definition: scene.h:408
Definition: scene.h:267
Definition: rect.h:45
Definition: scene.h:209
Definition: scene.h:191
Definition: scene.h:163
Definition: ptr.h:159
Definition: scene.h:353
Definition: movie_decoder.h:32
Definition: scene.h:145
Definition: decompress.h:67
Definition: resource.h:49