From 00e977b3dbb8f447b034b7be387ee1a1cce0598c Mon Sep 17 00:00:00 2001 From: Treeki Date: Fri, 25 Feb 2011 22:08:57 +0100 Subject: start of a brres writer --- NW4RTools/BrresWriter.cs | 121 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 NW4RTools/BrresWriter.cs (limited to 'NW4RTools/BrresWriter.cs') 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 OffsetMap; + private OutputStream Output; + + private BrresWriter() { + Debug = new ConsoleLogger(); + OffsetMap = new SortedDictionary(); + } + + 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); + } + + // 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 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 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 StringTableOffsets; + + private OutputStream StringTableData; + + + // Called at the start of the process + private void InitialiseStringTable() { + StringTable = new List(); + } + + private void AddString(string str) { + if (!StringTable.Contains(str)) { + StringTable.Add(str); + } + } + + private void CalculateStringTable() { + StringTable.Sort(); + + StringTableOffsets = new Dictionary(); + 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 + } +} + -- cgit v1.2.3