Add CLI argument to pass an argument to the game

This commit is contained in:
kalaposfos13 2025-01-12 11:43:30 +01:00
parent 8a309c30a9
commit cd5728f97e
6 changed files with 44 additions and 8 deletions

View File

@ -52,7 +52,7 @@ Linker::Linker() : memory{Memory::Instance()} {}
Linker::~Linker() = default; Linker::~Linker() = default;
void Linker::Execute() { void Linker::Execute(const std::string arg) {
if (Config::debugDump()) { if (Config::debugDump()) {
DebugDump(); DebugDump();
} }
@ -101,7 +101,7 @@ void Linker::Execute() {
memory->SetupMemoryRegions(fmem_size, use_extended_mem1, use_extended_mem2); 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"); Common::SetCurrentThreadName("GAME_MainThread");
LoadSharedLibraries(); LoadSharedLibraries();
@ -109,6 +109,10 @@ void Linker::Execute() {
EntryParams params{}; EntryParams params{};
params.argc = 1; params.argc = 1;
params.argv[0] = "eboot.bin"; params.argv[0] = "eboot.bin";
if (!arg.empty()) {
params.argc = 2;
params.argv[1] = arg.c_str();
}
params.entry_addr = module->GetEntryAddress(); params.entry_addr = module->GetEntryAddress();
RunMainEntry(&params); RunMainEntry(&params);
}); });

View File

@ -143,7 +143,7 @@ public:
void Relocate(Module* module); void Relocate(Module* module);
bool Resolve(const std::string& name, Loader::SymbolType type, Module* module, bool Resolve(const std::string& name, Loader::SymbolType type, Module* module,
Loader::SymbolRecord* return_info); Loader::SymbolRecord* return_info);
void Execute(); void Execute(const std::string arg = "");
void DebugDump(); void DebugDump();
private: private:

View File

@ -98,7 +98,7 @@ Emulator::~Emulator() {
Config::saveMainWindow(config_dir / "config.toml"); 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. // Applications expect to be run from /app0 so mount the file's parent path as app0.
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance(); auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
const auto game_folder = file.parent_path(); const auto game_folder = file.parent_path();
@ -238,7 +238,7 @@ void Emulator::Run(const std::filesystem::path& file) {
} }
#endif #endif
linker->Execute(); linker->Execute(arg);
window->InitTimers(); window->InitTimers();
while (window->IsOpen()) { while (window->IsOpen()) {

View File

@ -25,7 +25,7 @@ public:
Emulator(); Emulator();
~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); void UpdatePlayTime(const std::string& serial);
private: private:

View File

@ -29,6 +29,7 @@ int main(int argc, char* argv[]) {
bool has_game_argument = false; bool has_game_argument = false;
std::string game_path; std::string game_path;
std::string game_arg;
// Map of argument strings to lambda functions // Map of argument strings to lambda functions
std::unordered_map<std::string, std::function<void(int&)>> arg_map = { std::unordered_map<std::string, std::function<void(int&)>> arg_map = {
@ -37,6 +38,8 @@ int main(int argc, char* argv[]) {
std::cout << "Usage: shadps4 [options] <elf or eboot.bin path>\n" std::cout << "Usage: shadps4 [options] <elf or eboot.bin path>\n"
"Options:\n" "Options:\n"
" -g, --game <path|ID> Specify game path to launch\n" " -g, --game <path|ID> Specify game path to launch\n"
" -ga, --game-with-arg <path|ID> <arg>\n"
" Run a game executable with one argument passed to it.\n"
" -p, --patch <patch_file> Apply specified patch file\n" " -p, --patch <patch_file> Apply specified patch file\n"
" -f, --fullscreen <true|false> Specify window initial fullscreen " " -f, --fullscreen <true|false> Specify window initial fullscreen "
"state. Does not overwrite the config file.\n" "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); }}, {"--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", {"-p",
[&](int& i) { [&](int& i) {
if (i + 1 < argc) { if (i + 1 < argc) {
@ -166,7 +182,7 @@ int main(int argc, char* argv[]) {
// Run the emulator with the resolved eboot path // Run the emulator with the resolved eboot path
Core::Emulator emulator; Core::Emulator emulator;
emulator.Run(eboot_path); emulator.Run(eboot_path, game_arg);
return 0; return 0;
} }

View File

@ -33,6 +33,7 @@ int main(int argc, char* argv[]) {
bool has_command_line_argument = argc > 1; bool has_command_line_argument = argc > 1;
bool show_gui = false, has_game_argument = false; bool show_gui = false, has_game_argument = false;
std::string game_path; std::string game_path;
std::string game_arg = "";
// Map of argument strings to lambda functions // Map of argument strings to lambda functions
std::unordered_map<std::string, std::function<void(int&)>> arg_map = { std::unordered_map<std::string, std::function<void(int&)>> arg_map = {
@ -43,6 +44,8 @@ int main(int argc, char* argv[]) {
" No arguments: Opens the GUI.\n" " No arguments: Opens the GUI.\n"
" -g, --game <path|ID> Specify <eboot.bin or elf path> or " " -g, --game <path|ID> Specify <eboot.bin or elf path> or "
"<game ID (CUSAXXXXX)> to launch\n" "<game ID (CUSAXXXXX)> to launch\n"
" -ga, --game-with-arg <path|ID> <arg>\n"
" Run a game executable with one argument passed to it.\n"
" -p, --patch <patch_file> Apply specified patch file\n" " -p, --patch <patch_file> Apply specified patch file\n"
" -s, --show-gui Show the GUI\n" " -s, --show-gui Show the GUI\n"
" -f, --fullscreen <true|false> Specify window initial fullscreen " " -f, --fullscreen <true|false> Specify window initial fullscreen "
@ -68,6 +71,19 @@ int main(int argc, char* argv[]) {
}}, }},
{"--game", [&](int& i) { arg_map["-g"](i); }}, {"--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", {"-p",
[&](int& i) { [&](int& i) {
if (i + 1 < argc) { if (i + 1 < argc) {
@ -181,7 +197,7 @@ int main(int argc, char* argv[]) {
// Run the emulator with the resolved game path // Run the emulator with the resolved game path
Core::Emulator emulator; Core::Emulator emulator;
emulator.Run(game_file_path.string()); emulator.Run(game_file_path.string(), game_arg);
if (!show_gui) { if (!show_gui) {
return 0; // Exit after running the emulator without showing the GUI return 0; // Exit after running the emulator without showing the GUI
} }