diff --git a/src/core/linker.cpp b/src/core/linker.cpp index 28d2eea7b..4fef42f8e 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() { +void Linker::Execute(const std::string arg) { if (Config::debugDump()) { DebugDump(); } @@ -101,7 +101,7 @@ void Linker::Execute() { memory->SetupMemoryRegions(fmem_size, use_extended_mem1, use_extended_mem2); - main_thread.Run([this, module](std::stop_token) { + main_thread.Run([this, module, arg](std::stop_token) { Common::SetCurrentThreadName("GAME_MainThread"); LoadSharedLibraries(); @@ -109,6 +109,10 @@ void Linker::Execute() { EntryParams params{}; params.argc = 1; params.argv[0] = "eboot.bin"; + if (!arg.empty()) { + params.argc = 2; + params.argv[1] = arg.c_str(); + } params.entry_addr = module->GetEntryAddress(); RunMainEntry(¶ms); }); diff --git a/src/core/linker.h b/src/core/linker.h index 7ef13ae56..13839a176 100644 --- a/src/core/linker.h +++ b/src/core/linker.h @@ -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(); + void Execute(const std::string arg = ""); void DebugDump(); private: diff --git a/src/emulator.cpp b/src/emulator.cpp index dbe693340..530a1719d 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) { +void Emulator::Run(const std::filesystem::path& file, const std::string arg) { // 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(); @@ -238,7 +238,7 @@ void Emulator::Run(const std::filesystem::path& file) { } #endif - linker->Execute(); + linker->Execute(arg); window->InitTimers(); while (window->IsOpen()) { diff --git a/src/emulator.h b/src/emulator.h index a08ab43c3..e27d6e84a 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -25,7 +25,7 @@ public: Emulator(); ~Emulator(); - void Run(const std::filesystem::path& file); + void Run(const std::filesystem::path& file, const std::string arg = ""); void UpdatePlayTime(const std::string& serial); private: diff --git a/src/main.cpp b/src/main.cpp index 54772870c..e85d0d43e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,6 +29,7 @@ int main(int argc, char* argv[]) { bool has_game_argument = false; std::string game_path; + std::string game_arg; // Map of argument strings to lambda functions std::unordered_map> arg_map = { @@ -37,6 +38,8 @@ int main(int argc, char* argv[]) { std::cout << "Usage: shadps4 [options] \n" "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" " -p, --patch Apply specified patch file\n" " -f, --fullscreen Specify window initial fullscreen " "state. Does not overwrite the config file.\n" @@ -58,6 +61,19 @@ 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) { @@ -166,7 +182,7 @@ int main(int argc, char* argv[]) { // Run the emulator with the resolved eboot path Core::Emulator emulator; - emulator.Run(eboot_path); + emulator.Run(eboot_path, game_arg); return 0; } diff --git a/src/qt_gui/main.cpp b/src/qt_gui/main.cpp index 2d524e199..ee4e3db99 100644 --- a/src/qt_gui/main.cpp +++ b/src/qt_gui/main.cpp @@ -33,6 +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 = ""; // Map of argument strings to lambda functions std::unordered_map> arg_map = { @@ -43,6 +44,8 @@ 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" " -p, --patch Apply specified patch file\n" " -s, --show-gui Show the GUI\n" " -f, --fullscreen Specify window initial fullscreen " @@ -68,6 +71,19 @@ 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) { @@ -181,7 +197,7 @@ int main(int argc, char* argv[]) { // Run the emulator with the resolved game path Core::Emulator emulator; - emulator.Run(game_file_path.string()); + emulator.Run(game_file_path.string(), game_arg); if (!show_gui) { return 0; // Exit after running the emulator without showing the GUI }