diff --git a/src/core/gpu.cpp b/src/core/gpu.cpp index 5fd7f92c6..1dbb4d9d5 100644 --- a/src/core/gpu.cpp +++ b/src/core/gpu.cpp @@ -90,10 +90,11 @@ bool GPU::DoState(StateWrapper& sw) sw.Do(&m_crtc_state.horizontal_resolution); sw.Do(&m_crtc_state.vertical_resolution); sw.Do(&m_crtc_state.dot_clock_divider); - sw.Do(&m_crtc_state.visible_horizontal_resolution); - sw.Do(&m_crtc_state.visible_vertical_resolution); + sw.Do(&m_crtc_state.display_width); + sw.Do(&m_crtc_state.display_height); sw.Do(&m_crtc_state.ticks_per_scanline); sw.Do(&m_crtc_state.visible_ticks_per_scanline); + sw.Do(&m_crtc_state.visible_scanlines_per_frame); sw.Do(&m_crtc_state.total_scanlines_per_frame); sw.Do(&m_crtc_state.fractional_ticks); sw.Do(&m_crtc_state.current_tick_in_scanline); @@ -308,28 +309,11 @@ void GPU::DMAWrite(const u32* words, u32 word_count) void GPU::UpdateCRTCConfig() { - static constexpr std::array dot_clock_dividers = {{8, 4, 10, 5, 7, 7, 7, 7}}; - static constexpr std::array horizontal_resolutions = {{256, 320, 512, 630, 368, 368, 368, 368}}; + static constexpr std::array dot_clock_dividers = {{10, 8, 5, 4, 7, 7, 7, 7}}; + static constexpr std::array horizontal_resolutions = {{256, 320, 512, 640, 368, 368, 368, 368}}; static constexpr std::array vertical_resolutions = {{240, 480}}; CRTCState& cs = m_crtc_state; - const u8 horizontal_resolution_index = m_GPUSTAT.horizontal_resolution_1 | (m_GPUSTAT.horizontal_resolution_2 << 2); - cs.dot_clock_divider = dot_clock_dividers[horizontal_resolution_index]; - cs.horizontal_resolution = horizontal_resolutions[horizontal_resolution_index]; - cs.vertical_resolution = - vertical_resolutions[BoolToUInt8(m_GPUSTAT.vertical_interlace && m_GPUSTAT.vertical_resolution)]; - - // check for a change in resolution - const u32 old_horizontal_resolution = cs.visible_horizontal_resolution; - const u32 old_vertical_resolution = cs.visible_vertical_resolution; - cs.visible_horizontal_resolution = std::max((cs.regs.X2 - cs.regs.X1) / cs.dot_clock_divider, u32(1)); - cs.visible_vertical_resolution = cs.regs.Y2 - cs.regs.Y1 + 1; - if (cs.visible_horizontal_resolution != old_horizontal_resolution || - cs.visible_vertical_resolution != old_vertical_resolution) - { - Log_InfoPrintf("Visible resolution is now %ux%u", cs.visible_horizontal_resolution, cs.visible_vertical_resolution); - } - if (m_GPUSTAT.pal_mode) { cs.total_scanlines_per_frame = 314; @@ -341,6 +325,29 @@ void GPU::UpdateCRTCConfig() cs.ticks_per_scanline = 3413; } + const u8 horizontal_resolution_index = m_GPUSTAT.horizontal_resolution_1 | (m_GPUSTAT.horizontal_resolution_2 << 2); + cs.dot_clock_divider = dot_clock_dividers[horizontal_resolution_index]; + cs.horizontal_resolution = horizontal_resolutions[horizontal_resolution_index]; + cs.vertical_resolution = + vertical_resolutions[BoolToUInt8(m_GPUSTAT.vertical_interlace && m_GPUSTAT.vertical_resolution)]; + cs.visible_ticks_per_scanline = cs.regs.X2 - cs.regs.X1; + cs.visible_scanlines_per_frame = cs.regs.Y2 - cs.regs.Y1; + + // check for a change in resolution + const u32 old_horizontal_resolution = cs.display_width; + const u32 old_vertical_resolution = cs.display_height; + cs.display_width = std::max(cs.visible_ticks_per_scanline / cs.dot_clock_divider, 1); + cs.display_height = cs.visible_scanlines_per_frame; + + if (m_GPUSTAT.vertical_interlace) + { + // Force progressive for now. + cs.display_height *= 2; + } + + 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); + UpdateSliceTicks(); } @@ -393,7 +400,7 @@ void GPU::Execute(TickCount ticks) } const bool old_vblank = m_crtc_state.in_vblank; - const bool new_vblank = m_crtc_state.current_scanline >= m_crtc_state.visible_vertical_resolution; + const bool new_vblank = m_crtc_state.current_scanline >= m_crtc_state.visible_scanlines_per_frame; if (new_vblank != old_vblank) { m_crtc_state.in_vblank = new_vblank; @@ -445,7 +452,6 @@ void GPU::WriteGP0(u32 value) UpdateGPUSTAT(); } - void GPU::WriteGP1(u32 value) { const u8 command = Truncate8(value >> 24); @@ -756,9 +762,9 @@ void GPU::DrawDebugStateWindow() cs.regs.Y2.GetValue()); ImGui::NewLine(); - ImGui::Text("Visible Resolution: %ux%u", cs.visible_horizontal_resolution, cs.visible_vertical_resolution); + ImGui::Text("Display Resolution: %ux%u", cs.display_width, cs.display_height); ImGui::Text("Ticks Per Scanline: %u (%u visible)", cs.ticks_per_scanline, cs.visible_ticks_per_scanline); - ImGui::Text("Scanlines Per Frame: %u", cs.total_scanlines_per_frame); + ImGui::Text("Scanlines Per Frame: %u (%u visible)", cs.total_scanlines_per_frame, cs.visible_scanlines_per_frame); ImGui::Text("Current Scanline: %u (tick %u)", cs.current_scanline, cs.current_tick_in_scanline); ImGui::Text("Horizontal Blank: %s", cs.in_hblank ? "Yes" : "No"); ImGui::Text("Vertical Blank: %s", cs.in_vblank ? "Yes" : "No"); diff --git a/src/core/gpu.h b/src/core/gpu.h index 7ab4a26e7..53762510c 100644 --- a/src/core/gpu.h +++ b/src/core/gpu.h @@ -330,11 +330,12 @@ protected: u32 vertical_resolution; TickCount dot_clock_divider; - u32 visible_horizontal_resolution; - u32 visible_vertical_resolution; + u32 display_width; + u32 display_height; TickCount ticks_per_scanline; TickCount visible_ticks_per_scanline; + u32 visible_scanlines_per_frame; u32 total_scanlines_per_frame; TickCount fractional_ticks; diff --git a/src/core/gpu_hw_opengl.cpp b/src/core/gpu_hw_opengl.cpp index bda6613c8..68b161cdd 100644 --- a/src/core/gpu_hw_opengl.cpp +++ b/src/core/gpu_hw_opengl.cpp @@ -452,8 +452,8 @@ void GPU_HW_OpenGL::UpdateDisplay() const u32 vram_offset_y = m_crtc_state.regs.Y; const u32 scaled_vram_offset_x = vram_offset_x * m_resolution_scale; const u32 scaled_vram_offset_y = vram_offset_y * m_resolution_scale; - const u32 display_width = std::min(m_crtc_state.horizontal_resolution, VRAM_WIDTH - vram_offset_x); - const u32 display_height = std::min(m_crtc_state.vertical_resolution, VRAM_HEIGHT - vram_offset_y); + const u32 display_width = std::min(m_crtc_state.display_width, VRAM_WIDTH - vram_offset_x); + const u32 display_height = std::min(m_crtc_state.display_height, VRAM_HEIGHT - vram_offset_y); const u32 scaled_display_width = display_width * m_resolution_scale; const u32 scaled_display_height = display_height * m_resolution_scale; const u32 flipped_vram_offset_y = VRAM_HEIGHT - vram_offset_y - display_height;