summaryrefslogtreecommitdiff
path: root/NW4RTools
diff options
context:
space:
mode:
authorTreeki <treeki@gmail.com>2011-02-25 22:08:57 +0100
committerTreeki <treeki@gmail.com>2011-02-25 22:08:57 +0100
commit00e977b3dbb8f447b034b7be387ee1a1cce0598c (patch)
tree1a3e0c837d23b90c332e5e1dc4707607c19e7ebd /NW4RTools
parent1d5fa5585f08dd82a6722af3dd8ab360fd161151 (diff)
downloadnw4rtools-00e977b3dbb8f447b034b7be387ee1a1cce0598c.tar.gz
nw4rtools-00e977b3dbb8f447b034b7be387ee1a1cce0598c.zip
start of a brres writer
Diffstat (limited to '')
-rw-r--r--NW4RTools.userprefs21
-rw-r--r--NW4RTools/BrresReader.cs11
-rw-r--r--NW4RTools/BrresWriter.cs121
-rw-r--r--NW4RTools/Models/OpenGL/GLModel.cs14
-rw-r--r--NW4RTools/NW4RTools.csproj2
-rw-r--r--NW4RTools/NW4RTools.pidbbin541003 -> 545355 bytes
-rw-r--r--NW4RTools/OutputStream.cs131
-rwxr-xr-xNW4RTools/bin/Debug/NW4RTools.dllbin175616 -> 181760 bytes
-rw-r--r--NW4RTools/bin/Debug/NW4RTools.dll.mdbbin94193 -> 95922 bytes
9 files changed, 276 insertions, 24 deletions
diff --git a/NW4RTools.userprefs b/NW4RTools.userprefs
index facc6fe..b885128 100644
--- a/NW4RTools.userprefs
+++ b/NW4RTools.userprefs
@@ -1,23 +1,10 @@
<Properties>
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
- <MonoDevelop.Ide.Workbench ActiveDocument="NW4RTools/Models/OpenGL/GLModel.cs">
+ <MonoDevelop.Ide.Workbench ActiveDocument="NW4RTools/BrresWriter.cs">
<Files>
- <File FileName="TestApp/Main.cs" Line="14" Column="6" />
- <File FileName="NW4RTools/BrresReader.cs" Line="163" Column="17" />
- <File FileName="NW4RTools/Enums.cs" Line="20" Column="29" />
- <File FileName="NW4RTools/ColladaWriter.cs" Line="147" Column="1" />
- <File FileName="NW4RTools/Models/Node.cs" Line="27" Column="1" />
- <File FileName="NW4RTools/Models/Material.cs" Line="1" Column="1" />
- <File FileName="NW4RTools/Texture.cs" Line="263" Column="8" />
- <File FileName="NW4RTools/Models/VertexData.cs" Line="121" Column="32" />
- <File FileName="TestApp/RenderWindow.cs" Line="48" Column="82" />
- <File FileName="NW4RTools/Models/OpenGL/GLModel.cs" Line="310" Column="83" />
- <File FileName="NW4RTools/VertexSettings.cs" Line="187" Column="1" />
- <File FileName="NW4RTools/Util/OrderedDictionary.cs" Line="176" Column="24" />
- <File FileName="NW4RTools/Util/IOrderedDictionary.cs" Line="62" Column="38" />
- <File FileName="NW4RTools/Models/OpenGL/GLTexture.cs" Line="15" Column="1" />
- <File FileName="NW4RTools/Models/ByteCode.cs" Line="40" Column="18" />
- <File FileName="NW4RTools/Models/TextureInfo.cs" Line="1" Column="1" />
+ <File FileName="NW4RTools/BrresReader.cs" Line="49" Column="1" />
+ <File FileName="NW4RTools/BrresWriter.cs" Line="60" Column="6" />
+ <File FileName="TestApp/Main.cs" Line="29" Column="18" />
</Files>
</MonoDevelop.Ide.Workbench>
<MonoDevelop.Ide.DebuggingService.Breakpoints>
diff --git a/NW4RTools/BrresReader.cs b/NW4RTools/BrresReader.cs
index 8b48ef3..518096d 100644
--- a/NW4RTools/BrresReader.cs
+++ b/NW4RTools/BrresReader.cs
@@ -44,7 +44,7 @@ namespace NW4RTools {
UInt32 blkSize = ins.ReadUInt32();
using (var c = Debug.Push("Root Dictionary")) {
- ReadAndParseDict(ins, ParseRootEntry);
+ ReadAndParseDict(ins, ParseRootEntry, "Root Dictionary");
}
@@ -248,8 +248,13 @@ namespace NW4RTools {
using (var c2 = Debug.Push("Shapes"))
mdl.Shapes = ReadAndConvertDict<Shape>(ins.At(startPos + shapeOffset), ConvertModelShape);
- using (var c2 = Debug.Push("Texture Lookup for Texture Info/Material Pairing"))
- mdl.PairingLookupByTexture = ReadAndConvertDict<List<TexMatPairing>>(ins.At(startPos + textureOffset), ConvertPairingList);
+ if (textureOffset != 0) {
+ using (var c2 = Debug.Push("Texture Lookup for Texture Info/Material Pairing"))
+ mdl.PairingLookupByTexture = ReadAndConvertDict<List<TexMatPairing>>(ins.At(startPos + textureOffset), ConvertPairingList);
+ } else {
+ mdl.PairingLookupByTexture = new ResDict<List<TexMatPairing>>();
+ Debug.Send("Texture Lookup for Texture Info/Material Pairing: none");
+ }
if (paletteOffset != 0) {
using (var c2 = Debug.Push("Palette Lookup for Texture Info/Material Pairing"))
diff --git a/NW4RTools/BrresWriter.cs b/NW4RTools/BrresWriter.cs
new file mode 100644
index 0000000..5590ab5
--- /dev/null
+++ b/NW4RTools/BrresWriter.cs
@@ -0,0 +1,121 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+using NW4RTools.Models;
+
+namespace NW4RTools {
+ public class BrresWriter {
+ public static byte[] WriteFile(ResFile file) {
+ return new BrresWriter().Save(file);
+ }
+
+
+
+ private ResFile File;
+ private ILogger Debug;
+ private SortedDictionary<int, string> OffsetMap;
+ private OutputStream Output;
+
+ private BrresWriter() {
+ Debug = new ConsoleLogger();
+ OffsetMap = new SortedDictionary<int, string>();
+ }
+
+ private byte[] Save(ResFile file) {
+ Output = new OutputStream(ByteEndian.BigEndian);
+ File = file;
+
+ using (var c = Debug.Push("Offset Calculation"))
+ CalculateRoot();
+
+ Output.WriteBytes(StringTableData.GetBuffer());
+
+ return Output.GetBuffer();
+ }
+
+ // OK, here's how I'm going to code this: kinda like how BrawlLib works, first I'll calculate the size of
+ // 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/String Table Calculation
+ private int CurrentPos;
+
+ private void CalculateRoot() {
+ // Where it all starts!
+ InitialiseStringTable();
+
+ // First up: BRRES header
+ CurrentPos = 0x10;
+
+ // First block, and ResDict
+ CurrentPos += 8;
+ CurrentPos += GetSizeForResDict(File);
+
+ // Now do each ResDict in the File
+ foreach (object dict in File.Values) {
+ CurrentPos += GetSizeForResDict(dict as ResDict<object>);
+ }
+
+ // OK, so that's done. Process each type
+ foreach (var name in File.Keys) {
+ AddString(name);
+ switch (name) {
+ case "3DModels(NW4R)":
+ // do that stuff
+ break;
+ default:
+ Debug.Send("[[ UNIMPLEMENTED {0} ]]", name);
+ break;
+ }
+ }
+
+ // ... and done with that. Build the string table and go!
+ CalculateStringTable();
+ }
+
+
+ private int GetSizeForResDict(ResDict<object> dict) {
+ return 8 + ((dict.Count + 1) * 0x10);
+ }
+
+ #endregion
+
+ #region String Table Handling
+ // Contains the strings while they're being pulled from the ResFile data
+ private List<string> StringTable;
+
+ // Once every string used in the .brres is found, CalculateStringTable() is called, which
+ // writes the table to an OutputStream and saves every offset
+ private Dictionary<string, int> StringTableOffsets;
+
+ private OutputStream StringTableData;
+
+
+ // Called at the start of the process
+ private void InitialiseStringTable() {
+ StringTable = new List<string>();
+ }
+
+ private void AddString(string str) {
+ if (!StringTable.Contains(str)) {
+ StringTable.Add(str);
+ }
+ }
+
+ private void CalculateStringTable() {
+ StringTable.Sort();
+
+ StringTableOffsets = new Dictionary<string, int>();
+ StringTableData = new OutputStream(ByteEndian.BigEndian);
+
+ foreach (var s in StringTable) {
+ // Add 4 because the Names are referenced by the string data, and not by the ResName struct itself
+ StringTableOffsets[s] = StringTableData.Position + 4;
+ StringTableData.WriteName(s);
+ }
+ }
+ #endregion
+ }
+}
+
diff --git a/NW4RTools/Models/OpenGL/GLModel.cs b/NW4RTools/Models/OpenGL/GLModel.cs
index 315415e..8ca3f31 100644
--- a/NW4RTools/Models/OpenGL/GLModel.cs
+++ b/NW4RTools/Models/OpenGL/GLModel.cs
@@ -17,7 +17,11 @@ namespace NW4RTools.Models.OpenGL {
SourceModel = rf.GetGroup<Model>("3DModels(NW4R)")[modelName];
// cache some stuff
- m_textureGroup = rf.GetGroup<Texture>("Textures(NW4R)");
+ try {
+ m_textureGroup = rf.GetGroup<Texture>("Textures(NW4R)");
+ } catch (KeyNotFoundException) {
+ // boo
+ }
}
@@ -162,9 +166,11 @@ namespace NW4RTools.Models.OpenGL {
//CalculateNodes();
- foreach (var insn in SourceModel.Bytecode["DrawOpa"].Instructions) {
- if (insn is ByteCode.DrawShapeInstruction) {
- DrawShape(insn as ByteCode.DrawShapeInstruction);
+ if (SourceModel.Bytecode.ContainsKey("DrawOpa")) {
+ foreach (var insn in SourceModel.Bytecode["DrawOpa"].Instructions) {
+ if (insn is ByteCode.DrawShapeInstruction) {
+ DrawShape(insn as ByteCode.DrawShapeInstruction);
+ }
}
}
diff --git a/NW4RTools/NW4RTools.csproj b/NW4RTools/NW4RTools.csproj
index e1da0e8..3afef3b 100644
--- a/NW4RTools/NW4RTools.csproj
+++ b/NW4RTools/NW4RTools.csproj
@@ -70,6 +70,8 @@
<Compile Include="Models\OpenGL\GLModel.cs" />
<Compile Include="Models\OpenGL\GLTexture.cs" />
<Compile Include="Models\OpenGL\GLDisplayList.cs" />
+ <Compile Include="BrresWriter.cs" />
+ <Compile Include="OutputStream.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
diff --git a/NW4RTools/NW4RTools.pidb b/NW4RTools/NW4RTools.pidb
index d805eec..317dedf 100644
--- a/NW4RTools/NW4RTools.pidb
+++ b/NW4RTools/NW4RTools.pidb
Binary files differ
diff --git a/NW4RTools/OutputStream.cs b/NW4RTools/OutputStream.cs
new file mode 100644
index 0000000..3f250a2
--- /dev/null
+++ b/NW4RTools/OutputStream.cs
@@ -0,0 +1,131 @@
+using System;
+using System.IO;
+
+namespace NW4RTools {
+ public class OutputStream {
+ // TODO: look into making this (and InputStream) inherit from Stream, or something
+ public readonly ByteEndian Endian;
+ private readonly bool MustReverseArrays;
+ private readonly System.IO.MemoryStream BaseStream;
+
+ public int Position {
+ get { return (int)BaseStream.Position; }
+ }
+
+ public byte[] GetBuffer() {
+ return BaseStream.ToArray();
+ }
+
+ public OutputStream() {
+ BaseStream = new MemoryStream();
+ Endian = ByteEndian.BigEndian;
+ MustReverseArrays = BitConverter.IsLittleEndian;
+ }
+
+ public OutputStream(ByteEndian endian) {
+ BaseStream = new MemoryStream();
+ Endian = endian;
+
+ if (Endian == ByteEndian.BigEndian)
+ MustReverseArrays = BitConverter.IsLittleEndian;
+ else
+ MustReverseArrays = !BitConverter.IsLittleEndian;
+ }
+
+ public void Seek(int pos) {
+ if (pos < 0 || pos > BaseStream.Length)
+ throw new ArgumentOutOfRangeException();
+
+ BaseStream.Position = pos;
+ }
+
+ public void WriteBytes(byte[] data) {
+ BaseStream.Write(data, 0, data.Length);
+ }
+
+ private void WriteReversedBytes(byte[] data) {
+ // TODO: figure out if this modifies the array
+ if (MustReverseArrays)
+ Array.Reverse(data);
+ BaseStream.Write(data, 0, data.Length);
+ }
+
+ public void WriteByte(byte val) {
+ BaseStream.WriteByte(val);
+ }
+
+ public void WriteSByte(sbyte val) {
+ WriteByte(unchecked((byte)val));
+ }
+
+ public void WriteInt16(Int16 val) {
+ WriteReversedBytes(BitConverter.GetBytes(val));
+ }
+
+ public void WriteUInt16(UInt16 val) {
+ WriteReversedBytes(BitConverter.GetBytes(val));
+ }
+
+ public void WriteInt32(Int32 val) {
+ WriteReversedBytes(BitConverter.GetBytes(val));
+ }
+
+ public void WriteUInt32(UInt32 val) {
+ WriteReversedBytes(BitConverter.GetBytes(val));
+ }
+
+ public void WriteFloat(float val) {
+ WriteReversedBytes(BitConverter.GetBytes(val));
+ }
+
+ public void WriteDouble(double val) {
+ WriteReversedBytes(BitConverter.GetBytes(val));
+ }
+
+ public void WriteColor(Color col) {
+ WriteByte(col.r);
+ WriteByte(col.g);
+ WriteByte(col.b);
+ WriteByte(col.a);
+ }
+
+ public void WriteVec2(Vec2 vec) {
+ WriteFloat(vec.x);
+ WriteFloat(vec.y);
+ }
+
+ public void WriteVec3(Vec3 vec) {
+ WriteFloat(vec.x);
+ WriteFloat(vec.y);
+ WriteFloat(vec.z);
+ }
+
+ public void WriteMatrix(Matrix m) {
+ WriteFloat(m.v00);
+ WriteFloat(m.v01);
+ WriteFloat(m.v02);
+ WriteFloat(m.v03);
+ WriteFloat(m.v10);
+ WriteFloat(m.v11);
+ WriteFloat(m.v12);
+ WriteFloat(m.v13);
+ WriteFloat(m.v20);
+ WriteFloat(m.v21);
+ WriteFloat(m.v22);
+ WriteFloat(m.v23);
+ }
+
+ public void WriteName(string name) {
+ byte[] encoded = System.Text.Encoding.GetEncoding("Shift_JIS").GetBytes(name);
+ WriteInt32(encoded.Length);
+ WriteBytes(encoded);
+
+ if ((encoded.Length & 3) != 0) {
+ for (int i = 4 - (encoded.Length & 3); i > 0; i--) {
+ WriteByte(0);
+ }
+ }
+ }
+ }
+}
+
diff --git a/NW4RTools/bin/Debug/NW4RTools.dll b/NW4RTools/bin/Debug/NW4RTools.dll
index 0fe74f3..3962f15 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 f7eb0df..f5f1318 100644
--- a/NW4RTools/bin/Debug/NW4RTools.dll.mdb
+++ b/NW4RTools/bin/Debug/NW4RTools.dll.mdb
Binary files differ