/// <summary> /// Creates a Map Sprite from the given image /// </summary> public MapSprite(GBA.Image image) : base(WIDTH, HEIGHT) { if (image.Width != Width || image.Height != Height) { throw new Exception( "Image given has invalid dimensions: it should be " + Width + "x" + Height + " pixels"); } Tileset idleTiles = new GBA.Tileset(); Tileset moveTiles = new GBA.Tileset(); byte size = 0x02; if (image.IsRegionEmpty(new Rectangle(0, 32, Tile.SIZE, HEIGHT - 32)) && image.IsRegionEmpty(new Rectangle(24, 32, Tile.SIZE, HEIGHT - 32))) { size = 0x01; } else if ( image.IsRegionEmpty(new Rectangle(Tile.SIZE, 32 + 32 * 0, Tile.SIZE * 2, Tile.SIZE * 2)) && image.IsRegionEmpty(new Rectangle(Tile.SIZE, 32 + 32 * 1, Tile.SIZE * 2, Tile.SIZE * 2)) && image.IsRegionEmpty(new Rectangle(Tile.SIZE, 32 + 32 * 2, Tile.SIZE * 2, Tile.SIZE * 2))) { size = 0x00; } idleTiles.Parse(image, TileMap.Place(Map_Idle(size), 0, 4, W_TILES, H_TILES)); moveTiles.Parse(image, TileMap.Place(Map_Move(), 4, 0, W_TILES, H_TILES)); AddSprite(new Sprite(image.Colors, idleTiles, new TileMap(Map_Idle(size))), 0 * 8, 4 * 8); AddSprite(new Sprite(image.Colors, moveTiles, new TileMap(Map_Move())), 4 * 8, 0 * 8); IdleSize = size; }
void Core_InsertImage(string filepath) { Portrait portrait; try { GBA.Image image = new GBA.Image(filepath); int regular_width = Portrait.WIDTH * Tile.SIZE; int regular_height = Portrait.HEIGHT * Tile.SIZE; int generic_width = Portrait.Card_Width * Tile.SIZE; int generic_height = Portrait.Card_Height * Tile.SIZE; if (image.Width == regular_width && image.Height == regular_height) { portrait = new Portrait(image, false); } else if (image.Width == generic_width && image.Height == generic_height) { portrait = new Portrait(image, true); } else { throw new Exception("Image given has invalid dimensions.\r\n" + "It must be " + regular_width + "x" + regular_height + " or " + generic_width + "x" + generic_height + " (for a generic card portrait)"); } } catch (Exception ex) { Program.ShowError("Could not load the image file.", ex); return; } Core_Insert(portrait); }
/// <summary> /// Adds the image at 'filepath' as a new frame, creating the OAM data for said frame. /// Returns the index of the tilesheet for this frame /// </summary> Tuple <string, OAM_Array> AddFrame(bool background, GBA.Image frame, string filename) { OAM_Maker oam; if (frame.Width == 240 && frame.Height == 160) { try { oam = new OAM_Maker(ref Graphics, frame, BattleAnimation.SCREEN_OFFSET_X_R, BattleAnimation.SCREEN_OFFSET_Y); } catch (Exception ex) { throw new Exception("An error occurred while creating OAM for the image:\n" + filename + "\n\n" + ex.Message); } FrameData.Add(Tuple.Create((uint)oam.TilesetIndex, GetCurrentOAMOffset(Frames))); Frames.Add(oam.SpriteData); } else { throw new Exception("Frame image must be 240x160 pixels. Invalid image given:\n" + filename); } return(Tuple.Create(filename, oam.SpriteData)); }
void Core_DrawLayer(GBA.Bitmap result, GBA.Image image, Rectangle region, int offsetX, int offsetY) { int index; int pixel; for (int y = 0; y < region.Height; y++) { for (int x = 0; x < region.Width; x++) { index = ((region.X + x) / 2) + ((region.Y + y) * (image.Width / 2)); pixel = (x % 2 == 0) ? (image.Bytes[index] & 0x0F) : (image.Bytes[index] & 0xF0) >> 4; if (pixel != 0) { result.SetColor(offsetX + x, offsetY + y, image.Colors[pixel]); } } } }
/// <summary> /// Adds an affine sprite to the given tilesheet, and returns its position on said tilesheet /// </summary> Tuple <Point, Size> AddAffineToTilesheet(int frame, GBA.Image sprite) { int index = (int)FrameData[frame].Item1; Size size = new Size(sprite.Width / Tile.SIZE, sprite.Height / Tile.SIZE); Point sheet = Graphics[index].CheckIfFits(size); if (sheet == new Point(-1, -1)) { sheet = new Point(32 - size.Width, 8 - size.Height); //throw new Exception("Affine sprite doesn't fit on the current tilesheet."); } for (int y = 0; y < size.Height; y++) { for (int x = 0; x < size.Width; x++) { Graphics[index][sheet.X + x, sheet.Y + y] = sprite.GetTile(x * Tile.SIZE, y * Tile.SIZE); } } return(Tuple.Create(sheet, size)); }
void Core_InsertImage(string filepath) { MapSprite mapsprite; try { GBA.Image image = new GBA.Image(filepath, CurrentPalette); if (image.Width != MapSprite.W_TILES * 8 || image.Height != MapSprite.H_TILES * 8) { throw new Exception("Image given has invalid dimensions. It must be 160x128"); } mapsprite = new MapSprite(image); } catch (Exception ex) { Program.ShowError("Could not load the image file.", ex); return; } Core_Insert(mapsprite); }
void Core_LoadTitleScreen_FE7( Palette bg_palette, Tileset bg_tileset, Palette mg_palette, Tileset mg_tileset, TSA_Array mg_tsa, Palette fg_palette, Tileset fg_tileset) { GBA.Bitmap result; Palette palette = Palette.Empty(256); for (int i = 0; i < bg_palette.Count; i++) { palette.Set(GBA.Palette.MAX * 15 + i, bg_palette[i]); } for (int i = 0; i < mg_palette.Count; i++) { palette.Set(GBA.Palette.MAX * 14 + i, mg_palette[i]); } for (int i = 0; i < fg_palette.Count; i++) { palette.Set(i, fg_palette[i]); } result = new GBA.Bitmap(GBA.Screen.WIDTH, GBA.Screen.HEIGHT); result.Colors = palette; if (BG_CheckBox.Checked) { GBA.Image bg = bg_tileset.ToImage(GBA.Screen.W_TILES, GBA.Screen.H_TILES + 1, bg_palette.ToBytes(false)); for (int y = 0; y < GBA.Screen.HEIGHT; y++) { for (int x = 0; x < GBA.Screen.WIDTH; x++) { if (x < 8 && y < 8) { result[x, y] = GBA.Palette.MAX * 15 + bg[x, GBA.Screen.HEIGHT + y]; } else { result[x, y] = GBA.Palette.MAX * 15 + bg[x, y]; } } } } if (MG_CheckBox.Checked) { TSA_Image mg = new TSA_Image(mg_palette, mg_tileset, mg_tsa); for (int y = 0; y < mg.Height; y++) { for (int x = 0; x < mg.Width; x++) { if (mg[x, y] != 0) { result[x, 8 + y] = GBA.Palette.MAX * 14 + mg[x, y]; } } } } if (FG_CheckBox.Checked) { bool jap = (Core.CurrentROM.Version == GameVersion.JAP); bool eur = (Core.CurrentROM.Version == GameVersion.EUR); Palette[] palettes = Palette.Split(fg_palette, 8); GBA.Image fg; // durandal sword fg = fg_tileset.ToImage(32, 32, palettes[0].ToBytes(false)); Core_DrawLayer(result, fg, new Rectangle(0, 0, 192, 112), 32, 16); // large 'FIRE EMBLEM' title fg.Colors = palettes[4]; Core_DrawLayer(result, fg, new Rectangle(0, GBA.Screen.HEIGHT, GBA.Screen.WIDTH, 48), 2, jap ? 52 : 54); Core_DrawLayer(result, fg, new Rectangle(0, GBA.Screen.HEIGHT - 48, GBA.Screen.WIDTH, 48), 0, jap ? 48 : 52); // Nintendo & IS copyrights fg.Colors = palettes[2]; Core_DrawLayer(result, fg, new Rectangle(0, GBA.Screen.WIDTH - 16, GBA.Screen.HEIGHT - 16, 8), eur ? 8 : 16, GBA.Screen.HEIGHT - 16); Core_DrawLayer(result, fg, new Rectangle(0, GBA.Screen.WIDTH - 8, GBA.Screen.HEIGHT - 64, 8), eur ? 136 : GBA.Screen.HEIGHT, GBA.Screen.HEIGHT - 16); // 'Press Start' fg.Colors = palettes[1]; Core_DrawLayer(result, fg, new Rectangle(128, 208, 96, 16), jap ? 80 : 72, 120); if (jap) { // japanese subtitle fg.Colors = palettes[3]; Core_DrawLayer(result, fg, new Rectangle(144, 224, 112, 32), 64, 96); // japanese 'FIRE EMBLEM' overhead fg.Colors = palettes[2]; Core_DrawLayer(result, fg, new Rectangle(0, 208, 128, 16), 56, 40); } } Current = result; CurrentPalette = palette; }
void Core_LoadTitleScreen_FE6( Palette mg_palette, Tileset mg_tileset, Tileset fg_tileset, TSA_Array mg_tsa, Palette bg_palette, Tileset bg_tileset) { GBA.Bitmap result; Palette palette = Palette.Empty(256); for (int i = 0; i < mg_palette.Count; i++) { palette.Set(i, mg_palette[i]); } for (int i = 0; i < bg_palette.Count; i++) { bg_palette[i] = bg_palette[i].SetAlpha(false); palette.Set(GBA.Palette.MAX * 15 + i, bg_palette[i]); } result = new GBA.Bitmap(GBA.Screen.WIDTH, GBA.Screen.HEIGHT); result.Colors = palette; if (BG_CheckBox.Checked) { GBA.Image bg = bg_tileset.ToImage(GBA.Screen.W_TILES + 2, GBA.Screen.H_TILES, bg_palette.ToBytes(false)); for (int y = 0; y < GBA.Screen.HEIGHT; y++) { for (int x = 0; x < GBA.Screen.WIDTH; x++) { result[x, y] = GBA.Palette.MAX * 15 + bg[x, y]; } } } if (MG_CheckBox.Checked) { TSA_Image mg = new TSA_Image(mg_palette, mg_tileset, mg_tsa); for (int y = 0; y < GBA.Screen.HEIGHT; y++) { for (int x = 0; x < GBA.Screen.WIDTH; x++) { if (mg.GetColor(x, y).Value != 0) { result[x, y] = mg[x, y]; } } } } if (FG_CheckBox.Checked) { Palette[] palettes = Palette.Split(mg_palette, 8); GBA.Image fg; // large japanese 'FIRE EMBLEM' title fg = mg_tileset.ToImage(32, 25, palettes[4].ToBytes(false)); Core_DrawLayer(result, fg, new Rectangle(0, 152, GBA.Screen.WIDTH, 48), 0, 48); Core_DrawLayer(result, fg, new Rectangle(0, 104, GBA.Screen.WIDTH, 48), 0, 40); // small english 'FIRE EMBLEM' fg = fg_tileset.ToImage(32, 32, palettes[2].ToBytes(false)); Core_DrawLayer(result, fg, new Rectangle(0, 0, 128, 16), 99, 27); // Nintendo & IS copyrights Core_DrawLayer(result, fg, new Rectangle(0, 48, 208, 8), 16, 152); // japanese subtitle scroll thingy fg.Colors = palettes[3]; Core_DrawLayer(result, fg, new Rectangle(128, 16, 120, 32), 64, 85); // 'Press Start' fg.Colors = palettes[1]; Core_DrawLayer(result, fg, new Rectangle(128, 0, 80, 16), 80, 120); } Current = result; CurrentPalette = palette; }
void Core_InsertImage(string filepath) { IDisplayable image; try { Palette palette = Core.FindPaletteFile(filepath); if (TSA_Label.Checked && TSA_PointerBox.Value != new Pointer()) { int width = TSA_FlipRows_CheckBox.Checked ? ((TSA_Image)Image_ImageBox.Display).Tiling.Width : (int)Width_NumBox.Value; int height = TSA_FlipRows_CheckBox.Checked ? ((TSA_Image)Image_ImageBox.Display).Tiling.Height : (int)Height_NumBox.Value; if (palette == null) { image = new TSA_Image( width, height, new GBA.Bitmap(filepath), Palette.MAX, true); } else { image = new TSA_Image( width, height, new GBA.Bitmap(filepath), palette, Palette.MAX, true); } } else if (Tileset_8bpp_RadioButton.Checked) { image = new GBA.Bitmap(filepath, palette); } else { image = new GBA.Image(filepath, palette); } } catch (Exception ex) { Program.ShowError("Could not load image file.", ex); Core_Update(); return; } if (image is GBA.TSA_Image) { Core_Insert( Palette.Merge(((TSA_Image)image).Palettes), ((TSA_Image)image).Graphics.ToBytes(false), ((TSA_Image)image).Tiling); return; } if (image is GBA.Bitmap) { Core_Insert( ((Bitmap)image).Colors, ((Bitmap)image).ToBytes()); return; } if (image is GBA.Image) { Core_Insert( ((Image)image).Colors, new Tileset((Image)image).ToBytes(false)); return; } Program.ShowError("Image couldn't be inserted because of an internal error."); }