summaryrefslogtreecommitdiff
path: root/NW4RTools
diff options
context:
space:
mode:
authorTreeki <treeki@gmail.com>2011-02-28 03:23:02 +0100
committerTreeki <treeki@gmail.com>2011-02-28 03:23:02 +0100
commit6b14bc71cb699b72ca6cf164b7b800add414dec6 (patch)
tree414bc20c8af5ae1373a4a15ddaaf2f706e3cb75f /NW4RTools
parent00e977b3dbb8f447b034b7be387ee1a1cce0598c (diff)
downloadnw4rtools-6b14bc71cb699b72ca6cf164b7b800add414dec6.tar.gz
nw4rtools-6b14bc71cb699b72ca6cf164b7b800add414dec6.zip
progress on writing: offset calculation for models and textures complete!
Diffstat (limited to 'NW4RTools')
-rw-r--r--NW4RTools/BrresReader.cs41
-rw-r--r--NW4RTools/BrresWriter.cs367
-rw-r--r--NW4RTools/Models/Animation/TextureSRT.cs8
-rw-r--r--NW4RTools/Models/OpenGL/GLTexture.cs10
-rw-r--r--NW4RTools/Models/Shape.cs1
-rw-r--r--NW4RTools/NW4RTools.csproj2
-rw-r--r--NW4RTools/NW4RTools.pidbbin545355 -> 546082 bytes
-rw-r--r--NW4RTools/Texture.cs24
-rwxr-xr-xNW4RTools/bin/Debug/NW4RTools.dllbin181760 -> 189952 bytes
-rw-r--r--NW4RTools/bin/Debug/NW4RTools.dll.mdbbin95922 -> 97520 bytes
10 files changed, 434 insertions, 19 deletions
diff --git a/NW4RTools/BrresReader.cs b/NW4RTools/BrresReader.cs
index 518096d..db5d7c2 100644
--- a/NW4RTools/BrresReader.cs
+++ b/NW4RTools/BrresReader.cs
@@ -67,6 +67,9 @@ namespace NW4RTools {
case "Textures(NW4R)":
File.Add(name, ReadAndConvertDict<Texture>(ins, ConvertTextureResource));
break;
+ case "AnmTexSrt(NW4R)":
+ File.Add(name, ReadAndConvertDict<Models.Animation.TextureSRT>(ins, ConvertAnmTexSRTResource));
+ break;
default:
Debug.Send("Not implemented");
return;
@@ -101,13 +104,20 @@ namespace NW4RTools {
Int16 height = ins.ReadInt16();
TextureFormat format = (TextureFormat)ins.ReadUInt32();
- tex.MipMapCount = ins.ReadUInt32();
+ int mipmapCount = ins.ReadInt32();
tex.MinLOD = ins.ReadFloat();
tex.MaxLOD = ins.ReadFloat();
ins.Seek(startPos + dataOffset);
- OffsetMap.Add(ins.Position, String.Format("Texture Data for: {0} [{1}, {2}x{3}]", name, format, width, height));
- tex.ImportData(ins.ReadBytes(Texture.GetDataSize(width, height, format)), width, height, format);
+ OffsetMap.Add(ins.Position, String.Format("Texture Data for: {0} [{1}, {2}x{3}, {4} mipmaps]", name, format, width, height, mipmapCount));
+
+ // handle mipmaps
+ tex.Images = new System.Drawing.Bitmap[mipmapCount];
+ for (int i = 0; i < mipmapCount; i++) {
+ tex.ImportData(i, ins.ReadBytes(Texture.GetDataSize(width, height, format)), width, height, format);
+ width /= 2;
+ height /= 2;
+ }
return tex;
}
@@ -115,6 +125,22 @@ namespace NW4RTools {
+ private Models.Animation.TextureSRT ConvertAnmTexSRTResource(string name, InputStream ins) {
+ using (var c = Debug.Push(name)) {
+ var anim = new Models.Animation.TextureSRT();
+
+ int startPos = ins.Position;
+
+ OffsetMap.Add(startPos, "Texture SRT Animation: " + name);
+
+ // TODO
+
+ return anim;
+ }
+ }
+
+
+
private Model ConvertModelResource(string name, InputStream ins) {
using (var c = Debug.Push(name)) {
Model mdl = new Model();
@@ -167,6 +193,7 @@ namespace NW4RTools {
ins.Seek(infoStructPos + mtxDataOffset);
+ OffsetMap.Add(ins.Position, "Matrix ID to Node ID Data for: " + name);
UInt32 mtxDataCount = ins.ReadUInt32();
mdl.MatrixIDtoNodeID = new int[mtxDataCount];
@@ -450,6 +477,8 @@ namespace NW4RTools {
n.RawData = ins.ReadBytes(n.EntrySize * n.EntryCount);
n.Parse();
+ OffsetMap.Add(startPos + dataOffset, n.GetType().ToString() + " Data");
+
ins.Seek(structEndPos);
}
@@ -721,21 +750,23 @@ namespace NW4RTools {
int dlBase1 = ins.Position;
// 0x18
- UInt32 bufferSize1 = ins.ReadUInt32();
+ s.DLBufferSize1 = ins.ReadUInt32();
// 0x1C
UInt32 dataSize1 = ins.ReadUInt32();
// 0x20
Int32 offset1 = ins.ReadInt32();
s.DisplayList1 = ins.At(dlBase1 + offset1).ReadBytes((int)dataSize1);
+ OffsetMap.Add(dlBase1 + offset1, String.Format("Shape DL 1: {0} [Buffer Size: 0x{1:X}; Data Size: 0x{2:X}]", name, s.DLBufferSize1, dataSize1));
int dlBase2 = ins.Position;
// 0x24
- UInt32 bufferSize2 = ins.ReadUInt32();
+ s.DLBufferSize2 = ins.ReadUInt32();
// 0x28
UInt32 dataSize2 = ins.ReadUInt32();
// 0x2C
Int32 offset2 = ins.ReadInt32();
s.DisplayList2 = ins.At(dlBase2 + offset2).ReadBytes((int)dataSize2);
+ OffsetMap.Add(dlBase2 + offset2, String.Format("Shape DL 2: {0} [Buffer Size: 0x{1:X}; Data Size: 0x{2:X}]", name, s.DLBufferSize2, dataSize2));
// 0x30
s.DataFlags = ins.ReadUInt32();
diff --git a/NW4RTools/BrresWriter.cs b/NW4RTools/BrresWriter.cs
index 5590ab5..1b103fc 100644
--- a/NW4RTools/BrresWriter.cs
+++ b/NW4RTools/BrresWriter.cs
@@ -31,6 +31,12 @@ namespace NW4RTools {
Output.WriteBytes(StringTableData.GetBuffer());
+ using (var c = Debug.Push("Offset Map")) {
+ foreach (var e in OffsetMap) {
+ Debug.Send("0x{0:X} : {1}", e.Key, e.Value);
+ }
+ }
+
return Output.GetBuffer();
}
@@ -38,6 +44,24 @@ namespace NW4RTools {
// each written element, and use that to build up a list of offsets. Then, I'll actually write out the data.
// This code will also handle building the string table.
+ #region Offset Data Storage
+ private Dictionary<Model, int> ModelOffsets;
+ private Dictionary<ByteCode, int> BytecodeOffsets;
+ private Dictionary<Node, int> NodeOffsets;
+ private Dictionary<VertexPosData, int> VtxPosOffsets;
+ private Dictionary<VertexNrmData, int> VtxNrmOffsets;
+ private Dictionary<VertexClrData, int> VtxClrOffsets;
+ private Dictionary<VertexTexCoordData, int> VtxTexCoordOffsets;
+ private Dictionary<Material, int> MaterialOffsets;
+ private Dictionary<Shader, int> ShaderOffsets;
+ private Dictionary<Shape, int> ShapeOffsets;
+ private Dictionary<List<TexMatPairing>, int> PairingOffsets;
+
+ private Dictionary<Texture, int> TextureOffsets;
+ private Dictionary<Texture, int> TextureDataOffsets;
+
+ #endregion
+
#region Offset/String Table Calculation
private int CurrentPos;
@@ -50,11 +74,13 @@ namespace NW4RTools {
// First block, and ResDict
CurrentPos += 8;
- CurrentPos += GetSizeForResDict(File);
+ CurrentPos += GetSizeForResDict(File.Count);
// Now do each ResDict in the File
foreach (object dict in File.Values) {
- CurrentPos += GetSizeForResDict(dict as ResDict<object>);
+ // yay stupid hack
+ OffsetMap.Add(CurrentPos, "ResDict: " + dict.GetType().GetGenericArguments()[0].ToString());
+ CurrentPos += GetSizeForResDict((dict as ICollection).Count);
}
// OK, so that's done. Process each type
@@ -62,7 +88,10 @@ namespace NW4RTools {
AddString(name);
switch (name) {
case "3DModels(NW4R)":
- // do that stuff
+ CalculateModels();
+ break;
+ case "Textures(NW4R)":
+ CalculateTextures();
break;
default:
Debug.Send("[[ UNIMPLEMENTED {0} ]]", name);
@@ -74,9 +103,337 @@ namespace NW4RTools {
CalculateStringTable();
}
+ #region Model Calculation
+ private void CalculateModels() {
+ ModelOffsets = new Dictionary<Model, int>();
+ BytecodeOffsets = new Dictionary<ByteCode, int>();
+ NodeOffsets = new Dictionary<Node, int>();
+ VtxPosOffsets = new Dictionary<VertexPosData, int>();
+ VtxNrmOffsets = new Dictionary<VertexNrmData, int>();
+ VtxClrOffsets = new Dictionary<VertexClrData, int>();
+ VtxTexCoordOffsets = new Dictionary<VertexTexCoordData, int>();
+ MaterialOffsets = new Dictionary<Material, int>();
+ ShaderOffsets = new Dictionary<Shader, int>();
+ ShapeOffsets = new Dictionary<Shape, int>();
+ PairingOffsets = new Dictionary<List<TexMatPairing>, int>();
+
+
+ var modelDict = File.GetGroup<Model>("3DModels(NW4R)");
+
+ foreach (var kv in modelDict) {
+ AddString(kv.Key);
+ AlignCalcPos(0x20);
+ // 0x40? dunno
+ Model model = kv.Value;
+
+ OffsetMap.Add(CurrentPos, "Model: " + kv.Key);
+ CurrentPos += 0x4C;
+ OffsetMap.Add(CurrentPos, "Model Info Struct for: " + kv.Key);
+ CurrentPos += 0x40;
+
+ OffsetMap.Add(CurrentPos, "Matrix ID to Node ID Data for: " + kv.Key);
+ CurrentPos += 4 + (model.MatrixIDtoNodeID.Length * 4);
+
+
+ OffsetMap.Add(CurrentPos, "ResDict: ByteCode");
+ CurrentPos += GetSizeForResDict(model.Bytecode.Count);
+ OffsetMap.Add(CurrentPos, "ResDict: Nodes");
+ CurrentPos += GetSizeForResDict(model.Nodes.Count);
+ OffsetMap.Add(CurrentPos, "ResDict: VertexPosData");
+ CurrentPos += GetSizeForResDict(model.VtxPosData.Count);
+
+ if (model.VtxNrmData.Count > 0) {
+ OffsetMap.Add(CurrentPos, "ResDict: VertexNrmData");
+ CurrentPos += GetSizeForResDict(model.VtxNrmData.Count);
+ }
+
+ if (model.VtxClrData.Count > 0) {
+ OffsetMap.Add(CurrentPos, "ResDict: VertexClrData");
+ CurrentPos += GetSizeForResDict(model.VtxClrData.Count);
+ }
+
+ if (model.VtxTexCoordData.Count > 0) {
+ OffsetMap.Add(CurrentPos, "ResDict: VertexTexCoordData");
+ CurrentPos += GetSizeForResDict(model.VtxTexCoordData.Count);
+ }
+
+ OffsetMap.Add(CurrentPos, "ResDict: Materials");
+ CurrentPos += GetSizeForResDict(model.Materials.Count);
+ OffsetMap.Add(CurrentPos, "ResDict: Shaders");
+ CurrentPos += GetSizeForResDict(model.Shaders.Count);
+ OffsetMap.Add(CurrentPos, "ResDict: Shapes");
+ CurrentPos += GetSizeForResDict(model.Shapes.Count);
+
+ if (model.PairingLookupByTexture.Count > 0) {
+ OffsetMap.Add(CurrentPos, "ResDict: Texture Lookup");
+ CurrentPos += GetSizeForResDict(model.PairingLookupByTexture.Count);
+ }
+
+ // todo: palette lookup, checking if dicts are empty or do not exist
+ // todo: can dicts even NOT exist? must find this out
+
+ CalculatePairings(model, model.PairingLookupByTexture);
+ CalculateBytecode(model);
+ CalculateNodes(model);
+ CalculateMaterials(model);
+ CalculateShaders(model);
+ CalculateShapes(model);
+ CalculateVtxPosData(model);
+ CalculateVtxNrmData(model);
+ CalculateVtxClrData(model);
+ CalculateVtxTexCoordData(model);
+ }
+ }
+
+ private void CalculatePairings(Model m, ResDict<List<TexMatPairing>> dict) {
+ foreach (var kv in dict) {
+ OffsetMap.Add(CurrentPos, "Texture/Material Pairing List for: " + kv.Key);
+ PairingOffsets.Add(kv.Value, CurrentPos);
+
+ CurrentPos += 4 + (kv.Value.Count * 8);
+ }
+ }
+
+ private void CalculateBytecode(Model m) {
+ foreach (var kv in m.Bytecode) {
+ AddString(kv.Key);
+ ByteCode bc = kv.Value;
+
+ OffsetMap.Add(CurrentPos, "ByteCode: " + kv.Key);
+ BytecodeOffsets.Add(kv.Value, CurrentPos);
+
+ foreach (var insn in bc.Instructions) {
+ switch (insn.GetOp()) {
+ case ByteCode.OpType.None:
+ CurrentPos += 1;
+ break;
+ case ByteCode.OpType.Done:
+ CurrentPos += 1;
+ break;
+ case ByteCode.OpType.AssignNodeToParentMtx:
+ CurrentPos += 5;
+ break;
+ case ByteCode.OpType.BlendMatrices:
+ CurrentPos += 4 + (6 * (insn as ByteCode.BlendMatricesInstruction).BlendedMatrices.Length);
+ break;
+ case ByteCode.OpType.DrawShape:
+ CurrentPos += 8;
+ break;
+ case ByteCode.OpType.AssignMtxToNode:
+ CurrentPos += 5;
+ break;
+ }
+ }
+ }
+
+ AlignCalcPos(4); // should be per-bytecode maybe?
+ }
+
+ private void CalculateNodes(Model m) {
+ foreach (var kv in m.Nodes) {
+ AddString(kv.Key);
+
+ OffsetMap.Add(CurrentPos, "Node: " + kv.Key);
+ NodeOffsets.Add(kv.Value, CurrentPos);
+
+ CurrentPos += 0xD0;
+ }
+ }
+
+ private void CalculateMaterials(Model m) {
+ foreach (var kv in m.Materials) {
+ AddString(kv.Key);
+
+ OffsetMap.Add(CurrentPos, "Material: " + kv.Key);
+ MaterialOffsets.Add(kv.Value, CurrentPos);
+
+ // Base material struct
+ CurrentPos += 0x14;
+
+ // ResGenMode
+ CurrentPos += 8;
+
+ // ResMatMode
+ CurrentPos += 0xC;
+
+ // other stuff
+ CurrentPos += 0x18;
+
+ // ResTexObj
+ CurrentPos += 0x104;
+
+ // ResTlutObj
+ CurrentPos += 0x64;
+
+ // ResTexSrt
+ CurrentPos += 8 + (0x14 * 8) + (0x34 * 8);
+
+ // ResMatChan
+ CurrentPos += 0x28;
+
+ // Texture Infos
+ if (kv.Value.TextureInfos.Count > 0)
+ OffsetMap.Add(CurrentPos, "Material Texture Infos: " + kv.Key);
+
+ CurrentPos += (kv.Value.TextureInfos.Count * 0x34);
+
+ // Display Lists
+ AlignCalcPos(0x20);
+ OffsetMap.Add(CurrentPos, "Material Display Lists: " + kv.Key);
+ CurrentPos += 0x20 + 0x80 + 0x40 + 0xA0;
+ }
+ }
+
+ private void CalculateShaders(Model m) {
+ foreach (var kv in m.Shaders) {
+ AddString(kv.Key);
+
+ OffsetMap.Add(CurrentPos, "Shader: " + kv.Key);
+ ShaderOffsets.Add(kv.Value, CurrentPos);
+
+ CurrentPos += 0x200;
+ }
+ }
+
+ private void CalculateShapes(Model m) {
+ foreach (var kv in m.Shapes) {
+ AddString(kv.Key);
+
+ OffsetMap.Add(CurrentPos, "Shape: " + kv.Key);
+ ShapeOffsets.Add(kv.Value, CurrentPos);
+
+ CurrentPos += 0x68;
+
+ AlignCalcPos(0x20);
+
+ OffsetMap.Add(CurrentPos, "Shape DL 1: " + kv.Key);
+ CurrentPos += (int)kv.Value.DLBufferSize1;
+ AlignCalcPos(0x20);
+
+ OffsetMap.Add(CurrentPos, "Shape DL 2: " + kv.Key);
+ CurrentPos += (int)kv.Value.DLBufferSize2;
+ AlignCalcPos(0x20);
+ }
+ }
+
+ private void CalculateVtxPosData(Model m) {
+ foreach (var kv in m.VtxPosData) {
+ AddString(kv.Key);
+
+ OffsetMap.Add(CurrentPos, "VertexPosData: " + kv.Key);
+ VtxPosOffsets.Add(kv.Value, CurrentPos);
+
+ // Main data
+ CurrentPos += 0x20;
+
+ // Minimum/maximum VEC3 (specific to VtxPosData)
+ CurrentPos += 0x18;
+
+ AlignCalcPos(0x20);
+ OffsetMap.Add(CurrentPos, "Data: " + kv.Key);
+ CurrentPos += kv.Value.EntryCount * kv.Value.EntrySize;
+ AlignCalcPos(0x20);
+ }
+ }
+
+ private void CalculateVtxNrmData(Model m) {
+ foreach (var kv in m.VtxNrmData) {
+ AddString(kv.Key);
+
+ OffsetMap.Add(CurrentPos, "VertexNrmData: " + kv.Key);
+ VtxNrmOffsets.Add(kv.Value, CurrentPos);
+
+ // Main data
+ CurrentPos += 0x20;
+
+ AlignCalcPos(0x20);
+ OffsetMap.Add(CurrentPos, "Data: " + kv.Key);
+ CurrentPos += kv.Value.EntryCount * kv.Value.EntrySize;
+ AlignCalcPos(0x20);
+ }
+ }
+
+ private void CalculateVtxClrData(Model m) {
+ foreach (var kv in m.VtxClrData) {
+ AddString(kv.Key);
+
+ OffsetMap.Add(CurrentPos, "VertexClrData: " + kv.Key);
+ VtxClrOffsets.Add(kv.Value, CurrentPos);
+
+ // Main data
+ CurrentPos += 0x20;
+
+ AlignCalcPos(0x20);
+ OffsetMap.Add(CurrentPos, "Data: " + kv.Key);
+ CurrentPos += kv.Value.EntryCount * kv.Value.EntrySize;
+ AlignCalcPos(0x20);
+ }
+ }
+
+ private void CalculateVtxTexCoordData(Model m) {
+ foreach (var kv in m.VtxTexCoordData) {
+ AddString(kv.Key);
+
+ OffsetMap.Add(CurrentPos, "VertexTexCoordData: " + kv.Key);
+ VtxTexCoordOffsets.Add(kv.Value, CurrentPos);
+
+ // Main data
+ CurrentPos += 0x20;
+
+ // Minimum/maximum VEC2 (specific to VtxTexCoordData)
+ CurrentPos += 0x10;
+
+ AlignCalcPos(0x20);
+ OffsetMap.Add(CurrentPos, "Data: " + kv.Key);
+ CurrentPos += kv.Value.EntryCount * kv.Value.EntrySize;
+ AlignCalcPos(0x20);
+ }
+ }
+ #endregion
+
+ #region Texture Calculation
+ private void CalculateTextures() {
+ TextureOffsets = new Dictionary<Texture, int>();
+ TextureDataOffsets = new Dictionary<Texture, int>();
+
+
+ var textureDict = File.GetGroup<Texture>("Textures(NW4R)");
+
+ foreach (var kv in textureDict) {
+ AddString(kv.Key);
+ AlignCalcPos(0x20);
+ Texture texture = kv.Value;
+
+ Debug.Send("Current: {0}", kv.Key);
+
+
+ OffsetMap.Add(CurrentPos, "Texture: " + kv.Key);
+ TextureOffsets.Add(kv.Value, CurrentPos);
+
+ CurrentPos += 0x30;
+ AlignCalcPos(0x20);
+
+
+ OffsetMap.Add(CurrentPos, "Texture Data for: " + kv.Key);
+ TextureDataOffsets.Add(kv.Value, CurrentPos);
+
+ CurrentPos += texture.GetDataSize();
+ AlignCalcPos(0x20);
+ }
+ }
+ #endregion
+
+
+
+ private void AlignCalcPos(int alignTo) {
+ if ((CurrentPos & (alignTo - 1)) == 0)
+ return;
+
+ CurrentPos += (alignTo - (CurrentPos & (alignTo - 1)));
+ }
- private int GetSizeForResDict(ResDict<object> dict) {
- return 8 + ((dict.Count + 1) * 0x10);
+ private int GetSizeForResDict(int entryCount) {
+ return 8 + ((entryCount + 1) * 0x10);
}
#endregion
diff --git a/NW4RTools/Models/Animation/TextureSRT.cs b/NW4RTools/Models/Animation/TextureSRT.cs
new file mode 100644
index 0000000..5c35905
--- /dev/null
+++ b/NW4RTools/Models/Animation/TextureSRT.cs
@@ -0,0 +1,8 @@
+using System;
+namespace NW4RTools.Models.Animation {
+ public class TextureSRT {
+ public TextureSRT() {
+ }
+ }
+}
+
diff --git a/NW4RTools/Models/OpenGL/GLTexture.cs b/NW4RTools/Models/OpenGL/GLTexture.cs
index c4cdee6..d56d6ca 100644
--- a/NW4RTools/Models/OpenGL/GLTexture.cs
+++ b/NW4RTools/Models/OpenGL/GLTexture.cs
@@ -26,16 +26,18 @@ namespace NW4RTools.Models.OpenGL {
//byte[] pixelData = new byte[tex.BaseImage.Width * tex.BaseImage.Height * 4];
- var lb = tex.BaseImage.LockBits(
- new System.Drawing.Rectangle(0, 0, tex.BaseImage.Width, tex.BaseImage.Height),
+ // TODO: mipmaps
+
+ var lb = tex.Images[0].LockBits(
+ new System.Drawing.Rectangle(0, 0, tex.Images[0].Width, tex.Images[0].Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Four,
- tex.BaseImage.Width, tex.BaseImage.Height, 0,
+ tex.Images[0].Width, tex.Images[0].Height, 0,
PixelFormat.Bgra, PixelType.UnsignedByte, lb.Scan0);
- tex.BaseImage.UnlockBits(lb);
+ tex.Images[0].UnlockBits(lb);
}
public void Bind(TextureTarget target) {
diff --git a/NW4RTools/Models/Shape.cs b/NW4RTools/Models/Shape.cs
index 88d6670..6bc7e44 100644
--- a/NW4RTools/Models/Shape.cs
+++ b/NW4RTools/Models/Shape.cs
@@ -5,6 +5,7 @@ namespace NW4RTools.Models {
public Int32 MatrixID;
public byte[] Unk;
public byte[] DisplayList1, DisplayList2;
+ public UInt32 DLBufferSize1, DLBufferSize2;
public UInt32 DataFlags;
public UInt32 Flags;
public UInt32 Index;
diff --git a/NW4RTools/NW4RTools.csproj b/NW4RTools/NW4RTools.csproj
index 3afef3b..493cc46 100644
--- a/NW4RTools/NW4RTools.csproj
+++ b/NW4RTools/NW4RTools.csproj
@@ -72,12 +72,14 @@
<Compile Include="Models\OpenGL\GLDisplayList.cs" />
<Compile Include="BrresWriter.cs" />
<Compile Include="OutputStream.cs" />
+ <Compile Include="Models\Animation\TextureSRT.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<Folder Include="Models\" />
<Folder Include="Util\" />
<Folder Include="Models\OpenGL\" />
+ <Folder Include="Models\Animation\" />
</ItemGroup>
<ItemGroup>
<None Include="OpenTK.dll.config">
diff --git a/NW4RTools/NW4RTools.pidb b/NW4RTools/NW4RTools.pidb
index 317dedf..7330f88 100644
--- a/NW4RTools/NW4RTools.pidb
+++ b/NW4RTools/NW4RTools.pidb
Binary files differ
diff --git a/NW4RTools/Texture.cs b/NW4RTools/Texture.cs
index 7063056..0561435 100644
--- a/NW4RTools/Texture.cs
+++ b/NW4RTools/Texture.cs
@@ -64,10 +64,9 @@ namespace NW4RTools {
- public Bitmap BaseImage;
+ public Bitmap[] Images;
public TextureFormat Format;
- public UInt32 MipMapCount;
public float MinLOD, MaxLOD;
public Texture() {
@@ -82,11 +81,26 @@ namespace NW4RTools {
// align width, height up
width = Misc.AlignUp(width, info.TexelWidth);
height = Misc.AlignUp(height, info.TexelHeight);
-
+
+ // SPECIAL CASE:
+
return width * height * info.NybblesPerPixel / 2;
}
- unsafe public void ImportData(byte[] imgdata, int width, int height, TextureFormat format) {
+
+ public int GetDataSize() {
+ int size = 0;
+ for (int i = 0; i < Images.Length; i++) {
+ size += GetDataSize(i);
+ }
+ return size;
+ }
+
+ public int GetDataSize(int imageID) {
+ return GetDataSize(Images[imageID].Width, Images[imageID].Height, Format);
+ }
+
+ unsafe public void ImportData(int imageID, byte[] imgdata, int width, int height, TextureFormat format) {
var image = new Bitmap(width, height, PixelFormat.Format32bppArgb);
var bits = image.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, image.PixelFormat);
@@ -274,7 +288,7 @@ namespace NW4RTools {
image.UnlockBits(bits);
- BaseImage = image;
+ Images[imageID] = image;
Format = format;
}
diff --git a/NW4RTools/bin/Debug/NW4RTools.dll b/NW4RTools/bin/Debug/NW4RTools.dll
index 3962f15..13eb22e 100755
--- a/NW4RTools/bin/Debug/NW4RTools.dll
+++ b/NW4RTools/bin/Debug/NW4RTools.dll
Binary files differ
diff --git a/NW4RTools/bin/Debug/NW4RTools.dll.mdb b/NW4RTools/bin/Debug/NW4RTools.dll.mdb
index f5f1318..a2acbbc 100644
--- a/NW4RTools/bin/Debug/NW4RTools.dll.mdb
+++ b/NW4RTools/bin/Debug/NW4RTools.dll.mdb
Binary files differ