public void LoadPlayerPalettes(WorldRenderer wr, string playerName, Color color, bool replaceExisting) { var argb = (uint)Color.FromArgb(128, color).ToArgb(); var pal = new ImmutablePalette(Enumerable.Range(0, Palette.Size).Select(i => i == info.TransparentIndex ? 0 : argb)); wr.AddPalette(info.BaseName + playerName, pal, false, replaceExisting); }
public void LoadPalettes(WorldRenderer wr) { var basePalette = wr.Palette(info.BasePalette).Palette; var pal = new ImmutablePalette(basePalette, new IndexedColorRemap(basePalette, info.Index, info.ReplaceIndex)); wr.AddPalette(info.Name, pal, info.AllowModifiers); }
public void LoadPlayerPalettes(WorldRenderer wr, string playerName, HSLColor color, bool replaceExisting) { var remap = new PlayerColorRemap(info.RemapIndex, color, info.Ramp); var pal = new ImmutablePalette(wr.Palette(info.BasePalette).Palette, remap); wr.AddPalette(info.BaseName + playerName, pal, info.AllowModifiers, replaceExisting); }
void CreateNewTileset() { Show(); using (var formNew = new FormNew()) if (DialogResult.OK == formNew.ShowDialog()) { srcfile = formNew.ImageFile; size = formNew.TileSize; var bitmap = new Bitmap(srcfile); if (!formNew.PaletteFromImage) { var terrainPalette = new ImmutablePalette(formNew.PaletteFile, new int[0]); ColorPalette pal; using (var b = new Bitmap(1, 1, PixelFormat.Format8bppIndexed)) pal = b.Palette; for (var i = 0; i < 256; i++) { pal.Entries[i] = Color.FromArgb(terrainPalette.GetColor(i).ToArgb()); } bitmap.Palette = pal; } InitializeSurface(bitmap); } }
void IUtilityCommand.Run(Utility utility, string[] args) { // HACK: The engine code assumes that Game.modData is set. var modData = Game.ModData = utility.ModData; var palette = new ImmutablePalette(args[1], new int[0]); SequenceProvider sequences = null; var mapPackage = new Folder(".").OpenPackage(args[2], modData.ModFiles); if (mapPackage != null) { sequences = new Map(modData, mapPackage).Rules.Sequences; } else if (!modData.DefaultSequences.TryGetValue(args[2], out sequences)) { throw new InvalidOperationException("{0} is not a valid tileset or map path".F(args[2])); } sequences.Preload(); var count = 0; var sb = sequences.SpriteCache.SheetBuilder; foreach (var s in sb.AllSheets) { var max = s == sb.Current ? (int)sb.CurrentChannel + 1 : 4; for (var i = 0; i < max; i++) { s.AsBitmap((TextureChannel)ChannelMasks[i], palette).Save("{0}.png".F(count++)); } } Console.WriteLine("Saved [0..{0}].png", count - 1); }
public void LoadPlayerPalettes(WorldRenderer wr, string playerName, HSLColor color, bool replaceExisting) { var remap = new AlphaPaletteRemap(info.Alpha, info.Premultiply); var pal = new ImmutablePalette(wr.Palette(info.BasePalette + playerName).Palette, remap); wr.AddPalette(info.BaseName + playerName, pal, info.AllowModifiers, replaceExisting); }
public void TestMethod2() { var modSearchPaths = new string[] { "C:\\work\\games\\OpenRAModMaker\\OpenRA\\mods" }; var explicitModPaths = new string[] { "ra" }; Log.AddChannel("debug", "c:\\temp\\openra.log"); Log.AddChannel("perf", "c:\\temp\\openra-perf.log"); var currentDirectory = "C:\\work\\games\\OpenRAModMaker\\OpenRA"; Environment.CurrentDirectory = currentDirectory; Directory.SetCurrentDirectory(currentDirectory); Game.Settings = new Settings(Platform.ResolvePath(Path.Combine(Platform.SupportDirPrefix, "settings.yaml")), new Arguments { }); var mods = new InstalledMods(modSearchPaths, explicitModPaths); var raMod = mods["ra"]; var modData = new ModData(raMod, mods, true); var sequences = modData.DefaultSequences; var snowSeqProv = sequences["SNOW"]; var harv = snowSeqProv.GetSequence("harv", "icon"); int[] ChannelMasks = { 2, 1, 0, 3 }; var palette = new ImmutablePalette("C:\\work\\games\\OpenRAModMaker\\OpenRA\\mods\\cnc\\bits\\snow.pal", new int[0]); //png.Save($"C:\\temp\\harv\\harv-0.png"); for (int i = 0; i < 50; i++) { var sprite = harv.GetSprite(i); var sheet = sprite.Sheet; sheet.AsPng((TextureChannel)ChannelMasks[2], palette).Save($"C:\\temp\\harv\\harv-{i}.png"); } }
void LoadPalette(ImmutablePalette cpspalette, string customname) { try { pr = Game.worldRenderer.Palette(customname); return; } catch (Exception) { pr = null; } if (pr == null) { Game.worldRenderer.AddPalette(customname, cpspalette, false, false); pr = Game.worldRenderer.Palette(customname); } //palette = cpspalette; //hardwarePalette = new HardwarePalette(); //hardwarePalette.AddPalette(customname, palette, false); //hardwarePalette.Initialize(); //Game.Renderer.SetPalette(hardwarePalette); //var pal = hardwarePalette.GetPalette(customname); //pr = new PaletteReference(customname+"ref", hardwarePalette.GetPaletteIndex(customname), pal, hardwarePalette); }
public void ReadEmbeddedPalette(Stream s) { paldataByte = StreamExts.ReadBytes(s, 768); Stream stream = new MemoryStream(paldataByte); CpsPalette = new ImmutablePalette(stream, new int[] { }); }
public void Run(ModData modData, string[] args) { var remap = new Dictionary <int, int>(); /* the first 4 entries are fixed */ for (var i = 0; i < 4; i++) { remap[i] = i; } var srcMod = args[1].Split(':')[0]; Game.ModData = new ModData(srcMod); GlobalFileSystem.LoadFromManifest(Game.ModData.Manifest); var srcRules = Game.ModData.RulesetCache.Load(); var srcPaletteInfo = srcRules.Actors["player"].Traits.Get <PlayerColorPaletteInfo>(); var srcRemapIndex = srcPaletteInfo.RemapIndex; var destMod = args[2].Split(':')[0]; Game.ModData = new ModData(destMod); GlobalFileSystem.LoadFromManifest(Game.ModData.Manifest); var destRules = Game.ModData.RulesetCache.Load(); var destPaletteInfo = destRules.Actors["player"].Traits.Get <PlayerColorPaletteInfo>(); var destRemapIndex = destPaletteInfo.RemapIndex; var shadowIndex = new int[] { }; // the remap range is always 16 entries, but their location and order changes for (var i = 0; i < 16; i++) { remap[PlayerColorRemap.GetRemapIndex(srcRemapIndex, i)] = PlayerColorRemap.GetRemapIndex(destRemapIndex, i); } // map everything else to the best match based on channel-wise distance var srcPalette = new ImmutablePalette(args[1].Split(':')[1], shadowIndex); var destPalette = new ImmutablePalette(args[2].Split(':')[1], shadowIndex); for (var i = 0; i < Palette.Size; i++) { if (!remap.ContainsKey(i)) { remap[i] = Enumerable.Range(0, Palette.Size) .Where(a => !remap.ContainsValue(a)) .MinBy(a => ColorDistance(destPalette[a], srcPalette[i])); } } using (var s = File.OpenRead(args[3])) using (var destStream = File.Create(args[4])) { var srcImage = new ShpTDSprite(s); ShpTDSprite.Write(destStream, srcImage.Size, srcImage.Frames.Select(im => im.Data.Select(px => (byte)remap[px]).ToArray())); } }
void IUtilityCommand.Run(Utility utility, string[] args) { var remap = new Dictionary <int, int>(); /* the first 4 entries are fixed */ for (var i = 0; i < 4; i++) { remap[i] = i; } var srcMod = args[1].Split(':')[0]; var srcModData = new ModData(utility.Mods[srcMod], utility.Mods); Game.ModData = srcModData; var srcPaletteInfo = srcModData.DefaultRules.Actors[SystemActors.Player].TraitInfo <PlayerColorPaletteInfo>(); var srcRemapIndex = srcPaletteInfo.RemapIndex; var destMod = args[2].Split(':')[0]; var destModData = new ModData(utility.Mods[destMod], utility.Mods); Game.ModData = destModData; var destPaletteInfo = destModData.DefaultRules.Actors[SystemActors.Player].TraitInfo <PlayerColorPaletteInfo>(); var destRemapIndex = destPaletteInfo.RemapIndex; var shadowIndex = new int[] { }; // the remap range is always 16 entries, but their location and order changes for (var i = 0; i < 16; i++) { remap[srcRemapIndex[i]] = destRemapIndex[i]; } // map everything else to the best match based on channel-wise distance var srcPalette = new ImmutablePalette(args[1].Split(':')[1], new[] { 0 }, shadowIndex); var destPalette = new ImmutablePalette(args[2].Split(':')[1], new[] { 0 }, shadowIndex); for (var i = 0; i < Palette.Size; i++) { if (!remap.ContainsKey(i)) { remap[i] = Enumerable.Range(0, Palette.Size) .Where(a => !remap.ContainsValue(a)) .MinBy(a => ColorDistance(destPalette[a], srcPalette[i])); } } using (var s = File.OpenRead(args[3])) using (var destStream = File.Create(args[4])) { var srcImage = new ShpTDSprite(s); ShpTDSprite.Write(destStream, srcImage.Size, srcImage.Frames.Select(im => im.Data.Select(px => (byte)remap[px]).ToArray())); } }
void LoadPalette(ImmutablePalette cpspalette, string customname) { Game.worldRenderer.AddPalette("dune2widget", cpspalette, false, false); pr = Game.worldRenderer.Palette("dune2widget"); //palette = cpspalette; //hardwarePalette = new HardwarePalette(); //hardwarePalette.AddPalette(customname, palette, false); //hardwarePalette.Initialize(); //Game.Renderer.SetPalette(hardwarePalette); //var pal = hardwarePalette.GetPalette(customname); //pr = new PaletteReference(customname + "ref", hardwarePalette.GetPaletteIndex(customname), pal, hardwarePalette); }
public override void Init(ModData modData, Dictionary <string, string> info) { base.Init(modData, info); // Avoid standard loading mechanisms so we // can display the loadscreen as early as possible r = Game.Renderer; if (r == null) { return; } if (info.ContainsKey("Text")) { messages = info["Text"].Split(','); } if (info.ContainsKey("Palette")) { using (var stream = modData.DefaultFileSystem.Open(info["Palette"])) { palette = new ImmutablePalette(stream, new int[] { }); } hardwarePalette = new HardwarePalette(); hardwarePalette.AddPalette("loadscreen", palette, false); hardwarePalette.Initialize(); r.SetPalette(hardwarePalette); } if (info.ContainsKey("Image")) { using (var stream = modData.DefaultFileSystem.Open(info["Image"])) { CpsD2Loader loader = new CpsD2Loader(); if (!loader.TryParseSprite(stream, out frames)) { return; } } if (frames.Length == 0) { return; } sheetBuilder = new SheetBuilder(SheetType.Indexed, 512); logo = sheetBuilder.Add(frames[0]); logoPos = new float2((r.Resolution.Width - logo.Size.X) / 2, (r.Resolution.Height - logo.Size.Y) / 2); } }
void LoadPalette() { using (var stream = Game.ModData.DefaultFileSystem.Open("IBM.PAL")) palette = new ImmutablePalette(stream, new int[] { }); hardwarePalette = new HardwarePalette(); hardwarePalette.AddPalette("chrome", palette, false); hardwarePalette.Initialize(); Game.Renderer.SetPalette(hardwarePalette); var pal = hardwarePalette.GetPalette("chrome"); pr = new PaletteReference("chromeref", hardwarePalette.GetPaletteIndex("chrome"), pal, hardwarePalette); }
public void LoadPlayerPalettes(WorldRenderer wr, string playerName, Color color, bool replaceExisting) { var basePalette = wr.Palette(info.BasePalette).Palette; ImmutablePalette pal; if (info.PlayerIndex.TryGetValue(playerName, out var remap)) { pal = new ImmutablePalette(basePalette, new IndexedColorRemap(basePalette, info.RemapIndex, remap)); } else { pal = new ImmutablePalette(basePalette); } wr.AddPalette(info.BaseName + playerName, pal, info.AllowModifiers, replaceExisting); }
public void TestMethod3() { var modSearchPaths = new string[] { "C:\\work\\games\\OpenRAModMaker\\OpenRA\\mods" }; var explicitModPaths = new string[] { "ra" }; Log.AddChannel("debug", "c:\\temp\\openra.log"); Log.AddChannel("perf", "c:\\temp\\openra-perf.log"); var currentDirectory = "C:\\work\\games\\OpenRAModMaker\\OpenRA"; Environment.CurrentDirectory = currentDirectory; Directory.SetCurrentDirectory(currentDirectory); var palette = new ImmutablePalette("C:\\work\\games\\OpenRAModMaker\\OpenRA\\mods\\cnc\\bits\\snow.pal", new int[0]); int[] ChannelMasks = { 2, 1, 0, 3 }; Game.Settings = new Settings(Platform.ResolvePath(Path.Combine(Platform.SupportDirPrefix, "settings.yaml")), new Arguments { }); var mods = new InstalledMods(modSearchPaths, explicitModPaths); var raMod = mods["ra"]; var modData = new ModData(raMod, mods, true); var defaultSequences = modData.DefaultSequences; var sequences = defaultSequences["SNOW"]; var harv = sequences.GetSequence("harv", "harvest"); sequences.Preload(); for (int i = 0; i < harv.Length; i++) { var sprite = harv.GetSprite(i); byte[] spriteBytes = new byte[sprite.Bounds.Width * sprite.Bounds.Height]; GetSpriteData(sprite, spriteBytes); var bitmap = ToBitmap(spriteBytes, sprite.Bounds.Width, sprite.Bounds.Height, palette); bitmap.Save("c:\\temp\\harv\\to-bmp.bmp"); //var png = new Png(pngBytes, sprite.Bounds.Width, sprite.Bounds.Height); //var png = ToPng(pngBytes, sprite.Bounds.Width, sprite.Bounds.Height); //var png = ToPng(pngBytes, sprite.Bounds.Width, sprite.Bounds.Height, sprite.Channel, palette); //png.Save($"c:\\temp\\harv\\from-raw-bytes-{i}.png"); //Assert.IsNotNull(png); } }
void CreateNewTileset() { this.Show(); using (var formNew = new FormNew()) if (DialogResult.OK == formNew.ShowDialog()) { srcfile = formNew.ImageFile; this.size = formNew.TileSize; var bitmap = new Bitmap(srcfile); if (!formNew.PaletteFromImage) { var terrainPalette = new ImmutablePalette(formNew.PaletteFile, new int[0]); bitmap.Palette = terrainPalette.AsSystemPalette(); } InitializeSurface(bitmap); } }
public void CreateNewTileset() { this.Show(); using (var formNew = new FormNew { }) if (DialogResult.OK == formNew.ShowDialog()) { PaletteFromImage = formNew.PaletteFromImage; PaletteFile = formNew.PaletteFile; ImageFile = formNew.ImageFile; TileSize = formNew.TileSize; srcfile = ImageFile; this.size = TileSize; surface1.TileSize = TileSize; Bitmap rbitmap; using (var fbitmap = new Bitmap(ImageFile)) rbitmap = fbitmap.Clone(new Rectangle(0, 0, fbitmap.Width, fbitmap.Height), fbitmap.PixelFormat); int[] shadowIndex = { }; if (!PaletteFromImage) { TerrainPalette = new ImmutablePalette(PaletteFile, shadowIndex); rbitmap.Palette = TerrainPalette.AsSystemPalette(); } surface1.Image = (Bitmap)rbitmap; surface1.TilesPerRow = surface1.Image.Size.Width / surface1.TileSize; surface1.Image.SetResolution(96, 96); // people keep being noobs about DPI, and GDI+ cares. surface1.TerrainTypes = new int[surface1.Image.Width / size, surface1.Image.Height / size]; /* all passable by default */ surface1.Templates = new List <Template>(); surface1.Size = surface1.Image.Size; surface1.Enabled = true; Load(); } }
public static void ConvertSpriteToPng(string[] args) { var src = args[1]; var shadowIndex = new int[] { }; if (args.Contains("--noshadow")) { Array.Resize(ref shadowIndex, shadowIndex.Length + 3); shadowIndex[shadowIndex.Length - 1] = 1; shadowIndex[shadowIndex.Length - 2] = 3; shadowIndex[shadowIndex.Length - 3] = 4; } var palette = new ImmutablePalette(args[2], shadowIndex); ISpriteSource source; using (var stream = File.OpenRead(src)) source = SpriteSource.LoadSpriteSource(stream, src); // The r8 padding requires external information that we can't access here. var usePadding = !(args.Contains("--nopadding") || source is R8Reader); var count = 0; var prefix = Path.GetFileNameWithoutExtension(src); foreach (var frame in source.Frames) { var frameSize = usePadding ? frame.FrameSize : frame.Size; var offset = usePadding ? (frame.Offset - 0.5f * new float2(frame.Size - frame.FrameSize)).ToInt2() : int2.Zero; // shp(ts) may define empty frames if (frameSize.Width == 0 && frameSize.Height == 0) { count++; continue; } using (var bitmap = new Bitmap(frameSize.Width, frameSize.Height, PixelFormat.Format8bppIndexed)) { bitmap.Palette = palette.AsSystemPalette(); var data = bitmap.LockBits(new Rectangle(0, 0, frameSize.Width, frameSize.Height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); // Clear the frame if (usePadding) { var clearRow = new byte[data.Stride]; for (var i = 0; i < frameSize.Height; i++) { Marshal.Copy(clearRow, 0, new IntPtr(data.Scan0.ToInt64() + i * data.Stride), data.Stride); } } for (var i = 0; i < frame.Size.Height; i++) { var destIndex = new IntPtr(data.Scan0.ToInt64() + (i + offset.Y) * data.Stride + offset.X); Marshal.Copy(frame.Data, i * frame.Size.Width, destIndex, frame.Size.Width); } bitmap.UnlockBits(data); var filename = "{0}-{1:D4}.png".F(prefix, count++); bitmap.Save(filename); } } Console.WriteLine("Saved {0}-[0..{1}].png", prefix, count - 1); }
// this code is insanely stupid, and mostly my fault -- chrisf void PrepareMapResources(ModData modData, Map map) { Program.Rules = map.Rules; tileset = Program.Rules.TileSets[map.Tileset]; tilesetRenderer = new TileSetRenderer(tileset, modData.Manifest.TileSize); var shadowIndex = new int[] { 3, 4 }; var palette = new ImmutablePalette(GlobalFileSystem.Open(tileset.Palette), shadowIndex); // required for desert terrain in RA var playerPalette = tileset.PlayerPalette ?? tileset.Palette; var shadowedPalette = new ImmutablePalette(GlobalFileSystem.Open(playerPalette), shadowIndex); surface1.Bind(map, tileset, tilesetRenderer, palette, shadowedPalette); // construct the palette of tiles var palettes = new[] { tilePalette, actorPalette, resourcePalette }; foreach (var p in palettes) { p.Visible = false; p.SuspendLayout(); } var templateOrder = tileset.EditorTemplateOrder ?? new string[] { }; foreach (var tc in tileset.Templates.GroupBy(t => t.Value.Category).OrderBy(t => templateOrder.IndexOf(t.Key))) { var category = tc.Key ?? "(Uncategorized)"; var categoryHeader = new Label { BackColor = SystemColors.Highlight, ForeColor = SystemColors.HighlightText, Text = category, AutoSize = false, Height = 24, TextAlign = ContentAlignment.MiddleLeft, Width = tilePalette.ClientSize.Width, }; // hook this manually, anchoring inside FlowLayoutPanel is flaky. tilePalette.Resize += (_, e) => categoryHeader.Width = tilePalette.ClientSize.Width; if (tilePalette.Controls.Count > 0) { tilePalette.SetFlowBreak( tilePalette.Controls[tilePalette.Controls.Count - 1], true); } tilePalette.Controls.Add(categoryHeader); foreach (var t in tc) { try { var bitmap = tilesetRenderer.RenderTemplate((ushort)t.Key, palette); var ibox = new PictureBox { Image = bitmap, Width = bitmap.Width / 2, Height = bitmap.Height / 2, SizeMode = PictureBoxSizeMode.StretchImage }; var brushTemplate = new BrushTemplate { Bitmap = bitmap, N = t.Key }; ibox.Click += (_, e) => surface1.SetTool(new BrushTool(brushTemplate)); var template = t.Value; tilePalette.Controls.Add(ibox); tt.SetToolTip(ibox, "{1}:{0} ({2}x{3})".F(template.Images[0], template.Id, template.Size.X, template.Size.Y)); } catch { } } } var actorTemplates = new List <ActorTemplate>(); foreach (var a in Program.Rules.Actors.Keys) { try { var info = Program.Rules.Actors[a]; if (!info.Traits.Contains <ILegacyEditorRenderInfo>()) { continue; } var etf = info.Traits.GetOrDefault <EditorTilesetFilterInfo>(); if (etf != null && etf.ExcludeTilesets != null && etf.ExcludeTilesets.Contains(tileset.Id)) { continue; } if (etf != null && etf.RequireTilesets != null && !etf.RequireTilesets.Contains(tileset.Id)) { continue; } var templatePalette = shadowedPalette; var rsi = info.Traits.GetOrDefault <ILegacyEditorRenderInfo>(); // exception for desert buildings if (rsi != null && rsi.EditorPalette != null && rsi.EditorPalette.Contains("terrain")) { templatePalette = palette; } var race = Program.Rules.Actors["world"].Traits.WithInterface <CountryInfo>().First().Race; var sequenceProvider = Program.Rules.Sequences[tileset.Id]; var template = RenderUtils.RenderActor(info, sequenceProvider, tileset, templatePalette, race); var ibox = new PictureBox { Image = template.Bitmap, Width = 32, Height = 32, SizeMode = PictureBoxSizeMode.Zoom, BorderStyle = BorderStyle.FixedSingle }; ibox.Click += (_, e) => surface1.SetTool(new ActorTool(template)); actorPalette.Controls.Add(ibox); tt.SetToolTip(ibox, "{0}".F(info.Name)); actorTemplates.Add(template); } catch { } } surface1.BindActorTemplates(actorTemplates); var resourceTemplates = new List <ResourceTemplate>(); foreach (var a in Program.Rules.Actors["world"].Traits.WithInterface <ResourceTypeInfo>()) { try { var template = RenderUtils.RenderResourceType(a, tileset, shadowedPalette); var ibox = new PictureBox { Image = template.Bitmap, Width = 32, Height = 32, SizeMode = PictureBoxSizeMode.Zoom, BorderStyle = BorderStyle.FixedSingle }; ibox.Click += (_, e) => surface1.SetTool(new ResourceTool(template)); resourcePalette.Controls.Add(ibox); tt.SetToolTip(ibox, "{0}:{1}cr".F(template.Info.Name, template.Info.ValuePerUnit)); resourceTemplates.Add(template); } catch { } } surface1.BindResourceTemplates(resourceTemplates); foreach (var p in palettes) { p.Visible = true; p.ResumeLayout(); } miniMapBox.Image = Minimap.RenderMapPreview(tileset, surface1.Map, true); propertiesToolStripMenuItem.Enabled = true; toolStripMenuItemProperties.Enabled = true; resizeToolStripMenuItem.Enabled = true; toolStripMenuItemResize.Enabled = true; saveToolStripMenuItem.Enabled = true; toolStripMenuItemSave.Enabled = true; saveAsToolStripMenuItem.Enabled = true; miniMapToPng.Enabled = true; PopulateActorOwnerChooser(); }
void IUtilityCommand.Run(Utility utility, string[] args) { // HACK: The engine code assumes that Game.modData is set. var modData = Game.ModData = utility.ModData; var src = args[1]; var shadowIndex = Array.Empty <int>(); if (args.Contains("--noshadow")) { Array.Resize(ref shadowIndex, shadowIndex.Length + 3); shadowIndex[shadowIndex.Length - 1] = 1; shadowIndex[shadowIndex.Length - 2] = 3; shadowIndex[shadowIndex.Length - 3] = 4; } var palette = new ImmutablePalette(args[2], new[] { 0 }, shadowIndex); var palColors = new Color[Palette.Size]; for (var i = 0; i < Palette.Size; i++) { palColors[i] = palette.GetColor(i); } var frames = FrameLoader.GetFrames(File.OpenRead(src), modData.SpriteLoaders, src, out _); var usePadding = !args.Contains("--nopadding"); var count = 0; var prefix = Path.GetFileNameWithoutExtension(src); foreach (var frame in frames) { var frameSize = usePadding && !frame.DisableExportPadding ? frame.FrameSize : frame.Size; var offset = usePadding && !frame.DisableExportPadding ? (frame.Offset - 0.5f * new float2(frame.Size - frame.FrameSize)).ToInt2() : int2.Zero; // shp(ts) may define empty frames if (frameSize.Width == 0 && frameSize.Height == 0) { count++; continue; } // TODO: expand frame with zero padding var pngData = frame.Data; if (frameSize != frame.Size) { pngData = new byte[frameSize.Width * frameSize.Height]; for (var i = 0; i < frame.Size.Height; i++) { Buffer.BlockCopy(frame.Data, i * frame.Size.Width, pngData, (i + offset.Y) * frameSize.Width + offset.X, frame.Size.Width); } } var png = new Png(pngData, SpriteFrameType.Indexed8, frameSize.Width, frameSize.Height, palColors); png.Save($"{prefix}-{(count++):D4}.png"); } Console.WriteLine("Saved {0}-[0..{1}].png", prefix, count - 1); }
void IUtilityCommand.Run(Utility utility, string[] args) { // HACK: The engine code assumes that Game.modData is set. var modData = Game.ModData = utility.ModData; var src = args[1]; var shadowIndex = new int[] { }; if (args.Contains("--noshadow")) { Array.Resize(ref shadowIndex, shadowIndex.Length + 3); shadowIndex[shadowIndex.Length - 1] = 1; shadowIndex[shadowIndex.Length - 2] = 3; shadowIndex[shadowIndex.Length - 3] = 4; } var palette = new ImmutablePalette(args[2], shadowIndex); var frames = FrameLoader.GetFrames(File.OpenRead(src), modData.SpriteLoaders); var usePadding = !args.Contains("--nopadding"); var count = 0; var prefix = Path.GetFileNameWithoutExtension(src); foreach (var frame in frames) { var frameSize = usePadding && !frame.DisableExportPadding ? frame.FrameSize : frame.Size; var offset = usePadding && !frame.DisableExportPadding ? (frame.Offset - 0.5f * new float2(frame.Size - frame.FrameSize)).ToInt2() : int2.Zero; // shp(ts) may define empty frames if (frameSize.Width == 0 && frameSize.Height == 0) { count++; continue; } using (var bitmap = new Bitmap(frameSize.Width, frameSize.Height, PixelFormat.Format8bppIndexed)) { bitmap.Palette = palette.AsSystemPalette(); var data = bitmap.LockBits(new Rectangle(0, 0, frameSize.Width, frameSize.Height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); // Clear the frame if (usePadding && !frame.DisableExportPadding) { var clearRow = new byte[data.Stride]; for (var i = 0; i < frameSize.Height; i++) { Marshal.Copy(clearRow, 0, new IntPtr(data.Scan0.ToInt64() + i * data.Stride), data.Stride); } } for (var i = 0; i < frame.Size.Height; i++) { var destIndex = new IntPtr(data.Scan0.ToInt64() + (i + offset.Y) * data.Stride + offset.X); Marshal.Copy(frame.Data, i * frame.Size.Width, destIndex, frame.Size.Width); } bitmap.UnlockBits(data); var filename = "{0}-{1:D4}.png".F(prefix, count++); bitmap.Save(filename); } } Console.WriteLine("Saved {0}-[0..{1}].png", prefix, count - 1); }
public override void Init(ModData modData, Dictionary <string, string> info) { base.Init(modData, info); this.modData = modData; this.info = info; /* * Unpack files needed, because in some PAK files, some VOC files can have prefix 'Z' * Unpacking files will unpack such files and rename. so no modifications in yaml needed. * LoadScreen.Init, possibly not the best place to do this, but need to do that early, before * data will be used. and do this in LoadScreen.Init just works fine. */ if (D2UnpackContent.UnpackFiles(modData, info) > 0) { // Some files unpacked. need to reload mod packages modData.ModFiles.LoadFromManifest(modData.Manifest); } /* * Like for unpack files, OpenRA engine do not have proper place for import maps. * And can't import in LoadScreen.Init, because engine not ready. * but Game.OnShellmapLoaded just works. */ Game.OnShellmapLoaded += ImportOriginalMaps; // Avoid standard loading mechanisms so we // can display the loadscreen as early as possible r = Game.Renderer; if (r == null) { return; } if (info.ContainsKey("Text")) { messages = info["Text"].Split(','); } if (info.ContainsKey("Palette")) { using (var stream = modData.DefaultFileSystem.Open(info["Palette"])) palette = new ImmutablePalette(stream, new int[] { }); hardwarePalette = new HardwarePalette(); hardwarePalette.AddPalette("loadscreen", palette, false); hardwarePalette.Initialize(); r.SetPalette(hardwarePalette); var pal = hardwarePalette.GetPalette("loadscreen"); pr = new PaletteReference("loadscreenref", hardwarePalette.GetPaletteIndex("loadscreen"), pal, hardwarePalette); } if (info.ContainsKey("Image")) { using (var stream = modData.DefaultFileSystem.Open(info["Image"])) { CpsD2Loader loader = new CpsD2Loader(); TypeDictionary metadata; if (!loader.TryParseSprite(stream, out frames, out metadata)) { return; } } if (frames.Length == 0) { return; } sheetBuilder = new SheetBuilder(SheetType.Indexed, 512); logo = sheetBuilder.Add(frames[0]); logoPos = new float2((r.Resolution.Width - logo.Size.X) / 2, (r.Resolution.Height - logo.Size.Y) / 2); } }
public bool TryParseSpritePlusPalette(Stream s, out ISpriteFrame[] frames, out TypeDictionary metadata, out ImmutablePalette Palette) { metadata = null; if (!IsCpsD2(s)) { Palette = null; frames = null; return(false); } Palette = CpsPalette; s.Position = 0; frames = ParseFrames(s); return(true); }