Goodbye
This commit is contained in:
parent
e8b107efdb
commit
c267ad00b5
157
Core/display.c
157
Core/display.c
@ -120,163 +120,6 @@ static bool window_enabled(GB_gameboy_t *gb)
|
|||||||
return (gb->io_registers[GB_IO_LCDC] & 0x20) && gb->io_registers[GB_IO_WX] < 167;
|
return (gb->io_registers[GB_IO_LCDC] & 0x20) && gb->io_registers[GB_IO_WX] < 167;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Kept as a reference until I finish rewriting the PPU */
|
|
||||||
static uint32_t __attribute__((unused)) get_pixel(GB_gameboy_t *gb, uint8_t x, uint8_t y)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Bit 7 - LCD Display Enable (0=Off, 1=On)
|
|
||||||
Bit 6 - Window Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF)
|
|
||||||
Bit 5 - Window Display Enable (0=Off, 1=On)
|
|
||||||
Bit 4 - BG & Window Tile Data Select (0=8800-97FF, 1=8000-8FFF)
|
|
||||||
Bit 3 - BG Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF)
|
|
||||||
Bit 2 - OBJ (Sprite) Size (0=8x8, 1=8x16)
|
|
||||||
Bit 1 - OBJ (Sprite) Display Enable (0=Off, 1=On)
|
|
||||||
Bit 0 - BG Display (for CGB see below) (0=Off, 1=On)
|
|
||||||
*/
|
|
||||||
uint16_t map = 0x1800;
|
|
||||||
uint8_t tile = 0;
|
|
||||||
uint8_t attributes = 0;
|
|
||||||
uint8_t sprite_palette = 0;
|
|
||||||
uint16_t tile_address = 0;
|
|
||||||
uint8_t background_pixel = 0, sprite_pixel = 0;
|
|
||||||
GB_object_t *sprite = (GB_object_t *) &gb->oam;
|
|
||||||
uint8_t sprites_in_line = 0;
|
|
||||||
bool lcd_8_16_mode = (gb->io_registers[GB_IO_LCDC] & 4) != 0;
|
|
||||||
bool sprites_enabled = (gb->io_registers[GB_IO_LCDC] & 2) != 0;
|
|
||||||
uint8_t lowest_sprite_x = 0xFF;
|
|
||||||
bool use_obp1 = false, priority = false;
|
|
||||||
bool in_window = false;
|
|
||||||
bool bg_enabled = true;
|
|
||||||
bool bg_behind = false;
|
|
||||||
if ((gb->io_registers[GB_IO_LCDC] & 0x1) == 0) {
|
|
||||||
if (gb->cgb_mode) {
|
|
||||||
bg_behind = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
bg_enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window_enabled(gb) && y >= gb->io_registers[GB_IO_WY] + gb->wy_diff && x + 7 >= gb->io_registers[GB_IO_WX]) {
|
|
||||||
in_window = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sprites_enabled) {
|
|
||||||
// Loop all sprites
|
|
||||||
for (uint8_t i = 40; i--; sprite++) {
|
|
||||||
int sprite_y = sprite->y - 16;
|
|
||||||
int sprite_x = sprite->x - 8;
|
|
||||||
// Is sprite in our line?
|
|
||||||
if (sprite_y <= y && sprite_y + (lcd_8_16_mode? 16:8) > y) {
|
|
||||||
uint8_t tile_x, tile_y, current_sprite_pixel;
|
|
||||||
uint16_t line_address;
|
|
||||||
// Limit to 10 sprites in one scan line.
|
|
||||||
if (++sprites_in_line == 11) break;
|
|
||||||
// Does not overlap our pixel.
|
|
||||||
if (sprite_x > x || sprite_x + 8 <= x) continue;
|
|
||||||
tile_x = x - sprite_x;
|
|
||||||
tile_y = y - sprite_y;
|
|
||||||
if (sprite->flags & 0x20) tile_x = 7 - tile_x;
|
|
||||||
if (sprite->flags & 0x40) tile_y = (lcd_8_16_mode? 15:7) - tile_y;
|
|
||||||
line_address = (lcd_8_16_mode? sprite->tile & 0xFE : sprite->tile) * 0x10 + tile_y * 2;
|
|
||||||
if (gb->cgb_mode && (sprite->flags & 0x8)) {
|
|
||||||
line_address += 0x2000;
|
|
||||||
}
|
|
||||||
current_sprite_pixel = (((gb->vram[line_address ] >> ((~tile_x)&7)) & 1 ) |
|
|
||||||
((gb->vram[line_address + 1] >> ((~tile_x)&7)) & 1) << 1 );
|
|
||||||
/* From Pandocs:
|
|
||||||
When sprites with different x coordinate values overlap, the one with the smaller x coordinate
|
|
||||||
(closer to the left) will have priority and appear above any others. This applies in Non CGB Mode
|
|
||||||
only. When sprites with the same x coordinate values overlap, they have priority according to table
|
|
||||||
ordering. (i.e. $FE00 - highest, $FE04 - next highest, etc.) In CGB Mode priorities are always
|
|
||||||
assigned like this.
|
|
||||||
*/
|
|
||||||
if (current_sprite_pixel != 0) {
|
|
||||||
if (!gb->cgb_mode && sprite->x >= lowest_sprite_x) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sprite_pixel = current_sprite_pixel;
|
|
||||||
lowest_sprite_x = sprite->x;
|
|
||||||
use_obp1 = (sprite->flags & 0x10) != 0;
|
|
||||||
sprite_palette = sprite->flags & 7;
|
|
||||||
priority = (sprite->flags & 0x80) != 0;
|
|
||||||
if (gb->cgb_mode) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_window) {
|
|
||||||
x -= gb->io_registers[GB_IO_WX] - 7; // Todo: This value is probably latched
|
|
||||||
y -= gb->io_registers[GB_IO_WY] + gb->wy_diff;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
x += gb->effective_scx;
|
|
||||||
y += gb->effective_scy;
|
|
||||||
}
|
|
||||||
if (gb->io_registers[GB_IO_LCDC] & 0x08 && !in_window) {
|
|
||||||
map = 0x1C00;
|
|
||||||
}
|
|
||||||
else if (gb->io_registers[GB_IO_LCDC] & 0x40 && in_window) {
|
|
||||||
map = 0x1C00;
|
|
||||||
}
|
|
||||||
tile = gb->vram[map + x/8 + y/8 * 32];
|
|
||||||
if (gb->cgb_mode) {
|
|
||||||
attributes = gb->vram[map + x/8 + y/8 * 32 + 0x2000];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attributes & 0x80) {
|
|
||||||
priority = !bg_behind && bg_enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!priority && sprite_pixel) {
|
|
||||||
if (!gb->cgb_mode) {
|
|
||||||
sprite_pixel = (gb->io_registers[use_obp1? GB_IO_OBP1:GB_IO_OBP0] >> (sprite_pixel << 1)) & 3;
|
|
||||||
sprite_palette = use_obp1;
|
|
||||||
}
|
|
||||||
return gb->sprite_palettes_rgb[sprite_palette * 4 + sprite_pixel];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bg_enabled) {
|
|
||||||
if (gb->io_registers[GB_IO_LCDC] & 0x10) {
|
|
||||||
tile_address = tile * 0x10;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
tile_address = (int8_t) tile * 0x10 + 0x1000;
|
|
||||||
}
|
|
||||||
if (attributes & 0x8) {
|
|
||||||
tile_address += 0x2000;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attributes & 0x20) {
|
|
||||||
x = ~x;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attributes & 0x40) {
|
|
||||||
y = ~y;
|
|
||||||
}
|
|
||||||
|
|
||||||
background_pixel = (((gb->vram[tile_address + (y & 7) * 2 ] >> ((~x)&7)) & 1 ) |
|
|
||||||
((gb->vram[tile_address + (y & 7) * 2 + 1] >> ((~x)&7)) & 1) << 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priority && sprite_pixel && !background_pixel) {
|
|
||||||
if (!gb->cgb_mode) {
|
|
||||||
sprite_pixel = (gb->io_registers[use_obp1? GB_IO_OBP1:GB_IO_OBP0] >> (sprite_pixel << 1)) & 3;
|
|
||||||
sprite_palette = use_obp1;
|
|
||||||
}
|
|
||||||
return gb->sprite_palettes_rgb[sprite_palette * 4 + sprite_pixel];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gb->cgb_mode) {
|
|
||||||
background_pixel = ((gb->io_registers[GB_IO_BGP] >> (background_pixel << 1)) & 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
return gb->background_palettes_rgb[(attributes & 7) * 4 + background_pixel];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void display_vblank(GB_gameboy_t *gb)
|
static void display_vblank(GB_gameboy_t *gb)
|
||||||
{
|
{
|
||||||
gb->vblank_just_occured = true;
|
gb->vblank_just_occured = true;
|
||||||
|
@ -401,7 +401,6 @@ struct GB_gameboy_internal_s {
|
|||||||
bool oam_write_blocked;
|
bool oam_write_blocked;
|
||||||
bool vram_write_blocked;
|
bool vram_write_blocked;
|
||||||
bool window_disabled_while_active;
|
bool window_disabled_while_active;
|
||||||
uint8_t effective_scy; // Todo: delete me!
|
|
||||||
uint8_t current_line;
|
uint8_t current_line;
|
||||||
uint16_t ly_for_comparison;
|
uint16_t ly_for_comparison;
|
||||||
GB_fifo_t bg_fifo, oam_fifo;
|
GB_fifo_t bg_fifo, oam_fifo;
|
||||||
|
Loading…
Reference in New Issue
Block a user