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
35namespace Dgds {
36
37class ResourceManager;
38class Decompressor;
39class DgdsFont;
40class SoundRaw;
41class TTMInterpreter;
42class TTMEnviro;
43
44
45class HotArea {
46public:
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;
59
60 virtual ~HotArea() {}
61
62 virtual Common::String dump(const Common::String &indent) const;
63};
64
66public:
67 DynamicRect() : _num(0) {};
68 uint16 _num;
69 DgdsRect _rect;
70};
71
72
73enum GameItemState {
74 kItemStateDragging = 1,
75 kItemStateWasInInv = 0x10000,
76};
77
78class GameItem : public HotArea {
79public:
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
94public:
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
101private:
102 Common::Point _hot;
103};
104
105// Interactions between two objects when one is dropped on the other
107public:
108 ObjectInteraction(uint16 dropped, uint16 target) : _droppedItemNum(dropped), _targetItemNum(target) {}
109
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
119private:
120 uint16 _droppedItemNum;
121 uint16 _targetItemNum;
122
123};
124
126public:
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
138private:
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 */
146public:
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
155private:
156 // Immutable, read from the data file
157 uint16 _num;
158 uint16 _sceneNo;
159};
160
161
166class Scene {
167public:
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
191protected:
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
213class GDSScene : public Scene {
214public:
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
252private:
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
271class SDSScene : public Scene {
272public:
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
345protected:
346 HotArea *findAreaUnderMouse(const Common::Point &pt);
347
348private:
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
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: array.h:52
Definition: error.h:81
Definition: list.h:44
Definition: stream.h:745
Definition: serializer.h:80
Definition: str.h:59
Definition: head.h:141
Definition: decompress.h:67
Definition: dgds_rect.h:32
Definition: dialog.h:101
Definition: scene.h:65
Definition: scene.h:213
Definition: scene.h:78
Definition: scene.h:45
Definition: scene.h:93
Definition: scene.h:106
Definition: scene.h:145
Definition: resource.h:48
Definition: scene.h:271
Definition: scene.h:166
Definition: scene.h:125
Definition: head.h:93
Definition: managed_surface.h:51
Definition: rect.h:144