From 8d0b35e75d4741891039a8f5e871844f6f552f81 Mon Sep 17 00:00:00 2001 From: crueter Date: Tue, 22 Jul 2025 16:31:36 -0400 Subject: [PATCH 01/10] qt_common init Signed-off-by: crueter --- src/CMakeLists.txt | 1 + src/qt_common/CMakeLists.txt | 23 +++++++++ src/{yuzu => qt_common}/qt_common.cpp | 25 ++++++++-- src/qt_common/qt_common.h | 47 +++++++++++++++++++ .../configuration => qt_common}/qt_config.cpp | 0 .../configuration => qt_common}/qt_config.h | 0 .../shared_translation.cpp | 10 ++-- .../shared_translation.h | 9 ++-- src/{yuzu => qt_common}/uisettings.cpp | 2 +- src/{yuzu => qt_common}/uisettings.h | 2 +- src/yuzu/CMakeLists.txt | 14 +----- src/yuzu/bootmanager.cpp | 9 ++-- src/yuzu/configuration/configure_audio.cpp | 4 +- src/yuzu/configuration/configure_cpu.h | 2 +- src/yuzu/configuration/configure_debug.cpp | 2 +- src/yuzu/configuration/configure_dialog.cpp | 2 +- src/yuzu/configuration/configure_dialog.h | 2 +- .../configuration/configure_filesystem.cpp | 28 +++++------ src/yuzu/configuration/configure_general.cpp | 2 +- src/yuzu/configuration/configure_graphics.cpp | 4 +- src/yuzu/configuration/configure_graphics.h | 2 +- .../configure_graphics_advanced.cpp | 2 +- .../configure_graphics_extensions.cpp | 2 +- src/yuzu/configuration/configure_hotkeys.cpp | 2 +- .../configuration/configure_input_per_game.h | 2 +- .../configuration/configure_input_player.cpp | 2 +- src/yuzu/configuration/configure_per_game.cpp | 2 +- src/yuzu/configuration/configure_per_game.h | 4 +- .../configure_per_game_addons.cpp | 2 +- src/yuzu/configuration/configure_ringcon.cpp | 2 +- src/yuzu/configuration/configure_tas.cpp | 2 +- src/yuzu/configuration/configure_ui.cpp | 2 +- src/yuzu/configuration/configure_web.cpp | 2 +- src/yuzu/configuration/input_profiles.h | 2 +- src/yuzu/configuration/shared_widget.cpp | 2 +- src/yuzu/configuration/shared_widget.h | 2 +- src/yuzu/debugger/console.cpp | 2 +- src/yuzu/debugger/wait_tree.cpp | 2 +- src/yuzu/game_list.cpp | 15 ++---- src/yuzu/game_list.h | 5 +- src/yuzu/game_list_p.h | 2 +- src/yuzu/game_list_worker.cpp | 30 ++++-------- src/yuzu/game_list_worker.h | 7 +-- src/yuzu/hotkeys.cpp | 2 +- src/yuzu/install_dialog.cpp | 2 +- src/yuzu/main.cpp | 24 +++++----- src/yuzu/main.h | 2 +- src/yuzu/multiplayer/direct_connect.cpp | 2 +- src/yuzu/multiplayer/host_room.cpp | 2 +- src/yuzu/multiplayer/lobby.cpp | 2 +- src/yuzu/multiplayer/state.cpp | 2 +- src/yuzu/play_time_manager.cpp | 1 - src/yuzu/play_time_manager.h | 3 +- src/yuzu/qt_common.h | 15 ------ src/yuzu/vk_device_info.cpp | 2 +- 55 files changed, 188 insertions(+), 156 deletions(-) create mode 100644 src/qt_common/CMakeLists.txt rename src/{yuzu => qt_common}/qt_common.cpp (80%) create mode 100644 src/qt_common/qt_common.h rename src/{yuzu/configuration => qt_common}/qt_config.cpp (100%) rename src/{yuzu/configuration => qt_common}/qt_config.h (100%) rename src/{yuzu/configuration => qt_common}/shared_translation.cpp (99%) rename src/{yuzu/configuration => qt_common}/shared_translation.h (94%) rename src/{yuzu => qt_common}/uisettings.cpp (99%) rename src/{yuzu => qt_common}/uisettings.h (99%) delete mode 100644 src/yuzu/qt_common.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4308534f12..929da038d9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -212,6 +212,7 @@ if (YUZU_ROOM_STANDALONE) endif() if (ENABLE_QT) + add_subdirectory(qt_common) add_subdirectory(yuzu) endif() diff --git a/src/qt_common/CMakeLists.txt b/src/qt_common/CMakeLists.txt new file mode 100644 index 0000000000..be1a8ebbd0 --- /dev/null +++ b/src/qt_common/CMakeLists.txt @@ -0,0 +1,23 @@ +# SPDX-FileCopyrightText: 2023 yuzu Emulator Project +# SPDX-License-Identifier: GPL-2.0-or-later + +add_library(qt_common STATIC + qt_common.h + qt_common.cpp + + uisettings.cpp + uisettings.h + + qt_config.cpp + qt_config.h + + shared_translation.cpp + shared_translation.h +) + +create_target_directory_groups(qt_common) +target_link_libraries(qt_common PUBLIC core Qt6::Core Qt6::Gui SimpleIni::SimpleIni) + +if (NOT WIN32) + target_include_directories(qt_common PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS}) +endif() diff --git a/src/yuzu/qt_common.cpp b/src/qt_common/qt_common.cpp similarity index 80% rename from src/yuzu/qt_common.cpp rename to src/qt_common/qt_common.cpp index 413402165c..29379c1d54 100644 --- a/src/yuzu/qt_common.cpp +++ b/src/qt_common/qt_common.cpp @@ -1,12 +1,13 @@ -// SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later +#include "qt_common.h" +#include "common/fs/fs.h" +#include "common/fs/path_util.h" +#include "uisettings.h" #include #include #include #include "common/logging/log.h" #include "core/frontend/emu_window.h" -#include "yuzu/qt_common.h" #if !defined(WIN32) && !defined(__APPLE__) #include @@ -15,6 +16,21 @@ #endif namespace QtCommon { + +MetadataResult ResetMetadata() +{ + if (!Common::FS::Exists(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) + / "game_list/")) { + return Empty; + } else if (Common::FS::RemoveDirRecursively( + Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list")) { + return Success; + UISettings::values.is_game_list_reload_pending.exchange(true); + } else { + return Failure; + } +} + Core::Frontend::WindowSystemType GetWindowSystemType() { // Determine WSI type based on Qt platform. QString platform_name = QGuiApplication::platformName(); @@ -57,4 +73,5 @@ Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window) return wsi; } -} // namespace QtCommon + +} diff --git a/src/qt_common/qt_common.h b/src/qt_common/qt_common.h new file mode 100644 index 0000000000..3c7dddfc1f --- /dev/null +++ b/src/qt_common/qt_common.h @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef QT_COMMON_H +#define QT_COMMON_H + +#include + +#include +#include + +namespace QtCommon { + +static constexpr std::array METADATA_RESULTS = { + "The operation completed successfully.", + "The metadata cache couldn't be deleted. It might be in use or non-existent.", + "The metadata cache is already empty.", +}; + +enum MetadataResult { + Success, + Failure, + Empty, +}; +/** + * @brief ResetMetadata Reset game list metadata. + * @return A result code. + */ +MetadataResult ResetMetadata(); + +/** + * \brief Get a string representation of a result from ResetMetadata. + * \param result The result code. + * \return A string representation of the passed result code. + */ +inline constexpr const char *GetResetMetadataResultString(MetadataResult result) +{ + return METADATA_RESULTS.at(static_cast(result)); +} + +Core::Frontend::WindowSystemType GetWindowSystemType(); + +Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window); + + +} // namespace QtCommon +#endif diff --git a/src/yuzu/configuration/qt_config.cpp b/src/qt_common/qt_config.cpp similarity index 100% rename from src/yuzu/configuration/qt_config.cpp rename to src/qt_common/qt_config.cpp diff --git a/src/yuzu/configuration/qt_config.h b/src/qt_common/qt_config.h similarity index 100% rename from src/yuzu/configuration/qt_config.h rename to src/qt_common/qt_config.h diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/qt_common/shared_translation.cpp similarity index 99% rename from src/yuzu/configuration/shared_translation.cpp rename to src/qt_common/shared_translation.cpp index 770a16a481..03cdaed777 100644 --- a/src/yuzu/configuration/shared_translation.cpp +++ b/src/qt_common/shared_translation.cpp @@ -7,23 +7,21 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "yuzu/configuration/shared_translation.h" +#include "shared_translation.h" #include -#include #include "common/settings.h" #include "common/settings_enums.h" #include "common/settings_setting.h" #include "common/time_zone.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" #include #include -#include #include namespace ConfigurationShared { -std::unique_ptr InitializeTranslations(QWidget* parent) +std::unique_ptr InitializeTranslations(QObject* parent) { std::unique_ptr translations = std::make_unique(); const auto& tr = [parent](const char* text) -> QString { return parent->tr(text); }; @@ -459,7 +457,7 @@ std::unique_ptr InitializeTranslations(QWidget* parent) return translations; } -std::unique_ptr ComboboxEnumeration(QWidget* parent) +std::unique_ptr ComboboxEnumeration(QObject* parent) { std::unique_ptr translations = std::make_unique(); const auto& tr = [&](const char* text, const char* context = "") { diff --git a/src/yuzu/configuration/shared_translation.h b/src/qt_common/shared_translation.h similarity index 94% rename from src/yuzu/configuration/shared_translation.h rename to src/qt_common/shared_translation.h index 574b1e2c78..48a2cb5205 100644 --- a/src/yuzu/configuration/shared_translation.h +++ b/src/qt_common/shared_translation.h @@ -11,23 +11,20 @@ #include #include -#include #include #include #include #include "common/common_types.h" -#include "common/settings.h" - -class QWidget; +#include "common/settings_enums.h" namespace ConfigurationShared { using TranslationMap = std::map>; using ComboboxTranslations = std::vector>; using ComboboxTranslationMap = std::map; -std::unique_ptr InitializeTranslations(QWidget* parent); +std::unique_ptr InitializeTranslations(QObject *parent); -std::unique_ptr ComboboxEnumeration(QWidget* parent); +std::unique_ptr ComboboxEnumeration(QObject* parent); static const std::map anti_aliasing_texts_map = { {Settings::AntiAliasing::None, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "None"))}, diff --git a/src/yuzu/uisettings.cpp b/src/qt_common/uisettings.cpp similarity index 99% rename from src/yuzu/uisettings.cpp rename to src/qt_common/uisettings.cpp index 02d6bc9006..f573b9a9aa 100644 --- a/src/yuzu/uisettings.cpp +++ b/src/qt_common/uisettings.cpp @@ -4,7 +4,7 @@ #include #include "common/fs/fs.h" #include "common/fs/path_util.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" #ifndef CANNOT_EXPLICITLY_INSTANTIATE namespace Settings { diff --git a/src/yuzu/uisettings.h b/src/qt_common/uisettings.h similarity index 99% rename from src/yuzu/uisettings.h rename to src/qt_common/uisettings.h index b713b52fcc..18498162b2 100644 --- a/src/yuzu/uisettings.h +++ b/src/qt_common/uisettings.h @@ -14,7 +14,7 @@ #include "common/common_types.h" #include "common/settings.h" #include "common/settings_enums.h" -#include "configuration/qt_config.h" +#include "qt_common/qt_config.h" using Settings::Category; using Settings::ConfirmStop; diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 34f2ba455a..caaa4290df 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -150,12 +150,8 @@ add_executable(yuzu configuration/configure_web.ui configuration/input_profiles.cpp configuration/input_profiles.h - configuration/shared_translation.cpp - configuration/shared_translation.h configuration/shared_widget.cpp configuration/shared_widget.h - configuration/qt_config.cpp - configuration/qt_config.h debugger/console.cpp debugger/console.h debugger/controller.cpp @@ -207,12 +203,8 @@ add_executable(yuzu play_time_manager.cpp play_time_manager.h precompiled_headers.h - qt_common.cpp - qt_common.h startup_checks.cpp startup_checks.h - uisettings.cpp - uisettings.h util/clickable_label.cpp util/clickable_label.h util/controller_navigation.cpp @@ -394,14 +386,12 @@ elseif(WIN32) endif() endif() -target_link_libraries(yuzu PRIVATE common core input_common frontend_common network video_core) +target_link_libraries(yuzu PRIVATE common core input_common frontend_common network video_core qt_common) target_link_libraries(yuzu PRIVATE Boost::headers glad Qt6::Widgets) target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) target_link_libraries(yuzu PRIVATE Vulkan::Headers) -if (NOT WIN32) - target_include_directories(yuzu PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS}) -endif() + if (UNIX AND NOT APPLE) target_link_libraries(yuzu PRIVATE Qt6::DBus) endif() diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 6852193b1b..25b6ca8634 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -12,7 +12,7 @@ #include #include "common/settings_enums.h" -#include "uisettings.h" +#include "qt_common/uisettings.h" #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA #include #include @@ -59,7 +59,7 @@ #include "video_core/renderer_base.h" #include "yuzu/bootmanager.h" #include "yuzu/main.h" -#include "yuzu/qt_common.h" +#include "qt_common/qt_common.h" class QObject; class QPaintEngine; @@ -240,7 +240,7 @@ class DummyContext : public Core::Frontend::GraphicsContext {}; class RenderWidget : public QWidget { public: - explicit RenderWidget(GRenderWindow* parent) : QWidget(parent), render_window(parent) { + explicit RenderWidget(GRenderWindow* parent) : QWidget(parent) { setAttribute(Qt::WA_NativeWindow); setAttribute(Qt::WA_PaintOnScreen); if (QtCommon::GetWindowSystemType() == Core::Frontend::WindowSystemType::Wayland) { @@ -253,9 +253,6 @@ public: QPaintEngine* paintEngine() const override { return nullptr; } - -private: - GRenderWindow* render_window; }; struct OpenGLRenderWidget : public RenderWidget { diff --git a/src/yuzu/configuration/configure_audio.cpp b/src/yuzu/configuration/configure_audio.cpp index c235b0fca4..8d11920d31 100644 --- a/src/yuzu/configuration/configure_audio.cpp +++ b/src/yuzu/configuration/configure_audio.cpp @@ -16,9 +16,9 @@ #include "ui_configure_audio.h" #include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configure_audio.h" -#include "yuzu/configuration/shared_translation.h" +#include "qt_common/shared_translation.h" #include "yuzu/configuration/shared_widget.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" ConfigureAudio::ConfigureAudio(const Core::System& system_, std::shared_ptr> group_, diff --git a/src/yuzu/configuration/configure_cpu.h b/src/yuzu/configuration/configure_cpu.h index 7bbeac4963..21a40093b8 100644 --- a/src/yuzu/configuration/configure_cpu.h +++ b/src/yuzu/configuration/configure_cpu.h @@ -7,7 +7,7 @@ #include #include #include "yuzu/configuration/configuration_shared.h" -#include "yuzu/configuration/shared_translation.h" +#include "qt_common/shared_translation.h" class QComboBox; diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp index 10607ee233..d0ec0270e0 100644 --- a/src/yuzu/configuration/configure_debug.cpp +++ b/src/yuzu/configuration/configure_debug.cpp @@ -12,7 +12,7 @@ #include "ui_configure_debug.h" #include "yuzu/configuration/configure_debug.h" #include "yuzu/debugger/console.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" ConfigureDebug::ConfigureDebug(const Core::System& system_, QWidget* parent) : QScrollArea(parent), ui{std::make_unique()}, system{system_} { diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index 987b1462db..4e128106e7 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp @@ -27,7 +27,7 @@ #include "yuzu/configuration/configure_ui.h" #include "yuzu/configuration/configure_web.h" #include "yuzu/hotkeys.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, InputCommon::InputSubsystem* input_subsystem, diff --git a/src/yuzu/configuration/configure_dialog.h b/src/yuzu/configuration/configure_dialog.h index 0b6b285678..bf96035752 100644 --- a/src/yuzu/configuration/configure_dialog.h +++ b/src/yuzu/configuration/configure_dialog.h @@ -8,7 +8,7 @@ #include #include "configuration/shared_widget.h" #include "yuzu/configuration/configuration_shared.h" -#include "yuzu/configuration/shared_translation.h" +#include "qt_common/shared_translation.h" #include "yuzu/vk_device_info.h" namespace Core { diff --git a/src/yuzu/configuration/configure_filesystem.cpp b/src/yuzu/configuration/configure_filesystem.cpp index f25f14708b..392155d2a3 100644 --- a/src/yuzu/configuration/configure_filesystem.cpp +++ b/src/yuzu/configuration/configure_filesystem.cpp @@ -1,14 +1,15 @@ // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "yuzu/configuration/configure_filesystem.h" #include #include #include "common/fs/fs.h" #include "common/fs/path_util.h" #include "common/settings.h" +#include "qt_common/qt_common.h" +#include "qt_common/uisettings.h" #include "ui_configure_filesystem.h" -#include "yuzu/configuration/configure_filesystem.h" -#include "yuzu/uisettings.h" ConfigureFilesystem::ConfigureFilesystem(QWidget* parent) : QWidget(parent), ui(std::make_unique()) { @@ -126,19 +127,16 @@ void ConfigureFilesystem::SetDirectory(DirectoryTarget target, QLineEdit* edit) } void ConfigureFilesystem::ResetMetadata() { - if (!Common::FS::Exists(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / - "game_list/")) { - QMessageBox::information(this, tr("Reset Metadata Cache"), - tr("The metadata cache is already empty.")); - } else if (Common::FS::RemoveDirRecursively( - Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list")) { - QMessageBox::information(this, tr("Reset Metadata Cache"), - tr("The operation completed successfully.")); - UISettings::values.is_game_list_reload_pending.exchange(true); - } else { - QMessageBox::warning( - this, tr("Reset Metadata Cache"), - tr("The metadata cache couldn't be deleted. It might be in use or non-existent.")); + auto result = QtCommon::ResetMetadata(); + const QString resultMessage = tr(QtCommon::GetResetMetadataResultString(result)); + const QString title = tr("Reset Metadata Cache"); + + switch (result) { + case QtCommon::Failure: + QMessageBox::warning(this, title, resultMessage); + break; + default: + QMessageBox::information(this, title, resultMessage); } } diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp index 918fa15d4d..352ae8ab85 100644 --- a/src/yuzu/configuration/configure_general.cpp +++ b/src/yuzu/configuration/configure_general.cpp @@ -11,7 +11,7 @@ #include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configure_general.h" #include "yuzu/configuration/shared_widget.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" ConfigureGeneral::ConfigureGeneral(const Core::System& system_, std::shared_ptr> group_, diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 54c931e56c..131016af97 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp @@ -40,8 +40,8 @@ #include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configure_graphics.h" #include "yuzu/configuration/shared_widget.h" -#include "yuzu/qt_common.h" -#include "yuzu/uisettings.h" +#include "qt_common/qt_common.h" +#include "qt_common/uisettings.h" #include "yuzu/vk_device_info.h" static const std::vector default_present_modes{VK_PRESENT_MODE_IMMEDIATE_KHR, diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h index b92b4496ba..9f7ece5714 100644 --- a/src/yuzu/configuration/configure_graphics.h +++ b/src/yuzu/configuration/configure_graphics.h @@ -15,7 +15,7 @@ #include #include "common/common_types.h" #include "common/settings_enums.h" -#include "configuration/shared_translation.h" +#include "qt_common/shared_translation.h" #include "vk_device_info.h" #include "yuzu/configuration/configuration_shared.h" diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp index 4db18673d4..921cb83b08 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.cpp +++ b/src/yuzu/configuration/configure_graphics_advanced.cpp @@ -9,7 +9,7 @@ #include "ui_configure_graphics_advanced.h" #include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configure_graphics_advanced.h" -#include "yuzu/configuration/shared_translation.h" +#include "qt_common/shared_translation.h" #include "yuzu/configuration/shared_widget.h" ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced( diff --git a/src/yuzu/configuration/configure_graphics_extensions.cpp b/src/yuzu/configuration/configure_graphics_extensions.cpp index 61491c0ab7..973b9bad17 100644 --- a/src/yuzu/configuration/configure_graphics_extensions.cpp +++ b/src/yuzu/configuration/configure_graphics_extensions.cpp @@ -11,7 +11,7 @@ #include "ui_configure_graphics_extensions.h" #include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configure_graphics_extensions.h" -#include "yuzu/configuration/shared_translation.h" +#include "qt_common/shared_translation.h" #include "yuzu/configuration/shared_widget.h" ConfigureGraphicsExtensions::ConfigureGraphicsExtensions( diff --git a/src/yuzu/configuration/configure_hotkeys.cpp b/src/yuzu/configuration/configure_hotkeys.cpp index 3f68de12d8..53f7401ef4 100644 --- a/src/yuzu/configuration/configure_hotkeys.cpp +++ b/src/yuzu/configuration/configure_hotkeys.cpp @@ -13,7 +13,7 @@ #include "ui_configure_hotkeys.h" #include "yuzu/configuration/configure_hotkeys.h" #include "yuzu/hotkeys.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" #include "yuzu/util/sequence_dialog/sequence_dialog.h" constexpr int name_column = 0; diff --git a/src/yuzu/configuration/configure_input_per_game.h b/src/yuzu/configuration/configure_input_per_game.h index 4420e856cb..1323d101d3 100644 --- a/src/yuzu/configuration/configure_input_per_game.h +++ b/src/yuzu/configuration/configure_input_per_game.h @@ -9,7 +9,7 @@ #include "ui_configure_input_per_game.h" #include "yuzu/configuration/input_profiles.h" -#include "yuzu/configuration/qt_config.h" +#include "qt_common/qt_config.h" class QComboBox; diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 12fe935e41..f0e34d8dc2 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -12,7 +12,7 @@ #include #include "common/assert.h" #include "common/param_package.h" -#include "configuration/qt_config.h" +#include "qt_common/qt_config.h" #include "frontend_common/config.h" #include "hid_core/frontend/emulated_controller.h" #include "hid_core/hid_core.h" diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index 031a8d4c2d..545c37a2c9 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp @@ -38,7 +38,7 @@ #include "yuzu/configuration/configure_per_game.h" #include "yuzu/configuration/configure_per_game_addons.h" #include "yuzu/configuration/configure_system.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" #include "yuzu/util/util.h" #include "yuzu/vk_device_info.h" diff --git a/src/yuzu/configuration/configure_per_game.h b/src/yuzu/configuration/configure_per_game.h index e0f4e5cd67..a756b561a8 100644 --- a/src/yuzu/configuration/configure_per_game.h +++ b/src/yuzu/configuration/configure_per_game.h @@ -15,8 +15,8 @@ #include "frontend_common/config.h" #include "vk_device_info.h" #include "yuzu/configuration/configuration_shared.h" -#include "yuzu/configuration/qt_config.h" -#include "yuzu/configuration/shared_translation.h" +#include "qt_common/qt_config.h" +#include "qt_common/shared_translation.h" namespace Core { class System; diff --git a/src/yuzu/configuration/configure_per_game_addons.cpp b/src/yuzu/configuration/configure_per_game_addons.cpp index 078f2e8288..90c94cb923 100644 --- a/src/yuzu/configuration/configure_per_game_addons.cpp +++ b/src/yuzu/configuration/configure_per_game_addons.cpp @@ -21,7 +21,7 @@ #include "ui_configure_per_game_addons.h" #include "yuzu/configuration/configure_input.h" #include "yuzu/configuration/configure_per_game_addons.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" ConfigurePerGameAddons::ConfigurePerGameAddons(Core::System& system_, QWidget* parent) : QWidget(parent), ui{std::make_unique()}, system{system_} { diff --git a/src/yuzu/configuration/configure_ringcon.cpp b/src/yuzu/configuration/configure_ringcon.cpp index f7249be97e..7e7877aaf6 100644 --- a/src/yuzu/configuration/configure_ringcon.cpp +++ b/src/yuzu/configuration/configure_ringcon.cpp @@ -8,7 +8,7 @@ #include #include -#include "configuration/qt_config.h" +#include "qt_common/qt_config.h" #include "hid_core/frontend/emulated_controller.h" #include "hid_core/hid_core.h" #include "input_common/drivers/keyboard.h" diff --git a/src/yuzu/configuration/configure_tas.cpp b/src/yuzu/configuration/configure_tas.cpp index 773658bf22..290e825fe6 100644 --- a/src/yuzu/configuration/configure_tas.cpp +++ b/src/yuzu/configuration/configure_tas.cpp @@ -8,7 +8,7 @@ #include "common/settings.h" #include "ui_configure_tas.h" #include "yuzu/configuration/configure_tas.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" ConfigureTasDialog::ConfigureTasDialog(QWidget* parent) : QDialog(parent), ui(std::make_unique()) { diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp index 8dafee628b..ac6d6e34aa 100644 --- a/src/yuzu/configuration/configure_ui.cpp +++ b/src/yuzu/configuration/configure_ui.cpp @@ -27,7 +27,7 @@ #include "core/core.h" #include "core/frontend/framebuffer_layout.h" #include "ui_configure_ui.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" namespace { constexpr std::array default_game_icon_sizes{ diff --git a/src/yuzu/configuration/configure_web.cpp b/src/yuzu/configuration/configure_web.cpp index d62b5b0853..15a0029901 100644 --- a/src/yuzu/configuration/configure_web.cpp +++ b/src/yuzu/configuration/configure_web.cpp @@ -17,7 +17,7 @@ #include #include "common/settings.h" #include "ui_configure_web.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" ConfigureWeb::ConfigureWeb(QWidget* parent) : QWidget(parent) diff --git a/src/yuzu/configuration/input_profiles.h b/src/yuzu/configuration/input_profiles.h index 023ec74a63..64dcf0e603 100644 --- a/src/yuzu/configuration/input_profiles.h +++ b/src/yuzu/configuration/input_profiles.h @@ -6,7 +6,7 @@ #include #include -#include "configuration/qt_config.h" +#include "qt_common/qt_config.h" namespace Core { class System; diff --git a/src/yuzu/configuration/shared_widget.cpp b/src/yuzu/configuration/shared_widget.cpp index c27a4644e9..1033271cbe 100644 --- a/src/yuzu/configuration/shared_widget.cpp +++ b/src/yuzu/configuration/shared_widget.cpp @@ -42,7 +42,7 @@ #include "common/logging/log.h" #include "common/settings.h" #include "common/settings_common.h" -#include "yuzu/configuration/shared_translation.h" +#include "qt_common/shared_translation.h" namespace ConfigurationShared { diff --git a/src/yuzu/configuration/shared_widget.h b/src/yuzu/configuration/shared_widget.h index 5c67d83542..a793347ce5 100644 --- a/src/yuzu/configuration/shared_widget.h +++ b/src/yuzu/configuration/shared_widget.h @@ -11,7 +11,7 @@ #include #include #include -#include "yuzu/configuration/shared_translation.h" +#include "qt_common/shared_translation.h" class QCheckBox; class QComboBox; diff --git a/src/yuzu/debugger/console.cpp b/src/yuzu/debugger/console.cpp index 1c1342ff18..40b2fddbc9 100644 --- a/src/yuzu/debugger/console.cpp +++ b/src/yuzu/debugger/console.cpp @@ -9,7 +9,7 @@ #include "common/logging/backend.h" #include "yuzu/debugger/console.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" namespace Debugger { void ToggleConsole() { diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index 9f9e21bc28..f32f6348a5 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -5,7 +5,7 @@ #include #include "yuzu/debugger/wait_tree.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" #include "core/arm/debug.h" #include "core/core.h" diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 80dd90d876..dceafa58de 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -24,7 +24,7 @@ #include "yuzu/game_list_p.h" #include "yuzu/game_list_worker.h" #include "yuzu/main.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" #include "yuzu/util/controller_navigation.h" GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist_, QObject* parent) @@ -820,7 +820,7 @@ QStandardItemModel* GameList::GetModel() const { return item_model; } -void GameList::PopulateAsync(QVector& game_dirs, const bool cached) +void GameList::PopulateAsync(QVector& game_dirs) { tree_view->setEnabled(false); @@ -843,8 +843,7 @@ void GameList::PopulateAsync(QVector& game_dirs, const bool game_dirs, compatibility_list, play_time_manager, - system, - cached); + system); // Get events from the worker as data becomes available connect(current_worker.get(), &GameListWorker::DataAvailable, this, &GameList::WorkerEvent, @@ -873,14 +872,6 @@ const QStringList GameList::supported_file_extensions = { QStringLiteral("nso"), QStringLiteral("nro"), QStringLiteral("nca"), QStringLiteral("xci"), QStringLiteral("nsp"), QStringLiteral("kip")}; -void GameList::ForceRefreshGameDirectory() -{ - if (!UISettings::values.game_dirs.empty() && current_worker != nullptr) { - LOG_INFO(Frontend, "Force-reloading game list per user request."); - PopulateAsync(UISettings::values.game_dirs, false); - } -} - void GameList::RefreshGameDirectory() { if (!UISettings::values.game_dirs.empty() && current_worker != nullptr) { diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h index 7c492bc19f..328432138c 100644 --- a/src/yuzu/game_list.h +++ b/src/yuzu/game_list.h @@ -20,7 +20,7 @@ #include "common/common_types.h" #include "core/core.h" -#include "uisettings.h" +#include "qt_common/uisettings.h" #include "yuzu/compatibility_list.h" #include "yuzu/play_time_manager.h" @@ -97,7 +97,7 @@ public: bool IsEmpty() const; void LoadCompatibilityList(); - void PopulateAsync(QVector& game_dirs, const bool cached = true); + void PopulateAsync(QVector& game_dirs); void SaveInterfaceLayout(); void LoadInterfaceLayout(); @@ -110,7 +110,6 @@ public: static const QStringList supported_file_extensions; public slots: - void ForceRefreshGameDirectory(); void RefreshGameDirectory(); signals: diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h index c330b574f9..b3e05b8b34 100644 --- a/src/yuzu/game_list_p.h +++ b/src/yuzu/game_list_p.h @@ -19,7 +19,7 @@ #include "common/logging/log.h" #include "common/string_util.h" #include "yuzu/play_time_manager.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" #include "yuzu/util/util.h" enum class GameListItemType { diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp index 60109769bf..267faa7182 100644 --- a/src/yuzu/game_list_worker.cpp +++ b/src/yuzu/game_list_worker.cpp @@ -27,7 +27,7 @@ #include "yuzu/game_list.h" #include "yuzu/game_list_p.h" #include "yuzu/game_list_worker.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" namespace { @@ -199,8 +199,7 @@ QList MakeGameListEntry(const std::string& path, u64 program_id, const CompatibilityList& compatibility_list, const PlayTime::PlayTimeManager& play_time_manager, - const FileSys::PatchManager& patch, - const bool cached) + const FileSys::PatchManager& patch) { const auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); @@ -224,14 +223,10 @@ QList MakeGameListEntry(const std::string& path, QString patch_versions; - if (cached) { - patch_versions = GetGameListCachedObject( - fmt::format("{:016X}", patch.GetTitleID()), "pv.txt", [&patch, &loader] { - return FormatPatchNameVersions(patch, loader, loader.IsRomFSUpdatable()); - }); - } else { - patch_versions = FormatPatchNameVersions(patch, loader, loader.IsRomFSUpdatable()); - } + patch_versions = GetGameListCachedObject( + fmt::format("{:016X}", patch.GetTitleID()), "pv.txt", [&patch, &loader] { + return FormatPatchNameVersions(patch, loader, loader.IsRomFSUpdatable()); + }); list.insert(2, new GameListItem(patch_versions)); @@ -244,15 +239,13 @@ GameListWorker::GameListWorker(FileSys::VirtualFilesystem vfs_, QVector& game_dirs_, const CompatibilityList& compatibility_list_, const PlayTime::PlayTimeManager& play_time_manager_, - Core::System& system_, - const bool cached_) + Core::System& system_) : vfs{std::move(vfs_)} , provider{provider_} , game_dirs{game_dirs_} , compatibility_list{compatibility_list_} , play_time_manager{play_time_manager_} , system{system_} - , cached{cached_} { // We want the game list to manage our lifetime. setAutoDelete(false); @@ -355,8 +348,7 @@ void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) { program_id, compatibility_list, play_time_manager, - patch, - cached); + patch); RecordEvent([=](GameList* game_list) { game_list->AddEntry(entry, parent_dir); }); } } @@ -439,8 +431,7 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa id, compatibility_list, play_time_manager, - patch, - cached); + patch); RecordEvent( [=](GameList* game_list) { game_list->AddEntry(entry, parent_dir); }); @@ -463,8 +454,7 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa program_id, compatibility_list, play_time_manager, - patch, - cached); + patch); RecordEvent( [=](GameList* game_list) { game_list->AddEntry(entry, parent_dir); }); diff --git a/src/yuzu/game_list_worker.h b/src/yuzu/game_list_worker.h index 0afd7c7849..5c5fbb251f 100644 --- a/src/yuzu/game_list_worker.h +++ b/src/yuzu/game_list_worker.h @@ -15,7 +15,7 @@ #include "common/thread.h" #include "core/file_sys/registered_cache.h" -#include "uisettings.h" +#include "qt_common/uisettings.h" #include "yuzu/compatibility_list.h" #include "yuzu/play_time_manager.h" @@ -45,8 +45,7 @@ public: QVector& game_dirs_, const CompatibilityList& compatibility_list_, const PlayTime::PlayTimeManager& play_time_manager_, - Core::System& system_, - const bool cached = true); + Core::System& system_); ~GameListWorker() override; /// Starts the processing of directory tree information. @@ -95,6 +94,4 @@ private: Common::Event processing_completed; Core::System& system; - - const bool cached; }; diff --git a/src/yuzu/hotkeys.cpp b/src/yuzu/hotkeys.cpp index 1931dcd1f6..e9d0b4e23f 100644 --- a/src/yuzu/hotkeys.cpp +++ b/src/yuzu/hotkeys.cpp @@ -8,7 +8,7 @@ #include "hid_core/frontend/emulated_controller.h" #include "yuzu/hotkeys.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" HotkeyRegistry::HotkeyRegistry() = default; HotkeyRegistry::~HotkeyRegistry() = default; diff --git a/src/yuzu/install_dialog.cpp b/src/yuzu/install_dialog.cpp index 673bbaa836..0e8e785ae9 100644 --- a/src/yuzu/install_dialog.cpp +++ b/src/yuzu/install_dialog.cpp @@ -8,7 +8,7 @@ #include #include #include "yuzu/install_dialog.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" InstallDialog::InstallDialog(QWidget* parent, const QStringList& files) : QDialog(parent) { file_list = new QListWidget(this); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 6b2608375c..ef3707d407 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -11,6 +11,7 @@ #include "core/loader/nca.h" #include "core/tools/renderdoc.h" #include "frontend_common/firmware_manager.h" +#include "qt_common/qt_common.h" #include @@ -154,7 +155,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/profiler.h" @@ -168,7 +169,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #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" @@ -470,7 +471,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()); @@ -4509,8 +4510,9 @@ void GMainWindow::OnToggleStatusBar() { void GMainWindow::OnGameListRefresh() { - // force reload add-ons etc - game_list->ForceRefreshGameDirectory(); + // Resets metadata cache and reloads + QtCommon::ResetMetadata(); + game_list->RefreshGameDirectory(); } void GMainWindow::OnAlbum() { @@ -4518,7 +4520,7 @@ void GMainWindow::OnAlbum() { auto bis_system = 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; } @@ -4541,7 +4543,7 @@ void GMainWindow::OnCabinet(Service::NFP::CabinetMode mode) { auto bis_system = 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; } @@ -4565,7 +4567,7 @@ void GMainWindow::OnMiiEdit() { auto bis_system = 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; } @@ -4588,7 +4590,7 @@ void GMainWindow::OnOpenControllerMenu() { auto bis_system = 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; } @@ -4613,7 +4615,7 @@ void GMainWindow::OnHomeMenu() { auto bis_system = system->GetFileSystemController().GetSystemNANDContents(); if (!bis_system) { QMessageBox::warning(this, tr("No firmware available"), - tr("Please install the firmware to use the Home Menu.")); + tr("Please install firmware to use the Home Menu.")); return; } @@ -4637,7 +4639,7 @@ void GMainWindow::OnInitialSetup() auto bis_system = 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; } diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 7e7c00ec0b..bf067b80fa 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -17,7 +17,7 @@ #include #include "common/common_types.h" -#include "configuration/qt_config.h" +#include "qt_common/qt_config.h" #include "frontend_common/content_manager.h" #include "input_common/drivers/tas_input.h" #include "user_data_migration.h" diff --git a/src/yuzu/multiplayer/direct_connect.cpp b/src/yuzu/multiplayer/direct_connect.cpp index 30f37c2b4a..deac3b9e59 100644 --- a/src/yuzu/multiplayer/direct_connect.cpp +++ b/src/yuzu/multiplayer/direct_connect.cpp @@ -21,7 +21,7 @@ #include "yuzu/multiplayer/message.h" #include "yuzu/multiplayer/state.h" #include "yuzu/multiplayer/validation.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" enum class ConnectionType : u8 { TraversalServer, IP }; diff --git a/src/yuzu/multiplayer/host_room.cpp b/src/yuzu/multiplayer/host_room.cpp index d8e63da600..4dd3958550 100644 --- a/src/yuzu/multiplayer/host_room.cpp +++ b/src/yuzu/multiplayer/host_room.cpp @@ -25,7 +25,7 @@ #include "yuzu/multiplayer/message.h" #include "yuzu/multiplayer/state.h" #include "yuzu/multiplayer/validation.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" #ifdef ENABLE_WEB_SERVICE #include "web_service/verify_user_jwt.h" #endif diff --git a/src/yuzu/multiplayer/lobby.cpp b/src/yuzu/multiplayer/lobby.cpp index ed6ba6a15c..84723041df 100644 --- a/src/yuzu/multiplayer/lobby.cpp +++ b/src/yuzu/multiplayer/lobby.cpp @@ -22,7 +22,7 @@ #include "yuzu/multiplayer/message.h" #include "yuzu/multiplayer/state.h" #include "yuzu/multiplayer/validation.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" #ifdef ENABLE_WEB_SERVICE #include "web_service/web_backend.h" #endif diff --git a/src/yuzu/multiplayer/state.cpp b/src/yuzu/multiplayer/state.cpp index d5529712b0..2eed3cba63 100644 --- a/src/yuzu/multiplayer/state.cpp +++ b/src/yuzu/multiplayer/state.cpp @@ -19,7 +19,7 @@ #include "yuzu/multiplayer/lobby.h" #include "yuzu/multiplayer/message.h" #include "yuzu/multiplayer/state.h" -#include "yuzu/uisettings.h" +#include "qt_common/uisettings.h" #include "yuzu/util/clickable_label.h" MultiplayerState::MultiplayerState(QWidget* parent, QStandardItemModel* game_list_model_, diff --git a/src/yuzu/play_time_manager.cpp b/src/yuzu/play_time_manager.cpp index 2669e3a7ab..3b4eefca47 100644 --- a/src/yuzu/play_time_manager.cpp +++ b/src/yuzu/play_time_manager.cpp @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/alignment.h" #include "common/fs/file.h" #include "common/fs/fs.h" #include "common/fs/path_util.h" diff --git a/src/yuzu/play_time_manager.h b/src/yuzu/play_time_manager.h index 1714b91313..ea7d9debc3 100644 --- a/src/yuzu/play_time_manager.h +++ b/src/yuzu/play_time_manager.h @@ -9,8 +9,9 @@ #include "common/common_funcs.h" #include "common/common_types.h" -#include "common/polyfill_thread.h" +#include +// TODO(crueter): Extract this into frontend_common namespace Service::Account { class ProfileManager; } diff --git a/src/yuzu/qt_common.h b/src/yuzu/qt_common.h deleted file mode 100644 index 9c63f08f34..0000000000 --- a/src/yuzu/qt_common.h +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include "core/frontend/emu_window.h" - -namespace QtCommon { - -Core::Frontend::WindowSystemType GetWindowSystemType(); - -Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window); - -} // namespace QtCommon diff --git a/src/yuzu/vk_device_info.cpp b/src/yuzu/vk_device_info.cpp index ab0d39c256..65838f7d42 100644 --- a/src/yuzu/vk_device_info.cpp +++ b/src/yuzu/vk_device_info.cpp @@ -4,7 +4,7 @@ #include #include -#include "yuzu/qt_common.h" +#include "qt_common/qt_common.h" #include "common/dynamic_library.h" #include "common/logging/log.h" From 916d01242ef70bd89293679ce7b158deb5bc4d11 Mon Sep 17 00:00:00 2001 From: crueter Date: Tue, 22 Jul 2025 17:05:57 -0400 Subject: [PATCH 02/10] move fw install Signed-off-by: crueter --- src/qt_common/qt_common.cpp | 105 ++++++++++++++++-- src/qt_common/qt_common.h | 35 +++++- .../configuration/configure_filesystem.cpp | 2 +- src/yuzu/main.cpp | 105 ++++-------------- 4 files changed, 154 insertions(+), 93 deletions(-) diff --git a/src/qt_common/qt_common.cpp b/src/qt_common/qt_common.cpp index 29379c1d54..260255c62e 100644 --- a/src/qt_common/qt_common.cpp +++ b/src/qt_common/qt_common.cpp @@ -1,6 +1,7 @@ #include "qt_common.h" #include "common/fs/fs.h" #include "common/fs/path_util.h" +#include "core/hle/service/filesystem/filesystem.h" #include "uisettings.h" #include @@ -21,17 +22,18 @@ MetadataResult ResetMetadata() { if (!Common::FS::Exists(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list/")) { - return Empty; + return MetadataResult::Empty; } else if (Common::FS::RemoveDirRecursively( Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list")) { - return Success; + return MetadataResult::Success; UISettings::values.is_game_list_reload_pending.exchange(true); } else { - return Failure; + return MetadataResult::Failure; } } -Core::Frontend::WindowSystemType GetWindowSystemType() { +Core::Frontend::WindowSystemType GetWindowSystemType() +{ // Determine WSI type based on Qt platform. QString platform_name = QGuiApplication::platformName(); if (platform_name == QStringLiteral("windows")) @@ -51,7 +53,8 @@ Core::Frontend::WindowSystemType GetWindowSystemType() { return Core::Frontend::WindowSystemType::Windows; } // namespace Core::Frontend::WindowSystemType -Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window) { +Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window) +{ Core::Frontend::EmuWindow::WindowSystemInfo wsi; wsi.type = GetWindowSystemType(); @@ -59,8 +62,8 @@ Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window) // Our Win32 Qt external doesn't have the private API. wsi.render_surface = reinterpret_cast(window->winId()); #elif defined(__APPLE__) - wsi.render_surface = reinterpret_cast(objc_msgSend)( - reinterpret_cast(window->winId()), sel_registerName("layer")); + wsi.render_surface = reinterpret_cast( + objc_msgSend)(reinterpret_cast(window->winId()), sel_registerName("layer")); #else QPlatformNativeInterface* pni = QGuiApplication::platformNativeInterface(); wsi.display_connection = pni->nativeResourceForWindow("display", window); @@ -74,4 +77,92 @@ Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window) return wsi; } +FirmwareInstallResult InstallFirmware(const QString& location, + bool recursive, + std::function QtProgressCallback, + Core::System* system, + FileSys::VfsFilesystem* vfs) +{ + 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)) { + return FirmwareInstallResult::NoOp; + } + + std::vector 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) { + return FirmwareInstallResult::NoNCAs; + } + + // 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")) { + return FirmwareInstallResult::FailedDelete; + } + + 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(((i) / static_cast(out.size())) + * 70.0))) { + return FirmwareInstallResult::FailedCorrupted; + } + } + + if (!success) { + return FirmwareInstallResult::FailedCopy; + } + + // Re-scan VFS for the newly placed firmware files. + system->GetFileSystemController().CreateFactories(*vfs); + return FirmwareInstallResult::Success; +} + } diff --git a/src/qt_common/qt_common.h b/src/qt_common/qt_common.h index 3c7dddfc1f..31adcf05c7 100644 --- a/src/qt_common/qt_common.h +++ b/src/qt_common/qt_common.h @@ -7,8 +7,11 @@ #include #include +#include "core/core.h" #include +#include + namespace QtCommon { static constexpr std::array METADATA_RESULTS = { @@ -17,7 +20,7 @@ static constexpr std::array METADATA_RESULTS = { "The metadata cache is already empty.", }; -enum MetadataResult { +enum class MetadataResult { Success, Failure, Empty, @@ -38,6 +41,36 @@ inline constexpr const char *GetResetMetadataResultString(MetadataResult result) return METADATA_RESULTS.at(static_cast(result)); } +static constexpr std::array FIRMWARE_RESULTS = { + "", + "", + "Unable to locate potential firmware NCA files", + "Failed to delete one or more firmware files.", + "One or more firmware files failed to copy into NAND.", + "Firmware installation cancelled, firmware may be in a bad state or corrupted." + "Restart Eden or re-install firmware." +}; + +enum class FirmwareInstallResult { + Success, + NoOp, + NoNCAs, + FailedDelete, + FailedCopy, + FailedCorrupted, +}; + +FirmwareInstallResult InstallFirmware(const QString &location, + bool recursive, + std::function QtProgressCallback, + Core::System *system, + FileSys::VfsFilesystem *vfs); + +inline constexpr const char *GetFirmwareInstallResultString(FirmwareInstallResult result) +{ + return FIRMWARE_RESULTS.at(static_cast(result)); +} + Core::Frontend::WindowSystemType GetWindowSystemType(); Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window); diff --git a/src/yuzu/configuration/configure_filesystem.cpp b/src/yuzu/configuration/configure_filesystem.cpp index 392155d2a3..5459dc0377 100644 --- a/src/yuzu/configuration/configure_filesystem.cpp +++ b/src/yuzu/configuration/configure_filesystem.cpp @@ -132,7 +132,7 @@ void ConfigureFilesystem::ResetMetadata() { const QString title = tr("Reset Metadata Cache"); switch (result) { - case QtCommon::Failure: + case QtCommon::MetadataResult::Failure: QMessageBox::warning(this, title, resultMessage); break; default: diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index ef3707d407..9b3bbe411e 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -4259,104 +4259,41 @@ void GMainWindow::InstallFirmware(const QString &location, bool recursive) return progress.wasCanceled(); }; - LOG_INFO(Frontend, "Installing firmware from {}", location.toStdString()); + auto result = QtCommon::InstallFirmware(location, recursive, QtProgressCallback, system.get(), vfs.get()); + const char* resultMessage = QtCommon::GetFirmwareInstallResultString(result); - // 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(); + progress.close(); + + QMessageBox *box = new QMessageBox(QMessageBox::Icon::NoIcon, tr("Firmware Install Failed"), tr(resultMessage), QMessageBox::Ok, this); + + switch (result) { + case QtCommon::FirmwareInstallResult::NoNCAs: + case QtCommon::FirmwareInstallResult::FailedCorrupted: + box->setIcon(QMessageBox::Icon::Warning); + box->exec(); return; - } - - std::vector 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")); + case QtCommon::FirmwareInstallResult::FailedCopy: + case QtCommon::FirmwareInstallResult::FailedDelete: + box->setIcon(QMessageBox::Icon::Critical); + box->exec(); return; + default: + box->deleteLater(); + break; } - // 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(((i) / static_cast(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((processed_size * 10) / total_size)); return progress.wasCanceled(); }; - auto result = + auto results = ContentManager::VerifyInstalledContents(*system, *provider, VerifyFirmwareCallback, true); - if (result.size() > 0) { + if (results.size() > 0) { const auto failed_names = - QString::fromStdString(fmt::format("{}", fmt::join(result, "\n"))); + QString::fromStdString(fmt::format("{}", fmt::join(results, "\n"))); progress.close(); QMessageBox::critical( this, tr("Firmware integrity verification failed!"), From 6b13fd566dc604889dda526932b9d71df7940bf0 Mon Sep 17 00:00:00 2001 From: crueter Date: Tue, 22 Jul 2025 17:12:24 -0400 Subject: [PATCH 03/10] Fix license headers Signed-off-by: crueter --- .ci/license-header.sh | 14 +++++++++++--- src/qt_common/qt_common.cpp | 3 +++ src/qt_common/qt_config.cpp | 3 +++ src/qt_common/qt_config.h | 3 +++ src/qt_common/uisettings.cpp | 3 +++ src/qt_common/uisettings.h | 3 +++ src/yuzu/configuration/configure_audio.cpp | 3 +++ src/yuzu/configuration/configure_cpu.h | 3 +++ src/yuzu/configuration/configure_debug.cpp | 3 +++ src/yuzu/configuration/configure_dialog.cpp | 3 +++ src/yuzu/configuration/configure_dialog.h | 3 +++ src/yuzu/configuration/configure_filesystem.cpp | 3 +++ src/yuzu/configuration/configure_general.cpp | 3 +++ src/yuzu/configuration/configure_graphics.cpp | 3 +++ src/yuzu/configuration/configure_graphics.h | 3 +++ .../configuration/configure_graphics_advanced.cpp | 3 +++ .../configure_graphics_extensions.cpp | 3 +++ src/yuzu/configuration/configure_hotkeys.cpp | 3 +++ src/yuzu/configuration/configure_input_per_game.h | 3 +++ src/yuzu/configuration/configure_input_player.cpp | 3 +++ src/yuzu/configuration/configure_per_game.cpp | 3 +++ src/yuzu/configuration/configure_per_game.h | 3 +++ .../configuration/configure_per_game_addons.cpp | 3 +++ src/yuzu/configuration/configure_ringcon.cpp | 3 +++ src/yuzu/configuration/configure_tas.cpp | 3 +++ src/yuzu/configuration/input_profiles.h | 3 +++ src/yuzu/configuration/shared_widget.cpp | 3 +++ src/yuzu/configuration/shared_widget.h | 3 +++ src/yuzu/debugger/console.cpp | 3 +++ src/yuzu/debugger/wait_tree.cpp | 3 +++ src/yuzu/game_list_p.h | 3 +++ src/yuzu/game_list_worker.cpp | 3 +++ src/yuzu/game_list_worker.h | 3 +++ src/yuzu/hotkeys.cpp | 3 +++ src/yuzu/install_dialog.cpp | 3 +++ src/yuzu/multiplayer/state.cpp | 3 +++ src/yuzu/play_time_manager.cpp | 3 +++ src/yuzu/play_time_manager.h | 3 +++ src/yuzu/vk_device_info.cpp | 3 +++ 39 files changed, 125 insertions(+), 3 deletions(-) diff --git a/.ci/license-header.sh b/.ci/license-header.sh index b65ef6303f..b2ecc0b275 100755 --- a/.ci/license-header.sh +++ b/.ci/license-header.sh @@ -4,16 +4,24 @@ HEADER="$(cat "$PWD/.ci/license/header.txt")" echo "Getting branch changes" -BRANCH=`git rev-parse --abbrev-ref HEAD` -COMMITS=`git log ${BRANCH} --not master --pretty=format:"%h"` -RANGE="${COMMITS[${#COMMITS[@]}-1]}^..${COMMITS[0]}" +# BRANCH=`git rev-parse --abbrev-ref HEAD` +# COMMITS=`git log ${BRANCH} --not master --pretty=format:"%h"` +# RANGE="${COMMITS[${#COMMITS[@]}-1]}^..${COMMITS[0]}" +# FILES=`git diff-tree --no-commit-id --name-only ${RANGE} -r` + +CURRENT=`git rev-parse --short=10 HEAD` +BASE=`git merge-base master $CURRENT` +RANGE="$CURRENT^..$BASE" FILES=`git diff-tree --no-commit-id --name-only ${RANGE} -r` #FILES=$(git diff --name-only master) +echo $FILES echo "Done" for file in $FILES; do + [ -f "$file" ] || continue + EXTENSION="${file##*.}" case "$EXTENSION" in kts|kt|cpp|h) diff --git a/src/qt_common/qt_common.cpp b/src/qt_common/qt_common.cpp index 260255c62e..4a27566107 100644 --- a/src/qt_common/qt_common.cpp +++ b/src/qt_common/qt_common.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + #include "qt_common.h" #include "common/fs/fs.h" #include "common/fs/path_util.h" diff --git a/src/qt_common/qt_config.cpp b/src/qt_common/qt_config.cpp index ae5b330e23..f787873cf6 100644 --- a/src/qt_common/qt_config.cpp +++ b/src/qt_common/qt_config.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/qt_common/qt_config.h b/src/qt_common/qt_config.h index dc2dceb4d7..a8c80dd273 100644 --- a/src/qt_common/qt_config.h +++ b/src/qt_common/qt_config.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/qt_common/uisettings.cpp b/src/qt_common/uisettings.cpp index f573b9a9aa..04c9edb5b8 100644 --- a/src/qt_common/uisettings.cpp +++ b/src/qt_common/uisettings.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/qt_common/uisettings.h b/src/qt_common/uisettings.h index 18498162b2..d31ca56347 100644 --- a/src/qt_common/uisettings.h +++ b/src/qt_common/uisettings.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_audio.cpp b/src/yuzu/configuration/configure_audio.cpp index 8d11920d31..a7ebae91f8 100644 --- a/src/yuzu/configuration/configure_audio.cpp +++ b/src/yuzu/configuration/configure_audio.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_cpu.h b/src/yuzu/configuration/configure_cpu.h index 21a40093b8..2d9e87ca96 100644 --- a/src/yuzu/configuration/configure_cpu.h +++ b/src/yuzu/configuration/configure_cpu.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp index d0ec0270e0..aa5235a132 100644 --- a/src/yuzu/configuration/configure_debug.cpp +++ b/src/yuzu/configuration/configure_debug.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index 4e128106e7..0816782282 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_dialog.h b/src/yuzu/configuration/configure_dialog.h index bf96035752..c1e148fc8e 100644 --- a/src/yuzu/configuration/configure_dialog.h +++ b/src/yuzu/configuration/configure_dialog.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_filesystem.cpp b/src/yuzu/configuration/configure_filesystem.cpp index 5459dc0377..d02e6dec2b 100644 --- a/src/yuzu/configuration/configure_filesystem.cpp +++ b/src/yuzu/configuration/configure_filesystem.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp index 352ae8ab85..18c2c9cb77 100644 --- a/src/yuzu/configuration/configure_general.cpp +++ b/src/yuzu/configuration/configure_general.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 131016af97..d628fc951a 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h index 9f7ece5714..38d97aae80 100644 --- a/src/yuzu/configuration/configure_graphics.h +++ b/src/yuzu/configuration/configure_graphics.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp index 921cb83b08..e07ad8c466 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.cpp +++ b/src/yuzu/configuration/configure_graphics_advanced.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_graphics_extensions.cpp b/src/yuzu/configuration/configure_graphics_extensions.cpp index 973b9bad17..884892e6e1 100644 --- a/src/yuzu/configuration/configure_graphics_extensions.cpp +++ b/src/yuzu/configuration/configure_graphics_extensions.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_hotkeys.cpp b/src/yuzu/configuration/configure_hotkeys.cpp index 53f7401ef4..a5c1ee009a 100644 --- a/src/yuzu/configuration/configure_hotkeys.cpp +++ b/src/yuzu/configuration/configure_hotkeys.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2017 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_input_per_game.h b/src/yuzu/configuration/configure_input_per_game.h index 1323d101d3..dcd6dd841b 100644 --- a/src/yuzu/configuration/configure_input_per_game.h +++ b/src/yuzu/configuration/configure_input_per_game.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index f0e34d8dc2..c8d7f2f460 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index 545c37a2c9..b51ede0de8 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_per_game.h b/src/yuzu/configuration/configure_per_game.h index a756b561a8..83afc27f3d 100644 --- a/src/yuzu/configuration/configure_per_game.h +++ b/src/yuzu/configuration/configure_per_game.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_per_game_addons.cpp b/src/yuzu/configuration/configure_per_game_addons.cpp index 90c94cb923..ed4cbc1147 100644 --- a/src/yuzu/configuration/configure_per_game_addons.cpp +++ b/src/yuzu/configuration/configure_per_game_addons.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_ringcon.cpp b/src/yuzu/configuration/configure_ringcon.cpp index 7e7877aaf6..795ad1a85e 100644 --- a/src/yuzu/configuration/configure_ringcon.cpp +++ b/src/yuzu/configuration/configure_ringcon.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/configure_tas.cpp b/src/yuzu/configuration/configure_tas.cpp index 290e825fe6..898a1a3e59 100644 --- a/src/yuzu/configuration/configure_tas.cpp +++ b/src/yuzu/configuration/configure_tas.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/input_profiles.h b/src/yuzu/configuration/input_profiles.h index 64dcf0e603..dba5ce1318 100644 --- a/src/yuzu/configuration/input_profiles.h +++ b/src/yuzu/configuration/input_profiles.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/shared_widget.cpp b/src/yuzu/configuration/shared_widget.cpp index 1033271cbe..b5dacae69f 100644 --- a/src/yuzu/configuration/shared_widget.cpp +++ b/src/yuzu/configuration/shared_widget.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/configuration/shared_widget.h b/src/yuzu/configuration/shared_widget.h index a793347ce5..9e718098a3 100644 --- a/src/yuzu/configuration/shared_widget.h +++ b/src/yuzu/configuration/shared_widget.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/debugger/console.cpp b/src/yuzu/debugger/console.cpp index 40b2fddbc9..8fb22db192 100644 --- a/src/yuzu/debugger/console.cpp +++ b/src/yuzu/debugger/console.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index f32f6348a5..feb814b25e 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h index b3e05b8b34..5a3b5829f5 100644 --- a/src/yuzu/game_list_p.h +++ b/src/yuzu/game_list_p.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2015 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp index 267faa7182..538c7ab822 100644 --- a/src/yuzu/game_list_worker.cpp +++ b/src/yuzu/game_list_worker.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/game_list_worker.h b/src/yuzu/game_list_worker.h index 5c5fbb251f..f5d5f6341b 100644 --- a/src/yuzu/game_list_worker.h +++ b/src/yuzu/game_list_worker.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/hotkeys.cpp b/src/yuzu/hotkeys.cpp index e9d0b4e23f..31932e6f43 100644 --- a/src/yuzu/hotkeys.cpp +++ b/src/yuzu/hotkeys.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2014 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/install_dialog.cpp b/src/yuzu/install_dialog.cpp index 0e8e785ae9..e6f1392ce0 100644 --- a/src/yuzu/install_dialog.cpp +++ b/src/yuzu/install_dialog.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/multiplayer/state.cpp b/src/yuzu/multiplayer/state.cpp index 2eed3cba63..8ff1d991ec 100644 --- a/src/yuzu/multiplayer/state.cpp +++ b/src/yuzu/multiplayer/state.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/play_time_manager.cpp b/src/yuzu/play_time_manager.cpp index 3b4eefca47..4ad0fdfd08 100644 --- a/src/yuzu/play_time_manager.cpp +++ b/src/yuzu/play_time_manager.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/play_time_manager.h b/src/yuzu/play_time_manager.h index ea7d9debc3..cd81bdb061 100644 --- a/src/yuzu/play_time_manager.h +++ b/src/yuzu/play_time_manager.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/yuzu/vk_device_info.cpp b/src/yuzu/vk_device_info.cpp index 65838f7d42..d961d550a1 100644 --- a/src/yuzu/vk_device_info.cpp +++ b/src/yuzu/vk_device_info.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later From 6c48a82c83778bcb6c09bf8b0da76b00091d5043 Mon Sep 17 00:00:00 2001 From: crueter Date: Tue, 22 Jul 2025 17:56:58 -0400 Subject: [PATCH 04/10] debug: log user/save id Signed-off-by: crueter --- src/core/file_sys/savedata_factory.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index 106922e04f..0591517727 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp @@ -126,6 +126,10 @@ std::string SaveDataFactory::GetFullPath(ProgramId program_id, VirtualDir dir, std::string out = GetSaveDataSpaceIdPath(space); + LOG_INFO(Common_Filesystem, "Save ID: {:016X}", save_id); + LOG_INFO(Common_Filesystem, "User ID[1]: {:016X}", user_id[1]); + LOG_INFO(Common_Filesystem, "User ID[0]: {:016X}", user_id[0]); + switch (type) { case SaveDataType::System: return fmt::format("{}save/{:016X}/{:016X}{:016X}", out, save_id, user_id[1], user_id[0]); From 1da87f01f7b7c802765cb6f05af694cdb60fac14 Mon Sep 17 00:00:00 2001 From: crueter Date: Tue, 22 Jul 2025 18:17:20 -0400 Subject: [PATCH 05/10] explicitly check write status for dir Signed-off-by: crueter --- src/qt_common/qt_common.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt_common/qt_common.cpp b/src/qt_common/qt_common.cpp index 4a27566107..abeae4c3a1 100644 --- a/src/qt_common/qt_common.cpp +++ b/src/qt_common/qt_common.cpp @@ -123,7 +123,7 @@ FirmwareInstallResult InstallFirmware(const QString& location, // 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")) { + if (sysnand_content_vdir->IsWritable() && !sysnand_content_vdir->CleanSubdirectoryRecursive("registered")) { return FirmwareInstallResult::FailedDelete; } From 3198770ffbdfe26e6d691b080028e4e0d5a7e726 Mon Sep 17 00:00:00 2001 From: crueter Date: Tue, 22 Jul 2025 23:23:14 -0400 Subject: [PATCH 06/10] more common funcs Signed-off-by: crueter --- .ci/license-header.sh | 6 +- src/core/file_sys/savedata_factory.cpp | 3 + src/qt_common/CMakeLists.txt | 4 +- src/qt_common/qt_common.cpp | 43 ++++- src/qt_common/qt_common.h | 4 +- src/qt_common/qt_game_util.cpp | 170 +++++++++++++++++++ src/qt_common/qt_game_util.h | 41 +++++ src/qt_common/qt_path_util.cpp | 20 +++ src/qt_common/qt_path_util.h | 7 + src/yuzu/main.cpp | 225 ++++--------------------- src/yuzu/main.h | 8 +- 11 files changed, 321 insertions(+), 210 deletions(-) create mode 100644 src/qt_common/qt_game_util.cpp create mode 100644 src/qt_common/qt_game_util.h create mode 100644 src/qt_common/qt_path_util.cpp create mode 100644 src/qt_common/qt_path_util.h diff --git a/.ci/license-header.sh b/.ci/license-header.sh index b2ecc0b275..2240830b7e 100755 --- a/.ci/license-header.sh +++ b/.ci/license-header.sh @@ -9,10 +9,8 @@ echo "Getting branch changes" # RANGE="${COMMITS[${#COMMITS[@]}-1]}^..${COMMITS[0]}" # FILES=`git diff-tree --no-commit-id --name-only ${RANGE} -r` -CURRENT=`git rev-parse --short=10 HEAD` -BASE=`git merge-base master $CURRENT` -RANGE="$CURRENT^..$BASE" -FILES=`git diff-tree --no-commit-id --name-only ${RANGE} -r` +BASE=`git merge-base master HEAD` +FILES=`git diff --name-only $BASE` #FILES=$(git diff --name-only master) diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index 0591517727..edf51e74de 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/qt_common/CMakeLists.txt b/src/qt_common/CMakeLists.txt index be1a8ebbd0..d6ef427ba6 100644 --- a/src/qt_common/CMakeLists.txt +++ b/src/qt_common/CMakeLists.txt @@ -13,10 +13,12 @@ add_library(qt_common STATIC shared_translation.cpp shared_translation.h + qt_path_util.h qt_path_util.cpp + qt_game_util.h qt_game_util.cpp ) create_target_directory_groups(qt_common) -target_link_libraries(qt_common PUBLIC core Qt6::Core Qt6::Gui SimpleIni::SimpleIni) +target_link_libraries(qt_common PUBLIC core Qt6::Core Qt6::Gui SimpleIni::SimpleIni QuaZip::QuaZip) if (NOT WIN32) target_include_directories(qt_common PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS}) diff --git a/src/qt_common/qt_common.cpp b/src/qt_common/qt_common.cpp index abeae4c3a1..0cd4c86b4a 100644 --- a/src/qt_common/qt_common.cpp +++ b/src/qt_common/qt_common.cpp @@ -15,6 +15,11 @@ #if !defined(WIN32) && !defined(__APPLE__) #include + +#include + +#include + #elif defined(__APPLE__) #include #endif @@ -80,11 +85,12 @@ Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window) return wsi; } -FirmwareInstallResult InstallFirmware(const QString& location, - bool recursive, - std::function QtProgressCallback, - Core::System* system, - FileSys::VfsFilesystem* vfs) +FirmwareInstallResult InstallFirmware( + const QString& location, + bool recursive, + std::function QtProgressCallback, + Core::System* system, + FileSys::VfsFilesystem* vfs) { LOG_INFO(Frontend, "Installing firmware from {}", location.toStdString()); @@ -123,7 +129,8 @@ FirmwareInstallResult InstallFirmware(const QString& location, // Locate and erase the content of nand/system/Content/registered/*.nca, if any. auto sysnand_content_vdir = system->GetFileSystemController().GetSystemNANDContentDirectory(); - if (sysnand_content_vdir->IsWritable() && !sysnand_content_vdir->CleanSubdirectoryRecursive("registered")) { + if (sysnand_content_vdir->IsWritable() + && !sysnand_content_vdir->CleanSubdirectoryRecursive("registered")) { return FirmwareInstallResult::FailedDelete; } @@ -168,4 +175,28 @@ FirmwareInstallResult InstallFirmware(const QString& location, return FirmwareInstallResult::Success; } +QString UnzipFirmwareToTmp(const QString& location) +{ + namespace fs = std::filesystem; + fs::path tmp{fs::temp_directory_path()}; + + if (!fs::create_directories(tmp / "eden" / "firmware")) { + return ""; + } + + tmp /= "eden"; + tmp /= "firmware"; + + QString qCacheDir = QString::fromStdString(tmp.string()); + + QFile zip(location); + + QStringList result = JlCompress::extractDir(&zip, qCacheDir); + if (result.isEmpty()) { + return ""; + } + + return qCacheDir; } + +} // namespace QtCommon diff --git a/src/qt_common/qt_common.h b/src/qt_common/qt_common.h index 31adcf05c7..b3ca99e65a 100644 --- a/src/qt_common/qt_common.h +++ b/src/qt_common/qt_common.h @@ -62,10 +62,12 @@ enum class FirmwareInstallResult { FirmwareInstallResult InstallFirmware(const QString &location, bool recursive, - std::function QtProgressCallback, + std::function QtProgressCallback, Core::System *system, FileSys::VfsFilesystem *vfs); +QString UnzipFirmwareToTmp(const QString &location); + inline constexpr const char *GetFirmwareInstallResultString(FirmwareInstallResult result) { return FIRMWARE_RESULTS.at(static_cast(result)); diff --git a/src/qt_common/qt_game_util.cpp b/src/qt_common/qt_game_util.cpp new file mode 100644 index 0000000000..5b6e5f762a --- /dev/null +++ b/src/qt_common/qt_game_util.cpp @@ -0,0 +1,170 @@ +#include "qt_game_util.h" +#include "common/fs/fs.h" +#include "common/fs/path_util.h" + +#include +#include +#include "fmt/ostream.h" +#include + +#ifdef _WIN32 +#include +#endif + +namespace QtCommon { + +bool 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 { +#if defined(__linux__) || defined(__FreeBSD__) // Linux and FreeBSD + 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; +#elif defined(_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(&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(&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; +#else // Unsupported platform + return false; +#endif +} catch (const std::exception& e) { + LOG_ERROR(Frontend, "Failed to create shortcut: {}", e.what()); + return false; +} + +bool 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(__linux__) || defined(__FreeBSD__) + 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)) { + 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 OpenRootDataFolder() { + QDesktopServices::openUrl(QUrl( + QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::EdenDir)))); +} + +void OpenNANDFolder() +{ + QDesktopServices::openUrl(QUrl::fromLocalFile( + QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::NANDDir)))); +} + +void OpenSDMCFolder() +{ + QDesktopServices::openUrl(QUrl::fromLocalFile( + QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::SDMCDir)))); +} + +void OpenModFolder() +{ + QDesktopServices::openUrl(QUrl::fromLocalFile( + QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::LoadDir)))); +} + +void OpenLogFolder() +{ + QDesktopServices::openUrl(QUrl::fromLocalFile( + QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::LogDir)))); +} + +} diff --git a/src/qt_common/qt_game_util.h b/src/qt_common/qt_game_util.h new file mode 100644 index 0000000000..98d17027c4 --- /dev/null +++ b/src/qt_common/qt_game_util.h @@ -0,0 +1,41 @@ +#ifndef QT_GAME_UTIL_H +#define QT_GAME_UTIL_H + +#include "frontend_common/content_manager.h" +#include + +namespace QtCommon { + +static constexpr std::array GAME_VERIFICATION_RESULTS = { + "The operation completed successfully.", + "File contents may be corrupt or missing..", + "Firmware installation cancelled, firmware may be in a bad state or corrupted." + "File contents could not be checked for validity." +}; + +inline constexpr const char *GetGameVerificationResultString(ContentManager::GameVerificationResult result) +{ + return GAME_VERIFICATION_RESULTS.at(static_cast(result)); +} + +bool 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); + +bool MakeShortcutIcoPath(const u64 program_id, + const std::string_view game_file_name, + std::filesystem::path& out_icon_path); + +void OpenRootDataFolder(); +void OpenNANDFolder(); +void OpenSDMCFolder(); +void OpenModFolder(); +void OpenLogFolder(); +} + +#endif // QT_GAME_UTIL_H diff --git a/src/qt_common/qt_path_util.cpp b/src/qt_common/qt_path_util.cpp new file mode 100644 index 0000000000..2ca2f6bf72 --- /dev/null +++ b/src/qt_common/qt_path_util.cpp @@ -0,0 +1,20 @@ +#include "qt_path_util.h" +#include +#include +#include +#include "common/fs/fs.h" +#include "common/fs/path_util.h" +#include + +bool QtCommon::PathUtil::OpenShaderCache(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)) { + return false; + } + + const auto shader_path_string{Common::FS::PathToUTF8String(shader_cache_folder_path)}; + const auto qt_shader_cache_path = QString::fromStdString(shader_path_string); + return QDesktopServices::openUrl(QUrl::fromLocalFile(qt_shader_cache_path)); +} diff --git a/src/qt_common/qt_path_util.h b/src/qt_common/qt_path_util.h new file mode 100644 index 0000000000..6fafad7ed9 --- /dev/null +++ b/src/qt_common/qt_path_util.h @@ -0,0 +1,7 @@ +#ifndef QT_PATH_UTIL_H +#define QT_PATH_UTIL_H + +#include "common/common_types.h" +namespace QtCommon::PathUtil { bool OpenShaderCache(u64 program_id); } + +#endif // QT_PATH_UTIL_H diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 9b3bbe411e..884cca4257 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -12,6 +12,8 @@ #include "core/tools/renderdoc.h" #include "frontend_common/firmware_manager.h" #include "qt_common/qt_common.h" +#include "qt_common/qt_game_util.h" +#include "qt_common/qt_path_util.h" #include @@ -1077,7 +1079,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(); @@ -2520,16 +2522,9 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target } 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; + if (!QtCommon::PathUtil::OpenShaderCache(program_id)) { + QMessageBox::warning(this, tr("Error Opening Shader Cache"), tr("Failed to create or open shader cache for this title, ensure your app data directory has write permissions.")); } - 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, @@ -2594,6 +2589,7 @@ static bool RomFSRawCopy(size_t total_size, size_t& read_size, QProgressDialog& return true; } +// TODO(crueter): All this can be transfered to qt_common QString GMainWindow::GetGameListErrorRemoving(InstalledEntryType type) const { switch (type) { case InstalledEntryType::Game: @@ -2950,12 +2946,8 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa } } +// 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); @@ -2968,18 +2960,20 @@ void GMainWindow::OnGameListVerifyIntegrity(const std::string& game_path) { }; const auto result = ContentManager::VerifyGameContents(*system, game_path, QtProgressCallback); + const QString resultString = tr(QtCommon::GetGameVerificationResultString(result)); progress.close(); switch (result) { case ContentManager::GameVerificationResult::Success: QMessageBox::information(this, tr("Integrity verification succeeded!"), - tr("The operation completed successfully.")); + resultString); break; case ContentManager::GameVerificationResult::Failed: QMessageBox::critical(this, tr("Integrity verification failed!"), - tr("File contents may be corrupt.")); + resultString); break; case ContentManager::GameVerificationResult::NotImplemented: - NotImplemented(); + QMessageBox::warning(this, tr("Integrity verification couldn't be performed"), + resultString); } } @@ -3000,109 +2994,8 @@ void GMainWindow::OnGameListNavigateToGamedbEntry(u64 program_id, QDesktopServices::openUrl(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 { -#if defined(__linux__) || defined(__FreeBSD__) // Linux and FreeBSD - 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; -#elif defined(_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(&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(&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; -#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 +// TODO(crueter): Still need to decide what to do re: message boxes w/ qml bool GMainWindow::CreateShortcutMessagesGUI(QWidget* parent, int imsg, const QString& game_title) { int result = 0; QMessageBox::StandardButtons buttons; @@ -3133,33 +3026,6 @@ bool GMainWindow::CreateShortcutMessagesGUI(QWidget* parent, int imsg, const QSt } } -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(__linux__) || defined(__FreeBSD__) - 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) { // Create shortcut @@ -4186,32 +4052,27 @@ void GMainWindow::LoadAmiibo(const QString& filename) { } void GMainWindow::OnOpenRootDataFolder() { - QDesktopServices::openUrl(QUrl( - QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::EdenDir)))); + QtCommon::OpenRootDataFolder(); } void GMainWindow::OnOpenNANDFolder() { - QDesktopServices::openUrl(QUrl::fromLocalFile( - QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::NANDDir)))); + QtCommon::OpenNANDFolder(); } void GMainWindow::OnOpenSDMCFolder() { - QDesktopServices::openUrl(QUrl::fromLocalFile( - QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::SDMCDir)))); + QtCommon::OpenSDMCFolder(); } void GMainWindow::OnOpenModFolder() { - QDesktopServices::openUrl(QUrl::fromLocalFile( - QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::LoadDir)))); + QtCommon::OpenModFolder(); } void GMainWindow::OnOpenLogFolder() { - QDesktopServices::openUrl(QUrl::fromLocalFile( - QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::LogDir)))); + QtCommon::OpenLogFolder(); } void GMainWindow::OnVerifyInstalledContents() { @@ -4350,32 +4211,14 @@ void GMainWindow::OnInstallFirmwareFromZIP() return; } - namespace fs = std::filesystem; - fs::path tmp{std::filesystem::temp_directory_path()}; + const QString qCacheDir = QtCommon::UnzipFirmwareToTmp(firmware_zip_location); - 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); - - 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"), @@ -4383,14 +4226,7 @@ void GMainWindow::OnInstallFirmwareFromZIP() "Check write permissions in the system temp directory and try 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() { @@ -4639,7 +4475,7 @@ std::filesystem::path GMainWindow::GetShortcutPath(GameListShortcutTarget target } 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 + // Get path to Eden executable std::filesystem::path command = GetEdenCommand(); // Shortcut path @@ -4691,10 +4527,16 @@ void GMainWindow::CreateShortcut(const std::string &game_path, const u64 program QImage icon_data = QImage::fromData(icon_image_file.data(), static_cast(icon_image_file.size())); std::filesystem::path out_icon_path; - if (GMainWindow::MakeShortcutIcoPath(program_id, game_title, out_icon_path)) { + if (QtCommon::MakeShortcutIcoPath(program_id, game_title, out_icon_path)) { if (!SaveIconToFile(out_icon_path, icon_data)) { LOG_ERROR(Frontend, "Could not write icon to file"); } + } else { + 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); } #if defined(__linux__) @@ -4715,11 +4557,11 @@ void GMainWindow::CreateShortcut(const std::string &game_path, const u64 program 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 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, + if (QtCommon::CreateShortcutLink(shortcut_path, comment, out_icon_path, command, arguments, categories, keywords, game_title)) { GMainWindow::CreateShortcutMessagesGUI(this, GMainWindow::CREATE_SHORTCUT_MSGBOX_SUCCESS, qgame_title); @@ -4749,6 +4591,7 @@ void GMainWindow::OnCreateHomeMenuShortcut(GameListShortcutTarget target) auto qlaunch_applet_nca = bis_system->GetEntry(QLaunchId, FileSys::ContentRecordType::Program); const auto game_path = qlaunch_applet_nca->GetFullPath(); + // TODO(crueter): Make this use the Eden icon CreateShortcut(game_path, QLaunchId, "Switch Home Menu", target, "-qlaunch", false); } diff --git a/src/yuzu/main.h b/src/yuzu/main.h index bf067b80fa..b009dcb4c9 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -478,13 +478,7 @@ private: QString GetTasStateDescription() const; bool CreateShortcutMessagesGUI(QWidget* parent, int imsg, const QString& game_title); - bool MakeShortcutIcoPath(const u64 program_id, const std::string_view game_file_name, - std::filesystem::path& out_icon_path); - bool 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); + /** * Mimic the behavior of QMessageBox::question but link controller navigation to the dialog * The only difference is that it returns a boolean. From b080a8192bf619f6b53d36c11bded135da6bd315 Mon Sep 17 00:00:00 2001 From: crueter Date: Tue, 22 Jul 2025 23:28:13 -0400 Subject: [PATCH 07/10] Fix license headers --- src/qt_common/qt_game_util.cpp | 3 +++ src/qt_common/qt_game_util.h | 3 +++ src/qt_common/qt_path_util.cpp | 3 +++ src/qt_common/qt_path_util.h | 3 +++ 4 files changed, 12 insertions(+) diff --git a/src/qt_common/qt_game_util.cpp b/src/qt_common/qt_game_util.cpp index 5b6e5f762a..f6777334da 100644 --- a/src/qt_common/qt_game_util.cpp +++ b/src/qt_common/qt_game_util.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + #include "qt_game_util.h" #include "common/fs/fs.h" #include "common/fs/path_util.h" diff --git a/src/qt_common/qt_game_util.h b/src/qt_common/qt_game_util.h index 98d17027c4..3d27839672 100644 --- a/src/qt_common/qt_game_util.h +++ b/src/qt_common/qt_game_util.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + #ifndef QT_GAME_UTIL_H #define QT_GAME_UTIL_H diff --git a/src/qt_common/qt_path_util.cpp b/src/qt_common/qt_path_util.cpp index 2ca2f6bf72..6875d01dea 100644 --- a/src/qt_common/qt_path_util.cpp +++ b/src/qt_common/qt_path_util.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + #include "qt_path_util.h" #include #include diff --git a/src/qt_common/qt_path_util.h b/src/qt_common/qt_path_util.h index 6fafad7ed9..7f399c4bb4 100644 --- a/src/qt_common/qt_path_util.h +++ b/src/qt_common/qt_path_util.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + #ifndef QT_PATH_UTIL_H #define QT_PATH_UTIL_H From 0f28ecbe71af2cb2b1e70ff9cec8fd1237ca193a Mon Sep 17 00:00:00 2001 From: crueter Date: Wed, 23 Jul 2025 01:21:18 -0400 Subject: [PATCH 08/10] thank you Qt Creator, very cool Signed-off-by: crueter --- src/qt_common/qt_common.cpp | 7 ++----- src/qt_common/qt_game_util.cpp | 10 +++++++--- src/yuzu/main.cpp | 3 --- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/qt_common/qt_common.cpp b/src/qt_common/qt_common.cpp index 0cd4c86b4a..54c79c93e1 100644 --- a/src/qt_common/qt_common.cpp +++ b/src/qt_common/qt_common.cpp @@ -9,17 +9,14 @@ #include #include -#include #include "common/logging/log.h" #include "core/frontend/emu_window.h" -#if !defined(WIN32) && !defined(__APPLE__) -#include - #include - #include +#if !defined(WIN32) && !defined(__APPLE__) +#include #elif defined(__APPLE__) #include #endif diff --git a/src/qt_common/qt_game_util.cpp b/src/qt_common/qt_game_util.cpp index f6777334da..6c42a45964 100644 --- a/src/qt_common/qt_game_util.cpp +++ b/src/qt_common/qt_game_util.cpp @@ -7,11 +7,15 @@ #include #include -#include "fmt/ostream.h" -#include #ifdef _WIN32 -#include + #include + #include + #include "common/scope_exit.h" + #include "common/string_util.h" +#else + #include "fmt/ostream.h" + #include #endif namespace QtCommon { diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 884cca4257..c5c0c82598 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -15,8 +15,6 @@ #include "qt_common/qt_game_util.h" #include "qt_common/qt_path_util.h" -#include - #ifdef __APPLE__ #include // for chdir #endif @@ -119,7 +117,6 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #include "common/scm_rev.h" #include "common/scope_exit.h" #ifdef _WIN32 -#include #include "common/windows/timer_resolution.h" #endif #ifdef ARCHITECTURE_x86_64 From aafd2b7437464fb92775a62cad205e1da6a0178c Mon Sep 17 00:00:00 2001 From: crueter Date: Wed, 23 Jul 2025 21:10:17 -0400 Subject: [PATCH 09/10] [qt] frontend abstraction and message box early handling Signed-off-by: crueter --- src/CMakeLists.txt | 1 + src/frontend_common/firmware_manager.h | 5 ++- src/qt_common/CMakeLists.txt | 6 ++- src/qt_common/qt_common.cpp | 59 ++++++++++++++++++++++---- src/qt_common/qt_common.h | 34 +++++++-------- src/qt_common/qt_frontend_util.cpp | 25 +++++++++++ src/qt_common/qt_frontend_util.h | 29 +++++++++++++ src/yuzu/main.cpp | 25 +++-------- 8 files changed, 136 insertions(+), 48 deletions(-) create mode 100644 src/qt_common/qt_frontend_util.cpp create mode 100644 src/qt_common/qt_frontend_util.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 929da038d9..6bf8ddc106 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -212,6 +212,7 @@ if (YUZU_ROOM_STANDALONE) endif() if (ENABLE_QT) + add_definitions(-DYUZU_QT_WIDGETS) add_subdirectory(qt_common) add_subdirectory(yuzu) endif() diff --git a/src/frontend_common/firmware_manager.h b/src/frontend_common/firmware_manager.h index 20f3b41478..23fce59eb3 100644 --- a/src/frontend_common/firmware_manager.h +++ b/src/frontend_common/firmware_manager.h @@ -7,6 +7,7 @@ #include "common/common_types.h" #include "core/core.h" #include "core/file_sys/nca_metadata.h" +#include "core/file_sys/content_archive.h" #include "core/file_sys/registered_cache.h" #include "core/hle/service/filesystem/filesystem.h" #include @@ -143,6 +144,8 @@ inline std::pair GetFirmwareVersion return {firmware_data, result}; } + +// TODO(crueter): GET AS STRING } -#endif // FIRMWARE_MANAGER_H +#endif diff --git a/src/qt_common/CMakeLists.txt b/src/qt_common/CMakeLists.txt index d6ef427ba6..0c9bb54b11 100644 --- a/src/qt_common/CMakeLists.txt +++ b/src/qt_common/CMakeLists.txt @@ -1,6 +1,8 @@ # SPDX-FileCopyrightText: 2023 yuzu Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later +find_package(Qt6 REQUIRED COMPONENTS Core) + add_library(qt_common STATIC qt_common.h qt_common.cpp @@ -15,10 +17,12 @@ add_library(qt_common STATIC shared_translation.h qt_path_util.h qt_path_util.cpp qt_game_util.h qt_game_util.cpp + qt_frontend_util.h qt_frontend_util.cpp ) create_target_directory_groups(qt_common) -target_link_libraries(qt_common PUBLIC core Qt6::Core Qt6::Gui SimpleIni::SimpleIni QuaZip::QuaZip) +target_link_libraries(qt_common PUBLIC core Qt6::Widgets SimpleIni::SimpleIni QuaZip::QuaZip) +target_link_libraries(qt_common PRIVATE Qt6::Core) if (NOT WIN32) target_include_directories(qt_common PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS}) diff --git a/src/qt_common/qt_common.cpp b/src/qt_common/qt_common.cpp index 54c79c93e1..c7b75a196d 100644 --- a/src/qt_common/qt_common.cpp +++ b/src/qt_common/qt_common.cpp @@ -5,6 +5,7 @@ #include "common/fs/fs.h" #include "common/fs/path_util.h" #include "core/hle/service/filesystem/filesystem.h" +#include "frontend_common/firmware_manager.h" #include "uisettings.h" #include @@ -13,6 +14,10 @@ #include "core/frontend/emu_window.h" #include + +#include +#include "qt_frontend_util.h" + #include #if !defined(WIN32) && !defined(__APPLE__) @@ -22,7 +27,6 @@ #endif namespace QtCommon { - MetadataResult ResetMetadata() { if (!Common::FS::Exists(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) @@ -87,8 +91,24 @@ FirmwareInstallResult InstallFirmware( bool recursive, std::function QtProgressCallback, Core::System* system, - FileSys::VfsFilesystem* vfs) + FileSys::VfsFilesystem* vfs, + QWidget* parent) { + static constexpr const char* failedTitle = "Firmware Install Failed"; + static constexpr const char* successTitle = "Firmware Install Failed"; + static constexpr QMessageBox::StandardButtons buttons = QMessageBox::Ok; + + QMessageBox::Icon icon; + FirmwareInstallResult result; + + const auto ShowMessage = [&]() { + QtCommon::Frontend::ShowMessage(icon, + failedTitle, + GetFirmwareInstallResultString(result), + buttons, + parent); + }; + 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 @@ -121,14 +141,20 @@ FirmwareInstallResult InstallFirmware( } if (out.size() <= 0) { - return FirmwareInstallResult::NoNCAs; + result = FirmwareInstallResult::NoNCAs; + icon = QMessageBox::Warning; + ShowMessage(); + return result; } // Locate and erase the content of nand/system/Content/registered/*.nca, if any. auto sysnand_content_vdir = system->GetFileSystemController().GetSystemNANDContentDirectory(); if (sysnand_content_vdir->IsWritable() && !sysnand_content_vdir->CleanSubdirectoryRecursive("registered")) { - return FirmwareInstallResult::FailedDelete; + result = FirmwareInstallResult::FailedDelete; + icon = QMessageBox::Critical; + ShowMessage(); + return result; } LOG_INFO(Frontend, @@ -159,17 +185,35 @@ FirmwareInstallResult InstallFirmware( 20 + static_cast(((i) / static_cast(out.size())) * 70.0))) { - return FirmwareInstallResult::FailedCorrupted; + result = FirmwareInstallResult::FailedCorrupted; + icon = QMessageBox::Warning; + ShowMessage(); + return result; } } if (!success) { - return FirmwareInstallResult::FailedCopy; + result = FirmwareInstallResult::FailedCopy; + icon = QMessageBox::Critical; + ShowMessage(); + return result; } // Re-scan VFS for the newly placed firmware files. system->GetFileSystemController().CreateFactories(*vfs); - return FirmwareInstallResult::Success; + + const auto pair = FirmwareManager::GetFirmwareVersion(*system); + const auto firmware_data = pair.first; + const std::string display_version(firmware_data.display_version.data()); + + result = FirmwareInstallResult::Success; + QtCommon::Frontend::ShowMessage(QMessageBox::Information, + qApp->tr(successTitle), + qApp->tr(GetFirmwareInstallResultString(result)) + .arg(QString::fromStdString(display_version)), + buttons, + parent); + return result; } QString UnzipFirmwareToTmp(const QString& location) @@ -195,5 +239,4 @@ QString UnzipFirmwareToTmp(const QString& location) return qCacheDir; } - } // namespace QtCommon diff --git a/src/qt_common/qt_common.h b/src/qt_common/qt_common.h index b3ca99e65a..ef9b5577f1 100644 --- a/src/qt_common/qt_common.h +++ b/src/qt_common/qt_common.h @@ -13,7 +13,6 @@ #include namespace QtCommon { - static constexpr std::array METADATA_RESULTS = { "The operation completed successfully.", "The metadata cache couldn't be deleted. It might be in use or non-existent.", @@ -41,15 +40,14 @@ inline constexpr const char *GetResetMetadataResultString(MetadataResult result) return METADATA_RESULTS.at(static_cast(result)); } -static constexpr std::array FIRMWARE_RESULTS = { - "", - "", - "Unable to locate potential firmware NCA files", - "Failed to delete one or more firmware files.", - "One or more firmware files failed to copy into NAND.", - "Firmware installation cancelled, firmware may be in a bad state or corrupted." - "Restart Eden or re-install firmware." -}; +static constexpr std::array FIRMWARE_RESULTS + = {"Successfully installed firmware version %1", + "", + "Unable to locate potential firmware NCA files", + "Failed to delete one or more firmware files.", + "One or more firmware files failed to copy into NAND.", + "Firmware installation cancelled, firmware may be in a bad state or corrupted." + "Restart Eden or re-install firmware."}; enum class FirmwareInstallResult { Success, @@ -60,11 +58,13 @@ enum class FirmwareInstallResult { FailedCorrupted, }; -FirmwareInstallResult InstallFirmware(const QString &location, - bool recursive, - std::function QtProgressCallback, - Core::System *system, - FileSys::VfsFilesystem *vfs); +FirmwareInstallResult InstallFirmware( + const QString &location, + bool recursive, + std::function QtProgressCallback, + Core::System *system, + FileSys::VfsFilesystem *vfs, + QWidget *parent = nullptr); QString UnzipFirmwareToTmp(const QString &location); @@ -75,8 +75,6 @@ inline constexpr const char *GetFirmwareInstallResultString(FirmwareInstallResul Core::Frontend::WindowSystemType GetWindowSystemType(); -Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window); - - +Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow *window); } // namespace QtCommon #endif diff --git a/src/qt_common/qt_frontend_util.cpp b/src/qt_common/qt_frontend_util.cpp new file mode 100644 index 0000000000..6cbe82e000 --- /dev/null +++ b/src/qt_common/qt_frontend_util.cpp @@ -0,0 +1,25 @@ +#include "qt_frontend_util.h" + +namespace QtCommon::Frontend { +QMessageBox::StandardButton ShowMessage(QMessageBox::Icon icon, + const QString &title, + const QString &text, + QMessageBox::StandardButtons buttons, + QWidget *parent) +{ +#ifdef YUZU_QT_WIDGETS + QMessageBox *box = new QMessageBox(icon, title, text, buttons, parent); + return static_cast(box->exec()); +#endif +} + +QMessageBox::StandardButton ShowMessage(QMessageBox::Icon icon, + const char *title, + const char *text, + QMessageBox::StandardButtons buttons, + QWidget *parent) +{ + return ShowMessage(icon, qApp->tr(title), qApp->tr(text), buttons, parent); +} + +} // namespace QtCommon::Frontend diff --git a/src/qt_common/qt_frontend_util.h b/src/qt_common/qt_frontend_util.h new file mode 100644 index 0000000000..8508e29f18 --- /dev/null +++ b/src/qt_common/qt_frontend_util.h @@ -0,0 +1,29 @@ +#ifndef QT_FRONTEND_UTIL_H +#define QT_FRONTEND_UTIL_H + +#include +#include + +#ifdef YUZU_QT_WIDGETS +#include +#endif + +/** + * manages common functionality e.g. message boxes and such for Qt/QML + */ +namespace QtCommon::Frontend { +Q_NAMESPACE + +QMessageBox::StandardButton ShowMessage(QMessageBox::Icon icon, + const QString &title, + const QString &text, + QMessageBox::StandardButtons buttons = QMessageBox::NoButton, + QWidget *parent = nullptr); + +QMessageBox::StandardButton ShowMessage(QMessageBox::Icon icon, + const char *title, + const char *text, + QMessageBox::StandardButtons buttons = QMessageBox::NoButton, + QWidget *parent = nullptr); +} // namespace QtCommon::Frontend +#endif // QT_FRONTEND_UTIL_H diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index c5c0c82598..feb843fefb 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -2518,6 +2518,7 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target QDesktopServices::openUrl(QUrl::fromLocalFile(qpath)); } +// TODO(crueter): Transfer ts to showmessage void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) { if (!QtCommon::PathUtil::OpenShaderCache(program_id)) { QMessageBox::warning(this, tr("Error Opening Shader Cache"), tr("Failed to create or open shader cache for this title, ensure your app data directory has write permissions.")); @@ -2587,6 +2588,8 @@ static bool RomFSRawCopy(size_t total_size, size_t& read_size, QProgressDialog& } // 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 QString GMainWindow::GetGameListErrorRemoving(InstalledEntryType type) const { switch (type) { case InstalledEntryType::Game: @@ -4117,29 +4120,11 @@ void GMainWindow::InstallFirmware(const QString &location, bool recursive) return progress.wasCanceled(); }; - auto result = QtCommon::InstallFirmware(location, recursive, QtProgressCallback, system.get(), vfs.get()); - const char* resultMessage = QtCommon::GetFirmwareInstallResultString(result); + auto result = QtCommon::InstallFirmware(location, recursive, QtProgressCallback, system.get(), vfs.get(), this); progress.close(); - QMessageBox *box = new QMessageBox(QMessageBox::Icon::NoIcon, tr("Firmware Install Failed"), tr(resultMessage), QMessageBox::Ok, this); - - switch (result) { - case QtCommon::FirmwareInstallResult::NoNCAs: - case QtCommon::FirmwareInstallResult::FailedCorrupted: - box->setIcon(QMessageBox::Icon::Warning); - box->exec(); - return; - case QtCommon::FirmwareInstallResult::FailedCopy: - case QtCommon::FirmwareInstallResult::FailedDelete: - box->setIcon(QMessageBox::Icon::Critical); - box->exec(); - return; - default: - box->deleteLater(); - break; - } - + if (result != QtCommon::FirmwareInstallResult::Success) return; auto VerifyFirmwareCallback = [&](size_t total_size, size_t processed_size) { progress.setValue(90 + static_cast((processed_size * 10) / total_size)); From 490758c2ce7cc5abf36d5eb12b8ff27c5602d7c6 Mon Sep 17 00:00:00 2001 From: crueter Date: Wed, 23 Jul 2025 21:12:22 -0400 Subject: [PATCH 10/10] Fix license headers --- src/qt_common/qt_frontend_util.cpp | 3 +++ src/qt_common/qt_frontend_util.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/qt_common/qt_frontend_util.cpp b/src/qt_common/qt_frontend_util.cpp index 6cbe82e000..9a05c89928 100644 --- a/src/qt_common/qt_frontend_util.cpp +++ b/src/qt_common/qt_frontend_util.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + #include "qt_frontend_util.h" namespace QtCommon::Frontend { diff --git a/src/qt_common/qt_frontend_util.h b/src/qt_common/qt_frontend_util.h index 8508e29f18..8a38c033bf 100644 --- a/src/qt_common/qt_frontend_util.h +++ b/src/qt_common/qt_frontend_util.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + #ifndef QT_FRONTEND_UTIL_H #define QT_FRONTEND_UTIL_H