diff --git a/Gm1KonverterCrossPlatform/Files/TGXImage.cs b/Gm1KonverterCrossPlatform/Files/TGXImage.cs index 079ecc0..6cce9ed 100644 --- a/Gm1KonverterCrossPlatform/Files/TGXImage.cs +++ b/Gm1KonverterCrossPlatform/Files/TGXImage.cs @@ -234,7 +234,12 @@ public unsafe void CreateImageFromByteArray(Palette palette) } + internal void ConvertImageWithPaletteToByteArray(List colors, int width, int height, Palette palette, List[] colorsImages = null) + { + var array = Utility.ImgToGM1ByteArray(colors, width, height, animatedColor, palette, colorsImages); + imgFileAsBytearray = array.ToArray(); + } internal unsafe void CreateNoComppressionImageFromByteArray(Palette palette,int offset) { diff --git a/Gm1KonverterCrossPlatform/HelperClasses/Utility.cs b/Gm1KonverterCrossPlatform/HelperClasses/Utility.cs index 71f29a6..fde1c7b 100644 --- a/Gm1KonverterCrossPlatform/HelperClasses/Utility.cs +++ b/Gm1KonverterCrossPlatform/HelperClasses/Utility.cs @@ -85,6 +85,7 @@ internal static List LoadImage(String filename, out int width, out int h var pixel = image[j, i]; byte a = (animatedColor >= 1 || ((GM1FileHeader.DataType)type) == GM1FileHeader.DataType.TilesObject + || ((GM1FileHeader.DataType)type) == GM1FileHeader.DataType.Animations || ((GM1FileHeader.DataType)type) == GM1FileHeader.DataType.TGXConstSize || ((GM1FileHeader.DataType)type) == GM1FileHeader.DataType.NOCompression || ((GM1FileHeader.DataType)type) == GM1FileHeader.DataType.NOCompression1) ? byte.MaxValue : byte.MinValue; @@ -117,9 +118,8 @@ internal static List LoadImage(String filename, out int width, out int h /// The Height from the IMG /// Needed for Alpha is 1 or 0 /// - internal static List ImgToGM1ByteArray(List colors, int width, int height, int animatedColor, Palette palette = null) + internal static List ImgToGM1ByteArray(List colors, int width, int height, int animatedColor, Palette palette = null, List[] paletteImages = null) { - int transparent = 32767; ushort alpha=(animatedColor==0)?(ushort)0b1000_0000_0000_0000: (ushort)0b0; List array = new List(); @@ -260,8 +260,16 @@ internal static List ImgToGM1ByteArray(List colors, int width, int array.Add((byte)(header | length)); var color = (ushort)(colors[j + i * width + 1] | alpha); + if (palette == null) + { array.AddRange(BitConverter.GetBytes(color)); - + } + else + { + byte positioninColortable = FindColorPositionInPalette(color, j + i * width + 1, palette, paletteImages); + array.Add(positioninColortable); + } + dummy -= 32; } if (dummy != 0) @@ -270,8 +278,18 @@ internal static List ImgToGM1ByteArray(List colors, int width, int array.Add((byte)(header | length)); var color = (ushort)(colors[j + i * width + 1] | alpha); + if (palette==null) + { array.AddRange(BitConverter.GetBytes(color)); - + } + else + { + byte positioninColortable = FindColorPositionInPalette(color, j + i * width + 1, palette, paletteImages); + array.Add(positioninColortable); + } + + + } } else @@ -286,8 +304,16 @@ internal static List ImgToGM1ByteArray(List colors, int width, int for (int a = 0; a < 32; a++) { var color = (ushort)(colors[j + zaehler + i * width] | alpha); - array.AddRange(BitConverter.GetBytes(color)); - + if (palette == null) + { + array.AddRange(BitConverter.GetBytes(color)); + } + else + { + byte positioninColortable = FindColorPositionInPalette(color, j + zaehler + i * width, palette, paletteImages); + array.Add(positioninColortable); + } + dummy--; zaehler++; } @@ -299,8 +325,16 @@ internal static List ImgToGM1ByteArray(List colors, int width, int for (int a = 0; a < dummy; a++) { var color = (ushort)(colors[j + zaehler + i * width] | alpha); - array.AddRange(BitConverter.GetBytes(color)); - + if (palette == null) + { + array.AddRange(BitConverter.GetBytes(color)); + } + else + { + byte positioninColortable = FindColorPositionInPalette(color, j + zaehler + i * width, palette, paletteImages); + array.Add(positioninColortable); + } + zaehler++; } } @@ -324,6 +358,69 @@ internal static List ImgToGM1ByteArray(List colors, int width, int return array; } + private static byte FindColorPositionInPalette(ushort color,int position, Palette palette, List[] paletteImages) + { + + byte newPosition = 0; + if (paletteImages==null)//not orginal Stronghold Files do not need to check all + { + for (byte i = 0; i < byte.MaxValue; i++) + { + if (color == palette.ArrayPaletten[0,i]) + { + newPosition = i; + break; + } + + } + } + else // Orginal ones + { + List positions = new List(); + for (byte i = 0; i < byte.MaxValue; i++) + { + if (color == palette.ArrayPaletten[0, i]) + { + positions.Add(i); + } + } + if (positions.Count>1|| positions.Count==0) + { + + for (int j = 0; j < 9; j++)//other 9 pictures check for only one position + { + List otherPositions = new List(); + for (byte i = 0; i < byte.MaxValue; i++) + { + if (paletteImages[j][position] == palette.ArrayPaletten[j+1, i]) + { + otherPositions.Add(i); + } + } + if (otherPositions.Count==1) + { + newPosition = otherPositions[0]; + break; + }else if (otherPositions.Count > 1) + { + newPosition = otherPositions[0]; + } + } + + } + else + { + + newPosition = positions[0]; + } + } + if (newPosition==0) + { + + } + return newPosition; + } + private static bool CheckIfAllLinesUnderTransparent(List colors, int transparent, int offset) { for (int i = offset; i < colors.Count; i++) diff --git a/Gm1KonverterCrossPlatform/Languages/Language.de-DE.xaml b/Gm1KonverterCrossPlatform/Languages/Language.de-DE.xaml index d5138c4..6a5b906 100644 --- a/Gm1KonverterCrossPlatform/Languages/Language.de-DE.xaml +++ b/Gm1KonverterCrossPlatform/Languages/Language.de-DE.xaml @@ -73,4 +73,7 @@ Exportiere Gif Selektiere Bilder mit STRG danach klicke auf den Export Button Verzögerung: + + Importiere Orginal Stronghold Animation + Exportiere Orginal Stronghold Animation diff --git a/Gm1KonverterCrossPlatform/Languages/Language.ru-RU.xaml b/Gm1KonverterCrossPlatform/Languages/Language.ru-RU.xaml index e90c4b0..d4c35ba 100644 --- a/Gm1KonverterCrossPlatform/Languages/Language.ru-RU.xaml +++ b/Gm1KonverterCrossPlatform/Languages/Language.ru-RU.xaml @@ -75,4 +75,7 @@ Экспортировать Гиф Выберите изображения с помощью CTRL, затем нажмите кнопку «Экспорт». Задержка: + + Import Orginal Stronghold Animation + Export Orginal Stronghold Animation \ No newline at end of file diff --git a/Gm1KonverterCrossPlatform/Languages/Language.xaml b/Gm1KonverterCrossPlatform/Languages/Language.xaml index e6500a9..e68a5b2 100644 --- a/Gm1KonverterCrossPlatform/Languages/Language.xaml +++ b/Gm1KonverterCrossPlatform/Languages/Language.xaml @@ -75,5 +75,7 @@ Export Gif Select Images with CTRL than click on the Export Button Delay: - + + Import Orginal Stronghold Animation + Export Orginal Stronghold Animation diff --git a/Gm1KonverterCrossPlatform/ViewModels/MainWindowViewModel.cs b/Gm1KonverterCrossPlatform/ViewModels/MainWindowViewModel.cs index dce28c3..fae8c9b 100644 --- a/Gm1KonverterCrossPlatform/ViewModels/MainWindowViewModel.cs +++ b/Gm1KonverterCrossPlatform/ViewModels/MainWindowViewModel.cs @@ -224,6 +224,17 @@ public bool ColorButtonsEnabled get => colorButtonsEnabled; set => this.RaiseAndSetIfChanged(ref colorButtonsEnabled, value); } + + + + private bool orginalStrongholdAnimationButtonEnabled = false; + public bool OrginalStrongholdAnimationButtonEnabled + { + + get => orginalStrongholdAnimationButtonEnabled; + set => this.RaiseAndSetIfChanged(ref orginalStrongholdAnimationButtonEnabled, value); + } + private bool importButtonEnabled = false; public bool ImportButtonEnabled { diff --git a/Gm1KonverterCrossPlatform/Views/MainWindow.xaml b/Gm1KonverterCrossPlatform/Views/MainWindow.xaml index d149971..9e0d5d3 100644 --- a/Gm1KonverterCrossPlatform/Views/MainWindow.xaml +++ b/Gm1KonverterCrossPlatform/Views/MainWindow.xaml @@ -39,6 +39,10 @@ + + + + diff --git a/Gm1KonverterCrossPlatform/Views/MainWindow.xaml.cs b/Gm1KonverterCrossPlatform/Views/MainWindow.xaml.cs index 0a00b04..223d3d6 100644 --- a/Gm1KonverterCrossPlatform/Views/MainWindow.xaml.cs +++ b/Gm1KonverterCrossPlatform/Views/MainWindow.xaml.cs @@ -66,6 +66,13 @@ public MainWindow() MenuItem importImagesMenueItem = this.Get("ImportImagesMenueItem"); importImagesMenueItem.Click += ImportImages; + MenuItem exportOrginalStrongholdAnimation = this.Get("ExportOrginalStrongholdAnimation"); + exportOrginalStrongholdAnimation.Click += ExportOrginalStrongholdAnimation; + + MenuItem importOrginalStrongholdAnimation = this.Get("ImportOrginalStrongholdAnimation"); + importOrginalStrongholdAnimation.Click += ImportOrginalStrongholdAnimation; + + Image image = this.Get("HelpIcon"); Avalonia.Media.Imaging.Bitmap bitmap = new Avalonia.Media.Imaging.Bitmap("Images/info.png"); @@ -73,6 +80,85 @@ public MainWindow() image.Tapped += OpenInfoWindow; } + private void ExportOrginalStrongholdAnimation(object sender, RoutedEventArgs e) + { + Cursor = new Avalonia.Input.Cursor(Avalonia.Input.StandardCursorType.Wait); + var filewithoutgm1ending = vm.File.FileHeader.Name.Replace(".gm1", ""); + vm.File.Palette.ActualPalette = 0; + vm.File.DecodeGm1File(vm.File.FileArray, vm.File.FileHeader.Name); + for (int i = 0; i < 10; i++) + { + + if (!Directory.Exists(vm.UserConfig.WorkFolderPath + "\\" + filewithoutgm1ending + "\\OrginalAnimationPalette"+(i+1))) + { + Directory.CreateDirectory(vm.UserConfig.WorkFolderPath + "\\" + filewithoutgm1ending + "\\OrginalAnimationPalette" + (i + 1)); + } + int img = 1; + foreach (var image in vm.File.ImagesTGX) + { + image.Bitmap.Save(vm.UserConfig.WorkFolderPath + "\\" + filewithoutgm1ending + "\\OrginalAnimationPalette" + (i + 1)+"\\OrginalAnimationImg" + img + ".png"); + img++; + } + vm.ChangePalette(1); + } + + if (vm.UserConfig.OpenFolderAfterExport) + Process.Start("explorer.exe", vm.UserConfig.WorkFolderPath + "\\" + filewithoutgm1ending ); + + vm.LoadWorkfolderFiles(); + Cursor = new Avalonia.Input.Cursor(Avalonia.Input.StandardCursorType.Arrow); + } + + private void ImportOrginalStrongholdAnimation(object sender, RoutedEventArgs e) + { + Cursor = new Avalonia.Input.Cursor(Avalonia.Input.StandardCursorType.Wait); + var filewithoutgm1ending = vm.File.FileHeader.Name.Replace(".gm1", ""); + var files = Directory.GetFiles(vm.UserConfig.WorkFolderPath + "\\" + filewithoutgm1ending + "\\OrginalAnimationPalette1", "*.png", SearchOption.TopDirectoryOnly); + //sort because 11 is before 2 + files = files.OrderBy(x => x.Length).ThenBy(x => x).ToArray(); + int counter = 1; + foreach (var file in files) + { + var filename = Path.GetFileName(file); + if (filename.Equals("OrginalAnimationImg" + counter + ".png")) + { + int width, height; + var list = Utility.LoadImage(file, out width, out height, vm.File.ImagesTGX[counter-1].AnimatedColor, 1, vm.File.FileHeader.IDataType); + if (list.Count == 0) return; + List[] colorsImages = new List[9]; + + colorsImages[0] = Utility.LoadImage(vm.UserConfig.WorkFolderPath + "\\" + filewithoutgm1ending + "\\OrginalAnimationPalette" + 2 + "\\OrginalAnimationImg"+counter+".png", out width, out height, vm.File.ImagesTGX[counter - 1].AnimatedColor, 1, vm.File.FileHeader.IDataType); + colorsImages[1] = Utility.LoadImage(vm.UserConfig.WorkFolderPath + "\\" + filewithoutgm1ending + "\\OrginalAnimationPalette" + 3 + "\\OrginalAnimationImg" + counter + ".png", out width, out height, vm.File.ImagesTGX[counter - 1].AnimatedColor, 1, vm.File.FileHeader.IDataType); + colorsImages[2] = Utility.LoadImage(vm.UserConfig.WorkFolderPath + "\\" + filewithoutgm1ending + "\\OrginalAnimationPalette" + 4 + "\\OrginalAnimationImg" + counter + ".png", out width, out height, vm.File.ImagesTGX[counter - 1].AnimatedColor, 1, vm.File.FileHeader.IDataType); + colorsImages[3] = Utility.LoadImage(vm.UserConfig.WorkFolderPath + "\\" + filewithoutgm1ending + "\\OrginalAnimationPalette" + 5 + "\\OrginalAnimationImg" + counter + ".png", out width, out height, vm.File.ImagesTGX[counter - 1].AnimatedColor, 1, vm.File.FileHeader.IDataType); + colorsImages[4] = Utility.LoadImage(vm.UserConfig.WorkFolderPath + "\\" + filewithoutgm1ending + "\\OrginalAnimationPalette" + 6 + "\\OrginalAnimationImg" + counter + ".png", out width, out height, vm.File.ImagesTGX[counter - 1].AnimatedColor, 1, vm.File.FileHeader.IDataType); + colorsImages[5] = Utility.LoadImage(vm.UserConfig.WorkFolderPath + "\\" + filewithoutgm1ending + "\\OrginalAnimationPalette" + 7 + "\\OrginalAnimationImg" + counter + ".png", out width, out height, vm.File.ImagesTGX[counter - 1].AnimatedColor, 1, vm.File.FileHeader.IDataType); + colorsImages[6] = Utility.LoadImage(vm.UserConfig.WorkFolderPath + "\\" + filewithoutgm1ending + "\\OrginalAnimationPalette" + 8 + "\\OrginalAnimationImg" + counter + ".png", out width, out height, vm.File.ImagesTGX[counter - 1].AnimatedColor, 1, vm.File.FileHeader.IDataType); + colorsImages[7] = Utility.LoadImage(vm.UserConfig.WorkFolderPath + "\\" + filewithoutgm1ending + "\\OrginalAnimationPalette" + 9 + "\\OrginalAnimationImg" + counter + ".png", out width, out height, vm.File.ImagesTGX[counter - 1].AnimatedColor, 1, vm.File.FileHeader.IDataType); + colorsImages[8] = Utility.LoadImage(vm.UserConfig.WorkFolderPath + "\\" + filewithoutgm1ending + "\\OrginalAnimationPalette" + 10 + "\\OrginalAnimationImg" + counter + ".png", out width, out height, vm.File.ImagesTGX[counter - 1].AnimatedColor, 1, vm.File.FileHeader.IDataType); + vm.File.ImagesTGX[counter - 1].ConvertImageWithPaletteToByteArray(list, width, height, vm.File.Palette, colorsImages); + vm.File.ImagesTGX[counter - 1].Width = (ushort)width; + vm.File.ImagesTGX[counter - 1].Height = (ushort)height; + + counter++; + } + } + + if (vm.File.ImagesTGX.Count > 0) vm.File.ImagesTGX[0].SizeinByteArray = (uint)vm.File.ImagesTGX[0].ImgFileAsBytearray.Length; + uint zaehler = 0; + for (int i = 1; i < vm.File.ImagesTGX.Count; i++) + { + zaehler += vm.File.ImagesTGX[i - 1].SizeinByteArray; + vm.File.ImagesTGX[i].OffsetinByteArray = zaehler; + vm.File.ImagesTGX[i].SizeinByteArray = (uint)vm.File.ImagesTGX[i].ImgFileAsBytearray.Length; + } + + //datasize neu setzten + uint newDataSize = vm.File.ImagesTGX[vm.File.ImagesTGX.Count - 1].OffsetinByteArray + vm.File.ImagesTGX[vm.File.ImagesTGX.Count - 1].SizeinByteArray; ; + Cursor = new Avalonia.Input.Cursor(Avalonia.Input.StandardCursorType.Arrow); + + } + private void OpenInfoWindow(object sender, RoutedEventArgs e) { if (vm.File == null) return; @@ -103,7 +189,7 @@ private void ImportImages(object sender, RoutedEventArgs e) foreach (var file in files) { var filename = Path.GetFileName(file); - if (filename.Equals("Image"+ counter+".png")) + if (filename.Equals("Image"+ counter +".png")) { Avalonia.Media.Imaging.Bitmap image = new Avalonia.Media.Imaging.Bitmap(file); vm.TGXImages[counter - 1].Source = image; @@ -115,24 +201,28 @@ private void ImportImages(object sender, RoutedEventArgs e) var list = Utility.LoadImage(file,out width,out height, vm.File.ImagesTGX[fileindex].AnimatedColor,1,vm.File.FileHeader.IDataType); if (list.Count == 0) return; - if ((GM1FileHeader.DataType)vm.File.FileHeader.IDataType != GM1FileHeader.DataType.TilesObject - && (GM1FileHeader.DataType)vm.File.FileHeader.IDataType != GM1FileHeader.DataType.NOCompression - && (GM1FileHeader.DataType)vm.File.FileHeader.IDataType != GM1FileHeader.DataType.NOCompression1) + if ((GM1FileHeader.DataType)vm.File.FileHeader.IDataType == GM1FileHeader.DataType.Animations) { - vm.File.ImagesTGX[fileindex].ConvertImageWithoutPaletteToByteArray(list, width, height); + vm.File.ImagesTGX[fileindex].ConvertImageWithPaletteToByteArray(list, width, height,vm.File.Palette); vm.File.ImagesTGX[fileindex].Width = (ushort)width; vm.File.ImagesTGX[fileindex].Height = (ushort)height; - }else if ((GM1FileHeader.DataType)vm.File.FileHeader.IDataType == GM1FileHeader.DataType.NOCompression + } + else if ((GM1FileHeader.DataType)vm.File.FileHeader.IDataType == GM1FileHeader.DataType.NOCompression ||(GM1FileHeader.DataType)vm.File.FileHeader.IDataType == GM1FileHeader.DataType.NOCompression1) { vm.File.ImagesTGX[fileindex].ConvertNoCommpressionImageToByteArray(list, width, height); vm.File.ImagesTGX[fileindex].Width = (ushort)width; vm.File.ImagesTGX[fileindex].Height = (ushort)(height + ((GM1FileHeader.DataType)vm.File.FileHeader.IDataType == GM1FileHeader.DataType.NOCompression1 ? 0 : 7));//7 because stronghold want it so } - else + else if((GM1FileHeader.DataType)vm.File.FileHeader.IDataType == GM1FileHeader.DataType.TilesObject) { vm.File.ConvertImgToTiles(list, (ushort)width, (ushort)height); } + else { + vm.File.ImagesTGX[fileindex].ConvertImageWithoutPaletteToByteArray(list, width, height); + vm.File.ImagesTGX[fileindex].Width = (ushort)width; + vm.File.ImagesTGX[fileindex].Height = (ushort)height; + } } @@ -281,12 +371,14 @@ private void LoadGm1File(string listboxItemBefore) { vm.ImportButtonEnabled = true; vm.ColorButtonsEnabled = false; + vm.OrginalStrongholdAnimationButtonEnabled = false; vm.ActuellColorTable = null; } else { + vm.OrginalStrongholdAnimationButtonEnabled = true; vm.ColorButtonsEnabled = true; - vm.ImportButtonEnabled = false; + vm.ImportButtonEnabled = true; } vm.ButtonsEnabled = true;