aboutsummaryrefslogtreecommitdiff
path: root/src/yuzu/main.cpp
diff options
context:
space:
mode:
authorcrueter <crueter@eden-emu.dev>2025-09-15 17:21:18 +0200
committercrueter <crueter@eden-emu.dev>2025-09-15 17:21:18 +0200
commitf4386423e88ae2c01b4f7afb1ac46deb50d39332 (patch)
tree8a3b3fc11c9f8fe1f28c3a6fde06eff98f69fa05 /src/yuzu/main.cpp
parent4c5d03f5defedd6decf2dfbbaca93a518e6d0adc (diff)
[qt] refactor: qt_common lib (#94)
This is part of a series of PRs made in preparation for the QML rewrite. this PR specifically moves a bunch of utility functions from main.cpp into qt_common, with the biggest benefit being that QML can reuse the exact same code through ctx passthrough. Also, QtCommon::Frontend is an abstraction layer over several previously Widgets-specific stuff like QMessageBox that gets used everywhere. The idea is that once QML is implemented, these functions can have a Quick version implemented for systems that don't work well with Widgets (sun) or for those on Plasma 6+ (reduces memory usage w/o Widgets linkage) although Quick from C++ is actually anal, but whatever. Other than that this should also just kinda reduce the size of main.cpp which is a 6000-line behemoth rn, and clangd straight up gives up with it for me (likely caused by the massive amount of headers, which this DOES reduce). In the future, I probably want to create a common strings lookup table that both Qt and QML can reference--though I'm not sure how much linguist likes that--which should give us a way to keep language consistent (use frozen-map). TODO: Docs for Qt stuff Co-authored-by: MaranBr <maranbr@outlook.com> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/94 Reviewed-by: MaranBr <maranbr@eden-emu.dev> Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Diffstat (limited to 'src/yuzu/main.cpp')
-rw-r--r--src/yuzu/main.cpp1313
1 files changed, 229 insertions, 1084 deletions
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index e23e9a6a48..d7d4e94ab7 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1,18 +1,19 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
-#include <clocale>
-#include <cmath>
-#include <fstream>
-#include <iostream>
-#include <memory>
-#include <thread>
#include "core/hle/service/am/applet_manager.h"
#include "core/loader/nca.h"
#include "core/tools/renderdoc.h"
#include "frontend_common/firmware_manager.h"
-
-#include <JlCompress.h>
+#include "qt_common/qt_common.h"
+#include "qt_common/qt_content_util.h"
+#include "qt_common/qt_game_util.h"
+#include "qt_common/qt_meta.h"
+#include "qt_common/qt_path_util.h"
+#include <clocale>
+#include <cmath>
+#include <memory>
+#include <thread>
#ifdef __APPLE__
#include <unistd.h> // for chdir
@@ -39,21 +40,16 @@
#include "configuration/configure_input.h"
#include "configuration/configure_per_game.h"
#include "configuration/configure_tas.h"
-#include "core/core_timing.h"
#include "core/file_sys/romfs_factory.h"
-#include "core/file_sys/vfs/vfs.h"
-#include "core/file_sys/vfs/vfs_real.h"
#include "core/frontend/applets/cabinet.h"
#include "core/frontend/applets/controller.h"
#include "core/frontend/applets/general.h"
#include "core/frontend/applets/mii_edit.h"
#include "core/frontend/applets/software_keyboard.h"
-#include "core/hle/service/acc/profile_manager.h"
#include "core/hle/service/am/frontend/applets.h"
-#include "core/hle/service/set/system_settings_server.h"
#include "frontend_common/content_manager.h"
-#include "hid_core/frontend/emulated_controller.h"
#include "hid_core/hid_core.h"
+#include "hid_core/frontend/emulated_controller.h"
#include "yuzu/multiplayer/state.h"
#include "yuzu/util/controller_navigation.h"
@@ -67,9 +63,8 @@
// These are wrappers to avoid the calls to CreateDirectory and CreateFile because of the Windows
// defines.
-static FileSys::VirtualDir VfsFilesystemCreateDirectoryWrapper(
- const FileSys::VirtualFilesystem& vfs, const std::string& path, FileSys::OpenMode mode) {
- return vfs->CreateDirectory(path, mode);
+static FileSys::VirtualDir VfsFilesystemCreateDirectoryWrapper(const std::string& path, FileSys::OpenMode mode) {
+ return QtCommon::vfs->CreateDirectory(path, mode);
}
static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::VirtualDir& dir,
@@ -118,7 +113,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include "common/scm_rev.h"
#include "common/scope_exit.h"
#ifdef _WIN32
-#include <shlobj.h>
+#include "core/core_timing.h"
#include "common/windows/timer_resolution.h"
#endif
#ifdef ARCHITECTURE_x86_64
@@ -137,6 +132,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include "core/file_sys/savedata_factory.h"
#include "core/file_sys/submission_package.h"
#include "core/hle/kernel/k_process.h"
+#include "core/hle/service/acc/profile_manager.h"
#include "core/hle/service/am/am.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/sm/sm.h"
@@ -156,7 +152,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include "yuzu/compatibility_list.h"
#include "yuzu/configuration/configure_dialog.h"
#include "yuzu/configuration/configure_input_per_game.h"
-#include "yuzu/configuration/qt_config.h"
+#include "qt_common/qt_config.h"
#include "yuzu/debugger/console.h"
#include "yuzu/debugger/controller.h"
#include "yuzu/debugger/wait_tree.h"
@@ -164,13 +160,12 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include "yuzu/discord.h"
#include "yuzu/game_list.h"
#include "yuzu/game_list_p.h"
-#include "yuzu/hotkeys.h"
#include "yuzu/install_dialog.h"
#include "yuzu/loading_screen.h"
#include "yuzu/main.h"
#include "yuzu/play_time_manager.h"
#include "yuzu/startup_checks.h"
-#include "yuzu/uisettings.h"
+#include "qt_common/uisettings.h"
#include "yuzu/util/clickable_label.h"
#include "yuzu/vk_device_info.h"
@@ -299,14 +294,6 @@ enum class CalloutFlag : uint32_t {
DRDDeprecation = 0x2,
};
-/**
- * Some games perform worse or straight-up don't work with updates,
- * so this tracks which games are bad in this regard.
- */
-constexpr std::array<u64, 1> bad_update_games{
- 0x0100F2C0115B6000 // Tears of the Kingdom
-};
-
const int GMainWindow::max_recent_files_item;
static void RemoveCachedContents() {
@@ -389,6 +376,7 @@ static void OverrideWindowsFont() {
#endif
#ifndef _WIN32
+// TODO(crueter): carboxyl does this, is it needed in qml?
inline static bool isDarkMode() {
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
const auto scheme = QGuiApplication::styleHints()->colorScheme();
@@ -403,10 +391,10 @@ inline static bool isDarkMode() {
#endif // _WIN32
GMainWindow::GMainWindow(bool has_broken_vulkan)
- : ui{std::make_unique<Ui::MainWindow>()}, system{std::make_unique<Core::System>()},
- input_subsystem{std::make_shared<InputCommon::InputSubsystem>()}, user_data_migrator{this},
- vfs{std::make_shared<FileSys::RealVfsFilesystem>()},
- provider{std::make_unique<FileSys::ManualContentProvider>()} {
+ : ui{std::make_unique<Ui::MainWindow>()},
+ input_subsystem{std::make_shared<InputCommon::InputSubsystem>()}, user_data_migrator{this} {
+ QtCommon::Init(this);
+
Common::FS::CreateEdenPaths();
this->config = std::make_unique<QtConfig>();
@@ -437,7 +425,7 @@ GMainWindow::GMainWindow(bool has_broken_vulkan)
UISettings::RestoreWindowState(config);
- system->Initialize();
+ QtCommon::system->Initialize();
Common::Log::Initialize();
Common::Log::Start();
@@ -459,11 +447,11 @@ GMainWindow::GMainWindow(bool has_broken_vulkan)
SetDiscordEnabled(UISettings::values.enable_discord_presence.GetValue());
discord_rpc->Update();
- play_time_manager = std::make_unique<PlayTime::PlayTimeManager>(system->GetProfileManager());
+ play_time_manager = std::make_unique<PlayTime::PlayTimeManager>(QtCommon::system->GetProfileManager());
Network::Init();
- RegisterMetaTypes();
+ QtCommon::Meta::RegisterMetaTypes();
InitializeWidgets();
InitializeDebugWidgets();
@@ -476,7 +464,7 @@ GMainWindow::GMainWindow(bool has_broken_vulkan)
ConnectMenuEvents();
ConnectWidgetEvents();
- system->HIDCore().ReloadInputDevices();
+ QtCommon::system->HIDCore().ReloadInputDevices();
controller_dialog->refreshConfiguration();
const auto branch_name = std::string(Common::g_scm_branch);
@@ -520,7 +508,7 @@ GMainWindow::GMainWindow(bool has_broken_vulkan)
std::chrono::duration_cast<std::chrono::duration<f64, std::milli>>(
Common::Windows::SetCurrentTimerResolutionToMaximum())
.count());
- system->CoreTiming().SetTimerResolutionNs(Common::Windows::GetCurrentTimerResolution());
+ QtCommon::system->CoreTiming().SetTimerResolutionNs(Common::Windows::GetCurrentTimerResolution());
#endif
UpdateWindowTitle();
@@ -546,10 +534,10 @@ GMainWindow::GMainWindow(bool has_broken_vulkan)
}
#endif
- system->SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
- system->RegisterContentProvider(FileSys::ContentProviderUnionSlot::FrontendManual,
- provider.get());
- system->GetFileSystemController().CreateFactories(*vfs);
+ QtCommon::system->SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
+ QtCommon::system->RegisterContentProvider(FileSys::ContentProviderUnionSlot::FrontendManual,
+ QtCommon::provider.get());
+ QtCommon::system->GetFileSystemController().CreateFactories(*QtCommon::vfs);
// Remove cached contents generated during the previous session
RemoveCachedContents();
@@ -559,7 +547,7 @@ GMainWindow::GMainWindow(bool has_broken_vulkan)
game_list->LoadCompatibilityList();
// force reload on first load to ensure add-ons get updated
- game_list->PopulateAsync(UISettings::values.game_dirs, false);
+ game_list->PopulateAsync(UISettings::values.game_dirs);
// make sure menubar has the arrow cursor instead of inheriting from this
ui->menubar->setCursor(QCursor());
@@ -663,7 +651,7 @@ GMainWindow::GMainWindow(bool has_broken_vulkan)
if (!argument_ok) {
// try to look it up by username, only finds the first username that matches.
const std::string user_arg_str = args[user_arg_idx].toStdString();
- const auto user_idx = system->GetProfileManager().GetUserIndex(user_arg_str);
+ const auto user_idx = QtCommon::system->GetProfileManager().GetUserIndex(user_arg_str);
if (user_idx == std::nullopt) {
LOG_ERROR(Frontend, "Invalid user argument");
@@ -673,7 +661,7 @@ GMainWindow::GMainWindow(bool has_broken_vulkan)
selected_user = user_idx.value();
}
- if (!system->GetProfileManager().UserExistsIndex(selected_user)) {
+ if (!QtCommon::system->GetProfileManager().UserExistsIndex(selected_user)) {
LOG_ERROR(Frontend, "Selected user doesn't exist");
continue;
}
@@ -734,65 +722,6 @@ GMainWindow::~GMainWindow() {
#endif
}
-void GMainWindow::RegisterMetaTypes() {
- // Register integral and floating point types
- qRegisterMetaType<u8>("u8");
- qRegisterMetaType<u16>("u16");
- qRegisterMetaType<u32>("u32");
- qRegisterMetaType<u64>("u64");
- qRegisterMetaType<u128>("u128");
- qRegisterMetaType<s8>("s8");
- qRegisterMetaType<s16>("s16");
- qRegisterMetaType<s32>("s32");
- qRegisterMetaType<s64>("s64");
- qRegisterMetaType<f32>("f32");
- qRegisterMetaType<f64>("f64");
-
- // Register string types
- qRegisterMetaType<std::string>("std::string");
- qRegisterMetaType<std::wstring>("std::wstring");
- qRegisterMetaType<std::u8string>("std::u8string");
- qRegisterMetaType<std::u16string>("std::u16string");
- qRegisterMetaType<std::u32string>("std::u32string");
- qRegisterMetaType<std::string_view>("std::string_view");
- qRegisterMetaType<std::wstring_view>("std::wstring_view");
- qRegisterMetaType<std::u8string_view>("std::u8string_view");
- qRegisterMetaType<std::u16string_view>("std::u16string_view");
- qRegisterMetaType<std::u32string_view>("std::u32string_view");
-
- // Register applet types
-
- // Cabinet Applet
- qRegisterMetaType<Core::Frontend::CabinetParameters>("Core::Frontend::CabinetParameters");
- qRegisterMetaType<std::shared_ptr<Service::NFC::NfcDevice>>(
- "std::shared_ptr<Service::NFC::NfcDevice>");
-
- // Controller Applet
- qRegisterMetaType<Core::Frontend::ControllerParameters>("Core::Frontend::ControllerParameters");
-
- // Profile Select Applet
- qRegisterMetaType<Core::Frontend::ProfileSelectParameters>(
- "Core::Frontend::ProfileSelectParameters");
-
- // Software Keyboard Applet
- qRegisterMetaType<Core::Frontend::KeyboardInitializeParameters>(
- "Core::Frontend::KeyboardInitializeParameters");
- qRegisterMetaType<Core::Frontend::InlineAppearParameters>(
- "Core::Frontend::InlineAppearParameters");
- qRegisterMetaType<Core::Frontend::InlineTextParameters>("Core::Frontend::InlineTextParameters");
- qRegisterMetaType<Service::AM::Frontend::SwkbdResult>("Service::AM::Frontend::SwkbdResult");
- qRegisterMetaType<Service::AM::Frontend::SwkbdTextCheckResult>(
- "Service::AM::Frontend::SwkbdTextCheckResult");
- qRegisterMetaType<Service::AM::Frontend::SwkbdReplyType>(
- "Service::AM::Frontend::SwkbdReplyType");
-
- // Web Browser Applet
- qRegisterMetaType<Service::AM::Frontend::WebExitReason>("Service::AM::Frontend::WebExitReason");
-
- // Register loader types
- qRegisterMetaType<Core::SystemResultStatus>("Core::SystemResultStatus");
-}
-
void GMainWindow::AmiiboSettingsShowDialog(const Core::Frontend::CabinetParameters& parameters,
std::shared_ptr<Service::NFC::NfcDevice> nfp_device) {
cabinet_applet =
@@ -823,7 +752,7 @@ void GMainWindow::AmiiboSettingsRequestExit() {
void GMainWindow::ControllerSelectorReconfigureControllers(
const Core::Frontend::ControllerParameters& parameters) {
controller_applet =
- new QtControllerSelectorDialog(this, parameters, input_subsystem.get(), *system);
+ new QtControllerSelectorDialog(this, parameters, input_subsystem.get(), *QtCommon::system);
SCOPE_EXIT {
controller_applet->deleteLater();
controller_applet = nullptr;
@@ -836,8 +765,8 @@ void GMainWindow::ControllerSelectorReconfigureControllers(
bool is_success = controller_applet->exec() != QDialog::Rejected;
// Don't forget to apply settings.
- system->HIDCore().DisableAllControllerConfiguration();
- system->ApplySettings();
+ QtCommon::system->HIDCore().DisableAllControllerConfiguration();
+ QtCommon::system->ApplySettings();
config->SaveAllValues();
UpdateStatusButtons();
@@ -853,7 +782,7 @@ void GMainWindow::ControllerSelectorRequestExit() {
void GMainWindow::ProfileSelectorSelectProfile(
const Core::Frontend::ProfileSelectParameters& parameters) {
- profile_select_applet = new QtProfileSelectionDialog(*system, this, parameters);
+ profile_select_applet = new QtProfileSelectionDialog(*QtCommon::system, this, parameters);
SCOPE_EXIT {
profile_select_applet->deleteLater();
profile_select_applet = nullptr;
@@ -868,7 +797,7 @@ void GMainWindow::ProfileSelectorSelectProfile(
return;
}
- const auto uuid = system->GetProfileManager().GetUser(
+ const auto uuid = QtCommon::system->GetProfileManager().GetUser(
static_cast<std::size_t>(profile_select_applet->GetIndex()));
if (!uuid.has_value()) {
emit ProfileSelectorFinishedSelection(std::nullopt);
@@ -891,7 +820,7 @@ void GMainWindow::SoftwareKeyboardInitialize(
return;
}
- software_keyboard = new QtSoftwareKeyboardDialog(render_window, *system, is_inline,
+ software_keyboard = new QtSoftwareKeyboardDialog(render_window, *QtCommon::system, is_inline,
std::move(initialize_parameters));
if (is_inline) {
@@ -1008,7 +937,7 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url,
return;
}
- web_applet = new QtNXWebEngineView(this, *system, input_subsystem.get());
+ web_applet = new QtNXWebEngineView(this, *QtCommon::system, input_subsystem.get());
ui->action_Pause->setEnabled(false);
ui->action_Restart->setEnabled(false);
@@ -1152,10 +1081,10 @@ void GMainWindow::InitializeWidgets() {
#ifdef YUZU_ENABLE_COMPATIBILITY_REPORTING
ui->action_Report_Compatibility->setVisible(true);
#endif
- render_window = new GRenderWindow(this, emu_thread.get(), input_subsystem, *system);
+ render_window = new GRenderWindow(this, emu_thread.get(), input_subsystem, *QtCommon::system);
render_window->hide();
- game_list = new GameList(vfs, provider.get(), *play_time_manager, *system, this);
+ game_list = new GameList(QtCommon::vfs, QtCommon::provider.get(), *play_time_manager, *QtCommon::system, this);
ui->horizontalLayout->addWidget(game_list);
game_list_placeholder = new GameListPlaceholder(this);
@@ -1165,7 +1094,7 @@ void GMainWindow::InitializeWidgets() {
loading_screen = new LoadingScreen(this);
loading_screen->hide();
ui->horizontalLayout->addWidget(loading_screen);
- connect(loading_screen, &LoadingScreen::Hidden, [&] {
+ connect(loading_screen, &LoadingScreen::Hidden, this, [&] {
loading_screen->Clear();
if (emulation_running) {
render_window->show();
@@ -1174,7 +1103,7 @@ void GMainWindow::InitializeWidgets() {
});
multiplayer_state = new MultiplayerState(this, game_list->GetModel(), ui->action_Leave_Room,
- ui->action_Show_Room, *system);
+ ui->action_Show_Room, *QtCommon::system);
multiplayer_state->setVisible(false);
// Create status bar
@@ -1428,12 +1357,12 @@ void GMainWindow::InitializeWidgets() {
void GMainWindow::InitializeDebugWidgets() {
QMenu* debug_menu = ui->menu_View_Debugging;
- waitTreeWidget = new WaitTreeWidget(*system, this);
+ waitTreeWidget = new WaitTreeWidget(*QtCommon::system, this);
addDockWidget(Qt::LeftDockWidgetArea, waitTreeWidget);
waitTreeWidget->hide();
debug_menu->addAction(waitTreeWidget->toggleViewAction());
- controller_dialog = new ControllerDialog(system->HIDCore(), input_subsystem, this);
+ controller_dialog = new ControllerDialog(QtCommon::system->HIDCore(), input_subsystem, this);
controller_dialog->hide();
debug_menu->addAction(controller_dialog->toggleViewAction());
@@ -1473,7 +1402,7 @@ void GMainWindow::LinkActionShortcut(QAction* action, const QString& action_name
this->addAction(action);
- auto* controller = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
+ auto* controller = QtCommon::system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
const auto* controller_hotkey =
hotkey_registry.GetControllerHotkey(main_window, action_name.toStdString(), controller);
connect(
@@ -1518,7 +1447,7 @@ void GMainWindow::InitializeHotkeys() {
const auto connect_shortcut = [&]<typename Fn>(const QString& action_name, const Fn& function) {
const auto* hotkey =
hotkey_registry.GetHotkey(main_window.toStdString(), action_name.toStdString(), this);
- auto* controller = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
+ auto* controller = QtCommon::system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
const auto* controller_hotkey = hotkey_registry.GetControllerHotkey(
main_window.toStdString(), action_name.toStdString(), controller);
connect(hotkey, &QShortcut::activated, this, function);
@@ -1542,9 +1471,9 @@ void GMainWindow::InitializeHotkeys() {
connect_shortcut(QStringLiteral("Toggle Framerate Limit"), [] {
Settings::values.use_speed_limit.SetValue(!Settings::values.use_speed_limit.GetValue());
});
- connect_shortcut(QStringLiteral("Toggle Renderdoc Capture"), [this] {
+ connect_shortcut(QStringLiteral("Toggle Renderdoc Capture"), [] {
if (Settings::values.enable_renderdoc_hotkey) {
- system->GetRenderdocAPI().ToggleCapture();
+ QtCommon::system->GetRenderdocAPI().ToggleCapture();
}
});
connect_shortcut(QStringLiteral("Toggle Mouse Panning"), [&] {
@@ -1634,8 +1563,9 @@ void GMainWindow::ConnectWidgetEvents() {
connect(game_list, &GameList::GameChosen, this, &GMainWindow::OnGameListLoadFile);
connect(game_list, &GameList::OpenDirectory, this, &GMainWindow::OnGameListOpenDirectory);
connect(game_list, &GameList::OpenFolderRequested, this, &GMainWindow::OnGameListOpenFolder);
- connect(game_list, &GameList::OpenTransferableShaderCacheRequested, this,
- &GMainWindow::OnTransferableShaderCacheOpenFile);
+ connect(game_list, &GameList::OpenTransferableShaderCacheRequested, this, [this](u64 program_id) {
+ QtCommon::Path::OpenShaderCache(program_id, this);
+ });
connect(game_list, &GameList::RemoveInstalledEntryRequested, this,
&GMainWindow::OnGameListRemoveInstalledEntry);
connect(game_list, &GameList::RemoveFileRequested, this, &GMainWindow::OnGameListRemoveFile);
@@ -1949,13 +1879,13 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa
return false;
}
- system->SetFilesystem(vfs);
+ QtCommon::system->SetFilesystem(QtCommon::vfs);
if (params.launch_type == Service::AM::LaunchType::FrontendInitiated) {
- system->GetUserChannel().clear();
+ QtCommon::system->GetUserChannel().clear();
}
- system->SetFrontendAppletSet({
+ QtCommon::system->SetFrontendAppletSet({
std::make_unique<QtAmiiboSettings>(*this), // Amiibo Settings
(UISettings::values.controller_applet_disabled.GetValue() == true)
? nullptr
@@ -1970,89 +1900,21 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa
nullptr, // Net Connect
});
- /** Game Updates check */
-
- // yuzu's configuration doesn't actually support lists so this is a bit hacky
- QSettings settings;
- QStringList currentIgnored = settings.value("ignoredBadUpdates", {}).toStringList();
-
- if (std::find(bad_update_games.begin(), bad_update_games.end(), params.program_id) !=
- bad_update_games.end() &&
- !currentIgnored.contains(QString::number(params.program_id))) {
- QMessageBox* msg = new QMessageBox(this);
- msg->setWindowTitle(tr("Game Updates Warning"));
- msg->setIcon(QMessageBox::Warning);
- msg->setText(
- tr("The game you are trying to launch is known to have performance or booting "
- "issues when updates are applied. Please try increasing the memory layout to "
- "6GB or 8GB if any issues occur.<br><br>Press \"OK\" to continue launching, or "
- "\"Cancel\" to cancel the launch."));
-
- msg->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
-
- QCheckBox* dontShowAgain = new QCheckBox(msg);
- dontShowAgain->setText(tr("Don't show again for this game"));
- msg->setCheckBox(dontShowAgain);
-
- int result = msg->exec();
-
- // wtf
- QMessageBox::ButtonRole role =
- msg->buttonRole(msg->button((QMessageBox::StandardButton)result));
-
- switch (role) {
- case QMessageBox::RejectRole:
- return false;
- case QMessageBox::AcceptRole:
- default:
- if (dontShowAgain->isChecked()) {
- currentIgnored << QString::number(params.program_id);
- settings.setValue("ignoredBadUpdates", currentIgnored);
- settings.sync();
- }
- break;
- }
- }
-
- if (FirmwareManager::GameRequiresFirmware(params.program_id) &&
- !FirmwareManager::CheckFirmwarePresence(*system)) {
- QMessageBox* msg = new QMessageBox(this);
- msg->setWindowTitle(tr("Game Requires Firmware"));
- msg->setIcon(QMessageBox::Warning);
- msg->setText(
- tr("The game you are trying to launch requires firmware to boot or to get past the "
- "opening menu. Please <a href='https://yuzu-mirror.github.io/help/quickstart'>"
- "dump and install firmware</a>, or press \"OK\" to launch anyways."));
+ /** firmware check */
- msg->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
-
- int exec_result = msg->exec();
-
- QMessageBox::ButtonRole role =
- msg->buttonRole(msg->button((QMessageBox::StandardButton)exec_result));
-
- switch (role) {
- case QMessageBox::RejectRole:
- return false;
- case QMessageBox::AcceptRole:
- default:
- break;
- }
- }
-
- if (!OnCheckNcaVerification()) {
+ if (!QtCommon::Content::CheckGameFirmware(params.program_id, this)) {
return false;
}
/** Exec */
const Core::SystemResultStatus result{
- system->Load(*render_window, filename.toStdString(), params)};
+ QtCommon::system->Load(*render_window, filename.toStdString(), params)};
const auto drd_callout = (UISettings::values.callout_flags.GetValue() &
static_cast<u32>(CalloutFlag::DRDDeprecation)) == 0;
if (result == Core::SystemResultStatus::Success &&
- system->GetAppLoader().GetFileType() == Loader::FileType::DeconstructedRomDirectory &&
+ QtCommon::system->GetAppLoader().GetFileType() == Loader::FileType::DeconstructedRomDirectory &&
drd_callout) {
UISettings::values.callout_flags = UISettings::values.callout_flags.GetValue() |
static_cast<u32>(CalloutFlag::DRDDeprecation);
@@ -2117,7 +1979,7 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa
bool GMainWindow::SelectAndSetCurrentUser(
const Core::Frontend::ProfileSelectParameters& parameters) {
- QtProfileSelectionDialog dialog(*system, this, parameters);
+ QtProfileSelectionDialog dialog(*QtCommon::system, this, parameters);
dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint);
dialog.setWindowModality(Qt::WindowModal);
@@ -2132,12 +1994,12 @@ bool GMainWindow::SelectAndSetCurrentUser(
void GMainWindow::ConfigureFilesystemProvider(const std::string& filepath) {
// Ensure all NCAs are registered before launching the game
- const auto file = vfs->OpenFile(filepath, FileSys::OpenMode::Read);
+ const auto file = QtCommon::vfs->OpenFile(filepath, FileSys::OpenMode::Read);
if (!file) {
return;
}
- auto loader = Loader::GetLoader(*system, file);
+ auto loader = Loader::GetLoader(*QtCommon::system, file);
if (!loader) {
return;
}
@@ -2150,7 +2012,7 @@ void GMainWindow::ConfigureFilesystemProvider(const std::string& filepath) {
u64 program_id = 0;
const auto res2 = loader->ReadProgramId(program_id);
if (res2 == Loader::ResultStatus::Success && file_type == Loader::FileType::NCA) {
- provider->AddEntry(FileSys::TitleType::Application,
+ QtCommon::provider->AddEntry(FileSys::TitleType::Application,
FileSys::GetCRTypeFromNCAType(FileSys::NCA{file}.GetType()), program_id,
file);
} else if (res2 == Loader::ResultStatus::Success &&
@@ -2160,7 +2022,7 @@ void GMainWindow::ConfigureFilesystemProvider(const std::string& filepath) {
: FileSys::XCI{file}.GetSecurePartitionNSP();
for (const auto& title : nsp->GetNCAs()) {
for (const auto& entry : title.second) {
- provider->AddEntry(entry.first.first, entry.first.second, title.first,
+ QtCommon::provider->AddEntry(entry.first.first, entry.first.second, title.first,
entry.second->GetBaseFile());
}
}
@@ -2186,8 +2048,8 @@ void GMainWindow::BootGame(const QString& filename, Service::AM::FrontendAppletP
last_filename_booted = filename;
ConfigureFilesystemProvider(filename.toStdString());
- const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData());
- const auto loader = Loader::GetLoader(*system, v_file, params.program_id, params.program_index);
+ const auto v_file = Core::GetGameFileFromPath(QtCommon::vfs, filename.toUtf8().constData());
+ const auto loader = Loader::GetLoader(*QtCommon::system, v_file, params.program_id, params.program_index);
if (loader != nullptr && loader->ReadProgramId(title_id) == Loader::ResultStatus::Success &&
type == StartGameType::Normal) {
@@ -2198,8 +2060,8 @@ void GMainWindow::BootGame(const QString& filename, Service::AM::FrontendAppletP
? Common::FS::PathToUTF8String(file_path.filename())
: fmt::format("{:016X}", title_id);
QtConfig per_game_config(config_file_name, Config::ConfigType::PerGameConfig);
- system->HIDCore().ReloadInputDevices();
- system->ApplySettings();
+ QtCommon::system->HIDCore().ReloadInputDevices();
+ QtCommon::system->ApplySettings();
}
Settings::LogSettings();
@@ -2225,19 +2087,19 @@ void GMainWindow::BootGame(const QString& filename, Service::AM::FrontendAppletP
return;
}
- system->SetShuttingDown(false);
+ QtCommon::system->SetShuttingDown(false);
game_list->setDisabled(true);
// Create and start the emulation thread
- emu_thread = std::make_unique<EmuThread>(*system);
+ emu_thread = std::make_unique<EmuThread>(*QtCommon::system);
emit EmulationStarting(emu_thread.get());
emu_thread->start();
// Register an ExecuteProgram callback such that Core can execute a sub-program
- system->RegisterExecuteProgramCallback(
+ QtCommon::system->RegisterExecuteProgramCallback(
[this](std::size_t program_index_) { render_window->ExecuteProgram(program_index_); });
- system->RegisterExitCallback([this] {
+ QtCommon::system->RegisterExitCallback([this] {
emu_thread->ForceStop();
render_window->Exit();
});
@@ -2277,11 +2139,11 @@ void GMainWindow::BootGame(const QString& filename, Service::AM::FrontendAppletP
std::string title_name;
std::string title_version;
- const auto res = system->GetGameName(title_name);
+ const auto res = QtCommon::system->GetGameName(title_name);
- const auto metadata = [this, title_id] {
- const FileSys::PatchManager pm(title_id, system->GetFileSystemController(),
- system->GetContentProvider());
+ const auto metadata = [title_id] {
+ const FileSys::PatchManager pm(title_id, QtCommon::system->GetFileSystemController(),
+ QtCommon::system->GetContentProvider());
return pm.GetControlMetadata();
}();
if (metadata.first != nullptr) {
@@ -2293,16 +2155,16 @@ void GMainWindow::BootGame(const QString& filename, Service::AM::FrontendAppletP
std::filesystem::path{Common::U16StringFromBuffer(filename.utf16(), filename.size())}
.filename());
}
- const bool is_64bit = system->Kernel().ApplicationProcess()->Is64Bit();
+ const bool is_64bit = QtCommon::system->Kernel().ApplicationProcess()->Is64Bit();
const auto instruction_set_suffix = is_64bit ? tr("(64-bit)") : tr("(32-bit)");
title_name = tr("%1 %2", "%1 is the title name. %2 indicates if the title is 64-bit or 32-bit")
.arg(QString::fromStdString(title_name), instruction_set_suffix)
.toStdString();
LOG_INFO(Frontend, "Booting game: {:016X} | {} | {}", title_id, title_name, title_version);
- const auto gpu_vendor = system->GPU().Renderer().GetDeviceVendor();
+ const auto gpu_vendor = QtCommon::system->GPU().Renderer().GetDeviceVendor();
UpdateWindowTitle(title_name, title_version, gpu_vendor);
- loading_screen->Prepare(system->GetAppLoader());
+ loading_screen->Prepare(QtCommon::system->GetAppLoader());
loading_screen->show();
emulation_running = true;
@@ -2330,11 +2192,11 @@ bool GMainWindow::OnShutdownBegin() {
// Disable unlimited frame rate
Settings::values.use_speed_limit.SetValue(true);
- if (system->IsShuttingDown()) {
+ if (QtCommon::system->IsShuttingDown()) {
return false;
}
- system->SetShuttingDown(true);
+ QtCommon::system->SetShuttingDown(true);
discord_rpc->Pause();
RequestGameExit();
@@ -2345,9 +2207,9 @@ bool GMainWindow::OnShutdownBegin() {
int shutdown_time = 1000;
- if (system->DebuggerEnabled()) {
+ if (QtCommon::system->DebuggerEnabled()) {
shutdown_time = 0;
- } else if (system->GetExitLocked()) {
+ } else if (QtCommon::system->GetExitLocked()) {
shutdown_time = 5000;
}
@@ -2365,7 +2227,7 @@ bool GMainWindow::OnShutdownBegin() {
}
void GMainWindow::OnShutdownBeginDialog() {
- shutdown_dialog = new OverlayDialog(this, *system, QString{}, tr("Closing software..."),
+ shutdown_dialog = new OverlayDialog(this, *QtCommon::system, QString{}, tr("Closing software..."),
QString{}, QString{}, Qt::AlignHCenter | Qt::AlignVCenter);
shutdown_dialog->open();
}
@@ -2417,10 +2279,10 @@ void GMainWindow::OnEmulationStopped() {
OnTasStateChanged();
render_window->FinalizeCamera();
- system->GetFrontendAppletHolder().SetCurrentAppletId(Service::AM::AppletId::None);
+ QtCommon::system->GetFrontendAppletHolder().SetCurrentAppletId(Service::AM::AppletId::None);
// Enable all controllers
- system->HIDCore().SetSupportedStyleTag({Core::HID::NpadStyleSet::All});
+ QtCommon::system->HIDCore().SetSupportedStyleTag({Core::HID::NpadStyleSet::All});
render_window->removeEventFilter(render_window);
render_window->setAttribute(Qt::WA_Hover, false);
@@ -2449,8 +2311,8 @@ void GMainWindow::OnEmulationStopped() {
// Enable game list
game_list->setEnabled(true);
- Settings::RestoreGlobalState(system->IsPoweredOn());
- system->HIDCore().ReloadInputDevices();
+ Settings::RestoreGlobalState(QtCommon::system->IsPoweredOn());
+ QtCommon::system->HIDCore().ReloadInputDevices();
UpdateStatusButtons();
}
@@ -2459,6 +2321,7 @@ void GMainWindow::ShutdownGame() {
return;
}
+ // TODO(crueter): make this common as well (frontend_common?)
play_time_manager->Stop();
OnShutdownBegin();
OnEmulationStopTimeExpired();
@@ -2503,21 +2366,22 @@ void GMainWindow::OnGameListLoadFile(QString game_path, u64 program_id) {
BootGame(game_path, params);
}
+// TODO(crueter): Common profile selector
void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target,
const std::string& game_path) {
std::filesystem::path path;
QString open_target;
- const auto [user_save_size, device_save_size] = [this, &game_path, &program_id] {
- const FileSys::PatchManager pm{program_id, system->GetFileSystemController(),
- system->GetContentProvider()};
+ const auto [user_save_size, device_save_size] = [&game_path, &program_id] {
+ const FileSys::PatchManager pm{program_id, QtCommon::system->GetFileSystemController(),
+ QtCommon::system->GetContentProvider()};
const auto control = pm.GetControlMetadata().first;
if (control != nullptr) {
return std::make_pair(control->GetDefaultNormalSaveSize(),
control->GetDeviceSaveDataSize());
} else {
- const auto file = Core::GetGameFileFromPath(vfs, game_path);
- const auto loader = Loader::GetLoader(*system, file);
+ const auto file = Core::GetGameFileFromPath(QtCommon::vfs, game_path);
+ const auto loader = Loader::GetLoader(*QtCommon::system, file);
FileSys::NACP nacp{};
loader->ReadControlData(nacp);
@@ -2536,7 +2400,7 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
open_target = tr("Save Data");
const auto nand_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir);
auto vfs_nand_dir =
- vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir), FileSys::OpenMode::Read);
+ QtCommon::vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir), FileSys::OpenMode::Read);
if (has_user_save) {
// User save data
@@ -2547,7 +2411,7 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
.display_options = {},
.purpose = Service::AM::Frontend::UserSelectionPurpose::General,
};
- QtProfileSelectionDialog dialog(*system, this, parameters);
+ QtProfileSelectionDialog dialog(*QtCommon::system, this, parameters);
dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint);
dialog.setWindowModality(Qt::WindowModal);
@@ -2565,7 +2429,7 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
}
const auto user_id =
- system->GetProfileManager().GetUser(static_cast<std::size_t>(index));
+ QtCommon::system->GetProfileManager().GetUser(static_cast<std::size_t>(index));
ASSERT(user_id);
const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath(
@@ -2611,19 +2475,6 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
QDesktopServices::openUrl(QUrl::fromLocalFile(qpath));
}
-void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
- const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
- const auto shader_cache_folder_path{shader_cache_dir / fmt::format("{:016x}", program_id)};
- if (!Common::FS::CreateDirs(shader_cache_folder_path)) {
- QMessageBox::warning(this, tr("Error Opening Transferable Shader Cache"),
- tr("Failed to create the shader cache directory for this title."));
- return;
- }
- const auto shader_path_string{Common::FS::PathToUTF8String(shader_cache_folder_path)};
- const auto qt_shader_cache_path = QString::fromStdString(shader_path_string);
- QDesktopServices::openUrl(QUrl::fromLocalFile(qt_shader_cache_path));
-}
-
static bool RomFSRawCopy(size_t total_size, size_t& read_size, QProgressDialog& dialog,
const FileSys::VirtualDir& src, const FileSys::VirtualDir& dest,
bool full) {
@@ -2686,26 +2537,17 @@ static bool RomFSRawCopy(size_t total_size, size_t& read_size, QProgressDialog&
return true;
}
-QString GMainWindow::GetGameListErrorRemoving(InstalledEntryType type) const {
- switch (type) {
- case InstalledEntryType::Game:
- return tr("Error Removing Contents");
- case InstalledEntryType::Update:
- return tr("Error Removing Update");
- case InstalledEntryType::AddOnContent:
- return tr("Error Removing DLC");
- default:
- return QStringLiteral("Error Removing <Invalid Type>");
- }
-}
-void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryType type) {
+// TODO(crueter): All this can be transfered to qt_common
+// Aldoe I need to decide re: message boxes for QML
+// translations_common? strings_common? qt_strings? who knows
+void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, QtCommon::Game::InstalledEntryType type) {
const QString entry_question = [type] {
switch (type) {
- case InstalledEntryType::Game:
+ case QtCommon::Game::InstalledEntryType::Game:
return tr("Remove Installed Game Contents?");
- case InstalledEntryType::Update:
+ case QtCommon::Game::InstalledEntryType::Update:
return tr("Remove Installed Game Update?");
- case InstalledEntryType::AddOnContent:
+ case QtCommon::Game::InstalledEntryType::AddOnContent:
return tr("Remove Installed Game DLC?");
default:
return QStringLiteral("Remove Installed Game <Invalid Type>?");
@@ -2717,18 +2559,19 @@ void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryT
return;
}
+ // TODO(crueter): move this to QtCommon (populate async?)
switch (type) {
- case InstalledEntryType::Game:
- RemoveBaseContent(program_id, type);
+ case QtCommon::Game::InstalledEntryType::Game:
+ QtCommon::Game::RemoveBaseContent(program_id, type);
[[fallthrough]];
- case InstalledEntryType::Update:
- RemoveUpdateContent(program_id, type);
- if (type != InstalledEntryType::Game) {
+ case QtCommon::Game::InstalledEntryType::Update:
+ QtCommon::Game::RemoveUpdateContent(program_id, type);
+ if (type != QtCommon::Game::InstalledEntryType::Game) {
break;
}
[[fallthrough]];
- case InstalledEntryType::AddOnContent:
- RemoveAddOnContent(program_id, type);
+ case QtCommon::Game::InstalledEntryType::AddOnContent:
+ QtCommon::Game::RemoveAddOnContent(program_id, type);
break;
}
Common::FS::RemoveDirRecursively(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) /
@@ -2736,55 +2579,19 @@ void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryT
game_list->PopulateAsync(UISettings::values.game_dirs);
}
-void GMainWindow::RemoveBaseContent(u64 program_id, InstalledEntryType type) {
- const auto res =
- ContentManager::RemoveBaseContent(system->GetFileSystemController(), program_id);
- if (res) {
- QMessageBox::information(this, tr("Successfully Removed"),
- tr("Successfully removed the installed base game."));
- } else {
- QMessageBox::warning(
- this, GetGameListErrorRemoving(type),
- tr("The base game is not installed in the NAND and cannot be removed."));
- }
-}
-
-void GMainWindow::RemoveUpdateContent(u64 program_id, InstalledEntryType type) {
- const auto res = ContentManager::RemoveUpdate(system->GetFileSystemController(), program_id);
- if (res) {
- QMessageBox::information(this, tr("Successfully Removed"),
- tr("Successfully removed the installed update."));
- } else {
- QMessageBox::warning(this, GetGameListErrorRemoving(type),
- tr("There is no update installed for this title."));
- }
-}
-
-void GMainWindow::RemoveAddOnContent(u64 program_id, InstalledEntryType type) {
- const size_t count = ContentManager::RemoveAllDLC(*system, program_id);
- if (count == 0) {
- QMessageBox::warning(this, GetGameListErrorRemoving(type),
- tr("There are no DLC installed for this title."));
- return;
- }
-
- QMessageBox::information(this, tr("Successfully Removed"),
- tr("Successfully removed %1 installed DLC.").arg(count));
-}
-
-void GMainWindow::OnGameListRemoveFile(u64 program_id, GameListRemoveTarget target,
+void GMainWindow::OnGameListRemoveFile(u64 program_id, QtCommon::Game::GameListRemoveTarget target,
const std::string& game_path) {
const QString question = [target] {
switch (target) {
- case GameListRemoveTarget::GlShaderCache:
+ case QtCommon::Game::GameListRemoveTarget::GlShaderCache:
return tr("Delete OpenGL Transferable Shader Cache?");
- case GameListRemoveTarget::VkShaderCache:
+ case QtCommon::Game::GameListRemoveTarget::VkShaderCache:
return tr("Delete Vulkan Transferable Shader Cache?");
- case GameListRemoveTarget::AllShaderCache:
+ case QtCommon::Game::GameListRemoveTarget::AllShaderCache:
return tr("Delete All Transferable Shader Caches?");
- case GameListRemoveTarget::CustomConfiguration:
+ case QtCommon::Game::GameListRemoveTarget::CustomConfiguration:
return tr("Remove Custom Game Configuration?");
- case GameListRemoveTarget::CacheStorage:
+ case QtCommon::Game::GameListRemoveTarget::CacheStorage:
return tr("Remove Cache Storage?");
default:
return QString{};
@@ -2797,20 +2604,20 @@ void GMainWindow::OnGameListRemoveFile(u64 program_id, GameListRemoveTarget targ
}
switch (target) {
- case GameListRemoveTarget::VkShaderCache:
- RemoveVulkanDriverPipelineCache(program_id);
+ case QtCommon::Game::GameListRemoveTarget::VkShaderCache:
+ QtCommon::Game::RemoveVulkanDriverPipelineCache(program_id);
[[fallthrough]];
- case GameListRemoveTarget::GlShaderCache:
- RemoveTransferableShaderCache(program_id, target);
+ case QtCommon::Game::GameListRemoveTarget::GlShaderCache:
+ QtCommon::Game::RemoveTransferableShaderCache(program_id, target);
break;
- case GameListRemoveTarget::AllShaderCache:
- RemoveAllTransferableShaderCaches(program_id);
+ case QtCommon::Game::GameListRemoveTarget::AllShaderCache:
+ QtCommon::Game::RemoveAllTransferableShaderCaches(program_id);
break;
- case GameListRemoveTarget::CustomConfiguration:
- RemoveCustomConfiguration(program_id, game_path);
+ case QtCommon::Game::GameListRemoveTarget::CustomConfiguration:
+ QtCommon::Game::RemoveCustomConfiguration(program_id, game_path);
break;
- case GameListRemoveTarget::CacheStorage:
- RemoveCacheStorage(program_id);
+ case QtCommon::Game::GameListRemoveTarget::CacheStorage:
+ QtCommon::Game::RemoveCacheStorage(program_id);
break;
}
}
@@ -2826,107 +2633,6 @@ void GMainWindow::OnGameListRemovePlayTimeData(u64 program_id) {
game_list->PopulateAsync(UISettings::values.game_dirs);
}
-void GMainWindow::RemoveTransferableShaderCache(u64 program_id, GameListRemoveTarget target) {
- const auto target_file_name = [target] {
- switch (target) {
- case GameListRemoveTarget::GlShaderCache:
- return "opengl.bin";
- case GameListRemoveTarget::VkShaderCache:
- return "vulkan.bin";
- default:
- return "";
- }
- }();
- const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
- const auto shader_cache_folder_path = shader_cache_dir / fmt::format("{:016x}", program_id);
- const auto target_file = shader_cache_folder_path / target_file_name;
-
- if (!Common::FS::Exists(target_file)) {
- QMessageBox::warning(this, tr("Error Removing Transferable Shader Cache"),
- tr("A shader cache for this title does not exist."));
- return;
- }
- if (Common::FS::RemoveFile(target_file)) {
- QMessageBox::information(this, tr("Successfully Removed"),
- tr("Successfully removed the transferable shader cache."));
- } else {
- QMessageBox::warning(this, tr("Error Removing Transferable Shader Cache"),
- tr("Failed to remove the transferable shader cache."));
- }
-}
-
-void GMainWindow::RemoveVulkanDriverPipelineCache(u64 program_id) {
- static constexpr std::string_view target_file_name = "vulkan_pipelines.bin";
-
- const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
- const auto shader_cache_folder_path = shader_cache_dir / fmt::format("{:016x}", program_id);
- const auto target_file = shader_cache_folder_path / target_file_name;
-
- if (!Common::FS::Exists(target_file)) {
- return;
- }
- if (!Common::FS::RemoveFile(target_file)) {
- QMessageBox::warning(this, tr("Error Removing Vulkan Driver Pipeline Cache"),
- tr("Failed to remove the driver pipeline cache."));
- }
-}
-
-void GMainWindow::RemoveAllTransferableShaderCaches(u64 program_id) {
- const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
- const auto program_shader_cache_dir = shader_cache_dir / fmt::format("{:016x}", program_id);
-
- if (!Common::FS::Exists(program_shader_cache_dir)) {
- QMessageBox::warning(this, tr("Error Removing Transferable Shader Caches"),
- tr("A shader cache for this title does not exist."));
- return;
- }
- if (Common::FS::RemoveDirRecursively(program_shader_cache_dir)) {
- QMessageBox::information(this, tr("Successfully Removed"),
- tr("Successfully removed the transferable shader caches."));
- } else {
- QMessageBox::warning(this, tr("Error Removing Transferable Shader Caches"),
- tr("Failed to remove the transferable shader cache directory."));
- }
-}
-
-void GMainWindow::RemoveCustomConfiguration(u64 program_id, const std::string& game_path) {
- const auto file_path = std::filesystem::path(Common::FS::ToU8String(game_path));
- const auto config_file_name =
- program_id == 0 ? Common::FS::PathToUTF8String(file_path.filename()).append(".ini")
- : fmt::format("{:016X}.ini", program_id);
- const auto custom_config_file_path =
- Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir) / "custom" / config_file_name;
-
- if (!Common::FS::Exists(custom_config_file_path)) {
- QMessageBox::warning(this, tr("Error Removing Custom Configuration"),
- tr("A custom configuration for this title does not exist."));
- return;
- }
-
- if (Common::FS::RemoveFile(custom_config_file_path)) {
- QMessageBox::information(this, tr("Successfully Removed"),
- tr("Successfully removed the custom game configuration."));
- } else {
- QMessageBox::warning(this, tr("Error Removing Custom Configuration"),
- tr("Failed to remove the custom game configuration."));
- }
-}
-
-void GMainWindow::RemoveCacheStorage(u64 program_id) {
- const auto nand_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir);
- auto vfs_nand_dir =
- vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir), FileSys::OpenMode::Read);
-
- const auto cache_storage_path = FileSys::SaveDataFactory::GetFullPath(
- {}, vfs_nand_dir, FileSys::SaveDataSpaceId::User, FileSys::SaveDataType::Cache,
- 0 /* program_id */, {}, 0);
-
- const auto path = Common::FS::ConcatPathSafe(nand_dir, cache_storage_path);
-
- // Not an error if it wasn't cleared.
- Common::FS::RemoveDirRecursively(path);
-}
-
void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_path,
DumpRomFSTarget target) {
const auto failed = [this] {
@@ -2936,7 +2642,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
};
const auto loader =
- Loader::GetLoader(*system, vfs->OpenFile(game_path, FileSys::OpenMode::Read));
+ Loader::GetLoader(*QtCommon::system, QtCommon::vfs->OpenFile(game_path, FileSys::OpenMode::Read));
if (loader == nullptr) {
failed();
return;
@@ -2945,7 +2651,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
FileSys::VirtualFile packed_update_raw{};
loader->ReadUpdateRaw(packed_update_raw);
- const auto& installed = system->GetContentProvider();
+ const auto& installed = QtCommon::system->GetContentProvider();
u64 title_id{};
u8 raw_type{};
@@ -2977,14 +2683,14 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
const auto path = Common::FS::PathToUTF8String(dump_dir / romfs_dir);
- const FileSys::PatchManager pm{title_id, system->GetFileSystemController(), installed};
+ const FileSys::PatchManager pm{title_id, QtCommon::system->GetFileSystemController(), installed};
auto romfs = pm.PatchRomFS(base_nca.get(), base_romfs, type, packed_update_raw, false);
- const auto out = VfsFilesystemCreateDirectoryWrapper(vfs, path, FileSys::OpenMode::ReadWrite);
+ const auto out = VfsFilesystemCreateDirectoryWrapper(path, FileSys::OpenMode::ReadWrite);
if (out == nullptr) {
failed();
- vfs->DeleteDirectory(path);
+ QtCommon::vfs->DeleteDirectory(path);
return;
}
@@ -2998,7 +2704,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
selections, 0, false, &ok);
if (!ok) {
failed();
- vfs->DeleteDirectory(path);
+ QtCommon::vfs->DeleteDirectory(path);
return;
}
@@ -3038,41 +2744,13 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
} else {
progress.close();
failed();
- vfs->DeleteDirectory(path);
+ QtCommon::vfs->DeleteDirectory(path);
}
}
+// END
void GMainWindow::OnGameListVerifyIntegrity(const std::string& game_path) {
- const auto NotImplemented = [this] {
- QMessageBox::warning(this, tr("Integrity verification couldn't be performed!"),
- tr("File contents were not checked for validity."));
- };
-
- QProgressDialog progress(tr("Verifying integrity..."), tr("Cancel"), 0, 100, this);
- progress.setWindowModality(Qt::WindowModal);
- progress.setMinimumDuration(100);
- progress.setAutoClose(false);
- progress.setAutoReset(false);
-
- const auto QtProgressCallback = [&](size_t total_size, size_t processed_size) {
- progress.setValue(static_cast<int>((processed_size * 100) / total_size));
- return progress.wasCanceled();
- };
-
- const auto result = ContentManager::VerifyGameContents(*system, game_path, QtProgressCallback);
- progress.close();
- switch (result) {
- case ContentManager::GameVerificationResult::Success:
- QMessageBox::information(this, tr("Integrity verification succeeded!"),
- tr("The operation completed successfully."));
- break;
- case ContentManager::GameVerificationResult::Failed:
- QMessageBox::critical(this, tr("Integrity verification failed!"),
- tr("File contents may be corrupt."));
- break;
- case ContentManager::GameVerificationResult::NotImplemented:
- NotImplemented();
- }
+ QtCommon::Content::VerifyGameContents(game_path);
}
void GMainWindow::OnGameListCopyTID(u64 program_id) {
@@ -3093,172 +2771,12 @@ void GMainWindow::OnGameListNavigateToGamedbEntry(u64 program_id,
QUrl(QStringLiteral("https://eden-emulator.github.io/game/") + directory));
}
-bool GMainWindow::CreateShortcutLink(const std::filesystem::path& shortcut_path,
- const std::string& comment,
- const std::filesystem::path& icon_path,
- const std::filesystem::path& command,
- const std::string& arguments, const std::string& categories,
- const std::string& keywords, const std::string& name) try {
-#ifdef _WIN32 // Windows
- HRESULT hr = CoInitialize(nullptr);
- if (FAILED(hr)) {
- LOG_ERROR(Frontend, "CoInitialize failed");
- return false;
- }
- SCOPE_EXIT {
- CoUninitialize();
- };
- IShellLinkW* ps1 = nullptr;
- IPersistFile* persist_file = nullptr;
- SCOPE_EXIT {
- if (persist_file != nullptr) {
- persist_file->Release();
- }
- if (ps1 != nullptr) {
- ps1->Release();
- }
- };
- HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLinkW,
- reinterpret_cast<void**>(&ps1));
- if (FAILED(hres)) {
- LOG_ERROR(Frontend, "Failed to create IShellLinkW instance");
- return false;
- }
- hres = ps1->SetPath(command.c_str());
- if (FAILED(hres)) {
- LOG_ERROR(Frontend, "Failed to set path");
- return false;
- }
- if (!arguments.empty()) {
- hres = ps1->SetArguments(Common::UTF8ToUTF16W(arguments).data());
- if (FAILED(hres)) {
- LOG_ERROR(Frontend, "Failed to set arguments");
- return false;
- }
- }
- if (!comment.empty()) {
- hres = ps1->SetDescription(Common::UTF8ToUTF16W(comment).data());
- if (FAILED(hres)) {
- LOG_ERROR(Frontend, "Failed to set description");
- return false;
- }
- }
- if (std::filesystem::is_regular_file(icon_path)) {
- hres = ps1->SetIconLocation(icon_path.c_str(), 0);
- if (FAILED(hres)) {
- LOG_ERROR(Frontend, "Failed to set icon location");
- return false;
- }
- }
- hres = ps1->QueryInterface(IID_IPersistFile, reinterpret_cast<void**>(&persist_file));
- if (FAILED(hres)) {
- LOG_ERROR(Frontend, "Failed to get IPersistFile interface");
- return false;
- }
- hres = persist_file->Save(std::filesystem::path{shortcut_path / (name + ".lnk")}.c_str(), TRUE);
- if (FAILED(hres)) {
- LOG_ERROR(Frontend, "Failed to save shortcut");
- return false;
- }
- return true;
-#elif defined(__unix__) && !defined(__APPLE__) && !defined(__ANDROID__) // Any desktop NIX
- std::filesystem::path shortcut_path_full = shortcut_path / (name + ".desktop");
- std::ofstream shortcut_stream(shortcut_path_full, std::ios::binary | std::ios::trunc);
- if (!shortcut_stream.is_open()) {
- LOG_ERROR(Frontend, "Failed to create shortcut");
- return false;
- }
- // TODO: Migrate fmt::print to std::print in futures STD C++ 23.
- fmt::print(shortcut_stream, "[Desktop Entry]\n");
- fmt::print(shortcut_stream, "Type=Application\n");
- fmt::print(shortcut_stream, "Version=1.0\n");
- fmt::print(shortcut_stream, "Name={}\n", name);
- if (!comment.empty()) {
- fmt::print(shortcut_stream, "Comment={}\n", comment);
- }
- if (std::filesystem::is_regular_file(icon_path)) {
- fmt::print(shortcut_stream, "Icon={}\n", icon_path.string());
- }
- fmt::print(shortcut_stream, "TryExec={}\n", command.string());
- fmt::print(shortcut_stream, "Exec={} {}\n", command.string(), arguments);
- if (!categories.empty()) {
- fmt::print(shortcut_stream, "Categories={}\n", categories);
- }
- if (!keywords.empty()) {
- fmt::print(shortcut_stream, "Keywords={}\n", keywords);
- }
- return true;
-#else // Unsupported platform
- return false;
-#endif
-} catch (const std::exception& e) {
- LOG_ERROR(Frontend, "Failed to create shortcut: {}", e.what());
- return false;
-}
-// Messages in pre-defined message boxes for less code spaghetti
-bool GMainWindow::CreateShortcutMessagesGUI(QWidget* parent, int imsg, const QString& game_title) {
- int result = 0;
- QMessageBox::StandardButtons buttons;
- switch (imsg) {
- case GMainWindow::CREATE_SHORTCUT_MSGBOX_FULLSCREEN_YES:
- buttons = QMessageBox::Yes | QMessageBox::No;
- result =
- QMessageBox::information(parent, tr("Create Shortcut"),
- tr("Do you want to launch the game in fullscreen?"), buttons);
- return result == QMessageBox::Yes;
- case GMainWindow::CREATE_SHORTCUT_MSGBOX_SUCCESS:
- QMessageBox::information(parent, tr("Create Shortcut"),
- tr("Successfully created a shortcut to %1").arg(game_title));
- return false;
- case GMainWindow::CREATE_SHORTCUT_MSGBOX_APPVOLATILE_WARNING:
- buttons = QMessageBox::StandardButton::Ok | QMessageBox::StandardButton::Cancel;
- result =
- QMessageBox::warning(this, tr("Create Shortcut"),
- tr("This will create a shortcut to the current AppImage. This may "
- "not work well if you update. Continue?"),
- buttons);
- return result == QMessageBox::Ok;
- default:
- buttons = QMessageBox::Ok;
- QMessageBox::critical(parent, tr("Create Shortcut"),
- tr("Failed to create a shortcut to %1").arg(game_title), buttons);
- return false;
- }
-}
-
-bool GMainWindow::MakeShortcutIcoPath(const u64 program_id, const std::string_view game_file_name,
- std::filesystem::path& out_icon_path) {
- // Get path to Yuzu icons directory & icon extension
- std::string ico_extension = "png";
-#if defined(_WIN32)
- out_icon_path = Common::FS::GetEdenPath(Common::FS::EdenPath::IconsDir);
- ico_extension = "ico";
-#elif defined(__unix__) && !defined(__APPLE__) && !defined(__ANDROID__)
- out_icon_path = Common::FS::GetDataDirectory("XDG_DATA_HOME") / "icons/hicolor/256x256";
-#endif
- // Create icons directory if it doesn't exist
- if (!Common::FS::CreateDirs(out_icon_path)) {
- QMessageBox::critical(
- this, tr("Create Icon"),
- tr("Cannot create icon file. Path \"%1\" does not exist and cannot be created.")
- .arg(QString::fromStdString(out_icon_path.string())),
- QMessageBox::StandardButton::Ok);
- out_icon_path.clear();
- return false;
- }
-
- // Create icon file path
- out_icon_path /= (program_id == 0 ? fmt::format("eden-{}.{}", game_file_name, ico_extension)
- : fmt::format("eden-{:016X}.{}", program_id, ico_extension));
- return true;
-}
-
void GMainWindow::OnGameListCreateShortcut(u64 program_id, const std::string& game_path,
- GameListShortcutTarget target) {
+ const QtCommon::Game::ShortcutTarget target) {
// Create shortcut
std::string arguments = fmt::format("-g \"{:s}\"", game_path);
- CreateShortcut(game_path, program_id, "", target, arguments, true);
+ QtCommon::Game::CreateShortcut(game_path, program_id, "", target, arguments, true);
}
void GMainWindow::OnGameListOpenDirectory(const QString& directory) {
@@ -3313,8 +2831,8 @@ void GMainWindow::OnGameListShowList(bool show) {
void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) {
u64 title_id{};
- const auto v_file = Core::GetGameFileFromPath(vfs, file);
- const auto loader = Loader::GetLoader(*system, v_file);
+ const auto v_file = Core::GetGameFileFromPath(QtCommon::vfs, file);
+ const auto loader = Loader::GetLoader(*QtCommon::system, v_file);
if (loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success) {
QMessageBox::information(this, tr("Properties"),
@@ -3441,8 +2959,8 @@ void GMainWindow::OnMenuInstallToNAND() {
}
return false;
};
- future = QtConcurrent::run([this, &file, progress_callback] {
- return ContentManager::InstallNSP(*system, *vfs, file.toStdString(),
+ future = QtConcurrent::run([&file, progress_callback] {
+ return ContentManager::InstallNSP(*QtCommon::system, *QtCommon::vfs, file.toStdString(),
progress_callback);
});
@@ -3534,7 +3052,7 @@ ContentManager::InstallResult GMainWindow::InstallNCA(const QString& filename) {
}
const bool is_application = index >= static_cast<s32>(FileSys::TitleType::Application);
- const auto& fs_controller = system->GetFileSystemController();
+ const auto& fs_controller = QtCommon::system->GetFileSystemController();
auto* registered_cache = is_application ? fs_controller.GetUserNANDContents()
: fs_controller.GetSystemNANDContents();
@@ -3545,7 +3063,7 @@ ContentManager::InstallResult GMainWindow::InstallNCA(const QString& filename) {
}
return false;
};
- return ContentManager::InstallNCA(*vfs, filename.toStdString(), *registered_cache,
+ return ContentManager::InstallNCA(*QtCommon::vfs, filename.toStdString(), *registered_cache,
static_cast<FileSys::TitleType>(index), progress_callback);
}
@@ -3574,7 +3092,7 @@ void GMainWindow::OnStartGame() {
UpdateMenuState();
OnTasStateChanged();
- play_time_manager->SetProgramId(system->GetApplicationProcessProgramID());
+ play_time_manager->SetProgramId(QtCommon::system->GetApplicationProcessProgramID());
play_time_manager->Start();
discord_rpc->Update();
@@ -3585,7 +3103,7 @@ void GMainWindow::OnStartGame() {
}
void GMainWindow::OnRestartGame() {
- if (!system->IsPoweredOn()) {
+ if (!QtCommon::system->IsPoweredOn()) {
return;
}
@@ -3633,7 +3151,7 @@ void GMainWindow::OnStopGame() {
bool GMainWindow::ConfirmShutdownGame() {
if (UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Always) {
- if (system->GetExitLocked()) {
+ if (QtCommon::system->GetExitLocked()) {
if (!ConfirmForceLockedExit()) {
return false;
}
@@ -3645,7 +3163,7 @@ bool GMainWindow::ConfirmShutdownGame() {
} else {
if (UISettings::values.confirm_before_stopping.GetValue() ==
ConfirmStop::Ask_Based_On_Game &&
- system->GetExitLocked()) {
+ QtCommon::system->GetExitLocked()) {
if (!ConfirmForceLockedExit()) {
return false;
}
@@ -3672,12 +3190,12 @@ void GMainWindow::OnExit() {
}
void GMainWindow::OnSaveConfig() {
- system->ApplySettings();
+ QtCommon::system->ApplySettings();
config->SaveAllValues();
}
void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_text) {
- error_applet = new OverlayDialog(render_window, *system, error_code, error_text, QString{},
+ error_applet = new OverlayDialog(render_window, *QtCommon::system, error_code, error_text, QString{},
tr("OK"), Qt::AlignLeft | Qt::AlignVCenter);
SCOPE_EXIT {
error_applet->deleteLater();
@@ -3906,7 +3424,7 @@ void GMainWindow::OnConfigure() {
Settings::SetConfiguringGlobal(true);
ConfigureDialog configure_dialog(this, hotkey_registry, input_subsystem.get(),
- vk_device_records, *system,
+ vk_device_records, *QtCommon::system,
!multiplayer_state->IsHostingPublicRoom());
connect(&configure_dialog, &ConfigureDialog::LanguageChanged, this,
&GMainWindow::OnLanguageChanged);
@@ -4007,7 +3525,7 @@ void GMainWindow::OnConfigure() {
UpdateStatusButtons();
controller_dialog->refreshConfiguration();
- system->ApplySettings();
+ QtCommon::system->ApplySettings();
}
void GMainWindow::OnConfigureTas() {
@@ -4015,7 +3533,7 @@ void GMainWindow::OnConfigureTas() {
const auto result = dialog.exec();
if (result != QDialog::Accepted && !UISettings::values.configuration_applied) {
- Settings::RestoreGlobalState(system->IsPoweredOn());
+ Settings::RestoreGlobalState(QtCommon::system->IsPoweredOn());
return;
} else if (result == QDialog::Accepted) {
dialog.ApplyConfiguration();
@@ -4029,7 +3547,7 @@ void GMainWindow::OnTasStartStop() {
}
// Disable system buttons to prevent TAS from executing a hotkey
- auto* controller = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
+ auto* controller = QtCommon::system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
controller->ResetSystemButtons();
input_subsystem->GetTas()->StartStop();
@@ -4045,7 +3563,7 @@ void GMainWindow::OnTasRecord() {
}
// Disable system buttons to prevent TAS from recording a hotkey
- auto* controller = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
+ auto* controller = QtCommon::system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
controller->ResetSystemButtons();
const bool is_recording = input_subsystem->GetTas()->Record();
@@ -4067,8 +3585,8 @@ void GMainWindow::OnTasReset() {
void GMainWindow::OnToggleDockedMode() {
const bool is_docked = Settings::IsDockedMode();
- auto* player_1 = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
- auto* handheld = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
+ auto* player_1 = QtCommon::system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
+ auto* handheld = QtCommon::system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
if (!is_docked && handheld->IsConnected()) {
QMessageBox::warning(this, tr("Invalid config detected"),
@@ -4083,7 +3601,7 @@ void GMainWindow::OnToggleDockedMode() {
Settings::values.use_docked_mode.SetValue(is_docked ? Settings::ConsoleMode::Handheld
: Settings::ConsoleMode::Docked);
UpdateDockedButton();
- OnDockedModeChanged(is_docked, !is_docked, *system);
+ OnDockedModeChanged(is_docked, !is_docked, *QtCommon::system);
}
void GMainWindow::OnToggleGpuAccuracy() {
@@ -4100,7 +3618,7 @@ void GMainWindow::OnToggleGpuAccuracy() {
}
}
- system->ApplySettings();
+ QtCommon::system->ApplySettings();
UpdateGPUAccuracyButton();
}
@@ -4165,20 +3683,20 @@ void GMainWindow::OnToggleGraphicsAPI() {
}
void GMainWindow::OnConfigurePerGame() {
- const u64 title_id = system->GetApplicationProcessProgramID();
+ const u64 title_id = QtCommon::system->GetApplicationProcessProgramID();
OpenPerGameConfiguration(title_id, current_game_path.toStdString());
}
void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file_name) {
- const auto v_file = Core::GetGameFileFromPath(vfs, file_name);
+ const auto v_file = Core::GetGameFileFromPath(QtCommon::vfs, file_name);
Settings::SetConfiguringGlobal(false);
- ConfigurePerGame dialog(this, title_id, file_name, vk_device_records, *system);
+ ConfigurePerGame dialog(this, title_id, file_name, vk_device_records, *QtCommon::system);
dialog.LoadFromFile(v_file);
const auto result = dialog.exec();
if (result != QDialog::Accepted && !UISettings::values.configuration_applied) {
- Settings::RestoreGlobalState(system->IsPoweredOn());
+ Settings::RestoreGlobalState(QtCommon::system->IsPoweredOn());
return;
} else if (result == QDialog::Accepted) {
dialog.ApplyConfiguration();
@@ -4190,9 +3708,9 @@ void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file
}
// Do not cause the global config to write local settings into the config file
- const bool is_powered_on = system->IsPoweredOn();
+ const bool is_powered_on = QtCommon::system->IsPoweredOn();
Settings::RestoreGlobalState(is_powered_on);
- system->HIDCore().ReloadInputDevices();
+ QtCommon::system->HIDCore().ReloadInputDevices();
UISettings::values.configuration_applied = false;
@@ -4236,6 +3754,7 @@ void GMainWindow::OnLoadAmiibo() {
LoadAmiibo(filename);
}
+// TODO(crueter): does this need to be ported to QML?
bool GMainWindow::question(QWidget* parent, const QString& title, const QString& text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton) {
@@ -4246,7 +3765,7 @@ bool GMainWindow::question(QWidget* parent, const QString& title, const QString&
box_dialog->setDefaultButton(defaultButton);
ControllerNavigation* controller_navigation =
- new ControllerNavigation(system->HIDCore(), box_dialog);
+ new ControllerNavigation(QtCommon::system->HIDCore(), box_dialog);
connect(controller_navigation, &ControllerNavigation::TriggerKeyboardEvent,
[box_dialog](Qt::Key key) {
QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier);
@@ -4287,182 +3806,35 @@ void GMainWindow::LoadAmiibo(const QString& filename) {
}
void GMainWindow::OnOpenRootDataFolder() {
- QDesktopServices::openUrl(
- QUrl(QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::EdenDir))));
+ QtCommon::Game::OpenRootDataFolder();
}
-void GMainWindow::OnOpenNANDFolder() {
- QDesktopServices::openUrl(QUrl::fromLocalFile(
- QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::NANDDir))));
+void GMainWindow::OnOpenNANDFolder()
+{
+ QtCommon::Game::OpenNANDFolder();
}
-void GMainWindow::OnOpenSDMCFolder() {
- QDesktopServices::openUrl(QUrl::fromLocalFile(
- QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::SDMCDir))));
+void GMainWindow::OnOpenSDMCFolder()
+{
+ QtCommon::Game::OpenSDMCFolder();
}
-void GMainWindow::OnOpenModFolder() {
- QDesktopServices::openUrl(QUrl::fromLocalFile(
- QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::LoadDir))));
+void GMainWindow::OnOpenModFolder()
+{
+ QtCommon::Game::OpenModFolder();
}
-void GMainWindow::OnOpenLogFolder() {
- QDesktopServices::openUrl(QUrl::fromLocalFile(
- QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::LogDir))));
+void GMainWindow::OnOpenLogFolder()
+{
+ QtCommon::Game::OpenLogFolder();
}
void GMainWindow::OnVerifyInstalledContents() {
- // Initialize a progress dialog.
- QProgressDialog progress(tr("Verifying integrity..."), tr("Cancel"), 0, 100, this);
- progress.setWindowModality(Qt::WindowModal);
- progress.setMinimumDuration(100);
- progress.setAutoClose(false);
- progress.setAutoReset(false);
-
- // Declare progress callback.
- auto QtProgressCallback = [&](size_t total_size, size_t processed_size) {
- progress.setValue(static_cast<int>((processed_size * 100) / total_size));
- return progress.wasCanceled();
- };
-
- const std::vector<std::string> result =
- ContentManager::VerifyInstalledContents(*system, *provider, QtProgressCallback);
- progress.close();
-
- if (result.empty()) {
- QMessageBox::information(this, tr("Integrity verification succeeded!"),
- tr("The operation completed successfully."));
- } else {
- const auto failed_names =
- QString::fromStdString(fmt::format("{}", fmt::join(result, "\n")));
- QMessageBox::critical(
- this, tr("Integrity verification failed!"),
- tr("Verification failed for the following files:\n\n%1").arg(failed_names));
- }
+ QtCommon::Content::VerifyInstalledContents();
}
void GMainWindow::InstallFirmware(const QString& location, bool recursive) {
- QProgressDialog progress(tr("Installing Firmware..."), tr("Cancel"), 0, 100, this);
- progress.setWindowModality(Qt::WindowModal);
- progress.setMinimumDuration(100);
- progress.setAutoClose(false);
- progress.setAutoReset(false);
- progress.show();
-
- // Declare progress callback.
- auto QtProgressCallback = [&](size_t total_size, size_t processed_size) {
- progress.setValue(static_cast<int>((processed_size * 100) / total_size));
- return progress.wasCanceled();
- };
-
- LOG_INFO(Frontend, "Installing firmware from {}", location.toStdString());
-
- // Check for a reasonable number of .nca files (don't hardcode them, just see if there's some in
- // there.)
- std::filesystem::path firmware_source_path = location.toStdString();
- if (!Common::FS::IsDir(firmware_source_path)) {
- progress.close();
- return;
- }
-
- std::vector<std::filesystem::path> out;
- const Common::FS::DirEntryCallable callback =
- [&out](const std::filesystem::directory_entry& entry) {
- if (entry.path().has_extension() && entry.path().extension() == ".nca") {
- out.emplace_back(entry.path());
- }
-
- return true;
- };
-
- QtProgressCallback(100, 10);
-
- if (recursive) {
- Common::FS::IterateDirEntriesRecursively(firmware_source_path, callback,
- Common::FS::DirEntryFilter::File);
- } else {
- Common::FS::IterateDirEntries(firmware_source_path, callback,
- Common::FS::DirEntryFilter::File);
- }
-
- if (out.size() <= 0) {
- progress.close();
- QMessageBox::warning(this, tr("Firmware install failed"),
- tr("Unable to locate potential firmware NCA files"));
- return;
- }
-
- // Locate and erase the content of nand/system/Content/registered/*.nca, if any.
- auto sysnand_content_vdir = system->GetFileSystemController().GetSystemNANDContentDirectory();
- if (!sysnand_content_vdir->CleanSubdirectoryRecursive("registered")) {
- progress.close();
- QMessageBox::critical(this, tr("Firmware install failed"),
- tr("Failed to delete one or more firmware file."));
- return;
- }
-
- LOG_INFO(Frontend,
- "Cleaned nand/system/Content/registered folder in preparation for new firmware.");
-
- QtProgressCallback(100, 20);
-
- auto firmware_vdir = sysnand_content_vdir->GetDirectoryRelative("registered");
-
- bool success = true;
- int i = 0;
- for (const auto& firmware_src_path : out) {
- i++;
- auto firmware_src_vfile =
- vfs->OpenFile(firmware_src_path.generic_string(), FileSys::OpenMode::Read);
- auto firmware_dst_vfile =
- firmware_vdir->CreateFileRelative(firmware_src_path.filename().string());
-
- if (!VfsRawCopy(firmware_src_vfile, firmware_dst_vfile)) {
- LOG_ERROR(Frontend, "Failed to copy firmware file {} to {} in registered folder!",
- firmware_src_path.generic_string(), firmware_src_path.filename().string());
- success = false;
- }
-
- if (QtProgressCallback(
- 100, 20 + static_cast<int>(((i) / static_cast<float>(out.size())) * 70.0))) {
- progress.close();
- QMessageBox::warning(
- this, tr("Firmware install failed"),
- tr("Firmware installation cancelled, firmware may be in a bad state or corrupted. "
- "Restart Eden or re-install firmware."));
- return;
- }
- }
-
- if (!success) {
- progress.close();
- QMessageBox::critical(this, tr("Firmware install failed"),
- tr("One or more firmware files failed to copy into NAND."));
- return;
- }
-
- // Re-scan VFS for the newly placed firmware files.
- system->GetFileSystemController().CreateFactories(*vfs);
-
- auto VerifyFirmwareCallback = [&](size_t total_size, size_t processed_size) {
- progress.setValue(90 + static_cast<int>((processed_size * 10) / total_size));
- return progress.wasCanceled();
- };
-
- auto result =
- ContentManager::VerifyInstalledContents(*system, *provider, VerifyFirmwareCallback, true);
-
- if (result.size() > 0) {
- const auto failed_names =
- QString::fromStdString(fmt::format("{}", fmt::join(result, "\n")));
- progress.close();
- QMessageBox::critical(
- this, tr("Firmware integrity verification failed!"),
- tr("Verification failed for the following files:\n\n%1").arg(failed_names));
- return;
- }
-
- progress.close();
+ QtCommon::Content::InstallFirmware(location, recursive);
OnCheckFirmwareDecryption();
}
@@ -4509,32 +3881,14 @@ void GMainWindow::OnInstallFirmwareFromZIP() {
return;
}
- namespace fs = std::filesystem;
- fs::path tmp{std::filesystem::temp_directory_path()};
-
- if (!std::filesystem::create_directories(tmp / "eden" / "firmware")) {
- goto unzipFailed;
- }
-
- {
- tmp /= "eden";
- tmp /= "firmware";
-
- QString qCacheDir = QString::fromStdString(tmp.string());
-
- QFile zip(firmware_zip_location);
+ const QString qCacheDir = QtCommon::Content::UnzipFirmwareToTmp(firmware_zip_location);
- QStringList result = JlCompress::extractDir(&zip, qCacheDir);
- if (result.isEmpty()) {
- goto unzipFailed;
- }
-
- // In this case, it has to be done recursively, since sometimes people
- // will pack it into a subdirectory after dumping
+ // In this case, it has to be done recursively, since sometimes people
+ // will pack it into a subdirectory after dumping
+ if (!qCacheDir.isEmpty()) {
InstallFirmware(qCacheDir, true);
-
std::error_code ec;
- std::filesystem::remove_all(tmp, ec);
+ std::filesystem::remove_all(std::filesystem::temp_directory_path() / "eden" / "firmware", ec);
if (ec) {
QMessageBox::warning(this, tr("Firmware cleanup failed"),
@@ -4543,14 +3897,7 @@ void GMainWindow::OnInstallFirmwareFromZIP() {
"again.\nOS reported error: %1")
.arg(QString::fromStdString(ec.message())));
}
-
- return;
}
-unzipFailed:
- QMessageBox::critical(
- this, tr("Firmware unzip failed"),
- tr("Check write permissions in the system temp directory and try again."));
- return;
}
void GMainWindow::OnInstallDecryptionKeys() {
@@ -4559,30 +3906,9 @@ void GMainWindow::OnInstallDecryptionKeys() {
return;
}
- const QString key_source_location = QFileDialog::getOpenFileName(
- this, tr("Select Dumped Keys Location"), {}, QStringLiteral("Decryption Keys (*.keys)"), {},
- QFileDialog::ReadOnly);
- if (key_source_location.isEmpty()) {
- return;
- }
-
- FirmwareManager::KeyInstallResult result =
- FirmwareManager::InstallKeys(key_source_location.toStdString(), "keys");
+ QtCommon::Content::InstallKeys();
- system->GetFileSystemController().CreateFactories(*vfs);
game_list->PopulateAsync(UISettings::values.game_dirs);
-
- switch (result) {
- case FirmwareManager::KeyInstallResult::Success:
- QMessageBox::information(this, tr("Decryption Keys install succeeded"),
- tr("Decryption Keys were successfully installed"));
- break;
- default:
- QMessageBox::critical(this, tr("Decryption Keys install failed"),
- tr(FirmwareManager::GetKeyInstallResultString(result)));
- break;
- }
-
OnCheckFirmwareDecryption();
}
@@ -4609,18 +3935,20 @@ void GMainWindow::OnToggleStatusBar() {
statusBar()->setVisible(ui->action_Show_Status_Bar->isChecked());
}
-void GMainWindow::OnGameListRefresh() {
- // force reload add-ons etc
- game_list->ForceRefreshGameDirectory();
+void GMainWindow::OnGameListRefresh()
+{
+ // Resets metadata cache and reloads
+ QtCommon::Game::ResetMetadata();
+ game_list->RefreshGameDirectory();
SetFirmwareVersion();
}
void GMainWindow::OnAlbum() {
constexpr u64 AlbumId = static_cast<u64>(Service::AM::AppletProgramId::PhotoViewer);
- auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
+ auto bis_system = QtCommon::system->GetFileSystemController().GetSystemNANDContents();
if (!bis_system) {
QMessageBox::warning(this, tr("No firmware available"),
- tr("Please install the firmware to use the Album applet."));
+ tr("Please install firmware to use the Album applet."));
return;
}
@@ -4631,7 +3959,7 @@ void GMainWindow::OnAlbum() {
return;
}
- system->GetFrontendAppletHolder().SetCurrentAppletId(Service::AM::AppletId::PhotoViewer);
+ QtCommon::system->GetFrontendAppletHolder().SetCurrentAppletId(Service::AM::AppletId::PhotoViewer);
const auto filename = QString::fromStdString(album_nca->GetFullPath());
UISettings::values.roms_path = QFileInfo(filename).path().toStdString();
@@ -4640,10 +3968,10 @@ void GMainWindow::OnAlbum() {
void GMainWindow::OnCabinet(Service::NFP::CabinetMode mode) {
constexpr u64 CabinetId = static_cast<u64>(Service::AM::AppletProgramId::Cabinet);
- auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
+ auto bis_system = QtCommon::system->GetFileSystemController().GetSystemNANDContents();
if (!bis_system) {
QMessageBox::warning(this, tr("No firmware available"),
- tr("Please install the firmware to use the Cabinet applet."));
+ tr("Please install firmware to use the Cabinet applet."));
return;
}
@@ -4654,8 +3982,8 @@ void GMainWindow::OnCabinet(Service::NFP::CabinetMode mode) {
return;
}
- system->GetFrontendAppletHolder().SetCurrentAppletId(Service::AM::AppletId::Cabinet);
- system->GetFrontendAppletHolder().SetCabinetMode(mode);
+ QtCommon::system->GetFrontendAppletHolder().SetCurrentAppletId(Service::AM::AppletId::Cabinet);
+ QtCommon::system->GetFrontendAppletHolder().SetCabinetMode(mode);
const auto filename = QString::fromStdString(cabinet_nca->GetFullPath());
UISettings::values.roms_path = QFileInfo(filename).path().toStdString();
@@ -4664,10 +3992,10 @@ void GMainWindow::OnCabinet(Service::NFP::CabinetMode mode) {
void GMainWindow::OnMiiEdit() {
constexpr u64 MiiEditId = static_cast<u64>(Service::AM::AppletProgramId::MiiEdit);
- auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
+ auto bis_system = QtCommon::system->GetFileSystemController().GetSystemNANDContents();
if (!bis_system) {
QMessageBox::warning(this, tr("No firmware available"),
- tr("Please install the firmware to use the Mii editor."));
+ tr("Please install firmware to use the Mii editor."));
return;
}
@@ -4678,7 +4006,7 @@ void GMainWindow::OnMiiEdit() {
return;
}
- system->GetFrontendAppletHolder().SetCurrentAppletId(Service::AM::AppletId::MiiEdit);
+ QtCommon::system->GetFrontendAppletHolder().SetCurrentAppletId(Service::AM::AppletId::MiiEdit);
const auto filename = QString::fromStdString((mii_applet_nca->GetFullPath()));
UISettings::values.roms_path = QFileInfo(filename).path().toStdString();
@@ -4687,10 +4015,10 @@ void GMainWindow::OnMiiEdit() {
void GMainWindow::OnOpenControllerMenu() {
constexpr u64 ControllerAppletId = static_cast<u64>(Service::AM::AppletProgramId::Controller);
- auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
+ auto bis_system = QtCommon::system->GetFileSystemController().GetSystemNANDContents();
if (!bis_system) {
QMessageBox::warning(this, tr("No firmware available"),
- tr("Please install the firmware to use the Controller Menu."));
+ tr("Please install firmware to use the Controller Menu."));
return;
}
@@ -4702,7 +4030,7 @@ void GMainWindow::OnOpenControllerMenu() {
return;
}
- system->GetFrontendAppletHolder().SetCurrentAppletId(Service::AM::AppletId::Controller);
+ QtCommon::system->GetFrontendAppletHolder().SetCurrentAppletId(Service::AM::AppletId::Controller);
const auto filename = QString::fromStdString((controller_applet_nca->GetFullPath()));
UISettings::values.roms_path = QFileInfo(filename).path().toStdString();
@@ -4711,7 +4039,7 @@ void GMainWindow::OnOpenControllerMenu() {
}
void GMainWindow::OnHomeMenu() {
- auto result = FirmwareManager::VerifyFirmware(*system.get());
+ auto result = FirmwareManager::VerifyFirmware(*QtCommon::system.get());
switch (result) {
case FirmwareManager::ErrorFirmwareMissing:
@@ -4746,7 +4074,7 @@ void GMainWindow::OnHomeMenu() {
}
constexpr u64 QLaunchId = static_cast<u64>(Service::AM::AppletProgramId::QLaunch);
- auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
+ auto bis_system = QtCommon::system->GetFileSystemController().GetSystemNANDContents();
auto qlaunch_applet_nca = bis_system->GetEntry(QLaunchId, FileSys::ContentRecordType::Program);
if (!qlaunch_applet_nca) {
@@ -4755,7 +4083,7 @@ void GMainWindow::OnHomeMenu() {
return;
}
- system->GetFrontendAppletHolder().SetCurrentAppletId(Service::AM::AppletId::QLaunch);
+ QtCommon::system->GetFrontendAppletHolder().SetCurrentAppletId(Service::AM::AppletId::QLaunch);
const auto filename = QString::fromStdString((qlaunch_applet_nca->GetFullPath()));
UISettings::values.roms_path = QFileInfo(filename).path().toStdString();
@@ -4764,10 +4092,10 @@ void GMainWindow::OnHomeMenu() {
void GMainWindow::OnInitialSetup() {
constexpr u64 Starter = static_cast<u64>(Service::AM::AppletProgramId::Starter);
- auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
+ auto bis_system = QtCommon::system->GetFileSystemController().GetSystemNANDContents();
if (!bis_system) {
QMessageBox::warning(this, tr("No firmware available"),
- tr("Please install the firmware to use Starter."));
+ tr("Please install firmware to use Starter."));
return;
}
@@ -4778,7 +4106,7 @@ void GMainWindow::OnInitialSetup() {
return;
}
- system->GetFrontendAppletHolder().SetCurrentAppletId(Service::AM::AppletId::Starter);
+ QtCommon::system->GetFrontendAppletHolder().SetCurrentAppletId(Service::AM::AppletId::Starter);
const auto filename = QString::fromStdString((qlaunch_nca->GetFullPath()));
UISettings::values.roms_path = QFileInfo(filename).path().toStdString();
@@ -4786,158 +4114,11 @@ void GMainWindow::OnInitialSetup() {
}
void GMainWindow::OnCreateHomeMenuDesktopShortcut() {
- OnCreateHomeMenuShortcut(GameListShortcutTarget::Desktop);
+ QtCommon::Game::CreateHomeMenuShortcut(QtCommon::Game::ShortcutTarget::Desktop);
}
void GMainWindow::OnCreateHomeMenuApplicationMenuShortcut() {
- OnCreateHomeMenuShortcut(GameListShortcutTarget::Applications);
-}
-
-std::filesystem::path GMainWindow::GetEdenCommand() {
- std::filesystem::path command;
-
- QString appimage = QString::fromLocal8Bit(getenv("APPIMAGE"));
- if (!appimage.isEmpty()) {
- command = std::filesystem::path{appimage.toStdString()};
- } else {
- const QStringList args = QApplication::arguments();
- command = args[0].toStdString();
- }
-
- // If relative path, make it an absolute path
- if (command.c_str()[0] == '.') {
- command = Common::FS::GetCurrentDir() / command;
- }
-
- return command;
-}
-
-std::filesystem::path GMainWindow::GetShortcutPath(GameListShortcutTarget target) {
- std::filesystem::path shortcut_path{};
- if (target == GameListShortcutTarget::Desktop) {
- shortcut_path =
- QStandardPaths::writableLocation(QStandardPaths::DesktopLocation).toStdString();
- } else if (target == GameListShortcutTarget::Applications) {
- shortcut_path =
- QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation).toStdString();
- }
-
- return shortcut_path;
-}
-
-void GMainWindow::CreateShortcut(const std::string& game_path, const u64 program_id,
- const std::string& game_title_, GameListShortcutTarget target,
- std::string arguments_, const bool needs_title) {
- // Get path to yuzu executable
- std::filesystem::path command = GetEdenCommand();
-
- // Shortcut path
- std::filesystem::path shortcut_path = GetShortcutPath(target);
-
- if (!std::filesystem::exists(shortcut_path)) {
- GMainWindow::CreateShortcutMessagesGUI(
- this, GMainWindow::CREATE_SHORTCUT_MSGBOX_ERROR,
- QString::fromStdString(shortcut_path.generic_string()));
- LOG_ERROR(Frontend, "Invalid shortcut target {}", shortcut_path.generic_string());
- return;
- }
-
- const FileSys::PatchManager pm{program_id, system->GetFileSystemController(),
- system->GetContentProvider()};
- const auto control = pm.GetControlMetadata();
- const auto loader =
- Loader::GetLoader(*system, vfs->OpenFile(game_path, FileSys::OpenMode::Read));
-
- std::string game_title{game_title_};
-
- // Delete illegal characters from title
- if (needs_title) {
- game_title = fmt::format("{:016X}", program_id);
- if (control.first != nullptr) {
- game_title = control.first->GetApplicationName();
- } else {
- loader->ReadTitle(game_title);
- }
- }
-
- const std::string illegal_chars = "<>:\"/\\|?*.";
- for (auto it = game_title.rbegin(); it != game_title.rend(); ++it) {
- if (illegal_chars.find(*it) != std::string::npos) {
- game_title.erase(it.base() - 1);
- }
- }
-
- const QString qgame_title = QString::fromStdString(game_title);
-
- // Get icon from game file
- std::vector<u8> icon_image_file{};
- if (control.second != nullptr) {
- icon_image_file = control.second->ReadAllBytes();
- } else if (loader->ReadIcon(icon_image_file) != Loader::ResultStatus::Success) {
- LOG_WARNING(Frontend, "Could not read icon from {:s}", game_path);
- }
-
- QImage icon_data =
- QImage::fromData(icon_image_file.data(), static_cast<int>(icon_image_file.size()));
- std::filesystem::path out_icon_path;
- if (GMainWindow::MakeShortcutIcoPath(program_id, game_title, out_icon_path)) {
- if (!SaveIconToFile(out_icon_path, icon_data)) {
- LOG_ERROR(Frontend, "Could not write icon to file");
- }
- }
-
-#if defined(__unix__) && !defined(__APPLE__) && !defined(__ANDROID__)
- // Special case for AppImages
- // Warn once if we are making a shortcut to a volatile AppImage
- if (command.string().ends_with(".AppImage") && !UISettings::values.shortcut_already_warned) {
- if (!GMainWindow::CreateShortcutMessagesGUI(
- this, GMainWindow::CREATE_SHORTCUT_MSGBOX_APPVOLATILE_WARNING, qgame_title)) {
- return;
- }
- UISettings::values.shortcut_already_warned = true;
- }
-#endif
-
- // Create shortcut
- std::string arguments{arguments_};
- if (GMainWindow::CreateShortcutMessagesGUI(
- this, GMainWindow::CREATE_SHORTCUT_MSGBOX_FULLSCREEN_YES, qgame_title)) {
- arguments = "-f " + arguments;
- }
- const std::string comment = fmt::format("Start {:s} with the eden Emulator", game_title);
- const std::string categories = "Game;Emulator;Qt;";
- const std::string keywords = "Switch;Nintendo;";
-
- if (GMainWindow::CreateShortcutLink(shortcut_path, comment, out_icon_path, command, arguments,
- categories, keywords, game_title)) {
- GMainWindow::CreateShortcutMessagesGUI(this, GMainWindow::CREATE_SHORTCUT_MSGBOX_SUCCESS,
- qgame_title);
- return;
- }
- GMainWindow::CreateShortcutMessagesGUI(this, GMainWindow::CREATE_SHORTCUT_MSGBOX_ERROR,
- qgame_title);
-}
-
-void GMainWindow::OnCreateHomeMenuShortcut(GameListShortcutTarget target) {
- constexpr u64 QLaunchId = static_cast<u64>(Service::AM::AppletProgramId::QLaunch);
- auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
- if (!bis_system) {
- QMessageBox::warning(this, tr("No firmware available"),
- tr("Please install firmware to use the home menu."));
- return;
- }
-
- auto qlaunch_nca = bis_system->GetEntry(QLaunchId, FileSys::ContentRecordType::Program);
- if (!qlaunch_nca) {
- QMessageBox::warning(this, tr("Home Menu Applet"),
- tr("Home Menu is not available. Please reinstall firmware."));
- return;
- }
-
- auto qlaunch_applet_nca = bis_system->GetEntry(QLaunchId, FileSys::ContentRecordType::Program);
- const auto game_path = qlaunch_applet_nca->GetFullPath();
-
- CreateShortcut(game_path, QLaunchId, "Switch Home Menu", target, "-qlaunch", false);
+ QtCommon::Game::CreateHomeMenuShortcut(QtCommon::Game::ShortcutTarget::Applications);
}
void GMainWindow::OnCaptureScreenshot() {
@@ -4945,7 +4126,7 @@ void GMainWindow::OnCaptureScreenshot() {
return;
}
- const u64 title_id = system->GetApplicationProcessProgramID();
+ const u64 title_id = QtCommon::system->GetApplicationProcessProgramID();
const auto screenshot_path =
QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::ScreenshotsDir));
const auto date =
@@ -5107,7 +4288,7 @@ void GMainWindow::OnTasStateChanged() {
}
void GMainWindow::UpdateStatusBar() {
- if (emu_thread == nullptr || !system->IsPoweredOn()) {
+ if (emu_thread == nullptr || !QtCommon::system->IsPoweredOn()) {
status_bar_update_timer.stop();
return;
}
@@ -5118,8 +4299,8 @@ void GMainWindow::UpdateStatusBar() {
tas_label->clear();
}
- auto results = system->GetAndResetPerfStats();
- auto& shader_notify = system->GPU().ShaderNotify();
+ auto results = QtCommon::system->GetAndResetPerfStats();
+ auto& shader_notify = QtCommon::system->GPU().ShaderNotify();
const int shaders_building = shader_notify.ShadersBuilding();
if (shaders_building > 0) {
@@ -5265,7 +4446,6 @@ void GMainWindow::OnMouseActivity() {
}
void GMainWindow::OnCheckFirmwareDecryption() {
- system->GetFileSystemController().CreateFactories(*vfs);
if (!ContentManager::AreKeysPresent()) {
QMessageBox::warning(this, tr("Derivation Components Missing"),
tr("Encryption keys are missing."));
@@ -5274,47 +4454,12 @@ void GMainWindow::OnCheckFirmwareDecryption() {
UpdateMenuState();
}
-bool GMainWindow::OnCheckNcaVerification() {
- if (!Settings::values.disable_nca_verification.GetValue())
- return true;
-
- const bool currently_hidden = Settings::values.hide_nca_verification_popup.GetValue();
- LOG_INFO(Frontend, "NCA Verification is disabled. Popup State={}", currently_hidden);
- if (currently_hidden)
- return true;
-
- QMessageBox msgbox(this);
- msgbox.setWindowTitle(tr("NCA Verification Disabled"));
- msgbox.setText(tr("NCA Verification is disabled.\n"
- "This is required to run new games and updates.\n"
- "Running without verification can cause instability or crashes if NCA files "
- "are corrupt, modified, or tampered.\n"
- "If unsure, re-enable verification in Eden's Settings and use firmware "
- "version 19.0.1 or below."));
- msgbox.setIcon(QMessageBox::Warning);
- msgbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
- msgbox.setDefaultButton(QMessageBox::Ok);
-
- QCheckBox* cb = new QCheckBox(tr("Don't show again"), &msgbox);
- cb->setChecked(currently_hidden);
- msgbox.setCheckBox(cb);
-
- int result = msgbox.exec();
-
- const bool hide = cb->isChecked();
- if (hide != currently_hidden) {
- Settings::values.hide_nca_verification_popup.SetValue(hide);
- }
-
- return result == static_cast<int>(QMessageBox::Ok);
-}
-
bool GMainWindow::CheckFirmwarePresence() {
- return FirmwareManager::CheckFirmwarePresence(*system.get());
+ return FirmwareManager::CheckFirmwarePresence(*QtCommon::system.get());
}
void GMainWindow::SetFirmwareVersion() {
- const auto pair = FirmwareManager::GetFirmwareVersion(*system.get());
+ const auto pair = FirmwareManager::GetFirmwareVersion(*QtCommon::system.get());
const auto firmware_data = pair.first;
const auto result = pair.second;
@@ -5400,7 +4545,7 @@ bool GMainWindow::ConfirmClose() {
UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Never) {
return true;
}
- if (!system->GetExitLocked() &&
+ if (!QtCommon::system->GetExitLocked() &&
UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Based_On_Game) {
return true;
}
@@ -5430,7 +4575,7 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
render_window->close();
multiplayer_state->Close();
- system->HIDCore().UnloadInputDevices();
+ QtCommon::system->HIDCore().UnloadInputDevices();
Network::Shutdown();
QWidget::closeEvent(event);
@@ -5501,12 +4646,12 @@ bool GMainWindow::ConfirmForceLockedExit() {
}
void GMainWindow::RequestGameExit() {
- if (!system->IsPoweredOn()) {
+ if (!QtCommon::system->IsPoweredOn()) {
return;
}
- system->SetExitRequested(true);
- system->GetAppletManager().RequestExit();
+ QtCommon::system->SetExitRequested(true);
+ QtCommon::system->GetAppletManager().RequestExit();
}
void GMainWindow::filterBarSetChecked(bool state) {
@@ -5616,7 +4761,7 @@ void GMainWindow::OnLanguageChanged(const QString& locale) {
void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) {
#ifdef USE_DISCORD_PRESENCE
if (state) {
- discord_rpc = std::make_unique<DiscordRPC::DiscordImpl>(*system);
+ discord_rpc = std::make_unique<DiscordRPC::DiscordImpl>(*QtCommon::system);
} else {
discord_rpc = std::make_unique<DiscordRPC::NullImpl>();
}