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;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
gb->vblank_just_occured = true;
|
||||
|
Loading…
Reference in New Issue
Block a user