ScummVM API documentation
mystery.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 EEM_MYSTERY_H
23 #define EEM_MYSTERY_H
24 
25 #include "common/array.h"
26 #include "common/path.h"
27 #include "common/scummsys.h"
28 #include "common/serializer.h"
29 #include "common/str.h"
30 
31 namespace EEM {
32 
50 class Mystery {
51 public:
52  static const uint kNumChains = 3;
53  static const uint kChainLen = 5;
54  static const uint kCluesFoundCap = 100;
55  static const uint kHotSpotsCap = 100;
56  static const uint kGalleryCap = 5;
57  static const uint kVisitedSiteCap = 20;
58 
59  Mystery() = default;
60  ~Mystery() = default;
61 
63  bool load(uint num, class Common::RandomSource *rng = nullptr,
64  bool macintosh = false, bool london = false);
65 
66  void clear();
67 
68  bool isLoaded() const { return !_data.empty(); }
69  bool usesCompactMacData() const {
70  return _isMacintosh && !_isMacintoshLooseScripts;
71  }
72 
73  uint number() const { return _number; }
74  uint16 numSites() const { return _numSites; }
75  uint8 numSuspects() const { return _numSuspects; }
76  uint8 numCONSITEs() const { return _numCONSITEs; }
77  uint8 numCOFFSITEs() const { return _numCOFFSITEs; }
78 
80  const byte *initBlock() const;
81 
84  const byte *galleryData() const;
85 
89  const byte *floppySuspectEntry(uint suspectIdx) const;
90 
93  const byte *noteIndex() const;
94 
95  uint16 noteIndexCount() const;
96 
100  uint noteSectionSize() const;
101 
104  bool noteHasNotebookText(uint clueId) const;
105 
107  const byte *kdTextIndex() const;
108 
111  const byte *hintBlock() const;
112 
115  uint16 aChain(uint i) const {
116  return i < kChainLen ? _aChain[i] : 0xFFFF;
117  }
118 
122  uint16 hintChain(uint chainIdx, uint slot) const {
123  if (slot >= kChainLen)
124  return 0xFFFF;
125  switch (chainIdx) {
126  case 0: return _aChain[slot];
127  case 1: return _bChain[slot];
128  case 2: return _cChain[slot];
129  default: return 0xFFFF;
130  }
131  }
132 
134  const byte *mapEntry(uint siteNum) const;
135 
137  const byte *siteIndexEntry(uint siteNum) const;
138 
140  const byte *siteData(uint siteNum) const;
141 
145  const byte *floppySiteAnimData(uint siteNum) const;
146 
148  const byte *hotspots(uint siteNum) const;
149 
150  uint16 hotspotCount(uint siteNum) const;
151 
153  const char *textAt(uint16 offset) const;
154 
157  const byte *blobAt(uint32 offset) const {
158  return offset < _data.size() ? _data.data() + offset : nullptr;
159  }
160 
161  uint32 dataSize() const { return (uint32)_data.size(); }
162 
163  void syncState(Common::Serializer &s);
164 
166  int selectedPoints() const;
167 
169  int foundPoints() const;
170 
171  bool solvedCheck() const { return selectedPoints() > 99; }
172 
180  bool londonSolved() const;
181 
187  int minCluesRemaining() const;
188 
191  bool isGuilty(uint suspectIdx) const;
192 
194  uint16 alibiTextOffset(uint suspectIdx) const;
195 
198  const byte *solvedClueBlock() const;
199 
201  uint8 _cluesFound[kCluesFoundCap] = {};
202  uint8 _noteSelected[kCluesFoundCap] = {};
203  uint16 _hotSpotsSeen[kHotSpotsCap] = {};
204  uint16 _inGallery[kGalleryCap] = {};
205  uint8 _newOrder[kGalleryCap] = {};
206  uint16 _visitedSite[kVisitedSiteCap] = {};
207  uint16 _onSites[kVisitedSiteCap] = {};
208  bool _sawCOFFSITEs = false;
209  bool _sawCONSITEs = false;
210  uint8 _seenCOFFSITEs = 0;
211  uint8 _seenCONSITEs = 0;
212  bool _sawHelpHint = false;
213  bool _solvedPuzzle = false;
214  bool _firstTry = true;
215  uint16 _searchLocationNumber = 0xFFFF;
216  uint16 _siteNumber = 0xFFFF;
217  uint16 _lastSite = 0xFFFF;
218  uint16 _pendingSiteJump = 0;
219  uint16 _siteReturnDepth = 0;
220  uint16 _siteReturnStack[kVisitedSiteCap] = {};
221 
222 private:
223  Common::Array<byte> _data;
224  uint _number = 0;
225 
226  uint16 _initOffset = 0;
227  uint16 _mapOffset = 0;
228  uint16 _siteIndexOffset = 0;
229  uint16 _textOffset = 0;
230  uint16 _noteOffset = 0;
231  uint16 _galleryOffset = 0;
232  uint16 _kdTextOffset = 0;
233  uint16 _solvedOffset = 0;
234  uint16 _hintOffset = 0;
235 
236  uint16 _numSites = 0;
237  uint8 _numSuspects = 0;
238  uint8 _numCONSITEs = 0;
239  uint8 _numCOFFSITEs = 0;
240 
241  uint16 _aChain[kChainLen] = {};
242  uint16 _bChain[kChainLen] = {};
243  uint16 _cChain[kChainLen] = {};
244 
245  bool _isFloppy = false;
246  bool _isMacintosh = false;
247  bool _isMacintoshLooseScripts = false;
248  bool _isLondon = false;
249  uint16 _floppySuspectsOff = 0;
250  uint16 _floppyHintBlockOff = 0;
251  uint16 _floppyNoteIndexOff = 0;
252  uint16 _floppyGalleryOff = 0;
253  uint16 _floppyTextOff = 0;
254  uint16 _floppyKDTextOff = 0;
255  uint16 _floppySolvedOff = 0;
256  Common::Array<byte> _floppySiteAnimData;
257  uint16 _floppySiteAnimSiteOff[kVisitedSiteCap] = {};
258 
259  uint16 readU16(uint offset) const;
260  void loadFloppySiteAnimData();
261 };
262 
263 } // End of namespace EEM
264 
265 #endif
bool isGuilty(uint suspectIdx) const
const byte * noteIndex() const
const byte * siteData(uint siteNum) const
SiteData (sitepic, travel, hotspot count, ...) per SiteIndex[siteNum].
const T * data() const
Definition: array.h:208
uint16 aChain(uint i) const
Definition: mystery.h:115
Definition: mystery.h:50
Definition: random.h:44
bool noteHasNotebookText(uint clueId) const
uint8 _cluesFound[kCluesFoundCap]
Per-mystery runtime state, zeroed at load time.
Definition: mystery.h:201
uint noteSectionSize() const
int selectedPoints() const
_GetSelectedPoints @ 1df2:00bd.
Definition: serializer.h:80
const byte * floppySuspectEntry(uint suspectIdx) const
const byte * hintBlock() const
uint16 alibiTextOffset(uint suspectIdx) const
TextBlock offset of suspect&#39;s alibi text. 0xFFFF for guilty suspect.
bool empty() const
Definition: array.h:352
int foundPoints() const
_GetFoundPoints @ 1df2:0098 — sum of top 5 found notebook entries.
Definition: animation.h:30
const byte * floppySiteAnimData(uint siteNum) const
bool londonSolved() const
const byte * kdTextIndex() const
KDTextIndex; first u16s are TextBlock offsets for host hint lines.
const byte * blobAt(uint32 offset) const
Definition: mystery.h:157
size_type size() const
Definition: array.h:316
const byte * mapEntry(uint siteNum) const
MapData entry for siteNum: 14 bytes; first u16 = sitepic, +4..7 = (x, y).
uint16 hintChain(uint chainIdx, uint slot) const
Definition: mystery.h:122
const char * textAt(uint16 offset) const
NUL-terminated string at TextBlock + offset.
const byte * galleryData() const
const byte * initBlock() const
InitBlock (case briefing) at mystery + word[0].
int minCluesRemaining() const
const byte * solvedClueBlock() const
bool load(uint num, class Common::RandomSource *rng=nullptr, bool macintosh=false, bool london=false)
Load M<num>.BIN, or MysteryData for Mac floppy, and reset mystery state.
const byte * hotspots(uint siteNum) const
Hotspot rectangle array for siteNum (14 bytes each: x1,y1,x2,y2 + clue).
const byte * siteIndexEntry(uint siteNum) const
SiteIndex entry for siteNum (6 bytes per site on CD).