diff --git a/pcsx2-qt/CMakeLists.txt b/pcsx2-qt/CMakeLists.txt
index bc0e88d4e853a..7b1c1c6b56c09 100644
--- a/pcsx2-qt/CMakeLists.txt
+++ b/pcsx2-qt/CMakeLists.txt
@@ -22,7 +22,6 @@ target_sources(pcsx2-qt PRIVATE
EarlyHardwareCheck.cpp
EmuThread.cpp
EmuThread.h
- Main.cpp
MainWindow.cpp
MainWindow.h
MainWindow.ui
diff --git a/pcsx2-qt/Main.cpp b/pcsx2-qt/Main.cpp
deleted file mode 100644
index 980877a3d6928..0000000000000
--- a/pcsx2-qt/Main.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-/* 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
-
-#include "MainWindow.h"
-#include "EmuThread.h"
-#include "QtHost.h"
-
-#include "CDVD/CDVD.h"
-#include "Frontend/GameList.h"
-#include "Frontend/LogSink.h"
-
-#include "common/CrashHandler.h"
-
-static void PrintCommandLineVersion()
-{
- Host::InitializeEarlyConsole();
- std::fprintf(stderr, "%s\n", (QtHost::GetAppNameAndVersion() + QtHost::GetAppConfigSuffix()).toUtf8().constData());
- 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, " -bios: Starts the BIOS (System Menu/OSDSYS).\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, " -state : Loads specified save state by index.\n");
- std::fprintf(stderr, " -statefile : Loads state from the specified filename.\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, " -earlyconsolelog: Forces logging of early console messages to console.\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)
-{
- 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"))
- {
- QtHost::SetBatchMode(true);
- continue;
- }
- else if (CHECK_ARG("-fastboot"))
- {
- AutoBoot(autoboot)->fast_boot = true;
- continue;
- }
- else if (CHECK_ARG("-slowboot"))
- {
- AutoBoot(autoboot)->fast_boot = false;
- continue;
- }
- else if (CHECK_ARG_PARAM("-state"))
- {
- AutoBoot(autoboot)->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("-bios"))
- {
- AutoBoot(autoboot)->source_type = CDVD_SourceType::NoDisc;
- continue;
- }
- else if (CHECK_ARG("-fullscreen"))
- {
- AutoBoot(autoboot)->fullscreen = true;
- continue;
- }
- else if (CHECK_ARG("-nofullscreen"))
- {
- AutoBoot(autoboot)->fullscreen = false;
- continue;
- }
- else if (CHECK_ARG("-earlyconsolelog"))
- {
- Host::InitializeEarlyConsole();
- continue;
- }
- else if (CHECK_ARG("--"))
- {
- no_more_args = true;
- continue;
- }
- else if (argv[i][0] == '-')
- {
- Host::InitializeEarlyConsole();
- std::fprintf(stderr, "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];
- }
-
- // check autoboot parameters, if we set something like fullscreen without a bios
- // or disc, we don't want to actually start.
- if (autoboot && !autoboot->source_type.has_value() && autoboot->filename.empty() && autoboot->elf_override.empty())
- {
- Host::InitializeEarlyConsole();
- Console.Warning("Skipping autoboot due to no boot parameters.");
- autoboot.reset();
- }
-
- // if we don't have autoboot, we definitely don't want batch mode (because that'll skip
- // scanning the game list).
- if (QtHost::InBatchMode() && !autoboot)
- {
- Host::InitializeEarlyConsole();
- Console.Warning("Disabling batch mode, because we have no autoboot.");
- QtHost::SetBatchMode(false);
- }
-
- return true;
-}
-
-#ifndef _WIN32
-
-// See note at the end of the file as to why we don't do this on Windows.
-static bool PerformEarlyHardwareChecks()
-{
- // NOTE: No point translating this message, because the configuration isn't loaded yet, so we
- // won't know which language to use, and loading the configuration uses float instructions.
- const char* error;
- if (VMManager::PerformEarlyHardwareChecks(&error))
- return true;
-
- QMessageBox::critical(nullptr, QStringLiteral("Hardware Check Failed"), QString::fromUtf8(error));
- return false;
-}
-
-#endif
-
-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);
-
-#ifndef _WIN32
- if (!PerformEarlyHardwareChecks())
- return EXIT_FAILURE;
-#endif
-
- 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;
- }
-
- // actually show the window, the emuthread might still be starting up at this point
- main_window->initialize();
-
- // skip scanning the game list when running in batch mode
- if (!QtHost::InBatchMode())
- main_window->refreshGameList(false);
-
- main_window->show();
-
- if (autoboot)
- g_emu_thread->startVM(std::move(autoboot));
- else
- main_window->startupUpdateCheck();
-
- const int result = app.exec();
-
- QtHost::Shutdown();
- return result;
-}
diff --git a/pcsx2-qt/QtHost.cpp b/pcsx2-qt/QtHost.cpp
index e7e1805c24573..48f1424dcc7d7 100644
--- a/pcsx2-qt/QtHost.cpp
+++ b/pcsx2-qt/QtHost.cpp
@@ -18,6 +18,7 @@
#include
#include
+#include
#include
#ifdef _WIN32
@@ -35,6 +36,7 @@
#include "common/StringUtil.h"
#include "common/Timer.h"
+#include "pcsx2/CDVD/CDVDaccess.h"
#include "pcsx2/DebugTools/Debug.h"
#include "pcsx2/Frontend/GameList.h"
#include "pcsx2/Frontend/INISettingsInterface.h"
@@ -55,6 +57,10 @@ static constexpr u32 SETTINGS_SAVE_DELAY = 1000;
// Local function declarations
//////////////////////////////////////////////////////////////////////////
namespace QtHost {
+static void PrintCommandLineVersion();
+static void PrintCommandLineHelp(const char* progname);
+static std::shared_ptr& AutoBoot(std::shared_ptr& autoboot);
+static bool ParseCommandLineOptions(int argc, char* argv[], std::shared_ptr& autoboot);
static bool InitializeConfig();
static bool ShouldUsePortableMode();
static void SetAppRoot();
@@ -78,44 +84,6 @@ static bool s_batch_mode = false;
// Initialization/Shutdown
//////////////////////////////////////////////////////////////////////////
-bool QtHost::Initialize()
-{
- qRegisterMetaType>();
- qRegisterMetaType>();
- qRegisterMetaType>();
- qRegisterMetaType();
- qRegisterMetaType();
- qRegisterMetaType();
- qRegisterMetaType();
-
- if (!InitializeConfig())
- {
- // NOTE: No point translating this, because no config means the language won't be loaded anyway.
- QMessageBox::critical(nullptr, QStringLiteral("Error"), QStringLiteral("Failed to initialize config."));
- return false;
- }
-
- HookSignals();
- EmuThread::start();
- return true;
-}
-
-void QtHost::Shutdown()
-{
- EmuThread::stop();
- if (g_main_window)
- {
- g_main_window->close();
- delete g_main_window;
- }
-
- if (emuLog)
- {
- std::fclose(emuLog);
- emuLog = nullptr;
- }
-}
-
bool QtHost::SetCriticalFolders()
{
SetAppRoot();
@@ -373,11 +341,6 @@ bool QtHost::InBatchMode()
return s_batch_mode;
}
-void QtHost::SetBatchMode(bool enabled)
-{
- s_batch_mode = enabled;
-}
-
void QtHost::RunOnUIThread(const std::function& func, bool block /*= false*/)
{
// main window always exists, so it's fine to attach it to that.
@@ -509,3 +472,258 @@ void QtHost::HookSignals()
std::signal(SIGINT, SignalHandler);
std::signal(SIGTERM, SignalHandler);
}
+
+void QtHost::PrintCommandLineVersion()
+{
+ Host::InitializeEarlyConsole();
+ std::fprintf(stderr, "%s\n", (GetAppNameAndVersion() + GetAppConfigSuffix()).toUtf8().constData());
+ std::fprintf(stderr, "https://pcsx2.net/\n");
+ std::fprintf(stderr, "\n");
+}
+
+void QtHost::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, " -bios: Starts the BIOS (System Menu/OSDSYS).\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, " -state : Loads specified save state by index.\n");
+ std::fprintf(stderr, " -statefile : Loads state from the specified filename.\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, " -earlyconsolelog: Forces logging of early console messages to console.\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");
+}
+
+std::shared_ptr& QtHost::AutoBoot(std::shared_ptr& autoboot)
+{
+ if (!autoboot)
+ autoboot = std::make_shared();
+
+ return autoboot;
+}
+
+bool QtHost::ParseCommandLineOptions(int argc, char* argv[], std::shared_ptr& autoboot)
+{
+ 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"))
+ {
+ s_batch_mode = true;
+ continue;
+ }
+ else if (CHECK_ARG("-fastboot"))
+ {
+ AutoBoot(autoboot)->fast_boot = true;
+ continue;
+ }
+ else if (CHECK_ARG("-slowboot"))
+ {
+ AutoBoot(autoboot)->fast_boot = false;
+ continue;
+ }
+ else if (CHECK_ARG_PARAM("-state"))
+ {
+ AutoBoot(autoboot)->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("-bios"))
+ {
+ AutoBoot(autoboot)->source_type = CDVD_SourceType::NoDisc;
+ continue;
+ }
+ else if (CHECK_ARG("-fullscreen"))
+ {
+ AutoBoot(autoboot)->fullscreen = true;
+ continue;
+ }
+ else if (CHECK_ARG("-nofullscreen"))
+ {
+ AutoBoot(autoboot)->fullscreen = false;
+ continue;
+ }
+ else if (CHECK_ARG("-earlyconsolelog"))
+ {
+ Host::InitializeEarlyConsole();
+ continue;
+ }
+ else if (CHECK_ARG("--"))
+ {
+ no_more_args = true;
+ continue;
+ }
+ else if (argv[i][0] == '-')
+ {
+ Host::InitializeEarlyConsole();
+ std::fprintf(stderr, "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];
+ }
+
+ // check autoboot parameters, if we set something like fullscreen without a bios
+ // or disc, we don't want to actually start.
+ if (autoboot && !autoboot->source_type.has_value() && autoboot->filename.empty() && autoboot->elf_override.empty())
+ {
+ Host::InitializeEarlyConsole();
+ Console.Warning("Skipping autoboot due to no boot parameters.");
+ autoboot.reset();
+ }
+
+ // if we don't have autoboot, we definitely don't want batch mode (because that'll skip
+ // scanning the game list).
+ if (s_batch_mode && !autoboot)
+ {
+ QMessageBox::critical(nullptr, QStringLiteral("Error"), QStringLiteral("Cannot use batch mode, because no boot filename was specified."));
+ return false;
+ }
+
+ return true;
+}
+
+#ifndef _WIN32
+
+// See note in EarlyHardwareChecks.cpp as to why we don't do this on Windows.
+static bool PerformEarlyHardwareChecks()
+{
+ // NOTE: No point translating this message, because the configuration isn't loaded yet, so we
+ // won't know which language to use, and loading the configuration uses float instructions.
+ const char* error;
+ if (VMManager::PerformEarlyHardwareChecks(&error))
+ return true;
+
+ QMessageBox::critical(nullptr, QStringLiteral("Hardware Check Failed"), QString::fromUtf8(error));
+ return false;
+}
+
+#endif
+
+static void RegisterTypes()
+{
+ qRegisterMetaType>();
+ qRegisterMetaType>();
+ qRegisterMetaType>();
+ qRegisterMetaType();
+ qRegisterMetaType();
+ qRegisterMetaType();
+ qRegisterMetaType();
+}
+
+int main(int argc, char* argv[])
+{
+ CrashHandler::Install();
+
+ QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
+ QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
+ RegisterTypes();
+
+ QApplication app(argc, argv);
+
+#ifndef _WIN32
+ if (!PerformEarlyHardwareChecks())
+ return EXIT_FAILURE;
+#endif
+
+ std::shared_ptr autoboot;
+ if (!QtHost::ParseCommandLineOptions(argc, argv, autoboot))
+ return EXIT_FAILURE;
+
+ // Bail out if we can't find any config.
+ if (!QtHost::InitializeConfig())
+ {
+ // NOTE: No point translating this, because no config means the language won't be loaded anyway.
+ QMessageBox::critical(nullptr, QStringLiteral("Error"), QStringLiteral("Failed to initialize config."));
+ return EXIT_FAILURE;
+ }
+
+ // Start up the CPU thread.
+ MainWindow* main_window = new MainWindow(QApplication::style()->objectName());
+ QtHost::HookSignals();
+ EmuThread::start();
+
+ // Actually show the window, the emuthread might still be starting up at this point.
+ main_window->initialize();
+
+ // Skip scanning the game list when running in batch mode.
+ if (!s_batch_mode)
+ main_window->refreshGameList(false);
+
+ main_window->show();
+
+ if (autoboot)
+ g_emu_thread->startVM(std::move(autoboot));
+ else
+ main_window->startupUpdateCheck();
+
+ // This doesn't return until we exit.
+ const int result = app.exec();
+
+ // Shutting down.
+ EmuThread::stop();
+ if (g_main_window)
+ {
+ g_main_window->close();
+ delete g_main_window;
+ }
+
+ // Ensure emulog is flushed.
+ if (emuLog)
+ {
+ std::fclose(emuLog);
+ emuLog = nullptr;
+ }
+
+ return result;
+}
diff --git a/pcsx2-qt/QtHost.h b/pcsx2-qt/QtHost.h
index 2f6d27044da85..500ce2c35dd02 100644
--- a/pcsx2-qt/QtHost.h
+++ b/pcsx2-qt/QtHost.h
@@ -40,12 +40,8 @@ Q_DECLARE_METATYPE(CDVD_SourceType);
namespace QtHost
{
- bool Initialize();
- void Shutdown();
-
/// Sets batch mode (exit after game shutdown).
bool InBatchMode();
- void SetBatchMode(bool enabled);
/// Executes a function on the UI thread.
void RunOnUIThread(const std::function& func, bool block = false);
diff --git a/pcsx2-qt/pcsx2-qt.vcxproj b/pcsx2-qt/pcsx2-qt.vcxproj
index e7e785b41257d..8f29f2eb6a1e8 100644
--- a/pcsx2-qt/pcsx2-qt.vcxproj
+++ b/pcsx2-qt/pcsx2-qt.vcxproj
@@ -167,7 +167,6 @@
-
Create
diff --git a/pcsx2-qt/pcsx2-qt.vcxproj.filters b/pcsx2-qt/pcsx2-qt.vcxproj.filters
index aa24a55c49b89..dcf392a431c87 100644
--- a/pcsx2-qt/pcsx2-qt.vcxproj.filters
+++ b/pcsx2-qt/pcsx2-qt.vcxproj.filters
@@ -30,7 +30,6 @@
-