diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 5d1a147e5a..cc11db4350 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -437,7 +437,7 @@ - + diff --git a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs index aadc21c521..a2823f9405 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs @@ -102,22 +102,25 @@ namespace OpenRA.Mods.RA.Widgets.Logic { var ExtractGameFiles = new string[][] { - new string[] {"--extract", WidgetUtils.ActiveModId(), palette}, - new string[] {"--extract", WidgetUtils.ActiveModId(), "{0}.shp".F(spriteImage.Image)}, + new string[] {"--extract", WidgetUtils.ActiveModId(), palette, "--userdir"}, + new string[] {"--extract", WidgetUtils.ActiveModId(), "{0}.shp".F(spriteImage.Image), "--userdir"}, }; var ExportToPng = new string[][] { - new string[] {"--png", "{0}.shp".F(spriteImage.Image), palette}, + new string[] {"--png", Platform.SupportDir+"{0}.shp".F(spriteImage.Image), Platform.SupportDir+palette}, }; + var ImportFromPng = new string[][] { }; + var args = new WidgetArgs() { { "ExtractGameFiles", ExtractGameFiles }, - { "ExportToPng", ExportToPng } + { "ExportToPng", ExportToPng }, + { "ImportFromPng", ImportFromPng} }; - Ui.OpenWindow("EXTRACT_ASSETS_PANEL", args); + Ui.OpenWindow("CONVERT_ASSETS_PANEL", args); }; panel.Get("EXTRACT_BUTTON").OnClick = () => @@ -125,24 +128,50 @@ namespace OpenRA.Mods.RA.Widgets.Logic var ExtractGameFilesList = new List(); var ExportToPngList = new List(); - ExtractGameFilesList.Add(new string[] { "--extract", WidgetUtils.ActiveModId(), palette} ); + ExtractGameFilesList.Add(new string[] { "--extract", WidgetUtils.ActiveModId(), palette, "--userdir"} ); foreach (var shp in AvailableShps) { - ExtractGameFilesList.Add(new string[] { "--extract", WidgetUtils.ActiveModId(), shp } ); - ExportToPngList.Add(new string[] { "--png", shp, palette } ); + ExtractGameFilesList.Add(new string[] { "--extract", WidgetUtils.ActiveModId(), shp, "--userdir" } ); + ExportToPngList.Add(new string[] { "--png", Platform.SupportDir+shp, Platform.SupportDir+palette } ); + Console.WriteLine(Platform.SupportDir+shp); } var ExtractGameFiles = ExtractGameFilesList.ToArray(); var ExportToPng = ExportToPngList.ToArray(); + var ImportFromPng = new string[][] { }; var args = new WidgetArgs() { { "ExtractGameFiles", ExtractGameFiles }, - { "ExportToPng", ExportToPng } + { "ExportToPng", ExportToPng }, + { "ImportFromPng", ImportFromPng} }; - Ui.OpenWindow("EXTRACT_ASSETS_PANEL", args); + Ui.OpenWindow("CONVERT_ASSETS_PANEL", args); + }; + + + panel.Get("IMPORT_BUTTON").OnClick = () => + { + var imageSizeInput = panel.Get("IMAGE_SIZE_INPUT"); + var imageFilename = panel.Get("IMAGE_FILENAME_INPUT"); + + var ExtractGameFiles = new string[][] { }; + var ExportToPng = new string[][] { }; + var ImportFromPng = new string[][] + { + new string[] {"--shp", Platform.SupportDir+imageFilename.Text, imageSizeInput.Text}, + }; + + var args = new WidgetArgs() + { + { "ExtractGameFiles", ExtractGameFiles }, + { "ExportToPng", ExportToPng }, + { "ImportFromPng", ImportFromPng} + }; + + Ui.OpenWindow("CONVERT_ASSETS_PANEL", args); }; panel.Get("CLOSE_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); }; @@ -210,7 +239,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic foreach (var shp in shps) { AddAsset(assetList, shp, template); - AvailableShps.Add(shp); + AvailableShps.Add(Path.GetFileName(shp)); } } } diff --git a/OpenRA.Mods.RA/Widgets/Logic/ExtractGameFilesLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ConvertGameFilesLogic.cs similarity index 73% rename from OpenRA.Mods.RA/Widgets/Logic/ExtractGameFilesLogic.cs rename to OpenRA.Mods.RA/Widgets/Logic/ConvertGameFilesLogic.cs index 0acdb3293d..8c1f537a9d 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/ExtractGameFilesLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/ConvertGameFilesLogic.cs @@ -20,7 +20,7 @@ using OpenRA.Utility; namespace OpenRA.Mods.RA.Widgets.Logic { - public class ExtractGameFilesLogic + public class ConvertGameFilesLogic { Widget panel; ProgressBarWidget progressBar; @@ -28,12 +28,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic ButtonWidget retryButton, backButton; Widget extractingContainer; - string[][] ExtractGameFiles, ExportToPng; + string[][] ExtractGameFiles, ExportToPng, ImportFromPng; [ObjectCreator.UseCtor] - public ExtractGameFilesLogic(Widget widget, string[][] ExtractGameFiles, string[][] ExportToPng) + public ConvertGameFilesLogic(Widget widget, string[][] ExtractGameFiles, string[][] ExportToPng, string[][] ImportFromPng) { - panel = widget.Get("EXTRACT_ASSETS_PANEL"); + panel = widget.Get("CONVERT_ASSETS_PANEL"); progressBar = panel.Get("PROGRESS_BAR"); statusLabel = panel.Get("STATUS_LABEL"); @@ -47,6 +47,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic this.ExtractGameFiles = ExtractGameFiles; this.ExportToPng = ExportToPng; + this.ImportFromPng = ImportFromPng; Extract(); } @@ -78,21 +79,33 @@ namespace OpenRA.Mods.RA.Widgets.Logic for (int i = 0; i < ExportToPng.Length; i++) { progressBar.Percentage = i*100/ExportToPng.Count(); - statusLabel.GetText = () => "Converting..."; + statusLabel.GetText = () => "Exporting SHP to PNG..."; Utility.Command.ConvertShpToPng(ExportToPng[i]); } + for (int i = 0; i < ImportFromPng.Length; i++) + { + progressBar.Percentage = i*100/ImportFromPng.Count(); + statusLabel.GetText = () => "Converting PNG to SHP..."; + Utility.Command.ConvertPngToShp(ImportFromPng[i]); + } + Game.RunAfterTick(() => { progressBar.Percentage = 100; - statusLabel.GetText = () => "Extraction and conversion complete."; + statusLabel.GetText = () => "Done. Check {0}".F(Platform.SupportDir); backButton.IsDisabled = () => false; }); } - catch + catch (FileNotFoundException f) { - onError("Extraction or conversion failed"); + onError(f.FileName+" not found."); } + catch (Exception e) + { + onError(e.Message); + } + }) { IsBackground = true }; t.Start(); } diff --git a/OpenRA.Utility/Command.cs b/OpenRA.Utility/Command.cs index 82f321abad..15d9611fb6 100644 --- a/OpenRA.Utility/Command.cs +++ b/OpenRA.Utility/Command.cs @@ -55,7 +55,7 @@ namespace OpenRA.Utility ShpWriter.Write(destStream, width, srcImage.Height, srcImage.ToFrames(width)); - Console.WriteLine(dest+" saved"); + Console.WriteLine(dest+" saved."); } static IEnumerable ToFrames(this Bitmap bitmap, int width) @@ -108,10 +108,11 @@ namespace OpenRA.Utility x += srcImage.Width; - bitmap.UnlockBits( data ); + bitmap.UnlockBits(data); } bitmap.Save(dest); + Console.WriteLine(dest+" saved"); } } @@ -348,8 +349,8 @@ namespace OpenRA.Utility if (template.Value == null) throw new InvalidOperationException("No such template '{0}'".F(templateName)); - using( var image = tileset.RenderTemplate(template.Value.Id, palette) ) - image.Save( Path.ChangeExtension( templateName, ".png" ) ); + using (var image = tileset.RenderTemplate(template.Value.Id, palette)) + image.Save(Path.ChangeExtension(templateName, ".png")); } } @@ -359,17 +360,17 @@ namespace OpenRA.Utility var dest = args[2]; Dune2ShpReader srcImage = null; - using( var s = File.OpenRead( src ) ) + using(var s = File.OpenRead(src)) srcImage = new Dune2ShpReader(s); var size = srcImage.First().Size; - if (!srcImage.All( im => im.Size == size )) + if (!srcImage.All(im => im.Size == size)) throw new InvalidOperationException("All the frames must be the same size to convert from Dune2 to RA"); - using( var destStream = File.Create(dest) ) + using (var destStream = File.Create(dest)) ShpWriter.Write(destStream, size.Width, size.Height, - srcImage.Select( im => im.Image )); + srcImage.Select(im => im.Image)); } public static void ExtractFiles(string[] args) @@ -380,14 +381,18 @@ namespace OpenRA.Utility var manifest = new Manifest(mods); FileSystem.LoadFromManifest(manifest); - foreach( var f in files ) + foreach (var f in files) { + if (f == "--userdir") + break; + var src = FileSystem.Open(f); if (src == null) throw new InvalidOperationException("File not found: {0}".F(f)); var data = src.ReadAllBytes(); - - File.WriteAllBytes( f, data ); + var output = args.Contains("--userdir") ? Platform.SupportDir+f : f; + File.WriteAllBytes(output, data); + Console.WriteLine(output+" saved."); } } diff --git a/OpenRA.Utility/Program.cs b/OpenRA.Utility/Program.cs index 7fae4fb735..d891ef2218 100644 --- a/OpenRA.Utility/Program.cs +++ b/OpenRA.Utility/Program.cs @@ -60,7 +60,7 @@ namespace OpenRA.Utility Console.WriteLine(" --shp PNGFILE FRAMEWIDTH Convert a single PNG with multiple frames appended after another to a SHP"); Console.WriteLine(" --png SHPFILE PALETTE [--noshadow] Convert a SHP to a PNG containing all of its frames, optionally removing the shadow"); Console.WriteLine(" --fromd2 DUNE2SHP C&CSHP Convert a Dune II SHP (C&C mouse cursor) to C&C SHP format."); - Console.WriteLine(" --extract MOD[,MOD]* FILES Extract files from mod packages"); + Console.WriteLine(" --extract MOD[,MOD]* FILES [--userdir] Extract files from mod packages to the current (or user) directory"); Console.WriteLine(" --tmp-png MOD[,MOD]* THEATER FILES Extract terrain tiles to PNG"); Console.WriteLine(" --remap SRCMOD:PAL DESTMOD:PAL SRCSHP DESTSHP Remap SHPs to another palette"); Console.WriteLine(" --r8 R8FILE PALETTE START END FILENAME [--noshadow] [--infrantry] [--vehicle] [--projectile] [--building] [--wall] [--tileset] Convert Dune 2000 DATA.R8 to PNGs choosing start- and endframe as well as type for correct offset to append multiple frames to one PNG named by filename optionally removing the shadow."); diff --git a/mods/d2k/mod.yaml b/mods/d2k/mod.yaml index 22ce2ee495..dbebb7c280 100644 --- a/mods/d2k/mod.yaml +++ b/mods/d2k/mod.yaml @@ -69,7 +69,7 @@ ChromeLayout: mods/ra/chrome/musicplayer.yaml mods/d2k/chrome/tooltips.yaml mods/ra/chrome/assetbrowser.yaml - mods/ra/chrome/extractassets.yaml + mods/ra/chrome/convertassets.yaml Weapons: mods/d2k/weapons/defaults.yaml diff --git a/mods/ra/chrome/assetbrowser.yaml b/mods/ra/chrome/assetbrowser.yaml index 25c4f13fc2..fb77ec748c 100644 --- a/mods/ra/chrome/assetbrowser.yaml +++ b/mods/ra/chrome/assetbrowser.yaml @@ -78,35 +78,38 @@ Background@ASSETBROWSER_BG: Height:25 Text:Actions Font:Bold - Button@REMAP_BUTTON: + Button@EXPORT_BUTTON: X:PARENT_RIGHT - 200 - Y:PARENT_BOTTOM - 305 + Y:80 Width:160 Height:25 - Text:Change Palette + Text:Selected to PNG Font:Bold - Disabled: yes - Button@IMPORT_BUTTON: - X:PARENT_RIGHT - 200 - Y:PARENT_BOTTOM - 270 - Width:160 - Height:25 - Text:Import from PNG - Font:Bold - Disabled: yes Button@EXTRACT_BUTTON: X:PARENT_RIGHT - 200 - Y:PARENT_BOTTOM - 235 + Y:115 Width:160 Height:25 Text:Extract all to PNG Font:Bold - Button@EXPORT_BUTTON: + TextField@IMAGE_FILENAME_INPUT: + X:PARENT_RIGHT - 200 + Y:PARENT_BOTTOM - 235 + Width:100 + Height:25 + Text:pixelart.png + TextField@IMAGE_SIZE_INPUT: + X:PARENT_RIGHT - 90 + Y:PARENT_BOTTOM - 235 + Width:50 + Height:25 + Text:width + Button@IMPORT_BUTTON: X:PARENT_RIGHT - 200 Y:PARENT_BOTTOM - 200 Width:160 Height:25 - Text:Selected to PNG + Text:Import from PNG Font:Bold Button@CLOSE_BUTTON: X:PARENT_RIGHT - 200 diff --git a/mods/ra/chrome/extractassets.yaml b/mods/ra/chrome/convertassets.yaml similarity index 92% rename from mods/ra/chrome/extractassets.yaml rename to mods/ra/chrome/convertassets.yaml index 199eb7a06b..ecd4cc73af 100644 --- a/mods/ra/chrome/extractassets.yaml +++ b/mods/ra/chrome/convertassets.yaml @@ -1,5 +1,5 @@ -Background@EXTRACT_ASSETS_PANEL: - Logic:ExtractGameFilesLogic +Background@CONVERT_ASSETS_PANEL: + Logic:ConvertGameFilesLogic X:(WINDOW_RIGHT - WIDTH)/2 Y:(WINDOW_BOTTOM - HEIGHT)/2 Width:500 diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index 2af52f08d0..76cb2a1749 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -78,7 +78,7 @@ ChromeLayout: mods/ra/chrome/musicplayer.yaml mods/ra/chrome/tooltips.yaml mods/ra/chrome/assetbrowser.yaml - mods/ra/chrome/extractassets.yaml + mods/ra/chrome/convertassets.yaml Weapons: mods/ra/weapons.yaml