diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d4e486f68f..63c80ffd2b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,20 +22,20 @@ if (ENABLE_QT) endif() # Set compilation flags -if (MSVC) +if (MSVC AND NOT CXX_CLANG) set(CMAKE_CONFIGURATION_TYPES Debug Release CACHE STRING "" FORCE) # Silence "deprecation" warnings - add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS) + add_compile_definitions(_CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_DEPRECATE _SCL_SECURE_NO_WARNINGS) # Avoid windows.h junk - add_definitions(-DNOMINMAX) + add_compile_definitions(NOMINMAX) # Avoid windows.h from including some usually unused libs like winsocks.h, since this might cause some redefinition errors. - add_definitions(-DWIN32_LEAN_AND_MEAN) + add_compile_definitions(WIN32_LEAN_AND_MEAN) # Ensure that projects are built with Unicode support. - add_definitions(-DUNICODE -D_UNICODE) + add_compile_definitions(UNICODE _UNICODE) # /W4 - Level 4 warnings # /MP - Multi-threaded compilation @@ -69,10 +69,6 @@ if (MSVC) /external:anglebrackets # Treats all headers included by #include
, where the header file is enclosed in angle brackets (< >), as external headers /external:W0 # Sets the default warning level to 0 for external headers, effectively disabling warnings for them. - # Warnings - /W4 - /WX- - /we4062 # Enumerator 'identifier' in a switch of enum 'enumeration' is not handled /we4189 # 'identifier': local variable is initialized but not referenced /we4265 # 'class': class has virtual functions, but destructor is not virtual @@ -115,11 +111,16 @@ if (MSVC) set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG /MANIFEST:NO" CACHE STRING "" FORCE) set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/DEBUG /MANIFEST:NO /INCREMENTAL:NO /OPT:REF,ICF" CACHE STRING "" FORCE) else() - add_compile_options( - -fwrapv + if (NOT MSVC) + add_compile_options( + -fwrapv + ) + endif() + add_compile_options( -Werror=all -Werror=extra + -Werror=missing-declarations -Werror=shadow -Werror=unused @@ -142,9 +143,6 @@ else() -Wno-braced-scalar-init -Wno-unused-private-field -Wno-nullability-completeness - -Werror=shadow-uncaptured-local - -Werror=implicit-fallthrough - -Werror=type-limits ) endif() @@ -152,12 +150,12 @@ else() add_compile_options("-mcx16") endif() - if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL Clang) + if (APPLE AND CXX_CLANG) add_compile_options("-stdlib=libc++") endif() # GCC bugs - if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "11" AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "11" AND CXX_GCC) # These diagnostics would be great if they worked, but are just completely broken # and produce bogus errors on external libraries like fmt. add_compile_options( @@ -241,7 +239,6 @@ endif() if (ENABLE_QT) add_subdirectory(qt_common) add_subdirectory(Eden) - add_subdirectory(yuzu) endif() if (ENABLE_WEB_SERVICE) @@ -252,5 +249,3 @@ if (ANDROID) add_subdirectory(android/app/src/main/jni) target_include_directories(yuzu-android PRIVATE android/app/src/main) endif() - -include(GenerateDepHashes) diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index e1609e5957..4de159627f 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -20,554 +20,6 @@ #ifdef _WIN32 #include -<<<<<<< HEAD -||||||| parent of ee74fc3d5c (real vulkan device info (#1)) -#include -#include - -#ifdef HAVE_SDL2 -#include // For SDL ScreenSaver functions -#endif - -#include -#include "common/detached_tasks.h" -#include "common/fs/fs.h" -#include "common/fs/path_util.h" -#include "common/fs/ryujinx_compat.h" -#include "common/literals.h" -#include "common/logging/backend.h" -#include "common/logging/log.h" -#include "common/memory_detect.h" -#include "common/scm_rev.h" -#include "common/scope_exit.h" -#ifdef _WIN32 -#include "core/core_timing.h" -#include "common/windows/timer_resolution.h" -#endif -#ifdef ARCHITECTURE_x86_64 -#include "common/x64/cpu_detect.h" -#endif -#include "common/settings.h" -#include "core/core.h" -#include "core/crypto/key_manager.h" -#include "core/file_sys/card_image.h" -#include "core/file_sys/common_funcs.h" -#include "core/file_sys/content_archive.h" -#include "core/file_sys/control_metadata.h" -#include "core/file_sys/patch_manager.h" -#include "core/file_sys/registered_cache.h" -#include "core/file_sys/romfs.h" -#include "core/file_sys/savedata_factory.h" -#include "core/file_sys/submission_package.h" -#include "core/hle/kernel/k_process.h" -#include "core/hle/service/acc/profile_manager.h" -#include "core/hle/service/am/am.h" -#include "core/hle/service/filesystem/filesystem.h" -#include "core/hle/service/sm/sm.h" -#include "core/loader/loader.h" -#include "core/perf_stats.h" -#include "frontend_common/config.h" -#include "input_common/drivers/tas_input.h" -#include "input_common/drivers/virtual_amiibo.h" -#include "input_common/main.h" -#include "ui_main.h" -#include "yuzu/util/overlay_dialog.h" -#include "video_core/gpu.h" -#include "video_core/renderer_base.h" -#include "video_core/shader_notify.h" -#include "yuzu/about_dialog.h" -#include "yuzu/bootmanager.h" -#include "yuzu/compatibility_list.h" -#include "yuzu/configuration/configure_dialog.h" -#include "yuzu/configuration/configure_input_per_game.h" -#include "qt_common/config/qt_config.h" -#include "yuzu/debugger/console.h" -#include "yuzu/debugger/controller.h" -#include "yuzu/debugger/wait_tree.h" -#include "yuzu/data_dialog.h" -#include "yuzu/deps_dialog.h" -#include "yuzu/ryujinx_dialog.h" -#include "qt_common/discord/discord.h" -#include "yuzu/game_list.h" -#include "yuzu/game_list_p.h" -#include "yuzu/install_dialog.h" -#include "yuzu/loading_screen.h" -#include "yuzu/main.h" -#include "frontend_common/play_time_manager.h" -#include "yuzu/startup_checks.h" -#include "qt_common/config/uisettings.h" -#include "yuzu/util/clickable_label.h" -#include "yuzu/vk_device_info.h" - -#ifdef _WIN32 -#include -#include -#include -#ifdef _MSC_VER -#pragma comment(lib, "Dwmapi.lib") -#endif - -static inline void ApplyWindowsTitleBarDarkMode(HWND hwnd, bool enabled) { - if (!hwnd) - return; - BOOL val = enabled ? TRUE : FALSE; - // 20 = Win11/21H2+ - if (SUCCEEDED(DwmSetWindowAttribute(hwnd, 20, &val, sizeof(val)))) - return; - // 19 = pre-21H2 - DwmSetWindowAttribute(hwnd, 19, &val, sizeof(val)); -} - -static inline void ApplyDarkToTopLevel(QWidget* w, bool on) { - if (!w || !w->isWindow()) - return; - ApplyWindowsTitleBarDarkMode(reinterpret_cast(w->winId()), on); -} - -namespace { -struct TitlebarFilter final : QObject { - bool dark; - explicit TitlebarFilter(bool is_dark) : QObject(qApp), dark(is_dark) {} - - void setDark(bool is_dark) { - dark = is_dark; - } - - void onFocusChanged(QWidget*, QWidget* now) { - if (now) - ApplyDarkToTopLevel(now->window(), dark); - } - - bool eventFilter(QObject* obj, QEvent* ev) override { - if (auto* w = qobject_cast(obj)) { - switch (ev->type()) { - case QEvent::WinIdChange: - case QEvent::Show: - case QEvent::ShowToParent: - case QEvent::Polish: - case QEvent::WindowStateChange: - case QEvent::ZOrderChange: - ApplyDarkToTopLevel(w, dark); - break; - default: - break; - } - } - return QObject::eventFilter(obj, ev); - } -}; - -static TitlebarFilter* g_filter = nullptr; -static QMetaObject::Connection g_focusConn; - -} // namespace - -static void ApplyGlobalDarkTitlebar(bool is_dark) { - if (!g_filter) { - g_filter = new TitlebarFilter(is_dark); - qApp->installEventFilter(g_filter); - g_focusConn = QObject::connect(qApp, &QApplication::focusChanged, g_filter, - &TitlebarFilter::onFocusChanged); - } else { - g_filter->setDark(is_dark); - } - for (QWidget* w : QApplication::topLevelWidgets()) - ApplyDarkToTopLevel(w, is_dark); -} - -static void RemoveTitlebarFilter() { - if (!g_filter) - return; - qApp->removeEventFilter(g_filter); - QObject::disconnect(g_focusConn); - g_filter->deleteLater(); - g_filter = nullptr; -} - -#endif - -#ifdef YUZU_CRASH_DUMPS -#include "yuzu/breakpad.h" -#endif - -using namespace Common::Literals; - -#ifdef USE_DISCORD_PRESENCE -#include "qt_common/discord/discord_impl.h" -#endif - -#ifdef QT_STATICPLUGIN -Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin); -#endif - -#ifdef _WIN32 -#include -extern "C" { -// tells Nvidia and AMD drivers to use the dedicated GPU by default on laptops with switchable -// graphics -__declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001; -__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; -} -#endif - -constexpr int default_mouse_hide_timeout = 2500; -constexpr int default_input_update_timeout = 1; - -constexpr size_t CopyBufferSize = 1_MiB; - -/** - * "Callouts" are one-time instructional messages shown to the user. In the config settings, there - * is a bitfield "callout_flags" options, used to track if a message has already been shown to the - * user. This is 32-bits - if we have more than 32 callouts, we should retire and recycle old ones. - */ -enum class CalloutFlag : uint32_t { - DRDDeprecation = 0x2, -}; - -const int GMainWindow::max_recent_files_item; - -static void RemoveCachedContents() { - const auto cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir); - const auto offline_fonts = cache_dir / "fonts"; - const auto offline_manual = cache_dir / "offline_web_applet_manual"; - const auto offline_legal_information = cache_dir / "offline_web_applet_legal_information"; - const auto offline_system_data = cache_dir / "offline_web_applet_system_data"; - - Common::FS::RemoveDirRecursively(offline_fonts); - Common::FS::RemoveDirRecursively(offline_manual); - Common::FS::RemoveDirRecursively(offline_legal_information); - Common::FS::RemoveDirRecursively(offline_system_data); -} - -static void LogRuntimes() { -#ifdef _MSC_VER - // It is possible that the name of the dll will change. - // vcruntime140.dll is for 2015 and onwards - static constexpr char runtime_dll_name[] = "vcruntime140.dll"; - UINT sz = GetFileVersionInfoSizeA(runtime_dll_name, nullptr); - bool runtime_version_inspection_worked = false; - if (sz > 0) { - std::vector buf(sz); - if (GetFileVersionInfoA(runtime_dll_name, 0, sz, buf.data())) { - VS_FIXEDFILEINFO* pvi; - sz = sizeof(VS_FIXEDFILEINFO); - if (VerQueryValueA(buf.data(), "\\", reinterpret_cast(&pvi), &sz)) { - if (pvi->dwSignature == VS_FFI_SIGNATURE) { - runtime_version_inspection_worked = true; - LOG_INFO(Frontend, "MSVC Compiler: {} Runtime: {}.{}.{}.{}", _MSC_VER, - pvi->dwProductVersionMS >> 16, pvi->dwProductVersionMS & 0xFFFF, - pvi->dwProductVersionLS >> 16, pvi->dwProductVersionLS & 0xFFFF); - } - } - } - } - if (!runtime_version_inspection_worked) { - LOG_INFO(Frontend, "Unable to inspect {}", runtime_dll_name); - } -#endif - LOG_INFO(Frontend, "Qt Compile: {} Runtime: {}", QT_VERSION_STR, qVersion()); -} - -static QString PrettyProductName() { -#ifdef _WIN32 - // After Windows 10 Version 2004, Microsoft decided to switch to a different notation: 20H2 - // With that notation change they changed the registry key used to denote the current version - QSettings windows_registry( - QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), - QSettings::NativeFormat); - const QString release_id = windows_registry.value(QStringLiteral("ReleaseId")).toString(); - if (release_id == QStringLiteral("2009")) { - const u32 current_build = windows_registry.value(QStringLiteral("CurrentBuild")).toUInt(); - const QString display_version = - windows_registry.value(QStringLiteral("DisplayVersion")).toString(); - const u32 ubr = windows_registry.value(QStringLiteral("UBR")).toUInt(); - u32 version = 10; - if (current_build >= 22000) { - version = 11; - } - return QStringLiteral("Windows %1 Version %2 (Build %3.%4)") - .arg(QString::number(version), display_version, QString::number(current_build), - QString::number(ubr)); - } -#endif - return QSysInfo::prettyProductName(); -} - -#ifdef _WIN32 -======= -#include -#include - -#ifdef HAVE_SDL2 -#include // For SDL ScreenSaver functions -#endif - -#include -#include "common/detached_tasks.h" -#include "common/fs/fs.h" -#include "common/fs/path_util.h" -#include "common/fs/ryujinx_compat.h" -#include "common/literals.h" -#include "common/logging/backend.h" -#include "common/logging/log.h" -#include "common/memory_detect.h" -#include "common/scm_rev.h" -#include "common/scope_exit.h" -#ifdef _WIN32 -#include "core/core_timing.h" -#include "common/windows/timer_resolution.h" -#endif -#ifdef ARCHITECTURE_x86_64 -#include "common/x64/cpu_detect.h" -#endif -#include "common/settings.h" -#include "core/core.h" -#include "core/crypto/key_manager.h" -#include "core/file_sys/card_image.h" -#include "core/file_sys/common_funcs.h" -#include "core/file_sys/content_archive.h" -#include "core/file_sys/control_metadata.h" -#include "core/file_sys/patch_manager.h" -#include "core/file_sys/registered_cache.h" -#include "core/file_sys/romfs.h" -#include "core/file_sys/savedata_factory.h" -#include "core/file_sys/submission_package.h" -#include "core/hle/kernel/k_process.h" -#include "core/hle/service/acc/profile_manager.h" -#include "core/hle/service/am/am.h" -#include "core/hle/service/filesystem/filesystem.h" -#include "core/hle/service/sm/sm.h" -#include "core/loader/loader.h" -#include "core/perf_stats.h" -#include "frontend_common/config.h" -#include "input_common/drivers/tas_input.h" -#include "input_common/drivers/virtual_amiibo.h" -#include "input_common/main.h" -#include "ui_main.h" -#include "yuzu/util/overlay_dialog.h" -#include "video_core/gpu.h" -#include "video_core/renderer_base.h" -#include "video_core/shader_notify.h" -#include "yuzu/about_dialog.h" -#include "yuzu/bootmanager.h" -#include "yuzu/compatibility_list.h" -#include "yuzu/configuration/configure_dialog.h" -#include "yuzu/configuration/configure_input_per_game.h" -#include "qt_common/config/qt_config.h" -#include "yuzu/debugger/console.h" -#include "yuzu/debugger/controller.h" -#include "yuzu/debugger/wait_tree.h" -#include "yuzu/data_dialog.h" -#include "yuzu/deps_dialog.h" -#include "yuzu/ryujinx_dialog.h" -#include "qt_common/discord/discord.h" -#include "yuzu/game_list.h" -#include "yuzu/game_list_p.h" -#include "yuzu/install_dialog.h" -#include "yuzu/loading_screen.h" -#include "yuzu/main.h" -#include "frontend_common/play_time_manager.h" -#include "yuzu/startup_checks.h" -#include "qt_common/config/uisettings.h" -#include "yuzu/util/clickable_label.h" -#include "qt_common/util/vk_device_info.h" - -#ifdef _WIN32 -#include -#include -#include -#ifdef _MSC_VER -#pragma comment(lib, "Dwmapi.lib") -#endif - -static inline void ApplyWindowsTitleBarDarkMode(HWND hwnd, bool enabled) { - if (!hwnd) - return; - BOOL val = enabled ? TRUE : FALSE; - // 20 = Win11/21H2+ - if (SUCCEEDED(DwmSetWindowAttribute(hwnd, 20, &val, sizeof(val)))) - return; - // 19 = pre-21H2 - DwmSetWindowAttribute(hwnd, 19, &val, sizeof(val)); -} - -static inline void ApplyDarkToTopLevel(QWidget* w, bool on) { - if (!w || !w->isWindow()) - return; - ApplyWindowsTitleBarDarkMode(reinterpret_cast(w->winId()), on); -} - -namespace { -struct TitlebarFilter final : QObject { - bool dark; - explicit TitlebarFilter(bool is_dark) : QObject(qApp), dark(is_dark) {} - - void setDark(bool is_dark) { - dark = is_dark; - } - - void onFocusChanged(QWidget*, QWidget* now) { - if (now) - ApplyDarkToTopLevel(now->window(), dark); - } - - bool eventFilter(QObject* obj, QEvent* ev) override { - if (auto* w = qobject_cast(obj)) { - switch (ev->type()) { - case QEvent::WinIdChange: - case QEvent::Show: - case QEvent::ShowToParent: - case QEvent::Polish: - case QEvent::WindowStateChange: - case QEvent::ZOrderChange: - ApplyDarkToTopLevel(w, dark); - break; - default: - break; - } - } - return QObject::eventFilter(obj, ev); - } -}; - -static TitlebarFilter* g_filter = nullptr; -static QMetaObject::Connection g_focusConn; - -} // namespace - -static void ApplyGlobalDarkTitlebar(bool is_dark) { - if (!g_filter) { - g_filter = new TitlebarFilter(is_dark); - qApp->installEventFilter(g_filter); - g_focusConn = QObject::connect(qApp, &QApplication::focusChanged, g_filter, - &TitlebarFilter::onFocusChanged); - } else { - g_filter->setDark(is_dark); - } - for (QWidget* w : QApplication::topLevelWidgets()) - ApplyDarkToTopLevel(w, is_dark); -} - -static void RemoveTitlebarFilter() { - if (!g_filter) - return; - qApp->removeEventFilter(g_filter); - QObject::disconnect(g_focusConn); - g_filter->deleteLater(); - g_filter = nullptr; -} - -#endif - -#ifdef YUZU_CRASH_DUMPS -#include "yuzu/breakpad.h" -#endif - -using namespace Common::Literals; - -#ifdef USE_DISCORD_PRESENCE -#include "qt_common/discord/discord_impl.h" -#endif - -#ifdef QT_STATICPLUGIN -Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin); -#endif - -#ifdef _WIN32 -#include -extern "C" { -// tells Nvidia and AMD drivers to use the dedicated GPU by default on laptops with switchable -// graphics -__declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001; -__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; -} -#endif - -constexpr int default_mouse_hide_timeout = 2500; -constexpr int default_input_update_timeout = 1; - -constexpr size_t CopyBufferSize = 1_MiB; - -/** - * "Callouts" are one-time instructional messages shown to the user. In the config settings, there - * is a bitfield "callout_flags" options, used to track if a message has already been shown to the - * user. This is 32-bits - if we have more than 32 callouts, we should retire and recycle old ones. - */ -enum class CalloutFlag : uint32_t { - DRDDeprecation = 0x2, -}; - -const int GMainWindow::max_recent_files_item; - -static void RemoveCachedContents() { - const auto cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir); - const auto offline_fonts = cache_dir / "fonts"; - const auto offline_manual = cache_dir / "offline_web_applet_manual"; - const auto offline_legal_information = cache_dir / "offline_web_applet_legal_information"; - const auto offline_system_data = cache_dir / "offline_web_applet_system_data"; - - Common::FS::RemoveDirRecursively(offline_fonts); - Common::FS::RemoveDirRecursively(offline_manual); - Common::FS::RemoveDirRecursively(offline_legal_information); - Common::FS::RemoveDirRecursively(offline_system_data); -} - -static void LogRuntimes() { -#ifdef _MSC_VER - // It is possible that the name of the dll will change. - // vcruntime140.dll is for 2015 and onwards - static constexpr char runtime_dll_name[] = "vcruntime140.dll"; - UINT sz = GetFileVersionInfoSizeA(runtime_dll_name, nullptr); - bool runtime_version_inspection_worked = false; - if (sz > 0) { - std::vector buf(sz); - if (GetFileVersionInfoA(runtime_dll_name, 0, sz, buf.data())) { - VS_FIXEDFILEINFO* pvi; - sz = sizeof(VS_FIXEDFILEINFO); - if (VerQueryValueA(buf.data(), "\\", reinterpret_cast(&pvi), &sz)) { - if (pvi->dwSignature == VS_FFI_SIGNATURE) { - runtime_version_inspection_worked = true; - LOG_INFO(Frontend, "MSVC Compiler: {} Runtime: {}.{}.{}.{}", _MSC_VER, - pvi->dwProductVersionMS >> 16, pvi->dwProductVersionMS & 0xFFFF, - pvi->dwProductVersionLS >> 16, pvi->dwProductVersionLS & 0xFFFF); - } - } - } - } - if (!runtime_version_inspection_worked) { - LOG_INFO(Frontend, "Unable to inspect {}", runtime_dll_name); - } -#endif - LOG_INFO(Frontend, "Qt Compile: {} Runtime: {}", QT_VERSION_STR, qVersion()); -} - -static QString PrettyProductName() { -#ifdef _WIN32 - // After Windows 10 Version 2004, Microsoft decided to switch to a different notation: 20H2 - // With that notation change they changed the registry key used to denote the current version - QSettings windows_registry( - QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), - QSettings::NativeFormat); - const QString release_id = windows_registry.value(QStringLiteral("ReleaseId")).toString(); - if (release_id == QStringLiteral("2009")) { - const u32 current_build = windows_registry.value(QStringLiteral("CurrentBuild")).toUInt(); - const QString display_version = - windows_registry.value(QStringLiteral("DisplayVersion")).toString(); - const u32 ubr = windows_registry.value(QStringLiteral("UBR")).toUInt(); - u32 version = 10; - if (current_build >= 22000) { - version = 11; - } - return QStringLiteral("Windows %1 Version %2 (Build %3.%4)") - .arg(QString::number(version), display_version, QString::number(current_build), - QString::number(ubr)); - } -#endif - return QSysInfo::prettyProductName(); -} - -#ifdef _WIN32 ->>>>>>> ee74fc3d5c (real vulkan device info (#1)) static void OverrideWindowsFont() { // Qt5 chooses these fonts on Windows and they have fairly ugly alphanumeric/cyrillic characters // Asking to use "MS Shell Dlg 2" gives better other chars while leaving the Chinese Characters.