From 439db029d3c9ce872d54b82154889379d90fdb63 Mon Sep 17 00:00:00 2001 From: kalaposfos13 <153381648+kalaposfos13@users.noreply.github.com> Date: Sun, 12 Jan 2025 13:50:17 +0100 Subject: [PATCH] Replace -ga with --; increase max argument count to 32; and add logging --- src/core/linker.cpp | 12 +++++++----- src/core/linker.h | 4 ++-- src/emulator.cpp | 13 +++++++++++-- src/emulator.h | 3 ++- src/main.cpp | 31 ++++++++++++++----------------- src/qt_gui/main.cpp | 32 ++++++++++++++------------------ 6 files changed, 50 insertions(+), 45 deletions(-) diff --git a/src/core/linker.cpp b/src/core/linker.cpp index 4fef42f8e..2461edcb2 100644 --- a/src/core/linker.cpp +++ b/src/core/linker.cpp @@ -52,7 +52,7 @@ Linker::Linker() : memory{Memory::Instance()} {} Linker::~Linker() = default; -void Linker::Execute(const std::string arg) { +void Linker::Execute(const std::vector args) { if (Config::debugDump()) { DebugDump(); } @@ -101,7 +101,7 @@ void Linker::Execute(const std::string arg) { memory->SetupMemoryRegions(fmem_size, use_extended_mem1, use_extended_mem2); - main_thread.Run([this, module, arg](std::stop_token) { + main_thread.Run([this, module, args](std::stop_token) { Common::SetCurrentThreadName("GAME_MainThread"); LoadSharedLibraries(); @@ -109,9 +109,11 @@ void Linker::Execute(const std::string arg) { EntryParams params{}; params.argc = 1; params.argv[0] = "eboot.bin"; - if (!arg.empty()) { - params.argc = 2; - params.argv[1] = arg.c_str(); + if (!args.empty()) { + params.argc = args.size() + 1; + for (int i = 0; i < args.size() && i < 32; i++) { + params.argv[i + 1] = args[i].c_str(); + } } params.entry_addr = module->GetEntryAddress(); RunMainEntry(¶ms); diff --git a/src/core/linker.h b/src/core/linker.h index 13839a176..66bc83f66 100644 --- a/src/core/linker.h +++ b/src/core/linker.h @@ -49,7 +49,7 @@ class Linker; struct EntryParams { int argc; u32 padding; - const char* argv[3]; + const char* argv[32]; VAddr entry_addr; }; @@ -143,7 +143,7 @@ public: void Relocate(Module* module); bool Resolve(const std::string& name, Loader::SymbolType type, Module* module, Loader::SymbolRecord* return_info); - void Execute(const std::string arg = ""); + void Execute(const std::vector args = std::vector()); void DebugDump(); private: diff --git a/src/emulator.cpp b/src/emulator.cpp index 530a1719d..43575344c 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -98,7 +98,7 @@ Emulator::~Emulator() { Config::saveMainWindow(config_dir / "config.toml"); } -void Emulator::Run(const std::filesystem::path& file, const std::string arg) { +void Emulator::Run(const std::filesystem::path& file, const std::vector args) { // Applications expect to be run from /app0 so mount the file's parent path as app0. auto* mnt = Common::Singleton::Instance(); const auto game_folder = file.parent_path(); @@ -151,6 +151,15 @@ void Emulator::Run(const std::filesystem::path& file, const std::string arg) { if (const auto raw_attributes = param_sfo->GetInteger("ATTRIBUTE")) { psf_attributes.raw = *raw_attributes; } + if (!args.empty()) { + int argc = args.size() > 32 ? 32 : args.size(); + for (int i = 0; i < argc; i++) { + LOG_INFO(Loader, "Game argument {}: {}", i, args[i]); + } + if (args.size() > 32) { + LOG_ERROR(Loader, "Too many game arguments, only passing the first 32"); + } + } } const auto pic1_path = mnt->GetHostPath("/app0/sce_sys/pic1.png"); @@ -238,7 +247,7 @@ void Emulator::Run(const std::filesystem::path& file, const std::string arg) { } #endif - linker->Execute(arg); + linker->Execute(args); window->InitTimers(); while (window->IsOpen()) { diff --git a/src/emulator.h b/src/emulator.h index e27d6e84a..aabf6b44e 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -25,7 +25,8 @@ public: Emulator(); ~Emulator(); - void Run(const std::filesystem::path& file, const std::string arg = ""); + void Run(const std::filesystem::path& file, + const std::vector args = std::vector()); void UpdatePlayTime(const std::string& serial); private: diff --git a/src/main.cpp b/src/main.cpp index 153f8959c..b427c72ab 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,7 +29,7 @@ int main(int argc, char* argv[]) { bool has_game_argument = false; std::string game_path; - std::string game_arg; + std::vector game_args{}; // Map of argument strings to lambda functions std::unordered_map> arg_map = { @@ -39,8 +39,9 @@ int main(int argc, char* argv[]) { "Options:\n" " -g, --game Specify game path to launch\n" " -ga, --game-with-arg \n" - " Run a game executable with one argument " - "passed to it.\n" + " -- ... Parameters passed to the game ELF. " + "Needs to be at the end of the line, and everything after \"--\" is a " + "game argument.\n" " -p, --patch Apply specified patch file\n" " -f, --fullscreen Specify window initial fullscreen " "state. Does not overwrite the config file.\n" @@ -62,19 +63,6 @@ int main(int argc, char* argv[]) { }}, {"--game", [&](int& i) { arg_map["-g"](i); }}, - {"-ga", - [&](int& i) { - if (i + 2 < argc) { - game_path = argv[++i]; - game_arg = argv[++i]; - has_game_argument = true; - } else { - std::cerr << "Error: Missing argument for -ga/--game-with-arg\n"; - exit(1); - } - }}, - {"--game-with-arg", [&](int& i) { arg_map["-ga"](i); }}, - {"-p", [&](int& i) { if (i + 1 < argc) { @@ -139,6 +127,15 @@ 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 (std::string(argv[i + 1]) == "--") { + if (!has_game_argument) { + game_path = argv[i]; + has_game_argument = true; + } + for (int j = i + 2; j < argc; j++) { + game_args.push_back(argv[j]); + } + break; } 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]; @@ -183,7 +180,7 @@ int main(int argc, char* argv[]) { // Run the emulator with the resolved eboot path Core::Emulator emulator; - emulator.Run(eboot_path, game_arg); + emulator.Run(eboot_path, game_args); return 0; } diff --git a/src/qt_gui/main.cpp b/src/qt_gui/main.cpp index 1de059c96..88ea8c95d 100644 --- a/src/qt_gui/main.cpp +++ b/src/qt_gui/main.cpp @@ -33,7 +33,7 @@ int main(int argc, char* argv[]) { bool has_command_line_argument = argc > 1; bool show_gui = false, has_game_argument = false; std::string game_path; - std::string game_arg = ""; + std::vector game_args{}; // Map of argument strings to lambda functions std::unordered_map> arg_map = { @@ -44,9 +44,9 @@ int main(int argc, char* argv[]) { " No arguments: Opens the GUI.\n" " -g, --game Specify or " " to launch\n" - " -ga, --game-with-arg \n" - " Run a game executable with one argument " - "passed to it.\n" + " -- ... Parameters passed to the game ELF. " + "Needs to be at the end of the line, and everything after \"--\" is a " + "game argument.\n" " -p, --patch Apply specified patch file\n" " -s, --show-gui Show the GUI\n" " -f, --fullscreen Specify window initial fullscreen " @@ -72,19 +72,6 @@ int main(int argc, char* argv[]) { }}, {"--game", [&](int& i) { arg_map["-g"](i); }}, - {"-ga", - [&](int& i) { - if (i + 2 < argc) { - game_path = argv[++i]; - game_arg = argv[++i]; - has_game_argument = true; - } else { - std::cerr << "Error: Missing argument for -ga/--game-with-arg\n"; - exit(1); - } - }}, - {"--game-with-arg", [&](int& i) { arg_map["-ga"](i); }}, - {"-p", [&](int& i) { if (i + 1 < argc) { @@ -144,6 +131,15 @@ 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 (std::string(argv[i + 1]) == "--") { + if (!has_game_argument) { + game_path = argv[i]; + has_game_argument = true; + } + for (int j = i + 2; j < argc; j++) { + game_args.push_back(argv[j]); + } + break; } 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]; @@ -198,7 +194,7 @@ int main(int argc, char* argv[]) { // Run the emulator with the resolved game path Core::Emulator emulator; - emulator.Run(game_file_path.string(), game_arg); + emulator.Run(game_file_path.string(), game_args); if (!show_gui) { return 0; // Exit after running the emulator without showing the GUI }