GPU: Add auto (game native) aspect ratio

This commit is contained in:
Albert Liu 2020-12-11 21:37:53 -08:00
parent b4fb1e20d8
commit de8f03bd75
8 changed files with 49 additions and 12 deletions

View File

@ -7,6 +7,7 @@
#include "host_display.h"
#include "host_interface.h"
#include "interrupt_controller.h"
#include "settings.h"
#include "stb_image_write.h"
#include "system.h"
#include "timers.h"
@ -456,9 +457,41 @@ float GPU::ComputeVerticalFrequency() const
float GPU::GetDisplayAspectRatio() const
{
if (g_settings.display_force_4_3_for_24bit && m_GPUSTAT.display_area_color_depth_24)
{
return 4.0f / 3.0f;
}
else if (g_settings.display_aspect_ratio == DisplayAspectRatio::Auto)
{
const CRTCState& cs = m_crtc_state;
float relative_width = static_cast<float>(cs.horizontal_visible_end - cs.horizontal_visible_start);
float relative_height = static_cast<float>(cs.vertical_visible_end - cs.vertical_visible_start);
if (relative_width <= 0 || relative_height <= 0)
return 4.0f / 3.0f;
if (m_GPUSTAT.pal_mode)
{
relative_width /= static_cast<float>(PAL_HORIZONTAL_ACTIVE_END - PAL_HORIZONTAL_ACTIVE_START);
relative_height /= static_cast<float>(PAL_VERTICAL_ACTIVE_END - PAL_VERTICAL_ACTIVE_START);
}
else
{
relative_width /= static_cast<float>(NTSC_HORIZONTAL_ACTIVE_END - NTSC_HORIZONTAL_ACTIVE_START);
relative_height /= static_cast<float>(NTSC_VERTICAL_ACTIVE_END - NTSC_VERTICAL_ACTIVE_START);
}
return (relative_width / relative_height) * (4.0f / 3.0f);
}
else if (g_settings.display_aspect_ratio == DisplayAspectRatio::PAR1_1)
{
if (m_crtc_state.display_width == 0 || m_crtc_state.display_height == 0)
return 4.0f / 3.0f;
return static_cast<float>(m_crtc_state.display_width) / static_cast<float>(m_crtc_state.display_height);
}
else
{
return Settings::GetDisplayAspectRatioValue(g_settings.display_aspect_ratio);
}
}
void GPU::UpdateCRTCConfig()

View File

@ -655,6 +655,7 @@ static void RTPS(const s16 V[3], u8 shift, bool lm, bool last)
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:
@ -747,6 +748,7 @@ static void RTPS(const s16 V[3], u8 shift, bool lm, bool last)
precise_x = (precise_x * 7.0f) / 6.0f;
break;
case DisplayAspectRatio::Auto:
case DisplayAspectRatio::R4_3:
case DisplayAspectRatio::PAR1_1:
default:

View File

@ -138,7 +138,6 @@ void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, s32* ou
s32* out_height, s32* out_left_padding, s32* out_top_padding, float* out_scale,
float* out_y_scale, bool apply_aspect_ratio) const
{
apply_aspect_ratio = (m_display_aspect_ratio > 0) ? apply_aspect_ratio : false;
const float y_scale =
apply_aspect_ratio ?
((static_cast<float>(m_display_width) / static_cast<float>(m_display_height)) / m_display_aspect_ratio) :

View File

@ -625,10 +625,11 @@ const char* Settings::GetDisplayCropModeDisplayName(DisplayCropMode crop_mode)
return s_display_crop_mode_display_names[static_cast<int>(crop_mode)];
}
static std::array<const char*, 11> s_display_aspect_ratio_names = {
{"4:3", "16:9", "16:10", "19:9", "21:9", "8:7", "5:4", "3:2", "2:1 (VRAM 1:1)", "1:1", "PAR 1:1"}};
static constexpr std::array<float, 11> s_display_aspect_ratio_values = {
{4.0f / 3.0f, 16.0f / 9.0f, 16.0f / 10.0f, 19.0f / 9.0f, 21.0f / 9.0f, 8.0f / 7.0f, 5.0f / 4.0f, 3.0f / 2.0f,
static std::array<const char*, 12> s_display_aspect_ratio_names = {{"Auto (Game Native)", "4:3", "16:9", "16:10",
"19:9", "21:9", "8:7", "5:4", "3:2",
"2:1 (VRAM 1:1)", "1:1", "PAR 1:1"}};
static constexpr std::array<float, 12> s_display_aspect_ratio_values = {
{-1.0f, 4.0f / 3.0f, 16.0f / 9.0f, 16.0f / 10.0f, 19.0f / 9.0f, 21.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)

View File

@ -111,7 +111,7 @@ struct Settings
bool gpu_pgxp_cpu = false;
bool gpu_pgxp_preserve_proj_fp = false;
DisplayCropMode display_crop_mode = DisplayCropMode::None;
DisplayAspectRatio display_aspect_ratio = DisplayAspectRatio::R4_3;
DisplayAspectRatio display_aspect_ratio = DisplayAspectRatio::Auto;
s16 display_active_start_offset = 0;
s16 display_active_end_offset = 0;
s8 display_line_start_offset = 0;
@ -300,7 +300,7 @@ struct Settings
#endif
static constexpr DisplayCropMode DEFAULT_DISPLAY_CROP_MODE = DisplayCropMode::Overscan;
static constexpr DisplayAspectRatio DEFAULT_DISPLAY_ASPECT_RATIO = DisplayAspectRatio::R4_3;
static constexpr DisplayAspectRatio DEFAULT_DISPLAY_ASPECT_RATIO = DisplayAspectRatio::Auto;
static constexpr ControllerType DEFAULT_CONTROLLER_1_TYPE = ControllerType::DigitalController;
static constexpr ControllerType DEFAULT_CONTROLLER_2_TYPE = ControllerType::None;
static constexpr MemoryCardType DEFAULT_MEMORY_CARD_1_TYPE = MemoryCardType::PerGameTitle;

View File

@ -85,6 +85,7 @@ enum class DisplayCropMode : u8
enum class DisplayAspectRatio : u8
{
Auto,
R4_3,
R16_9,
R16_10,

View File

@ -704,7 +704,8 @@ static std::array<retro_core_option_definition, 49> s_option_definitions = {{
{"duckstation_Display.AspectRatio",
"Aspect Ratio",
"Sets the core-provided aspect ratio.",
{{"4:3", "4:3"},
{{"Auto", "Auto (Game Native)"},
{"4:3", "4:3"},
{"16:9", "16:9"},
{"16:10", "16:10"},
{"19:9", "19:9"},
@ -715,7 +716,7 @@ static std::array<retro_core_option_definition, 49> s_option_definitions = {{
{"2:1 (VRAM 1:1)", "2:1 (VRAM 1:1)"},
{"1:1", "1:1"},
{"PAR 1:1", "PAR 1:1"}},
"4:3"},
"Auto"},
{"duckstation_Main.LoadDevicesFromSaveStates",
"Load Devices From Save States",
"Sets whether the contents of devices and memory cards will be loaded when a save state is loaded.",

View File

@ -62,9 +62,9 @@ DisplaySettingsWidget::DisplaySettingsWidget(QtHostInterface* host_interface, QW
"renderers. <br>This option is only supported in Direct3D and Vulkan. OpenGL will always use the default "
"device."));
dialog->registerWidgetHelp(
m_ui.displayAspectRatio, tr("Aspect Ratio"), QStringLiteral("4:3"),
tr("Changes the aspect ratio used to display the console's output to the screen. The default "
"is 4:3 which matches a typical TV of the era."));
m_ui.displayAspectRatio, tr("Aspect Ratio"), QStringLiteral("Auto (Game Native)"),
tr("Changes the aspect ratio used to display the console's output to the screen. The default is Auto (Game Native) "
"which automatically adjusts the aspect ratio to match how a game would be shown on a typical TV of the era."));
dialog->registerWidgetHelp(
m_ui.displayCropMode, tr("Crop Mode"), tr("Only Overscan Area"),
tr("Determines how much of the area typically not visible on a consumer TV set to crop/hide. <br>"