Added window support
This commit is contained in:
parent
5ea33cc931
commit
496c5589e6
@ -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 */
|
||||||
|
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->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;
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user