private void renderBG(MMU mmu) { byte WX = (byte)(mmu.WX - 7); //WX needs -7 Offset byte WY = mmu.WY; byte LY = mmu.LY; byte LCDC = mmu.LCDC; byte SCY = mmu.SCY; byte SCX = mmu.SCX; byte BGP = mmu.BGP; bool isWin = isWindow(LCDC, WY, LY); byte y = isWin ? (byte)(LY - WY) : (byte)(LY + SCY); byte tileLine = (byte)((y & 7) * 2); ushort tileRow = (ushort)(y / 8 * 32); ushort tileMap = isWin ? getWindowTileMapAdress(LCDC) : getBGTileMapAdress(LCDC); byte hi = 0; byte lo = 0; for (int p = 0; p < SCREEN_WIDTH; p++) { byte x = isWin && p >= WX ? (byte)(p - WX) : (byte)(p + SCX); if ((p & 0x7) == 0 || ((p + SCX) & 0x7) == 0) { ushort tileCol = (ushort)(x / 8); ushort tileAdress = (ushort)(tileMap + tileRow + tileCol); ushort tileLoc; if (isSignedAdress(LCDC)) { tileLoc = (ushort)(getTileDataAdress(LCDC) + mmu.readVRAM(tileAdress) * 16); } else { tileLoc = (ushort)(getTileDataAdress(LCDC) + ((sbyte)mmu.readVRAM(tileAdress) + 128) * 16); } lo = mmu.readVRAM((ushort)(tileLoc + tileLine)); hi = mmu.readVRAM((ushort)(tileLoc + tileLine + 1)); } int colorBit = 7 - (x & 7); //inversed int colorId = GetColorIdBits(colorBit, lo, hi); int colorIdThroughtPalette = GetColorIdThroughtPalette(BGP, colorId); bmp.SetPixel(p, LY, color[colorIdThroughtPalette]); } }
private void renderSprites(MMU mmu) { byte LY = mmu.LY; byte LCDC = mmu.LCDC; for (int i = 0x9C; i >= 0; i -= 4) { //0x9F OAM Size, 40 Sprites x 4 bytes: int y = mmu.readOAM(i) - 16; //Byte0 - Y Position //needs 16 offset int x = mmu.readOAM(i + 1) - 8; //Byte1 - X Position //needs 8 offset byte tile = mmu.readOAM(i + 2); //Byte2 - Tile/Pattern Number byte attr = mmu.readOAM(i + 3); //Byte3 - Attributes/Flags if ((LY >= y) && (LY < (y + spriteSize(LCDC)))) { byte palette = isBit(4, attr) ? mmu.OBP1 : mmu.OBP0; //Bit4 Palette number **Non CGB Mode Only** (0=OBP0, 1=OBP1) int tileRow = isYFlipped(attr) ? spriteSize(LCDC) - 1 - (LY - y) : (LY - y); ushort tileddress = (ushort)(0x8000 + (tile * 16) + (tileRow * 2)); byte lo = mmu.readVRAM(tileddress); byte hi = mmu.readVRAM((ushort)(tileddress + 1)); for (int p = 0; p < 8; p++) { int IdPos = isXFlipped(attr) ? p : 7 - p; int colorId = GetColorIdBits(IdPos, lo, hi); int colorIdThroughtPalette = GetColorIdThroughtPalette(palette, colorId); if ((x + p) >= 0 && (x + p) < SCREEN_WIDTH) { if (!isTransparent(colorId) && (isAboveBG(attr) || isBGWhite(mmu.BGP, x + p, LY))) { bmp.SetPixel(x + p, LY, color[colorIdThroughtPalette]); } } } } } }