From 1400534127bdf717cd1ea9cf0252bd441f0dd7cd Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 28 Sep 2019 00:53:11 +1000 Subject: [PATCH] GPU/SDL: Correct aspect ratio when displaying --- src/pse-sdl/sdl_interface.cpp | 36 +++++++++++++++++++++++++++++++---- src/pse-sdl/sdl_interface.h | 3 ++- src/pse/gpu.h | 1 + src/pse/gpu_hw_opengl.cpp | 8 ++++---- src/pse/host_interface.h | 2 +- 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/pse-sdl/sdl_interface.cpp b/src/pse-sdl/sdl_interface.cpp index 10e5caa5f..28ab2fc63 100644 --- a/src/pse-sdl/sdl_interface.cpp +++ b/src/pse-sdl/sdl_interface.cpp @@ -371,12 +371,38 @@ void SDLInterface::Render() ImGui::NewFrame(); } +static std::tuple CalculateDrawRect(int window_width, int window_height, float display_ratio) +{ + const float window_ratio = float(window_width) / float(window_height); + int left, top, width, height; + if (window_ratio >= display_ratio) + { + width = static_cast(float(window_height) * display_ratio); + height = static_cast(window_height); + left = (window_width - width) / 2; + top = 0; + } + else + { + width = static_cast(window_width); + height = static_cast(float(window_width) / display_ratio); + left = 0; + top = (window_height - height) / 2; + } + + return std::tie(left, top, width, height); +} + void SDLInterface::RenderDisplay() { if (!m_display_texture) return; - glViewport(0, 0, m_window_width, m_window_height - 20); + // - 20 for main menu padding + const auto [vp_left, vp_top, vp_width, vp_height] = + CalculateDrawRect(m_window_width, std::max(m_window_height - 20, 1), m_display_aspect_ratio); + + glViewport(vp_left, m_window_height - (20 + vp_top) - vp_height, vp_width, vp_height); glDisable(GL_BLEND); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); @@ -473,13 +499,15 @@ void SDLInterface::AddOSDMessage(const char* message, float duration /*= 2.0f*/) m_osd_messages.push_back(std::move(msg)); } -void SDLInterface::SetDisplayTexture(GL::Texture* texture, u32 offset_x, u32 offset_y, u32 width, u32 height) +void SDLInterface::SetDisplayTexture(GL::Texture* texture, u32 offset_x, u32 offset_y, u32 width, u32 height, + float aspect_ratio) { m_display_texture = texture; - m_display_texture_offset_x = 0; - m_display_texture_offset_y = 0; + m_display_texture_offset_x = offset_x; + m_display_texture_offset_y = offset_y; m_display_texture_width = width; m_display_texture_height = height; + m_display_aspect_ratio = aspect_ratio; m_display_texture_changed = true; } diff --git a/src/pse-sdl/sdl_interface.h b/src/pse-sdl/sdl_interface.h index 068a5e4fa..10caa5cc0 100644 --- a/src/pse-sdl/sdl_interface.h +++ b/src/pse-sdl/sdl_interface.h @@ -23,7 +23,7 @@ public: static TinyString GetSaveStateFilename(u32 index); - void SetDisplayTexture(GL::Texture* texture, u32 offset_x, u32 offset_y, u32 width, u32 height) override; + void SetDisplayTexture(GL::Texture* texture, u32 offset_x, u32 offset_y, u32 width, u32 height, float aspect_ratio) override; void ReportMessage(const char* message) override; @@ -70,6 +70,7 @@ private: u32 m_display_texture_offset_y = 0; u32 m_display_texture_width = 0; u32 m_display_texture_height = 0; + float m_display_aspect_ratio = 1.0f; bool m_display_texture_changed = false; std::deque m_osd_messages; diff --git a/src/pse/gpu.h b/src/pse/gpu.h index b82cf7812..472241c33 100644 --- a/src/pse/gpu.h +++ b/src/pse/gpu.h @@ -37,6 +37,7 @@ public: void Execute(TickCount ticks); protected: + static constexpr float DISPLAY_ASPECT_RATIO = 4.0f / 3.0f; static constexpr u32 VRAM_WIDTH = 1024; static constexpr u32 VRAM_HEIGHT = 512; static constexpr u32 VRAM_SIZE = VRAM_WIDTH * VRAM_HEIGHT * sizeof(u16); diff --git a/src/pse/gpu_hw_opengl.cpp b/src/pse/gpu_hw_opengl.cpp index 6c180581d..55f13e410 100644 --- a/src/pse/gpu_hw_opengl.cpp +++ b/src/pse/gpu_hw_opengl.cpp @@ -23,6 +23,7 @@ bool GPU_HW_OpenGL::Initialize(System* system, DMA* dma, InterruptController* in if (!CompilePrograms()) return false; + m_system->GetHostInterface()->SetDisplayTexture(m_display_texture.get(), 0, 0, VRAM_WIDTH, VRAM_HEIGHT, 1.0f); return true; } @@ -123,8 +124,6 @@ void GPU_HW_OpenGL::ClearFramebuffer() glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); glBindFramebuffer(GL_FRAMEBUFFER, 0); - - m_system->GetHostInterface()->SetDisplayTexture(m_framebuffer_texture.get(), 0, 0, VRAM_WIDTH, VRAM_HEIGHT); } void GPU_HW_OpenGL::DestroyFramebuffer() @@ -287,7 +286,7 @@ void GPU_HW_OpenGL::UpdateDisplay() // TODO: 24-bit support. if (m_show_vram) { - m_system->GetHostInterface()->SetDisplayTexture(m_framebuffer_texture.get(), 0, 0, VRAM_WIDTH, VRAM_HEIGHT); + m_system->GetHostInterface()->SetDisplayTexture(m_framebuffer_texture.get(), 0, 0, VRAM_WIDTH, VRAM_HEIGHT, 1.0f); } else { @@ -303,7 +302,8 @@ void GPU_HW_OpenGL::UpdateDisplay() VRAM_HEIGHT - vram_offset_y - copy_height, 0, m_display_texture->GetGLId(), GL_TEXTURE_2D, 0, 0, 0, 0, copy_width, copy_height, 1); - m_system->GetHostInterface()->SetDisplayTexture(m_display_texture.get(), 0, 0, copy_width, copy_height); + m_system->GetHostInterface()->SetDisplayTexture(m_display_texture.get(), 0, 0, copy_width, copy_height, + DISPLAY_ASPECT_RATIO); } } diff --git a/src/pse/host_interface.h b/src/pse/host_interface.h index 4127335b1..c5fdd730f 100644 --- a/src/pse/host_interface.h +++ b/src/pse/host_interface.h @@ -16,7 +16,7 @@ public: bool InitializeSystem(const char* filename, const char* exp1_filename, const char* save_state_filename); - virtual void SetDisplayTexture(GL::Texture* texture, u32 offset_x, u32 offset_y, u32 width, u32 height) = 0; + virtual void SetDisplayTexture(GL::Texture* texture, u32 offset_x, u32 offset_y, u32 width, u32 height, float aspect_ratio) = 0; virtual void ReportMessage(const char* message) = 0; // Adds OSD messages, duration is in seconds.