GPU: Compute display aspect ratio based on visible area
This commit is contained in:
parent
2e70c22422
commit
1b8b730f85
|
@ -348,6 +348,54 @@ void GPU::UpdateCRTCConfig()
|
||||||
if (cs.display_width != old_horizontal_resolution || cs.display_height != old_vertical_resolution)
|
if (cs.display_width != old_horizontal_resolution || cs.display_height != old_vertical_resolution)
|
||||||
Log_InfoPrintf("Visible resolution is now %ux%u", cs.display_width, cs.display_height);
|
Log_InfoPrintf("Visible resolution is now %ux%u", cs.display_width, cs.display_height);
|
||||||
|
|
||||||
|
// Compute the aspect ratio necessary to display borders in the inactive region of the picture.
|
||||||
|
// Convert total dots/lines to time.
|
||||||
|
const float dot_clock =
|
||||||
|
(static_cast<float>(MASTER_CLOCK) * (11.0f / 7.0f / static_cast<float>(cs.dot_clock_divider)));
|
||||||
|
const float dot_clock_period = 1.0f / dot_clock;
|
||||||
|
const float dots_per_scanline = static_cast<float>(cs.ticks_per_scanline) / static_cast<float>(cs.dot_clock_divider);
|
||||||
|
const float horizontal_period = dots_per_scanline * dot_clock_period;
|
||||||
|
const float vertical_period = horizontal_period * static_cast<float>(cs.total_scanlines_per_frame);
|
||||||
|
|
||||||
|
// Convert active dots/lines to time.
|
||||||
|
const float visible_dots_per_scanline =
|
||||||
|
static_cast<float>(cs.visible_ticks_per_scanline) / static_cast<float>(cs.dot_clock_divider);
|
||||||
|
const float horizontal_active_time = horizontal_period * visible_dots_per_scanline;
|
||||||
|
const float vertical_active_time = horizontal_active_time * static_cast<float>(cs.visible_scanlines_per_frame);
|
||||||
|
|
||||||
|
// Use the reference active time/lines for the signal to work out the border area, and thus aspect ratio
|
||||||
|
// transformation for the active area in our framebuffer. For the purposes of these calculations, we're assuming
|
||||||
|
// progressive scan.
|
||||||
|
float display_ratio;
|
||||||
|
if (m_GPUSTAT.pal_mode)
|
||||||
|
{
|
||||||
|
// Wikipedia says PAL is active 51.95us of 64.00us, and 576/625 lines.
|
||||||
|
const float signal_horizontal_active_time = 51.95f;
|
||||||
|
const float signal_horizontal_total_time = 64.0f;
|
||||||
|
const float signal_vertical_active_lines = 576.0f;
|
||||||
|
const float signal_vertical_total_lines = 625.0f;
|
||||||
|
const float h_ratio =
|
||||||
|
(horizontal_active_time / horizontal_period) * (signal_horizontal_total_time / signal_horizontal_active_time);
|
||||||
|
const float v_ratio =
|
||||||
|
(vertical_active_time / vertical_period) * (signal_vertical_total_lines / signal_vertical_active_lines);
|
||||||
|
display_ratio = h_ratio / v_ratio;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const float signal_horizontal_active_time = 52.66f;
|
||||||
|
const float signal_horizontal_total_time = 63.56f;
|
||||||
|
const float signal_vertical_active_lines = 486.0f;
|
||||||
|
const float signal_vertical_total_lines = 525.0f;
|
||||||
|
const float h_ratio =
|
||||||
|
(horizontal_active_time / horizontal_period) * (signal_horizontal_total_time / signal_horizontal_active_time);
|
||||||
|
const float v_ratio =
|
||||||
|
(vertical_active_time / vertical_period) * (signal_vertical_total_lines / signal_vertical_active_lines);
|
||||||
|
display_ratio = h_ratio / v_ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the numbers are sane, and not due to a misconfigured active display range.
|
||||||
|
cs.display_aspect_ratio = (std::isnormal(display_ratio) && display_ratio != 0.0f) ? display_ratio : (4.0f / 3.0f);
|
||||||
|
|
||||||
UpdateSliceTicks();
|
UpdateSliceTicks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ class Timers;
|
||||||
class GPU
|
class GPU
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static constexpr float DISPLAY_ASPECT_RATIO = 4.0f / 3.0f;
|
|
||||||
enum : u32
|
enum : u32
|
||||||
{
|
{
|
||||||
VRAM_WIDTH = 1024,
|
VRAM_WIDTH = 1024,
|
||||||
|
@ -342,6 +341,8 @@ protected:
|
||||||
TickCount current_tick_in_scanline;
|
TickCount current_tick_in_scanline;
|
||||||
u32 current_scanline;
|
u32 current_scanline;
|
||||||
|
|
||||||
|
float display_aspect_ratio;
|
||||||
|
|
||||||
bool in_hblank;
|
bool in_hblank;
|
||||||
bool in_vblank;
|
bool in_vblank;
|
||||||
} m_crtc_state = {};
|
} m_crtc_state = {};
|
||||||
|
|
|
@ -492,7 +492,7 @@ void GPU_HW_OpenGL::UpdateDisplay()
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
m_system->GetHostInterface()->SetDisplayTexture(m_display_texture.get(), 0, 0, display_width, display_height,
|
m_system->GetHostInterface()->SetDisplayTexture(m_display_texture.get(), 0, 0, display_width, display_height,
|
||||||
DISPLAY_ASPECT_RATIO);
|
m_crtc_state.display_aspect_ratio);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -501,7 +501,7 @@ void GPU_HW_OpenGL::UpdateDisplay()
|
||||||
scaled_display_width, scaled_display_height, 1);
|
scaled_display_width, scaled_display_height, 1);
|
||||||
|
|
||||||
m_system->GetHostInterface()->SetDisplayTexture(m_display_texture.get(), 0, 0, scaled_display_width,
|
m_system->GetHostInterface()->SetDisplayTexture(m_display_texture.get(), 0, 0, scaled_display_width,
|
||||||
scaled_display_height, DISPLAY_ASPECT_RATIO);
|
scaled_display_height, m_crtc_state.display_aspect_ratio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue