diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/common/fs/fs_util.cpp | 4 | ||||
-rw-r--r-- | src/common/fs/fs_util.h | 11 | ||||
-rw-r--r-- | src/common/settings.h | 11 | ||||
-rw-r--r-- | src/video_core/texture_cache/render_targets.h | 6 | ||||
-rw-r--r-- | src/yuzu/applets/qt_web_browser.cpp | 15 | ||||
-rw-r--r-- | src/yuzu/applets/qt_web_browser.h | 3 | ||||
-rw-r--r-- | src/yuzu/applets/qt_web_browser_scripts.h | 6 | ||||
-rw-r--r-- | src/yuzu/configuration/config.cpp | 5 | ||||
-rw-r--r-- | src/yuzu/configuration/config.h | 1 | ||||
-rw-r--r-- | src/yuzu/configuration/configuration_shared.cpp | 14 | ||||
-rw-r--r-- | src/yuzu/configuration/configuration_shared.h | 15 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_cpu.cpp | 17 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_graphics.cpp | 8 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_graphics_advanced.cpp | 20 | ||||
-rw-r--r-- | src/yuzu/main.cpp | 8 | ||||
-rw-r--r-- | src/yuzu_cmd/emu_window/emu_window_sdl2.cpp | 4 |
17 files changed, 82 insertions, 68 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 857550e71..d98ba7767 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -496,7 +496,7 @@ endif() # Ensure libusb is properly configured (based on dolphin libusb include) if(NOT APPLE AND NOT YUZU_USE_BUNDLED_LIBUSB) include(FindPkgConfig) - if (PKG_CONFIG_FOUND) + if (PKG_CONFIG_FOUND AND NOT CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD") pkg_check_modules(LIBUSB QUIET libusb-1.0>=1.0.24) else() find_package(LibUSB) diff --git a/src/common/fs/fs_util.cpp b/src/common/fs/fs_util.cpp index 357cf5855..9f8671982 100644 --- a/src/common/fs/fs_util.cpp +++ b/src/common/fs/fs_util.cpp @@ -20,6 +20,10 @@ std::string ToUTF8String(std::u8string_view u8_string) { return std::string{u8_string.begin(), u8_string.end()}; } +std::string BufferToUTF8String(std::span<const u8> buffer) { + return std::string{buffer.begin(), std::ranges::find(buffer, u8{0})}; +} + std::string PathToUTF8String(const std::filesystem::path& path) { return ToUTF8String(path.u8string()); } diff --git a/src/common/fs/fs_util.h b/src/common/fs/fs_util.h index ec9950ee7..1ec82eb35 100644 --- a/src/common/fs/fs_util.h +++ b/src/common/fs/fs_util.h @@ -47,6 +47,17 @@ concept IsChar = std::same_as<T, char>; [[nodiscard]] std::string ToUTF8String(std::u8string_view u8_string); /** + * Converts a buffer of bytes to a UTF8-encoded std::string. + * This converts from the start of the buffer until the first encountered null-terminator. + * If no null-terminator is found, this converts the entire buffer instead. + * + * @param buffer Buffer of bytes + * + * @returns UTF-8 encoded std::string. + */ +[[nodiscard]] std::string BufferToUTF8String(std::span<const u8> buffer); + +/** * Converts a filesystem path to a UTF-8 encoded std::string. * * @param path Filesystem path diff --git a/src/common/settings.h b/src/common/settings.h index d8730f515..cfc1ab46f 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -42,6 +42,11 @@ enum class CPUAccuracy : u32 { Unsafe = 2, }; +enum class FullscreenMode : u32 { + Borderless = 0, + Exclusive = 1, +}; + /** The BasicSetting class is a simple resource manager. It defines a label and default value * alongside the actual value of the setting for simpler and less-error prone use with frontend * configurations. Setting a default value and label is required, though subclasses may deviate from @@ -322,11 +327,11 @@ struct Values { Setting<u16> resolution_factor{1, "resolution_factor"}; // *nix platforms may have issues with the borderless windowed fullscreen mode. // Default to exclusive fullscreen on these platforms for now. - Setting<int> fullscreen_mode{ + Setting<FullscreenMode> fullscreen_mode{ #ifdef _WIN32 - 0, + FullscreenMode::Borderless, #else - 1, + FullscreenMode::Exclusive, #endif "fullscreen_mode"}; Setting<int> aspect_ratio{0, "aspect_ratio"}; diff --git a/src/video_core/texture_cache/render_targets.h b/src/video_core/texture_cache/render_targets.h index 9b9544b07..0cb227d69 100644 --- a/src/video_core/texture_cache/render_targets.h +++ b/src/video_core/texture_cache/render_targets.h @@ -24,10 +24,10 @@ struct RenderTargets { return std::ranges::any_of(color_buffer_ids, contains) || contains(depth_buffer_id); } - std::array<ImageViewId, NUM_RT> color_buffer_ids; - ImageViewId depth_buffer_id; + std::array<ImageViewId, NUM_RT> color_buffer_ids{}; + ImageViewId depth_buffer_id{}; std::array<u8, NUM_RT> draw_buffers{}; - Extent2D size; + Extent2D size{}; }; } // namespace VideoCommon diff --git a/src/yuzu/applets/qt_web_browser.cpp b/src/yuzu/applets/qt_web_browser.cpp index b112dd7b0..652d99570 100644 --- a/src/yuzu/applets/qt_web_browser.cpp +++ b/src/yuzu/applets/qt_web_browser.cpp @@ -107,6 +107,7 @@ void QtNXWebEngineView::LoadLocalWebPage(const std::string& main_url, is_local = true; LoadExtractedFonts(); + FocusFirstLinkElement(); SetUserAgent(UserAgent::WebApplet); SetFinished(false); SetExitReason(Service::AM::Applets::WebExitReason::EndButtonPressed); @@ -121,6 +122,7 @@ void QtNXWebEngineView::LoadExternalWebPage(const std::string& main_url, const std::string& additional_args) { is_local = false; + FocusFirstLinkElement(); SetUserAgent(UserAgent::WebApplet); SetFinished(false); SetExitReason(Service::AM::Applets::WebExitReason::EndButtonPressed); @@ -208,7 +210,7 @@ void QtNXWebEngineView::HandleWindowFooterButtonPressedOnce() { if (input_interpreter->IsButtonPressedOnce(button)) { page()->runJavaScript( QStringLiteral("yuzu_key_callbacks[%1] == null;").arg(static_cast<u8>(button)), - [&](const QVariant& variant) { + [this, button](const QVariant& variant) { if (variant.toBool()) { switch (button) { case HIDButton::A: @@ -364,6 +366,17 @@ void QtNXWebEngineView::LoadExtractedFonts() { Qt::QueuedConnection); } +void QtNXWebEngineView::FocusFirstLinkElement() { + QWebEngineScript focus_link_element; + + focus_link_element.setName(QStringLiteral("focus_link_element.js")); + focus_link_element.setSourceCode(QString::fromStdString(FOCUS_LINK_ELEMENT_SCRIPT)); + focus_link_element.setWorldId(QWebEngineScript::MainWorld); + focus_link_element.setInjectionPoint(QWebEngineScript::Deferred); + focus_link_element.setRunsOnSubFrames(true); + default_profile->scripts()->insert(focus_link_element); +} + #endif QtWebBrowser::QtWebBrowser(GMainWindow& main_window) { diff --git a/src/yuzu/applets/qt_web_browser.h b/src/yuzu/applets/qt_web_browser.h index 7ad07409f..7e9f703fc 100644 --- a/src/yuzu/applets/qt_web_browser.h +++ b/src/yuzu/applets/qt_web_browser.h @@ -161,6 +161,9 @@ private: /// Loads the extracted fonts using JavaScript. void LoadExtractedFonts(); + /// Brings focus to the first available link element. + void FocusFirstLinkElement(); + InputCommon::InputSubsystem* input_subsystem; std::unique_ptr<UrlRequestInterceptor> url_interceptor; diff --git a/src/yuzu/applets/qt_web_browser_scripts.h b/src/yuzu/applets/qt_web_browser_scripts.h index 992837a85..c4ba8d40f 100644 --- a/src/yuzu/applets/qt_web_browser_scripts.h +++ b/src/yuzu/applets/qt_web_browser_scripts.h @@ -73,6 +73,12 @@ constexpr char LOAD_NX_FONT[] = R"( })(); )"; +constexpr char FOCUS_LINK_ELEMENT_SCRIPT[] = R"( +if (document.getElementsByTagName("a").length > 0) { + document.getElementsByTagName("a")[0].focus(); +} +)"; + constexpr char GAMEPAD_SCRIPT[] = R"( window.addEventListener("gamepadconnected", function(e) { console.log("Gamepad connected at index %d: %s. %d buttons, %d axes.", diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 72027e773..ecd5dfac1 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -1332,7 +1332,10 @@ void Config::SaveRendererValues() { static_cast<u32>(Settings::values.renderer_backend.GetDefault()), Settings::values.renderer_backend.UsingGlobal()); WriteGlobalSetting(Settings::values.vulkan_device); - WriteGlobalSetting(Settings::values.fullscreen_mode); + WriteSetting(QString::fromStdString(Settings::values.fullscreen_mode.GetLabel()), + static_cast<u32>(Settings::values.fullscreen_mode.GetValue(global)), + static_cast<u32>(Settings::values.fullscreen_mode.GetDefault()), + Settings::values.fullscreen_mode.UsingGlobal()); WriteGlobalSetting(Settings::values.aspect_ratio); WriteGlobalSetting(Settings::values.max_anisotropy); WriteGlobalSetting(Settings::values.use_speed_limit); diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h index 4bbb9f1cd..c1d7feb9f 100644 --- a/src/yuzu/configuration/config.h +++ b/src/yuzu/configuration/config.h @@ -181,5 +181,6 @@ private: // These metatype declarations cannot be in common/settings.h because core is devoid of QT Q_DECLARE_METATYPE(Settings::CPUAccuracy); Q_DECLARE_METATYPE(Settings::GPUAccuracy); +Q_DECLARE_METATYPE(Settings::FullscreenMode); Q_DECLARE_METATYPE(Settings::RendererBackend); Q_DECLARE_METATYPE(Settings::ShaderBackend); diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index 096e42e94..251aab912 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -25,20 +25,6 @@ void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<bool>* setting, } } -void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<int>* setting, - const QComboBox* combobox) { - if (Settings::IsConfiguringGlobal() && setting->UsingGlobal()) { - setting->SetValue(combobox->currentIndex()); - } else if (!Settings::IsConfiguringGlobal()) { - if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { - setting->SetGlobal(true); - } else { - setting->SetGlobal(false); - setting->SetValue(combobox->currentIndex() - ConfigurationShared::USE_GLOBAL_OFFSET); - } - } -} - void ConfigurationShared::SetPerGameSetting(QCheckBox* checkbox, const Settings::Setting<bool>* setting) { if (setting->UsingGlobal()) { diff --git a/src/yuzu/configuration/configuration_shared.h b/src/yuzu/configuration/configuration_shared.h index 1e0ef01ca..5423dbc92 100644 --- a/src/yuzu/configuration/configuration_shared.h +++ b/src/yuzu/configuration/configuration_shared.h @@ -28,7 +28,20 @@ enum class CheckState { // ApplyPerGameSetting, given a Settings::Setting and a Qt UI element, properly applies a Setting void ApplyPerGameSetting(Settings::Setting<bool>* setting, const QCheckBox* checkbox, const CheckState& tracker); -void ApplyPerGameSetting(Settings::Setting<int>* setting, const QComboBox* combobox); +template <typename Type> +void ApplyPerGameSetting(Settings::Setting<Type>* setting, const QComboBox* combobox) { + if (Settings::IsConfiguringGlobal() && setting->UsingGlobal()) { + setting->SetValue(static_cast<Type>(combobox->currentIndex())); + } else if (!Settings::IsConfiguringGlobal()) { + if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { + setting->SetGlobal(true); + } else { + setting->SetGlobal(false); + setting->SetValue(static_cast<Type>(combobox->currentIndex() - + ConfigurationShared::USE_GLOBAL_OFFSET)); + } + } +} // Sets a Qt UI element given a Settings::Setting void SetPerGameSetting(QCheckBox* checkbox, const Settings::Setting<bool>* setting); diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp index 8d7171487..784b6484e 100644 --- a/src/yuzu/configuration/configure_cpu.cpp +++ b/src/yuzu/configuration/configure_cpu.cpp @@ -65,6 +65,7 @@ void ConfigureCpu::UpdateGroup(int index) { } void ConfigureCpu::ApplyConfiguration() { + ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpu_accuracy, ui->accuracy); ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_unfuse_fma, ui->cpuopt_unsafe_unfuse_fma, cpuopt_unsafe_unfuse_fma); @@ -80,22 +81,6 @@ void ConfigureCpu::ApplyConfiguration() { ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_fastmem_check, ui->cpuopt_unsafe_fastmem_check, cpuopt_unsafe_fastmem_check); - - if (Settings::IsConfiguringGlobal()) { - // Guard if during game and set to game-specific value - if (Settings::values.cpu_accuracy.UsingGlobal()) { - Settings::values.cpu_accuracy.SetValue( - static_cast<Settings::CPUAccuracy>(ui->accuracy->currentIndex())); - } - } else { - if (ui->accuracy->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { - Settings::values.cpu_accuracy.SetGlobal(true); - } else { - Settings::values.cpu_accuracy.SetGlobal(false); - Settings::values.cpu_accuracy.SetValue(static_cast<Settings::CPUAccuracy>( - ui->accuracy->currentIndex() - ConfigurationShared::USE_GLOBAL_OFFSET)); - } - } } void ConfigureCpu::changeEvent(QEvent* event) { diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 1bc477c96..37e896258 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp @@ -98,7 +98,8 @@ void ConfigureGraphics::SetConfiguration() { if (Settings::IsConfiguringGlobal()) { ui->api->setCurrentIndex(static_cast<int>(Settings::values.renderer_backend.GetValue())); - ui->fullscreen_mode_combobox->setCurrentIndex(Settings::values.fullscreen_mode.GetValue()); + ui->fullscreen_mode_combobox->setCurrentIndex( + static_cast<int>(Settings::values.fullscreen_mode.GetValue())); ui->aspect_ratio_combobox->setCurrentIndex(Settings::values.aspect_ratio.GetValue()); } else { ConfigurationShared::SetPerGameSetting(ui->api, &Settings::values.renderer_backend); @@ -310,8 +311,9 @@ void ConfigureGraphics::SetupPerGameUI() { ConfigurationShared::SetColoredComboBox(ui->aspect_ratio_combobox, ui->ar_label, Settings::values.aspect_ratio.GetValue(true)); - ConfigurationShared::SetColoredComboBox(ui->fullscreen_mode_combobox, ui->fullscreen_mode_label, - Settings::values.fullscreen_mode.GetValue(true)); + ConfigurationShared::SetColoredComboBox( + ui->fullscreen_mode_combobox, ui->fullscreen_mode_label, + static_cast<int>(Settings::values.fullscreen_mode.GetValue(true))); ConfigurationShared::InsertGlobalItem( ui->api, static_cast<int>(Settings::values.renderer_backend.GetValue(true))); } diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp index 38276feb1..a31b8e192 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.cpp +++ b/src/yuzu/configuration/configure_graphics_advanced.cpp @@ -48,11 +48,7 @@ void ConfigureGraphicsAdvanced::SetConfiguration() { } void ConfigureGraphicsAdvanced::ApplyConfiguration() { - // Subtract 2 if configuring per-game (separator and "use global configuration" take 2 slots) - const auto gpu_accuracy = static_cast<Settings::GPUAccuracy>( - ui->gpu_accuracy->currentIndex() - - ((Settings::IsConfiguringGlobal()) ? 0 : ConfigurationShared::USE_GLOBAL_OFFSET)); - + ConfigurationShared::ApplyPerGameSetting(&Settings::values.gpu_accuracy, ui->gpu_accuracy); ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy, ui->anisotropic_filtering_combobox); ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync, ui->use_vsync, use_vsync); @@ -63,20 +59,6 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() { use_caches_gc); ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_fast_gpu_time, ui->use_fast_gpu_time, use_fast_gpu_time); - - if (Settings::IsConfiguringGlobal()) { - // Must guard in case of a during-game configuration when set to be game-specific. - if (Settings::values.gpu_accuracy.UsingGlobal()) { - Settings::values.gpu_accuracy.SetValue(gpu_accuracy); - } - } else { - if (ui->gpu_accuracy->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { - Settings::values.gpu_accuracy.SetGlobal(true); - } else { - Settings::values.gpu_accuracy.SetGlobal(false); - Settings::values.gpu_accuracy.SetValue(gpu_accuracy); - } - } } void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) { diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index e172d2ff4..9544f0fb0 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -2513,7 +2513,7 @@ void GMainWindow::ShowFullscreen() { ui.menubar->hide(); statusBar()->hide(); - if (Settings::values.fullscreen_mode.GetValue() == 1) { + if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) { showFullScreen(); return; } @@ -2528,7 +2528,7 @@ void GMainWindow::ShowFullscreen() { } else { UISettings::values.renderwindow_geometry = render_window->saveGeometry(); - if (Settings::values.fullscreen_mode.GetValue() == 1) { + if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) { render_window->showFullScreen(); return; } @@ -2545,7 +2545,7 @@ void GMainWindow::ShowFullscreen() { void GMainWindow::HideFullscreen() { if (ui.action_Single_Window_Mode->isChecked()) { - if (Settings::values.fullscreen_mode.GetValue() == 1) { + if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) { showNormal(); restoreGeometry(UISettings::values.geometry); } else { @@ -2559,7 +2559,7 @@ void GMainWindow::HideFullscreen() { statusBar()->setVisible(ui.action_Show_Status_Bar->isChecked()); ui.menubar->show(); } else { - if (Settings::values.fullscreen_mode.GetValue() == 1) { + if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) { render_window->showNormal(); render_window->restoreGeometry(UISettings::values.renderwindow_geometry); } else { diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index 353e51ea7..ea3e0ada4 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp @@ -124,7 +124,7 @@ void EmuWindow_SDL2::OnResize() { void EmuWindow_SDL2::Fullscreen() { switch (Settings::values.fullscreen_mode.GetValue()) { - case 1: // Exclusive fullscreen + case Settings::FullscreenMode::Exclusive: // Set window size to render size before entering fullscreen -- SDL does not resize to // display dimensions in this mode. // TODO: Multiply the window size by resolution_factor (for both docked modes) @@ -140,7 +140,7 @@ void EmuWindow_SDL2::Fullscreen() { LOG_ERROR(Frontend, "Fullscreening failed: {}", SDL_GetError()); LOG_INFO(Frontend, "Attempting to use borderless fullscreen..."); [[fallthrough]]; - case 0: // Borderless window + case Settings::FullscreenMode::Borderless: if (SDL_SetWindowFullscreen(render_window, SDL_WINDOW_FULLSCREEN_DESKTOP) == 0) { return; } |