mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
patch FMV playback, fix artifact flicker on cutover to new video
This commit is contained in:
@@ -44,6 +44,10 @@ uint32_t gpu_display_pixel_argb(const GpuDisplayInfo* di, uint32_t x, uint32_t y
|
||||
* trailing margin without shrinking the CRTC-derived width globally. */
|
||||
uint32_t gpu_depth24_rgb_limit(uint32_t display_x, uint32_t crtc_w);
|
||||
void gpu_depth24_upload_span_reset(void);
|
||||
/* MotK intro cuts retarget GP1(07h). While hold > 0, present should skip
|
||||
* Swap (keep prior frame) so stale trailing VRAM never flashes. One tick
|
||||
* per vblank; returns non-zero while the hold is still active after tick. */
|
||||
int gpu_depth24_present_hold_tick(void);
|
||||
/* GP1(06h)/GP1(07h)/GP1(08h) fields for debug (gpu_state). */
|
||||
void gpu_get_crtc_debug(uint32_t *x1, uint32_t *x2, uint32_t *y1, uint32_t *y2,
|
||||
uint32_t *hres1_out, uint32_t *hres2_out);
|
||||
|
||||
+28
-4
@@ -1655,6 +1655,8 @@ static uint16_t vram_write_pixels[1024 * 512];
|
||||
/* Depth24 CPU→VRAM upload span (halfwords, exclusive end). See
|
||||
* gpu_depth24_rgb_limit — declared early so gpu_reset_state can clear it. */
|
||||
static uint32_t s_d24_upload_x1 = 0;
|
||||
static int s_d24_present_hold = 0; /* vblanks to skip Swap after GP1(07h) */
|
||||
static uint32_t s_d24_prev_disp_h = 0; /* last GP1(07h) band height */
|
||||
static void depth24_note_upload(uint32_t x, uint32_t w);
|
||||
|
||||
static void gp0_commit_cpu_to_vram(void) {
|
||||
@@ -1892,6 +1894,8 @@ static void gpu_reset_state(int clear_vram) {
|
||||
s_ws_fmv_frame_cache = 0xFFFFFFFFu;
|
||||
s_ws_fmv_cached = 0;
|
||||
s_d24_upload_x1 = 0;
|
||||
s_d24_present_hold = 0;
|
||||
s_d24_prev_disp_h = 0;
|
||||
}
|
||||
|
||||
void gpu_init(void) {
|
||||
@@ -2070,9 +2074,12 @@ static uint8_t gpu_vram_byte(uint32_t byte_x, uint32_t y) {
|
||||
|
||||
/* Depth24: note/query/reset the CPU→VRAM upload span tracked above. Used to
|
||||
* hide trailing RGB columns when a movie blit doesn't fill the full CRTC
|
||||
* width — MotK's Star Wars crawl leaves ~8px of stale VRAM on the right. */
|
||||
* width — MotK's Star Wars crawl leaves ~8px of stale VRAM on the right.
|
||||
* Only FB-class A0s (w >= 256 halfwords) grow the span; texture uploads must
|
||||
* not collapse it. During present-hold, ignore updates entirely. */
|
||||
static void depth24_note_upload(uint32_t x, uint32_t w) {
|
||||
if (!(display_depth & 1u) || w == 0u) return;
|
||||
if (!(display_depth & 1u) || w < 256u) return;
|
||||
if (s_d24_present_hold > 0) return;
|
||||
uint32_t x1 = x + w;
|
||||
if (x1 > 1024u) x1 = 1024u;
|
||||
if (x1 > s_d24_upload_x1) s_d24_upload_x1 = x1;
|
||||
@@ -2093,6 +2100,12 @@ void gpu_depth24_upload_span_reset(void) {
|
||||
s_d24_upload_x1 = 0;
|
||||
}
|
||||
|
||||
int gpu_depth24_present_hold_tick(void) {
|
||||
if (s_d24_present_hold <= 0) return 0;
|
||||
s_d24_present_hold--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ---- Present-time screen-colour LUT (verified-enhancement, opt-in) -------
|
||||
*
|
||||
* PRESENT-TIME ONLY. This sits on the 15-bit-scanout -> RGB888 conversion that
|
||||
@@ -4192,8 +4205,19 @@ static void gp1_v_display_range(uint32_t val) {
|
||||
/* GP1(07h): Vertical display range
|
||||
* bits 0-9: Y1
|
||||
* bits 10-19: Y2 */
|
||||
v_display_y1 = val & 0x3FF;
|
||||
v_display_y2 = (val >> 10) & 0x3FF;
|
||||
uint32_t y1 = val & 0x3FF;
|
||||
uint32_t y2 = (val >> 10) & 0x3FF;
|
||||
uint32_t h = (y2 > y1) ? (y2 - y1) : 0u;
|
||||
/* MotK intro→crawl retargets the band while staying in depth24. Stale
|
||||
* trailing RGB from the prior movie would flash for a frame or two —
|
||||
* reset the upload span and hold present (skip Swap) for 3 vblanks. */
|
||||
if ((display_depth & 1u) && s_d24_prev_disp_h != 0u && h != s_d24_prev_disp_h) {
|
||||
s_d24_upload_x1 = 0;
|
||||
s_d24_present_hold = 3;
|
||||
}
|
||||
v_display_y1 = y1;
|
||||
v_display_y2 = y2;
|
||||
if (h != 0u) s_d24_prev_disp_h = h;
|
||||
}
|
||||
|
||||
static void gp1_display_mode(uint32_t val) {
|
||||
|
||||
+27
-33
@@ -2998,36 +2998,23 @@ static void load_transition_note(int read_active, int load_active,
|
||||
prev_turbo = turbo_active;
|
||||
}
|
||||
|
||||
/* Depth24 FMV: last ~8 RGB columns can be stale/chroma junk while CRTC width
|
||||
* stays full (e.g. MotK 512). Present width is never shrunk — cropping the
|
||||
* GL/SDL rect left a flickering black pillar when upload coverage varied.
|
||||
/* Depth24 FMV: trailing RGB columns can be stale while CRTC width stays full
|
||||
* (MotK 512). Present width is never shrunk — cropping the GL/SDL rect left a
|
||||
* flickering black pillar when upload coverage varied.
|
||||
*
|
||||
* Do NOT replicate the last good column: on MotK's starfield intro that turns
|
||||
* a single tinted edge pixel into an 8-wide horizontal streak (flickering
|
||||
* stretch into the pillar). Black-fill the margin instead. Require a dense
|
||||
* chroma signal so sparse stars never trip the repair. */
|
||||
static void depth24_fix_trailing_margin(uint32_t *buf, uint32_t w, uint32_t h) {
|
||||
if (!buf || w < 24u || h == 0u) return;
|
||||
const uint32_t margin = 8u;
|
||||
const uint32_t edge = w - margin;
|
||||
const uint32_t total = margin * h;
|
||||
uint32_t junk_px = 0;
|
||||
for (uint32_t x = edge; x < w; x++) {
|
||||
for (uint32_t y = 0; y < h; y++) {
|
||||
uint32_t p = buf[y * w + x];
|
||||
int r = (int)((p >> 16) & 255u);
|
||||
int g = (int)((p >> 8) & 255u);
|
||||
int b = (int)(p & 255u);
|
||||
int m = (r + g + b) / 3;
|
||||
int ch = (r > m ? r - m : m - r) + (g > m ? g - m : m - g) +
|
||||
(b > m ? b - m : m - b);
|
||||
if (ch > 40) junk_px++;
|
||||
}
|
||||
}
|
||||
/* ~12% of margin texels — sparse stars stay; dense chroma fringe cleans. */
|
||||
if (total == 0u || junk_px * 100u < total * 12u) return;
|
||||
* Always black-fill the last 8 RGB cols. Also blank beyond the tracked FB A0
|
||||
* span when it falls short of the CRTC (movie cut / partial cover). Do NOT
|
||||
* replicate the last good column — that smeared MotK's starfield into an
|
||||
* 8-wide streak. */
|
||||
static void depth24_fix_trailing_margin(uint32_t *buf, uint32_t w, uint32_t h,
|
||||
uint32_t display_x) {
|
||||
if (!buf || w < 8u || h == 0u) return;
|
||||
uint32_t start = w - 8u;
|
||||
uint32_t lim = gpu_depth24_rgb_limit(display_x, w);
|
||||
if (lim > 0u && lim < w && lim < start)
|
||||
start = lim;
|
||||
for (uint32_t y = 0; y < h; y++) {
|
||||
for (uint32_t x = edge; x < w; x++)
|
||||
for (uint32_t x = start; x < w; x++)
|
||||
buf[y * w + x] = 0xFF000000u;
|
||||
}
|
||||
}
|
||||
@@ -3437,6 +3424,11 @@ static void sdl_vblank_present(void) {
|
||||
/* Mod hooks. Run after all normal input sampling. */
|
||||
mod_call_frame_hooks();
|
||||
|
||||
/* Depth24 GP1(07h) retarget (MotK intro→crawl): keep the prior Swap for a
|
||||
* few vblanks so stale trailing VRAM never flashes on the right edge. */
|
||||
if (gpu_depth24_present_hold_tick())
|
||||
return;
|
||||
|
||||
/* Engage widescreen at game entry: BIOS boot stays authentic 4:3. */
|
||||
if (!g_ws_engaged) {
|
||||
extern int fntrace_is_game_started(void);
|
||||
@@ -3576,9 +3568,10 @@ static void sdl_vblank_present(void) {
|
||||
for (uint32_t x = 0; x < present_w; x++)
|
||||
sdl_pixel_buf[y * present_w + x] =
|
||||
gpu_display_pixel_argb(&di, x, y);
|
||||
/* Trailing margin: replicate last good column into junk cols
|
||||
* inside the full-width buffer — never shrink present width. */
|
||||
depth24_fix_trailing_margin(sdl_pixel_buf, present_w, h);
|
||||
/* Trailing margin: blank junk cols inside the full-width
|
||||
* buffer — never shrink present width. */
|
||||
depth24_fix_trailing_margin(sdl_pixel_buf, present_w, h,
|
||||
di.display_x);
|
||||
vk_renderer_present_cpu(sdl_pixel_buf, (int)present_w, (int)h,
|
||||
0 /* nearest */, fmv_frame ? 1 : 0);
|
||||
} else if (wide_present &&
|
||||
@@ -3640,11 +3633,12 @@ static void sdl_vblank_present(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Depth24 trailing margin: MotK CRTC is 512 RGB but the last ~8 cols
|
||||
/* Depth24 trailing margin: MotK CRTC is 512 RGB but trailing cols
|
||||
* can be stale. Fix pixels in-place at full present_w — never crop the
|
||||
* GL/SDL draw width (that caused a flickering black pillar). */
|
||||
if (di.depth24 && active_scale == 1 && !wide_present)
|
||||
depth24_fix_trailing_margin(sdl_pixel_buf, present_w, h);
|
||||
depth24_fix_trailing_margin(sdl_pixel_buf, present_w, h,
|
||||
di.display_x);
|
||||
|
||||
smooth_60_present(sdl_pixel_buf,
|
||||
present_w * (uint32_t)active_scale,
|
||||
|
||||
Reference in New Issue
Block a user