예제 #1
0
 /// <summary>
 /// Returns a boolean indicating whether or not 'this' and 'oam' have the same value.
 /// </summary>
 public bool Equals(OAM oam)
 {
     for (int i = 0; i < LENGTH; i++)
     {
         if (Data[i] != oam.Data[i])
         {
             return(false);
         }
     }
     return(true);
 }
예제 #2
0
        /// <summary>
        /// Creates an affine/transformed sprite from a block of OAM data and the affine data with it
        /// </summary>
        public Sprite(Palette palette, Tileset tileset, OAM oam, OAM_Affine transform)
        {
            Size size = oam.GetDimensions();

            Load(palette, tileset, new TileMap(oam.GetTileMap(size)), false, false);

            int width  = (oam.OBJMode == OAM_OBJMode.BigAffine) ? size.Width * 16 : size.Width * 8;
            int height = (oam.OBJMode == OAM_OBJMode.BigAffine) ? size.Height * 16: size.Height * 8;

            byte[] data = new byte[width * height];
            int    tileX, tileY;
            int    affX, affY;
            int    halfW = width / 2;
            int    halfH = height / 2;

            for (int y = halfH * -1; y < halfH; y++)
            {
                for (int x = halfW * -1; x < halfW; x++)
                {
                    affX = (int)(transform.Ux * x + transform.Vx * y) + size.Width * 4;
                    affY = (int)(transform.Uy * x + transform.Vy * y) + size.Height * 4;
                    if (affX < 0 || affX >= size.Width * 8)
                    {
                        continue;
                    }
                    if (affY < 0 || affY >= size.Height * 8)
                    {
                        continue;
                    }

                    tileX = affX / Tile.SIZE;
                    tileY = affY / Tile.SIZE;
                    int index = Tiles[tileX, tileY];
                    if (index < 0 || index >= Sheet.Count)
                    {
                        continue;
                    }
                    tileX = affX % Tile.SIZE;
                    tileY = affY % Tile.SIZE;

                    data[(halfW + x) + (halfH + y) * width] = (byte)Sheet[index][tileX, tileY];
                }
            }
            Transform = new Bitmap(width, height, palette.ToBytes(false), data);
        }
        public static List <OAM> OAMGet(byte[] data, int address, int num, int i)
        {
            List <OAM> OAM = new List <OAM>();

            for (int j = 0; j < num; j++)
            {
                OAM Tuk = new OAM();
                Tuk.Address = address + (j * 8);
                Tuk.Num     = i;
                Tuk.Y       = data[Tuk.Address];
                if (Tuk.Y >= 0x80)
                {
                    Tuk.Y -= 0x80;
                }
                else
                {
                    Tuk.Y += 0x80;
                }
                Tuk.X = data[Tuk.Address + 2] + ((data[Tuk.Address + 3] & 0x1) << 8);
                if (Tuk.X >= 0x100)
                {
                    Tuk.X -= 0x100;
                }
                else
                {
                    Tuk.X += 0x100;
                }
                int Shape = (data[Tuk.Address + 1]) & 0xC0;
                int Size  = (data[Tuk.Address + 3]) & 0xC0;
                getSizesOAM(Shape, Size, out Tuk.Width, out Tuk.Height);
                Tuk.Flips = (data[Tuk.Address + 3] >> 4) & 0x3;
                Tuk.Tile  = (data[Tuk.Address + 4]) + (((data[Tuk.Address + 5]) & 0x3) << 8);
                OAM.Add(Tuk);
            }
            return(OAM);
        }
예제 #4
0
        /// <summary>
        /// Supposed to check other OAMs in the sheet to avoid redundancy - currently unused
        /// </summary>
        OAM GetMatch(GBA.Image image, int imageX, int imageY, int tileset, Tuple <Point, bool, bool> match, ref List <TileSheet> Graphics)
        {
            if (match == null)
            {
                return(OAM.Terminator);
            }

            bool[,] matched = new bool[8, 8];
            Point sheet = match.Item1;
            bool  flipH = match.Item2;
            bool  flipV = match.Item3;
            Tile  tile;

            for (int tileY = 0; flipV ? (tileY > -8) : (tileY < 8); tileY += flipV ? -1 : 1)
            {
                for (int tileX = 0; flipH ? (tileX > -8) : (tileX < 8); tileX += flipH ? -1 : 1)
                {
                    if (tileX == 0 && tileY == 0)
                    {
                        continue;
                    }
                    // top-left corner tile of OAM obj has already been matched
                    try
                    {
                        if (Graphics[tileset][sheet.X + tileX, sheet.Y + tileY] == null)
                        {
                            continue;
                        }

                        tile = image.GetTile(imageX + tileX * 8, imageY + tileY * 8);
                    }
                    catch { break; }

                    if (flipH)
                    {
                        tile = tile.FlipHorizontal();
                    }
                    if (flipV)
                    {
                        tile = tile.FlipVertical();
                    }

                    if (tile.Equals(Graphics[tileset][sheet.X + tileX, sheet.Y + tileY]))
                    {
                        matched[Math.Abs(tileX), Math.Abs(tileY)] = true;
                    }
                }
            }

            var shapesize = OAM.GetShapeSize(GetSpriteSize(matched));

            if (shapesize == null)
            {
                return(OAM.Terminator);
            }

            return(new OAM(
                       shapesize.Item1,
                       shapesize.Item2,
                       (Int16)(imageX - 0x94), (Int16)(imageY),
                       0x00,
                       0x00,
                       OAM_GFXMode.Normal,
                       OAM_OBJMode.Normal,
                       false,
                       false,
                       (byte)sheet.X, (byte)sheet.Y,
                       flipH, flipV));
        }
예제 #5
0
        public OAM_Maker(ref List <TileSheet> Graphics, GBA.Image image, int offsetX, int offsetY)
        {
            Rectangle sprite = GetSpriteArea(image);

            if (sprite == new Rectangle())
            {
                TilesetIndex = 0;
                SpriteData   = new OAM_Array();
                return;
            }

            var OAMs = GetSpriteOAMs(image, sprite);

            TilesetIndex = -1;
            Point[] sheet = new Point[OAMs.Count];
            for (int i = 0; i < Graphics.Count; i++)
            {
                sheet = Graphics[i].CheckIfFits(OAMs);

                if (sheet == null)
                {
                    continue;
                }
                else
                {
                    TilesetIndex = i; break;
                }
            }
            if (TilesetIndex == -1)
            {
                TilesetIndex = Graphics.Count;
                Graphics.Add(new TileSheet(32, 8));
                sheet = Graphics[TilesetIndex].CheckIfFits(OAMs);
                if (sheet == null)
                {
                    throw new Exception("Frame has more tiles than a 32x8 TileSheet allows.");
                }
            }

            List <OAM> result = new List <OAM>();
            Point      pos;
            Size       size;

            for (int i = 0; i < OAMs.Count; i++)
            {
                pos  = OAMs[i].Item1;
                size = OAMs[i].Item2;

                for (int y = 0; y < size.Height; y++)
                {
                    for (int x = 0; x < size.Width; x++)
                    {
                        Graphics[TilesetIndex][sheet[i].X + x, sheet[i].Y + y] = image.GetTile(
                            pos.X + x * Tile.SIZE,
                            pos.Y + y * Tile.SIZE);
                    }
                }

                var shapesize = OAM.GetShapeSize(size);
                if (shapesize == null)
                {
                    throw new Exception("Invalid OAM Shape/Size created.");
                }

                if (result.Count == MAXIMUM)
                {
                    throw new Exception("There cannot be more than " + MAXIMUM + " OAM objects in one frame.");
                }
                result.Add(new OAM(
                               shapesize.Item1,
                               shapesize.Item2,
                               (Int16)(pos.X - offsetX),
                               (Int16)(pos.Y - offsetY),
                               0x00,
                               0x00,
                               OAM_GFXMode.Normal,
                               OAM_OBJMode.Normal,
                               false,
                               false,
                               (byte)sheet[i].X, (byte)sheet[i].Y,
                               false, false));

                /*
                 * EmblemMagic.Program.ShowMessage(
                 *  "h: " + size.Width + ", w: " + size.Height +
                 *  '\n' + "shape: " + shapesize.Item1 + ", size: " + shapesize.Item2 +
                 *  '\n' + result[result.Count - 1].SpriteShape + ", " + result[result.Count - 1].SpriteSize +
                 *  '\n' + EmblemMagic.Util.BytesToSpacedHex(result[result.Count - 1].ToBytes())); */
            }

            SpriteData = new OAM_Array(result);
        }
 public static int compareTiles(OAM one, OAM two)
 {
     return(one.Tile.CompareTo(two.Tile));
 }
예제 #7
0
 /// <summary>
 /// Creates a sprite from a block of OAM data
 /// </summary>
 public Sprite(Palette palette, Tileset tileset, OAM oam)
 {
     Load(palette, tileset, new TileMap(oam.GetTileMap(oam.GetDimensions())), oam.FlipH, oam.FlipV);
 }