public static void Save(string FileName, Gfx Scene) { using (FileStream FS = new FileStream(FileName, FileMode.Create)) { GfxHeader Header = new GfxHeader(); BinarySerializer Serializer = new BinarySerializer(FS, GetSerializationOptions()); Serializer.FileVersion = 0x07010000; Section Contents = Serializer.Sections[(uint)H3DSectionId.Contents]; Contents.Header = Header; Section Strings = new Section(); Section Image = new Section(); Image.Header = new GfxSectionHeader("IMAG"); Serializer.AddSection((uint)GfxSectionId.Strings, Strings, typeof(string)); Serializer.AddSection((uint)GfxSectionId.Strings, Strings, typeof(GfxStringUtf8)); Serializer.AddSection((uint)GfxSectionId.Strings, Strings, typeof(GfxStringUtf16LE)); Serializer.AddSection((uint)GfxSectionId.Strings, Strings, typeof(GfxStringUtf16BE)); bool WriteImage = Scene.Models.Count > 0 || Scene.Textures.Count > 0; if (WriteImage) { Serializer.AddSection((uint)GfxSectionId.Image, Image); } Serializer.Serialize(Scene); Header.FileLength = (int)FS.Length; Header.SectionsCount = Image.Values.Count > 0 ? 2 : 1; Header.Data.Length = Contents.Length + Strings.Length + 8; FS.Seek(0, SeekOrigin.Begin); Serializer.WriteValue(Header); if (WriteImage) { FS.Seek(Image.Position - 4, SeekOrigin.Begin); Serializer.Writer.Write(Image.LengthWithHeader); } } }
public static void Save(string FileName, H3D Scene) { using (FileStream FS = new FileStream(FileName, FileMode.Create)) { H3DHeader Header = new H3DHeader(); H3DRelocator Relocator = new H3DRelocator(FS, Header); BinarySerializer Serializer = new BinarySerializer(FS, GetSerializationOptions()); Section Contents = Serializer.Sections[(uint)H3DSectionId.Contents]; Contents.Header = Header; /* * Those comparisons are used to sort Strings and data buffers. * Strings are sorted in alphabetical order (like on the original file), * while buffers places textures first, and then vertex/index data after. * It's unknown why textures needs to come first, but placing the textures * at the end or at random order causes issues on the game. * It's most likely an alignment issue. */ Comparison <RefValue> CompStr = H3DComparers.GetComparisonStr(); Comparison <RefValue> CompRaw = H3DComparers.GetComparisonRaw(); Section Strings = new Section(0x10, CompStr); Section Commands = new Section(0x80); Section RawData = new Section(0x80, CompRaw); Section RawExt = new Section(0x80, CompRaw); Section Relocation = new Section(); Serializer.AddSection((uint)H3DSectionId.Strings, Strings, typeof(string)); Serializer.AddSection((uint)H3DSectionId.Strings, Strings, typeof(H3DStringUtf16)); Serializer.AddSection((uint)H3DSectionId.Commands, Commands, typeof(uint[])); Serializer.AddSection((uint)H3DSectionId.RawData, RawData); Serializer.AddSection((uint)H3DSectionId.RawExt, RawExt); Serializer.AddSection((uint)H3DSectionId.Relocation, Relocation); Header.BackwardCompatibility = Scene.BackwardCompatibility; Header.ForwardCompatibility = Scene.ForwardCompatibility; Header.ConverterVersion = Scene.ConverterVersion; Header.Flags = Scene.Flags; Serializer.Serialize(Scene); Header.AddressCount = (ushort)RawData.Values.Count; Header.AddressCount += (ushort)RawExt.Values.Count; Header.UnInitDataLength = Header.AddressCount * 4; Header.ContentsAddress = Contents.Position; Header.StringsAddress = Strings.Position; Header.CommandsAddress = Commands.Position; Header.RawDataAddress = RawData.Position; Header.RawExtAddress = RawExt.Position; Header.RelocationAddress = Relocation.Position; Header.ContentsLength = Contents.Length; Header.StringsLength = Strings.Length; Header.CommandsLength = Commands.Length; Header.RawDataLength = RawData.Length; Header.RawExtLength = RawExt.Length; Relocator.ToRelative(Serializer); FS.Seek(0, SeekOrigin.Begin); Serializer.WriteValue(Header); } }