mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-25 23:25:40 +00:00
Smarter game selection when a zip file contains multiple games (prefer child when parent is also present in zip)
This commit is contained in:
parent
e40d268214
commit
b0957e6459
|
@ -276,6 +276,15 @@ bool GameLoader::ParseXML(const Util::Config::Node &xml)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GameLoader::LoadDefinitionXML(const std::string &filename)
|
||||||
|
{
|
||||||
|
m_xml_filename = filename;
|
||||||
|
Util::Config::Node xml("xml");
|
||||||
|
if (Util::Config::FromXMLFile(&xml, filename))
|
||||||
|
return true;
|
||||||
|
return ParseXML(xml);
|
||||||
|
}
|
||||||
|
|
||||||
std::set<std::string> GameLoader::IdentifyCompleteGamesInZipArchive(const ZipArchive &zip) const
|
std::set<std::string> GameLoader::IdentifyCompleteGamesInZipArchive(const ZipArchive &zip) const
|
||||||
{
|
{
|
||||||
std::set<std::string> complete_games;
|
std::set<std::string> complete_games;
|
||||||
|
@ -490,15 +499,6 @@ bool GameLoader::LoadROMs(ROMSet *rom_set, const std::string &game_name, const Z
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GameLoader::LoadDefinitionXML(const std::string &filename)
|
|
||||||
{
|
|
||||||
m_xml_filename = filename;
|
|
||||||
Util::Config::Node xml("xml");
|
|
||||||
if (Util::Config::FromXMLFile(&xml, filename))
|
|
||||||
return true;
|
|
||||||
return ParseXML(xml);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string StripFilename(const std::string &filepath)
|
std::string StripFilename(const std::string &filepath)
|
||||||
{
|
{
|
||||||
// Search for last '/' or '\', if any
|
// Search for last '/' or '\', if any
|
||||||
|
@ -520,6 +520,36 @@ std::string StripFilename(const std::string &filepath)
|
||||||
return std::string(filepath, 0, last_slash + 1);
|
return std::string(filepath, 0, last_slash + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A heuristic is used that favors child sets with present parent
|
||||||
|
std::string GameLoader::ChooseGame(const std::set<std::string> &games_found) const
|
||||||
|
{
|
||||||
|
// Identify children sets and parent sets
|
||||||
|
std::set<std::string> parents;
|
||||||
|
std::set<std::string> children;
|
||||||
|
for (auto &game_name: games_found)
|
||||||
|
{
|
||||||
|
auto it = m_game_info_by_game.find(game_name);
|
||||||
|
const Game &game = it->second;
|
||||||
|
if (game.parent.empty())
|
||||||
|
parents.insert(game_name);
|
||||||
|
else
|
||||||
|
children.insert(game_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the first child set whose parent is also present
|
||||||
|
for (auto &child: children)
|
||||||
|
{
|
||||||
|
auto it = m_game_info_by_game.find(child);
|
||||||
|
const Game &game = it->second;
|
||||||
|
const std::string &parent = game.parent;
|
||||||
|
if (parents.count(parent) > 0)
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, just grab whatever is first
|
||||||
|
return *games_found.begin();
|
||||||
|
}
|
||||||
|
|
||||||
bool GameLoader::Load(Game *game, ROMSet *rom_set, const std::string &zipfilename)
|
bool GameLoader::Load(Game *game, ROMSet *rom_set, const std::string &zipfilename)
|
||||||
{
|
{
|
||||||
*game = Game();
|
*game = Game();
|
||||||
|
@ -534,11 +564,14 @@ bool GameLoader::Load(Game *game, ROMSet *rom_set, const std::string &zipfilenam
|
||||||
ErrorLog("No complete Model 3 games found in '%s'.", zipfilename.c_str());
|
ErrorLog("No complete Model 3 games found in '%s'.", zipfilename.c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (games_found.size() > 1)
|
|
||||||
ErrorLog("Multiple games found in '%s' (%s). Loading '%s'.", zipfilename.c_str(), std::string(Util::Format(", ").Join(games_found)).c_str(), games_found.begin()->c_str());
|
|
||||||
|
|
||||||
// Pick the first game in the first zip file
|
// Pick the game to load (if there are multiple games present)
|
||||||
*game = m_game_info_by_game[*games_found.begin()];
|
std::string chosen_game = ChooseGame(games_found);
|
||||||
|
if (games_found.size() > 1)
|
||||||
|
ErrorLog("Multiple games found in '%s' (%s). Loading '%s'.", zipfilename.c_str(), std::string(Util::Format(", ").Join(games_found)).c_str(), chosen_game.c_str());
|
||||||
|
|
||||||
|
// Return game information to caller
|
||||||
|
*game = m_game_info_by_game[chosen_game];
|
||||||
|
|
||||||
// If there is a parent ROM set, determine where it is 1) contained in the
|
// If there is a parent ROM set, determine where it is 1) contained in the
|
||||||
// same zip file or 2) try loading it from the same directory
|
// same zip file or 2) try loading it from the same directory
|
||||||
|
|
|
@ -68,11 +68,12 @@ private:
|
||||||
const ZippedFile *LookupFile(const File::ptr_t &file, const ZipArchive &zip) const;
|
const ZippedFile *LookupFile(const File::ptr_t &file, const ZipArchive &zip) const;
|
||||||
static bool MissingAttrib(const GameLoader &loader, const Util::Config::Node &node, const std::string &attribute);
|
static bool MissingAttrib(const GameLoader &loader, const Util::Config::Node &node, const std::string &attribute);
|
||||||
bool ParseXML(const Util::Config::Node &xml);
|
bool ParseXML(const Util::Config::Node &xml);
|
||||||
|
bool LoadDefinitionXML(const std::string &filename);
|
||||||
std::set<std::string> IdentifyCompleteGamesInZipArchive(const ZipArchive &zip) const;
|
std::set<std::string> IdentifyCompleteGamesInZipArchive(const ZipArchive &zip) const;
|
||||||
bool ComputeRegionSize(uint32_t *region_size, const Region::ptr_t ®ion, const ZipArchive &zip) const;
|
bool ComputeRegionSize(uint32_t *region_size, const Region::ptr_t ®ion, const ZipArchive &zip) const;
|
||||||
bool LoadRegion(ROM *buffer, const GameLoader::Region::ptr_t ®ion, const ZipArchive &zip);
|
bool LoadRegion(ROM *buffer, const GameLoader::Region::ptr_t ®ion, const ZipArchive &zip);
|
||||||
bool LoadROMs(ROMSet *rom_set, const std::string &game_name, const ZipArchive *zip, const std::string &parent_name, const ZipArchive *parent_zip);
|
bool LoadROMs(ROMSet *rom_set, const std::string &game_name, const ZipArchive *zip, const std::string &parent_name, const ZipArchive *parent_zip);
|
||||||
bool LoadDefinitionXML(const std::string &filename);
|
std::string ChooseGame(const std::set<std::string> &games_found) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GameLoader(const std::string &xml_file);
|
GameLoader(const std::string &xml_file);
|
||||||
|
|
Loading…
Reference in a new issue