internal void WriteSection11s(BinaryWriterEx bw, int index, ref int section11Count) { bw.FillInt32($"Section10Section11sOffset[{index}]", (int)bw.Position); bw.WriteInt32s(Section11s); section11Count += Section11s.Count; }
internal override void Write(BinaryWriterEx bw) { bool bigEndian = Format == Game.DarkSouls1BE; bool is64Bit = Format >= Game.Scholar; bool unicode = Format >= Game.Bloodborne; bool unk07 = Format >= Game.Sekiro; int version = Format < Game.DarkSouls3 ? 0xCC : 0xCD; var layers = new List <uint>(); foreach (Event evt in Events) { foreach (Instruction inst in evt.Instructions) { if (inst.Layer.HasValue && !layers.Contains(inst.Layer.Value)) { layers.Add(inst.Layer.Value); } } } bw.WriteASCII("EVD\0"); bw.WriteBoolean(bigEndian); bw.WriteSByte((sbyte)(is64Bit ? -1 : 0)); bw.WriteBoolean(unicode); bw.WriteSByte((sbyte)(unk07 ? -1 : 0)); bw.BigEndian = bigEndian; bw.VarintLong = is64Bit; bw.WriteInt32(version); bw.ReserveInt32("FileSize"); Offsets offsets = default; bw.WriteVarint(Events.Count); bw.ReserveVarint("EventsOffset"); bw.WriteVarint(Events.Sum(e => e.Instructions.Count)); bw.ReserveVarint("InstructionsOffset"); bw.WriteVarint(0); bw.ReserveVarint("Offset3"); bw.WriteVarint(layers.Count); bw.ReserveVarint("LayersOffset"); bw.WriteVarint(Events.Sum(e => e.Parameters.Count)); bw.ReserveVarint("ParametersOffset"); bw.WriteVarint(LinkedFileOffsets.Count); bw.ReserveVarint("LinkedFilesOffset"); bw.ReserveVarint("ArgumentsLength"); bw.ReserveVarint("ArgumentsOffset"); bw.WriteVarint(StringData.Length); bw.ReserveVarint("StringsOffset"); if (!is64Bit) { bw.WriteInt32(0); } offsets.Events = bw.Position; bw.FillVarint("EventsOffset", bw.Position); for (int i = 0; i < Events.Count; i++) { Events[i].Write(bw, Format, i); } offsets.Instructions = bw.Position; bw.FillVarint("InstructionsOffset", bw.Position); for (int i = 0; i < Events.Count; i++) { Events[i].WriteInstructions(bw, Format, offsets, i); } bw.FillVarint("Offset3", bw.Position); offsets.Layers = bw.Position; bw.FillVarint("LayersOffset", bw.Position); var layerOffsets = new Dictionary <uint, long>(layers.Count); foreach (uint layer in layers) { layerOffsets[layer] = bw.Position - offsets.Layers; Layer.Write(bw, layer); } for (int i = 0; i < Events.Count; i++) { Event evt = Events[i]; for (int j = 0; j < evt.Instructions.Count; j++) { evt.Instructions[j].FillLayerOffset(bw, Format, i, j, layerOffsets); } } offsets.Arguments = bw.Position; bw.FillVarint("ArgumentsOffset", bw.Position); for (int i = 0; i < Events.Count; i++) { Event evt = Events[i]; for (int j = 0; j < evt.Instructions.Count; j++) { evt.Instructions[j].WriteArgs(bw, Format, offsets, i, j); } } if ((bw.Position - offsets.Arguments) % 0x10 > 0) { bw.WritePattern(0x10 - (int)(bw.Position - offsets.Arguments) % 0x10, 0x00); } bw.FillVarint("ArgumentsLength", bw.Position - offsets.Arguments); offsets.Parameters = bw.Position; bw.FillVarint("ParametersOffset", bw.Position); for (int i = 0; i < Events.Count; i++) { Events[i].WriteParameters(bw, Format, offsets, i); } offsets.LinkedFiles = bw.Position; bw.FillVarint("LinkedFilesOffset", bw.Position); foreach (long offset in LinkedFileOffsets) { bw.WriteVarint((int)offset); } offsets.Strings = bw.Position; bw.FillVarint("StringsOffset", bw.Position); bw.WriteBytes(StringData); bw.FillInt32("FileSize", (int)bw.Position); }
/// <summary> /// Serializes file data to a stream. /// </summary> protected override void Write(BinaryWriterEx bw) { bw.BigEndian = BigEndian; bw.ReserveInt32("FileSize"); bw.WriteInt16((short)(FormatVersion >= 200 ? 0xFF : 0x30)); bw.WriteInt16(DataVersion); bw.WriteInt16((short)Fields.Count); if (FormatVersion == 101) { bw.WriteInt16(0x8C); } else if (FormatVersion == 102) { bw.WriteInt16(0xAC); } else if (FormatVersion == 103) { bw.WriteInt16(0x6C); } else if (FormatVersion == 104) { bw.WriteInt16(0xB0); } else if (FormatVersion == 201) { bw.WriteInt16(0xD0); } else if (FormatVersion == 202) { bw.WriteInt16(0x68); } if (FormatVersion >= 202) { bw.WriteInt32(0); bw.ReserveInt64("ParamTypeOffset"); bw.WriteInt64(0); bw.WriteInt64(0); bw.WriteInt32(0); } else { bw.WriteFixStr(ParamType, 0x20, (byte)(FormatVersion >= 200 ? 0x00 : 0x20)); } bw.WriteSByte((sbyte)(BigEndian ? -1 : 0)); bw.WriteBoolean(Unicode); bw.WriteInt16(FormatVersion); if (FormatVersion >= 200) { bw.WriteInt64(0x38); } for (int i = 0; i < Fields.Count; i++) { Fields[i].Write(bw, this, i); } if (FormatVersion >= 202) { bw.FillInt64("ParamTypeOffset", bw.Position); bw.WriteShiftJIS(ParamType, true); } long fieldStringsStart = bw.Position; var sharedStringOffsets = new Dictionary <string, long>(); for (int i = 0; i < Fields.Count; i++) { Fields[i].WriteStrings(bw, this, i, sharedStringOffsets); } if (FormatVersion >= 104 && FormatVersion < 202) { long fieldStringsLength = bw.Position - fieldStringsStart; if (fieldStringsLength % 0x10 != 0) { bw.WritePattern((int)(0x10 - fieldStringsLength % 0x10), 0x00); } } else { if (FormatVersion >= 202 && bw.Position % 0x10 == 0) { bw.WritePattern(0x10, 0x00); } bw.Pad(0x10); } bw.FillInt32("FileSize", (int)bw.Position); }
internal void WriteValues(BinaryWriterEx bw, GPGame game, int index, int unk3ValueIDsOffset) { bw.FillInt32($"Unk3ValueIDsOffset{index}", (int)bw.Position - unk3ValueIDsOffset); bw.WriteInt32s(ValueIDs); }
internal abstract void Write(BinaryWriterEx bw, int id);
internal void WriteCommentOffsetsOffset(BinaryWriterEx bw, int index) { bw.ReserveInt32($"CommentOffsetsOffset{index}"); }
internal void WriteParamHeaderOffset(BinaryWriterEx bw, int groupIndex, int paramIndex) { bw.ReserveInt32($"ParamHeaderOffset{groupIndex}:{paramIndex}"); }
internal override void Write(BinaryWriterEx bw) { bw.BigEndian = false; bw.WriteUTF16("filt"); bw.WriteUInt32((uint)Game); bw.WriteInt32(Unk0C); bw.WriteInt32(Groups.Count); bw.WriteInt32(Unk14); bw.WriteInt32(Game == GPGame.DarkSouls3 ? 0x50 : 0x54); bw.ReserveInt32("GroupHeadersOffset"); bw.ReserveInt32("ParamHeaderOffsetsOffset"); bw.ReserveInt32("ParamHeadersOffset"); bw.ReserveInt32("ValuesOffset"); bw.ReserveInt32("ValueIDsOffset"); bw.ReserveInt32("UnkOffset2"); bw.WriteInt32(Unk3s.Count); bw.ReserveInt32("UnkOffset3"); bw.ReserveInt32("Unk3ValuesOffset"); bw.WriteInt32(0); bw.ReserveInt32("CommentOffsetsOffsetsOffset"); bw.ReserveInt32("CommentOffsetsOffset"); bw.ReserveInt32("CommentsOffset"); if (Game == GPGame.Sekiro) { bw.WriteSingle(Unk50); } for (int i = 0; i < Groups.Count; i++) { Groups[i].WriteHeaderOffset(bw, i); } int groupHeadersOffset = (int)bw.Position; bw.FillInt32("GroupHeadersOffset", groupHeadersOffset); for (int i = 0; i < Groups.Count; i++) { Groups[i].WriteHeader(bw, i, groupHeadersOffset); } int paramHeaderOffsetsOffset = (int)bw.Position; bw.FillInt32("ParamHeaderOffsetsOffset", paramHeaderOffsetsOffset); for (int i = 0; i < Groups.Count; i++) { Groups[i].WriteParamHeaderOffsets(bw, i, paramHeaderOffsetsOffset); } int paramHeadersOffset = (int)bw.Position; bw.FillInt32("ParamHeadersOffset", paramHeadersOffset); for (int i = 0; i < Groups.Count; i++) { Groups[i].WriteParamHeaders(bw, i, paramHeadersOffset); } int valuesOffset = (int)bw.Position; bw.FillInt32("ValuesOffset", valuesOffset); for (int i = 0; i < Groups.Count; i++) { Groups[i].WriteValues(bw, i, valuesOffset); } int valueIDsOffset = (int)bw.Position; bw.FillInt32("ValueIDsOffset", (int)bw.Position); for (int i = 0; i < Groups.Count; i++) { Groups[i].WriteValueIDs(bw, Game, i, valueIDsOffset); } bw.FillInt32("UnkOffset2", (int)bw.Position); bw.WriteBytes(UnkBlock2); bw.FillInt32("UnkOffset3", (int)bw.Position); for (int i = 0; i < Unk3s.Count; i++) { Unk3s[i].WriteHeader(bw, Game, i); } int unk3ValuesOffset = (int)bw.Position; bw.FillInt32("Unk3ValuesOffset", unk3ValuesOffset); for (int i = 0; i < Unk3s.Count; i++) { Unk3s[i].WriteValues(bw, Game, i, unk3ValuesOffset); } bw.FillInt32("CommentOffsetsOffsetsOffset", (int)bw.Position); for (int i = 0; i < Groups.Count; i++) { Groups[i].WriteCommentOffsetsOffset(bw, i); } int commentOffsetsOffset = (int)bw.Position; bw.FillInt32("CommentOffsetsOffset", commentOffsetsOffset); for (int i = 0; i < Groups.Count; i++) { Groups[i].WriteCommentOffsets(bw, i, commentOffsetsOffset); } int commentsOffset = (int)bw.Position; bw.FillInt32("CommentsOffset", commentsOffset); for (int i = 0; i < Groups.Count; i++) { Groups[i].WriteComments(bw, i, commentsOffset); } }
internal void WriteHeaderOffset(BinaryWriterEx bw, int groupIndex) { bw.ReserveInt32($"GroupHeaderOffset{groupIndex}"); }
internal void Write(BinaryWriterEx bw) { bw.WriteInt16(Step); bw.WriteInt16(Index); }
internal void Write(BinaryWriterEx bw) { bw.WriteInt64(Unk1); }
internal override void Write(BinaryWriterEx bw) { bw.BigEndian = BigEndian; bw.WriteInt32(1); bw.WriteInt32(Vertices.Count); bw.ReserveInt32("VertexOffset"); bw.WriteInt32(Triangles.Count); bw.ReserveInt32("TriangleOffset"); bw.ReserveInt32("RootBoxOffset"); bw.WriteInt32(0); bw.WriteInt32(Entities.Count); bw.ReserveInt32("EntityOffset"); for (int i = 0; i < 23; i++) { bw.WriteInt32(0); } bw.FillInt32("VertexOffset", (int)bw.Position); foreach (Vector3 vertex in Vertices) { bw.WriteVector3(vertex); } bw.FillInt32("TriangleOffset", (int)bw.Position); foreach (Triangle triangle in Triangles) { triangle.Write(bw); } var boxTriangleIndexOffsets = new Queue <int>(); void WriteBoxTriangleIndices(Box box) { if (box == null) { return; } WriteBoxTriangleIndices(box.ChildBox1); WriteBoxTriangleIndices(box.ChildBox2); WriteBoxTriangleIndices(box.ChildBox3); WriteBoxTriangleIndices(box.ChildBox4); if (box.TriangleIndices.Count == 0) { boxTriangleIndexOffsets.Enqueue(0); } else { boxTriangleIndexOffsets.Enqueue((int)bw.Position); bw.WriteInt32s(box.TriangleIndices); } } WriteBoxTriangleIndices(RootBox); int rootBoxOffset = RootBox.Write(bw, boxTriangleIndexOffsets); bw.FillInt32("RootBoxOffset", rootBoxOffset); var entityTriangleIndexOffsets = new List <int>(); foreach (Entity entity in Entities) { entityTriangleIndexOffsets.Add((int)bw.Position); bw.WriteInt32s(entity.TriangleIndices); } bw.FillInt32("EntityOffset", (int)bw.Position); for (int i = 0; i < Entities.Count; i++) { Entities[i].Write(bw, entityTriangleIndexOffsets[i]); } }
internal override void WriteSpecific(BinaryWriterEx bw, long start) { bw.FillInt64("UnkOffset", 0); }
internal abstract void WriteSpecific(BinaryWriterEx bw, long start);
internal virtual void WriteTypeData(BinaryWriterEx bw) { throw new InvalidOperationException("Type data should not be written for models with no type data."); }
internal override void WriteEntry(BinaryWriterEx bw, int id, Model entry) { entry.Write(bw, id); }