public static ushort[,] RenderMap(ROM game, Bitmap mapImage, Bitmap tileset, Bitmap attributeImage, Bitmap attributeBlocks, Map map) { FastPixel tp = new FastPixel(tileset); FastPixel mp = new FastPixel(mapImage); FastPixel ap = new FastPixel(attributeImage); FastPixel abp = new FastPixel(attributeBlocks); ushort[,] MapData = new ushort[map.Width, map.Height]; BinaryReader ReadROM = new BinaryReader(File.Open(game.FilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)); tp.rgbValues = new byte[tileset.Width * tileset.Height * 4]; mp.rgbValues = new byte[mapImage.Width * mapImage.Height * 4]; ap.rgbValues = new byte[attributeImage.Width * attributeImage.Height * 4]; abp.rgbValues = new byte[attributeBlocks.Width * attributeBlocks.Height * 4]; mp.Lock(); tp.Lock(); ap.Lock(); abp.Lock(); int TileSrcX, TileSrcY, AttSrcX, AttSrcY, DestX, DestY; ReadROM.BaseStream.Position = map.MapData - 0x8000000; for (int y = 0; y < map.Height; y++) { DestY = y * 16; for (int x = 0; x < map.Width; x++) { MapData[x, y] = ReadROM.ReadUInt16(); int Tile = MapData[x, y] & 0x3FF; int Attribute = MapData[x, y] >> 10; TileSrcX = (Tile % 8) * 16; TileSrcY = (Tile / 8) * 16; AttSrcX = (Attribute % 8) * 16; AttSrcY = (Attribute / 8) * 16; DestX = x * 16; for (int px = 0; px < 16; px++) { for (int py = 0; py < 16; py++) { mp.SetPixel(DestX + px, DestY + py, tp.GetPixel(TileSrcX + px, TileSrcY + py)); // Draw map ap.SetPixel(DestX + px, DestY + py, abp.GetPixel(AttSrcX + px, AttSrcY + py)); // Draw attribute map } } } } mp.Unlock(true); tp.Unlock(true); ap.Unlock(true); abp.Unlock(true); ReadROM.Close(); return(MapData); }
public static void RenderAttributes(Bitmap attributeImage, Bitmap attributeBlocks, Map map) { FastPixel ap = new FastPixel(attributeImage); FastPixel abp = new FastPixel(attributeBlocks); ap.rgbValues = new byte[attributeImage.Width * attributeImage.Height * 4]; abp.rgbValues = new byte[attributeBlocks.Width * attributeBlocks.Height * 4]; ap.Lock(); abp.Lock(); int SrcX, SrcY, DestX, DestY; for (int y = 0; y < map.Height; y++) { DestY = y * 16; for (int x = 0; x < map.Width; x++) { int Att = map.MapTileData[x, y] >> 10; SrcX = (Att % 8) * 16; SrcY = (Att / 8) * 16; DestX = x * 16; for (int px = 0; px < 16; px++) { for (int py = 0; py < 16; py++) { ap.SetPixel(DestX + px, DestY + py, abp.GetPixel(SrcX + px, SrcY + py)); } } } } ap.Unlock(true); abp.Unlock(true); }
public static void DrawTile8(FastPixel fpDrawer, byte[] gfxData, int tileindex, int x, int y, bool flipX, bool flipY, int palIndex, Color[] palette) { int mx = 0; int my = 0; if (flipX) { x += 7; } if (flipY) { y += 7; } int TileSeeker = tileindex * 64; if (TileSeeker + 64 > gfxData.Length) { return; } for (int i = 0; i < 64; i++) { if (gfxData[TileSeeker + i] > 0) { fpDrawer.SetPixel(x + (flipX ? -mx : mx), y + (flipY ? -my : my), palette[gfxData[TileSeeker + i] + (palIndex * 16)]); } mx++; if (mx == 8) { mx = 0; my++; } } }
public static Bitmap Render(ROM game, Tileset major, Tileset minor, Map map) { Bitmap TilesetImage = new Bitmap(128, 2560); Graphics tsGraphics = Graphics.FromImage(TilesetImage); BinaryReader ReadROM = new BinaryReader(File.Open(game.FilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)); tsGraphics.Clear(Color.FromArgb(24, 48, 80)); // Background color // Reading Palettes ushort[] GBAPalettes = new ushort[256]; ReadROM.BaseStream.Position = minor.Palette - 0x8000000; for (int i = 0; i < 208; i++) { GBAPalettes[i] = ReadROM.ReadUInt16(); } int[] BlockLimit = new int[2]; // Block limits for the 2 tilesets int[] TilesetSize = new int[2]; // Tileset filesize of the 2 tilesets int MajorPalettes; // Number of palettes for the major tileset if (game.GameCode.Substring(0, 3) == "BPR" || game.GameCode.Substring(0, 3) == "BPG") { MajorPalettes = 112; BlockLimit[0] = 640; BlockLimit[1] = 512; TilesetSize[0] = 0x5000; TilesetSize[1] = 0X5000; } else { MajorPalettes = 96; BlockLimit[0] = 512; BlockLimit[1] = 512; TilesetSize[0] = 0x4000; TilesetSize[1] = 0X5000; } ReadROM.BaseStream.Position = major.Palette - 0x8000000; for (int i = 0; i < MajorPalettes; i++) { GBAPalettes[i] = ReadROM.ReadUInt16(); } PaletteHook(GBAPalettes, map); // Reading Tileset uint[] TilesetImageOffsets = new uint[2] { major.Image - 0x8000000, minor.Image - 0x8000000 }; List <byte> Gfx = new List <byte>(); for (int i = 0; i < 2; i++) { ReadROM.BaseStream.Position = TilesetImageOffsets[i]; byte[] RawGfx = ReadROM.ReadBytes(TilesetSize[i]); if (RawGfx[0] == 0x10) // Check for LZ77 compression { Gfx.AddRange(Decode(LZ77.Uncompress(RawGfx))); } else { Gfx.AddRange(Decode(RawGfx)); } if (i == 0 && Gfx.Count < 0x8000) { for (int ii = 0; ii < 640; ii++) { Gfx.Add(0x0); } } } byte[] TilesetGfx = Gfx.ToArray(); // Decoding Palettes Color[] Palettes = new Color[256]; for (int i = 0; i < 256; i++) { Palettes[i] = GBAGraphics.DecodePalette(GBAPalettes[i]); } // Drawing Tileset FastPixel fp = new FastPixel(TilesetImage); uint[] TilesetBlockDataOffset = new uint[2] { major.BlockData - 0x8000000, minor.BlockData - 0x8000000 }; int x = 0; int y = 0; byte[] PositionX = new byte[4] { 0, 8, 0, 8 }; byte[] PositionY = new byte[4] { 0, 0, 8, 8 }; fp.rgbValues = new byte[TilesetImage.Width * TilesetImage.Height * 4]; fp.Lock(); for (int Tileset = 0; Tileset < 2; Tileset++) // 2 Tilesets { ReadROM.BaseStream.Position = TilesetBlockDataOffset[Tileset]; for (int i = 0; i < BlockLimit[Tileset]; i++) // Amount of tiles for each tileset (block number) { for (int Layer = 0; Layer < 2; Layer++) // 2 Layers (Bottom & Top) { for (int Tile = 0; Tile < 4; Tile++) // 4 Tiles for each layer { ushort TileData = ReadROM.ReadUInt16(); int TileIndex = TileData & 0x3FF; int FlipX = (TileData & 0x400) >> 10; int FlipY = (TileData & 0x800) >> 11; int PalIndex = (TileData & 0xF000) >> 12; DrawTile8(fp, TilesetGfx, TileIndex, x * 16 + PositionX[Tile], y * 16 + PositionY[Tile], FlipX == 1, FlipY == 1, PalIndex, Palettes); } } x++; if (x == 8) { x = 0; y++; } } } fp.Unlock(true); ReadROM.Close(); return(TilesetImage); }