diff --git a/MeshUnpacker/MeshUnpacker.csproj b/MeshUnpacker/MeshUnpacker.csproj new file mode 100644 index 0000000..2f4fc77 --- /dev/null +++ b/MeshUnpacker/MeshUnpacker.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/MeshUnpacker/Program.cs b/MeshUnpacker/Program.cs new file mode 100644 index 0000000..40dac44 --- /dev/null +++ b/MeshUnpacker/Program.cs @@ -0,0 +1,14 @@ +// See https://aka.ms/new-console-template for more information + +Console.WriteLine("Hello, World!"); + +using var fs = new FileStream("C:\\ParkanUnpacked\\11_fr_e_brige.msh\\0_fr_e_brige.bin", FileMode.Open); + +byte[] buffer = new byte[38]; + +for (int i = 0; i < 6; i++) +{ + fs.ReadExactly(buffer); + + Console.WriteLine(string.Join(" ", buffer.Select(x => x.ToString("X2")))); +} \ No newline at end of file diff --git a/NResUI/App.cs b/NResUI/App.cs index aedf80f..219fe41 100644 --- a/NResUI/App.cs +++ b/NResUI/App.cs @@ -47,7 +47,8 @@ public class App serviceCollection.AddSingleton(type); } - serviceCollection.AddSingleton(new ExplorerViewModel()); + serviceCollection.AddSingleton(new NResExplorerViewModel()); + serviceCollection.AddSingleton(new TexmExplorerViewModel()); var serviceProvider = serviceCollection.BuildServiceProvider(); diff --git a/NResUI/ImGuiUI/MainMenuBar.cs b/NResUI/ImGuiUI/MainMenuBar.cs index 2b845d6..4589778 100644 --- a/NResUI/ImGuiUI/MainMenuBar.cs +++ b/NResUI/ImGuiUI/MainMenuBar.cs @@ -4,17 +4,20 @@ using NativeFileDialogSharp; using NResLib; using NResUI.Abstractions; using NResUI.Models; +using TexmLib; namespace NResUI.ImGuiUI { public class MainMenuBar : IImGuiPanel { - private readonly ExplorerViewModel _explorerViewModel; + private readonly NResExplorerViewModel _nResExplorerViewModel; + private readonly TexmExplorerViewModel _texmExplorerViewModel; private readonly MessageBoxModalPanel _messageBox; - public MainMenuBar(ExplorerViewModel explorerViewModel, MessageBoxModalPanel messageBox) + public MainMenuBar(NResExplorerViewModel nResExplorerViewModel, TexmExplorerViewModel texmExplorerViewModel, MessageBoxModalPanel messageBox) { - _explorerViewModel = explorerViewModel; + _nResExplorerViewModel = nResExplorerViewModel; + _texmExplorerViewModel = texmExplorerViewModel; _messageBox = messageBox; } @@ -34,11 +37,29 @@ namespace NResUI.ImGuiUI var parseResult = NResParser.ReadFile(path); - _explorerViewModel.SetParseResult(parseResult, path); + _nResExplorerViewModel.SetParseResult(parseResult, path); + Console.WriteLine("Read NRES"); } } - if (_explorerViewModel.HasFile) + if (ImGui.MenuItem("Open TEXM")) + { + var result = Dialog.FileOpen(); + + if (result.IsOk) + { + var path = result.Path; + + using var fs = new FileStream(path, FileMode.Open); + + var parseResult = TexmParser.ReadFromStream(fs, path); + + _texmExplorerViewModel.SetParseResult(parseResult, path); + Console.WriteLine("Read TEXM"); + } + } + + if (_nResExplorerViewModel.HasFile) { if (ImGui.MenuItem("Экспортировать")) { @@ -48,32 +69,13 @@ namespace NResUI.ImGuiUI { var path = result.Path; - NResExporter.Export(_explorerViewModel.Archive!, path, _explorerViewModel.Path!); + NResExporter.Export(_nResExplorerViewModel.Archive!, path, _nResExplorerViewModel.Path!); _messageBox.Show("Успешно экспортировано"); } } } - if (ImGui.BeginMenu("Open Recent")) - { - ImGui.EndMenu(); - } - - if (ImGui.MenuItem("Exit")) - { - App.Instance.Exit(); - } - - ImGui.EndMenu(); - } - - if (ImGui.BeginMenu("Windows")) - { - if (ImGui.MenuItem("Settings")) - { - } - ImGui.EndMenu(); } diff --git a/NResUI/ImGuiUI/ExplorerPanel.cs b/NResUI/ImGuiUI/NResExplorerPanel.cs similarity index 95% rename from NResUI/ImGuiUI/ExplorerPanel.cs rename to NResUI/ImGuiUI/NResExplorerPanel.cs index 82b4189..d3902aa 100644 --- a/NResUI/ImGuiUI/ExplorerPanel.cs +++ b/NResUI/ImGuiUI/NResExplorerPanel.cs @@ -4,18 +4,18 @@ using NResUI.Models; namespace NResUI.ImGuiUI; -public class ExplorerPanel : IImGuiPanel +public class NResExplorerPanel : IImGuiPanel { - private readonly ExplorerViewModel _viewModel; + private readonly NResExplorerViewModel _viewModel; - public ExplorerPanel(ExplorerViewModel viewModel) + public NResExplorerPanel(NResExplorerViewModel viewModel) { _viewModel = viewModel; } public void OnImGuiRender() { - if (ImGui.Begin("Explorer")) + if (ImGui.Begin("NRes Explorer")) { if (!_viewModel.HasFile) { diff --git a/NResUI/ImGuiUI/TexmExplorer.cs b/NResUI/ImGuiUI/TexmExplorer.cs new file mode 100644 index 0000000..3c0bbc6 --- /dev/null +++ b/NResUI/ImGuiUI/TexmExplorer.cs @@ -0,0 +1,73 @@ +using ImGuiNET; +using NResUI.Abstractions; +using NResUI.Models; + +namespace NResUI.ImGuiUI; + +public class TexmExplorer : IImGuiPanel +{ + private readonly TexmExplorerViewModel _viewModel; + + public TexmExplorer(TexmExplorerViewModel viewModel) + { + _viewModel = viewModel; + } + + public void OnImGuiRender() + { + if (ImGui.Begin("TEXM Explorer")) + { + if (!_viewModel.HasFile) + { + ImGui.Text("No TEXM opened"); + } + else + { + if (_viewModel.TexmFile is not null) + { + ImGui.Text("File: "); + ImGui.SameLine(); + ImGui.Text(_viewModel.Path); + + ImGui.Text("Header: "); + ImGui.SameLine(); + ImGui.Text(_viewModel.TexmFile.Header.TexmAscii); + + ImGui.Text("Width: "); + ImGui.SameLine(); + ImGui.Text(_viewModel.TexmFile.Header.Width.ToString()); + + ImGui.Text("Height: "); + ImGui.SameLine(); + ImGui.Text(_viewModel.TexmFile.Header.Height.ToString()); + + ImGui.Text("MipMap Count: "); + ImGui.SameLine(); + ImGui.Text(_viewModel.TexmFile.Header.MipmapCount.ToString()); + + ImGui.Text("Stride: "); + ImGui.SameLine(); + ImGui.Text(_viewModel.TexmFile.Header.Stride.ToString()); + + ImGui.Text("Magic1: "); + ImGui.SameLine(); + ImGui.Text(_viewModel.TexmFile.Header.Magic1.ToString()); + + ImGui.Text("Magic2: "); + ImGui.SameLine(); + ImGui.Text(_viewModel.TexmFile.Header.Magic2.ToString()); + + ImGui.Text("Format: "); + ImGui.SameLine(); + ImGui.Text(_viewModel.TexmFile.Header.Format.ToString()); + + ImGui.Text("IsIndexed: "); + ImGui.SameLine(); + ImGui.Text(_viewModel.TexmFile.IsIndexed.ToString()); + } + } + + ImGui.End(); + } + } +} \ No newline at end of file diff --git a/NResUI/Models/ExplorerViewModel.cs b/NResUI/Models/NResExplorerViewModel.cs similarity index 92% rename from NResUI/Models/ExplorerViewModel.cs rename to NResUI/Models/NResExplorerViewModel.cs index bb83211..02ee12c 100644 --- a/NResUI/Models/ExplorerViewModel.cs +++ b/NResUI/Models/NResExplorerViewModel.cs @@ -2,7 +2,7 @@ namespace NResUI.Models; -public class ExplorerViewModel +public class NResExplorerViewModel { public bool HasFile { get; set; } public string? Error { get; set; } diff --git a/NResUI/Models/TexmExplorerViewModel.cs b/NResUI/Models/TexmExplorerViewModel.cs new file mode 100644 index 0000000..8d25d25 --- /dev/null +++ b/NResUI/Models/TexmExplorerViewModel.cs @@ -0,0 +1,27 @@ +using TexmLib; + +namespace NResUI.Models; + +public class TexmExplorerViewModel +{ + public bool HasFile { get; set; } + public string? Error { get; set; } + + public TexmFile? TexmFile { get; set; } + + public string? Path { get; set; } + + public void SetParseResult(TexmParseResult result, string path) + { + Error = result.Error; + + if (result.TexmFile != null) + { + HasFile = true; + } + + TexmFile = result.TexmFile; + Path = path; + } + +} \ No newline at end of file diff --git a/NResUI/NResUI.csproj b/NResUI/NResUI.csproj index 16483bf..ce453ea 100644 --- a/NResUI/NResUI.csproj +++ b/NResUI/NResUI.csproj @@ -20,6 +20,7 @@ + diff --git a/ParkanPlayground.sln b/ParkanPlayground.sln index 73783f3..4f762b2 100644 --- a/ParkanPlayground.sln +++ b/ParkanPlayground.sln @@ -10,6 +10,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NResUI", "NResUI\NResUI.csp EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NResLib", "NResLib\NResLib.csproj", "{9429AEAE-80A6-4EE7-AB66-9161CC4C3A3D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MeshUnpacker", "MeshUnpacker\MeshUnpacker.csproj", "{F1465FFE-0D66-4A3C-90D7-153A14E226E6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TexmLib", "TexmLib\TexmLib.csproj", "{40097CB1-B4B8-4D3E-A874-7D46F5C81DB3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -36,5 +40,13 @@ Global {9429AEAE-80A6-4EE7-AB66-9161CC4C3A3D}.Debug|Any CPU.Build.0 = Debug|Any CPU {9429AEAE-80A6-4EE7-AB66-9161CC4C3A3D}.Release|Any CPU.ActiveCfg = Release|Any CPU {9429AEAE-80A6-4EE7-AB66-9161CC4C3A3D}.Release|Any CPU.Build.0 = Release|Any CPU + {F1465FFE-0D66-4A3C-90D7-153A14E226E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F1465FFE-0D66-4A3C-90D7-153A14E226E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F1465FFE-0D66-4A3C-90D7-153A14E226E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F1465FFE-0D66-4A3C-90D7-153A14E226E6}.Release|Any CPU.Build.0 = Release|Any CPU + {40097CB1-B4B8-4D3E-A874-7D46F5C81DB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {40097CB1-B4B8-4D3E-A874-7D46F5C81DB3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {40097CB1-B4B8-4D3E-A874-7D46F5C81DB3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {40097CB1-B4B8-4D3E-A874-7D46F5C81DB3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/TextureDecoder/Extensions.cs b/TexmLib/Extensions.cs similarity index 89% rename from TextureDecoder/Extensions.cs rename to TexmLib/Extensions.cs index e422529..c37bf1c 100644 --- a/TextureDecoder/Extensions.cs +++ b/TexmLib/Extensions.cs @@ -1,4 +1,4 @@ -namespace TextureDecoder; +namespace TexmLib; public static class Extensions { diff --git a/TexmLib/NResParseResult.cs b/TexmLib/NResParseResult.cs new file mode 100644 index 0000000..46ac40b --- /dev/null +++ b/TexmLib/NResParseResult.cs @@ -0,0 +1,3 @@ +namespace TexmLib; + +public record TexmParseResult(TexmFile? TexmFile = null, string? Error = null); \ No newline at end of file diff --git a/TextureDecoder/TextureFile.cs b/TexmLib/TexmFile.cs similarity index 59% rename from TextureDecoder/TextureFile.cs rename to TexmLib/TexmFile.cs index f947ed4..3c2090f 100644 --- a/TextureDecoder/TextureFile.cs +++ b/TexmLib/TexmFile.cs @@ -3,7 +3,7 @@ using System.Text; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; -namespace TextureDecoder; +namespace TexmLib; /// /// Заголовок TEXM файла (может быть .0 файл) @@ -37,7 +37,7 @@ public record PageHeader(string Page, int Count, List Items); public record PageItem(short X, short Width, short Y, short Height); -public class TextureFile +public class TexmFile { /// /// Исходное имя файла текстуры TEXM @@ -70,195 +70,6 @@ public class TextureFile /// public byte[] LookupColors { get; set; } - - private TextureFile() - { - } - - public static TextureFile ReadFromStream(Stream stream, string file) - { - Span headerBytes = stackalloc byte[32]; - stream.ReadExactly(headerBytes); - - var texmHeader = headerBytes[0..4]; - - var widthBytes = headerBytes[4..8]; - var heightBytes = headerBytes[8..12]; - var mipmapCountBytes = headerBytes[12..16]; - var strideBytes = headerBytes[16..20]; - var magic1Bytes = headerBytes[20..24]; - var magic2Bytes = headerBytes[24..28]; - var formatBytes = headerBytes[28..32]; - - var texmAscii = Encoding.ASCII.GetString(texmHeader); - var width = BinaryPrimitives.ReadInt32LittleEndian(widthBytes); - var height = BinaryPrimitives.ReadInt32LittleEndian(heightBytes); - var mipmapCount = BinaryPrimitives.ReadInt32LittleEndian(mipmapCountBytes); - var stride = BinaryPrimitives.ReadInt32LittleEndian(strideBytes); - var magic1 = BinaryPrimitives.ReadInt32LittleEndian(magic1Bytes); - var magic2 = BinaryPrimitives.ReadInt32LittleEndian(magic2Bytes); - var format = BinaryPrimitives.ReadInt32LittleEndian(formatBytes); - - var textureFile = new TextureFile() - { - FileName = file - }; - - var header = new TexmHeader( - texmAscii, - width, - height, - mipmapCount, - stride, - magic1, - magic2, - format - ); - - textureFile.Header = header; - - if (format == 0) - { - // если формат 0, то текстура использует lookup таблицу в первых 1024 байтах (256 разных цветов в формате ARGB 888) - - var lookupColors = new byte[1024]; - stream.ReadExactly(lookupColors, 0, lookupColors.Length); - - textureFile.LookupColors = lookupColors; - - var mipmapBytesList = ReadMipmapsAsIndexes( - stream, - mipmapCount, - width, - height - ); - - textureFile.MipmapBytes = mipmapBytesList; - textureFile.IsIndexed = true; - } - else - { - var mipmapBytesList = ReadMipmaps( - stream, - format.AsStride(), - mipmapCount, - width, - height - ); - - textureFile.MipmapBytes = mipmapBytesList; - } - - if (stream.Position < stream.Length) - { - // has PAGE data - var pageHeader = ReadPage(stream); - - textureFile.Pages = pageHeader; - } - - return textureFile; - } - - private static PageHeader ReadPage(Stream stream) - { - Span pageBytes = stackalloc byte[4]; - - stream.ReadExactly(pageBytes); - - var pageHeaderAscii = Encoding.ASCII.GetString(pageBytes); - - stream.ReadExactly(pageBytes); - - var pageCount = BinaryPrimitives.ReadInt32LittleEndian(pageBytes); - - List pageItems = []; - - Span itemBytes = stackalloc byte[2]; - for (int i = 0; i < pageCount; i++) - { - stream.ReadExactly(itemBytes); - var x = BinaryPrimitives.ReadInt16LittleEndian(itemBytes); - stream.ReadExactly(itemBytes); - var pageWidth = BinaryPrimitives.ReadInt16LittleEndian(itemBytes); - stream.ReadExactly(itemBytes); - var y = BinaryPrimitives.ReadInt16LittleEndian(itemBytes); - stream.ReadExactly(itemBytes); - var pageHeight = BinaryPrimitives.ReadInt16LittleEndian(itemBytes); - - pageItems.Add( - new PageItem( - x, - pageWidth, - y, - pageHeight - ) - ); - } - - var pageHeader = new PageHeader(pageHeaderAscii, pageCount, pageItems); - return pageHeader; - } - - private static List ReadMipmaps(Stream stream, int stride, int mipmapCount, int topWidth, int topHeight) - { - if (stride == 0) - { - stride = 16; - } - - List mipmapByteLengths = []; - - for (int i = 0; i < mipmapCount; i++) - { - var mipWidth = topWidth / (int) Math.Pow(2, i); - var mipHeight = topHeight / (int) Math.Pow(2, i); - - var imageByteLength = mipWidth * mipHeight * (stride / 8); - mipmapByteLengths.Add(imageByteLength); - } - - List mipmapBytesList = []; - - foreach (var mipmapByteLength in mipmapByteLengths) - { - var mipmapBuffer = new byte[mipmapByteLength]; - - stream.ReadExactly(mipmapBuffer, 0, mipmapByteLength); - - mipmapBytesList.Add(mipmapBuffer); - } - - return mipmapBytesList; - } - - private static List ReadMipmapsAsIndexes(Stream stream, int mipmapCount, int topWidth, int topHeight) - { - List mipmapByteLengths = []; - - for (int i = 0; i < mipmapCount; i++) - { - var mipWidth = topWidth / (int) Math.Pow(2, i); - var mipHeight = topHeight / (int) Math.Pow(2, i); - - var imageByteLength = mipWidth * mipHeight; - mipmapByteLengths.Add(imageByteLength); - } - - List mipmapBytesList = []; - - foreach (var mipmapByteLength in mipmapByteLengths) - { - var mipmapBuffer = new byte[mipmapByteLength]; - - stream.ReadExactly(mipmapBuffer, 0, mipmapByteLength); - - mipmapBytesList.Add(mipmapBuffer); - } - - return mipmapBytesList; - } - public async Task WriteToFolder(string folder) { if (Directory.Exists(folder)) diff --git a/TexmLib/TexmLib.csproj b/TexmLib/TexmLib.csproj new file mode 100644 index 0000000..a1fcf00 --- /dev/null +++ b/TexmLib/TexmLib.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/TexmLib/TexmParser.cs b/TexmLib/TexmParser.cs new file mode 100644 index 0000000..f79648e --- /dev/null +++ b/TexmLib/TexmParser.cs @@ -0,0 +1,201 @@ +using System.Buffers.Binary; +using System.Text; + +namespace TexmLib; + +public class TexmParser +{ + public static TexmParseResult ReadFromStream(Stream stream, string file) + { + if (stream.Length < 32) + { + return new TexmParseResult(null, "Файл короче 32 байт - точно не текстура"); + } + + Span headerBytes = stackalloc byte[32]; + stream.ReadExactly(headerBytes); + + var texmHeader = headerBytes[0..4]; + + var widthBytes = headerBytes[4..8]; + var heightBytes = headerBytes[8..12]; + var mipmapCountBytes = headerBytes[12..16]; + var strideBytes = headerBytes[16..20]; + var magic1Bytes = headerBytes[20..24]; + var magic2Bytes = headerBytes[24..28]; + var formatBytes = headerBytes[28..32]; + + var texmAscii = Encoding.ASCII.GetString(texmHeader).Trim('\0'); + var width = BinaryPrimitives.ReadInt32LittleEndian(widthBytes); + var height = BinaryPrimitives.ReadInt32LittleEndian(heightBytes); + var mipmapCount = BinaryPrimitives.ReadInt32LittleEndian(mipmapCountBytes); + var stride = BinaryPrimitives.ReadInt32LittleEndian(strideBytes); + var magic1 = BinaryPrimitives.ReadInt32LittleEndian(magic1Bytes); + var magic2 = BinaryPrimitives.ReadInt32LittleEndian(magic2Bytes); + var format = BinaryPrimitives.ReadInt32LittleEndian(formatBytes); + + if (texmAscii != "Texm") + { + return new TexmParseResult(null, "Файл не начинается с Texm"); + } + + var textureFile = new TexmFile() + { + FileName = file + }; + + var header = new TexmHeader( + texmAscii, + width, + height, + mipmapCount, + stride, + magic1, + magic2, + format + ); + + textureFile.Header = header; + + if (format == 0) + { + // если формат 0, то текстура использует lookup таблицу в первых 1024 байтах (256 разных цветов в формате ARGB 888) + + var lookupColors = new byte[1024]; + stream.ReadExactly(lookupColors, 0, lookupColors.Length); + + textureFile.LookupColors = lookupColors; + + var mipmapBytesList = ReadMipmapsAsIndexes( + stream, + mipmapCount, + width, + height + ); + + textureFile.MipmapBytes = mipmapBytesList; + textureFile.IsIndexed = true; + } + else + { + var mipmapBytesList = ReadMipmaps( + stream, + format.AsStride(), + mipmapCount, + width, + height + ); + + textureFile.MipmapBytes = mipmapBytesList; + } + + if (stream.Position < stream.Length) + { + // has PAGE data + var pageHeader = ReadPage(stream); + + textureFile.Pages = pageHeader; + } + + return new TexmParseResult(textureFile); + } + + private static PageHeader ReadPage(Stream stream) + { + Span pageBytes = stackalloc byte[4]; + + stream.ReadExactly(pageBytes); + + var pageHeaderAscii = Encoding.ASCII.GetString(pageBytes); + + stream.ReadExactly(pageBytes); + + var pageCount = BinaryPrimitives.ReadInt32LittleEndian(pageBytes); + + List pageItems = []; + + Span itemBytes = stackalloc byte[2]; + for (int i = 0; i < pageCount; i++) + { + stream.ReadExactly(itemBytes); + var x = BinaryPrimitives.ReadInt16LittleEndian(itemBytes); + stream.ReadExactly(itemBytes); + var pageWidth = BinaryPrimitives.ReadInt16LittleEndian(itemBytes); + stream.ReadExactly(itemBytes); + var y = BinaryPrimitives.ReadInt16LittleEndian(itemBytes); + stream.ReadExactly(itemBytes); + var pageHeight = BinaryPrimitives.ReadInt16LittleEndian(itemBytes); + + pageItems.Add( + new PageItem( + x, + pageWidth, + y, + pageHeight + ) + ); + } + + var pageHeader = new PageHeader(pageHeaderAscii, pageCount, pageItems); + return pageHeader; + } + + private static List ReadMipmaps(Stream stream, int stride, int mipmapCount, int topWidth, int topHeight) + { + if (stride == 0) + { + stride = 16; + } + + List mipmapByteLengths = []; + + for (int i = 0; i < mipmapCount; i++) + { + var mipWidth = topWidth / (int) Math.Pow(2, i); + var mipHeight = topHeight / (int) Math.Pow(2, i); + + var imageByteLength = mipWidth * mipHeight * (stride / 8); + mipmapByteLengths.Add(imageByteLength); + } + + List mipmapBytesList = []; + + foreach (var mipmapByteLength in mipmapByteLengths) + { + var mipmapBuffer = new byte[mipmapByteLength]; + + stream.ReadExactly(mipmapBuffer, 0, mipmapByteLength); + + mipmapBytesList.Add(mipmapBuffer); + } + + return mipmapBytesList; + } + + private static List ReadMipmapsAsIndexes(Stream stream, int mipmapCount, int topWidth, int topHeight) + { + List mipmapByteLengths = []; + + for (int i = 0; i < mipmapCount; i++) + { + var mipWidth = topWidth / (int) Math.Pow(2, i); + var mipHeight = topHeight / (int) Math.Pow(2, i); + + var imageByteLength = mipWidth * mipHeight; + mipmapByteLengths.Add(imageByteLength); + } + + List mipmapBytesList = []; + + foreach (var mipmapByteLength in mipmapByteLengths) + { + var mipmapBuffer = new byte[mipmapByteLength]; + + stream.ReadExactly(mipmapBuffer, 0, mipmapByteLength); + + mipmapBytesList.Add(mipmapBuffer); + } + + return mipmapBytesList; + } +} \ No newline at end of file diff --git a/TextureDecoder/Program.cs b/TextureDecoder/Program.cs index 5b8c0f3..97eba84 100644 --- a/TextureDecoder/Program.cs +++ b/TextureDecoder/Program.cs @@ -1,13 +1,13 @@ using System.Buffers.Binary; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; -using TextureDecoder; +using TexmLib; var folder = "C:\\Projects\\CSharp\\ParkanPlayground\\ParkanPlayground\\bin\\Debug\\net8.0\\ui.lib"; var files = Directory.EnumerateFiles(folder); -List textureFiles = []; +List textureFiles = []; foreach (var file in files) { @@ -15,9 +15,9 @@ foreach (var file in files) { var fs = new FileStream(file, FileMode.Open); - var textureFile = TextureFile.ReadFromStream(fs, file); + var parseResult = TexmParser.ReadFromStream(fs, file); - textureFiles.Add(textureFile); + textureFiles.Add(parseResult.TexmFile); Console.WriteLine($"Successfully read: {file}"); } diff --git a/TextureDecoder/TextureDecoder.csproj b/TextureDecoder/TextureDecoder.csproj index 1e43a53..50c9527 100644 --- a/TextureDecoder/TextureDecoder.csproj +++ b/TextureDecoder/TextureDecoder.csproj @@ -11,4 +11,12 @@ + + + + + + + +