public void AddObjectToDictionary(SerializableDOMNode actor, Dictionary <FourCC, List <SerializableDOMNode> > actorCategories) { string rawFourCC = FourCCConversion.GetStringFromEnum(actor.FourCC); string fixedFourCC = ChunkHeader.LayerToFourCC(rawFourCC, actor.Layer); FourCC fixedFourCCEnum = FourCCConversion.GetEnumFromString(fixedFourCC); if (!actorCategories.ContainsKey(fixedFourCCEnum)) { actorCategories[fixedFourCCEnum] = new List <SerializableDOMNode>(); } actorCategories[fixedFourCCEnum].Add(actor); }
public void ExportToStream(EndianBinaryWriter writer, WScene scene) { // Build a dictionary which lists unique FourCC's and a list of all relevant actors. var actorCategories = new Dictionary <string, List <WActorNode> >(); foreach (var child in scene) { WActorNode actor = child as WActorNode; if (actor != null) { string fixedFourCC = ChunkHeader.LayerToFourCC(actor.FourCC, actor.Layer); if (!actorCategories.ContainsKey(fixedFourCC)) { actorCategories[fixedFourCC] = new List <WActorNode>(); } actorCategories[fixedFourCC].Add(actor); } } // Create a chunk header for each one. var chunkHeaders = new List <ChunkHeader>(); foreach (var kvp in actorCategories) { ChunkHeader header = new ChunkHeader(); header.FourCC = kvp.Key; header.ElementCount = kvp.Value.Count; chunkHeaders.Add(header); } long chunkStart = writer.BaseStream.Position; // Write the Header writer.Write(chunkHeaders.Count); for (int i = 0; i < chunkHeaders.Count; i++) { writer.Write((int)0); // Dummy Placeholder values for the Chunk Header. writer.Write((int)0); writer.Write((int)0); } // For each chunk, write the data for that chunk. Before writing the data, get the current offset and update the header. List <WActorNode>[] dictionaryData = new List <WActorNode> [actorCategories.Count]; actorCategories.Values.CopyTo(dictionaryData, 0); for (int i = 0; i < chunkHeaders.Count; i++) { ChunkHeader header = chunkHeaders[i]; chunkHeaders[i] = new ChunkHeader(header.FourCC, header.ElementCount, (int)(writer.BaseStream.Position - chunkStart)); List <WActorNode> actors = dictionaryData[i]; foreach (var actor in actors) { MapActorDescriptor template = m_sActorDescriptors.Find(x => x.FourCC == actor.FourCC); if (template == null) { Console.WriteLine("Unsupported FourCC (\"{0}\") for exporting!", actor.FourCC); continue; } WriteActorToChunk(actor, template, writer); } } // Now that we've written every actor to file we can go back and re-write the headers now that we know their offsets. writer.BaseStream.Position = chunkStart + 0x4; // 0x4 is the offset to the Chunk Headers foreach (var header in chunkHeaders) { writer.WriteFixedString(header.FourCC, 4); // FourCC writer.Write(header.ElementCount); // Number of Entries writer.Write(header.ChunkOffset); // Offset from start of file. } // Seek to the end of the file, and then pad us to 32-byte alignment. writer.BaseStream.Seek(0, SeekOrigin.End); int delta = WMath.Pad32Delta(writer.BaseStream.Position); for (int i = 0; i < delta; i++) { writer.Write((byte)0xFF); } }