Exemplo n.º 1
0
        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();
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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;
                    }
                }
            }
        }
Exemplo n.º 4
0
        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;
            }
        }