From a8b4e14bf526b4983eab8cc544263ee3d28412f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quang=20Ng=C3=B4?= Date: Sat, 28 Dec 2024 21:35:12 +0700 Subject: [PATCH] Fix SDL version cannot launch game using game ID (#1650) * Fix SDL version cannot launch game using game ID Missing from https://github.com/shadps4-emu/shadPS4/pull/1507. * Added --add-game-folder argument Also added "treat the last argument as the game, if it isn't found already" option to the qt version --------- Co-authored-by: kalaposfos13 <153381648+kalaposfos13@users.noreply.github.com> --- src/main.cpp | 58 +++++++++++++++++++++++++++++++++++++++++---- src/qt_gui/main.cpp | 35 +++++++++++++++++++++++---- 2 files changed, 83 insertions(+), 10 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 17b5c11f..bdbab89c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,11 +4,14 @@ #include "functional" #include "iostream" #include "string" +#include "system_error" #include "unordered_map" #include #include "common/config.h" #include "common/memory_patcher.h" +#include "common/path_util.h" +#include "core/file_sys/fs.h" #include "emulator.h" #ifdef _WIN32 @@ -20,6 +23,10 @@ int main(int argc, char* argv[]) { SetConsoleOutputCP(CP_UTF8); #endif + // Load configurations + const auto user_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir); + Config::load(user_dir / "config.toml"); + bool has_game_argument = false; std::string game_path; @@ -33,6 +40,7 @@ int main(int argc, char* argv[]) { " -p, --patch Apply specified patch file\n" " -f, --fullscreen Specify window initial fullscreen " "state. Does not overwrite the config file.\n" + " --add-game-folder Adds a new game folder to the config.\n" " -h, --help Display this help message\n"; exit(0); }}, @@ -81,6 +89,25 @@ int main(int argc, char* argv[]) { Config::setFullscreenMode(is_fullscreen); }}, {"--fullscreen", [&](int& i) { arg_map["-f"](i); }}, + {"--add-game-folder", + [&](int& i) { + if (++i >= argc) { + std::cerr << "Error: Missing argument for --add-game-folder\n"; + exit(1); + } + std::string config_dir(argv[i]); + std::filesystem::path config_path = std::filesystem::path(config_dir); + std::error_code discard; + if (!std::filesystem::exists(config_path, discard)) { + std::cerr << "Error: File does not exist: " << config_path << "\n"; + exit(1); + } + + Config::addGameInstallDir(config_path); + Config::save(Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "config.toml"); + std::cout << "Game folder successfully saved.\n"; + exit(0); + }}, }; if (argc == 1) { @@ -105,20 +132,41 @@ int main(int argc, char* argv[]) { } } + // If no game directory is set and no command line argument, prompt for it + if (Config::getGameInstallDirs().empty()) { + std::cout << "Warning: No game folder set, please set it by calling shadps4" + " with the --add-game-folder argument"; + } + if (!has_game_argument) { std::cerr << "Error: Please provide a game path or ID.\n"; exit(1); } // Check if the game path or ID exists - if (!std::filesystem::exists(game_path)) { - std::cerr << "Error: Game file not found\n"; - return -1; + std::filesystem::path eboot_path(game_path); + + // Check if the provided path is a valid file + if (!std::filesystem::exists(eboot_path)) { + // If not a file, treat it as a game ID and search in install directories + bool game_found = false; + for (const auto& install_dir : Config::getGameInstallDirs()) { + const auto candidate_path = install_dir / game_path / "eboot.bin"; + if (std::filesystem::exists(candidate_path)) { + eboot_path = candidate_path; + game_found = true; + break; + } + } + if (!game_found) { + std::cerr << "Error: Game ID or file path not found: " << game_path << std::endl; + return 1; + } } - // Run the emulator with the specified game + // Run the emulator with the resolved eboot path Core::Emulator emulator; - emulator.Run(game_path); + emulator.Run(eboot_path); return 0; } diff --git a/src/qt_gui/main.cpp b/src/qt_gui/main.cpp index 31824505..ac731fdc 100644 --- a/src/qt_gui/main.cpp +++ b/src/qt_gui/main.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "iostream" +#include "system_error" #include "unordered_map" #include "common/config.h" @@ -31,7 +32,7 @@ int main(int argc, char* argv[]) { bool has_command_line_argument = argc > 1; bool show_gui = false, has_game_argument = false; - std::string gamePath; + std::string game_path; // Map of argument strings to lambda functions std::unordered_map> arg_map = { @@ -46,6 +47,7 @@ int main(int argc, char* argv[]) { " -s, --show-gui Show the GUI\n" " -f, --fullscreen Specify window initial fullscreen " "state. Does not overwrite the config file.\n" + " --add-game-folder Adds a new game folder to the config.\n" " -h, --help Display this help message\n"; exit(0); }}, @@ -57,7 +59,7 @@ int main(int argc, char* argv[]) { {"-g", [&](int& i) { if (i + 1 < argc) { - gamePath = argv[++i]; + game_path = argv[++i]; has_game_argument = true; } else { std::cerr << "Error: Missing argument for -g/--game\n"; @@ -98,6 +100,25 @@ int main(int argc, char* argv[]) { Config::setFullscreenMode(is_fullscreen); }}, {"--fullscreen", [&](int& i) { arg_map["-f"](i); }}, + {"--add-game-folder", + [&](int& i) { + if (++i >= argc) { + std::cerr << "Error: Missing argument for --add-game-folder\n"; + exit(1); + } + std::string config_dir(argv[i]); + std::filesystem::path config_path = std::filesystem::path(config_dir); + std::error_code discard; + if (!std::filesystem::is_directory(config_path, discard)) { + std::cerr << "Error: Directory does not exist: " << config_path << "\n"; + exit(1); + } + + Config::addGameInstallDir(config_path); + Config::save(Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "config.toml"); + std::cout << "Game folder successfully saved.\n"; + exit(0); + }}, }; // Parse command-line arguments using the map @@ -106,6 +127,10 @@ int main(int argc, char* argv[]) { auto it = arg_map.find(cur_arg); if (it != arg_map.end()) { it->second(i); // Call the associated lambda function + } else if (i == argc - 1 && !has_game_argument) { + // Assume the last argument is the game file if not specified via -g/--game + game_path = argv[i]; + has_game_argument = true; } else { std::cerr << "Unknown argument: " << cur_arg << ", see --help for info.\n"; return 1; @@ -134,14 +159,14 @@ int main(int argc, char* argv[]) { // Process game path or ID if provided if (has_game_argument) { - std::filesystem::path game_file_path(gamePath); + std::filesystem::path game_file_path(game_path); // Check if the provided path is a valid file if (!std::filesystem::exists(game_file_path)) { // If not a file, treat it as a game ID and search in install directories bool game_found = false; for (const auto& install_dir : Config::getGameInstallDirs()) { - auto potential_game_path = install_dir / gamePath / "eboot.bin"; + auto potential_game_path = install_dir / game_path / "eboot.bin"; if (std::filesystem::exists(potential_game_path)) { game_file_path = potential_game_path; game_found = true; @@ -149,7 +174,7 @@ int main(int argc, char* argv[]) { } } if (!game_found) { - std::cerr << "Error: Game ID or file path not found: " << gamePath << std::endl; + std::cerr << "Error: Game ID or file path not found: " << game_path << std::endl; return 1; } }