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