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);
        }
示例#6
0
        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);
        }
示例#9
0
        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);
        }
示例#10
0
        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);
        }