diff --git a/Src/GameLoader.cpp b/Src/GameLoader.cpp index a32a0fa6..566c446b 100644 --- a/Src/GameLoader.cpp +++ b/Src/GameLoader.cpp @@ -663,7 +663,6 @@ void GameLoader::IdentifyGamesInZipArchive( void GameLoader::ChooseGameInZipArchive(std::string *chosen_game, bool *missing_parent_roms, const ZipArchive &zip, const std::string &zipfilename) const { - chosen_game->clear(); *missing_parent_roms = false; // Find complete unmerged games (those that do not need to be merged with a @@ -725,6 +724,25 @@ void GameLoader::ChooseGameInZipArchive(std::string *chosen_game, bool *missing_ ErrorLog("Ignoring game '%s' in '%s' because it is missing files.", v.first.c_str(), zipfilename.c_str()); } + std::set candidates(complete_games); + candidates.insert(complete_merged_games.begin(), complete_merged_games.end()); + candidates.insert(incomplete_child_games.begin(), incomplete_child_games.end()); + + // If named game requested, is it valid and complete? + if (!chosen_game->empty()) { + if (candidates.count(chosen_game->c_str()) < 1) { + auto it = m_game_info_by_game.find(chosen_game->c_str()); + if (it == m_game_info_by_game.end()) + { + ErrorLog("Cannot find unknown game '%s'. Is it defined in '%s'?", chosen_game->c_str(), m_xml_filename.c_str()); + } else { + ErrorLog("Complete '%s' Model 3 game not found in '%s'.", chosen_game->c_str(), zipfilename.c_str()); + } + chosen_game->clear(); + } + return; + } + // Choose game: complete merged game > incomplete child game > complete // unmerged game if (!complete_merged_games.empty()) @@ -744,9 +762,6 @@ void GameLoader::ChooseGameInZipArchive(std::string *chosen_game, bool *missing_ } // Print out which game we chose from valid candidates in the zip file - std::set candidates(complete_games); - candidates.insert(complete_merged_games.begin(), complete_merged_games.end()); - candidates.insert(incomplete_child_games.begin(), incomplete_child_games.end()); if (candidates.size() > 1) ErrorLog("Multiple games found in '%s' (%s). Loading '%s'.", zipfilename.c_str(), Util::Format(", ").Join(candidates).str().c_str(), chosen_game->c_str()); } @@ -968,7 +983,7 @@ std::string StripFilename(const std::string &filepath) return std::string(filepath, 0, last_slash + 1); } -bool GameLoader::Load(Game *game, ROMSet *rom_set, const std::string &zipfilename) const +bool GameLoader::Load(Game *game, ROMSet *rom_set, const std::string &zipfilename, const std::string &game_name) const { *game = Game(); @@ -978,7 +993,7 @@ bool GameLoader::Load(Game *game, ROMSet *rom_set, const std::string &zipfilenam return true; // Pick the game to load (there could be multiple ROM sets in a zip file) - std::string chosen_game; + std::string chosen_game = game_name; bool missing_parent_roms = false; ChooseGameInZipArchive(&chosen_game, &missing_parent_roms, zip, zipfilename); if (chosen_game.empty()) diff --git a/Src/GameLoader.h b/Src/GameLoader.h index 70703bcb..816adca5 100644 --- a/Src/GameLoader.h +++ b/Src/GameLoader.h @@ -104,7 +104,7 @@ class GameLoader public: GameLoader(const std::string &xml_file); - bool Load(Game *game, ROMSet *rom_set, const std::string &zipfilename) const; + bool Load(Game *game, ROMSet *rom_set, const std::string &zipfilename, const std::string &game_name) const; const std::map &GetGames() const { return m_game_info_by_game; diff --git a/Src/OSD/SDL/Main.cpp b/Src/OSD/SDL/Main.cpp index dc37b669..710e74fa 100644 --- a/Src/OSD/SDL/Main.cpp +++ b/Src/OSD/SDL/Main.cpp @@ -1558,6 +1558,7 @@ static void Help(void) printf(" -game-xml-file= ROM set definition file [Default: %s]\n", s_gameXMLFilePath.c_str()); printf(" -log-output= Log output destination(s) [Default: %s]\n", s_logFilePath.c_str()); puts(" -log-level= Logging threshold [Default: info]"); + puts(" -game= Specific game to start in multi-romset"); puts(""); puts("Core Options:"); puts(" -ppc-frequency= PowerPC frequency (default varies by stepping)"); @@ -1645,6 +1646,7 @@ struct ParsedCommandLine { Util::Config::Node config = Util::Config::Node("CommandLine"); std::vector rom_files; + std::string game_name; bool error = false; bool print_help = false; bool print_games = false; @@ -1880,6 +1882,17 @@ static ParsedCommandLine ParseCommandLine(int argc, char **argv) cmd_line.gfx_state = parts[1]; } #endif + else if (arg == "-game" || arg.find("-game=") == 0) + { + std::vector parts = Util::Format(arg).Split('='); + if (parts.size() != 2) + { + ErrorLog("'-game' requires a name."); + cmd_line.error = true; + } + else + cmd_line.game_name = parts[1]; + } else { ErrorLog("Ignoring unrecognized option: %s", argv[i]); @@ -1973,7 +1986,7 @@ int main(int argc, char **argv) PrintGameList(xml_file, loader.GetGames()); return 0; } - if (loader.Load(&game, &rom_set, *cmd_line.rom_files.begin())) + if (loader.Load(&game, &rom_set, *cmd_line.rom_files.begin(), cmd_line.game_name)) return 1; Util::Config::MergeINISections(&config4, config3, fileConfig[game.name]); // apply game-specific config }