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++;
return;
}
if (gb->fifo_paused) return;
uint8_t pixel = ((gb->io_registers[GB_IO_BGP] >> (fifo_item->pixel << 1)) & 3);
gb->screen[gb->position_in_line + gb->current_line * WIDTH] = gb->background_palettes_rgb[pixel];
/* Mixing */
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++;
}
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)
{
@ -546,16 +569,31 @@ void GB_display_run(GB_gameboy_t *gb, uint8_t cycles)
gb->fetcher_divisor = false;
gb->fetcher_state = GB_FETCHER_GET_TILE;
gb->fifo_paused = true;
gb->in_window = false;
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) {
switch (gb->fetcher_state) {
case GB_FETCHER_GET_TILE: {
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;
}
uint8_t y = gb->current_line + gb->io_registers[GB_IO_SCY];
gb->current_tile = gb->vram[map + gb->fetcher_x + y / 8 * 32];
else if (gb->io_registers[GB_IO_LCDC] & 0x40 && gb->in_window) {
map = 0x1C00;
}
gb->current_tile = gb->vram[map + gb->fetcher_x + scrolled_y(gb) / 8 * 32];
gb->fetcher_x++;
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_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;
case GB_FETCHER_GET_TILE_DATA_HIGH: {
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;

View File

@ -419,7 +419,7 @@ struct GB_gameboy_internal_s {
} fetcher_state:8;
bool fetcher_divisor; // The fetcher runs at 2MHz
bool fifo_paused;
bool in_window;
);
/* Unsaved data. This includes all pointers, as well as everything that shouldn't be on a save state */