mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
widescreen: fix vertical-double-buffer top/bottom flicker (rt_wide Y-clip)
The native-wide mirror target clipped Y to the full surface (0..511), but a vertically double-buffered game (MMX6: front y0..239 / back y240..479, both sharing base_x=0) keeps both buffers in one shared wide surface. The background tile loop starts a partial top row at y = buffer_top - (scrollY & 0xf), so back-buffer draws bled across the band boundary into the front buffer's region of the wide surface -> top/bottom edge flicker as the buffers flipped. Canonical VRAM never showed it because its draw-area clip already confines each buffer. Clip the wide target's Y to the canonical draw area (g_clip_y1..g_clip_y2), exactly like rt_native, so each buffer's draws stay in its own band. X still spans the full wide width (that is where the reveal margins live). User-confirmed the top/bottom flicker is fixed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -146,17 +146,23 @@ static inline RTarget rt_hires(void) {
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Native-wide mirror target: the active wide surface (g_wide_cur). Clip is the
|
||||
* full surface; callers pass coordinates already translated into surface space
|
||||
* (vram_x - base_x + OFFSET) and y-clipped to the buffer's band via the source
|
||||
* primitive. Scale matches the SSAA scale. Only used when g_wide_cur != NULL. */
|
||||
/* Native-wide mirror target: the active wide surface (g_wide_cur). X spans the
|
||||
* full wide width (that is where the revealed margins live), but Y is clipped to
|
||||
* the canonical DRAW AREA — exactly like rt_native — so a primitive that bleeds
|
||||
* past the current framebuffer's vertical band is confined to it. This matters
|
||||
* for VERTICALLY double-buffered games (e.g. MMX6: front y0..239 / back
|
||||
* y240..479, same base_x): the background tile loop starts a partial row at
|
||||
* y = buffer_top - (scrollY & 0xf), which without the band clip would draw up
|
||||
* into the OTHER buffer's band in the shared wide surface and corrupt it
|
||||
* (top/bottom edge flicker as the buffers flip). Canonical VRAM never showed
|
||||
* this because its draw-area clip already confines it. Scale matches SSAA. */
|
||||
static inline RTarget rt_wide(void) {
|
||||
int s = g_scale;
|
||||
RTarget t;
|
||||
t.buf = g_wide_cur;
|
||||
t.w = g_wide_w * s; t.h = VRAM_HEIGHT * s; t.s = s;
|
||||
t.cx1 = 0; t.cy1 = 0;
|
||||
t.cx2 = g_wide_w * s - 1; t.cy2 = VRAM_HEIGHT * s - 1;
|
||||
t.cx1 = 0; t.cy1 = g_clip_y1 * s;
|
||||
t.cx2 = g_wide_w * s - 1; t.cy2 = g_clip_y2 * s + (s - 1);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user