From 4f206d2773a09942669b2263032deba6657dc69a Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 12 Jul 2022 15:55:49 +0200 Subject: [PATCH] pvr: set correct framebuffer size in 240p/pixel_double Some games use 240p and pixel_double resulting in a 320x240 framebuffer. Renderer should be resized accordingly. Fixes linear filtering artifact in KoF dream match 1999 (Issue #690) --- core/emulator.cpp | 1 + core/hw/pvr/Renderer_if.cpp | 31 ++++++++++++++++++++++--------- core/hw/pvr/Renderer_if.h | 1 + core/hw/pvr/pvr_regs.cpp | 11 +++++++++++ 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/core/emulator.cpp b/core/emulator.cpp index 22ddf1b9f..0841862eb 100644 --- a/core/emulator.cpp +++ b/core/emulator.cpp @@ -811,6 +811,7 @@ bool Emulator::checkStatus() bool Emulator::render() { + rend_resize_renderer_if_needed(); if (!config::ThreadedRendering) { if (state != Running) diff --git a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp index 2445cf983..6bf4f410d 100644 --- a/core/hw/pvr/Renderer_if.cpp +++ b/core/hw/pvr/Renderer_if.cpp @@ -38,6 +38,7 @@ bool fb_dirty; static bool pend_rend; TA_context* _pvrrc; +extern bool rend_needs_resize; static bool rend_frame(TA_context* ctx) { @@ -363,32 +364,44 @@ void rend_deserialize(Deserializer& deser) deser >> fb_watch_addr_end; } pend_rend = false; + rend_needs_resize = true; } void rend_resize_renderer() { if (renderer == nullptr) return; - float hres; - int vres = config::RenderResolution; + int fbwidth = VO_CONTROL.pixel_double ? 320 : 640; + int fbheight = (SPG_CONTROL.PAL == SPG_CONTROL.NTSC) || SPG_CONTROL.interlace == 1 ? 480 : 240; + + float upscaling = config::RenderResolution / 480.f; + float hres = fbwidth * upscaling; + float vres = fbheight * upscaling; if (config::Widescreen && !config::Rotate90) { if (config::SuperWidescreen) - hres = (float)config::RenderResolution * settings.display.width / settings.display.height; + hres = vres * settings.display.width / settings.display.height; else - hres = config::RenderResolution * 16.f / 9.f; + hres *= 4.f / 3.f; } else if (config::Rotate90) { - vres = vres * config::ScreenStretching / 100; - hres = config::RenderResolution * 4.f / 3.f; + vres *= config::ScreenStretching / 100.f; } else { - hres = config::RenderResolution * 4.f * config::ScreenStretching / 3.f / 100.f; + hres *= config::ScreenStretching / 100.f; } if (!config::Rotate90) hres = std::roundf(hres / 2.f) * 2.f; - DEBUG_LOG(RENDERER, "rend_resize_renderer: %d x %d", (int)hres, vres); - renderer->Resize((int)hres, vres); + DEBUG_LOG(RENDERER, "rend_resize_renderer: %d x %d", (int)hres, (int)vres); + renderer->Resize((int)hres, (int)vres); + rend_needs_resize = false; +} + +void rend_resize_renderer_if_needed() +{ + if (!rend_needs_resize) + return; + rend_resize_renderer(); } diff --git a/core/hw/pvr/Renderer_if.h b/core/hw/pvr/Renderer_if.h index e5ac5f50b..5e8b80e51 100644 --- a/core/hw/pvr/Renderer_if.h +++ b/core/hw/pvr/Renderer_if.h @@ -21,6 +21,7 @@ void rend_allow_rollback(); void rend_serialize(Serializer& ser); void rend_deserialize(Deserializer& deser); void rend_resize_renderer(); +void rend_resize_renderer_if_needed(); /////// extern TA_context* _pvrrc; diff --git a/core/hw/pvr/pvr_regs.cpp b/core/hw/pvr/pvr_regs.cpp index 261b5babd..bedd415eb 100644 --- a/core/hw/pvr/pvr_regs.cpp +++ b/core/hw/pvr/pvr_regs.cpp @@ -7,6 +7,7 @@ bool pal_needs_update=true; bool fog_needs_update=true; +bool rend_needs_resize = true; u8 pvr_regs[pvr_RegSize]; @@ -159,6 +160,16 @@ void pvr_WriteReg(u32 paddr,u32 data) { PvrReg(addr, u32) = data; CalculateSync(); + if (addr == SPG_CONTROL_addr) + rend_needs_resize = true; + } + return; + + case VO_CONTROL_addr: + if (PvrReg(addr, u32) != data) + { + PvrReg(addr, u32) = data; + rend_needs_resize = true; } return;