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 NANCY_STATE_SCENE_H
23 #define NANCY_STATE_SCENE_H
24 
25 #include "common/singleton.h"
26 #include "common/queue.h"
27 
28 #include "engines/nancy/commontypes.h"
29 #include "engines/nancy/puzzledata.h"
30 
31 #include "engines/nancy/action/actionmanager.h"
32 
33 #include "engines/nancy/state/state.h"
34 
35 #include "engines/nancy/ui/fullscreenimage.h"
36 #include "engines/nancy/ui/viewport.h"
37 #include "engines/nancy/ui/textbox.h"
38 #include "engines/nancy/ui/inventorybox.h"
39 #include "engines/nancy/ui/inventorypopup.h"
40 #include "engines/nancy/ui/notebookpopup.h"
41 #include "engines/nancy/ui/cellphonepopup.h"
42 #include "engines/nancy/ui/conversationpopup.h"
43 
44 namespace Common {
45 class SeekableReadStream;
46 class Serializer;
47 }
48 
49 namespace Nancy {
50 
51 class NancyEngine;
52 class NancyConsole;
53 struct SceneChangeDescription;
54 
55 namespace Action {
56 class ConversationSound;
57 class PlaySecondaryMovie;
58 }
59 
60 namespace Misc {
61 class Lightning;
62 class SpecialEffect;
63 }
64 
65 namespace UI {
66 class Button;
67 class Taskbar;
68 class ViewportOrnaments;
69 class TextboxOrnaments;
70 class InventoryBoxOrnaments;
71 class Clock;
72 }
73 
74 namespace State {
75 
76 // The game state that handles all of the gameplay
77 class Scene : public State, public Common::Singleton<Scene> {
78 public:
79  struct SceneSummary {
80  // SSUM and TSUM
81  // Default values set to match those applied when loading from a TSUM chunk
82  Common::String description;
83  Common::Path videoFile;
84 
85  uint16 videoFormat = kLargeVideoFormat;
87  SoundDescription sound;
88 
89  byte panningType = kPan360;
90  uint16 numberOfVideoFrames = 0;
91  uint16 degreesPerRotation = 18;
92  uint16 totalViewAngle = 0;
93  uint16 horizontalScrollDelta = 1;
94  uint16 verticalScrollDelta = 10;
95  uint16 horizontalEdgeSize = 15;
96  uint16 verticalEdgeSize = 15;
97  Time slowMoveTimeDelta = 400;
98  Time fastMoveTimeDelta = 66;
99 
100  // Sound start vectors, used in nancy3 and up
101  Math::Vector3d listenerPosition;
102 
103  void read(Common::SeekableReadStream &stream);
104  void readTerse(Common::SeekableReadStream &stream);
105  };
106 
107  Scene();
108  virtual ~Scene();
109 
110  // State API
111  void process() override;
112  void onStateEnter(const NancyState::NancyState prevState) override;
113  bool onStateExit(const NancyState::NancyState nextState) override;
114 
115  // Used when winning/losing game
116  void setDestroyOnExit() { _destroyOnExit = true; }
117 
118  bool isRunningAd() const { return _isRunningAd; }
119 
120  void changeScene(const SceneChangeDescription &sceneDescription);
121  void pushScene(int16 itemID = -1);
122  void popScene(bool inventory = false);
123  uint16 getSceneCounts(int16 hours) const {
124  return _flags.sceneCounts.contains(hours) ? _flags.sceneCounts[hours] : 0;
125  }
126 
127  void setPlayerTime(Time time, byte relative);
128  Time getPlayerTime() const { return _timers.playerTime; }
129  Time getTimerTime() const { return _timers.timerIsActive ? _timers.timerTime : 0; }
130  byte getPlayerTOD() const;
131 
132  void addItemToInventory(int16 id);
133  void removeItemFromInventory(int16 id, bool pickUp = true);
134  int16 getHeldItem() const { return _flags.heldItem; }
135  void setHeldItem(int16 id);
136  void setNoHeldItem();
137  byte hasItem(int16 id) const;
138  byte getItemDisabledState(int16 id) const { return _flags.disabledItems[id]; }
139  void setItemDisabledState(int16 id, byte state) {
140  if ((uint16)id < _flags.disabledItems.size())
141  _flags.disabledItems[id] = state;
142  }
143 
144  void installInventorySoundOverride(byte command, const SoundDescription &sound, const Common::String &caption, uint16 itemID);
145  void playItemCantSound(int16 itemID = -1, bool notHoldingSound = false);
146 
147  void setEventFlag(int16 label, byte flag);
148  void setEventFlag(FlagDescription eventFlag);
149  bool getEventFlag(int16 label, byte flag) const;
150  bool getEventFlag(FlagDescription eventFlag) const;
151 
152  void setLogicCondition(int16 label, byte flag);
153  bool getLogicCondition(int16 label, byte flag) const;
154  void clearLogicConditions();
155  Time getLogicConditionTimestamp(int16 label) const {
156  return _flags.logicConditions[label].timestamp;
157  }
158 
159  void setDifficulty(uint difficulty) { _difficulty = difficulty; }
160  uint16 getDifficulty() const { return _difficulty; }
161 
162  byte getHintsRemaining() const { return _hintsRemaining[_difficulty]; }
163  void useHint(uint16 characterID, uint16 hintID);
164 
165  void requestStateChange(NancyState::NancyState state) { _gameStateRequested = state; }
166  void resetStateToInit() { _state = kInit; }
167 
168  void resetAndStartTimer() { _timers.timerIsActive = true; _timers.timerTime = 0; }
169  void stopTimer() { _timers.timerIsActive = false; _timers.timerTime = 0; }
170 
171  Time getMovementTimeDelta(bool fast) const { return fast ? _sceneState.summary.fastMoveTimeDelta : _sceneState.summary.slowMoveTimeDelta; }
172 
173  // Nancy 11+ AR 30/31. Toggles whether the player may scroll/pan the viewport.
174  // Backed by a reserved event flag (so it persists across scene changes and
175  // is saved/restored with the rest of the event flags).
176  void setPlayerScrolling(bool enabled);
177  bool getPlayerScrolling() const;
178 
179  void registerGraphics();
180 
181  void synchronize(Common::Serializer &serializer);
182 
183  UI::FullScreenImage &getFrame() { return _frame; }
184  UI::Viewport &getViewport() { return _viewport; }
185  UI::Textbox &getTextbox() { return _textbox; }
186  UI::InventoryBox &getInventoryBox() { return _inventoryBox; }
187  UI::InventoryPopup &getInventoryPopup() { return _inventoryPopup; }
188  UI::NotebookPopup &getNotebookPopup() { return _notebookPopup; }
189  UI::CellPhonePopup &getCellPhonePopup() { return _cellPhonePopup; }
190  UI::ConversationPopup &getConversationPopup() { return _conversationPopup; }
191  UI::Clock *getClock();
192  UI::Taskbar *getTaskbar() { return _taskbar; }
193 
194  Action::ActionManager &getActionManager() { return _actionManager; }
195 
196  SceneChangeDescription &getSceneInfo() { return _sceneState.currentScene; }
197  SceneChangeDescription &getNextSceneInfo() { return _sceneState.nextScene; }
198  const SceneSummary &getSceneSummary() const { return _sceneState.summary; }
199 
200  void setActiveMovie(Action::PlaySecondaryMovie *activeMovie);
201  Action::PlaySecondaryMovie *getActiveMovie();
202 
203  // Called when a PSM(isRandom) AR is loaded — drives stale-chain cleanup.
204  void notifyRandomMovieARLoaded() { _hadRandomMovieARThisScene = true; }
205  void setActiveConversation(Action::ConversationSound *activeConversation);
206  Action::ConversationSound *getActiveConversation();
207 
208  Graphics::ManagedSurface &getLastScreenshot() { return _lastScreenshot; }
209 
210  // The Vampire Diaries only;
211  void beginLightning(int16 distance, uint16 pulseTime, int16 rgbPercent);
212 
213  // Used from nancy2 onwards
214  void specialEffect(byte type, uint16 fadeToBlackTime, uint16 frameTime);
215  void specialEffect(byte type, uint16 totalTime, uint16 fadeToBlackTime, Common::Rect rect);
216 
217  // Get the persistent data for a given puzzle type
218  PuzzleData *getPuzzleData(const uint32 tag);
219 
220  enum State {
221  kInit,
222  kLoad,
223  kStartSound,
224  kRun
225  };
226 
227  State getState() const { return _state; }
228  void setState(State state) { _state = state; }
229 
230  struct Timers {
231  Time pushedPlayTime;
232  Time lastTotalTime;
233  Time sceneTime;
234  Time timerTime;
235  bool timerIsActive = false;
236  Time playerTime; // In-game time of day, adds a minute every 5 seconds
237  Time playerTimeNextMinute; // Stores the next tick count until we add a minute to playerTime
238  };
239 
240  Timers _timers;
241 
242  RenderObject _hotspotDebug;
243 
244 private:
245  void init();
246  void load(bool fromSaveFile = false);
247  void run();
248  void handleInput();
249 
250  // Nancy 11+ AR 69. Advances all running software timers (stored as TimerData
251  // puzzle data) and fires any whose configured duration has just elapsed.
252  void tickSoftwareTimers(uint32 deltaMs);
253  void fireSoftwareTimer(TimerData::Timer &timer);
254 
255  // Rect of the open Nancy 10+ taskbar popup, or empty if none.
256  Common::Rect activePopupConfinement() const;
257 
258  void initStaticData();
259 
260  void clearSceneData();
261  void clearPuzzleData();
262 
263  struct SceneState {
264  SceneSummary summary;
265  SceneChangeDescription currentScene;
266  SceneChangeDescription nextScene;
267  SceneChangeDescription pushedScene;
268  bool isScenePushed = false;
269  SceneChangeDescription pushedInvScene;
270  int16 pushedInvItemID = -1;
271  bool isInvScenePushed = false;
272  };
273 
274  struct PlayFlags {
275  struct LogicCondition {
276  LogicCondition();
277  byte flag;
278  Time timestamp;
279  };
280 
281  LogicCondition logicConditions[30];
282  Common::Array<byte> eventFlags;
284  Common::Array<byte> items;
285  Common::Array<byte> disabledItems;
286  int16 heldItem = -1;
287  int16 primaryVideoResponsePicked = -1;
288  };
289 
290  struct InventorySoundOverride {
291  bool isDefault = false; // When true, other fields are ignored
292  SoundDescription sound;
293  Common::String caption;
294  };
295 
296  // UI
297  UI::FullScreenImage _frame;
298  UI::Viewport _viewport;
299  UI::Textbox _textbox;
300  UI::InventoryBox _inventoryBox;
301  UI::InventoryPopup _inventoryPopup;
302  UI::NotebookPopup _notebookPopup;
303  UI::CellPhonePopup _cellPhonePopup;
304  UI::ConversationPopup _conversationPopup;
305 
306  UI::Button *_menuButton;
307  UI::Button *_helpButton;
308  UI::Taskbar *_taskbar;
309  Time _buttonPressActivationTime;
310 
311  UI::ViewportOrnaments *_viewportOrnaments;
312  UI::TextboxOrnaments *_textboxOrnaments;
313  UI::InventoryBoxOrnaments *_inventoryBoxOrnaments;
314  RenderObject *_clock;
315 
316  Common::Rect _mapHotspot;
317 
318  // General data
319  SceneState _sceneState;
320  PlayFlags _flags;
321  uint16 _difficulty;
322  Common::Array<uint16> _hintsRemaining;
323  int16 _lastHintCharacter;
324  int16 _lastHintID;
325  NancyState::NancyState _gameStateRequested;
326  Common::HashMap<uint16, InventorySoundOverride> _inventorySoundOverrides;
327 
328  Misc::Lightning *_lightning;
329  Common::Queue<Misc::SpecialEffect> _specialEffects;
330 
332 
333  Action::ActionManager _actionManager;
334  Action::PlaySecondaryMovie *_activeMovie;
335  Action::ConversationSound *_activeConversation;
336 
337  // Set by notifyRandomMovieARLoaded; checked in clearSceneData to wind
338  // down a persistent random-movie whose scene chain is over.
339  bool _hadRandomMovieARThisScene = false;
340 
341  // Contains a screenshot of the Scene state from the last time it was exited
342  Graphics::ManagedSurface _lastScreenshot;
343 
344  bool _destroyOnExit;
345  bool _isRunningAd;
346 
347  State _state;
348 };
349 
350 #define NancySceneState Nancy::State::Scene::instance()
351 
352 } // End of namespace State
353 } // End of namespace Nancy
354 
355 #endif // NANCY_STATE_SCENE_H
Definition: managed_surface.h:51
Definition: conversationpopup.h:40
Definition: str.h:59
Definition: inventorypopup.h:42
Definition: viewport.h:41
Definition: time.h:30
Definition: taskbar.h:36
Definition: commontypes.h:152
Definition: puzzledata.h:37
Definition: inventorybox.h:42
Definition: rect.h:524
Definition: path.h:52
Definition: textbox.h:38
Definition: stream.h:745
Definition: secondarymovie.h:49
Definition: conversation.h:42
Definition: queue.h:42
Definition: serializer.h:80
Definition: actionmanager.h:48
Definition: soundequalizerpuzzle.h:27
Definition: renderobject.h:36
Definition: scene.h:79
Definition: scene.h:230
Definition: ornaments.h:30
Definition: lightning.h:32
Definition: clock.h:37
Definition: button.h:33
Definition: algorithm.h:29
Definition: cellphonepopup.h:37
Definition: notebookpopup.h:37
Definition: commontypes.h:255
Definition: puzzledata.h:263
Definition: ornaments.h:38
Definition: fullscreenimage.h:30
Definition: ornaments.h:46
Definition: scene.h:77
Definition: input.h:69
Definition: commontypes.h:167
Definition: actionmanager.h:32
Definition: singleton.h:42