diff options
author | Treeki <treeki@gmail.com> | 2011-02-28 03:23:02 +0100 |
---|---|---|
committer | Treeki <treeki@gmail.com> | 2011-02-28 03:23:02 +0100 |
commit | 6b14bc71cb699b72ca6cf164b7b800add414dec6 (patch) | |
tree | 414bc20c8af5ae1373a4a15ddaaf2f706e3cb75f /NW4RTools | |
parent | 00e977b3dbb8f447b034b7be387ee1a1cce0598c (diff) | |
download | nw4rtools-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.cs | 41 | ||||
-rw-r--r-- | NW4RTools/BrresWriter.cs | 367 | ||||
-rw-r--r-- | NW4RTools/Models/Animation/TextureSRT.cs | 8 | ||||
-rw-r--r-- | NW4RTools/Models/OpenGL/GLTexture.cs | 10 | ||||
-rw-r--r-- | NW4RTools/Models/Shape.cs | 1 | ||||
-rw-r--r-- | NW4RTools/NW4RTools.csproj | 2 | ||||
-rw-r--r-- | NW4RTools/NW4RTools.pidb | bin | 545355 -> 546082 bytes | |||
-rw-r--r-- | NW4RTools/Texture.cs | 24 | ||||
-rwxr-xr-x | NW4RTools/bin/Debug/NW4RTools.dll | bin | 181760 -> 189952 bytes | |||
-rw-r--r-- | NW4RTools/bin/Debug/NW4RTools.dll.mdb | bin | 95922 -> 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 Binary files differindex 317dedf..7330f88 100644 --- a/NW4RTools/NW4RTools.pidb +++ b/NW4RTools/NW4RTools.pidb 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 Binary files differindex 3962f15..13eb22e 100755 --- a/NW4RTools/bin/Debug/NW4RTools.dll +++ b/NW4RTools/bin/Debug/NW4RTools.dll diff --git a/NW4RTools/bin/Debug/NW4RTools.dll.mdb b/NW4RTools/bin/Debug/NW4RTools.dll.mdb Binary files differindex f5f1318..a2acbbc 100644 --- a/NW4RTools/bin/Debug/NW4RTools.dll.mdb +++ b/NW4RTools/bin/Debug/NW4RTools.dll.mdb |