public PaletteEntry(bool isBackround) { red = new int[4]; green = new int[4]; blue = new int[4]; Colors = new GBColor[4]; PaletteDataAddress = isBackround ? 0xFF69 : 0xFF6B; PaletteIndexAddress = isBackround ? 0xFF68 : 0xFF6A; Reset(); }
public int[] GetTiles(int vramBank) { int[] tiles = new int[384 * 8 * 8 * 4]; int count = 0; for (int yy = 0; yy < 192; yy++) { for (int xx = 0; xx < 128; xx++) { int colorIndex = (_tileset[vramBank, xx / 8 + ((yy / 8) * (128 / 8)), yy % 8, xx % 8]); GBColor color2 = _bgPalettes[0].Colors[colorIndex]; tiles[count] = color2.R; tiles[count + 1] = color2.G; tiles[count + 2] = color2.B; tiles[count + 3] = 255; count += 4; } } return(tiles); }
private void DrawSprites() { int ly = _gameboy.Mmu.LY; int lcdc = _gameboy.Mmu.LCDC; bool isSpriteHeight16 = Bitwise.IsBitOn(lcdc, 2); int spriteHeight = isSpriteHeight16 ? 16 : 8; int spriteCount = 0; for (int i = 0; i < OAM_SIZE; i += SPRITE_SIZE) { int spriteY = _gameboy.Mmu.LoadOAM(i) - 16; if (ly >= spriteY && ly < spriteY + spriteHeight) { oamSprites[spriteCount++] = i; } if (spriteCount >= OAM_HORIZONTAL_LIMIT) { break; } } for (int i = spriteCount - 1; i >= 0; i--) { int index = oamSprites[i]; int spriteY = _gameboy.Mmu.LoadOAM(index) - 16; int spriteX = _gameboy.Mmu.LoadOAM(index + 1) - 8; int tileNumber = _gameboy.Mmu.LoadOAM(index + 2); int upperTile = tileNumber & 0xFE; int lowerTile = tileNumber | 0x01; int attribs = _gameboy.Mmu.LoadOAM(index + 3); bool objAboveBg = !Bitwise.IsBitOn(attribs, 7); bool yFlip = Bitwise.IsBitOn(attribs, 6); bool xFlip = Bitwise.IsBitOn(attribs, 5); int paletteNumber = Bitwise.IsBitOn(attribs, 4) ? 1 : 0; int vramBank = 0; if (_gameboy.IsCGB) { vramBank = Bitwise.IsBitOn(attribs, 3) ? 1 : 0; paletteNumber = attribs & 0x07; } if (ly >= spriteY && ly < spriteY + spriteHeight) { int writePosition = (ly * SCREEN_WIDTH * 4) + (spriteX * 4); for (int x = 0; x < 8; x++) { if (spriteX + x >= 0 && spriteX + x < SCREEN_WIDTH) { int drawY = yFlip ? spriteHeight - 1 - (ly - spriteY) : ly - spriteY; int drawX = xFlip ? 7 - x : x; if (isSpriteHeight16) { if (drawY < 8) { tileNumber = upperTile; } else { tileNumber = lowerTile; } } int pixel = _tileset[vramBank, tileNumber, drawY % 8, drawX]; //int colorIndex = GetSpriteColorIndexFromPalette(pixel, paletteNumber); if (pixel != 0 && BGPriority[spriteX + x] != 2) { if (objAboveBg || BGPriority[spriteX + x] == 0 || (!objAboveBg && BGPriority[spriteX + x] == 3)) { GBColor color = _spPalettes[paletteNumber].Colors[pixel]; FrameBuffer[writePosition] = color.R; FrameBuffer[writePosition + 1] = color.G; FrameBuffer[writePosition + 2] = color.B; FrameBuffer[writePosition + 3] = 255; } } } writePosition += 4; } } } }
private void DrawBackground() { int sx = _gameboy.Mmu.SCX; int sy = _gameboy.Mmu.SCY; int lcdc = _gameboy.Mmu.LCDC; int ly = _gameboy.Mmu.LY; int wx = _gameboy.Mmu.WX - 7; int wy = _gameboy.Mmu.WY; bool windowEnabled = Bitwise.IsBitOn(lcdc, 5); bool inWindowY = windowEnabled && ly >= wy; int y = (Bitwise.Wrap8(ly + sy) / 8) * 32; int windowY = (((ly - wy) / 8) * 32 + 1024) % 1024; int bgTileMapLocation = Bitwise.IsBitOn(lcdc, 3) ? 0x9C00 : 0x9800; int windowTileMapLocation = Bitwise.IsBitOn(lcdc, 6) ? 0x9C00 : 0x9800; int startingIndex = ly * SCREEN_WIDTH * 4; bool shouldValueBeSigned = !Bitwise.IsBitOn(lcdc, 4); int tileInitLocation = shouldValueBeSigned ? 256 : 0; bool bgPriority; for (int xx = 0; xx < SCREEN_WIDTH; xx++) { bool hFlip = false, vFlip = false; int paletteNumber = 0, vramBank = 0; bool isInWindow = (inWindowY && xx >= wx); int x = isInWindow ? (xx - wx) / 8 : Bitwise.Wrap8(xx + sx) / 8; int actualY = isInWindow ? windowY : y; int tile;// = _gameboy.Mmu.LoadVRAM(0x9800 + y + x); int mapLocation = isInWindow ? windowTileMapLocation : bgTileMapLocation; if (shouldValueBeSigned) { tile = (sbyte)_gameboy.Mmu.LoadVRAM0(mapLocation + actualY + x); } else { tile = (byte)_gameboy.Mmu.LoadVRAM0(mapLocation + actualY + x); } if (_gameboy.IsCGB) { int value; if (shouldValueBeSigned) { value = (sbyte)_gameboy.Mmu.LoadVRAM1(mapLocation + actualY + x); } else { value = (byte)_gameboy.Mmu.LoadVRAM1(mapLocation + actualY + x); } hFlip = Bitwise.IsBitOn(value, 5); vFlip = Bitwise.IsBitOn(value, 6); paletteNumber = value & 0x07; vramBank = (value >> 3) & 0x01; bgPriority = Bitwise.IsBitOn(value, 7); } else { bgPriority = false; } int drawX = hFlip ? 7 - (xx % 8) : xx; int drawY = vFlip ? 7 - (ly % 8) : ly; if (isInWindow) { drawX = hFlip ? 7 - ((xx - wx) % 8) : (xx - wx); drawY = vFlip ? 7 - ((ly - wy) % 8) : (ly - wy); drawX %= 8; drawY %= 8; } else { if (hFlip) { drawX = 7 - ((xx + sx) % 8); } else { drawX = (drawX + sx) % 8; } if (vFlip) { drawY = 7 - ((ly + sy) % 8); } else { drawY = (drawY + sy) % 8; } } int pixel = _tileset[vramBank, tileInitLocation + tile, drawY, drawX]; if (!bgPriority) { BGPriority[xx] = (pixel != 0) ? 1 : 0; } else { BGPriority[xx] = (pixel != 0) ? 2: 3; } GBColor color = _bgPalettes[paletteNumber].Colors[pixel]; FrameBuffer[startingIndex] = color.R; FrameBuffer[startingIndex + 1] = color.G; FrameBuffer[startingIndex + 2] = color.B; FrameBuffer[startingIndex + 3] = 255; startingIndex += 4; } }