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 @@
+
+
+
+
+
+
+
+