public void Save(EndianBinaryWriter stream)
        {
            if (stream == null)
                throw new ArgumentException("Null stream to save to!", "stream");

            // Header
            stream.Write((byte)Categories.Count);
            stream.Write((byte)0x5E);
            stream.Write((byte)0x00);
            stream.Write((byte)0x61);

            // Offset to the first entry
            stream.Write((int)stream.BaseStream.Position + 0x4);

            // Pre-allocate the offset to sub-entries based on the size of the Category header and the # of Categories
            long entryOffsetStart = stream.BaseStream.Position + (Categories.Count * 0x28);

            // Write each category and its children.
            foreach(var category in Categories)
            {
                category.Save(stream, ref entryOffsetStart);
            }

            // Pad file to a 32-byte alignment boundry using the formula:
            // (0 + (n-1)) & ~(n-1)
            long nextAlignedPos = (stream.BaseStream.Length + 0x1F) & ~0x1F;
            long delta = nextAlignedPos - stream.BaseStream.Length;
            stream.Seek(0, System.IO.SeekOrigin.End);

            stream.Write(new byte[delta]);
        }
 public void Write(EndianBinaryWriter writer)
 {
     writer.Write(FileId);
     writer.Write(NameHash);
     writer.Write(Type);
     writer.Write(Padding);
     writer.Write(NameOffset);
     writer.Write(DataOffset);
     writer.Write(DataSize);
     writer.Write(Zero);
 }
        public void Save(EndianBinaryWriter stream)
        {
            // Write 0x21 bytes of the display name (shift-jis encoded)
            byte[] encodedDisplayName = Encoding.GetEncoding("shift-jis").GetBytes(DisplayName);
            for(int i = 0; i < 0x21; i++)
            {
                if (i < encodedDisplayName.Length)
                    stream.Write((byte)encodedDisplayName[i]);
                else
                    stream.Write((byte)0);
            }

            // Write the 8 bytes of the map name (shift-jis encoded, though all map names in existing game use ASCI)
            byte[] encodedMapName = Encoding.GetEncoding("shift-jis").GetBytes(MapName);
            for (int i = 0; i < 0x8; i++)
            {
                if (i < encodedMapName.Length)
                    stream.Write((byte)encodedMapName[i]);
                else
                    stream.Write((byte)0);
            }

            stream.Write(RoomIndex);
            stream.Write(SpawnIndex);
            stream.Write((byte)LayerIndex);
        }
 public void Write(EndianBinaryWriter writer)
 {
     writer.WriteFixedString(Magic, 4);
     writer.Write(FileSize);
     writer.Write(Unknown1);
     writer.Write(DataOffset);
     writer.Write(Unknown2);
     writer.Write(Unknown3);
     writer.Write(Unknown4);
     writer.Write(Unknown5);
     writer.Write(NodeCount);
     writer.Write(Unknown6);
     writer.Write(Unknown7);
     writer.Write(FileEntriesOffset);
     writer.Write(Unknown8);
     writer.Write(StringTableOffset);
     writer.Write(FileEntryCount);
     writer.Write(UnknownBool1);
     writer.Write(Padding);
     writer.Write(Unknown10);
 }
 public void Write(EndianBinaryWriter writer)
 {
     writer.WriteFixedString(Type, 4);
     writer.Write(NameOffset);
     writer.Write(NameHash);
     writer.Write(FileEntryCount);
     writer.Write(FirstFileEntryIndex);
 }
        public void Save(EndianBinaryWriter stream, ref long entryOffsetStart)
        {
            // Write the first 0x20 characters of the DisplayName. The data is converted into shift-jis which can take up to two bytes per
            // character depending on the symbol. ASCII should take the usual one.
            long streamPos = stream.BaseStream.Position;
            byte[] encodedName = Encoding.GetEncoding("shift-jis").GetBytes(DisplayName);
            for (int i = 0; i < 0x20; i++)
            {
                if (i < encodedName.Length)
                    stream.Write((byte)encodedName[i]);
                else
                    stream.Write((byte)0);
            }

            // Write the entry count and padding
            stream.Write((short)Entries.Count);
            stream.Write((short)0);
            stream.Write((int)entryOffsetStart);

            // Write the entries
            stream.BaseStream.Position = entryOffsetStart;
            foreach (var entry in Entries)
            {
                entry.Save(stream);

                // Advance the sub-entry offset by the size of an entry so that when the next category
                // is written to disk, it writes them after our current ones.
                entryOffsetStart += 0x2C;
            }

            // Finally, restore our stream back to the end of the Category header so that the stream
            // writes the next category right after this one.
            stream.BaseStream.Position = streamPos + 0x28;
        }