Added window support

This commit is contained in:
Lior Halphon 2018-03-03 19:36:21 +02:00
parent 5ea33cc931
commit 496c5589e6
2 changed files with 47 additions and 9 deletions

View File

@ -419,14 +419,37 @@ static void render_pixel_if_possible(GB_gameboy_t *gb)
gb->position_in_line++; gb->position_in_line++;
return; return;
} }
if (gb->fifo_paused) return; if (gb->fifo_paused) return;
uint8_t pixel = ((gb->io_registers[GB_IO_BGP] >> (fifo_item->pixel << 1)) & 3); /* Mixing */
gb->screen[gb->position_in_line + gb->current_line * WIDTH] = gb->background_palettes_rgb[pixel]; bool bg_enabled = true, bg_behind = false;
if ((gb->io_registers[GB_IO_LCDC] & 0x1) == 0) {
if (gb->cgb_mode) {
bg_behind = true;
}
else {
bg_enabled = false;
}
}
if (!bg_enabled) {
gb->screen[gb->position_in_line + gb->current_line * WIDTH] = gb->rgb_encode_callback(gb, 0xFF, 0xFF, 0xFF);
}
else {
uint8_t pixel = fifo_item->pixel;
if (!gb->cgb_mode) {
pixel = ((gb->io_registers[GB_IO_BGP] >> (pixel << 1)) & 3);
}
gb->screen[gb->position_in_line + gb->current_line * WIDTH] = gb->background_palettes_rgb[pixel];
}
gb->position_in_line++; gb->position_in_line++;
} }
static inline uint8_t scrolled_y(GB_gameboy_t *gb)
{
return gb->current_line + (gb->in_window? - gb->io_registers[GB_IO_WY] - gb->wy_diff : gb->io_registers[GB_IO_SCY]);
}
void GB_display_run(GB_gameboy_t *gb, uint8_t cycles) void GB_display_run(GB_gameboy_t *gb, uint8_t cycles)
{ {
@ -546,16 +569,31 @@ void GB_display_run(GB_gameboy_t *gb, uint8_t cycles)
gb->fetcher_divisor = false; gb->fetcher_divisor = false;
gb->fetcher_state = GB_FETCHER_GET_TILE; gb->fetcher_state = GB_FETCHER_GET_TILE;
gb->fifo_paused = true; gb->fifo_paused = true;
gb->in_window = false;
while (true) { while (true) {
/* Handle window */
/* Todo: Timing not verified by test ROM */
if (!gb->in_window && window_enabled(gb) &&
gb->current_line >= gb->io_registers[GB_IO_WY] + gb->wy_diff &&
gb->position_in_line + 7 == gb->io_registers[GB_IO_WX]) {
gb->in_window = true;
fifo_clear(&gb->bg_fifo);
gb->fifo_paused = true;
gb->fetcher_x = 0;
gb->fetcher_state = GB_FETCHER_GET_TILE;
}
if (gb->fetcher_divisor) { if (gb->fetcher_divisor) {
switch (gb->fetcher_state) { switch (gb->fetcher_state) {
case GB_FETCHER_GET_TILE: { case GB_FETCHER_GET_TILE: {
uint16_t map = 0x1800; uint16_t map = 0x1800;
if (gb->io_registers[GB_IO_LCDC] & 0x08) { if (gb->io_registers[GB_IO_LCDC] & 0x08 && !gb->in_window) {
map = 0x1C00; map = 0x1C00;
} }
uint8_t y = gb->current_line + gb->io_registers[GB_IO_SCY]; else if (gb->io_registers[GB_IO_LCDC] & 0x40 && gb->in_window) {
gb->current_tile = gb->vram[map + gb->fetcher_x + y / 8 * 32]; map = 0x1C00;
}
gb->current_tile = gb->vram[map + gb->fetcher_x + scrolled_y(gb) / 8 * 32];
gb->fetcher_x++; gb->fetcher_x++;
gb->fetcher_x &= 0x1f; gb->fetcher_x &= 0x1f;
} }
@ -569,13 +607,13 @@ void GB_display_run(GB_gameboy_t *gb, uint8_t cycles)
gb->current_tile_address = (int8_t)gb->current_tile * 0x10 + 0x1000; gb->current_tile_address = (int8_t)gb->current_tile * 0x10 + 0x1000;
} }
gb->current_tile_data[0] = gb->current_tile_data[0] =
gb->vram[gb->current_tile_address + ((gb->current_line + gb->io_registers[GB_IO_SCY]) & 7) * 2]; gb->vram[gb->current_tile_address + (scrolled_y(gb) & 7) * 2];
} }
break; break;
case GB_FETCHER_GET_TILE_DATA_HIGH: { case GB_FETCHER_GET_TILE_DATA_HIGH: {
gb->current_tile_data[1] = gb->current_tile_data[1] =
gb->vram[gb->current_tile_address + ((gb->current_line + gb->io_registers[GB_IO_SCY]) & 7) * 2 + 1]; gb->vram[gb->current_tile_address + (scrolled_y(gb) & 7) * 2 + 1];
} }
break; break;

View File

@ -419,7 +419,7 @@ struct GB_gameboy_internal_s {
} fetcher_state:8; } fetcher_state:8;
bool fetcher_divisor; // The fetcher runs at 2MHz bool fetcher_divisor; // The fetcher runs at 2MHz
bool fifo_paused; bool fifo_paused;
bool in_window;
); );
/* 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 */