From 04b0b66f674725c3cd167bb1bcf3e6e7b65fe1ec Mon Sep 17 00:00:00 2001 From: miku-666 <74728189+NessieHax@users.noreply.github.com> Date: Mon, 10 Apr 2023 11:29:18 +0200 Subject: [PATCH] Remove CSM.cs and 3DSUtil and created reader/writer for 3ds textures --- PCK-Studio/Classes/FileTypes/CSM.cs | 91 ------------ .../Classes/IO/3DST/3DSTextureReader.cs | 94 +++++++++++++ .../Classes/IO/3DST/3DSTextureWriter.cs | 47 +++++++ .../{Utils/3DS => IO/3DST}/TextureCodec.cs | 27 +++- PCK-Studio/Classes/Utils/3DS/3DSUtil.cs | 131 ------------------ .../Forms/Skins-And-Textures/addnewskin.cs | 5 +- PCK-Studio/MainForm.cs | 8 +- PCK-Studio/PckStudio.csproj | 6 +- 8 files changed, 175 insertions(+), 234 deletions(-) delete mode 100644 PCK-Studio/Classes/FileTypes/CSM.cs create mode 100644 PCK-Studio/Classes/IO/3DST/3DSTextureReader.cs create mode 100644 PCK-Studio/Classes/IO/3DST/3DSTextureWriter.cs rename PCK-Studio/Classes/{Utils/3DS => IO/3DST}/TextureCodec.cs (96%) delete mode 100644 PCK-Studio/Classes/Utils/3DS/3DSUtil.cs diff --git a/PCK-Studio/Classes/FileTypes/CSM.cs b/PCK-Studio/Classes/FileTypes/CSM.cs deleted file mode 100644 index 5c8e27ff..00000000 --- a/PCK-Studio/Classes/FileTypes/CSM.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Drawing; -using System.IO; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using PckStudio.Models; - -namespace PckStudio.Classes -{ - class CSM - { - - //Part Name - //Part Parent(HEAD, BODY, LEG0, LEG1, ARM0, ARM1) - //Part Name - //Position-X - //Position-Y - //Position-Z - //Size-X - //Size-Y - //Size-Z - //UV-Y - //UV-X - - public static List CSMBlock = new List(); - - public static void TryParse(string CSM, MinecraftModelView modelView) - { - try - { - int i = 0; - string[] CSMLines = CSM.Split(new[] { "\n", "\r\n" }, StringSplitOptions.None); - foreach (string line in CSMLines) - { - if (i > 10) - { - GetModelPartFromCSM(CSMBlock, modelView); - CSMBlock.Clear(); - i = 0; - } - CSMBlock.Add(line + "\n"); - i++; - } - - modelView.Invalidate(); - } - catch { } - } - - public static void GetModelPartFromCSM(List CSM, MinecraftModelView modelView) - { - string PartName = CSM[0]; - string PartParent = CSM[1]; - string PartName2 = CSM[2]; - int PositionX = int.Parse(CSM[3]); - int PositionY = int.Parse(CSM[4]); - int PositionZ = int.Parse(CSM[5]); - int SizeX = int.Parse(CSM[6]); - int SizeY = int.Parse(CSM[7]); - int SizeZ = int.Parse(CSM[8]); - int UVY = int.Parse(CSM[9]); - int UVX = int.Parse(CSM[10]); - - //RenderBox - System.Drawing.Image source = Textures[0].Source; - Object3D object3D = new Box(source, new Rectangle(8, 0, 0x10, 8), new Rectangle(0, 8, 0x20, 8), new Point3D(0f, 0f, 0f), Effects.None); - Object3D object3D2 = new Box(source, new Rectangle(0x28, 0, 0x10, 8), new Rectangle(0x20, 8, 0x20, 8), new Point3D(0f, 0f, 0f), Effects.None); - Object3D object3D3 = new Box(source, new Rectangle(0x2C, 0x10, 8, 4), new Rectangle(0x28, 0x14, 0x20, 0xC), new Point3D(0f, 4f, 0f), Effects.FlipHorizontally); - - - //RenderGroup - Object3DGroup object3DGroup = new Object3DGroup(); - object3D2.Scale = 1.16f; - object3DGroup.RotationOrder = RotationOrders.XY; - object3DGroup.MinDegrees1 = -80f; - object3DGroup.MaxDegrees1 = 80f; - object3DGroup.MinDegrees2 = -57f; - object3DGroup.MaxDegrees2 = 57f; - object3DGroup.Add(object3D); - object3DGroup.Add(object3D2); - object3DGroup.Position = new Point3D(0f, 8f, 0f); - object3DGroup.Origin = new Point3D(0f, -4f, 0f); - object3DGroup.RotationOrder = RotationOrders.XY; - modelView.AddDynamic(object3DGroup); - } - - public static Texture[] Textures = new Texture[] { new Texture(Bitmap.FromFile(Environment.CurrentDirectory + "\\default.png")) }; - } -} diff --git a/PCK-Studio/Classes/IO/3DST/3DSTextureReader.cs b/PCK-Studio/Classes/IO/3DST/3DSTextureReader.cs new file mode 100644 index 00000000..e944003f --- /dev/null +++ b/PCK-Studio/Classes/IO/3DST/3DSTextureReader.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OMI.Workers; +using PckStudio.Classes._3ds; +using OMI; + +namespace PckStudio.Classes.IO._3DST +{ + internal class _3DSTextureReader : IDataFormatReader, IDataFormatReader + { + public Image FromFile(string filename) + { + if (File.Exists(filename)) + { + Image img = null; + using (var fs = File.OpenRead(filename)) + { + img = FromStream(fs); + } + return img; + } + throw new FileNotFoundException(filename); + } + + public Image FromStream(Stream stream) + { + Image img = null; + using (var reader = new EndiannessAwareBinaryReader(stream, Encoding.ASCII, leaveOpen: true, Endianness.LittleEndian)) + { + if (reader.ReadString(4) == "3DST") + { + const int offset = 32; + reader.ReadInt32(); // unknown value + _3DSTextureFormat format = reader.ReadInt32() switch + { + 0 => _3DSTextureFormat.argb8, + 1 => _3DSTextureFormat.rgb8, + 2 => _3DSTextureFormat.rgba5551, + 3 => _3DSTextureFormat.rgb8, + 4 => _3DSTextureFormat.rgba4, + 9 => _3DSTextureFormat.la4, + _ => _3DSTextureFormat.dontCare, + }; + int width = reader.ReadInt32(); + int height = reader.ReadInt32(); + int bufferSize = CalcBufferSize(format, width, height); + stream.Seek(offset, SeekOrigin.Begin); + byte[] buffer = new byte[bufferSize]; + reader.Read(buffer, 0, bufferSize); + img = TextureCodec.Decode(buffer, width, height, format); + img.RotateFlip(RotateFlipType.RotateNoneFlipY); + } + } + return img; + } + + private static int CalcBufferSize(_3DSTextureFormat textureFormat, int width, int height) + { + switch (textureFormat) + { + case _3DSTextureFormat.argb8: + return width * height * 4; + case _3DSTextureFormat.rgb8: + return width * height * 3; + case _3DSTextureFormat.rgba5551: + case _3DSTextureFormat.rgb565: + case _3DSTextureFormat.rgba4: + case _3DSTextureFormat.la8: + case _3DSTextureFormat.hilo8: + return width * height * 2; + case _3DSTextureFormat.l8: + case _3DSTextureFormat.a8: + case _3DSTextureFormat.la4: + case _3DSTextureFormat.etc1a4: + return width * height; + case _3DSTextureFormat.l4: + case _3DSTextureFormat.a4: + case _3DSTextureFormat.etc1: + return width * height >> 1; + default: + throw new InvalidDataException("Invalid texture format on BCH!"); + } + } + + object IDataFormatReader.FromFile(string filename) => FromFile(filename); + + object IDataFormatReader.FromStream(Stream stream) => FromStream(stream); + } +} diff --git a/PCK-Studio/Classes/IO/3DST/3DSTextureWriter.cs b/PCK-Studio/Classes/IO/3DST/3DSTextureWriter.cs new file mode 100644 index 00000000..28864ed2 --- /dev/null +++ b/PCK-Studio/Classes/IO/3DST/3DSTextureWriter.cs @@ -0,0 +1,47 @@ +using System; +using System.Drawing; +using System.IO; +using System.Text; +using OMI; +using OMI.Workers; +using PckStudio.Classes._3ds; + +namespace PckStudio.Classes.IO._3DST +{ + internal class _3DSTextureWriter : IDataFormatWriter + { + private Image _image; + private _3DSTextureFormat _format; + public _3DSTextureWriter(Image image, _3DSTextureFormat format = _3DSTextureFormat.argb8) + { + _image = image; + _format = format; + } + + public void WriteToFile(string filename) + { + using(var fs = File.OpenWrite(filename)) + { + WriteToStream(fs); + } + } + + public void WriteToStream(Stream stream) + { + using (var writer = new EndiannessAwareBinaryWriter(stream, Encoding.ASCII, leaveOpen: true, Endianness.LittleEndian)) + { + writer.WriteString("3DST"); // 0 + writer.Write(2); // 4 unknown + writer.Write((int)_format); // 8 + writer.Write(_image.Width); // 12 + writer.Write(_image.Height); // 16 + writer.Write(0); // 20 + writer.Write(0); // 24 + writer.Write(0); // 28 + _image.RotateFlip(RotateFlipType.RotateNoneFlipY); + byte[] buffer = TextureCodec.Encode(new Bitmap(_image), _format); + stream.Write(buffer, 0, buffer.Length); + } + } + } +} diff --git a/PCK-Studio/Classes/Utils/3DS/TextureCodec.cs b/PCK-Studio/Classes/IO/3DST/TextureCodec.cs similarity index 96% rename from PCK-Studio/Classes/Utils/3DS/TextureCodec.cs rename to PCK-Studio/Classes/IO/3DST/TextureCodec.cs index aa0b963a..2f208a2f 100644 --- a/PCK-Studio/Classes/Utils/3DS/TextureCodec.cs +++ b/PCK-Studio/Classes/IO/3DST/TextureCodec.cs @@ -2,14 +2,35 @@ using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; -using PckStudio.Classes._3ds.Utils; namespace PckStudio.Classes._3ds { + /// + /// Format of the texture used on the PICA200. + /// + public enum _3DSTextureFormat + { + argb8 = 0, + rgb8 = 1, + rgba5551 = 2, + rgb565 = 3, + rgba4 = 4, + la8 = 5, + hilo8 = 6, + l8 = 7, + a8 = 8, + la4 = 9, + l4 = 0xa, + a4 = 0xb, + etc1 = 0xc, + etc1a4 = 0xd, + dontCare + } + class TextureCodec { - private static int[] tileOrder = { 0, 1, 8, 9, 2, 3, 10, 11, 16, 17, 24, 25, 18, 19, 26, 27, 4, 5, 12, 13, 6, 7, 14, 15, 20, 21, 28, 29, 22, 23, 30, 31, 32, 33, 40, 41, 34, 35, 42, 43, 48, 49, 56, 57, 50, 51, 58, 59, 36, 37, 44, 45, 38, 39, 46, 47, 52, 53, 60, 61, 54, 55, 62, 63 }; - private static int[,] etc1LUT = { { 2, 8, -2, -8 }, { 5, 17, -5, -17 }, { 9, 29, -9, -29 }, { 13, 42, -13, -42 }, { 18, 60, -18, -60 }, { 24, 80, -24, -80 }, { 33, 106, -33, -106 }, { 47, 183, -47, -183 } }; + private static readonly int[] tileOrder = { 0, 1, 8, 9, 2, 3, 10, 11, 16, 17, 24, 25, 18, 19, 26, 27, 4, 5, 12, 13, 6, 7, 14, 15, 20, 21, 28, 29, 22, 23, 30, 31, 32, 33, 40, 41, 34, 35, 42, 43, 48, 49, 56, 57, 50, 51, 58, 59, 36, 37, 44, 45, 38, 39, 46, 47, 52, 53, 60, 61, 54, 55, 62, 63 }; + private static readonly int[,] etc1LUT = { { 2, 8, -2, -8 }, { 5, 17, -5, -17 }, { 9, 29, -9, -29 }, { 13, 42, -13, -42 }, { 18, 60, -18, -60 }, { 24, 80, -24, -80 }, { 33, 106, -33, -106 }, { 47, 183, -47, -183 } }; private static class TextureConverter { diff --git a/PCK-Studio/Classes/Utils/3DS/3DSUtil.cs b/PCK-Studio/Classes/Utils/3DS/3DSUtil.cs deleted file mode 100644 index 485420a7..00000000 --- a/PCK-Studio/Classes/Utils/3DS/3DSUtil.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System; -using System.Drawing; -using System.IO; -using System.Text; - -namespace PckStudio.Classes._3ds.Utils -{ - /// - /// Format of the texture used on the PICA200. - /// - public enum _3DSTextureFormat - { - argb8 = 0, - rgb8 = 1, - rgba5551 = 2, - rgb565 = 3, - rgba4 = 4, - la8 = 5, - hilo8 = 6, - l8 = 7, - a8 = 8, - la4 = 9, - l4 = 0xa, - a4 = 0xb, - etc1 = 0xc, - etc1a4 = 0xd, - dontCare - } - - internal class _3DSUtil - { - private static string ReadString(Stream stream, int len) - { - byte[] buffer = new byte[len]; - stream.Read(buffer, 0, len); - return Encoding.ASCII.GetString(buffer); - } - - private static int ReadInt32(Stream stream) - { - byte[] buffer = new byte[4]; - stream.Read(buffer, 0, 4); - return BitConverter.ToInt32(buffer, 0); - } - - private static void WriteString(Stream stream, string s) - { - byte[] buffer = Encoding.ASCII.GetBytes(s); - stream.Write(buffer, 0, buffer.Length); - } - - private static void WriteInt32(Stream stream, int value) - { - byte[] buffer = BitConverter.GetBytes(value); - stream.Write(buffer, 0, 4); - } - - public static int CalcBufferSize(_3DSTextureFormat textureFormat, int width, int height) - { - switch (textureFormat) - { - case _3DSTextureFormat.argb8: - return width * height * 4; - case _3DSTextureFormat.rgb8: - return width * height * 3; - case _3DSTextureFormat.rgba5551: - case _3DSTextureFormat.rgb565: - case _3DSTextureFormat.rgba4: - case _3DSTextureFormat.la8: - case _3DSTextureFormat.hilo8: - return width * height * 2; - case _3DSTextureFormat.l8: - case _3DSTextureFormat.a8: - case _3DSTextureFormat.la4: - case _3DSTextureFormat.etc1a4: - return width * height; - case _3DSTextureFormat.l4: - case _3DSTextureFormat.a4: - case _3DSTextureFormat.etc1: - return width * height >> 1; - default: - throw new InvalidDataException("Invalid texture format on BCH!"); - } - } - - public static Image GetImageFrom3DST(Stream stream) - { - if (ReadString(stream, 4) == "3DST") - { - const int offset = 32; - stream.Seek(8L, SeekOrigin.Begin); - _3DSTextureFormat format = ReadInt32(stream) switch - { - 0 => _3DSTextureFormat.argb8, - 1 => _3DSTextureFormat.rgb8, - 2 => _3DSTextureFormat.rgba5551, - 3 => _3DSTextureFormat.rgb8, - 4 => _3DSTextureFormat.rgba4, - 9 => _3DSTextureFormat.la4, - _ => _3DSTextureFormat.dontCare, - }; - int width = ReadInt32(stream); - int height = ReadInt32(stream); - int bufferSize = CalcBufferSize(format, width, height); - stream.Seek(offset, SeekOrigin.Begin); - byte[] buffer = new byte[bufferSize]; - stream.Read(buffer, 0, bufferSize); - var img = TextureCodec.Decode(buffer, width, height, format); - img.RotateFlip(RotateFlipType.RotateNoneFlipY); - return img; - } - return null; - } - - public static void SetImageTo3DST(Stream stream, Image source, _3DSTextureFormat format = _3DSTextureFormat.argb8) - { - // TODO: fix Encoding - WriteString(stream, "3DST"); // 0 - WriteInt32(stream, 2); // 4 unknown - WriteInt32(stream, (int)format); // 8 - WriteInt32(stream, source.Width); // 12 - WriteInt32(stream, source.Height); // 16 - WriteInt32(stream, 0); // 20 - WriteInt32(stream, 0); // 24 - WriteInt32(stream, 0); // 28 - source.RotateFlip(RotateFlipType.RotateNoneFlipY); - byte[] buffer = TextureCodec.Encode(new Bitmap(source), format); - stream.Write(buffer, 0, buffer.Length); - } - } -} diff --git a/PCK-Studio/Forms/Skins-And-Textures/addnewskin.cs b/PCK-Studio/Forms/Skins-And-Textures/addnewskin.cs index 1fda9bed..76a66e8c 100644 --- a/PCK-Studio/Forms/Skins-And-Textures/addnewskin.cs +++ b/PCK-Studio/Forms/Skins-And-Textures/addnewskin.cs @@ -5,10 +5,10 @@ using System.Windows.Forms; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using PckStudio.Classes.Utils; -using PckStudio.Classes._3ds.Utils; using OMI.Formats.Languages; using OMI.Formats.Pck; using PckStudio.Forms.Editor; +using PckStudio.Classes.IO._3DST; namespace PckStudio { @@ -347,7 +347,8 @@ namespace PckStudio { using (var fs = File.OpenRead(ofdd.FileName)) { - CheckImage(_3DSUtil.GetImageFrom3DST(fs)); + var reader = new _3DSTextureReader(); + CheckImage(reader.FromStream(fs)); textSkinName.Text = Path.GetFileNameWithoutExtension(ofdd.FileName); } return; diff --git a/PCK-Studio/MainForm.cs b/PCK-Studio/MainForm.cs index 1c981353..5be7fa29 100644 --- a/PCK-Studio/MainForm.cs +++ b/PCK-Studio/MainForm.cs @@ -19,7 +19,6 @@ using PckStudio.Properties; using PckStudio.Classes.FileTypes; using PckStudio.Classes.Utils; using PckStudio.Classes.Utils.ARC; -using PckStudio.Classes._3ds.Utils; using PckStudio.Forms; using PckStudio.Forms.Utilities; using PckStudio.Forms.Editor; @@ -27,6 +26,7 @@ using PckStudio.Forms.Additional_Popups.Animation; using PckStudio.Forms.Additional_Popups; using PckStudio.Classes.Misc; using PckStudio.Classes.IO.PCK; +using PckStudio.Classes.IO._3DST; namespace PckStudio { @@ -2069,11 +2069,11 @@ namespace PckStudio saveFileDialog.DefaultExt = ".3dst"; if (saveFileDialog.ShowDialog() == DialogResult.OK) { - using (var fs = saveFileDialog.OpenFile()) + using (var ms = new MemoryStream(file.Data)) { - using var ms = new MemoryStream(file.Data); Image img = Image.FromStream(ms); - _3DSUtil.SetImageTo3DST(fs, img); + var writer = new _3DSTextureWriter(img); + writer.WriteToFile(saveFileDialog.FileName); } } } diff --git a/PCK-Studio/PckStudio.csproj b/PCK-Studio/PckStudio.csproj index ae28ad89..47575773 100644 --- a/PCK-Studio/PckStudio.csproj +++ b/PCK-Studio/PckStudio.csproj @@ -176,7 +176,8 @@ - + + @@ -185,7 +186,6 @@ - @@ -464,7 +464,7 @@ CreditsForm.cs - + AddEntry.cs