diff --git a/gbscreen.cpp b/gbscreen.cpp index e66570b..277b654 100644 --- a/gbscreen.cpp +++ b/gbscreen.cpp @@ -135,6 +135,10 @@ namespace gbscreen void fill_line_buffer_bkg(uint8_t LY) { const uint8_t LCDC = mem::readMem(0xff40); + if ((LCDC & 0x1) == 0) { + for (int i=0; i<160; ++i) line_buffer[i]=0; + return; + } const uint8_t SCY = mem::readMem(0xff42); const uint8_t SCX = mem::readMem(0xff43); const uint8_t BGP = mem::readMem(0xff47); @@ -169,6 +173,45 @@ namespace gbscreen } } + void fill_line_buffer_win(uint8_t LY) + { + const uint8_t LCDC = mem::readMem(0xff40); + if ((LCDC & 0x21) == 0) return; + const uint8_t WY = mem::readMem(0xff4a); + if (LY> 3; + const uint8_t ly = uint8_t(LY-WY) & 0x7; + uint8_t ox = WX<7 ? 7-WX : 0; + uint16_t tx = 0; + + uint16_t base_tilemap_address = LCDC&0x40 ? 0x9c00 : 0x9800; + + int pi = WX<7 ? 0 : WX-7; + while(true) { + uint16_t tilemap_address = base_tilemap_address + tx + (ty<<5); + uint16_t tile = mem::readMem(tilemap_address); + uint16_t base_tile_address = 0x8000; + if ( ((LCDC&0x10)==0) && (tile<128) ) base_tile_address = 0x9000; + uint16_t tile_address = base_tile_address + (tile<<4) + (ly*2); + + uint8_t a = mem::readMem(tile_address); + uint8_t b = mem::readMem(tile_address+1); + for (int i=0; i<8; ++i) { + if (ox==0) { + uint8_t index = (a&0x80 ? 1 : 0) + (b&0x80 ? 2 : 0 ); + line_buffer[pi++] = (BGP >> (index*2)) & 0x3; + } else { + ox--; + } + a=a<<1; b=b<<1; + if (pi==160) return; + } + tx = (tx+1)&0x1f; + } + } + struct oam_entry_t { uint8_t y, x, tile, attr; @@ -288,6 +331,7 @@ namespace gbscreen STAT = (STAT & 0xFC) | 0x02; // Set mode 2 if (STAT&0x20) stat_interrupt = true; fill_line_buffer_bkg(LY); + fill_line_buffer_win(LY); fill_line_buffer_obj(LY); } else if (LY==154)