mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2024-11-23 03:09:55 +00:00
Skip GUI if launching a game directly (#1507)
* Skip GUI if launching a game directly * Rerun jobs 2 * Added --show-gui, --help, open game by ID and more * Clang-format * Added non-GUI related upgrades to SDL version * clang-format * Added --fullscreen <true|false> argument * Update --help text
This commit is contained in:
parent
f9ae945a55
commit
8f2d71d458
109
src/main.cpp
109
src/main.cpp
@ -1,7 +1,13 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "functional"
|
||||
#include "iostream"
|
||||
#include "string"
|
||||
#include "unordered_map"
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include "common/config.h"
|
||||
#include "common/memory_patcher.h"
|
||||
#include "emulator.h"
|
||||
|
||||
@ -14,26 +20,105 @@ int main(int argc, char* argv[]) {
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
#endif
|
||||
|
||||
bool has_game_argument = false;
|
||||
std::string game_path;
|
||||
|
||||
// Map of argument strings to lambda functions
|
||||
std::unordered_map<std::string, std::function<void(int&)>> arg_map = {
|
||||
{"-h",
|
||||
[&](int&) {
|
||||
std::cout << "Usage: shadps4 [options] <elf or eboot.bin path>\n"
|
||||
"Options:\n"
|
||||
" -g, --game <path|ID> Specify game path to launch\n"
|
||||
" -p, --patch <patch_file> Apply specified patch file\n"
|
||||
" -f, --fullscreen <true|false> Specify window initial fullscreen "
|
||||
"state. Does not overwrite the config file."
|
||||
" -h, --help Display this help message\n";
|
||||
exit(0);
|
||||
}},
|
||||
{"--help", [&](int& i) { arg_map["-h"](i); }},
|
||||
|
||||
{"-g",
|
||||
[&](int& i) {
|
||||
if (i + 1 < argc) {
|
||||
game_path = argv[++i];
|
||||
has_game_argument = true;
|
||||
} else {
|
||||
std::cerr << "Error: Missing argument for -g/--game\n";
|
||||
exit(1);
|
||||
}
|
||||
}},
|
||||
{"--game", [&](int& i) { arg_map["-g"](i); }},
|
||||
|
||||
{"-p",
|
||||
[&](int& i) {
|
||||
if (i + 1 < argc) {
|
||||
MemoryPatcher::patchFile = argv[++i];
|
||||
} else {
|
||||
std::cerr << "Error: Missing argument for -p/--patch\n";
|
||||
exit(1);
|
||||
}
|
||||
}},
|
||||
{"--patch", [&](int& i) { arg_map["-p"](i); }},
|
||||
{"-f",
|
||||
[&](int& i) {
|
||||
if (++i >= argc) {
|
||||
std::cerr << "Error: Missing argument for -f/--fullscreen\n";
|
||||
exit(1);
|
||||
}
|
||||
std::string f_param(argv[i]);
|
||||
bool is_fullscreen;
|
||||
if (f_param == "true") {
|
||||
is_fullscreen = true;
|
||||
} else if (f_param == "false") {
|
||||
is_fullscreen = false;
|
||||
} else {
|
||||
std::cerr
|
||||
<< "Error: Invalid argument for -f/--fullscreen. Use 'true' or 'false'.\n";
|
||||
exit(1);
|
||||
}
|
||||
// Set fullscreen mode without saving it to config file
|
||||
Config::setFullscreenMode(is_fullscreen);
|
||||
}},
|
||||
{"--fullscreen", [&](int& i) { arg_map["-f"](i); }},
|
||||
};
|
||||
|
||||
if (argc == 1) {
|
||||
fmt::print("Usage: {} <elf or eboot.bin path>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
// check if eboot file exists
|
||||
if (!std::filesystem::exists(argv[1])) {
|
||||
fmt::print("Eboot.bin file not found\n");
|
||||
int dummy = 0; // one does not simply pass 0 directly
|
||||
arg_map.at("-h")(dummy);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
std::string curArg = argv[i];
|
||||
if (curArg == "-p") {
|
||||
std::string patchFile = argv[i + 1];
|
||||
MemoryPatcher::patchFile = patchFile;
|
||||
// Parse command-line arguments using the map
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
std::string cur_arg = argv[i];
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Run the emulator with the specified game
|
||||
Core::Emulator emulator;
|
||||
emulator.Run(argv[1]);
|
||||
emulator.Run(game_path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "iostream"
|
||||
#include "unordered_map"
|
||||
|
||||
#include "common/config.h"
|
||||
#include "common/memory_patcher.h"
|
||||
#include "core/file_sys/fs.h"
|
||||
@ -26,10 +29,90 @@ int main(int argc, char* argv[]) {
|
||||
const auto user_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
|
||||
Config::load(user_dir / "config.toml");
|
||||
|
||||
// Check if elf or eboot.bin path was passed as a command line argument
|
||||
bool has_command_line_argument = argc > 1;
|
||||
bool show_gui = false, has_game_argument = false;
|
||||
std::string gamePath;
|
||||
|
||||
// Check if the game install directory is set
|
||||
// Map of argument strings to lambda functions
|
||||
std::unordered_map<std::string, std::function<void(int&)>> arg_map = {
|
||||
{"-h",
|
||||
[&](int&) {
|
||||
std::cout << "Usage: shadps4 [options]\n"
|
||||
"Options:\n"
|
||||
" No arguments: Opens the GUI.\n"
|
||||
" -g, --game <path|ID> Specify <eboot.bin or elf path> or "
|
||||
"<game ID (CUSAXXXXX)> to launch\n"
|
||||
" -p, --patch <patch_file> Apply specified patch file\n"
|
||||
" -s, --show-gui Show the GUI\n"
|
||||
" -f, --fullscreen <true|false> Specify window initial fullscreen "
|
||||
"state. Does not overwrite the config file."
|
||||
" -h, --help Display this help message\n";
|
||||
exit(0);
|
||||
}},
|
||||
{"--help", [&](int& i) { arg_map["-h"](i); }}, // Redirect --help to -h
|
||||
|
||||
{"-s", [&](int&) { show_gui = true; }},
|
||||
{"--show-gui", [&](int& i) { arg_map["-s"](i); }},
|
||||
|
||||
{"-g",
|
||||
[&](int& i) {
|
||||
if (i + 1 < argc) {
|
||||
gamePath = argv[++i];
|
||||
has_game_argument = true;
|
||||
} else {
|
||||
std::cerr << "Error: Missing argument for -g/--game\n";
|
||||
exit(1);
|
||||
}
|
||||
}},
|
||||
{"--game", [&](int& i) { arg_map["-g"](i); }},
|
||||
|
||||
{"-p",
|
||||
[&](int& i) {
|
||||
if (i + 1 < argc) {
|
||||
MemoryPatcher::patchFile = argv[++i];
|
||||
} else {
|
||||
std::cerr << "Error: Missing argument for -p\n";
|
||||
exit(1);
|
||||
}
|
||||
}},
|
||||
{"--patch", [&](int& i) { arg_map["-p"](i); }},
|
||||
{"-f",
|
||||
[&](int& i) {
|
||||
if (++i >= argc) {
|
||||
std::cerr
|
||||
<< "Error: Invalid argument for -f/--fullscreen. Use 'true' or 'false'.\n";
|
||||
exit(1);
|
||||
}
|
||||
std::string f_param(argv[i]);
|
||||
bool is_fullscreen;
|
||||
if (f_param == "true") {
|
||||
is_fullscreen = true;
|
||||
} else if (f_param == "false") {
|
||||
is_fullscreen = false;
|
||||
} else {
|
||||
std::cerr
|
||||
<< "Error: Invalid argument for -f/--fullscreen. Use 'true' or 'false'.\n";
|
||||
exit(1);
|
||||
}
|
||||
// Set fullscreen mode without saving it to config file
|
||||
Config::setFullscreenMode(is_fullscreen);
|
||||
}},
|
||||
{"--fullscreen", [&](int& i) { arg_map["-f"](i); }},
|
||||
};
|
||||
|
||||
// Parse command-line arguments using the map
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
std::string cur_arg = argv[i];
|
||||
auto it = arg_map.find(cur_arg);
|
||||
if (it != arg_map.end()) {
|
||||
it->second(i); // Call the associated lambda function
|
||||
} else {
|
||||
std::cerr << "Unknown argument: " << cur_arg << ", see --help for info.\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// If no game directory is set and no command line argument, prompt for it
|
||||
if (Config::getGameInstallDirs().empty() && !has_command_line_argument) {
|
||||
GameInstallDialog dlg;
|
||||
dlg.exec();
|
||||
@ -40,21 +123,46 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
// Initialize the main window
|
||||
MainWindow* m_main_window = new MainWindow(nullptr);
|
||||
m_main_window->Init();
|
||||
|
||||
// Check for command line arguments
|
||||
if (has_command_line_argument) {
|
||||
Core::Emulator emulator;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
std::string curArg = argv[i];
|
||||
if (curArg == "-p") {
|
||||
std::string patchFile = argv[i + 1];
|
||||
MemoryPatcher::patchFile = patchFile;
|
||||
}
|
||||
}
|
||||
emulator.Run(argv[1]);
|
||||
if ((has_command_line_argument && show_gui) || !has_command_line_argument) {
|
||||
m_main_window->Init();
|
||||
}
|
||||
|
||||
// Run the Qt application
|
||||
if (has_command_line_argument && !has_game_argument) {
|
||||
std::cerr << "Error: Please provide a game path or ID.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Process game path or ID if provided
|
||||
if (has_game_argument) {
|
||||
std::filesystem::path game_file_path(gamePath);
|
||||
|
||||
// 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";
|
||||
if (std::filesystem::exists(potential_game_path)) {
|
||||
game_file_path = potential_game_path;
|
||||
game_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!game_found) {
|
||||
std::cerr << "Error: Game ID or file path not found: " << gamePath << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Run the emulator with the resolved game path
|
||||
Core::Emulator emulator;
|
||||
emulator.Run(game_file_path.string());
|
||||
if (!show_gui) {
|
||||
return 0; // Exit after running the emulator without showing the GUI
|
||||
}
|
||||
}
|
||||
|
||||
// Show the main window and run the Qt application
|
||||
m_main_window->show();
|
||||
return a.exec();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user