/* PCSX2 - PS2 Emulator for PCs * Copyright (C) 2002-2022 PCSX2 Dev Team * * PCSX2 is free software: you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with PCSX2. * If not, see . */ #include "PrecompiledHeader.h" #include #include #include #include "MainWindow.h" #include "EmuThread.h" #include "QtHost.h" #include "CDVD/CDVD.h" #include "Frontend/GameList.h" #include "svnrev.h" #include "common/CrashHandler.h" static void PrintCommandLineVersion() { std::fprintf(stderr, "PCSX2 Version %s\n", GIT_REV); std::fprintf(stderr, "https://pcsx2.net/\n"); std::fprintf(stderr, "\n"); } static void PrintCommandLineHelp(const char* progname) { PrintCommandLineVersion(); std::fprintf(stderr, "Usage: %s [parameters] [--] [boot filename]\n", progname); std::fprintf(stderr, "\n"); std::fprintf(stderr, " -help: Displays this information and exits.\n"); std::fprintf(stderr, " -version: Displays version information and exits.\n"); std::fprintf(stderr, " -batch: Enables batch mode (exits after shutting down).\n"); std::fprintf(stderr, " -elf : Overrides the boot ELF with the specified filename.\n"); std::fprintf(stderr, " -disc : Uses the specified host DVD drive as a source.\n"); std::fprintf(stderr, " -fastboot: Force fast boot for provided filename.\n"); std::fprintf(stderr, " -slowboot: Force slow boot for provided filename.\n"); std::fprintf(stderr, " -resume: Load resume save state. If a boot filename is provided,\n" " that game's resume state will be loaded, otherwise the most\n" " recent resume save state will be loaded.\n"); std::fprintf(stderr, " -state : Loads specified save state by index.\n"); std::fprintf(stderr, " -statefile : Loads state from the specified filename.\n" " No boot filename is required with this option.\n"); std::fprintf(stderr, " -fullscreen: Enters fullscreen mode immediately after starting.\n"); std::fprintf(stderr, " -nofullscreen: Prevents fullscreen mode from triggering if enabled.\n"); std::fprintf(stderr, " -portable: Forces \"portable mode\", data in same directory.\n"); std::fprintf(stderr, " -settings : Loads a custom settings configuration from the\n" " specified filename. Default settings applied if file not found.\n"); std::fprintf(stderr, " --: Signals that no more arguments will follow and the remaining\n" " parameters make up the filename. Use when the filename contains\n" " spaces or starts with a dash.\n"); std::fprintf(stderr, "\n"); } static std::shared_ptr& AutoBoot(std::shared_ptr& autoboot) { if (!autoboot) autoboot = std::make_shared(); return autoboot; } static bool ParseCommandLineOptions(int argc, char* argv[], std::shared_ptr& autoboot) { std::optional fast_boot; std::optional start_fullscreen; std::optional state_index; std::string state_filename; bool no_more_args = false; for (int i = 1; i < argc; i++) { if (!no_more_args) { #define CHECK_ARG(str) !std::strcmp(argv[i], str) #define CHECK_ARG_PARAM(str) (!std::strcmp(argv[i], str) && ((i + 1) < argc)) if (CHECK_ARG("-help")) { PrintCommandLineHelp(argv[0]); return false; } else if (CHECK_ARG("-version")) { PrintCommandLineVersion(); return false; } else if (CHECK_ARG("-batch")) { Console.WriteLn("Enabling batch mode."); AutoBoot(autoboot)->batch_mode = true; continue; } else if (CHECK_ARG("-fastboot")) { Console.WriteLn("Forcing fast boot."); fast_boot = true; continue; } else if (CHECK_ARG("-slowboot")) { Console.WriteLn("Forcing slow boot."); fast_boot = false; continue; } else if (CHECK_ARG("-resume")) { state_index = -1; continue; } else if (CHECK_ARG_PARAM("-state")) { state_index = std::atoi(argv[++i]); continue; } else if (CHECK_ARG_PARAM("-statefile")) { AutoBoot(autoboot)->save_state = argv[++i]; continue; } else if (CHECK_ARG_PARAM("-elf")) { AutoBoot(autoboot)->elf_override = argv[++i]; continue; } else if (CHECK_ARG_PARAM("-disc")) { AutoBoot(autoboot)->source_type = CDVD_SourceType::Disc; AutoBoot(autoboot)->filename = argv[++i]; continue; } else if (CHECK_ARG("-fullscreen")) { Console.WriteLn("Going fullscreen after booting."); start_fullscreen = true; continue; } else if (CHECK_ARG("-nofullscreen")) { Console.WriteLn("Preventing fullscreen after booting."); start_fullscreen = false; continue; } else if (CHECK_ARG("-portable")) { Console.WriteLn("Using portable mode."); // SetUserDirectoryToProgramDirectory(); continue; } else if (CHECK_ARG("-resume")) { state_index = -1; continue; } else if (CHECK_ARG("--")) { no_more_args = true; continue; } else if (argv[i][0] == '-') { Console.Error("Unknown parameter: '%s'", argv[i]); return false; } #undef CHECK_ARG #undef CHECK_ARG_PARAM } if (!AutoBoot(autoboot)->filename.empty()) AutoBoot(autoboot)->filename += ' '; AutoBoot(autoboot)->filename += argv[i]; } return true; } int main(int argc, char* argv[]) { CrashHandler::Install(); QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); QApplication app(argc, argv); std::shared_ptr autoboot; if (!ParseCommandLineOptions(argc, argv, autoboot)) return EXIT_FAILURE; MainWindow* main_window = new MainWindow(QApplication::style()->objectName()); if (!QtHost::Initialize()) { delete main_window; return EXIT_FAILURE; } main_window->initialize(); EmuThread::start(); main_window->refreshGameList(false); main_window->show(); if (autoboot) g_emu_thread->startVM(std::move(autoboot)); const int result = app.exec(); QtHost::Shutdown(); return result; }