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 
64  bool load(uint num, class Common::RandomSource *rng = nullptr,
65  bool macintosh = false);
66 
67  void clear();
68 
69  bool isLoaded() const { return !_data.empty(); }
70  bool usesCompactMacData() const {
71  return _isMacintosh && !_isMacintoshLooseScripts;
72  }
73 
74  uint number() const { return _number; }
75  uint16 numSites() const { return _numSites; }
76  uint8 numSuspects() const { return _numSuspects; }
77  uint8 numCONSITEs() const { return _numCONSITEs; }
78  uint8 numCOFFSITEs() const { return _numCOFFSITEs; }
79 
81  const byte *initBlock() const;
82 
85  const byte *galleryData() const;
86 
90  const byte *floppySuspectEntry(uint suspectIdx) const;
91 
94  const byte *noteIndex() const;
95 
96  uint16 noteIndexCount() const;
97 
101  uint noteSectionSize() const;
102 
105  bool noteHasNotebookText(uint clueId) const;
106 
108  const byte *kdTextIndex() const;
109 
112  const byte *hintBlock() const;
113 
116  uint16 aChain(uint i) const {
117  return i < kChainLen ? _aChain[i] : 0xFFFF;
118  }
119 
123  uint16 hintChain(uint chainIdx, uint slot) const {
124  if (slot >= kChainLen)
125  return 0xFFFF;
126  switch (chainIdx) {
127  case 0: return _aChain[slot];
128  case 1: return _bChain[slot];
129  case 2: return _cChain[slot];
130  default: return 0xFFFF;
131  }
132  }
133 
135  const byte *mapEntry(uint siteNum) const;
136 
138  const byte *siteIndexEntry(uint siteNum) const;
139 
141  const byte *siteData(uint siteNum) const;
142 
146  const byte *floppySiteAnimData(uint siteNum) const;
147 
149  const byte *hotspots(uint siteNum) const;
150 
151  uint16 hotspotCount(uint siteNum) const;
152 
154  const char *textAt(uint16 offset) const;
155 
158  const byte *blobAt(uint32 offset) const {
159  return offset < _data.size() ? _data.data() + offset : nullptr;
160  }
161 
162  uint32 dataSize() const { return (uint32)_data.size(); }
163 
164  void syncState(Common::Serializer &s);
165 
167  int selectedPoints() const;
168 
170  int foundPoints() const;
171 
172  bool solvedCheck() const { return selectedPoints() > 99; }
173 
181  bool londonSolved() const;
182 
188  int minCluesRemaining() const;
189 
192  bool isGuilty(uint suspectIdx) const;
193 
195  uint16 alibiTextOffset(uint suspectIdx) const;
196 
199  const byte *solvedClueBlock() const;
200 
202  uint8 _cluesFound[kCluesFoundCap] = {};
203  uint8 _noteSelected[kCluesFoundCap] = {};
204  uint16 _hotSpotsSeen[kHotSpotsCap] = {};
205  uint16 _inGallery[kGalleryCap] = {};
206  uint8 _newOrder[kGalleryCap] = {};
207  uint16 _visitedSite[kVisitedSiteCap] = {};
208  uint16 _onSites[kVisitedSiteCap] = {};
209  bool _sawCOFFSITEs = false;
210  bool _sawCONSITEs = false;
211  uint8 _seenCOFFSITEs = 0;
212  uint8 _seenCONSITEs = 0;
213  bool _sawHelpHint = false;
214  bool _solvedPuzzle = false;
215  bool _firstTry = true;
216  uint16 _searchLocationNumber = 0xFFFF;
217  uint16 _siteNumber = 0xFFFF;
218  uint16 _lastSite = 0xFFFF;
219  uint16 _pendingSiteJump = 0;
220  uint16 _siteReturnDepth = 0;
221  uint16 _siteReturnStack[kVisitedSiteCap] = {};
222 
223 private:
224  Common::Array<byte> _data;
225  uint _number = 0;
226 
227  uint16 _initOffset = 0;
228  uint16 _mapOffset = 0;
229  uint16 _siteIndexOffset = 0;
230  uint16 _textOffset = 0;
231  uint16 _noteOffset = 0;
232  uint16 _galleryOffset = 0;
233  uint16 _kdTextOffset = 0;
234  uint16 _solvedOffset = 0;
235  uint16 _hintOffset = 0;
236 
237  uint16 _numSites = 0;
238  uint8 _numSuspects = 0;
239  uint8 _numCONSITEs = 0;
240  uint8 _numCOFFSITEs = 0;
241 
242  uint16 _aChain[kChainLen] = {};
243  uint16 _bChain[kChainLen] = {};
244  uint16 _cChain[kChainLen] = {};
245 
246  bool _isFloppy = false;
247  bool _isMacintosh = false;
248  bool _isMacintoshLooseScripts = 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:116
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:202
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:158
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).
bool load(uint num, class Common::RandomSource *rng=nullptr, bool macintosh=false)
uint16 hintChain(uint chainIdx, uint slot) const
Definition: mystery.h:123
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
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).