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); }