Support custom and match display aspect ratios

This commit is contained in:
Connor McLaughlin 2021-04-29 02:42:08 +10:00
parent 48bc152a63
commit 256f272768
19 changed files with 283 additions and 112 deletions

View File

@ -45,6 +45,7 @@
</string-array>
<string-array name="settings_display_aspect_ratio_names">
<item>Auto (Nativo del juego)</item>
<item>Auto (Match Display)</item>
<item>4:3</item>
<item>16:9</item>
<item>16:10</item>

View File

@ -45,6 +45,7 @@
</string-array>
<string-array name="settings_display_aspect_ratio_names">
<item>Auto (Game Native)</item>
<item>Auto (Match Display)</item>
<item>4:3</item>
<item>16:9</item>
<item>16:10</item>

View File

@ -45,6 +45,7 @@
</string-array>
<string-array name="settings_display_aspect_ratio_names">
<item>Auto (Game Native)</item>
<item>Auto (Match Display)</item>
<item>4:3</item>
<item>16:9</item>
<item>16:10</item>

View File

@ -45,6 +45,7 @@
</string-array>
<string-array name="settings_display_aspect_ratio_names">
<item>Auto (Nativo)</item>
<item>Auto (Match Display)</item>
<item>4:3</item>
<item>16:9</item>
<item>16:10</item>

View File

@ -44,8 +44,9 @@
<item>Все границы</item>
</string-array>
<string-array name="settings_display_aspect_ratio_names">
<item>Автонастройка (нативное игре)</item>
<item>4:3</item>
<item>Автонастройка (нативное игре)</item>
<item>Auto (Match Display)</item>
<item>4:3</item>
<item>16:9</item>
<item>16:10</item>
<item>19:9</item>

View File

@ -89,6 +89,7 @@
</string-array>
<string-array name="settings_display_aspect_ratio_names">
<item>Auto (Game Native)</item>
<item>Auto (Match Display)</item>
<item>4:3</item>
<item>16:9</item>
<item>16:10</item>
@ -105,6 +106,7 @@
</string-array>
<string-array name="settings_display_aspect_ratio_values">
<item>Auto (Game Native)</item>
<item>Auto (Match Window)</item>
<item>4:3</item>
<item>16:9</item>
<item>16:10</item>

View File

@ -492,7 +492,7 @@ float GPU::GetDisplayAspectRatio() const
}
else
{
return Settings::GetDisplayAspectRatioValue(g_settings.display_aspect_ratio);
return g_settings.GetDisplayAspectRatioValue();
}
}

View File

@ -3,10 +3,13 @@
#include "common/bitutils.h"
#include "common/state_wrapper.h"
#include "cpu_core.h"
#include "host_display.h"
#include "host_interface.h"
#include "pgxp.h"
#include "settings.h"
#include <algorithm>
#include <array>
#include <numeric>
namespace GTE {
@ -19,6 +22,11 @@ static constexpr s32 IR0_MAX_VALUE = 0x1000;
static constexpr s32 IR123_MIN_VALUE = -(INT64_C(1) << 15);
static constexpr s32 IR123_MAX_VALUE = (INT64_C(1) << 15) - 1;
static DisplayAspectRatio s_aspect_ratio = DisplayAspectRatio::R4_3;
static u32 s_custom_aspect_ratio_numerator;
static u32 s_custom_aspect_ratio_denominator;
static float s_custom_aspect_ratio_f;
#define REGS CPU::g_state.gte_regs
ALWAYS_INLINE static u32 CountLeadingBits(u32 value)
@ -148,6 +156,7 @@ ALWAYS_INLINE static u32 TruncateRGB(s32 value)
void Initialize()
{
UpdateAspectRatio();
Reset();
}
@ -162,6 +171,55 @@ bool DoState(StateWrapper& sw)
return !sw.HasError();
}
void UpdateAspectRatio()
{
if (!g_settings.gpu_widescreen_hack)
{
s_aspect_ratio = DisplayAspectRatio::R4_3;
return;
}
s_aspect_ratio = g_settings.display_aspect_ratio;
u32 num, denom;
switch (s_aspect_ratio)
{
case DisplayAspectRatio::MatchWindow:
{
const HostDisplay* display = g_host_interface->GetDisplay();
if (!display)
{
s_aspect_ratio = DisplayAspectRatio::R4_3;
return;
}
num = display->GetWindowWidth();
denom = display->GetWindowHeight();
}
break;
case DisplayAspectRatio::Custom:
{
num = g_settings.display_aspect_ratio_custom_numerator;
denom = g_settings.display_aspect_ratio_custom_denominator;
}
break;
default:
return;
}
// (4 / 3) / (num / denom) => gcd((4 * denom) / (3 * num))
const u32 x = 4u * denom;
const u32 y = 3u * num;
const u32 gcd = std::gcd(x, y);
s_custom_aspect_ratio_numerator = x / gcd;
s_custom_aspect_ratio_denominator = y / gcd;
s_custom_aspect_ratio_f = static_cast<float>((4.0 / 3.0) / (static_cast<double>(num) / static_cast<double>(denom)));
}
u32 ReadRegister(u32 index)
{
DebugAssert(index < countof(REGS.r32));
@ -614,66 +672,65 @@ static void RTPS(const s16 V[3], u8 shift, bool lm, bool last)
const s64 result = static_cast<s64>(ZeroExtend64(UNRDivide(REGS.H, REGS.SZ3)));
s64 Sx;
if (g_settings.gpu_widescreen_hack)
switch (s_aspect_ratio)
{
const DisplayAspectRatio ar = g_settings.display_aspect_ratio;
switch (ar)
{
case DisplayAspectRatio::R16_9:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(3)) / s64(4)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R16_9:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(3)) / s64(4)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R16_10:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(5)) / s64(6)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R16_10:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(5)) / s64(6)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R19_9:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(12)) / s64(19)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R19_9:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(12)) / s64(19)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R20_9:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(3)) / s64(5)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R20_9:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(3)) / s64(5)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R21_9:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(9)) / s64(16)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R21_9:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(9)) / s64(16)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R32_9:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(3)) / s64(8)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R32_9:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(3)) / s64(8)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R8_7:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(7)) / s64(6)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R8_7:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(7)) / s64(6)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R5_4:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(16)) / s64(15)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R5_4:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(16)) / s64(15)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R3_2:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(8)) / s64(9)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R3_2:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(8)) / s64(9)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R2_1:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(2)) / s64(3)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R2_1:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(2)) / s64(3)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R1_1:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(7)) / s64(6)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::R1_1:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(7)) / s64(6)) + s64(REGS.OFX));
break;
case DisplayAspectRatio::Auto:
case DisplayAspectRatio::R4_3:
case DisplayAspectRatio::PAR1_1:
default:
Sx = (s64(result) * s64(REGS.IR1) + s64(REGS.OFX));
break;
}
}
else
{
Sx = (s64(result) * s64(REGS.IR1) + s64(REGS.OFX));
case DisplayAspectRatio::Custom:
case DisplayAspectRatio::MatchWindow:
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(s_custom_aspect_ratio_numerator)) /
s64(s_custom_aspect_ratio_denominator)) +
s64(REGS.OFX));
break;
case DisplayAspectRatio::Auto:
case DisplayAspectRatio::R4_3:
case DisplayAspectRatio::PAR1_1:
default:
Sx = (s64(result) * s64(REGS.IR1) + s64(REGS.OFX));
break;
}
const s64 Sy = s64(result) * s64(REGS.IR2) + s64(REGS.OFY);
@ -713,70 +770,68 @@ static void RTPS(const s16 V[3], u8 shift, bool lm, bool last)
const float precise_h_div_sz = float(REGS.H) / precise_z;
const float fofx = float(REGS.OFX) / float(1 << 16);
const float fofy = float(REGS.OFY) / float(1 << 16);
float precise_x;
if (g_settings.gpu_widescreen_hack)
float precise_x = precise_ir1 * precise_h_div_sz;
switch (s_aspect_ratio)
{
precise_x = precise_ir1 * precise_h_div_sz;
const DisplayAspectRatio ar = g_settings.display_aspect_ratio;
switch (ar)
{
case DisplayAspectRatio::R16_9:
precise_x = (precise_x * 3.0f) / 4.0f;
break;
case DisplayAspectRatio::R16_9:
precise_x = (precise_x * 3.0f) / 4.0f;
break;
case DisplayAspectRatio::R16_10:
precise_x = (precise_x * 5.0f) / 6.0f;
break;
case DisplayAspectRatio::R16_10:
precise_x = (precise_x * 5.0f) / 6.0f;
break;
case DisplayAspectRatio::R19_9:
precise_x = (precise_x * 12.0f) / 19.0f;
break;
case DisplayAspectRatio::R19_9:
precise_x = (precise_x * 12.0f) / 19.0f;
break;
case DisplayAspectRatio::R20_9:
precise_x = (precise_x * 3.0f) / 5.0f;
break;
case DisplayAspectRatio::R20_9:
precise_x = (precise_x * 3.0f) / 5.0f;
break;
case DisplayAspectRatio::R21_9:
precise_x = (precise_x * 9.0f) / 16.0f;
break;
case DisplayAspectRatio::R21_9:
precise_x = (precise_x * 9.0f) / 16.0f;
break;
case DisplayAspectRatio::R32_9:
precise_x = (precise_x * 3.0f) / 8.0f;
break;
case DisplayAspectRatio::R32_9:
precise_x = (precise_x * 3.0f) / 8.0f;
break;
case DisplayAspectRatio::R8_7:
precise_x = (precise_x * 7.0f) / 6.0f;
break;
case DisplayAspectRatio::R8_7:
precise_x = (precise_x * 7.0f) / 6.0f;
break;
case DisplayAspectRatio::R5_4:
precise_x = (precise_x * 16.0f) / 15.0f;
break;
case DisplayAspectRatio::R5_4:
precise_x = (precise_x * 16.0f) / 15.0f;
break;
case DisplayAspectRatio::R3_2:
precise_x = (precise_x * 8.0f) / 9.0f;
break;
case DisplayAspectRatio::R3_2:
precise_x = (precise_x * 8.0f) / 9.0f;
break;
case DisplayAspectRatio::R2_1:
precise_x = (precise_x * 2.0f) / 3.0f;
break;
case DisplayAspectRatio::R2_1:
precise_x = (precise_x * 2.0f) / 3.0f;
break;
case DisplayAspectRatio::R1_1:
precise_x = (precise_x * 7.0f) / 6.0f;
break;
case DisplayAspectRatio::R1_1:
precise_x = (precise_x * 7.0f) / 6.0f;
break;
case DisplayAspectRatio::Auto:
case DisplayAspectRatio::R4_3:
case DisplayAspectRatio::PAR1_1:
default:
break;
}
precise_x += fofx;
}
else
{
precise_x = fofx + (precise_ir1 * precise_h_div_sz);
case DisplayAspectRatio::MatchWindow:
case DisplayAspectRatio::Custom:
precise_x = precise_x * s_custom_aspect_ratio_f;
break;
case DisplayAspectRatio::Auto:
case DisplayAspectRatio::R4_3:
case DisplayAspectRatio::PAR1_1:
default:
break;
}
precise_x += fofx;
float precise_y = fofy + (precise_ir2 * precise_h_div_sz);
precise_x = std::clamp<float>(precise_x, -1024.0f, 1023.0f);

View File

@ -8,6 +8,7 @@ namespace GTE {
void Initialize();
void Reset();
bool DoState(StateWrapper& sw);
void UpdateAspectRatio();
// control registers are offset by +32
u32 ReadRegister(u32 index);

View File

@ -533,6 +533,8 @@ void HostInterface::SetDefaultSettings(SettingsInterface& si)
si.SetIntValue("Display", "LineEndOffset", 0);
si.SetStringValue("Display", "AspectRatio",
Settings::GetDisplayAspectRatioName(Settings::DEFAULT_DISPLAY_ASPECT_RATIO));
si.SetIntValue("Display", "CustomAspectRatioNumerator", 4);
si.GetIntValue("Display", "CustomAspectRatioDenominator", 3);
si.SetBoolValue("Display", "Force4_3For24Bit", false);
si.SetBoolValue("Display", "LinearFiltering", true);
si.SetBoolValue("Display", "IntegerScaling", false);
@ -803,6 +805,14 @@ void HostInterface::CheckForSettingsChanges(const Settings& old_settings)
g_gpu->UpdateSettings();
}
if (g_settings.display_aspect_ratio != old_settings.display_aspect_ratio ||
(g_settings.display_aspect_ratio == DisplayAspectRatio::Custom &&
(g_settings.display_aspect_ratio_custom_numerator != old_settings.display_aspect_ratio_custom_numerator ||
g_settings.display_aspect_ratio_custom_denominator != old_settings.display_aspect_ratio_custom_denominator)))
{
GTE::UpdateAspectRatio();
}
if (g_settings.gpu_pgxp_enable != old_settings.gpu_pgxp_enable ||
(g_settings.gpu_pgxp_enable && (g_settings.gpu_pgxp_culling != old_settings.gpu_pgxp_culling ||
g_settings.gpu_pgxp_cpu != old_settings.gpu_pgxp_cpu)))
@ -899,6 +909,15 @@ void HostInterface::SetUserDirectoryToProgramDirectory()
m_user_directory = program_directory;
}
void HostInterface::OnHostDisplayResized()
{
if (System::IsValid())
{
if (g_settings.display_aspect_ratio == DisplayAspectRatio::MatchWindow)
GTE::UpdateAspectRatio();
}
}
std::string HostInterface::GetUserDirectoryRelativePath(const char* format, ...) const
{
std::va_list ap;

View File

@ -183,6 +183,9 @@ protected:
/// Enables "relative" mouse mode, locking the cursor position and returning relative coordinates.
virtual void SetMouseMode(bool relative, bool hide_cursor);
/// Call when host display size changes, use with "match display" aspect ratio setting.
virtual void OnHostDisplayResized();
/// Sets the user directory to the program directory, i.e. "portable mode".
void SetUserDirectoryToProgramDirectory();

View File

@ -3,6 +3,7 @@
#include "common/file_system.h"
#include "common/make_array.h"
#include "common/string_util.h"
#include "host_display.h"
#include "host_interface.h"
#include <algorithm>
#include <array>
@ -222,6 +223,10 @@ void Settings::Load(SettingsInterface& si)
ParseDisplayAspectRatio(
si.GetStringValue("Display", "AspectRatio", GetDisplayAspectRatioName(DEFAULT_DISPLAY_ASPECT_RATIO)).c_str())
.value_or(DEFAULT_DISPLAY_ASPECT_RATIO);
display_aspect_ratio_custom_numerator = static_cast<u16>(
std::clamp<int>(si.GetIntValue("Display", "CustomAspectRatioNumerator", 4), 1, std::numeric_limits<u16>::max()));
display_aspect_ratio_custom_denominator = static_cast<u16>(
std::clamp<int>(si.GetIntValue("Display", "CustomAspectRatioDenominator", 3), 1, std::numeric_limits<u16>::max()));
display_force_4_3_for_24bit = si.GetBoolValue("Display", "Force4_3For24Bit", false);
display_active_start_offset = static_cast<s16>(si.GetIntValue("Display", "ActiveStartOffset", 0));
display_active_end_offset = static_cast<s16>(si.GetIntValue("Display", "ActiveEndOffset", 0));
@ -395,6 +400,8 @@ void Settings::Save(SettingsInterface& si) const
si.SetIntValue("Display", "LineEndOffset", display_line_end_offset);
si.SetBoolValue("Display", "Force4_3For24Bit", display_force_4_3_for_24bit);
si.SetStringValue("Display", "AspectRatio", GetDisplayAspectRatioName(display_aspect_ratio));
si.SetIntValue("Display", "CustomAspectRatioNumerator", display_aspect_ratio_custom_numerator);
si.GetIntValue("Display", "CustomAspectRatioDenominator", display_aspect_ratio_custom_denominator);
si.SetBoolValue("Display", "LinearFiltering", display_linear_filtering);
si.SetBoolValue("Display", "IntegerScaling", display_integer_scaling);
si.SetBoolValue("Display", "Stretch", display_stretch);
@ -767,12 +774,12 @@ const char* Settings::GetDisplayCropModeDisplayName(DisplayCropMode crop_mode)
return s_display_crop_mode_display_names[static_cast<int>(crop_mode)];
}
static std::array<const char*, 14> s_display_aspect_ratio_names = {
{TRANSLATABLE("DisplayAspectRatio", "Auto (Game Native)"), "4:3", "16:9", "16:10", "19:9", "20:9", "21:9", "32:9",
"8:7", "5:4", "3:2", "2:1 (VRAM 1:1)", "1:1", "PAR 1:1"}};
static constexpr std::array<float, 14> s_display_aspect_ratio_values = {
{-1.0f, 4.0f / 3.0f, 16.0f / 9.0f, 16.0f / 10.0f, 19.0f / 9.0f, 20.0f / 9.0f, 64.0f / 27.0f, 32.0f / 9.0f,
8.0f / 7.0f, 5.0f / 4.0f, 3.0f / 2.0f, 2.0f / 1.0f, 1.0f, -1.0f}};
static std::array<const char*, 16> s_display_aspect_ratio_names = {
{TRANSLATABLE("DisplayAspectRatio", "Auto (Game Native)"), "Auto (Match Window)", "Custom", "4:3", "16:9", "16:10",
"19:9", "20:9", "21:9", "32:9", "8:7", "5:4", "3:2", "2:1 (VRAM 1:1)", "1:1", "PAR 1:1"}};
static constexpr std::array<float, 16> s_display_aspect_ratio_values = {
{-1.0f, -1.0f, -1.0f, 4.0f / 3.0f, 16.0f / 9.0f, 16.0f / 10.0f, 19.0f / 9.0f, 20.0f / 9.0f, 64.0f / 27.0f,
32.0f / 9.0f, 8.0f / 7.0f, 5.0f / 4.0f, 3.0f / 2.0f, 2.0f / 1.0f, 1.0f, -1.0f}};
std::optional<DisplayAspectRatio> Settings::ParseDisplayAspectRatio(const char* str)
{
@ -793,9 +800,32 @@ const char* Settings::GetDisplayAspectRatioName(DisplayAspectRatio ar)
return s_display_aspect_ratio_names[static_cast<int>(ar)];
}
float Settings::GetDisplayAspectRatioValue(DisplayAspectRatio ar)
float Settings::GetDisplayAspectRatioValue() const
{
return s_display_aspect_ratio_values[static_cast<int>(ar)];
switch (display_aspect_ratio)
{
case DisplayAspectRatio::MatchWindow:
{
const HostDisplay* display = g_host_interface->GetDisplay();
if (!display)
return s_display_aspect_ratio_values[static_cast<int>(DEFAULT_DISPLAY_ASPECT_RATIO)];
const u32 width = display->GetWindowWidth();
const u32 height = display->GetWindowHeight() - display->GetDisplayTopMargin();
return static_cast<float>(width) / static_cast<float>(height);
}
case DisplayAspectRatio::Custom:
{
return static_cast<float>(display_aspect_ratio_custom_numerator) /
static_cast<float>(display_aspect_ratio_custom_denominator);
}
default:
{
return s_display_aspect_ratio_values[static_cast<int>(display_aspect_ratio)];
}
}
}
static std::array<const char*, 3> s_audio_backend_names = {{

View File

@ -127,6 +127,8 @@ struct Settings
bool gpu_pgxp_depth_buffer = false;
DisplayCropMode display_crop_mode = DisplayCropMode::None;
DisplayAspectRatio display_aspect_ratio = DisplayAspectRatio::Auto;
u16 display_aspect_ratio_custom_numerator = 0;
u16 display_aspect_ratio_custom_denominator = 0;
s16 display_active_start_offset = 0;
s16 display_active_end_offset = 0;
s8 display_line_start_offset = 0;
@ -256,6 +258,8 @@ struct Settings
return audio_output_muted ? 0 : (fast_forwarding ? audio_fast_forward_volume : audio_output_volume);
}
float GetDisplayAspectRatioValue() const;
bool HasAnyPerGameMemoryCards() const;
static void CPUOverclockPercentToFraction(u32 percent, u32* numerator, u32* denominator);
@ -316,7 +320,6 @@ struct Settings
static std::optional<DisplayAspectRatio> ParseDisplayAspectRatio(const char* str);
static const char* GetDisplayAspectRatioName(DisplayAspectRatio ar);
static float GetDisplayAspectRatioValue(DisplayAspectRatio ar);
static std::optional<AudioBackend> ParseAudioBackend(const char* str);
static const char* GetAudioBackendName(AudioBackend backend);

View File

@ -94,6 +94,8 @@ enum class DisplayCropMode : u8
enum class DisplayAspectRatio : u8
{
Auto,
MatchWindow,
Custom,
R4_3,
R16_9,
R16_10,

View File

@ -25,6 +25,10 @@ DisplaySettingsWidget::DisplaySettingsWidget(QtHostInterface* host_interface, QW
SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.displayAspectRatio, "Display", "AspectRatio",
&Settings::ParseDisplayAspectRatio, &Settings::GetDisplayAspectRatioName,
Settings::DEFAULT_DISPLAY_ASPECT_RATIO);
SettingWidgetBinder::BindWidgetToIntSetting(m_host_interface, m_ui.customAspectRatioNumerator, "Display",
"CustomAspectRatioNumerator", 1);
SettingWidgetBinder::BindWidgetToIntSetting(m_host_interface, m_ui.customAspectRatioDenominator, "Display",
"CustomAspectRatioDenominator", 1);
SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.displayCropMode, "Display", "CropMode",
&Settings::ParseDisplayCropMode, &Settings::GetDisplayCropModeName,
Settings::DEFAULT_DISPLAY_CROP_MODE);
@ -59,10 +63,13 @@ DisplaySettingsWidget::DisplaySettingsWidget(QtHostInterface* host_interface, QW
&DisplaySettingsWidget::onGPUAdapterIndexChanged);
connect(m_ui.fullscreenMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&DisplaySettingsWidget::onGPUFullscreenModeIndexChanged);
connect(m_ui.displayAspectRatio, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&DisplaySettingsWidget::onAspectRatioChanged);
connect(m_ui.displayIntegerScaling, &QCheckBox::stateChanged, this,
&DisplaySettingsWidget::onIntegerFilteringChanged);
populateGPUAdaptersAndResolutions();
onIntegerFilteringChanged();
onAspectRatioChanged();
dialog->registerWidgetHelp(
m_ui.renderer, tr("Renderer"),
@ -283,3 +290,13 @@ void DisplaySettingsWidget::onIntegerFilteringChanged()
m_ui.displayLinearFiltering->setEnabled(!m_ui.displayIntegerScaling->isChecked());
m_ui.displayStretch->setEnabled(!m_ui.displayIntegerScaling->isChecked());
}
void DisplaySettingsWidget::onAspectRatioChanged()
{
const bool is_custom =
static_cast<DisplayAspectRatio>(m_ui.displayAspectRatio->currentIndex()) == DisplayAspectRatio::Custom;
m_ui.customAspectRatioNumerator->setVisible(is_custom);
m_ui.customAspectRatioDenominator->setVisible(is_custom);
m_ui.customAspectRatioSeparator->setVisible(is_custom);
}

View File

@ -21,6 +21,7 @@ private Q_SLOTS:
void onGPUAdapterIndexChanged();
void onGPUFullscreenModeIndexChanged();
void onIntegerFilteringChanged();
void onAspectRatioChanged();
private:
void setupAdditionalUi();

View File

@ -111,7 +111,38 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="displayAspectRatio"/>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0,0,0">
<item>
<widget class="QComboBox" name="displayAspectRatio"/>
</item>
<item>
<widget class="QSpinBox" name="customAspectRatioNumerator">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="customAspectRatioSeparator">
<property name="text">
<string>:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="customAspectRatioDenominator">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">

View File

@ -575,6 +575,8 @@ void CommonHostInterface::OnHostDisplayResized()
const u32 new_height = m_display ? m_display->GetWindowHeight() : 0;
const float new_scale = m_display ? m_display->GetWindowScale() : 1.0f;
HostInterface::OnHostDisplayResized();
ImGui::GetIO().DisplaySize.x = static_cast<float>(new_width);
ImGui::GetIO().DisplaySize.y = static_cast<float>(new_height);

View File

@ -412,13 +412,13 @@ protected:
void UpdateSpeedLimiterState();
void RecreateSystem() override;
void OnHostDisplayResized() override;
void ApplyGameSettings(bool display_osd_messages);
void ApplyControllerCompatibilitySettings(u64 controller_mask, bool display_osd_messages);
bool CreateHostDisplayResources();
void ReleaseHostDisplayResources();
void OnHostDisplayResized();
virtual void DrawImGuiWindows();