public static void RenderSprites(BitmapData canvas, int center_x, int center_y, OamSprite[] oam, byte[] gfxData, int gfxPointer, int palettenum, bool transparent = true) { for (int priority = 3; priority >= 0; priority--) { for (int oamIndex = 0; oamIndex < oam.Length; oamIndex++) { var o = oam[oamIndex]; if (o.Priority == priority) { // Draw the subsprite int tilePointer = o.Tile << 5; for (int y = 0; y < o.Height; y += 8) { int actualY = o.FlipV ? (o.Height - y - 8) : y; for (int x = 0; x < o.Width; x += 8) { byte[,] pixelData = gfxData.Read4BppTile(gfxPointer + tilePointer); tilePointer += 0x20; int actualX = o.FlipH ? (o.Width - x - 8) : x; GfxProvider.RenderToBitmap(canvas, pixelData, (o.CoordX + center_x) + actualX, (o.CoordY + center_y) + actualY, o.FlipH, o.FlipV, palettenum, transparent); } } } } } }
unsafe public static Bitmap[] GetEnemySprite(int index) { Bitmap[] ret = new Bitmap[2]; // Get gfx stuff int gfxPointer = GetPointer(index + 8) + 12; byte[] gfxData; if (LZ77.Decompress(Rom, gfxPointer, out gfxData) == -1) { return(null); } // Bug with MOTHER 3: for the second Mole Cricket (index 0x3D), // it uses tiles that are out of bounds in the tile data! // So let's resize the tile buffer to 32KB (max addressable size) Array.Resize(ref gfxData, 0x8000); // Get pal stuff var palette = GetPals(index); // Get OAM stuff int oamPointer = GetPointer(index + 0x2A4); var oam = new OamSprite[2][]; for (int i = 0; i < 2; i++) { // Get the front/back sprite pointer int subPointer = Rom.ReadUShort(oamPointer + 8 + (i << 1)) + oamPointer; // Get the number of sub-sprites ushort numSubSprites = Rom.ReadUShort(subPointer + 2); oam[i] = new OamSprite[numSubSprites]; // Get the OAM data for (int j = 0; j < numSubSprites; j++) { oam[i][j] = Rom.ReadOam(subPointer + 4 + (j << 3)); // Filter out the palette -- each enemy only has one palette, regardless of what the OAM entry says // This is only an issue with enemy #0 anyway oam[i][j].Palette = 0; } // Render the sprites Bitmap bmp = GfxProvider.RenderSprites(oam[i], gfxData, palette); ret[i] = bmp; } return(ret); }
public static Bitmap GetFrame(int index, int frame) { var pd = GfxBattleAnimations.AnimEntries[index]; // Get the gfx pointer var gfxEntry = GfxBattleTable.GetEntry(pd.GfxEntry); // Get the arrangement var arr = GfxBattleTable.GetArr(pd.ArrEntries[frame]); // Get the palette var pal = GfxBattleTable.GetPalettes(pd.PalEntry); // Render return(GfxProvider.RenderArrangement(arr, 32, 32, Rom, gfxEntry[0], pal, true, false)); }
public static Bitmap GetOam(int bank, int index, int subindex, int oam, int palnum = -1, bool transparent = true) { // Get the palette var pal = SpritePalettes.GetPalette(index, palnum); // Get the graphics pointer int gfxpointer = SpriteGfx.GetPointer(bank, index); // Get the sprite info var si = SpriteInfo.InfoEntries[bank][index].Sprites[subindex].Sprites[oam]; // Bail out if we need to if ((pal == null) || (gfxpointer == -1) || (si == null)) { return(null); } return(GfxProvider.RenderSprites(new OamSprite[] { si }, Rom, gfxpointer, pal, transparent)); }
public static void GetFrame(BitmapData bd, int index, int frame, int pal) { var s = Sequences[index]; if (frame >= s.ArrLen) { throw new Exception("Frame number exceeded max value!"); } int[] gfxEntry = GetEntry(s.GfxEntry); int[] palEntry = GetEntry(s.PalEntry); // Get the palette var palette = Palettes[pal]; // Read the arrangement var arr = GetArr(s.ArrStart + frame); GfxProvider.RenderArrangement(bd, arr, 30, 20, Rom, gfxEntry[0], false, false); }
public static void RenderItems(BitmapData canvas, int index, int center_x, int center_y, int Palnum, bool transparent = true) { int Addresses = Rom.ReadInt(0x1439388) + 0x14383E4; int tileAddress = Addresses + ((index * 9) << 5); var Palette = Rom.ReadPal(GfxItems.GetPaletteAddress(index)); for (int y = 0; y < 24; y += 8) { for (int x = 0; x < 24; x += 8) { byte[,] ch = Rom.Read4BppTile(tileAddress); tileAddress += 0x20; GfxProvider.RenderToBitmap(canvas, ch, (x + center_x), (y + center_y), false, false, Palnum, transparent); } } }
public static void GetLayer(Bitmap bmp, BitmapData bd, int index, int t = 0) { var bg = Bgs[index]; var arr = GfxBattleBgTable.GetArr(bg.ArrEntry); var tmpPal = (MPalette)bg.Palette.Clone(); // Rotate the palette UpdatePal(tmpPal, bg, t); for (int i = 0; i < arr.Length; i++) { arr[i].Palette &= 1; } // Set the palette bmp.CopyPalette(tmpPal, false); int gfxPointer = GfxBattleBgTable.GetEntry(bg.GfxEntry)[0]; GfxProvider.RenderArrangement(bd, arr, 32, 32, Rom, gfxPointer, true, false); }
public static Bitmap GetImage(int index) { // All item images are stored nice and linearly // Each item image is 3x3 tiles int tileAddress = Address + ((index * 9) << 5); var palette = Rom.ReadPal(GetPaletteAddress(index)); Bitmap ret = new Bitmap(24, 24, PixelFormat.Format8bppIndexed); ColorPalette cp = ret.Palette; cp.Entries[0] = Color.Transparent; for (int i = 1; i < 16; i++) { cp.Entries[i] = palette.Entries[0][i]; } ret.Palette = cp; BitmapData bd = ret.LockBits(ImageLockMode.WriteOnly); if (Helpers.IsLinux) { Helpers.FillBitmap(bd); } for (int y = 0; y < 24; y += 8) { for (int x = 0; x < 24; x += 8) { byte[,] ch = Rom.Read4BppTile(tileAddress); tileAddress += 0x20; GfxProvider.RenderToBitmap(bd, ch, x, y, false, false, 0, true); } } ret.UnlockBits(bd); return(ret); }
public static Bitmap GetLayer2(int room, int flags) { var rInfo = RoomInfo.RoomInfoEntries[room]; var rGfxPal = RoomGfxPal.RoomGfxPalEntries[room]; // Get the width and height (in 16*16 tiles) int w = rInfo.Width; int h = rInfo.Height; // Create the bitmap Bitmap bmp = new Bitmap(w << 4, h << 4, PixelFormat.Format8bppIndexed); BitmapData bd = bmp.LockBits(ImageLockMode.WriteOnly); // Get the graphics var gfx = RoomGfx.GetTilesets(rGfxPal); int hash = gfx.GetHashCode(); // Get the tiles var tiles = RoomTiles.GetTiles(room); if (tiles == null) { return(null); } // Get the map var map = new byte[1][]; for (int i = 1; i < 2; i++) { map[i - 1] = RoomMap.GetMap(room, i); } // Get the palette var pal = RoomPal.GetPalette(rGfxPal.Pal); bmp.CopyPalette(pal, true); // For each layer... for (int layer = 1; layer >= 1; layer--) { // Check if it's in the flags for rendering this layer if (((flags & (1 << layer)) != 0) && (map[layer - 1] != null)) { // Make sure the map is big enough: some of them aren't! if (map[layer - 1].Length >= (w * h * 2)) { // We're drawing it, so for each entry in the map... for (int mapy = 0; mapy < h; mapy++) { for (int mapx = 0; mapx < w; mapx++) { // Get the 16x16 tile number ushort ch = map[layer - 1].ReadUShort((mapx + (mapy * w)) * 2); ushort tile16 = (ushort)(ch & 0x3FF); if ((tile16 >> 6) < 12) { int tpal = (ch >> 10) & 0xF; bool tflipx = (ch & 0x4000) != 0; bool tflipy = (ch & 0x8000) != 0; // For this tile... get the four 8x8 subtiles int[,] tile8 = new int[2, 2]; bool[,] sflipx = new bool[2, 2]; bool[,] sflipy = new bool[2, 2]; uint magic = tiles.ReadUInt(tile16 * 8); tile8[0, 0] = tiles[(tile16 * 8) + 4]; tile8[0, 1] = tiles[(tile16 * 8) + 5]; tile8[1, 0] = tiles[(tile16 * 8) + 6]; tile8[1, 1] = tiles[(tile16 * 8) + 7]; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { sflipx[i, j] = (tile8[i, j] & 0x40) != 0; sflipy[i, j] = (tile8[i, j] & 0x80) != 0; tile8[i, j] &= 0x3F; tile8[i, j] |= (ch & 0x3C0); } } // magic appears to contain some sort of tile mask... uint mask = (magic >> 16) & 0xF; if ((mask & 0x1) == 0) { tile8[0, 0] = -1; } if ((mask & 0x2) == 0) { tile8[0, 1] = -1; } if ((mask & 0x4) == 0) { tile8[1, 0] = -1; } if ((mask & 0x8) == 0) { tile8[1, 1] = -1; } // For each of these subtiles... for (int tiley = 0; tiley < 2; tiley++) { for (int tilex = 0; tilex < 2; tilex++) { if (tile8[tiley, tilex] >= 0) { int tileset = tile8[tiley, tilex] >> 6; int subtile = tile8[tiley, tilex] & 0x3F; int tileoffset = subtile << 5; var pixels = gfx[tileset].Read4BppTile(tileoffset); int tx = tflipx ? 1 - tilex : tilex; int ty = tflipy ? 1 - tiley : tiley; GfxProvider.RenderToBitmap(bd, pixels, (mapx << 4) + (tx << 3), (mapy << 4) + (ty << 3), sflipx[tiley, tilex] ^ tflipx, sflipy[tiley, tilex] ^ tflipy, tpal, true); } } } } } } } } } bmp.UnlockBits(bd); return(bmp); }
public static Bitmap GetSprites(int canvas0Width, int canvas0Height, int room, CheckBox[] chkTable, out Bitmap Enemies, out Bitmap Enemies2) { var rInfo = RoomInfo.RoomInfoEntries[room]; var rGfxPal = SpritePalettes.DefaultPals; // Get the width and height (in 16*16 tiles) int w = rInfo.Width; int h = rInfo.Height; // Create the bitmap Bitmap bmp = new Bitmap(canvas0Width, canvas0Height, PixelFormat.Format8bppIndexed); Enemies = new Bitmap(canvas0Width, canvas0Height, PixelFormat.Format8bppIndexed); Enemies2 = new Bitmap(canvas0Width, canvas0Height, PixelFormat.Format8bppIndexed); Enemies.CopyPalette(rGfxPal, true); Enemies2.CopyPalette(rGfxPal, true); int Last = 0, palettenum = 0; List <int> Palettenum = new List <int>(); BitmapData bd = bmp.LockBits(ImageLockMode.WriteOnly); BitmapData be = Enemies.LockBits(ImageLockMode.WriteOnly); BitmapData be2 = Enemies2.LockBits(ImageLockMode.WriteOnly); bmp.CopyPalette(rGfxPal, true); for (int j = 0; j <= 4; j++) { if (chkTable[j].Checked == true) { for (int i = 0; i < RoomSprites.Sprites[(room * 5) + j].Count; i++) { var rs = RoomSprites.Sprites[(room * 5) + j][i]; if (!((rs.Sprite <= 0xFF) || (rs.Sprite >= 0x26C))) { MPalette[] NewestPalette; MPalette[] NewestPalette2; RenderPalette(SpritePalettes.GetPalette(rs.Sprite), Enemies.Palette, Enemies2.Palette, Last, out NewestPalette, out Last, out NewestPalette2, out palettenum); Palettenum.Add(palettenum); Enemies.CopyPalette(NewestPalette, true); Enemies2.CopyPalette(NewestPalette2, true); } } } } int count = 0; for (int j = 0; j <= 4; j++) { if (chkTable[j].Checked == true) { for (int i = 0; i < RoomSprites.Sprites[(room * 5) + j].Count; i++) { var rs = RoomSprites.Sprites[(room * 5) + j][i]; var si = SpriteInfo.InfoEntries[0][rs.Sprite]; if ((rs.Sprite == 0) || (rs.Sprite == 0xC0)) { continue; } if ((rs.Sprite >= 0x2D0) && (rs.Sprite < 0x3D0)) { // All item images are stored nice and linearly // Each item image is 3x3 tiles var index = rs.Sprite - 0x2D0; RenderItems(bd, index, rs.X, rs.Y, SpritePalettes.GetPalNum(rs.Sprite)); } else { var s = si.Sprites[rs.Direction % si.Sprites.Length]; if ((rs.Sprite <= 0xFF) || (rs.Sprite >= 0x26C)) { GfxProvider.RenderSprites(bd, rs.X, rs.Y, s.Sprites, Rom, SpriteGfx.GetPointer(0, rs.Sprite), SpritePalettes.GetPalNum(rs.Sprite)); } else { RenderEnemies(be, be2, rs.X, rs.Y, s.Sprites, Rom, SpriteGfx.GetPointer(0, rs.Sprite), Palettenum[count]); count++; } } } } } Enemies2.UnlockBits(be2); Enemies.UnlockBits(be); bmp.UnlockBits(bd); return(bmp); }