interp_capture's FLIP decision moves into frame_flip_is_new_frame()
(frame_interpolation.c), unit-tested in frame_interpolation_schedule_test.
A new source guard, frame_interpolation_flip_source (recompiler ctest),
pins what no unit test reaches: main.cpp hands the session's source to the
renderer at every session start, right after its interpolation settings;
interp_capture feeds the origin and the redraw test to the decision and the
tracker and returns before the copy on a duplicate; both present paths pass
the display origin and present_dirty_test; a source change restarts the
history. Deleting the hand-off, or never returning on a duplicate, now fails
the guard (both passed every test before).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
psx_mod_set_frame_interpolation_source(PSX_MOD_FRAME_SOURCE_FLIP) makes the
OpenGL presenter rotate its blend history only when the guest really flips
(the displayed VRAM origin moves or the displayed rect is redrawn) and spread
one crossfade over the measured flip period. A game that flips every second
VBlank (R4 races) used to blend for one VBlank and hold for the next; it now
blends across its whole frame.
VBLANK stays the default. reset_mod_owned_presentation() puts it back at
every session start (first boot and the lobby rematch), next to the blend
mode, so titles that never call the setter keep today's code path and a
netplay session never inherits it. begin() is begin_phase(0, 1) and stays
bit-identical (test). gl_interp reports the source, the flip period,
captures and duplicate VBlanks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>