From d9275b77570562a94c726f3fe630886c96850396 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Tue, 15 Aug 2023 22:42:28 -0400 Subject: [PATCH] yuzu-qt: Enable specifying screenshot resolution --- src/yuzu/bootmanager.cpp | 16 +++- src/yuzu/configuration/configure_ui.cpp | 97 ++++++++++++++++++++++++- src/yuzu/configuration/configure_ui.ui | 51 +++++++++++++ src/yuzu/uisettings.cpp | 31 ++++++++ src/yuzu/uisettings.h | 10 +++ 5 files changed, 200 insertions(+), 5 deletions(-) diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index bdd1497b5..593e59e8e 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -11,6 +11,8 @@ #include #include +#include "common/settings_enums.h" +#include "uisettings.h" #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA #include #include @@ -924,7 +926,19 @@ void GRenderWindow::CaptureScreenshot(const QString& screenshot_path) { return; } - const Layout::FramebufferLayout layout{Layout::FrameLayoutFromResolutionScale(res_scale)}; + const Layout::FramebufferLayout layout{[res_scale]() { + if (UISettings::values.screenshot_height.GetValue() == 0 && + UISettings::values.screenshot_aspect_ratio.GetValue() == + Settings::ScreenshotAspectRatio::Auto) { + return Layout::FrameLayoutFromResolutionScale(res_scale); + } + const u32 height = UISettings::values.screenshot_height.GetValue(); + const u32 width = UISettings::CalculateWidth( + height, UISettings::ConvertScreenshotRatioToRatio( + UISettings::values.screenshot_aspect_ratio.GetValue())); + return Layout::DefaultFrameLayout(width, height); + }()}; + screenshot_image = QImage(QSize(layout.width, layout.height), QImage::Format_RGB32); renderer.RequestScreenshot( screenshot_image.bits(), diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp index 2ebb80302..3c99c5709 100644 --- a/src/yuzu/configuration/configure_ui.cpp +++ b/src/yuzu/configuration/configure_ui.cpp @@ -1,18 +1,30 @@ // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include -#include -#include +#include "yuzu/configuration/configure_ui.h" +#include +#include +#include +#include +#include + +#include +#include +#include #include +#include +#include +#include +#include + #include "common/common_types.h" #include "common/fs/path_util.h" #include "common/logging/log.h" #include "common/settings.h" +#include "common/settings_enums.h" #include "core/core.h" #include "ui_configure_ui.h" -#include "yuzu/configuration/configure_ui.h" #include "yuzu/uisettings.h" namespace { @@ -54,6 +66,52 @@ QString GetTranslatedRowTextName(size_t index) { } } // Anonymous namespace +constexpr static std::array, 5> + screenshot_aspect_ratio_translations = { + std::pair{Settings::ScreenshotAspectRatio::Auto, "Auto"}, + std::pair{Settings::ScreenshotAspectRatio::R16_9, "16:9"}, + std::pair{Settings::ScreenshotAspectRatio::R4_3, "4:3"}, + std::pair{Settings::ScreenshotAspectRatio::R21_9, "21:9"}, + std::pair{Settings::ScreenshotAspectRatio::R16_10, "16:10"}, +}; + +static void PopulateAspectRatioComboBox(QComboBox* screenshot_aspect_ratio) { + screenshot_aspect_ratio->clear(); + + for (const auto& [value, name] : screenshot_aspect_ratio_translations) { + screenshot_aspect_ratio->addItem(QString::fromStdString(name)); + } +} + +static void PopulateResolutionComboBox(QComboBox* screenshot_height) { + screenshot_height->clear(); + + const auto& enumeration = + Settings::EnumMetadata::Canonicalizations(); + Settings::ResolutionScalingInfo info{}; + std::set resolutions{}; + for (const auto& [name, value] : enumeration) { + Settings::TranslateResolutionInfo(value, info); + u32 height_undocked = 720 * info.up_factor; + u32 height_docked = 1080 * info.up_factor; + resolutions.emplace(height_undocked); + resolutions.emplace(height_docked); + } + + screenshot_height->addItem(QStringLiteral("0")); + for (const auto res : resolutions) { + screenshot_height->addItem(QString::fromStdString(std::to_string(res))); + } +} + +static u32 HeightToInt(const QString& height) { + try { + return std::stoi(height.toStdString()); + } catch (std::invalid_argument& e) { + return 0; + } +} + ConfigureUi::ConfigureUi(Core::System& system_, QWidget* parent) : QWidget(parent), ui{std::make_unique()}, system{system_} { ui->setupUi(this); @@ -68,6 +126,9 @@ ConfigureUi::ConfigureUi(Core::System& system_, QWidget* parent) InitializeIconSizeComboBox(); InitializeRowComboBoxes(); + PopulateAspectRatioComboBox(ui->screenshot_aspect_ratio); + PopulateResolutionComboBox(ui->screenshot_height); + SetConfiguration(); // Force game list reload if any of the relevant settings are changed. @@ -104,6 +165,25 @@ ConfigureUi::ConfigureUi(Core::System& system_, QWidget* parent) ui->screenshot_path_edit->setText(dir); } }); + + const auto update_height_text = [this]() { + const auto index = ui->screenshot_aspect_ratio->currentIndex(); + const Settings::AspectRatio ratio = UISettings::ConvertScreenshotRatioToRatio( + screenshot_aspect_ratio_translations[index].first); + const auto height = HeightToInt(ui->screenshot_height->currentText()); + const auto width = UISettings::CalculateWidth(height, ratio); + if (height == 0) { + ui->screenshot_width->setText(QString::fromStdString(fmt::format("Auto"))); + } else { + ui->screenshot_width->setText(QString::fromStdString(std::to_string(width))); + } + }; + + connect(ui->screenshot_aspect_ratio, QOverload::of(&QComboBox::currentIndexChanged), + update_height_text); + connect(ui->screenshot_height, &QComboBox::currentTextChanged, update_height_text); + + update_height_text(); } ConfigureUi::~ConfigureUi() = default; @@ -123,6 +203,15 @@ void ConfigureUi::ApplyConfiguration() { UISettings::values.enable_screenshot_save_as = ui->enable_screenshot_save_as->isChecked(); Common::FS::SetYuzuPath(Common::FS::YuzuPath::ScreenshotsDir, ui->screenshot_path_edit->text().toStdString()); + + const auto ratio = + screenshot_aspect_ratio_translations[ui->screenshot_aspect_ratio->currentIndex()].first; + UISettings::values.screenshot_aspect_ratio.SetValue(ratio); + const u32 height = HeightToInt(ui->screenshot_height->currentText()); + UISettings::values.screenshot_height.SetValue(height); + UISettings::values.screenshot_width.SetValue( + UISettings::CalculateWidth(height, UISettings::ConvertScreenshotRatioToRatio(ratio))); + system.ApplySettings(); } diff --git a/src/yuzu/configuration/configure_ui.ui b/src/yuzu/configuration/configure_ui.ui index 10bb27312..906fdd5b3 100644 --- a/src/yuzu/configuration/configure_ui.ui +++ b/src/yuzu/configuration/configure_ui.ui @@ -201,6 +201,57 @@ + + + + 6 + + + + + Resolution: + + + + + + + + + + Aspect Ratio: + + + + + + + + + true + + + + 0 + 0 + + + + true + + + + + + + true + + + + + + + diff --git a/src/yuzu/uisettings.cpp b/src/yuzu/uisettings.cpp index f03dc01dd..3ab0d1b45 100644 --- a/src/yuzu/uisettings.cpp +++ b/src/yuzu/uisettings.cpp @@ -36,4 +36,35 @@ bool IsDarkTheme() { Values values = {}; +u32 CalculateWidth(u32 height, Settings::AspectRatio ratio) { + switch (ratio) { + case Settings::AspectRatio::R4_3: + return height * 4 / 3; + case Settings::AspectRatio::R21_9: + return height * 21 / 9; + case Settings::AspectRatio::R16_10: + return height * 16 / 10; + case Settings::AspectRatio::R16_9: + case Settings::AspectRatio::Stretch: + break; + } + return height * 16 / 9; +} + +Settings::AspectRatio ConvertScreenshotRatioToRatio(Settings::ScreenshotAspectRatio ratio) { + switch (ratio) { + case Settings::ScreenshotAspectRatio::Auto: + return Settings::values.aspect_ratio.GetValue(); + case Settings::ScreenshotAspectRatio::R16_9: + return Settings::AspectRatio::R16_9; + case Settings::ScreenshotAspectRatio::R4_3: + return Settings::AspectRatio::R4_3; + case Settings::ScreenshotAspectRatio::R21_9: + return Settings::AspectRatio::R21_9; + case Settings::ScreenshotAspectRatio::R16_10: + return Settings::AspectRatio::R16_10; + } + return Settings::AspectRatio::R16_9; +} + } // namespace UISettings diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h index c9c89cee4..7b5d630d7 100644 --- a/src/yuzu/uisettings.h +++ b/src/yuzu/uisettings.h @@ -13,6 +13,7 @@ #include #include "common/common_types.h" #include "common/settings.h" +#include "common/settings_enums.h" using Settings::Category; using Settings::Setting; @@ -127,8 +128,14 @@ struct Values { // logging Setting show_console{linkage, false, "showConsole", Category::Ui}; + // Screenshots Setting enable_screenshot_save_as{linkage, true, "enable_screenshot_save_as", Category::Screenshots}; + Setting screenshot_height{linkage, 0, "screenshot_height", Category::Screenshots}; + Setting screenshot_width{linkage, 0, "screenshot_width", Category::Screenshots}; + Setting screenshot_aspect_ratio{ + linkage, Settings::ScreenshotAspectRatio::Auto, "screenshot_aspect_ratio", + Category::Screenshots}; QString roms_path; QString symbols_path; @@ -187,6 +194,9 @@ struct Values { extern Values values; +u32 CalculateWidth(u32 height, Settings::AspectRatio ratio); +Settings::AspectRatio ConvertScreenshotRatioToRatio(Settings::ScreenshotAspectRatio ratio); + } // namespace UISettings Q_DECLARE_METATYPE(UISettings::GameDir*);