Example #1
0
        public int PixelValue(int screenX, int screenY)
        {
            int paletteOffset = 0;

            int scrollX = ScrollX;

            if (scrollX >= bgWidthInPixel)
            {
                scrollX -= bgWidthInPixel;
            }

            int scrollY = ScrollY;

            if (scrollY >= bgHeightInPixel)
            {
                scrollY -= bgHeightInPixel;
            }

            int wrappedBgY = scrollY + screenY;

            if (wrappedBgY >= bgHeightInPixel)
            {
                wrappedBgY -= bgHeightInPixel;
            }

            // Which line within the current tile are we rendering?
            int tileRow = wrappedBgY % 8;

            // If we reach the edge of the Bg, wrap around
            int wrappedBgX = scrollX + screenX;

            if (wrappedBgX >= bgWidthInPixel)
            {
                wrappedBgX -= bgWidthInPixel;
            }

            // Which column within the current tile are we rendering?
            int tileColumn = wrappedBgX % 8;

            var tileMetaData = TileMap.TileMapItemFromBgXY(wrappedBgX, wrappedBgY);

            // If we are in 4 bpp mode the tilemap contains which 16 colour palette to use. 16 entries per palette
            if (eightBitColour == false)
            {
                paletteOffset = tileMetaData.Palette * 16;
            }

            int tileVramOffset = (int)(tileDataVramOffset + ((tileMetaData.TileNumber) * tileSize));

            int paletteIndex = TileHelpers.GetTilePixel(tileColumn, tileRow, eightBitColour, gba.Memory.VRam, tileVramOffset, tileMetaData.FlipHorizontal, tileMetaData.FlipVertical);

            if (paletteIndex == 0)
            {
                return(0);
            }

            return(paletteOffset + paletteIndex);
        }
Example #2
0
File: Obj.cs Project: 5l1v3r1/Y2Gba
        // What is the pixel value within the sprite. passing 0,0 returns the pixel value of the top left of this sprite
        public int PixelValue(int spriteX, int spriteY)
        {
            Size spriteDimensions = Attributes.Dimensions;

            if (spriteX < 0 || spriteX >= spriteDimensions.Width ||
                spriteY < 0 || spriteY >= spriteDimensions.Height)
            {
                return(0);
            }

            int currentSpriteColumnInTiles = spriteX / 8;
            int currentSpriteRowInTiles    = spriteY / 8;

            int currentColumnWithinTile = spriteX % 8;
            int currentRowWithinTile    = spriteY % 8;

            if (hFlip)
            {
                currentSpriteColumnInTiles = (spriteWidthInTiles - 1) - currentSpriteColumnInTiles;
            }
            if (vFlip)
            {
                currentSpriteRowInTiles = (spriteHeightInTiles - 1) - currentSpriteRowInTiles;
            }

            // This offset will be set to point to the start of the 8x8 that spriteX,spriteY is within
            int vramTileOffset;

            // We count tile sizes in 4bpp when measuring tile rows / tile grid position

            // Addressing mode (1d / 2d)
            if (TileMapping2D)
            {
                // 2D addressing, vram is thought of as a 32x32 matrix of tiles. A sprites tiles are arranged as you would view them on a screen
                int full32TileRowSizeInBytes = LcdController.Tile_Size_4bit * 32;
                vramTileOffset = vramBaseOffset + offsetToFirstTile + (currentSpriteRowInTiles * full32TileRowSizeInBytes) + (currentSpriteColumnInTiles * tileSize);
            }
            else
            {
                // 1D addressing, all the sprites tiles are contiguous in vram
                vramTileOffset = vramBaseOffset + offsetToFirstTile + (currentSpriteRowInTiles * spriteRowSizeInBytes) + (currentSpriteColumnInTiles * tileSize);
            }

            // Lookup the actual pixel value (which is a palette index) in the tile data
            int paletteIndex = TileHelpers.GetTilePixel(currentColumnWithinTile, currentRowWithinTile, eightBitColour, gba.Memory.VRam, vramTileOffset, hFlip, vFlip);

            // Pal 0 == Transparent
            if (paletteIndex == 0)
            {
                return(0);
            }

            return(paletteOffset + paletteIndex);
        }
Example #3
0
        // Code to dump both BG and Obj tiles. Quite a complex list of parameters in order to make it work for both
        public void DebugDrawTiles(DirectBitmap image, byte[] vram, int vramBaseOffset, Color[] palette, bool eightBitColour, Func <int, int> getTile4BitPaletteNumber)
        {
            int tileCountX = 32;
            int tileCountY = 32;

            int tileX = 0;
            int tileY = 0;

            int tileSize = eightBitColour ? LcdController.Tile_Size_8bit: LcdController.Tile_Size_4bit;

            int totalTiles = eightBitColour ? 512 : 1024;

            for (int tileNumber = 0; tileNumber < totalTiles; tileNumber++)
            {
                int tileVramOffset = vramBaseOffset + (tileNumber * tileSize);

                int paletteOffset = 0;
                if (eightBitColour == false && getTile4BitPaletteNumber != null)
                {
                    paletteOffset = getTile4BitPaletteNumber(tileNumber);
                }

                // Add one tiles pixels
                for (int y = 0; y < 8; y++)
                {
                    for (int x = 0; x < 8; x++)
                    {
                        int paletteIndex = TileHelpers.GetTilePixel(x, y, eightBitColour, vram, tileVramOffset, false, false);

                        // 0 == transparent / pal 0
                        int colIndex = (paletteIndex == 0 ? 0 : paletteOffset + paletteIndex);

                        image.SetPixel(x + (tileX * 8), y + (tileY * 8), palette[colIndex]);
                    }
                }

                // Coordinates on the output image
                tileX++;
                if (tileX == tileCountX)
                {
                    tileX = 0;
                    tileY++;
                }
            }

            bool drawGrid = true;

            if (drawGrid)
            {
                GfxHelpers.DrawGrid(image.Bitmap, Color.FromArgb(64, 0, 0, 0), 0, 0, tileCountX, tileCountY, 8, 8);
            }
        }
Example #4
0
        // Used for debug rendering BG's. Renders the source BG, does not scroll etc
        public void DebugRenderScanline(int scanline, int scanlineWidth, DirectBitmap drawBuffer)
        {
            Color[] palette       = gba.LcdController.Palettes.Palette0;
            int     paletteOffset = 0;

            bool eightBitColour = (CntRegister.PaletteMode == BgPaletteMode.PaletteMode256x1);

            // Which line within the current tile are we rendering?
            int tileRow = scanline % 8;

            for (int x = 0; x < scanlineWidth; x++)
            {
                // Which column within the current tile are we rendering?
                int tileColumn = x % 8;

                var tileMetaData = TileMap.TileMapItemFromBgXY(x, scanline);

                // If we are in 4 bpp mode the tilemap contains which 16 colour palette to use. 16 entries per palette
                if (eightBitColour == false)
                {
                    paletteOffset = tileMetaData.Palette * 16;
                }

                int tileSize = (eightBitColour ? LcdController.Tile_Size_8bit : LcdController.Tile_Size_4bit);

                // 4 bytes represent one row of pixel data for a single tile
                int tileVramOffset = (int)(tileDataVramOffset + ((tileMetaData.TileNumber) * tileSize));

                // Sometimes Bg's can be set up with invalid data which won't be drawn
                if (tileVramOffset >= gba.Memory.VRam.Length)
                {
                    continue;
                }

                int paletteIndex = TileHelpers.GetTilePixel(tileColumn, tileRow, eightBitColour, gba.Memory.VRam, tileVramOffset, tileMetaData.FlipHorizontal, tileMetaData.FlipVertical);

                // Pal 0 == Transparent
                if (paletteIndex == 0)
                {
                    continue;
                }

                drawBuffer.SetPixel(x, scanline, palette[paletteOffset + paletteIndex]);
            }
        }
Example #5
0
        // Used for debug rendering BG's. Renders the source BG, does not scroll etc
        public void DebugRenderScanlineAffine(int scanline, int scanlineWidth, DirectBitmap drawBuffer)
        {
            Color[] palette        = gba.LcdController.Palettes.Palette0;
            bool    eightBitColour = CntRegister.PaletteMode == BgPaletteMode.PaletteMode256x1;

            // Which line within the current tile are we rendering?
            int tileRow = scanline % 8;

            for (int x = 0; x < scanlineWidth; x++)
            {
                // Coords (measured in tiles) of the tile we want to render
                int bgRow    = scanline / 8;
                int bgColumn = x / 8;

                // Which row / column within the tile we are rendering?
                int tileColumn = x % 8;

                // Affine BG's have one byte screen data (the tile index). Also all tiles are 8bpp
                // Affine BG's are also all square (they have their own size table which is different to regular tiled bg's)
                int tileInfoOffset = (bgRow * bgWidthInTiles) + bgColumn;

                int tileNumber = gba.Memory.VRam[(CntRegister.ScreenBlockBaseAddress * 2048) + tileInfoOffset];

                int tileVramOffset = (int)(tileDataVramOffset + (tileNumber * tileSize));

                // Sometimes Bg's can be set up with invalid data which won't be drawn
                if (tileVramOffset >= gba.Memory.VRam.Length)
                {
                    continue;
                }

                int paletteIndex = TileHelpers.GetTilePixel(tileColumn, tileRow, true, gba.Memory.VRam, tileVramOffset, false, false);

                // Pal 0 == Transparent
                if (paletteIndex == 0)
                {
                    continue;
                }

                drawBuffer.SetPixel(x, scanline, palette[paletteIndex]);
            }
        }
Example #6
0
        public int PixelValueAffine(int screenX, int screenY)
        {
            // Scrolling values set the origin so that BG 0,0 == Screen 0,0
            // Affine scroll are 24.8 fixed point numbers but as long as you shift away the fraction part at the end, you can just do integer math on them and they work
            int scrollX = AffineScrollXCached; // >> 8;
            int scrollY = AffineScrollYCached; // >> 8;

            // The game will have set up the matrix to be the inverse texture mapping matrix. I.E it maps from screen space to texture space. Just what we need!
            int textureSpaceX, textureSpaceY;

            textureSpaceX = ((scrollX + (AffineMatrix.Pa * screenX)) >> 8);
            textureSpaceY = ((scrollY + (AffineMatrix.Pc * screenX)) >> 8);

            //AffineMatrix.Multiply(screenX, screenY, out textureSpaceX, out textureSpaceY);

            // Apply displacement vector (affine scroll)
            // textureSpaceX += scrollX;
            // textureSpaceY += scrollY;

            // BG Wrap?
            if (CntRegister.DisplayAreaOverflow)
            {
                /*
                 * while (textureSpaceX >= bgWidthInPixel) textureSpaceX -= bgWidthInPixel;
                 * while (textureSpaceY >= bgHeightInPixel) textureSpaceY -= bgHeightInPixel;
                 * while (textureSpaceX < 0) textureSpaceX += bgWidthInPixel;
                 * while (textureSpaceY < 0) textureSpaceY += bgHeightInPixel;
                 */
                textureSpaceX &= (bgWidthInPixel - 1);
                textureSpaceY &= (bgHeightInPixel - 1);
            }
            else
            {
                if (textureSpaceX < 0 || textureSpaceX >= bgWidthInPixel)
                {
                    return(0);
                }
                if (textureSpaceY < 0 || textureSpaceY >= bgHeightInPixel)
                {
                    return(0);
                }
            }


            // Coords (measured in tiles) of the tile we want to render
            //int bgRow = textureSpaceY / 8;
            //int bgColumn = textureSpaceX / 8;

            // Which row / column within the tile we are rendering?
            int tileRow    = textureSpaceY % 8;
            int tileColumn = textureSpaceX % 8;

            // Affine BG's have one byte screen data (the tile index). Also all tiles are 8bpp
            // Affine BG's are also all square (they have their own size table which is different to regular tiled bg's)
            //int tileInfoOffset = (bgRow * bgWidthInTiles) + bgColumn;
            uint tileInfoOffset = ((CntRegister.ScreenBlockBaseAddress * 2048u) | (uint)((textureSpaceY >> 3) * ((uint)bgWidthInPixel >> 3)) | (uint)(textureSpaceX >> 3));
            int  tileNumber     = gba.Memory.VRam[tileInfoOffset];

            int tileVramOffset = (int)(tileDataVramOffset + (tileNumber * tileSize));

            // Sometimes Bg's can be set up with invalid data which won't be drawn
            if (tileVramOffset >= gba.Memory.VRam.Length)
            {
                return(0);
            }

            int paletteIndex = TileHelpers.GetTilePixel(tileColumn, tileRow, true, gba.Memory.VRam, tileVramOffset, false, false);

            return(paletteIndex);
        }