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 enum GameItemState {
75  kItemStateDragging = 1,
76  kItemStateWasInInv = 0x10000,
77 };
78 
79 class GameItem : public HotArea {
80 public:
81  Common::Array<SceneOp> onDragFinishedOps;
82  Common::Array<SceneOp> onBothButtonsOps;
83  uint16 _altCursor;
84  uint16 _iconNum;
85 
86  // mutable values
87  uint16 _inSceneNum;
88  uint32 _flags;
89  uint16 _quality;
90 
91  Common::String dump(const Common::String &indent) const override;
92 };
93 
94 class MouseCursor {
95 public:
96  MouseCursor(uint16 hotX, uint16 hotY) : _hot(hotX, hotY) {}
97 
98  Common::String dump(const Common::String &indent) const;
99 
100  const Common::Point getHot() const { return _hot; }
101 
102 private:
103  Common::Point _hot;
104 };
105 
106 // Interactions between two objects when one is dropped on the other
108 public:
109  ObjectInteraction(uint16 dropped, uint16 target) : _droppedItemNum(dropped), _targetItemNum(target) {}
110 
111  Common::Array<SceneOp> opList;
112 
113  bool matches(uint16 droppedItemNum, uint16 targetItemNum) const {
114  return (_droppedItemNum == 0xFFFF || _droppedItemNum == droppedItemNum)
115  && _targetItemNum == targetItemNum;
116  }
117 
118  Common::String dump(const Common::String &indent) const;
119 
120 private:
121  uint16 _droppedItemNum;
122  uint16 _targetItemNum;
123 
124 };
125 
127 public:
128  SceneTrigger(uint16 num) : _num(num), _enabled(false), _timesToCheckBeforeRunning(0), _checksUntilRun(0) {}
129  Common::String dump(const Common::String &indent) const;
130 
131  Common::Array<SceneConditions> conditionList;
132  Common::Array<SceneOp> sceneOpList;
133 
134  uint16 _timesToCheckBeforeRunning; // Only used in Beamish.
135  uint16 _checksUntilRun;
136  bool _enabled;
137  uint16 getNum() const { return _num; }
138 
139 private:
140  uint16 _num;
141 };
142 
143 /* A global value that only applies on a per-SDS-scene,
144  but stays with the GDS data as it sticks around during
145  the game */
147 public:
148  PerSceneGlobal(uint16 num, uint16 scene) : _num(num), _sceneNo(scene), _val(0) {}
149 
150  Common::String dump(const Common::String &indent) const;
151  bool matches(uint16 num, uint16 scene) const { return num == _num && (_sceneNo == 0 || _sceneNo == scene); }
152  bool numMatches(uint16 num) const { return num == _num; }
153 
154  int16 _val;
155 
156 private:
157  // Immutable, read from the data file
158  uint16 _num;
159  uint16 _sceneNo;
160 };
161 
162 
167 class Scene {
168 public:
169  Scene();
170  virtual ~Scene() {};
171 
172  virtual bool parse(Common::SeekableReadStream *s) = 0;
173 
174  bool isVersionOver(const char *version) const;
175  bool isVersionUnder(const char *version) const;
176 
177  uint32 getMagic() const { return _magic; }
178  const Common::String &getVersion() const { return _version; }
179 
180  bool runPreTickOps() { return runOps(_preTickOps); }
181  bool runPostTickOps() { return runOps(_postTickOps); }
182 
183  static bool runOps(const Common::Array<SceneOp> ops, int16 addMinutes = 0);
184 
185  virtual Common::Error syncState(Common::Serializer &s) = 0;
186 
187  // These are all static as they are potentially run over scene changes.
188  static void segmentStateOps(const Common::Array<uint16> &args);
189  static void setItemAttrOp(const Common::Array<uint16> &args);
190  static void setDragItemOp(const Common::Array<uint16> &args);
191 
192 protected:
193  bool readConditionList(Common::SeekableReadStream *s, Common::Array<SceneConditions> &list) const;
194  bool readHotArea(Common::SeekableReadStream *s, HotArea &dst) const;
195  bool readHotAreaList(Common::SeekableReadStream *s, Common::List<HotArea> &list) const;
196  bool readGameItemList(Common::SeekableReadStream *s, Common::Array<GameItem> &list) const;
197  bool readMouseHotspotList(Common::SeekableReadStream *s, Common::Array<MouseCursor> &list) const;
198  bool readObjInteractionList(Common::SeekableReadStream *s, Common::Array<ObjectInteraction> &list) const;
199  bool readOpList(Common::SeekableReadStream *s, Common::Array<SceneOp> &list) const;
200  bool readDialogList(Common::SeekableReadStream *s, Common::Array<Dialog> &list, int16 filenum = 0) const;
201  bool readTriggerList(Common::SeekableReadStream *s, Common::Array<SceneTrigger> &list) const;
202  bool readDialogActionList(Common::SeekableReadStream *s, Common::Array<DialogAction> &list) const;
203  bool readConditionalSceneOpList(Common::SeekableReadStream *s, Common::Array<ConditionalSceneOp> &list) const;
204 
205  uint32 _magic;
206  Common::String _version;
207 
208  Common::Array<SceneOp> _preTickOps;
209  Common::Array<SceneOp> _postTickOps;
210  Common::Array<ConditionalSceneOp> _conditionalOps; // Beamish only
211 };
212 
213 
214 class GDSScene : public Scene {
215 public:
216  GDSScene();
217 
218  bool load(const Common::String &filename, ResourceManager *resourceManager, Decompressor *decompressor);
219  bool loadRestart(const Common::String &filename, ResourceManager *resourceManager, Decompressor *decompressor);
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 mouseMoved(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 rightButtonAction(const Common::Point &pt);
352 
353  int _num;
354  Common::Array<SceneOp> _enterSceneOps;
355  Common::Array<SceneOp> _leaveSceneOps;
356  //uint _field5_0x12;
357  uint _field6_0x14;
358  Common::String _adsFile;
359  //uint _field8_0x23;
360  Common::List<HotArea> _hotAreaList;
361  Common::Array<ObjectInteraction> _objInteractions1;
362  Common::Array<ObjectInteraction> _objInteractions2;
363  Common::Array<DynamicRect> _dynamicRects; // Only used in Willy Beamish
364  //uint _field12_0x2b;
365  //uint _field15_0x33;
366 
367  Common::Array<TalkData> _talkData;
368 
369  // From here on is mutable stuff that might need saving
370  Common::Array<Dialog> _dialogs;
371  Common::Array<SceneTrigger> _triggers;
372  Conversation _conversation;
373 
374  GameItem *_dragItem;
375  bool _shouldClearDlg;
376  bool _ignoreMouseUp;
377  bool _lbuttonDown;
378  bool _rbuttonDown;
379  bool _lbuttonDownWithDrag;
380 
382  int16 _lookMode;
383 
384  static bool _dlgWithFlagLo8IsClosing;
385  static DialogFlags _sceneDialogFlags;
386 };
387 
388 } // End of namespace Dgds
389 
390 #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:94
Definition: ads.h:28
Definition: list.h:44
Definition: stream.h:745
Definition: serializer.h:79
Definition: scene.h:167
Definition: head.h:92
Definition: scene.h:146
Definition: dgds_rect.h:32
Definition: scene.h:66
Definition: scene.h:271
Definition: rect.h:45
Definition: head.h:140
Definition: scene.h:126
Definition: scene.h:107
Definition: scene.h:79
Definition: scene.h:214
Definition: decompress.h:67
Definition: resource.h:49