Skip to content

Commit 0f67470

Browse files
trekawekclaude
andcommitted
Abort a flickered-on window through the map read (wewx 83->3)
The stray 8-pixel window tiles left in m3_lcdc_win_en_change_multiple_wx were the drop-side of the same LCDC-pulse phase the activation desync handles: when the window turns on for a dot and straight back off, the disabling write lands a couple of dots later on our fetcher timeline than on hardware, so by the time we check, the fetch had already passed GET_TILE_T2 and pushed a window tile. Extending the window-drop check through GET_TILE_DATA_LOW_T2 (and restarting the fetch as background from GET_TILE_T2 onward) aborts those fetches with no window pixels, matching hardware. m3_lcdc_win_en_change_multiple stays pixel-perfect and no other test moves; mealybug DMG total 537 -> 457. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J1wLWscyUGS7CFwc3CjJR8
1 parent 4789306 commit 0f67470

2 files changed

Lines changed: 9 additions & 7 deletions

File tree

core/src/main/java/eu/rekawek/coffeegb/core/gpu/phase/PixelTransfer.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -298,12 +298,14 @@ public boolean tick() {
298298
if (window
299299
&& !lcdc.isWindowDisplay()
300300
&& objStep < 0
301-
&& fetcher.getState() <= Fetcher.GET_TILE_T2) {
302-
// the write disabling the window can commit one dot after our fetch's T1
303-
// and still catch the fetch on hardware (the map is only read later):
304-
// dropping at T2 restarts the fetch so the map offset recomputes as
305-
// background (m3_lcdc_win_en_change_multiple)
306-
if (fetcher.getState() == Fetcher.GET_TILE_T2) {
301+
&& fetcher.getState() <= Fetcher.GET_TILE_DATA_LOW_T2) {
302+
// the write disabling the window catches the fetch through GET_TILE_DATA_LOW_T2
303+
// (the map read): our LCDC-pulse commit lands a couple of dots later on the
304+
// fetcher timeline than hardware, so a window that flickers on and straight
305+
// back off produces no window pixels only if we still abort the fetch here.
306+
// Restarting from T2 onwards recomputes the map offset as background
307+
// (m3_lcdc_win_en_change_multiple, and the stray 8-px window tiles in wewx).
308+
if (fetcher.getState() >= Fetcher.GET_TILE_T2) {
307309
fetcher.restartTile();
308310
}
309311
window = false;

core/src/test/java/eu/rekawek/coffeegb/core/integration/mealybug/MealybugRomTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public class MealybugRomTest {
4242
Map.entry("m3_lcdc_tile_sel_change.gb", 0),
4343
Map.entry("m3_lcdc_tile_sel_win_change.gb", 192),
4444
Map.entry("m3_lcdc_win_en_change_multiple.gb", 0),
45-
Map.entry("m3_lcdc_win_en_change_multiple_wx.gb", 83),
45+
Map.entry("m3_lcdc_win_en_change_multiple_wx.gb", 3),
4646
Map.entry("m3_lcdc_win_map_change.gb", 92),
4747
Map.entry("m3_obp0_change.gb", 0),
4848
Map.entry("m3_scx_high_5_bits.gb", 0),

0 commit comments

Comments
 (0)