BASE: Allow listing save games for all targets

This commit is contained in:
Thierry Crozat 2018-04-22 12:00:27 +01:00
parent 5907add148
commit cb02d7471d
2 changed files with 67 additions and 37 deletions

6
README
View file

@ -1463,7 +1463,8 @@ arguments -- see the next section.
-h, --help Display a brief help text and exit
-z, --list-games Display list of supported games and exit
-t, --list-targets Display list of configured targets and exit
--list-saves Display a list of saved games for the target specified with --game=TARGET
--list-saves Display a list of saved games for the target specified
with --game=TARGET, or all targets if none is specified
-a, --add Add all games from current or specified directory.
If --game=ID is passed only the game with id ID is
added. See also --detect.
@ -2009,7 +2010,8 @@ Where 'xxx' is exact the saved game slot (i.e., 001) under ScummVM
--list-saves:
This switch may be used to display a list of the current saved games
of the specified target game and their corresponding save slots.
of the specified target game and their corresponding save slots. If no
target is specified, it lists saved games for all known target.
Usage: --list-saves --game=[TARGET], where [TARGET] is the target game.

View file

@ -68,7 +68,8 @@ static const char HELP_STRING[] =
" -h, --help Display a brief help text and exit\n"
" -z, --list-games Display list of supported games and exit\n"
" -t, --list-targets Display list of configured targets and exit\n"
" --list-saves Display a list of saved games for the target specified with --game=TARGET\n"
" --list-saves Display a list of saved games for the target specified\n"
" with --game=TARGET, or all targets if none is specified\n"
" -a, --add Add all games from current or specified directory.\n"
" If --game=ID is passed only the game with id ID is added. See also --detect\n"
" Use --path=PATH to specify a directory.\n"
@ -732,67 +733,94 @@ static void listTargets() {
static Common::Error listSaves(const Common::String &target) {
Common::Error result = Common::kNoError;
// TODO: Make the target argument optional. If no argument is given, list all saved games
// for all configured targets.
if (target.empty())
usage("You must specify a target using --game=TARGET when using --list-saves.");
// If no target is specified, list save games for all known targets
Common::Array<Common::String> targets;
if (!target.empty())
targets.push_back(target);
else {
const Common::ConfigManager::DomainMap &domains = ConfMan.getGameDomains();
Common::ConfigManager::DomainMap::const_iterator iter;
targets.reserve(domains.size());
for (iter = domains.begin(); iter != domains.end(); ++iter)
targets.push_back(iter->_key);
}
// FIXME HACK
g_system->initBackend();
// Grab the "target" domain, if any
const Common::ConfigManager::Domain *domain = ConfMan.getDomain(target);
// Set up the game domain as newly active domain, so
// target specific savepath will be checked
Common::String oldDomain = ConfMan.getActiveDomainName();
ConfMan.setActiveDomain(target);
// Grab the gameid from the domain resp. use the target as gameid
Common::String gameid;
if (domain)
gameid = domain->getVal("gameid");
if (gameid.empty())
gameid = target;
gameid.toLowercase(); // Normalize it to lower case
bool atLeastOneFound = false;
for (Common::Array<Common::String>::const_iterator i = targets.begin(), end = targets.end(); i != end; ++i) {
// Grab the "target" domain, if any
const Common::ConfigManager::Domain *domain = ConfMan.getDomain(*i);
// Find the plugin that will handle the specified gameid
const Plugin *plugin = nullptr;
GameDescriptor game = EngineMan.findGame(gameid, &plugin);
// Set up the game domain as newly active domain, so
// target specific savepath will be checked
ConfMan.setActiveDomain(*i);
if (!plugin) {
return Common::Error(Common::kEnginePluginNotFound,
Common::String::format("target '%s', gameid '%s", target.c_str(), gameid.c_str()));
}
// Grab the gameid from the domain resp. use the target as gameid
Common::String gameid;
if (domain)
gameid = domain->getVal("gameid");
if (gameid.empty())
gameid = *i;
gameid.toLowercase(); // Normalize it to lower case
const MetaEngine &metaEngine = plugin->get<MetaEngine>();
// Find the plugin that will handle the specified gameid
const Plugin *plugin = nullptr;
GameDescriptor game = EngineMan.findGame(gameid, &plugin);
if (!plugin) {
// If the target was specified, treat this as an error, and otherwise skip it.
if (!target.empty())
return Common::Error(Common::kEnginePluginNotFound,
Common::String::format("target '%s', gameid '%s", i->c_str(), gameid.c_str()));
printf("Plugin could not be loaded for target '%s', gameid '%s", i->c_str(), gameid.c_str());
continue;
}
const MetaEngine &metaEngine = plugin->get<MetaEngine>();
if (!metaEngine.hasFeature(MetaEngine::kSupportsListSaves)) {
// If the target was specified, treat this as an error, and otherwise skip it.
if (!target.empty())
// TODO: Include more info about the target (desc, engine name, ...) ???
return Common::Error(Common::kEnginePluginNotSupportSaves,
Common::String::format("target '%s', gameid '%s", i->c_str(), gameid.c_str()));
continue;
}
if (!metaEngine.hasFeature(MetaEngine::kSupportsListSaves)) {
// TODO: Include more info about the target (desc, engine name, ...) ???
return Common::Error(Common::kEnginePluginNotSupportSaves,
Common::String::format("target '%s', gameid '%s", target.c_str(), gameid.c_str()));
} else {
// Query the plugin for a list of saved games
SaveStateList saveList = metaEngine.listSaves(target.c_str());
SaveStateList saveList = metaEngine.listSaves(i->c_str());
if (saveList.size() > 0) {
// TODO: Include more info about the target (desc, engine name, ...) ???
printf("Save states for target '%s' (gameid '%s'):\n", target.c_str(), gameid.c_str());
if (atLeastOneFound)
printf("\n");
printf("Save states for target '%s' (gameid '%s'):\n", i->c_str(), gameid.c_str());
printf(" Slot Description \n"
" ---- ------------------------------------------------------\n");
" ---- ------------------------------------------------------\n");
for (SaveStateList::const_iterator x = saveList.begin(); x != saveList.end(); ++x) {
printf(" %-4d %s\n", x->getSaveSlot(), x->getDescription().c_str());
// TODO: Could also iterate over the full hashmap, printing all key-value pairs
}
atLeastOneFound = true;
} else {
printf("There are no save states for target '%s' (gameid '%s'):\n", target.c_str(), gameid.c_str());
// If the target was specified, indicate no save games were found for it. Otherwise just skip it.
if (!target.empty())
printf("There are no save states for target '%s' (gameid '%s'):\n", i->c_str(), gameid.c_str());
}
}
// Revert to the old active domain
ConfMan.setActiveDomain(oldDomain);
if (!atLeastOneFound && target.empty())
printf("No save states could be found.\n");
return result;
}