mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-14 08:12:16 +00:00
CLI: Add argument to pass an argument to the game (#2135)
This commit is contained in:
parent
1ea5f8f092
commit
3b92cd1c1a
6 changed files with 61 additions and 9 deletions
|
@ -52,7 +52,7 @@ Linker::Linker() : memory{Memory::Instance()} {}
|
||||||
|
|
||||||
Linker::~Linker() = default;
|
Linker::~Linker() = default;
|
||||||
|
|
||||||
void Linker::Execute() {
|
void Linker::Execute(const std::vector<std::string> args) {
|
||||||
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, args](std::stop_token) {
|
||||||
Common::SetCurrentThreadName("GAME_MainThread");
|
Common::SetCurrentThreadName("GAME_MainThread");
|
||||||
LoadSharedLibraries();
|
LoadSharedLibraries();
|
||||||
|
|
||||||
|
@ -109,6 +109,12 @@ void Linker::Execute() {
|
||||||
EntryParams params{};
|
EntryParams params{};
|
||||||
params.argc = 1;
|
params.argc = 1;
|
||||||
params.argv[0] = "eboot.bin";
|
params.argv[0] = "eboot.bin";
|
||||||
|
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();
|
params.entry_addr = module->GetEntryAddress();
|
||||||
RunMainEntry(¶ms);
|
RunMainEntry(¶ms);
|
||||||
});
|
});
|
||||||
|
|
|
@ -49,7 +49,7 @@ class Linker;
|
||||||
struct EntryParams {
|
struct EntryParams {
|
||||||
int argc;
|
int argc;
|
||||||
u32 padding;
|
u32 padding;
|
||||||
const char* argv[3];
|
const char* argv[33];
|
||||||
VAddr entry_addr;
|
VAddr entry_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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::vector<std::string> args = {});
|
||||||
void DebugDump();
|
void DebugDump();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -99,7 +99,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::vector<std::string> args) {
|
||||||
// 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();
|
||||||
|
@ -152,6 +152,15 @@ void Emulator::Run(const std::filesystem::path& file) {
|
||||||
if (const auto raw_attributes = param_sfo->GetInteger("ATTRIBUTE")) {
|
if (const auto raw_attributes = param_sfo->GetInteger("ATTRIBUTE")) {
|
||||||
psf_attributes.raw = *raw_attributes;
|
psf_attributes.raw = *raw_attributes;
|
||||||
}
|
}
|
||||||
|
if (!args.empty()) {
|
||||||
|
int argc = std::min<int>(args.size(), 32);
|
||||||
|
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");
|
const auto pic1_path = mnt->GetHostPath("/app0/sce_sys/pic1.png");
|
||||||
|
@ -239,7 +248,7 @@ void Emulator::Run(const std::filesystem::path& file) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
linker->Execute();
|
linker->Execute(args);
|
||||||
|
|
||||||
window->InitTimers();
|
window->InitTimers();
|
||||||
while (window->IsOpen()) {
|
while (window->IsOpen()) {
|
||||||
|
|
|
@ -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::vector<std::string> args = {});
|
||||||
void UpdatePlayTime(const std::string& serial);
|
void UpdatePlayTime(const std::string& serial);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
21
src/main.cpp
21
src/main.cpp
|
@ -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::vector<std::string> game_args{};
|
||||||
|
|
||||||
// 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,9 @@ 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"
|
||||||
|
" -- ... 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 <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"
|
||||||
|
@ -126,6 +130,21 @@ int main(int argc, char* argv[]) {
|
||||||
// Assume the last argument is the game file if not specified via -g/--game
|
// Assume the last argument is the game file if not specified via -g/--game
|
||||||
game_path = argv[i];
|
game_path = argv[i];
|
||||||
has_game_argument = true;
|
has_game_argument = true;
|
||||||
|
} else if (std::string(argv[i]) == "--") {
|
||||||
|
if (i + 1 == argc) {
|
||||||
|
std::cerr << "Warning: -- is set, but no game arguments are added!\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (int j = i + 1; j < argc; j++) {
|
||||||
|
game_args.push_back(argv[j]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else if (i + 1 < argc && std::string(argv[i + 1]) == "--") {
|
||||||
|
if (!has_game_argument) {
|
||||||
|
game_path = argv[i];
|
||||||
|
has_game_argument = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Unknown argument: " << cur_arg << ", see --help for info.\n";
|
std::cerr << "Unknown argument: " << cur_arg << ", see --help for info.\n";
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -166,7 +185,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_args);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::vector<std::string> game_args{};
|
||||||
|
|
||||||
// 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,9 @@ 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"
|
||||||
|
" -- ... 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 <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 "
|
||||||
|
@ -131,6 +135,20 @@ int main(int argc, char* argv[]) {
|
||||||
// Assume the last argument is the game file if not specified via -g/--game
|
// Assume the last argument is the game file if not specified via -g/--game
|
||||||
game_path = argv[i];
|
game_path = argv[i];
|
||||||
has_game_argument = true;
|
has_game_argument = true;
|
||||||
|
} else if (std::string(argv[i]) == "--") {
|
||||||
|
if (i + 1 == argc) {
|
||||||
|
std::cerr << "Warning: -- is set, but no game arguments are added!\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (int j = i + 1; j < argc; j++) {
|
||||||
|
game_args.push_back(argv[j]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else if (i + 1 < argc && std::string(argv[i + 1]) == "--") {
|
||||||
|
if (!has_game_argument) {
|
||||||
|
game_path = argv[i];
|
||||||
|
has_game_argument = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Unknown argument: " << cur_arg << ", see --help for info.\n";
|
std::cerr << "Unknown argument: " << cur_arg << ", see --help for info.\n";
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -181,7 +199,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_args);
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue