Add custom relative and raw (squared pixels) aspect ratio modes
This commit is contained in:
parent
5090a028e6
commit
41b19e262f
|
@ -55,9 +55,9 @@ void GeneralWidget::CreateWidgets()
|
||||||
m_video_layout = new QGridLayout();
|
m_video_layout = new QGridLayout();
|
||||||
|
|
||||||
m_backend_combo = new ToolTipComboBox();
|
m_backend_combo = new ToolTipComboBox();
|
||||||
m_aspect_combo = new ConfigChoice(
|
m_aspect_combo = new ConfigChoice({tr("Auto"), tr("Force 16:9"), tr("Force 4:3"),
|
||||||
{tr("Auto"), tr("Force 16:9"), tr("Force 4:3"), tr("Stretch to Window"), tr("Custom")},
|
tr("Stretch to Window"), tr("Custom"), tr("Custom (Stretch)")},
|
||||||
Config::GFX_ASPECT_RATIO);
|
Config::GFX_ASPECT_RATIO);
|
||||||
m_custom_aspect_label = new QLabel(tr("Custom Aspect Ratio:"));
|
m_custom_aspect_label = new QLabel(tr("Custom Aspect Ratio:"));
|
||||||
m_custom_aspect_label->setHidden(true);
|
m_custom_aspect_label->setHidden(true);
|
||||||
constexpr int MAX_CUSTOM_ASPECT_RATIO_RESOLUTION = 10000;
|
constexpr int MAX_CUSTOM_ASPECT_RATIO_RESOLUTION = 10000;
|
||||||
|
@ -155,7 +155,8 @@ void GeneralWidget::ConnectWidgets()
|
||||||
emit BackendChanged(QString::fromStdString(Config::Get(Config::MAIN_GFX_BACKEND)));
|
emit BackendChanged(QString::fromStdString(Config::Get(Config::MAIN_GFX_BACKEND)));
|
||||||
});
|
});
|
||||||
connect(m_aspect_combo, qOverload<int>(&QComboBox::currentIndexChanged), this, [&](int index) {
|
connect(m_aspect_combo, qOverload<int>(&QComboBox::currentIndexChanged), this, [&](int index) {
|
||||||
const bool is_custom_aspect_ratio = (index == static_cast<int>(AspectMode::Custom));
|
const bool is_custom_aspect_ratio = (index == static_cast<int>(AspectMode::Custom)) ||
|
||||||
|
(index == static_cast<int>(AspectMode::CustomStretch));
|
||||||
m_custom_aspect_width->setEnabled(is_custom_aspect_ratio);
|
m_custom_aspect_width->setEnabled(is_custom_aspect_ratio);
|
||||||
m_custom_aspect_height->setEnabled(is_custom_aspect_ratio);
|
m_custom_aspect_height->setEnabled(is_custom_aspect_ratio);
|
||||||
m_custom_aspect_label->setHidden(!is_custom_aspect_ratio);
|
m_custom_aspect_label->setHidden(!is_custom_aspect_ratio);
|
||||||
|
@ -170,7 +171,9 @@ void GeneralWidget::LoadSettings()
|
||||||
m_backend_combo->setCurrentIndex(m_backend_combo->findData(
|
m_backend_combo->setCurrentIndex(m_backend_combo->findData(
|
||||||
QVariant(QString::fromStdString(Config::Get(Config::MAIN_GFX_BACKEND)))));
|
QVariant(QString::fromStdString(Config::Get(Config::MAIN_GFX_BACKEND)))));
|
||||||
|
|
||||||
const bool is_custom_aspect_ratio = (Config::Get(Config::GFX_ASPECT_RATIO) == AspectMode::Custom);
|
const bool is_custom_aspect_ratio =
|
||||||
|
(Config::Get(Config::GFX_ASPECT_RATIO) == AspectMode::Custom) ||
|
||||||
|
(Config::Get(Config::GFX_ASPECT_RATIO) == AspectMode::CustomStretch);
|
||||||
m_custom_aspect_width->setEnabled(is_custom_aspect_ratio);
|
m_custom_aspect_width->setEnabled(is_custom_aspect_ratio);
|
||||||
m_custom_aspect_height->setEnabled(is_custom_aspect_ratio);
|
m_custom_aspect_height->setEnabled(is_custom_aspect_ratio);
|
||||||
m_custom_aspect_label->setHidden(!is_custom_aspect_ratio);
|
m_custom_aspect_label->setHidden(!is_custom_aspect_ratio);
|
||||||
|
@ -247,15 +250,19 @@ void GeneralWidget::AddDescriptions()
|
||||||
QT_TR_NOOP("Uses the main Dolphin window for rendering rather than "
|
QT_TR_NOOP("Uses the main Dolphin window for rendering rather than "
|
||||||
"a separate render window.<br><br><dolphin_emphasis>If unsure, leave "
|
"a separate render window.<br><br><dolphin_emphasis>If unsure, leave "
|
||||||
"this unchecked.</dolphin_emphasis>");
|
"this unchecked.</dolphin_emphasis>");
|
||||||
static const char TR_ASPECT_RATIO_DESCRIPTION[] =
|
static const char TR_ASPECT_RATIO_DESCRIPTION[] = QT_TR_NOOP(
|
||||||
QT_TR_NOOP("Selects which aspect ratio to use when rendering.<br>"
|
"Selects which aspect ratio to use when drawing on the render window.<br>"
|
||||||
"Each game can have a slightly different native aspect ratio."
|
"Each game can have a slightly different native aspect ratio.<br>They can vary by "
|
||||||
"<br><br>Auto: Uses the native aspect ratio"
|
"scene and settings and rarely ever exactly match 4:3 or 16:9."
|
||||||
"<br>Force 16:9: Mimics an analog TV with a widescreen aspect ratio."
|
"<br><br><b>Auto</b>: Uses the native aspect ratio"
|
||||||
"<br>Force 4:3: Mimics a standard 4:3 analog TV."
|
"<br><br><b>Force 16:9</b>: Mimics an analog TV with a widescreen aspect ratio."
|
||||||
"<br>Stretch to Window: Stretches the picture to the window size."
|
"<br><br><b>Force 4:3</b>: Mimics a standard 4:3 analog TV."
|
||||||
"<br>Custom: For games running with specific custom aspect ratio cheats.<br><br>"
|
"<br><br><b>Stretch to Window</b>: Stretches the picture to the window size."
|
||||||
"<dolphin_emphasis>If unsure, select Auto.</dolphin_emphasis>");
|
"<br><br><b>Custom</b>: Forces the specified aspect ratio."
|
||||||
|
"<br>This is mostly intended to be used with aspect ratio cheats/mods."
|
||||||
|
"<br><br><b>Custom (Stretch)</b>: Similar to `Custom` but not relative to the "
|
||||||
|
"title's native aspect ratio.<br>This is not meant to be used under normal circumstances."
|
||||||
|
"<br><br><dolphin_emphasis>If unsure, select Auto.</dolphin_emphasis>");
|
||||||
static const char TR_VSYNC_DESCRIPTION[] = QT_TR_NOOP(
|
static const char TR_VSYNC_DESCRIPTION[] = QT_TR_NOOP(
|
||||||
"Waits for vertical blanks in order to prevent tearing.<br><br>Decreases performance "
|
"Waits for vertical blanks in order to prevent tearing.<br><br>Decreases performance "
|
||||||
"if emulation speed is below 100%.<br><br><dolphin_emphasis>If unsure, leave "
|
"if emulation speed is below 100%.<br><br><dolphin_emphasis>If unsure, leave "
|
||||||
|
|
|
@ -410,6 +410,12 @@ void HotkeyScheduler::Run()
|
||||||
case AspectMode::Custom:
|
case AspectMode::Custom:
|
||||||
OSD::AddMessage("Custom");
|
OSD::AddMessage("Custom");
|
||||||
break;
|
break;
|
||||||
|
case AspectMode::CustomStretch:
|
||||||
|
OSD::AddMessage("Custom (Stretch)");
|
||||||
|
break;
|
||||||
|
case AspectMode::Raw:
|
||||||
|
OSD::AddMessage("Raw (Square Pixels)");
|
||||||
|
break;
|
||||||
case AspectMode::Auto:
|
case AspectMode::Auto:
|
||||||
default:
|
default:
|
||||||
OSD::AddMessage("Auto");
|
OSD::AddMessage("Auto");
|
||||||
|
|
|
@ -356,12 +356,20 @@ float Presenter::CalculateDrawAspectRatio(bool allow_stretch) const
|
||||||
{
|
{
|
||||||
return SourceAspectRatioToWidescreen(source_aspect_ratio);
|
return SourceAspectRatioToWidescreen(source_aspect_ratio);
|
||||||
}
|
}
|
||||||
// For the "custom" mode, we force the exact target aspect ratio, without
|
|
||||||
// acknowleding the difference between the source aspect ratio and 4:3.
|
|
||||||
else if (aspect_mode == AspectMode::Custom)
|
else if (aspect_mode == AspectMode::Custom)
|
||||||
|
{
|
||||||
|
return source_aspect_ratio * (g_ActiveConfig.GetCustomAspectRatio() / (4.0f / 3.0f));
|
||||||
|
}
|
||||||
|
// For the "custom stretch" mode, we force the exact target aspect ratio, without
|
||||||
|
// acknowleding the difference between the source aspect ratio and 4:3.
|
||||||
|
else if (aspect_mode == AspectMode::CustomStretch)
|
||||||
{
|
{
|
||||||
return g_ActiveConfig.GetCustomAspectRatio();
|
return g_ActiveConfig.GetCustomAspectRatio();
|
||||||
}
|
}
|
||||||
|
else if (aspect_mode == AspectMode::Raw)
|
||||||
|
{
|
||||||
|
return m_xfb_entry ? (static_cast<float>(m_last_xfb_width) / m_last_xfb_height) : 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
return source_aspect_ratio;
|
return source_aspect_ratio;
|
||||||
}
|
}
|
||||||
|
@ -428,9 +436,11 @@ void* Presenter::GetNewSurfaceHandle()
|
||||||
|
|
||||||
u32 Presenter::AutoIntegralScale() const
|
u32 Presenter::AutoIntegralScale() const
|
||||||
{
|
{
|
||||||
// Take the source resolution (XFB) and stretch it on the target aspect ratio.
|
// Take the source/native resolution (XFB) and stretch it on the target (window) aspect ratio.
|
||||||
// If the target resolution is larger (on either x or y), we scale the source
|
// If the target resolution is larger (on either x or y), we scale the source
|
||||||
// by a integer multiplier until it won't have to be scaled up anymore.
|
// by a integer multiplier until it won't have to be scaled up anymore.
|
||||||
|
// NOTE: this might conflict with "Config::MAIN_RENDER_WINDOW_AUTOSIZE",
|
||||||
|
// as they mutually influence each other.
|
||||||
u32 source_width = m_last_xfb_width;
|
u32 source_width = m_last_xfb_width;
|
||||||
u32 source_height = m_last_xfb_height;
|
u32 source_height = m_last_xfb_height;
|
||||||
const u32 target_width = m_target_rectangle.GetWidth();
|
const u32 target_width = m_target_rectangle.GetWidth();
|
||||||
|
@ -477,7 +487,7 @@ std::tuple<float, float> Presenter::ApplyStandardAspectCrop(float width, float h
|
||||||
if (!allow_stretch && aspect_mode == AspectMode::Stretch)
|
if (!allow_stretch && aspect_mode == AspectMode::Stretch)
|
||||||
aspect_mode = AspectMode::Auto;
|
aspect_mode = AspectMode::Auto;
|
||||||
|
|
||||||
if (!g_ActiveConfig.bCrop || aspect_mode == AspectMode::Stretch)
|
if (!g_ActiveConfig.bCrop || aspect_mode == AspectMode::Stretch || aspect_mode == AspectMode::Raw)
|
||||||
return {width, height};
|
return {width, height};
|
||||||
|
|
||||||
// Force aspect ratios by cropping the image.
|
// Force aspect ratios by cropping the image.
|
||||||
|
@ -495,9 +505,12 @@ std::tuple<float, float> Presenter::ApplyStandardAspectCrop(float width, float h
|
||||||
case AspectMode::ForceStandard:
|
case AspectMode::ForceStandard:
|
||||||
expected_aspect = 4.0f / 3.0f;
|
expected_aspect = 4.0f / 3.0f;
|
||||||
break;
|
break;
|
||||||
// There should be no cropping needed in the custom case,
|
// For the custom (relative) case, we want to crop from the native aspect ratio
|
||||||
// as output should always exactly match the target aspect ratio
|
// to the specific target one, as they likely have a small difference
|
||||||
case AspectMode::Custom:
|
case AspectMode::Custom:
|
||||||
|
// There should be no cropping needed in the custom strech case,
|
||||||
|
// as output should always exactly match the target aspect ratio
|
||||||
|
case AspectMode::CustomStretch:
|
||||||
expected_aspect = g_ActiveConfig.GetCustomAspectRatio();
|
expected_aspect = g_ActiveConfig.GetCustomAspectRatio();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -602,9 +615,10 @@ void Presenter::UpdateDrawRectangle()
|
||||||
int_draw_width = static_cast<int>(draw_width);
|
int_draw_width = static_cast<int>(draw_width);
|
||||||
int_draw_height = static_cast<int>(draw_height);
|
int_draw_height = static_cast<int>(draw_height);
|
||||||
}
|
}
|
||||||
else
|
else if (g_ActiveConfig.aspect_mode != AspectMode::Raw || !m_xfb_entry)
|
||||||
{
|
{
|
||||||
// Find the best integer resolution: the closest aspect ratio with the least black bars
|
// Find the best integer resolution: the closest aspect ratio with the least black bars.
|
||||||
|
// This should have no influence if "AspectMode::Stretch" is active.
|
||||||
const float updated_draw_aspect_ratio = draw_width / draw_height;
|
const float updated_draw_aspect_ratio = draw_width / draw_height;
|
||||||
const auto int_draw_res =
|
const auto int_draw_res =
|
||||||
FindClosestIntegerResolution(draw_width, draw_height, updated_draw_aspect_ratio);
|
FindClosestIntegerResolution(draw_width, draw_height, updated_draw_aspect_ratio);
|
||||||
|
@ -612,13 +626,21 @@ void Presenter::UpdateDrawRectangle()
|
||||||
int_draw_height = std::get<1>(int_draw_res);
|
int_draw_height = std::get<1>(int_draw_res);
|
||||||
if (!g_ActiveConfig.bCrop)
|
if (!g_ActiveConfig.bCrop)
|
||||||
{
|
{
|
||||||
TryToSnapToXFBSize(int_draw_width, int_draw_height, m_xfb_rect.GetWidth(),
|
if (g_ActiveConfig.aspect_mode != AspectMode::Stretch)
|
||||||
m_xfb_rect.GetHeight());
|
{
|
||||||
|
TryToSnapToXFBSize(int_draw_width, int_draw_height, m_xfb_rect.GetWidth(),
|
||||||
|
m_xfb_rect.GetHeight());
|
||||||
|
}
|
||||||
// We can't draw something bigger than the window, it will crop
|
// We can't draw something bigger than the window, it will crop
|
||||||
int_draw_width = std::min(int_draw_width, static_cast<int>(win_width));
|
int_draw_width = std::min(int_draw_width, static_cast<int>(win_width));
|
||||||
int_draw_height = std::min(int_draw_height, static_cast<int>(win_height));
|
int_draw_height = std::min(int_draw_height, static_cast<int>(win_height));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int_draw_width = m_xfb_rect.GetWidth();
|
||||||
|
int_draw_height = m_xfb_rect.GetHeight();
|
||||||
|
}
|
||||||
|
|
||||||
m_target_rectangle.left = static_cast<int>(std::round(win_width / 2.0 - int_draw_width / 2.0));
|
m_target_rectangle.left = static_cast<int>(std::round(win_width / 2.0 - int_draw_width / 2.0));
|
||||||
m_target_rectangle.top = static_cast<int>(std::round(win_height / 2.0 - int_draw_height / 2.0));
|
m_target_rectangle.top = static_cast<int>(std::round(win_height / 2.0 - int_draw_height / 2.0));
|
||||||
|
@ -665,7 +687,10 @@ std::tuple<int, int> Presenter::CalculateOutputDimensions(int width, int height,
|
||||||
const float draw_aspect_ratio = CalculateDrawAspectRatio(allow_stretch);
|
const float draw_aspect_ratio = CalculateDrawAspectRatio(allow_stretch);
|
||||||
auto [int_width, int_height] =
|
auto [int_width, int_height] =
|
||||||
FindClosestIntegerResolution(scaled_width, scaled_height, draw_aspect_ratio);
|
FindClosestIntegerResolution(scaled_width, scaled_height, draw_aspect_ratio);
|
||||||
TryToSnapToXFBSize(int_width, int_height, m_xfb_rect.GetWidth(), m_xfb_rect.GetHeight());
|
if (aspect_mode != AspectMode::Raw)
|
||||||
|
{
|
||||||
|
TryToSnapToXFBSize(int_width, int_height, m_xfb_rect.GetWidth(), m_xfb_rect.GetHeight());
|
||||||
|
}
|
||||||
width = int_width;
|
width = int_width;
|
||||||
height = int_height;
|
height = int_height;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,13 @@ constexpr int EFB_SCALE_AUTO_INTEGRAL = 0;
|
||||||
|
|
||||||
enum class AspectMode : int
|
enum class AspectMode : int
|
||||||
{
|
{
|
||||||
Auto, // 4:3 or 16:9
|
Auto, // ~4:3 or ~16:9 (auto detected)
|
||||||
ForceWide, // 16:9
|
ForceWide, // ~16:9
|
||||||
ForceStandard, // 4:3
|
ForceStandard, // ~4:3
|
||||||
Stretch,
|
Stretch,
|
||||||
Custom,
|
Custom, // Forced relative custom AR
|
||||||
|
CustomStretch, // Forced absolute custom AR
|
||||||
|
Raw, // Forced squared pixels
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class StereoMode : int
|
enum class StereoMode : int
|
||||||
|
|
Loading…
Reference in New Issue