ScummVM API documentation
advancedDetector.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 ENGINES_ADVANCED_DETECTOR_H
23 #define ENGINES_ADVANCED_DETECTOR_H
24 
25 #include "engines/metaengine.h"
26 #include "engines/engine.h"
27 
28 #include "common/hash-str.h"
29 
30 #include "common/gui_options.h" // Keep it here, so detection tables can refer to them
31 
32 namespace Common {
33 class Error;
34 class FSList;
35 }
51  const char *fileName;
52  uint16 fileType;
53  const char *md5;
54  int64 fileSize;
55 };
56 
61 #define AD_LISTEND {NULL, 0, NULL, 0}
62 
67 #define AD_ENTRY1(f, x) {{ f, 0, x, -1}, AD_LISTEND}
68 
73 #define AD_ENTRY1s(f, x, s) {{ f, 0, x, s}, AD_LISTEND}
74 
79 #define AD_ENTRY2s(f1, x1, s1, f2, x2, s2) {{f1, 0, x1, s1}, {f2, 0, x2, s2}, AD_LISTEND}
80 
85 #define AD_ENTRY3s(f1, x1, s1, f2, x2, s2, f3, x3, s3) {{f1, 0, x1, s1}, {f2, 0, x2, s2}, {f3, 0, x3, s3}, AD_LISTEND}
86 #define AD_ENTRY4s(f1, x1, s1, f2, x2, s2, f3, x3, s3, f4, x4, s4) {{f1, 0, x1, s1}, {f2, 0, x2, s2}, {f3, 0, x3, s3}, {f4, 0, x4, s4}, AD_LISTEND}
87 #define AD_ENTRY5s(f1, x1, s1, f2, x2, s2, f3, x3, s3, f4, x4, s4, f5, x5, s5) {{f1, 0, x1, s1}, {f2, 0, x2, s2}, {f3, 0, x3, s3}, {f4, 0, x4, s4}, {f5, 0, x5, s5}, AD_LISTEND}
88 #define AD_ENTRY6s(f1, x1, s1, f2, x2, s2, f3, x3, s3, f4, x4, s4, f5, x5, s5, f6, x6, s6) {{f1, 0, x1, s1}, {f2, 0, x2, s2}, {f3, 0, x3, s3}, {f4, 0, x4, s4}, {f5, 0, x5, s5}, {f6, 0, x6, s6}, AD_LISTEND}
89 
95 enum ADGameFlags : uint {
97  ADGF_TAILMD5 = (1u << 16),
98  ADGF_AUTOGENTARGET = (1u << 17),
99  ADGF_UNSTABLE = (1u << 18),
100  ADGF_TESTING = (1u << 19),
101  ADGF_PIRATED = (1u << 20),
102  ADGF_UNSUPPORTED = (1u << 21),
104  ADGF_WARNING = (1u << 22),
106  ADGF_ADDENGLISH = (1u << 23),
107  ADGF_MACRESFORK = (1u << 24),
108  ADGF_USEEXTRAASTITLE = (1u << 25),
109  ADGF_DROPLANGUAGE = (1u << 26),
110  ADGF_DROPPLATFORM = (1u << 27),
111  ADGF_CD = (1u << 28),
112  ADGF_DVD = (1u << 29),
113  ADGF_DEMO = (1u << 30),
114  ADGF_REMASTERED = (1u << 31)
115 };
116 
126  const char *gameId;
127 
137  const char *extra;
138 
145  ADGameFileDescription filesDescriptions[14];
146 
151 
156 
163  uint32 flags;
164 
172  const char *guiOptions;
173 };
174 
181 };
182 
191  ADDetectedGame() : desc(nullptr), hasUnknownFiles(false) {}
195  explicit ADDetectedGame(const ADGameDescription *d) : desc(d), hasUnknownFiles(false) {}
196 };
197 
200 
205 #define AD_TABLE_END_MARKER \
206  { NULL, NULL, { { NULL, 0, NULL, 0 } }, Common::UNK_LANG, Common::kPlatformUnknown, ADGF_NO_FLAGS, GUIO0() }
207 
214 
219  const char *filenames[10];
220 };
221 
222 
223 enum ADFlags {
235 
248 
258 
265 };
266 
267 
273  const char *guioFlag;
275 };
276 
277 #define AD_EXTRA_GUI_OPTIONS_TERMINATOR { 0, { 0, 0, 0, 0, 0, 0 } }
278 
283 protected:
291  const byte *_gameDescriptors;
292 
298  const uint _descItemSize;
299 
305 
315  uint _md5Bytes;
316 
323  uint32 _flags;
324 
332 
339 
348  const char * const *_directoryGlobs;
349 
356 
363 
364 public:
368  AdvancedMetaEngineDetection(const void *descs, uint descItemSize, const PlainGameDescriptor *gameIds);
369 
375  PlainGameList getSupportedGames() const override;
376 
378  PlainGameDescriptor findGame(const char *gameId) const override;
379 
385  DetectedGames detectGames(const Common::FSList &fslist, uint32 skipADFlags, bool skipIncomplete) override;
386 
393  Common::Error createInstance(OSystem *syst, Engine **engine);
394 
395  static Common::StringArray getPathsFromEntry(const ADGameDescription *g);
396 
397  uint getMD5Bytes() const override final { return _md5Bytes; }
398 
399  int getGameVariantCount() const override final {
400  uint count = 0;
401  for (const byte *descPtr = _gameDescriptors; ((const ADGameDescription *)descPtr)->gameId != nullptr; descPtr += _descItemSize)
402  ++count;
403  return count;
404  }
405 
406  void dumpDetectionEntries() const override final;
407 
408 protected:
413 
418  virtual ADDetectedGame fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist, ADDetectedGameExtraInfo **extra = nullptr) const {
419  return ADDetectedGame();
420  }
421 
422 private:
423  void initSubSystems(const ADGameDescription *gameDesc) const;
424  void preprocessDescriptions();
425  bool isEntryGrayListed(const ADGameDescription *g) const;
426  void detectClashes() const;
427 
428 private:
431  bool _hashMapsInited;
432 
433 protected:
450  virtual ADDetectedGames detectGame(const Common::FSNode &parent, const FileMap &allFiles, Common::Language language, Common::Platform platform, const Common::String &extra, uint32 skipADFlags = 0, bool skipIncomplete = false);
451 
463  ADDetectedGame detectGameFilebased(const FileMap &allFiles, const ADFileBasedFallback *fileBasedFallback) const;
464 
470  void composeFileHashMap(FileMap &allFiles, const Common::FSList &fslist, int depth, const Common::Path &parentName = Common::Path()) const;
471 
473  bool getFileProperties(const FileMap &allFiles, MD5Properties md5prop, const Common::Path &fname, FileProperties &fileProps) const;
474 
476  virtual DetectedGame toDetectedGame(const ADDetectedGame &adGame, ADDetectedGameExtraInfo *extraInfo = nullptr) const;
477 
479  bool cleanupPirated(ADDetectedGames &matched) const;
480 
481  friend class FileMapArchive;
482 };
483 
488 public:
497  Common::Error createInstance(OSystem *syst, Engine **engine) override;
498 
503  virtual Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const = 0;
504 
512  const char *getName() const override = 0;
513 
514 public:
519 
533  virtual ADDetectedGame fallbackDetectExtern(uint md5Bytes, const FileMap &allFiles, const Common::FSList &fslist, ADDetectedGameExtraInfo **extra = nullptr) const {
534  return ADDetectedGame();
535  }
536 
542  bool getFilePropertiesExtern(uint md5Bytes, const FileMap &allFiles, MD5Properties md5prop, const Common::Path &fname, FileProperties &fileProps) const;
543 
544 protected:
559  const ExtraGuiOptions getExtraGuiOptions(const Common::String &target) const override final;
560 
564  virtual const ADExtraGuiOptionsMap *getAdvancedExtraGuiOptions() const { return nullptr; }
565 
570  bool checkExtendedSaves(MetaEngineFeature f) const;
571 };
572 
576 class AdvancedDetectorCacheManager : public Common::Singleton<AdvancedDetectorCacheManager> {
577 public:
578  void setMD5(const Common::String &fname, const Common::String &md5) {
579  md5HashMap.setVal(fname, md5);
580  }
581 
582  const Common::String &getMD5(const Common::String &fname) const {
583  return md5HashMap.getVal(fname);
584  }
585 
586  void setSize(const Common::String &fname, int64 size) {
587  sizeHashMap.setVal(fname, size);
588  }
589 
590  int64 getSize(const Common::String &fname) const {
591  return sizeHashMap.getVal(fname);
592  }
593 
594  bool containsMD5(const Common::String &fname) const {
595  return (md5HashMap.contains(fname) && sizeHashMap.contains(fname));
596  }
597 
598  void addArchive(const Common::FSNode &node, Common::Archive *archivePtr) {
599  if (!archivePtr)
600  return;
601 
602  Common::Path filename = node.getPath();
603 
604  if (archiveHashMap.contains(filename)) {
605  delete archiveHashMap[filename];
606  }
607 
608  archiveHashMap.setVal(filename, archivePtr);
609  }
610 
611  Common::Archive *getArchive(const Common::FSNode &node) const {
612  return archiveHashMap.getValOrDefault(node.getPath(), nullptr);
613  }
614 
616  clear();
617  }
618 
619  void clearArchives() {
620  for (auto &entry : archiveHashMap) {
621  delete entry._value;
622  }
623  archiveHashMap.clear(true);
624  }
625 
626  void clear() {
627  md5HashMap.clear(true);
628  sizeHashMap.clear(true);
629  clearArchives();
630  }
631 
632 private:
633  friend class Common::Singleton<AdvancedDetectorCacheManager>;
634 
638  FileHashMap md5HashMap;
639  SizeHashMap sizeHashMap;
640  ArchiveHashMap archiveHashMap;
641 };
642 
644 #define ADCacheMan AdvancedDetectorCacheManager::instance()
645 
646 #endif
Definition: advancedDetector.h:178
virtual ADDetectedGame fallbackDetectExtern(uint md5Bytes, const FileMap &allFiles, const Common::FSList &fslist, ADDetectedGameExtraInfo **extra=nullptr) const
Definition: advancedDetector.h:533
Common::String _guiOptions
Definition: advancedDetector.h:331
Definition: metaengine.h:200
Always add English as a language option.
Definition: advancedDetector.h:106
Definition: str.h:59
virtual const ADExtraGuiOptionsMap * getAdvancedExtraGuiOptions() const
Definition: advancedDetector.h:564
const uint _descItemSize
Definition: advancedDetector.h:298
Flag to designate not yet officially supported games that are not fit for public testing.
Definition: advancedDetector.h:99
Common::HashMap< Common::Path, Common::FSNode, Common::Path::IgnoreCase_Hash, Common::Path::IgnoreCase_EqualTo > FileMap
Definition: advancedDetector.h:518
Definition: advancedDetector.h:257
MetaEngineFeature
Definition: metaengine.h:400
Definition: error.h:84
Definition: game.h:147
Definition: advancedDetector.h:282
const PlainGameDescriptor * _gameIds
Definition: advancedDetector.h:304
const char * md5
MD5 of (the beginning of) the described file. Optional. Set to NULL to ignore.
Definition: advancedDetector.h:53
Common::Array< ADDetectedGame > ADDetectedGames
Definition: advancedDetector.h:199
Definition: array.h:52
const char * extra
Definition: advancedDetector.h:137
Definition: advancedDetector.h:120
const ADGameDescription * desc
Definition: advancedDetector.h:189
Definition: game.h:122
const char * fileName
Name of the described file.
Definition: advancedDetector.h:51
const ADGameDescription * desc
Definition: advancedDetector.h:213
const char * gameId
Definition: advancedDetector.h:126
Do not add platform to gameid.
Definition: advancedDetector.h:110
ADDetectedGame(const ADGameDescription *d)
Definition: advancedDetector.h:195
MD5Properties
Definition: game.h:106
Definition: game.h:64
Definition: path.h:52
No flags.
Definition: advancedDetector.h:96
uint16 fileType
Optional. Not used during detection, only by engines.
Definition: advancedDetector.h:52
virtual ADDetectedGame fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist, ADDetectedGameExtraInfo **extra=nullptr) const
Definition: advancedDetector.h:418
Definition: advancedDetector.h:247
Definition: advancedDetector.h:272
uint _md5Bytes
Definition: advancedDetector.h:315
Definition: game.h:49
bool hasUnknownFiles
Definition: advancedDetector.h:187
uint32 flags
Definition: advancedDetector.h:163
Add "-dvd" to gameid.
Definition: advancedDetector.h:112
Calculate the MD5 for this entry from the resource fork.
Definition: advancedDetector.h:107
ADGameFlags
Definition: advancedDetector.h:95
ADFlags
Definition: advancedDetector.h:223
Definition: archive.h:141
Definition: advancedDetector.h:487
int64 fileSize
Size of the described file. Set to -1 to ignore.
Definition: advancedDetector.h:54
Flag to designate not yet officially supported games that are fit for public testing.
Definition: advancedDetector.h:100
Common::Language language
Definition: advancedDetector.h:150
Do not add language to gameid.
Definition: advancedDetector.h:109
Definition: metaengine.h:69
uint32 _maxScanDepth
Definition: advancedDetector.h:338
Add "-cd" to gameid.
Definition: advancedDetector.h:111
Automatically generate gameid from ADGameDescription::extra.
Definition: advancedDetector.h:98
Use ADGameDescription::extra as the main game title, not gameid.
Definition: advancedDetector.h:108
Path getPath() const
ExtraGuiOption option
Definition: advancedDetector.h:274
Definition: advancedDetector.h:264
int getGameVariantCount() const override final
Definition: advancedDetector.h:399
Definition: algorithm.h:29
Definition: fs.h:69
Definition: advancedDetector.h:102
Definition: advancedDetector.h:576
const char * guiOptions
Definition: advancedDetector.h:172
Definition: metaengine.h:139
Definition: fs.h:57
Flag to designate well-known pirated versions with cracks.
Definition: advancedDetector.h:101
Definition: advancedDetector.h:186
int _fullPathGlobsDepth
Definition: advancedDetector.h:362
Calculate the MD5 for this entry from the end of the file.
Definition: advancedDetector.h:97
Definition: advancedDetector.h:208
Definition: advancedDetector.h:104
uint32 _flags
Definition: advancedDetector.h:323
Common::String targetID
Definition: advancedDetector.h:180
Common::HashMap< Common::Path, Common::FSNode, Common::Path::IgnoreCase_Hash, Common::Path::IgnoreCase_EqualTo > FileMap
Definition: advancedDetector.h:412
Definition: system.h:175
FilePropertiesMap matchedFiles
Definition: advancedDetector.h:188
const char *const * _directoryGlobs
Definition: advancedDetector.h:348
Add "-demo" to gameid.
Definition: advancedDetector.h:113
Common::Platform platform
Definition: advancedDetector.h:155
int _maxAutogenLength
Definition: advancedDetector.h:355
Definition: engine.h:143
const byte * _gameDescriptors
Definition: advancedDetector.h:291
Definition: advancedDetector.h:234
Platform
Definition: platform.h:46
Add "-remastered&#39; to gameid.
Definition: advancedDetector.h:114
Definition: singleton.h:42
const char * guioFlag
Definition: advancedDetector.h:273
Common::String gameName
Definition: advancedDetector.h:179
Language
Definition: language.h:45
uint getMD5Bytes() const override final
Definition: advancedDetector.h:397
Definition: advancedDetector.h:50