private void importMDPaletteToolStripMenuItem_Click(object sender, EventArgs e) { using (OpenFileDialog a = new OpenFileDialog() { DefaultExt = "bin", Filter = "MD Palettes|*.bin", RestoreDirectory = true }) if (a.ShowDialog(this) == DialogResult.OK) { SonLVLColor[] colors = SonLVLColor.Load(a.FileName, EngineVersion.S1); for (int i = 0; i < colors.Length && selectedColor + i < palette.Entries.Length; i++) { palette.Entries[selectedColor + i] = colors[i].RGBColor; } palettePanel.Invalidate(); spriteImagePanel.Invalidate(); } }
private void importPaletteToolStripMenuItem_Click(object sender, EventArgs e) { using (OpenFileDialog a = new OpenFileDialog() { DefaultExt = "bin", Filter = "32X Palettes|*.bin|Image Files|*.bmp;*.png;*.jpg;*.gif", RestoreDirectory = true }) if (a.ShowDialog(this) == DialogResult.OK) { switch (Path.GetExtension(a.FileName)) { case ".bin": SonLVLColor[] colors = SonLVLColor.Load(a.FileName, EngineVersion.Chaotix); for (int i = 0; i < colors.Length && selectedColor + i < palette.Entries.Length; i++) { palette.Entries[selectedColor + i] = colors[i].RGBColor; } break; case ".bmp": case ".png": case ".jpg": case ".gif": using (Bitmap bmp = new Bitmap(a.FileName)) if ((bmp.PixelFormat & PixelFormat.Indexed) == PixelFormat.Indexed) { Color[] pal = bmp.Palette.Entries; for (int i = 0; i < pal.Length && selectedColor + i < palette.Entries.Length; i++) { palette.Entries[selectedColor + i] = pal[i]; } } break; } palettePanel.Invalidate(); spriteImagePanel.Invalidate(); } }
static void Main(string[] args) { LongOpt[] opts = new[] { new LongOpt("help", Argument.No, null, 'h'), new LongOpt("padding", Argument.Required, null, 'p'), new LongOpt("startpal", Argument.Required, null, 's'), new LongOpt("nullfirst", Argument.No, null, 'n'), new LongOpt("twoplayer", Argument.No, null, '2'), new LongOpt("format", Argument.Required, null, 'f'), new LongOpt("game", Argument.Required, null, 'g'), new LongOpt("artcmp", Argument.Required, null, 'c'), new LongOpt("lowplane", Argument.Required, null, 0), new LongOpt("highplane", Argument.Required, null, 0), new LongOpt("palette", Argument.Required, null, 0), new LongOpt("center", Argument.Required, null, 0), new LongOpt("artfile", Argument.Required, null, 0), new LongOpt("mapfile", Argument.Required, null, 0), new LongOpt("dplcfile", Argument.Required, null, 0), new LongOpt("palfile", Argument.Required, null, 0) }; if (args.Length == 0) { args = new string[] { "-h" } } ; Getopt getopt = new Getopt("SpritePlotter.NET", args, Getopt.digest(opts), opts); int padding = 2; byte startpal = 0; bool nullfirst = false; bool twoplayer = false; MappingsFormat mapfmt = MappingsFormat.Binary; EngineVersion mapgame = EngineVersion.Invalid; bool s3kp = false; CompressionType artcmp = CompressionType.Uncompressed; Bitmap lowplanefile = null; Bitmap highplanefile = null; Color[] palette = null; Bitmap centerfile = null; string artfile = null; string mapfile = null; string dplcfile = null; string palfile = null; int opt = getopt.getopt(); while (opt != -1) { switch (opt) { case 'h': Console.Write(Properties.Resources.HelpText); return; case 'p': padding = int.Parse(getopt.Optarg); break; case 's': startpal = byte.Parse(getopt.Optarg); break; case 'n': nullfirst = true; break; case '2': twoplayer = true; break; case 'f': mapfmt = (MappingsFormat)Enum.Parse(typeof(MappingsFormat), getopt.Optarg, true); break; case 'g': if (getopt.Optarg.Equals("s3kp", StringComparison.OrdinalIgnoreCase)) { mapgame = EngineVersion.S3K; s3kp = true; } else { mapgame = (EngineVersion)Enum.Parse(typeof(EngineVersion), getopt.Optarg, true); } break; case 'c': artcmp = (CompressionType)Enum.Parse(typeof(CompressionType), getopt.Optarg, true); break; case 0: switch (opts[getopt.Longind].Name) { case "lowplane": lowplanefile = new Bitmap(getopt.Optarg); if (palette == null && (lowplanefile.PixelFormat & PixelFormat.Indexed) == PixelFormat.Indexed) { palette = lowplanefile.Palette.Entries; } break; case "highplane": highplanefile = new Bitmap(getopt.Optarg); if (palette == null && (highplanefile.PixelFormat & PixelFormat.Indexed) == PixelFormat.Indexed) { palette = highplanefile.Palette.Entries; } break; case "palette": switch (System.IO.Path.GetExtension(getopt.Optarg)) { case ".bin": palette = SonLVLColor.Load(getopt.Optarg, EngineVersion.S2).Select(a => a.RGBColor).ToArray(); break; case ".bmp": case ".png": case ".jpg": case ".gif": using (Bitmap bmp = new Bitmap(getopt.Optarg)) { if ((bmp.PixelFormat & PixelFormat.Indexed) == PixelFormat.Indexed) { palette = bmp.Palette.Entries; } else { List <Color> pal = new List <Color>(); for (int y = 0; y < bmp.Height; y += 8) { for (int x = 0; x < bmp.Width; x += 8) { pal.Add(bmp.GetPixel(x, y)); } } palette = pal.ToArray(); } } break; } break; case "center": centerfile = new Bitmap(getopt.Optarg); break; case "artfile": artfile = getopt.Optarg; break; case "mapfile": mapfile = getopt.Optarg; break; case "dplcfile": dplcfile = getopt.Optarg; break; case "palfile": palfile = getopt.Optarg; break; } break; } opt = getopt.getopt(); } if (mapgame == EngineVersion.Invalid) { Console.Error.WriteLine("No game specified."); return; } if (lowplanefile == null && highplanefile == null) { Console.Error.WriteLine("No image file specified."); return; } if (palette == null) { Console.Error.WriteLine("No palette specified, and image(s) did not contain palette."); return; } if (artfile == null) { Console.Error.WriteLine("No output art file specified."); return; } if (mapfile == null) { Console.Error.WriteLine("No output mappings file specified."); return; } if (palette.Length > 64) { palette = palette.Take(64).ToArray(); // lazy } BitmapBits lowplane = null, highplane = null, combinedplanes = null; if (lowplanefile != null) { if ((lowplanefile.PixelFormat & PixelFormat.Indexed) == PixelFormat.Indexed) { lowplane = new BitmapBits(lowplanefile); } else { using (Bitmap bmp = lowplanefile.To32bpp()) lowplane = LoadBitmap32BppArgb(bmp, palette); } lowplanefile.Dispose(); if (highplanefile == null) { combinedplanes = lowplane; } } if (highplanefile != null) { if ((highplanefile.PixelFormat & PixelFormat.Indexed) == PixelFormat.Indexed) { highplane = new BitmapBits(highplanefile); } else { using (Bitmap bmp = highplanefile.To32bpp()) highplane = LoadBitmap32BppArgb(bmp, palette); } highplanefile.Dispose(); if (lowplanefile == null) { combinedplanes = highplane; } } if (combinedplanes == null) { combinedplanes = new BitmapBits(Math.Max(lowplane.Width, highplane.Width), Math.Max(lowplane.Height, highplane.Height)); combinedplanes.DrawBitmap(lowplane, 0, 0); combinedplanes.DrawBitmapComposited(highplane, 0, 0); } List <Point> centers = null; if (centerfile != null) { centers = new List <Point>(); BitmapBits cntr; if ((centerfile.PixelFormat & PixelFormat.Indexed) == PixelFormat.Indexed) { cntr = new BitmapBits(centerfile); } else { using (Bitmap bmp = centerfile.To32bpp()) cntr = LoadBitmap32BppArgb(bmp, Color.Black, Color.White); } centerfile.Dispose(); for (int y = 0; y < cntr.Height; y++) { for (int x = 0; x < cntr.Width; x++) { if (cntr[x, y] != 0) { centers.Add(new Point(x, y)); } } } } List <Rectangle> sprites = new List <Rectangle>(); for (int y = 0; y < combinedplanes.Height; y++) { for (int x = 0; x < combinedplanes.Width; x++) { if (combinedplanes[x, y] % 16 != 0) { Rectangle newrect = new Rectangle(x - padding, y - padding, (padding * 2) + 1, (padding * 2) + 1); for (int i = 0; i < sprites.Count; i++) { if (newrect.IntersectsWith(sprites[i])) { newrect = Rectangle.Union(newrect, sprites[i]); sprites.RemoveAt(i); i = -1; } } sprites.Add(newrect); } } } List <Rectangle> rows = new List <Rectangle>(); for (int i = 0; i < sprites.Count; i++) { Rectangle rect = sprites[i]; rect.Inflate(-padding, -padding); sprites[i] = rect; if (rows.Count > 0 && sprites[i].IntersectsWith(rows[rows.Count - 1])) { rows[rows.Count - 1] = Rectangle.Union(sprites[i], rows[rows.Count - 1]); } else { rows.Add(new Rectangle(0, sprites[i].Y, combinedplanes.Width, sprites[i].Height)); } } List <Rectangle> newsprites = new List <Rectangle>(sprites.Count); foreach (Rectangle rect in rows) { newsprites.AddRange(sprites.Where(a => a.IntersectsWith(rect)).OrderBy(a => a.X)); } sprites = newsprites; List <byte[]> tiles = new List <byte[]>(); NamedList <MappingsFrame> map = new NamedList <MappingsFrame>("Map_" + Path.GetFileNameWithoutExtension(mapfile), sprites.Count); NamedList <DPLCFrame> dplc = null; if (dplcfile != null) { dplc = new NamedList <DPLCFrame>("DPLC_" + Path.GetFileNameWithoutExtension(dplcfile), sprites.Count); } if (nullfirst) { map.Add(new MappingsFrame(map.Name + "_Null")); if (dplc != null) { dplc.Add(new DPLCFrame(dplc.Name + "_Null")); } } for (int i = 0; i < sprites.Count; i++) { Point center = new Point(sprites[i].Width / 2, sprites[i].Height / 2); if (centers != null) { foreach (Point item in centers) { if (sprites[i].Contains(item)) { center = new Point(item.X - sprites[i].Left, item.Y - sprites[i].Top); break; } } } MappingsFrame mapframe = new MappingsFrame(map.Name + "_" + i); map.Add(mapframe); DPLCFrame dplcframe = null; if (dplc != null) { dplcframe = new DPLCFrame(dplc.Name + "_" + i); dplc.Add(dplcframe); } if (lowplane != null) { SpriteToMap(sprites[i], center, lowplane, tiles, mapframe, dplcframe, startpal, false, twoplayer); } if (highplane != null) { SpriteToMap(sprites[i], center, highplane, tiles, mapframe, dplcframe, startpal, true, twoplayer); } } using (MemoryStream ms = new MemoryStream(tiles.Count * 32)) { using (BinaryWriter bw = new BinaryWriter(ms)) foreach (byte[] b in tiles) { bw.Write(b); } Compression.Compress(ms.ToArray(), artfile, artcmp); } if (mapfmt == MappingsFormat.Binary) { File.WriteAllBytes(mapfile, MappingsFrame.GetBytes(map, mapgame)); if (dplc != null) { File.WriteAllBytes(dplcfile, DPLCFrame.GetBytes(dplc, s3kp ? EngineVersion.S2 : mapgame)); } } else { MappingsFrame.ToASM(mapfile, map, mapgame, mapfmt == MappingsFormat.Macro); if (dplc != null) { DPLCFrame.ToASM(dplcfile, dplc, mapgame, mapfmt == MappingsFormat.Macro, s3kp); } } if (palfile != null) { using (FileStream fs = File.Create(palfile)) using (BinaryWriter bw = new BinaryWriter(fs)) foreach (Color c in palette) { bw.Write(ByteConverter.GetBytes(new SonLVLColor(c).MDColor)); } } }
public static void Init() { using (Bitmap tmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed)) Palette = tmp.Palette; SonLVLColor[] pal = SonLVLColor.Load(Properties.Resources.Palette, EngineVersion.S1); for (int i = 0; i < pal.Length; i++) { Palette.Entries[i] = pal[i].RGBColor; } Palette.Entries[0] = Color.Transparent; BitmapBits bmp = new BitmapBits(Properties.Resources.GFX); BitmapBits[] sprites = new BitmapBits[bmp.Width / 24]; for (int i = 0; i < sprites.Length; i++) { sprites[i] = bmp.GetSection(i * 24, 0, 24, 24); } bmp = new BitmapBits(Properties.Resources.Font); BitmapBits[] font = new BitmapBits[11]; for (int i = 0; i < 10; i++) { font[i] = bmp.GetSection(i * 8, 0, 8, 8); } font[10] = bmp.GetSection(10 * 8, 0, 16, 8); ObjectBmps[0] = new BitmapBits(24, 24); byte ind = 1; // walls for (int p = 0; p < 4; p++) { BitmapBits tmp = new BitmapBits(sprites[0]); ObjectBmps[ind++] = tmp; for (int i = 1; i < 9; i++) { BitmapBits t2 = new BitmapBits(tmp); t2.DrawBitmapComposited(font[i], 16, 16); ObjectBmps[ind++] = t2; } sprites[0].IncrementIndexes(16); } // misc for (int i = 1; i < 7; i++) { ObjectBmps[ind++] = sprites[i]; } // "R" sprites[7].IncrementIndexes(16); ObjectBmps[ind++] = sprites[7]; // red/white ObjectBmps[ind++] = sprites[8]; // diamonds for (int p = 0; p < 4; p++) { BitmapBits tmp = new BitmapBits(sprites[9]); ObjectBmps[ind++] = tmp; sprites[9].IncrementIndexes(16); } // unused blocks ind += 3; // "ZONE" blocks for (int i = 10; i < 16; i++) { ObjectBmps[ind++] = sprites[i]; } // ring sprites[16].IncrementIndexes(16); ObjectBmps[ind++] = sprites[16]; // blue/yellow/pink/green emerald for (int p = 0; p < 4; p++) { BitmapBits tmp = new BitmapBits(sprites[19]); ObjectBmps[ind++] = tmp; sprites[19].IncrementIndexes(16); } // red emerald ObjectBmps[ind++] = sprites[17]; // gray emerald ObjectBmps[ind++] = sprites[18]; // pass-through barrier ObjectBmps[ind++] = sprites[20]; ObjectBmps[0x4A] = new BitmapBits(sprites[20]); ObjectBmps[0x4A].DrawBitmapComposited(font[10], 4, 8); ObjectBmpsNoNum = new Dictionary <byte, BitmapBits>(ObjectBmps); for (int p = 0; p < 4; p++) { BitmapBits tmp = ObjectBmps[(byte)(p * 9 + 1)]; for (int i = 1; i < 9; i++) { ObjectBmpsNoNum[(byte)(p * 9 + 1 + i)] = tmp; } } StartPosBmp = new BitmapBits(Properties.Resources.StartPos); }