Better emulation of CGB’s first frame behavior

This commit is contained in:
Lior Halphon 2020-05-30 01:25:21 +03:00
parent ffa569deeb
commit fa7232944f
2 changed files with 10 additions and 2 deletions

View File

@ -128,7 +128,7 @@ static void display_vblank(GB_gameboy_t *gb)
bool is_ppu_stopped = !GB_is_cgb(gb) && gb->stopped && gb->io_registers[GB_IO_LCDC] & 0x80; bool is_ppu_stopped = !GB_is_cgb(gb) && gb->stopped && gb->io_registers[GB_IO_LCDC] & 0x80;
if (!gb->disable_rendering && ((!(gb->io_registers[GB_IO_LCDC] & 0x80) || is_ppu_stopped) || gb->frame_skip_state == GB_FRAMESKIP_LCD_TURNED_ON)) { if (!gb->disable_rendering && ((!(gb->io_registers[GB_IO_LCDC] & 0x80) || is_ppu_stopped) || gb->cgb_repeated_a_frame)) {
/* LCD is off, set screen to white or black (if LCD is on in stop mode) */ /* LCD is off, set screen to white or black (if LCD is on in stop mode) */
if (!GB_is_sgb(gb)) { if (!GB_is_sgb(gb)) {
uint32_t color = 0; uint32_t color = 0;
@ -796,6 +796,7 @@ void GB_display_run(GB_gameboy_t *gb, uint8_t cycles)
while (true) { while (true) {
GB_SLEEP(gb, display, 1, LCDC_PERIOD); GB_SLEEP(gb, display, 1, LCDC_PERIOD);
display_vblank(gb); display_vblank(gb);
gb->cgb_repeated_a_frame = true;
} }
return; return;
} }
@ -1240,11 +1241,17 @@ abort_fetching_object:
} }
} }
else { else {
gb->frame_skip_state = GB_FRAMESKIP_SECOND_FRAME_RENDERED;
if (!GB_is_sgb(gb) || gb->current_lcd_line < LINES) { if (!GB_is_sgb(gb) || gb->current_lcd_line < LINES) {
gb->is_odd_frame ^= true; gb->is_odd_frame ^= true;
display_vblank(gb); display_vblank(gb);
} }
if (gb->frame_skip_state == GB_FRAMESKIP_FIRST_FRAME_SKIPPED) {
gb->cgb_repeated_a_frame = true;
gb->frame_skip_state = GB_FRAMESKIP_SECOND_FRAME_RENDERED;
}
else {
gb->cgb_repeated_a_frame = false;
}
} }
} }

View File

@ -540,6 +540,7 @@ struct GB_gameboy_internal_s {
bool is_odd_frame; bool is_odd_frame;
uint16_t last_tile_data_address; uint16_t last_tile_data_address;
uint16_t last_tile_index_address; uint16_t last_tile_index_address;
bool cgb_repeated_a_frame;
); );
/* Unsaved data. This includes all pointers, as well as everything that shouldn't be on a save state */ /* Unsaved data. This includes all pointers, as well as everything that shouldn't be on a save state */