diff --git a/Core/display.c b/Core/display.c index 15d8d26..4def6c8 100755 --- a/Core/display.c +++ b/Core/display.c @@ -133,7 +133,7 @@ static uint32_t get_pixel(GB_gameboy_t *gb, uint8_t x, uint8_t y) } else { x += gb->effective_scx; - y += gb->io_registers[GB_IO_SCY]; + y += gb->effective_scy; } if (gb->io_registers[GB_IO_LCDC] & 0x08 && !in_window) { map = 0x1C00; @@ -619,13 +619,17 @@ void GB_display_run(GB_gameboy_t *gb, uint8_t cycles) /* Render */ - /* Todo: it appears that the actual rendering starts 4 cycles after mode 3 starts. Is this correct? */ - int16_t current_lcdc_x = gb->display_cycles % LINE_LENGTH - MODE2_LENGTH - (gb->effective_scx & 0x7) - 4; + int16_t current_lcdc_x = gb->display_cycles % LINE_LENGTH - MODE2_LENGTH - (gb->effective_scx & 0x7) - 7; for (;gb->previous_lcdc_x < current_lcdc_x; gb->previous_lcdc_x++) { if (gb->previous_lcdc_x >= WIDTH) { continue; } + + if (((gb->previous_lcdc_x + gb->effective_scx) & 7) == 0) { + gb->effective_scy = gb->io_registers[GB_IO_SCY]; + } + if (gb->previous_lcdc_x < 0) { continue; } diff --git a/Core/gb.h b/Core/gb.h index a929762..3756256 100644 --- a/Core/gb.h +++ b/Core/gb.h @@ -385,6 +385,7 @@ struct GB_gameboy_internal_s { bool oam_write_blocked; bool vram_write_blocked; bool window_disabled_while_active; + uint8_t effective_scy; // SCY is latched when starting to draw a tile ); /* Unsaved data. This includes all pointers, as well as everything that shouldn't be on a save state */