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/head.h"
31 #include "dgds/dgds_rect.h"
32 #include "dgds/minigames/shell_game.h"
33 #include "dgds/scene_condition.h"
34 #include "dgds/scene_op.h"
35 
36 namespace Dgds {
37 
38 class ResourceManager;
39 class Decompressor;
40 class DgdsFont;
41 class SoundRaw;
42 class TTMInterpreter;
43 class TTMEnviro;
44 
45 
46 class HotArea {
47 public:
48  DgdsRect _rect;
49  uint16 _num; //
50  uint16 _cursorNum;
51 
52  // Used in Willy Beamish
53  uint16 _cursorNum2;
54  uint16 _objInteractionRectNum;
55 
56  Common::Array<SceneConditions> enableConditions;
57  Common::Array<SceneOp> onRClickOps;
58  Common::Array<SceneOp> onLDownOps;
59  Common::Array<SceneOp> onLClickOps;
60 
61  virtual ~HotArea() {}
62 
63  virtual Common::String dump(const Common::String &indent) const;
64 };
65 
66 class DynamicRect {
67 public:
68  DynamicRect() : _num(0) {};
69  uint16 _num;
70  DgdsRect _rect;
71 };
72 
73 
74 class GameItem : public HotArea {
75 public:
76  Common::Array<SceneOp> onDragFinishedOps;
77  Common::Array<SceneOp> onBothButtonsOps;
78  uint16 _altCursor;
79  uint16 _iconNum;
80 
81  // mutable values
82  uint16 _inSceneNum;
83  uint16 _flags;
84  uint16 _quality;
85 
86  Common::String dump(const Common::String &indent) const override;
87 };
88 
89 class MouseCursor {
90 public:
91  MouseCursor(uint16 hotX, uint16 hotY) : _hot(hotX, hotY) {}
92 
93  Common::String dump(const Common::String &indent) const;
94 
95  const Common::Point getHot() const { return _hot; }
96 
97 private:
98  Common::Point _hot;
99 };
100 
101 // Interactions between two objects when one is dropped on the other
103 public:
104  ObjectInteraction(uint16 dropped, uint16 target) : _droppedItemNum(dropped), _targetItemNum(target) {}
105 
106  Common::Array<SceneOp> opList;
107 
108  bool matches(uint16 droppedItemNum, uint16 targetItemNum) const {
109  return (_droppedItemNum == 0xFFFF || _droppedItemNum == droppedItemNum)
110  && _targetItemNum == targetItemNum;
111  }
112 
113  Common::String dump(const Common::String &indent) const;
114 
115 private:
116  uint16 _droppedItemNum;
117  uint16 _targetItemNum;
118 
119 };
120 
122 public:
123  SceneTrigger(uint16 num) : _num(num), _enabled(false), _timesToCheckBeforeRunning(0) {}
124  Common::String dump(const Common::String &indent) const;
125 
126  Common::Array<SceneConditions> conditionList;
127  Common::Array<SceneOp> sceneOpList;
128 
129  uint16 _timesToCheckBeforeRunning; // Only used in Beamish.
130  bool _enabled;
131  uint16 getNum() const { return _num; }
132 
133 private:
134  uint16 _num;
135 };
136 
137 /* A global value that only applies on a per-SDS-scene,
138  but stays with the GDS data as it sticks around during
139  the game */
141 public:
142  PerSceneGlobal(uint16 num, uint16 scene) : _num(num), _sceneNo(scene), _val(0) {}
143 
144  Common::String dump(const Common::String &indent) const;
145  bool matches(uint16 num, uint16 scene) const { return num == _num && (_sceneNo == 0 || _sceneNo == scene); }
146  bool numMatches(uint16 num) const { return num == _num; }
147 
148  int16 _val;
149 
150 private:
151  // Immutable, read from the data file
152  uint16 _num;
153  uint16 _sceneNo;
154 };
155 
156 
161 class Scene {
162 public:
163  Scene();
164  virtual ~Scene() {};
165 
166  virtual bool parse(Common::SeekableReadStream *s) = 0;
167 
168  bool isVersionOver(const char *version) const;
169  bool isVersionUnder(const char *version) const;
170 
171  uint32 getMagic() const { return _magic; }
172  const Common::String &getVersion() const { return _version; }
173 
174  bool runPreTickOps() { return runOps(_preTickOps); }
175  bool runPostTickOps() { return runOps(_postTickOps); }
176 
177  static bool runOps(const Common::Array<SceneOp> ops, int16 addMinutes = 0);
178 
179  virtual Common::Error syncState(Common::Serializer &s) = 0;
180 
181  // These are all static as they are potentially run over scene changes.
182  static bool checkConditions(const Common::Array<SceneConditions> &cond);
183 
184  static void segmentStateOps(const Common::Array<uint16> &args);
185  static void setItemAttrOp(const Common::Array<uint16> &args);
186  static void setDragItemOp(const Common::Array<uint16> &args);
187 
188 protected:
189  bool readConditionList(Common::SeekableReadStream *s, Common::Array<SceneConditions> &list) const;
190  bool readHotArea(Common::SeekableReadStream *s, HotArea &dst) const;
191  bool readHotAreaList(Common::SeekableReadStream *s, Common::List<HotArea> &list) const;
192  bool readGameItemList(Common::SeekableReadStream *s, Common::Array<GameItem> &list) const;
193  bool readMouseHotspotList(Common::SeekableReadStream *s, Common::Array<MouseCursor> &list) const;
194  bool readObjInteractionList(Common::SeekableReadStream *s, Common::Array<ObjectInteraction> &list) const;
195  bool readOpList(Common::SeekableReadStream *s, Common::Array<SceneOp> &list) const;
196  bool readDialogList(Common::SeekableReadStream *s, Common::Array<Dialog> &list, int16 filenum = 0) const;
197  bool readTriggerList(Common::SeekableReadStream *s, Common::Array<SceneTrigger> &list) const;
198  bool readDialogActionList(Common::SeekableReadStream *s, Common::Array<DialogAction> &list) const;
199  bool readConditionalSceneOpList(Common::SeekableReadStream *s, Common::Array<ConditionalSceneOp> &list) const;
200 
201  uint32 _magic;
202  Common::String _version;
203 
204  Common::Array<SceneOp> _preTickOps;
205  Common::Array<SceneOp> _postTickOps;
206  Common::Array<ConditionalSceneOp> _conditionalOps; // Beamish only
207 };
208 
209 
210 class GDSScene : public Scene {
211 public:
212  GDSScene();
213 
214  bool load(const Common::String &filename, ResourceManager *resourceManager, Decompressor *decompressor);
215  bool loadRestart(const Common::String &filename, ResourceManager *resourceManager, Decompressor *decompressor);
216  bool parse(Common::SeekableReadStream *s) override;
217  bool parseInf(Common::SeekableReadStream *s);
218  const Common::String &getIconFile() const { return _iconFile; }
219  bool readPerSceneGlobals(Common::SeekableReadStream *s);
220 
221  Common::String dump(const Common::String &indent) const;
222 
223  void runStartGameOps() { runOps(_startGameOps); }
224  void runQuitGameOps() { runOps(_quitGameOps); }
225  void runChangeSceneOps() { runOps(_onChangeSceneOps); }
226  void globalOps(const Common::Array<uint16> &args);
227  int16 getGlobal(uint16 num) const;
228  int16 setGlobal(uint16 num, int16 val);
229 
230  const Common::Array<MouseCursor> &getCursorList() const { return _cursorList; }
231  void drawItems(Graphics::ManagedSurface &surf);
232  Common::Array<GameItem> &getGameItems() { return _gameItems; }
233  int countItemsInInventory() const;
234 
235  const Common::Array<ObjectInteraction> &getObjInteractions1() { return _objInteractions1; }
236  const Common::Array<ObjectInteraction> &getObjInteractions2() { return _objInteractions2; }
237 
238  Common::Error syncState(Common::Serializer &s) override;
239  void initIconSizes();
240  GameItem *getActiveItem();
241 
242  int16 getDefaultMouseCursor() const { return _defaultMouseCursor; }
243  int16 getDefaultMouseCursor2() const { return _defaultMouseCursor2; }
244  int16 getOtherDefaultMouseCursor() const { return _defaultOtherMouseCursor; }
245  uint16 getInvIconNum() const { return _invIconNum; }
246  int16 getInvIconMouseCursor() const { return _invIconMouseCursor; }
247 
248 private:
249  Common::String _iconFile;
250  Common::Array<GameItem> _gameItems;
251  Common::Array<SceneOp> _startGameOps;
252  Common::Array<SceneOp> _quitGameOps;
253  Common::Array<SceneOp> _onChangeSceneOps;
254  Common::Array<MouseCursor> _cursorList;
255  Common::Array<PerSceneGlobal> _perSceneGlobals;
256  Common::Array<ObjectInteraction> _objInteractions2;
257  Common::Array<ObjectInteraction> _objInteractions1;
258 
259  // Additional fields that appear in Willy Beamish (unused in others)
260  int16 _defaultMouseCursor;
261  int16 _defaultMouseCursor2;
262  uint16 _invIconNum;
263  int16 _invIconMouseCursor;
264  int16 _defaultOtherMouseCursor;
265 };
266 
267 class SDSScene : public Scene {
268 public:
269  SDSScene();
270 
271  bool load(const Common::String &filename, ResourceManager *resourceManager, Decompressor *decompressor);
272  bool parse(Common::SeekableReadStream *s) override;
273  void unload();
274 
275  const Common::String &getAdsFile() const { return _adsFile; }
276  void runEnterSceneOps() { runOps(_enterSceneOps); }
277  void runLeaveSceneOps() { runOps(_leaveSceneOps); }
278  void checkTriggers();
279 
280  int getNum() const { return _num; }
281  Common::String dump(const Common::String &indent) const;
282 
283  bool checkDialogActive();
284  void drawActiveDialogBgs(Graphics::ManagedSurface *dst);
285  bool drawAndUpdateDialogs(Graphics::ManagedSurface *dst);
286  bool checkForClearedDialogs();
287 
288  void mouseMoved(const Common::Point &pt);
289  void mouseLDown(const Common::Point &pt);
290  void mouseLUp(const Common::Point &pt);
291  void mouseRDown(const Common::Point &pt);
292  void mouseRUp(const Common::Point &pt);
293 
294  void addInvButtonToHotAreaList();
295  void removeInvButtonFromHotAreaList();
296 
297  const Common::List<HotArea> &getHotAreas() const { return _hotAreaList; }
298 
299  const GameItem *getDragItem() const { return _dragItem; }
300  GameItem *getDragItem() { return _dragItem; }
301  void setDragItem(GameItem *item) { _dragItem = item; }
302 
303  const Common::Array<ObjectInteraction> &getObjInteractions1() { return _objInteractions1; }
304  const Common::Array<ObjectInteraction> &getObjInteractions2() { return _objInteractions2; }
305 
306  bool hasVisibleDialog();
307  bool hasVisibleOrOpeningDialog() const;
308 
309  Common::Error syncState(Common::Serializer &s) override;
310 
311  void onDragFinish(const Common::Point &pt);
312  void enableTrigger(uint16 num, bool enable = true);
313 
314  Dialog *loadDialogData(uint16 num);
315  void freeDialogData(uint16 num);
316  bool loadTalkData(uint16 num);
317  void freeTalkData(uint16 num);
318  void updateVisibleTalkers();
319  void loadTalkDataAndSetFlags(uint16 talknum, uint16 headnum);
320  void drawVisibleHeads(Graphics::ManagedSurface *dst);
321  bool hasVisibleHead() const;
322 
323  // dragon-specific scene ops
324  void addAndShowTiredDialog();
325 
326  void prevChoice();
327  void nextChoice();
328  void activateChoice();
329  bool isTriggerEnabled(uint16 num);
330  bool isLButtonDown() const { return _lbuttonDown; }
331  bool isRButtonDown() const { return _rbuttonDown; }
332  void showDialog(uint16 fileNum, uint16 dlgNum);
333  const Common::Array<ConditionalSceneOp> &getConditionalOps() { return _conditionalOps; }
334  void updateHotAreasFromDynamicRects();
335  void setDynamicSceneRect(int16 num, int16 x, int16 y, int16 width, int16 height);
336  void setSceneNum(int16 num) { _num = num; }
337 
338 protected:
339  HotArea *findAreaUnderMouse(const Common::Point &pt);
340 
341 private:
342  Dialog *getVisibleDialog();
343  bool readTalkData(Common::SeekableReadStream *s, TalkData &dst);
344 
345  int _num;
346  Common::Array<SceneOp> _enterSceneOps;
347  Common::Array<SceneOp> _leaveSceneOps;
348  //uint _field5_0x12;
349  uint _field6_0x14;
350  Common::String _adsFile;
351  //uint _field8_0x23;
352  Common::List<HotArea> _hotAreaList;
353  Common::Array<ObjectInteraction> _objInteractions1;
354  Common::Array<ObjectInteraction> _objInteractions2;
355  Common::Array<DynamicRect> _dynamicRects; // Only used in Willy Beamish
356  //uint _field12_0x2b;
357  //uint _field15_0x33;
358 
359  Common::Array<TalkData> _talkData;
360 
361  // From here on is mutable stuff that might need saving
362  Common::Array<Dialog> _dialogs;
363  Common::Array<SceneTrigger> _triggers;
364  Conversation _conversation;
365 
366  GameItem *_dragItem;
367  bool _shouldClearDlg;
368  bool _ignoreMouseUp;
369  bool _lbuttonDown;
370  bool _rbuttonDown;
371 
372  static bool _dlgWithFlagLo8IsClosing;
373  static DialogFlags _sceneDialogFlags;
374 };
375 
376 } // End of namespace Dgds
377 
378 #endif // DGDS_SCENE_H
Definition: managed_surface.h:51
Definition: scene.h:46
Definition: str.h:59
Definition: error.h:84
Definition: dialog.h:102
Definition: array.h:52
Definition: scene.h:89
Definition: ads.h:28
Definition: list.h:44
Definition: stream.h:745
Definition: serializer.h:79
Definition: scene.h:161
Definition: head.h:92
Definition: scene.h:140
Definition: dgds_rect.h:32
Definition: scene.h:66
Definition: scene.h:267
Definition: rect.h:45
Definition: head.h:109
Definition: scene.h:121
Definition: scene.h:102
Definition: scene.h:74
Definition: scene.h:210
Definition: decompress.h:67
Definition: resource.h:49