public Background( int width, int height, GBA.Bitmap image, int paletteAmount, bool checkRedundantTiles) : base(width, height, image, paletteAmount, checkRedundantTiles) { }
public WorldMap_FE6_Large( Pointer palette, Pointer tiles) { Pointer[] palettes = GetPointerArray(palette); Pointer[] tilesets = GetPointerArray(tiles); Graphics = new GBA.Bitmap[4]; for (int i = 0; i < 4; i++) { Graphics[i] = new GBA.Bitmap(240, 160, Core.ReadData(palettes[i], 0), Core.ReadData(tilesets[i], 0)); for (int p = 0; p < 256; p++) { Graphics[i].Colors[p] = Graphics[i].Colors[p].SetAlpha(false); } } }
void Core_Screen_InsertImage(string filepath) { BattleScreen screen; try { GBA.Bitmap image = new GBA.Bitmap(filepath); GBA.Palette palettes = new Palette( filepath.Substring(0, filepath.Length - 4) + " palette.png", 4 * Palette.MAX); screen = new BattleScreen(image, Palette.Split(palettes, 4)); } catch (Exception ex) { Program.ShowError("Could not load the image.", ex); return; } Core_Insert(screen); }
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]); } } } }
public WorldMap_FE6_Large(GBA.Bitmap image) { if (image.Width != Width || image.Height != Height) { throw new Exception("Image given has invalid dimensions. It should be 480x320 pixels."); } for (int i = image.Colors.Count; i < 256; i++) { image.Colors.Add(new GBA.Color(0x0000)); } Graphics = new GBA.Bitmap[4]; for (int i = 0; i < 4; i++) { Graphics[i] = new GBA.Bitmap(image, new Rectangle( ((i & 0x1) == 0) ? 0 : 240, ((i & 0x2) == 0) ? 0 : 160, 240, 160)); } }
public Font(GBA.Bitmap image) { GBA.Color[] colors = new GBA.Color[4] { image.Colors[0], image.Colors[1], image.Colors[2], image.Colors[3] }; Glyphs = new Glyph[256]; int x = 1; int y = 0; for (int i = 1; i < Glyphs.Length; i++) { Glyphs[i] = new Glyph(new GBA.Bitmap(image, new Rectangle(x * 16, y * 16, 16, 16)), colors); if (Glyphs[i].IsEmpty()) { Glyphs[i] = null; } /* * for (int j = 0; j < i; j++) * { * if (Glyphs[i].Equals(Glyphs[j])) * Glyphs[i] = Glyphs[j]; * } */ x++; if (x % 16 == 0) { x = 0; y++; } } }
void Core_LoadTitleScreen_FE8( Palette bg_palette, Tileset bg_tileset, TSA_Array bg_tsa, 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++) { bg_palette[i] = bg_palette[i].SetAlpha(false); 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) { TSA_Image bg = new TSA_Image(bg_palette, bg_tileset, bg_tsa); for (int y = 0; y < bg.Height; y++) { for (int x = 0; x < bg.Width; x++) { if (bg[x, y] != 0) { 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, y] = GBA.Palette.MAX * 14 + mg[x, y]; } } } } if (FG_CheckBox.Checked) { Palette[] palettes = Palette.Split(fg_palette, 8); GBA.Image fg; if (Core.CurrentROM.Version == GameVersion.JAP) { // large 'FIRE EMBLEM' title logo fg = fg_tileset.ToImage(32, 32, palettes[2].ToBytes(false)); Core_DrawLayer(result, fg, new Rectangle(0, 48, 240, 48), 0, 44); // shadow Core_DrawLayer(result, fg, new Rectangle(0, 0, 240, 48), 0, 39); // logo Core_DrawLayer(result, fg, new Rectangle(240, 0, 16, 16), 216, 39); // TM // small 'FIRE EMBLEM' overhead fg.Colors = palettes[1]; Core_DrawLayer(result, fg, new Rectangle(128, 104, 120, 16), 60, 26); // 'THE SACRED STONES' subtitle/scroll thingy fg.Colors = palettes[3]; Core_DrawLayer(result, fg, new Rectangle(0, 104, 128, 32), 56, 87); // 'Press START' fg.Colors = palettes[0]; Core_DrawLayer(result, fg, new Rectangle(128, 120, 80, 16), 80, 124); // Nintendo & IS copyrights fg.Colors = palettes[1]; Core_DrawLayer(result, fg, new Rectangle(0, 96, 240, 8), 16, 148); } else { // large 'FIRE EMBLEM' title logo fg = fg_tileset.ToImage(32, 32, palettes[2].ToBytes(false)); Core_DrawLayer(result, fg, new Rectangle(0, 32, 240, 32), 4, 53); // shadow Core_DrawLayer(result, fg, new Rectangle(0, 0, 240, 32), 4, 48); // logo Core_DrawLayer(result, fg, new Rectangle(240, 0, 16, 16), 220, 41); // TM // 'THE SACRED STONES' subtitle/scroll thingy fg.Colors = palettes[3]; Core_DrawLayer(result, fg, new Rectangle(0, 72, 208, 32), 16, 85); // 'Press START' fg.Colors = palettes[0]; Core_DrawLayer(result, fg, new Rectangle(208, 72, 48, 16), 72, 124); Core_DrawLayer(result, fg, new Rectangle(208, 88, 48, 16), 120, 124); // Nintendo & IS copyrights fg.Colors = palettes[1]; Core_DrawLayer(result, fg, new Rectangle(0, 64, 240, 8), 4, 148); } } Current = result; CurrentPalette = palette; }
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."); }
void Core_LoadMap_Units(GBA.Bitmap result) { try { Pointer address_mapsprites = Core.GetPointer("Map Sprite Idle Array"); Pointer address_classes = Core.GetPointer("Class Array"); Pointer address; byte palette_index; byte palette_amount = 4; address = Core.GetPointer("Map Sprite Palettes"); byte[][] palettes = new byte[palette_amount][]; for (int i = 0; i < palette_amount; i++) { palettes[i] = Core.ReadData(address + i * Palette.LENGTH, Palette.LENGTH); result.Colors.Add(new Palette(palettes[i])); } int class_length = (Core.CurrentROM is FE6 ? 72 : 84); GBA.Image image; byte unitclass; byte mapsprite; byte size; Tileset tileset; int offsetX; int offsetY; int index; for (int i = 0; i < EventList.Count; i++) { if (EventList[i].Command == "UNIT" && EventList[i].Label != null) { index = UnitEvents_ListBox.Items.IndexOf(EventList[i].Label); if (index == -1) { continue; } else if (!UnitEvents_ListBox.GetItemChecked(index)) { continue; } unitclass = (byte)EventList[i].Arguments[1]; mapsprite = Core.ReadByte(address_classes + 6 + unitclass * class_length); address = address_mapsprites + mapsprite * 8; size = Core.ReadByte(address + 2); tileset = new Tileset(Core.ReadData(Core.ReadPointer(address + 4), 0)); palette_index = (byte)(EventList[i].Arguments[3] & 6); if (palette_index > 2) { palette_index -= 3; } switch (size) { case 0x00: image = tileset.ToImage(2, 2, palettes[palette_index]); break; case 0x01: image = tileset.ToImage(2, 4, palettes[palette_index]); break; case 0x02: image = tileset.ToImage(4, 4, palettes[palette_index]); break; default: image = null; break; } if (image != null) { offsetX = (int)(EventList[i].Arguments[UNIT_argX] * 16); offsetY = (int)(EventList[i].Arguments[UNIT_argY] * 16); offsetX -= (size == 0x02 ? 8 : 0); offsetY -= (size == 0x00 ? 0 : 16); int pixel; for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { index = (x / 2) + y * (image.Width / 2); pixel = (x % 2 == 0) ? (image.Bytes[index] & 0x0F) : (image.Bytes[index] & 0xF0) >> 4; if (pixel != 0 && offsetX + x >= 0 && offsetX + x < result.Width && offsetY + y >= 0 && offsetY + y < result.Height) { result.SetColor(offsetX + x, offsetY + y, image.Colors[pixel]); } } } } } } } catch (Exception ex) { Program.ShowError("Could not load the units to display on the map.", ex); } }
void Core_LoadMap() { Pointer address = Core.GetPointer("Map Data Array"); Pointer poin_palette = Core.ReadPointer(address + 4 * (byte)Current["Palette"]); Pointer poin_tileset1 = Core.ReadPointer(address + 4 * (byte)Current["Tileset1"]); Pointer poin_tileset2 = Core.ReadPointer(address + 4 * (byte)Current["Tileset2"]); Pointer poin_tsa = Core.ReadPointer(address + 4 * (byte)Current["TSA"]); Pointer poin_mapdata = Core.ReadPointer(address + 4 * (byte)Current["Map"]); Pointer poin_mapchanges = Core.ReadPointer(address + 4 * (byte)Current["MapChanges"]); MapTileset map_tileset; try { map_tileset = new MapTileset( Core.ReadData(poin_palette, Map.PALETTES * Palette.LENGTH), Core.ReadData(poin_tileset1, 0), Core.ReadData(poin_tileset2, 0), Core.ReadData(poin_tsa, 0)); } catch (Exception ex) { map_tileset = null; Program.ShowError("Could not load the the tileset for this chapter.", ex); } try { CurrentMap = new Map(map_tileset, Core.ReadData(poin_mapdata, 0), poin_mapchanges, false); } catch (Exception ex) { CurrentMap = null; Program.ShowError("Could not load the map for this chapter.", ex); } if (CurrentMap.Changes != null) { MapChanges_ListBox.ItemCheck -= MapChanges_ListBox_ItemCheck; if (MapChanges_ListBox.Items.Count > 0) { for (int i = 0; i < CurrentMap.ShowChanges.Length; i++) { CurrentMap.ShowChanges[i] = MapChanges_ListBox.GetItemChecked(i); } MapChanges_ListBox.Items.Clear(); } for (int i = 0; i < CurrentMap.Changes.Count; i++) { MapChanges_ListBox.Items.Add( "0x" + Util.ByteToHex(CurrentMap.Changes.GetNumber(i)), CurrentMap.ShowChanges[i]); } MapChanges_ListBox.ItemCheck += MapChanges_ListBox_ItemCheck; } GBA.Bitmap result = new GBA.Bitmap(CurrentMap); if (View_Units.Checked) { Core_LoadMap_Units(result); } MapViewBox.Size = new Size(CurrentMap.Width, CurrentMap.Height); MapViewBox.Load(result); }
private void File_Tools_CreateImage_Click(Object sender, EventArgs e) { GBA.Bitmap idle = null; GBA.Bitmap move = null; byte size; OpenFileDialog openWindow_idle = new OpenFileDialog(); openWindow_idle.RestoreDirectory = true; openWindow_idle.Multiselect = false; openWindow_idle.FilterIndex = 1; openWindow_idle.Filter = "'IDLE' Map sprite image file (*.png, *.bmp, *.gif)|*.png;*.bmp;*.gif|" + "All files (*.*)|*.*"; if (openWindow_idle.ShowDialog() == DialogResult.OK) { if (openWindow_idle.FileName.EndsWith(".png", StringComparison.OrdinalIgnoreCase) || openWindow_idle.FileName.EndsWith(".bmp", StringComparison.OrdinalIgnoreCase) || openWindow_idle.FileName.EndsWith(".gif", StringComparison.OrdinalIgnoreCase)) { try { idle = new GBA.Bitmap(openWindow_idle.FileName, CurrentPalette); } catch (Exception ex) { Program.ShowError("Could not read bitmap for map sprite 'idle'.", ex); return; } if (idle.Width == 16 && idle.Height == 16 * 3) { size = 0x00; } else if (idle.Width == 16 && idle.Height == 32 * 3) { size = 0x01; } else if (idle.Width == 32 && idle.Height == 32 * 3) { size = 0x02; } else { Program.ShowError("Invalid IDLE Map sprite image file, size should be either 16x48, 16x96, or 32x96 pixels"); return; } } else { Program.ShowError("File chosen has invalid extension.\r\n" + openWindow_idle.FileName); return; } } else { return; } OpenFileDialog openWindow_move = new OpenFileDialog(); openWindow_move.RestoreDirectory = true; openWindow_move.Multiselect = false; openWindow_move.FilterIndex = 1; openWindow_move.Filter = "'MOVE' Map sprite image file (*.png, *.bmp, *.gif)|*.png;*.bmp;*.gif|" + "'MOVE' Map sprite image data (.move.chr)|*.chr|" + "All files (*.*)|*.*"; if (openWindow_move.ShowDialog() == DialogResult.OK) { if (openWindow_move.FileName.EndsWith(".png", StringComparison.OrdinalIgnoreCase) || openWindow_move.FileName.EndsWith(".bmp", StringComparison.OrdinalIgnoreCase) || openWindow_move.FileName.EndsWith(".gif", StringComparison.OrdinalIgnoreCase)) { try { move = new GBA.Bitmap(openWindow_move.FileName, CurrentPalette); } catch (Exception ex) { Program.ShowError("Could not read bitmap for map sprite 'move'.", ex); return; } if (move.Width != 32 && move.Height != 480) { Program.ShowError("Invalid MOVE Map sprite image file, size should be 32x480 pixels"); return; } } else if (openWindow_move.FileName.EndsWith(".chr", StringComparison.OrdinalIgnoreCase)) { // TODO return; } else { Program.ShowError("File chosen has invalid extension.\r\n" + openWindow_move.FileName); return; } } else { return; } GBA.Bitmap result = new GBA.Bitmap( MapSprite.WIDTH, MapSprite.HEIGHT); result.Colors = Core.ReadPalette(Core.CurrentROM.Address_MapSpritePalettes(), GBA.Palette.LENGTH * 8); result.SetPixels(delegate(int x, int y) { return((byte)move[x, y + 32 * 0]); }, new Rectangle(32, 0, 32, 32 * 4)); // MOVE side result.SetPixels(delegate(int x, int y) { return((byte)move[x, y + 32 * 4]); }, new Rectangle(64, 0, 32, 32 * 4)); // MOVE down result.SetPixels(delegate(int x, int y) { return((byte)move[x, y + 32 * 8]); }, new Rectangle(96, 0, 32, 32 * 4)); // MOVE up result.SetPixels(delegate(int x, int y) { return((byte)move[x, y + 32 * 12]); }, new Rectangle(128, 32, 32, 32 * 3)); // MOVE cursor-hover switch (size) { case 0x00: // IDLE 16x16 result.SetPixels(delegate(int x, int y) { return((byte)idle[x, y + 16 * 0]); }, new Rectangle(8, 32 * 1 + 16, 16, 16)); result.SetPixels(delegate(int x, int y) { return((byte)idle[x, y + 16 * 1]); }, new Rectangle(8, 32 * 2 + 16, 16, 16)); result.SetPixels(delegate(int x, int y) { return((byte)idle[x, y + 16 * 2]); }, new Rectangle(8, 32 * 3 + 16, 16, 16)); break; case 0x01: // IDLE 16x32 result.SetPixels(delegate(int x, int y) { return((byte)idle[x, y]); }, new Rectangle(8, 32, 16, 32 * 3)); break; case 0x02: // IDLE 32x32 result.SetPixels(delegate(int x, int y) { return((byte)idle[x, y]); }, new Rectangle(0, 32, 32, 32 * 3)); break; default: throw new Exception("Invalid map sprite size value recieved."); } SaveFileDialog saveWindow = new SaveFileDialog(); saveWindow.RestoreDirectory = true; saveWindow.OverwritePrompt = true; saveWindow.CreatePrompt = false; saveWindow.FilterIndex = 1; saveWindow.Filter = "Image file (*.png, *.bmp)|*.png;*.bmp|" + "All files (*.*)|*.*"; if (saveWindow.ShowDialog() == DialogResult.OK) { if (saveWindow.FileName.EndsWith(".png", StringComparison.OrdinalIgnoreCase) || saveWindow.FileName.EndsWith(".bmp", StringComparison.OrdinalIgnoreCase)) { try { Core.SaveImage(saveWindow.FileName.Remove(saveWindow.FileName.Length - 4), Tile.SIZE * MapSprite.W_TILES, Tile.SIZE * MapSprite.H_TILES, Palette.Split(CurrentPalette, 8), delegate(int x, int y) { return((byte)result[x, y]); }); } catch (Exception ex) { Program.ShowError("Could not save image.", ex); } return; } else { Program.ShowError("File chosen has invalid extension.\r\n" + saveWindow.FileName); return; } } }