ScummVM API documentation
puzzledata.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 #include "common/serializer.h"
23 #include "common/array.h"
24 #include "common/hashmap.h"
25 
26 #include "engines/nancy/commontypes.h"
27 #include "engines/nancy/enginedata.h"
28 
29 #ifndef NANCY_PUZZLEDATA_H
30 #define NANCY_PUZZLEDATA_H
31 
32 namespace Nancy {
33 
34 // The following structs contain persistent data for specific
35 // puzzle types, which is to be stored in savefiles
36 
37 struct PuzzleData {
38  PuzzleData() {}
39  virtual ~PuzzleData() {}
40 
41  virtual void synchronize(Common::Serializer &ser) = 0;
42 };
43 
44 struct SliderPuzzleData : public PuzzleData {
46  virtual ~SliderPuzzleData() {}
47 
48  static constexpr uint32 getTag() { return MKTAG('S', 'L', 'I', 'D'); }
49  virtual void synchronize(Common::Serializer &ser);
50 
51  Common::Array<Common::Array<int16>> playerTileOrder;
52  bool playerHasTriedPuzzle;
53 };
54 
57  virtual ~RippedLetterPuzzleData() {}
58 
59  static constexpr uint32 getTag() { return MKTAG('R', 'I', 'P', 'L'); }
60  virtual void synchronize(Common::Serializer &ser);
61 
62  Common::Array<int8> order;
63  Common::Array<byte> rotations;
64  bool playerHasTriedPuzzle;
65 
66  // Temporary values, do not save to file
67  int8 _pickedUpPieceID = -1;
68  byte _pickedUpPieceRot = 0;
69  int _pickedUpPieceLastPos = -1;
70 };
71 
72 struct TowerPuzzleData : public PuzzleData {
74  virtual ~TowerPuzzleData() {}
75 
76  static constexpr uint32 getTag() { return MKTAG('T', 'O', 'W', 'R'); }
77  virtual void synchronize(Common::Serializer &ser);
78 
80  bool playerHasTriedPuzzle;
81 };
82 
83 struct RiddlePuzzleData : public PuzzleData {
85  virtual ~RiddlePuzzleData() {}
86 
87  static constexpr uint32 getTag() { return MKTAG('R', 'I', 'D', 'L'); }
88  virtual void synchronize(Common::Serializer &ser);
89 
90  Common::Array<byte> solvedRiddleIDs;
91  int8 incorrectRiddleID;
92 };
93 
96  virtual ~SoundEqualizerPuzzleData() {}
97 
98  static constexpr uint32 getTag() { return MKTAG('S', 'E', 'Q', 'L'); }
99  virtual void synchronize(Common::Serializer &ser);
100 
101  Common::Array<byte> sliderValues;
102 };
103 
104 // Contains a single bool indicating whether the puzzle was solved
105 struct SimplePuzzleData : public PuzzleData {
107  virtual ~SimplePuzzleData() {}
108 
109  virtual void synchronize(Common::Serializer &ser);
110 
111  bool solvedPuzzle;
112 };
113 
115  static constexpr uint32 getTag() { return MKTAG('A', 'S', 'M', 'B'); }
116 };
117 
118 // Placed bead-type ids on the thread.
119 struct BeadPuzzleData : public PuzzleData {
120  BeadPuzzleData() {}
121  virtual ~BeadPuzzleData() {}
122 
123  static constexpr uint32 getTag() { return MKTAG('B', 'E', 'A', 'D'); }
124  virtual void synchronize(Common::Serializer &ser);
125 
126  Common::Array<int16> placedBeads;
127 };
128 
129 // Cached current/solved tile layouts for a SortPuzzle. Each cell is encoded as
130 // 4 consecutive int16s: srcRow, srcCol, value, isEmpty. The first two int16s
131 // of each array are the grid rows and cols.
132 struct SortPuzzleData : public PuzzleData {
133  SortPuzzleData() {}
134  virtual ~SortPuzzleData() {}
135 
136  static constexpr uint32 getTag() { return MKTAG('S', 'O', 'R', 'T'); }
137  virtual void synchronize(Common::Serializer &ser);
138 
139  Common::Array<int16> currentState;
140  Common::Array<int16> solvedState;
141 };
142 
143 // Per-magnet (left, top, right, bottom, locked) packed as 5 int16s. The
144 // puzzle's two scenes (3280, 3281) are the same puzzle with the same data,
145 // so a single flat array suffices.
148  virtual ~MagnetMazePuzzleData() {}
149 
150  static constexpr uint32 getTag() { return MKTAG('M', 'M', 'A', 'Z'); }
151  virtual void synchronize(Common::Serializer &ser);
152 
153  Common::Array<int16> magnetState;
154 };
155 
156 // Per-item (inMap, inItems, mapRow, mapCol, itemsRow, itemsCol) packed as
157 // 6 int16s.
158 struct GridMapPuzzleData : public PuzzleData {
159  GridMapPuzzleData() {}
160  virtual ~GridMapPuzzleData() {}
161 
162  static constexpr uint32 getTag() { return MKTAG('G', 'M', 'A', 'P'); }
163  virtual void synchronize(Common::Serializer &ser);
164 
165  Common::Array<int16> itemState;
166 };
167 
168 struct QuizPuzzleData : public PuzzleData {
169  QuizPuzzleData() {}
170  virtual ~QuizPuzzleData() {}
171 
172  static constexpr uint32 getTag() { return MKTAG('Q', 'U', 'I', 'Z'); }
173  virtual void synchronize(Common::Serializer &ser);
174 
175  // Keyed by solve-scene ID so that multiple QuizPuzzle instances
176  // (e.g. a two-page Nancy 9 puzzle) each maintain their own state.
179 };
180 
181 struct JournalData : public PuzzleData {
182  JournalData() {}
183  virtual ~JournalData() {}
184 
185  struct Entry {
186  Entry(const Common::String &s = Common::String(), uint16 m = 0, uint16 sc = kNoScene) : stringID(s), mark(m), sceneID(sc) {}
187 
188  Common::String stringID;
189  uint16 mark = 0;
190  uint16 sceneID = kNoScene;
191  };
192 
193  static constexpr uint32 getTag() { return MKTAG('J', 'O', 'U', 'R'); }
194  virtual void synchronize(Common::Serializer &ser);
195 
197 };
198 
199 // Contains variables that can be read and modified through action records.
200 // Mixes two separate things:
201 // - the exhibit data table in nancy6
202 // - the general variable storage in nancy8 and up
203 // The exhibit data was only ever used in nancy6, so mixing these should be ok.
204 struct TableData : public PuzzleData {
205  TableData();
206  virtual ~TableData() {}
207 
208  static constexpr uint32 getTag() { return MKTAG('T', 'A', 'B', 'L'); }
209  virtual void synchronize(Common::Serializer &ser);
210 
211  void setSingleValue(uint16 index, int16 value);
212  int16 getSingleValue(uint16 index) const;
213 
214  void setComboValue(uint16 index, float value);
215  float getComboValue(uint16 index) const;
216 
217  Common::Array<int16> singleValues;
218  Common::Array<float> comboValues;
219 };
220 
221 // Nancy 10+ cellphone state mutated by the ChangeCellPhoneInfo,
222 // SetCellPhoneBatteryAndSignal and AddSearchLink action records,
223 // persisted between saves.
224 struct CellPhoneData : public PuzzleData {
225  CellPhoneData() {}
226  virtual ~CellPhoneData() {}
227 
228  static constexpr uint32 getTag() { return MKTAG('C', 'E', 'L', 'L'); }
229  virtual void synchronize(Common::Serializer &ser);
230 
231  bool noSignal = false;
232  bool batteryLow = false;
233  // Loaded set to true once the popup has seeded the contact list from
234  // the UICL chunk; we then own it as runtime data.
235  bool seeded = false;
237 
238  // Populated by AR 131 (AddSearchLink). Mode 0 → emailMessages (each
239  // with a body-text CVTX key + read flag); any non-zero mode →
240  // searchLinks (web search topics).
241  Common::Array<SearchLink> emailMessages;
242  Common::Array<SearchLink> searchLinks;
243 
244 private:
245  void syncLinkArray(Common::Serializer &ser, Common::Array<SearchLink> &arr);
246 };
247 
248 // A cell-phone camera snapshot (Nancy 13). Stored as raw BGRA32 pixels so it
249 // survives save/load independently of the scene it was taken from.
251  uint16 width = 0;
252  uint16 height = 0;
253  Common::Array<byte> pixels; // width * height * 4, BGRA32
254  bool sent = false; // true once the player has "sent" it
255 };
256 
257 // Nancy 13 camera snapshots. Kept in its own lazily-created PuzzleData chunk so
258 // existing saves and the CELL chunk are untouched (no save-version bump).
261  virtual ~CellPhonePictureData() {}
262 
263  static constexpr uint32 getTag() { return MKTAG('C', 'P', 'I', 'C'); }
264  virtual void synchronize(Common::Serializer &ser);
265 
267 };
268 
269 // Nancy 11+ AR 69 (TimerControl). 10 software timers, each counting up from
270 // zero. A "configured" timer (state 5/6) fires a set of event flags, plays an
271 // optional sound and shows an optional caption once its target duration
272 // elapses. Started/stopped via ResetAndStartTimer (104) and StopTimer (105),
273 // which in Nancy 11 carry a timer-slot index.
274 struct TimerData : public PuzzleData {
275  struct Timer {
276  enum State { kIdle = 0, kRunning = 1, kPaused = 2, kOneShot = 5, kRepeating = 6 };
277 
278  int32 state = kIdle;
279  uint32 currentTimeMs = 0;
280  uint32 durationMs = 0;
281  bool hasFired = false;
282  SoundDescription sound;
283  Common::String autotextKey;
284  Common::String caption;
285  FlagDescription flags[10];
286 
287  void reset() { *this = Timer(); }
288  };
289 
290  static const uint kNumTimers = 10;
291 
292  TimerData() {}
293  virtual ~TimerData() {}
294 
295  static constexpr uint32 getTag() { return MKTAG('T', 'M', 'R', 'S'); }
296  virtual void synchronize(Common::Serializer &ser);
297 
298  Timer timers[kNumTimers];
299 };
300 
301 // Nancy 12+ UI resource values (from the UIRC boot chunk), e.g. resource 0 is
302 // the coin purse amount in cents. Seeded from UIRC on first use, mutated by AR
303 // 132 (ResourceUse), and persisted between saves.
304 struct UIResourceData : public PuzzleData {
305  UIResourceData() {}
306  virtual ~UIResourceData() {}
307 
308  static constexpr uint32 getTag() { return MKTAG('U', 'R', 'E', 'S'); }
309  virtual void synchronize(Common::Serializer &ser);
310 
311  // Set true once seeded from UIRC, so a loaded save isn't re-seeded.
312  bool seeded = false;
313  Common::Array<int32> values;
314 };
315 
316 // Nancy 10+ taskbar button-disable overrides, set by AR 29 (ControlUIItems).
317 // A disable can span a range of scenes set from an earlier scene's AR, so the
318 // override has to persist across saves for the button to stay disabled after a
319 // load into a scene that doesn't itself re-run the AR.
320 struct TaskbarData : public PuzzleData {
321  static const uint kNumButtons = 6;
322  static const uint kNumNotificationSubCategories = 3;
323 
324  struct Override {
325  bool active = false;
326  int16 startScene = -1;
327  int16 endScene = -1;
328  uint16 clickSoundMode = 0;
329  };
330 
331  TaskbarData() {}
332  virtual ~TaskbarData() {}
333 
334  static constexpr uint32 getTag() { return MKTAG('T', 'S', 'K', 'B'); }
335  virtual void synchronize(Common::Serializer &ser);
336 
337  Override overrides[kNumButtons];
338  // Notification badge flags, mirrored from the Taskbar so they survive a
339  // load. Set by AR triggers (inventory add, ModifyListEntryAdd, etc.) that
340  // won't re-run when loading into a later scene.
341  bool notifications[kNumButtons][kNumNotificationSubCategories] = {};
342 };
343 
344 // Nancy13+ WordFindPuzzle (AR 170). The puzzle is solved one word at a time across
345 // several scene visits; this remembers which word is currently active so progress
346 // survives leaving and re-entering the scene (and saving/loading).
348  WordFindPuzzleData() {}
349  virtual ~WordFindPuzzleData() {}
350 
351  static constexpr uint32 getTag() { return MKTAG('W', 'F', 'N', 'D'); }
352  virtual void synchronize(Common::Serializer &ser);
353 
354  int16 currentWord = 0;
355 };
356 
357 PuzzleData *makePuzzleData(const uint32 tag);
358 
359 } // End of namespace Nancy
360 
361 #endif // NANCY_PUZZLEDATA_H
Definition: puzzledata.h:114
Definition: str.h:59
Definition: puzzledata.h:55
Definition: puzzledata.h:304
Definition: array.h:52
Definition: puzzledata.h:37
Definition: puzzledata.h:105
Definition: puzzledata.h:324
Definition: puzzledata.h:168
Definition: serializer.h:80
Definition: puzzledata.h:347
Definition: puzzledata.h:44
Definition: puzzledata.h:274
Definition: puzzledata.h:204
Definition: hashmap.h:85
Definition: puzzledata.h:94
Definition: puzzledata.h:259
Definition: puzzledata.h:224
Definition: puzzledata.h:83
Definition: puzzledata.h:158
Definition: puzzledata.h:320
#define MKTAG(a0, a1, a2, a3)
Definition: endian.h:188
Definition: puzzledata.h:185
Definition: commontypes.h:277
Definition: puzzledata.h:72
Definition: puzzledata.h:275
Definition: puzzledata.h:132
Definition: puzzledata.h:146
Definition: puzzledata.h:119
Definition: commontypes.h:175
Definition: puzzledata.h:181
Definition: puzzledata.h:250
Definition: actionmanager.h:32