Difference between revisions of "Advanced Detector"

Jump to navigation Jump to search
326 bytes removed ,  00:15, 24 April 2021
→‎How Advanced Detector works: Add some details about possibility to run games detected by the file-based fallback detection
m (Text replacement - "<source lang=" to "<syntaxhighlight lang=")
(→‎How Advanced Detector works: Add some details about possibility to run games detected by the file-based fallback detection)
(3 intermediate revisions by 2 users not shown)
Line 18: Line 18:
The code for this can be found in <tt>engines/advancedDetector.*</tt>
The code for this can be found in <tt>engines/advancedDetector.*</tt>


To use this, you will have to follow the instructions [[HOWTO-Engines#Subclassing_MetaEngine|here]], but you will subclass AdvancedMetaEngine instead within your engine's detection.h and detection.cpp.
To use this, you will have to follow the instructions [[HOWTO-Engines#Subclassing_AdvancedMetaEngine|here]] within your engine's detection.h and detection.cpp.


All you will have to provide is a standard data table of ADGameDescription entries describing each game variant, which is usually placed in a separate detection_tables.h header, which is included in detection.cpp for use there.
All you will have to provide is a standard data table of ADGameDescription entries describing each game variant, which is usually placed in a separate detection_tables.h header, which is included in detection.cpp for use there.


This structure plus other parameters are passed to the AdvancedMetaEngine constructor, which can also contain overrides of the default parameters for detection e.g. _md5Bytes is the number of bytes used for the MD5 hash for each file, etc.
This structure plus other parameters are passed to the AdvancedMetaEngineDetection constructor, which can also contain overrides of the default parameters for detection e.g. _md5Bytes is the number of bytes used for the MD5 hash for each file, etc.


It is suggested you consult the code and header comments in <tt>engines/advancedDetector.*</tt> and look at the examples provided by current engines for a more complete example.
It is suggested you consult the code and header comments in <tt>engines/advancedDetector.*</tt> and look at the examples provided by current engines for a more complete example.
Line 38: Line 38:
description=Monkey Island 2: LeChuck's Revenge (DOS/English)
description=Monkey Island 2: LeChuck's Revenge (DOS/English)
path=/Users/sev/games/scumm/monkey2
path=/Users/sev/games/scumm/monkey2
engindid=scumm
gameid=monkey2
gameid=monkey2
language=en
language=en
platform=pc
platform=pc
</source>
</syntaxhighlight>


What you see here is several sections designated by identifiers in square brackets and set of key/value pairs belonging to each such section.
What you see here is several sections designated by identifiers in square brackets and set of key/value pairs belonging to each such section.
Line 49: Line 50:
Name of each game is what we are calling '''target'''. Target, which is in the sample above specified as ''monkey2-vga'' is user-editable identifier unique to the specific user, and could be used for launching the game from command line.
Name of each game is what we are calling '''target'''. Target, which is in the sample above specified as ''monkey2-vga'' is user-editable identifier unique to the specific user, and could be used for launching the game from command line.


Then each entry has '''description''' which is also user-editable, '''path''' to the game, and '''gameid'''. '''gameid''' is a service name which identifies the game within whole ScummVM. There should be no clashes, and each engine knows which gameids it does support. First engine which finds a match for a given gameid will be used to run the game. This is why it is important to keep this ID unique, since there is no guarantee in sequence of engines which ScummVM probes when launching a game.
Then each entry has '''description''' which is also user-editable, '''path''' to the game, '''engineid''' and '''gameid'''. '''engineid''' is a service name which identifies the engine within whole ScummVM. There should be no clashes, and each engine knows which gameids it does support, so '''gameid''' is only unique to each engine.


Keys '''platform''' and '''language''' are used for narrowing down the possible game candidate but are fully optional.
Keys '''platform''' and '''language''' are used for narrowing down the possible game candidate but are fully optional.
Line 67: Line 68:
In the running mode Advanced Detector tries to match as much information stored in the config game entry as possible. The typical keys it matches against are '''gameid''', '''platform''' and '''language''', but it may also use '''extra''' when instructed to do so.
In the running mode Advanced Detector tries to match as much information stored in the config game entry as possible. The typical keys it matches against are '''gameid''', '''platform''' and '''language''', but it may also use '''extra''' when instructed to do so.


In case there are no matches in the ''ADGameDescription'' list, there are two additional fallback detection modes. One is file-based detection, which matches just the file names, and second one is a hook which gets called and could contain code of any complexity. The most prominent example of advanced fallback detection is SCI engine.
In case there are no matches in the ''ADGameDescription'' list, there are two additional fallback detection modes. One is file-based detection, which matches just the file names, and second one is a hook which gets called and could contain code of any complexity. The most prominent example of advanced fallback detection is SCI engine. Note that by default the file-based fallback detection doesn't allow to add the games to ScummVM or start them, and is only used to report to the user that a possible unknown variant was found. This behaviour can be changed by reimplementing <syntaxhighlight lang="cpp" inline>bool canPlayUnknownVariants() const</syntaxhighlight > to return true in the derived class.  


=== Generated targets ===
=== Generated targets ===
Line 84: Line 85:
const char *description;
const char *description;
};
};
</source>
</syntaxhighlight>


This table contains all gameids which are known by the engine. Also each gameid contains a full human-readable description, which is used to provide the '''description''' field in the ScummVM configuration file.
This table contains all gameids which are known by the engine. Also each gameid contains a full human-readable description, which is used to provide the '''description''' field in the ScummVM configuration file.
Line 99: Line 100:
{0, 0}
{0, 0}
};
};
</source>
</syntaxhighlight>


Please note that it is NULL-terminated, and also contains the generic gameid ''cine'' which is used by fallback detection.
Please note that it is NULL-terminated, and also contains the generic gameid ''cine'' which is used by fallback detection.
Line 117: Line 118:
const char *guioptions;
const char *guioptions;
};
};
</source>
</syntaxhighlight>


'''gameid''' -- This is the gameid. Mainly it is used for taking the game description from the ''PlainGameDescriptor'' table.
'''gameid''' -- This is the gameid. Mainly it is used for taking the game description from the ''PlainGameDescriptor'' table.
Line 143: Line 144:
AD_ENTRY1("part01", "61d003202d301c29dd399acfb1354310"),
AD_ENTRY1("part01", "61d003202d301c29dd399acfb1354310"),
Common::EN_ANY,
Common::EN_ANY,
Common::kPlatformPC,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
ADGF_NO_FLAGS,
GUIO0()
GUIO0()
Line 149: Line 150:
{ AD_TABLE_END_MARKER, 0, 0 }
{ AD_TABLE_END_MARKER, 0, 0 }
};
};
</source>
</syntaxhighlight>


== ADGameFileDescription structure ==
== ADGameFileDescription structure ==
Line 160: Line 161:
int32 fileSize;  ///< Size of the described file. Set to -1 to ignore.
int32 fileSize;  ///< Size of the described file. Set to -1 to ignore.
};
};
</source>
</syntaxhighlight>


'''fileName''' -- name of the file. It is case insensitive, but historically we use lowercase names.
'''fileName''' -- name of the file. It is case insensitive, but historically we use lowercase names.
Line 166: Line 167:
'''fileType''' -- rarely used field where ''ADGameFileDescription'' structure is used by the engine. May specify music file, script file, etc.
'''fileType''' -- rarely used field where ''ADGameFileDescription'' structure is used by the engine. May specify music file, script file, etc.


'''md5''' -- MD5 of the file. Most often it is MD5 of the beginning of the file for performance reasons. See '''_md5Bytes''' setting of ''AdvancedMetaEngine''. If set to NULL, the md5 is not used in detection and the entry matches against any content.
'''md5''' -- MD5 of the file. Most often it is MD5 of the beginning of the file for performance reasons. See '''_md5Bytes''' setting of ''AdvancedMetaEngineDetection''. If set to NULL, the md5 is not used in detection and the entry matches against any content.


'''fileSize''' -- file size in bytes. Optional too, set to -1 in order to match against any file size.
'''fileSize''' -- file size in bytes. Optional too, set to -1 in order to match against any file size.
Line 206: Line 207:
         {"simon1acorn", "simon1", Common::kPlatformAcorn},
         {"simon1acorn", "simon1", Common::kPlatformAcorn},
         {"simon1amiga", "simon1", Common::kPlatformAmiga},
         {"simon1amiga", "simon1", Common::kPlatformAmiga},
         {"simon2talkie", "simon2", Common::kPlatformPC},
         {"simon2talkie", "simon2", Common::kPlatformDOS},
         {"simon2mac", "simon2", Common::kPlatformMacintosh},
         {"simon2mac", "simon2", Common::kPlatformMacintosh},
         {"simon2win", "simon2", Common::kPlatformWindows},
         {"simon2win", "simon2", Common::kPlatformWindows},
         {0, 0, Common::kPlatformUnknown}
         {0, 0, Common::kPlatformUnknown}
};
};
</source>
</syntaxhighlight>


= AdvancedMetaEngine =
= AdvancedMetaEngineDetection =


Is a generic MetaEngine wrapper which is aware of the Advanced Detector. It should be used whenever AD is used.
Is a generic MetaEngine wrapper which is aware of the Advanced Detector. It should be used whenever AD is used.
Line 220: Line 221:


<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
AdvancedMetaEngine(const void *descs, uint descItemSize, const PlainGameDescriptor *gameids);
AdvancedMetaEngineDetection(const void *descs, uint descItemSize, const PlainGameDescriptor *gameIds);
</source>
</syntaxhighlight>


'''descs''' must point to a list of ''ADGameDescription'' structures, or their supersets.
'''descs''' must point to a list of ''ADGameDescription'' structures, or their supersets.
Line 227: Line 228:
'''descItemSize''' is sizeof of the '''descs''' element used for iterating over it.
'''descItemSize''' is sizeof of the '''descs''' element used for iterating over it.


'''gameids''' must point to a list of ''PlainGameDescriptor'' structures defining supported gameids.
'''gameIds''' must point to a list of ''PlainGameDescriptor'' structures defining supported gameids.


== Additional Advanced MetaEngine parameters ==
== Additional Advanced MetaEngine parameters ==


'''_md5bytes''' -- number of bytes used to compute md5. If set to 0 then whole file will be used. Beware of doing this if your detection might encounter large files, since that can dramatically slow down the detection. Typically a sane value is 5000 bytes (the default), but often experimentation is required for many game variants with subtle differences.
'''_md5Bytes''' -- number of bytes used to compute md5. If set to 0 then whole file will be used. Beware of doing this if your detection might encounter large files, since that can dramatically slow down the detection. Typically a sane value is 5000 bytes (the default), but often experimentation is required for many game variants with subtle differences.
 
'''_singleid''' -- Used to override gameid. A recommended setting to prevent global gameid pollution. With this option set, the gameid effectively turns into engineid.
 
In the past we started to have clashes in game names, thus the option was introduced. Also it was mentioned that in the ideal world it should be enough to point just the game directory and ScummVM correctly detects and runs the game. This is a step towards this direction, however there are several cases when it is not possible to identify the game to run, particularly in those cases when there are more than single game stored in a directory.


'''_flags''' -- same as individual game flags but user for engine-wide settings. For instance, we know for sure that all games in the engine are unstable, so instead of modifying every game entry, we specify it here.
'''_flags''' -- same as individual game flags but user for engine-wide settings. For instance, we know for sure that all games in the engine are unstable, so instead of modifying every game entry, we specify it here.


'''_guioptions''' -- same as individual GUI options, but applied engine-wide. For example, when none of the games have speech, we may specify it in this spot.
'''_guiOptions''' -- same as individual GUI options, but applied engine-wide. For example, when none of the games have speech, we may specify it in this spot.


'''_maxScanDepth''' -- Maximum traversal depth for directories. Default is 1, that is do not go inside of subdirectories for detection.
'''_maxScanDepth''' -- Maximum traversal depth for directories. Default is 1, that is do not go inside of subdirectories for detection.
TrustedUser
2,147

edits

Navigation menu