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