mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-25 23:25:41 +00:00
GPU: Add pixel aspect ratio option
Can display in 4:3, 16:9, 1:1 ratios.
This commit is contained in:
parent
3325d2c42c
commit
fbfd838e22
|
@ -29,6 +29,8 @@ bool GPU::Initialize(HostDisplay* host_display, System* system, DMA* dma, Interr
|
|||
m_timers = timers;
|
||||
m_force_progressive_scan = m_system->GetSettings().display_force_progressive_scan;
|
||||
m_force_ntsc_timings = m_system->GetSettings().gpu_force_ntsc_timings;
|
||||
m_crtc_state.display_aspect_ratio =
|
||||
Settings::GetDisplayAspectRatioValue(m_system->GetSettings().display_aspect_ratio);
|
||||
m_tick_event =
|
||||
m_system->CreateTimingEvent("GPU Tick", 1, 1, std::bind(&GPU::Execute, this, std::placeholders::_1), true);
|
||||
return true;
|
||||
|
@ -44,6 +46,9 @@ void GPU::UpdateSettings()
|
|||
UpdateCRTCConfig();
|
||||
}
|
||||
|
||||
m_crtc_state.display_aspect_ratio =
|
||||
Settings::GetDisplayAspectRatioValue(m_system->GetSettings().display_aspect_ratio);
|
||||
|
||||
// Crop mode calls this, so recalculate the display area
|
||||
UpdateCRTCDisplayParameters();
|
||||
}
|
||||
|
@ -64,10 +69,14 @@ void GPU::SoftReset()
|
|||
m_drawing_area.Set(0, 0, 0, 0);
|
||||
m_drawing_area_changed = true;
|
||||
m_drawing_offset = {};
|
||||
std::memset(&m_crtc_state, 0, sizeof(m_crtc_state));
|
||||
m_crtc_state.regs.display_address_start = 0;
|
||||
std::memset(&m_crtc_state.regs, 0, sizeof(m_crtc_state.regs));
|
||||
m_crtc_state.regs.horizontal_display_range = 0xC60260;
|
||||
m_crtc_state.regs.vertical_display_range = 0x3FC10;
|
||||
m_crtc_state.fractional_ticks = 0;
|
||||
m_crtc_state.current_tick_in_scanline = 0;
|
||||
m_crtc_state.current_scanline = 0;
|
||||
m_crtc_state.in_hblank = false;
|
||||
m_crtc_state.in_vblank = false;
|
||||
m_state = State::Idle;
|
||||
m_blitter_ticks = 0;
|
||||
m_command_total_words = 0;
|
||||
|
@ -136,7 +145,6 @@ bool GPU::DoState(StateWrapper& sw)
|
|||
sw.Do(&m_crtc_state.fractional_ticks);
|
||||
sw.Do(&m_crtc_state.current_tick_in_scanline);
|
||||
sw.Do(&m_crtc_state.current_scanline);
|
||||
sw.Do(&m_crtc_state.display_aspect_ratio);
|
||||
sw.Do(&m_crtc_state.in_hblank);
|
||||
sw.Do(&m_crtc_state.in_vblank);
|
||||
|
||||
|
@ -521,9 +529,6 @@ void GPU::UpdateCRTCDisplayParameters()
|
|||
(vertical_visible_end_line - std::max(vertical_display_start, vertical_visible_start_line)) << height_shift,
|
||||
VRAM_HEIGHT - cs.display_vram_top);
|
||||
}
|
||||
|
||||
// Aspect ratio is always 4:3.
|
||||
cs.display_aspect_ratio = 4.0f / 3.0f;
|
||||
}
|
||||
|
||||
TickCount GPU::GetPendingGPUTicks() const
|
||||
|
|
|
@ -20,32 +20,6 @@ void HostDisplay::WindowResized(s32 new_window_width, s32 new_window_height)
|
|||
|
||||
std::tuple<s32, s32, s32, s32> HostDisplay::CalculateDrawRect() const
|
||||
{
|
||||
#if 0
|
||||
// convert display region to correct pixel aspect ratio
|
||||
float display_width, display_height, active_left, active_top, active_width, active_height;
|
||||
if (m_display_width >= m_display_height)
|
||||
{
|
||||
display_width = static_cast<float>(m_display_width);
|
||||
display_height = static_cast<float>(m_display_width) / m_display_pixel_aspect_ratio;
|
||||
|
||||
const float scale = display_height / static_cast<float>(m_display_height);
|
||||
active_left = static_cast<float>(m_display_active_left);
|
||||
active_top = static_cast<float>(m_display_active_top) * scale;
|
||||
active_width = static_cast<float>(m_display_active_width);
|
||||
active_height = static_cast<float>(m_display_active_width) / m_display_pixel_aspect_ratio;
|
||||
}
|
||||
else
|
||||
{
|
||||
display_width = static_cast<float>(m_display_height) * m_display_pixel_aspect_ratio;
|
||||
display_height = static_cast<float>(m_display_height);
|
||||
|
||||
const float scale = display_width / static_cast<float>(m_display_width);
|
||||
active_left = static_cast<float>(m_display_active_left) * scale;
|
||||
active_top = static_cast<float>(m_display_active_top);
|
||||
active_width = static_cast<float>(m_display_active_height) * m_display_pixel_aspect_ratio;
|
||||
active_height = static_cast<float>(m_display_active_height);
|
||||
}
|
||||
#else
|
||||
const float y_scale =
|
||||
(static_cast<float>(m_display_width) / static_cast<float>(m_display_height)) / m_display_pixel_aspect_ratio;
|
||||
const float display_width = static_cast<float>(m_display_width);
|
||||
|
@ -54,7 +28,6 @@ std::tuple<s32, s32, s32, s32> HostDisplay::CalculateDrawRect() const
|
|||
const float active_top = static_cast<float>(m_display_active_top) * y_scale;
|
||||
const float active_width = static_cast<float>(m_display_active_width);
|
||||
const float active_height = static_cast<float>(m_display_active_height) * y_scale;
|
||||
#endif
|
||||
|
||||
// now fit it within the window
|
||||
const s32 window_width = m_window_width;
|
||||
|
|
|
@ -880,6 +880,7 @@ void HostInterface::SetDefaultSettings(SettingsInterface& si)
|
|||
si.SetBoolValue("GPU", "ForceNTSCTimings", false);
|
||||
|
||||
si.SetStringValue("Display", "CropMode", "Overscan");
|
||||
si.SetStringValue("Display", "PixelAspectRatio", "4:3");
|
||||
si.SetBoolValue("Display", "ForceProgressiveScan", true);
|
||||
si.SetBoolValue("Display", "LinearFiltering", true);
|
||||
si.SetBoolValue("Display", "ShowOSDMessages", true);
|
||||
|
@ -934,6 +935,7 @@ void HostInterface::UpdateSettings(const std::function<void()>& apply_callback)
|
|||
const bool old_audio_sync_enabled = m_settings.audio_sync_enabled;
|
||||
const bool old_speed_limiter_enabled = m_settings.speed_limiter_enabled;
|
||||
const DisplayCropMode old_display_crop_mode = m_settings.display_crop_mode;
|
||||
const DisplayAspectRatio old_display_aspect_ratio = m_settings.display_aspect_ratio;
|
||||
const bool old_display_linear_filtering = m_settings.display_linear_filtering;
|
||||
const bool old_cdrom_read_thread = m_settings.cdrom_read_thread;
|
||||
std::array<ControllerType, NUM_CONTROLLER_AND_CARD_PORTS> old_controller_types = m_settings.controller_types;
|
||||
|
@ -983,7 +985,8 @@ void HostInterface::UpdateSettings(const std::function<void()>& apply_callback)
|
|||
m_settings.gpu_texture_filtering != old_gpu_texture_filtering ||
|
||||
m_settings.gpu_force_ntsc_timings != old_gpu_force_ntsc_timings ||
|
||||
m_settings.display_force_progressive_scan != old_display_force_progressive_scan ||
|
||||
m_settings.display_crop_mode != old_display_crop_mode)
|
||||
m_settings.display_crop_mode != old_display_crop_mode ||
|
||||
m_settings.display_aspect_ratio != old_display_aspect_ratio)
|
||||
{
|
||||
m_system->UpdateGPUSettings();
|
||||
}
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
#include "types.h"
|
||||
|
||||
static constexpr u32 SAVE_STATE_MAGIC = 0x43435544;
|
||||
static constexpr u32 SAVE_STATE_VERSION = 20;
|
||||
static constexpr u32 SAVE_STATE_VERSION = 21;
|
||||
|
|
|
@ -32,6 +32,10 @@ void Settings::Load(SettingsInterface& si)
|
|||
display_crop_mode = ParseDisplayCropMode(
|
||||
si.GetStringValue("Display", "CropMode", GetDisplayCropModeName(DisplayCropMode::None)).c_str())
|
||||
.value_or(DisplayCropMode::None);
|
||||
display_aspect_ratio =
|
||||
ParseDisplayAspectRatio(
|
||||
si.GetStringValue("Display", "AspectRatio", GetDisplayAspectRatioName(DisplayAspectRatio::R4_3)).c_str())
|
||||
.value_or(DisplayAspectRatio::R4_3);
|
||||
display_force_progressive_scan = si.GetBoolValue("Display", "ForceProgressiveScan", true);
|
||||
display_linear_filtering = si.GetBoolValue("Display", "LinearFiltering", true);
|
||||
display_show_osd_messages = si.GetBoolValue("Display", "ShowOSDMessages", true);
|
||||
|
@ -93,6 +97,7 @@ void Settings::Save(SettingsInterface& si) const
|
|||
si.SetBoolValue("GPU", "ForceNTSCTimings", gpu_force_ntsc_timings);
|
||||
|
||||
si.SetStringValue("Display", "CropMode", GetDisplayCropModeName(display_crop_mode));
|
||||
si.SetStringValue("Display", "AspectRatio", GetDisplayAspectRatioName(display_aspect_ratio));
|
||||
si.SetBoolValue("Display", "ForceProgressiveScan", display_force_progressive_scan);
|
||||
si.SetBoolValue("Display", "LinearFiltering", display_linear_filtering);
|
||||
si.SetBoolValue("Display", "ShowOSDMessages", display_show_osd_messages);
|
||||
|
@ -288,6 +293,33 @@ const char* Settings::GetDisplayCropModeDisplayName(DisplayCropMode crop_mode)
|
|||
return s_display_crop_mode_display_names[static_cast<int>(crop_mode)];
|
||||
}
|
||||
|
||||
static std::array<const char*, 3> s_display_aspect_ratio_names = {{"4:3", "16:9", "1:1"}};
|
||||
static constexpr std::array<float, 3> s_display_aspect_ratio_values = {{4.0f / 3.0f, 16.0f / 9.0f, 1.0f}};
|
||||
|
||||
std::optional<DisplayAspectRatio> Settings::ParseDisplayAspectRatio(const char* str)
|
||||
{
|
||||
int index = 0;
|
||||
for (const char* name : s_display_aspect_ratio_names)
|
||||
{
|
||||
if (StringUtil::Strcasecmp(name, str) == 0)
|
||||
return static_cast<DisplayAspectRatio>(index);
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const char* Settings::GetDisplayAspectRatioName(DisplayAspectRatio ar)
|
||||
{
|
||||
return s_display_aspect_ratio_names[static_cast<int>(ar)];
|
||||
}
|
||||
|
||||
float Settings::GetDisplayAspectRatioValue(DisplayAspectRatio ar)
|
||||
{
|
||||
return s_display_aspect_ratio_values[static_cast<int>(ar)];
|
||||
}
|
||||
|
||||
static std::array<const char*, 3> s_audio_backend_names = {{"Null", "Cubeb", "SDL"}};
|
||||
static std::array<const char*, 3> s_audio_backend_display_names = {{"Null (No Output)", "Cubeb", "SDL"}};
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ struct Settings
|
|||
bool gpu_use_debug_device = false;
|
||||
bool gpu_force_ntsc_timings = false;
|
||||
DisplayCropMode display_crop_mode = DisplayCropMode::None;
|
||||
DisplayAspectRatio display_aspect_ratio = DisplayAspectRatio::R4_3;
|
||||
bool display_force_progressive_scan = false;
|
||||
bool display_linear_filtering = true;
|
||||
bool display_show_osd_messages = false;
|
||||
|
@ -114,6 +115,10 @@ struct Settings
|
|||
static const char* GetDisplayCropModeName(DisplayCropMode crop_mode);
|
||||
static const char* GetDisplayCropModeDisplayName(DisplayCropMode crop_mode);
|
||||
|
||||
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);
|
||||
static const char* GetAudioBackendDisplayName(AudioBackend backend);
|
||||
|
|
|
@ -66,6 +66,14 @@ enum class DisplayCropMode : u8
|
|||
Count
|
||||
};
|
||||
|
||||
enum class DisplayAspectRatio : u8
|
||||
{
|
||||
R4_3,
|
||||
R16_9,
|
||||
R1_1,
|
||||
Count
|
||||
};
|
||||
|
||||
enum class AudioBackend : u8
|
||||
{
|
||||
Null,
|
||||
|
|
|
@ -12,7 +12,10 @@ GPUSettingsWidget::GPUSettingsWidget(QtHostInterface* host_interface, QWidget* p
|
|||
SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.renderer, "GPU/Renderer",
|
||||
&Settings::ParseRendererName, &Settings::GetRendererName);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.useDebugDevice, "GPU/UseDebugDevice");
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.cropMode, "Display/CropMode",
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.displayAspectRatio, "Display/AspectRatio",
|
||||
&Settings::ParseDisplayAspectRatio,
|
||||
&Settings::GetDisplayAspectRatioName);
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.displayCropMode, "Display/CropMode",
|
||||
&Settings::ParseDisplayCropMode, &Settings::GetDisplayCropModeName);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.forceProgressiveScan,
|
||||
"Display/ForceProgressiveScan");
|
||||
|
@ -46,9 +49,15 @@ void GPUSettingsWidget::setupAdditionalUi()
|
|||
for (u32 i = 0; i < static_cast<u32>(GPURenderer::Count); i++)
|
||||
m_ui.renderer->addItem(QString::fromLocal8Bit(Settings::GetRendererDisplayName(static_cast<GPURenderer>(i))));
|
||||
|
||||
for (u32 i = 0; i < static_cast<u32>(DisplayAspectRatio::Count); i++)
|
||||
{
|
||||
m_ui.displayAspectRatio->addItem(
|
||||
QString::fromLocal8Bit(Settings::GetDisplayAspectRatioName(static_cast<DisplayAspectRatio>(i))));
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < static_cast<u32>(DisplayCropMode::Count); i++)
|
||||
{
|
||||
m_ui.cropMode->addItem(
|
||||
m_ui.displayCropMode->addItem(
|
||||
QString::fromLocal8Bit(Settings::GetDisplayCropModeDisplayName(static_cast<DisplayCropMode>(i))));
|
||||
}
|
||||
|
||||
|
|
|
@ -59,23 +59,33 @@
|
|||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Aspect Ratio:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="displayAspectRatio"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Crop:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="cropMode"/>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="displayCropMode"/>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="displayLinearFiltering">
|
||||
<property name="text">
|
||||
<string>Linear Upscaling</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="vsync">
|
||||
<property name="text">
|
||||
<string>VSync</string>
|
||||
|
|
|
@ -1245,6 +1245,21 @@ void SDLHostInterface::DrawSettingsWindow()
|
|||
|
||||
if (DrawSettingsSectionHeader("Display Output"))
|
||||
{
|
||||
ImGui::Text("Aspect Ratio:");
|
||||
ImGui::SameLine(indent);
|
||||
int display_aspect_ratio = static_cast<int>(m_settings_copy.display_aspect_ratio);
|
||||
if (ImGui::Combo(
|
||||
"##display_pixel_aspect_ratio", &display_aspect_ratio,
|
||||
[](void*, int index, const char** out_text) {
|
||||
*out_text = Settings::GetDisplayAspectRatioName(static_cast<DisplayAspectRatio>(index));
|
||||
return true;
|
||||
},
|
||||
nullptr, static_cast<int>(DisplayAspectRatio::Count)))
|
||||
{
|
||||
m_settings_copy.display_aspect_ratio = static_cast<DisplayAspectRatio>(display_aspect_ratio);
|
||||
settings_changed = true;
|
||||
}
|
||||
|
||||
ImGui::Text("Crop:");
|
||||
ImGui::SameLine(indent);
|
||||
|
||||
|
|
Loading…
Reference in a new issue