Refined the behavior of the last fix on a DMG.

This commit is contained in:
Lior Halphon 2017-06-03 20:06:52 +03:00
parent 65b0dcb2c5
commit a9475fbdf4
2 changed files with 14 additions and 6 deletions

View File

@ -203,7 +203,7 @@ static void display_vblank(GB_gameboy_t *gb)
}
}
if (!gb->disable_rendering && (!(gb->io_registers[GB_IO_LCDC] & 0x80) || gb->stopped)) {
if (!gb->disable_rendering && ((!(gb->io_registers[GB_IO_LCDC] & 0x80) || gb->stopped) || gb->frame_skip_state == GB_FRAMESKIP_LCD_TURNED_ON)) {
/* LCD is off, set screen to white */
uint32_t white = gb->rgb_encode_callback(gb, 0xFF, 0xFF, 0xFF);
for (unsigned i = 0; i < WIDTH * LINES; i++) {
@ -319,7 +319,13 @@ static void update_display_state(GB_gameboy_t *gb, uint8_t cycles)
gb->stat_interrupt_line = true;
}
if (gb->frame_skip_state == GB_FRAMESKIP_LCD_TURNED_ON) {
gb->frame_skip_state = GB_FRAMESKIP_FIRST_FRAME_SKIPPED;
if (!gb->is_cgb) {
display_vblank(gb);
gb->frame_skip_state = GB_FRAMESKIP_SECOND_FRAME_RENDERED;
}
else {
gb->frame_skip_state = GB_FRAMESKIP_FIRST_FRAME_SKIPPED;
}
}
else {
gb->frame_skip_state = GB_FRAMESKIP_SECOND_FRAME_RENDERED;

View File

@ -365,12 +365,14 @@ struct GB_gameboy_internal_s {
bool stat_interrupt_line;
uint8_t effective_scx;
uint8_t current_window_line;
/* The LCDC will skip the first frame it renders after turning it on, unless the previous
frame was skipped as well.
/* The LCDC will skip the first frame it renders after turning it on.
On the CGB, a frame is not skipped if the previous frame was skipped as well.
See https://www.reddit.com/r/EmuDev/comments/6exyxu/ */
enum {
GB_FRAMESKIP_LCD_TURNED_ON,
GB_FRAMESKIP_FIRST_FRAME_SKIPPED,
GB_FRAMESKIP_LCD_TURNED_ON, // On a DMG, the LCD renders a blank screen during this state,
// on a CGB, the previous frame is repeated (which might be
// blank if the LCD was off for more than a few cycles)
GB_FRAMESKIP_FIRST_FRAME_SKIPPED, // This state is 'skipped' when emulating a DMG
GB_FRAMESKIP_SECOND_FRAME_RENDERED,
} frame_skip_state;
);