internal override void Write(BinaryWriterEx bw, int id) { long start = bw.Position; bw.ReserveVarint("NameOffset"); bw.WriteByte((byte)Type); bw.WriteByte(0); bw.WriteInt16((short)id); if (bw.VarintLong) { bw.WriteInt32(0); } bw.ReserveVarint("TypeDataOffset"); bw.WriteVarint(0); bw.FillVarint("NameOffset", bw.Position - start); bw.WriteUTF16(MSB.ReambiguateName(Name), true); bw.Pad(bw.VarintSize); if (HasTypeData) { bw.FillVarint("TypeDataOffset", bw.Position - start); WriteTypeData(bw); } else { bw.FillVarint("TypeDataOffset", 0); } }
internal override void Write(BinaryWriterEx bw) { bool bigEndian = Format == EMEVD.Game.DarkSouls1BE; bool is64Bit = Format >= EMEVD.Game.Bloodborne; bw.WriteASCII("ELD\0"); bw.WriteBoolean(bigEndian); bw.WriteSByte((sbyte)(is64Bit ? -1 : 0)); bw.WriteByte(0); bw.WriteByte(0); bw.BigEndian = bigEndian; bw.VarintLong = is64Bit; bw.WriteInt16(0x65); bw.WriteInt16(0xCC); bw.ReserveInt32("FileSize"); bw.WriteVarint(Events.Count); bw.ReserveVarint("EventsOffset"); bw.WriteVarint(0); bw.ReserveVarint("Offset2"); bw.WriteVarint(0); bw.ReserveVarint("Offset3"); bw.ReserveVarint("StringsLength"); bw.ReserveVarint("StringsOffset"); if (!is64Bit) { bw.WriteInt32(0); bw.WriteInt32(0); } bw.FillVarint("EventsOffset", bw.Position); for (int i = 0; i < Events.Count; i++) { Events[i].Write(bw, Format, i); } bw.FillVarint("Offset2", bw.Position); bw.FillVarint("Offset3", bw.Position); long stringsOffset = bw.Position; bw.FillVarint("StringsOffset", bw.Position); for (int i = 0; i < Events.Count; i++) { Events[i].WriteName(bw, i, stringsOffset); } if ((bw.Position - stringsOffset) % 0x10 > 0) { bw.WritePattern(0x10 - (int)(bw.Position - stringsOffset) % 0x10, 0x00); } bw.FillVarint("StringsLength", bw.Position - stringsOffset); bw.FillInt32("FileSize", (int)bw.Position); }
internal void Write(BinaryWriterEx bw, MQBVersion version, int cutIndex, int timelineIndex) { bw.ReserveVarint($"DisposOffsetsOffset[{cutIndex}:{timelineIndex}]"); bw.WriteInt32(Dispositions.Count); if (version == MQBVersion.DarkSouls2Scholar) { bw.WriteInt32(0); } bw.ReserveVarint($"TimelineCustomDataOffset[{cutIndex}:{timelineIndex}]"); bw.WriteInt32(CustomData.Count); bw.WriteInt32(Unk10); }
internal void Write(BinaryWriterEx bw, MQBVersion version, Dictionary <Disposition, long> offsetsByDispos, int cutIndex, List <CustomData> allCustomData, List <long> customDataValueOffsets) { int disposCount = Timelines.Sum(g => g.Dispositions.Count); bw.WriteFixStrW(Name, 0x40, 0x00); bw.WriteInt32(disposCount); bw.WriteInt32(Unk44); bw.WriteInt32(Duration); bw.WriteInt32(0); bw.WriteInt32(Timelines.Count); if (version == MQBVersion.DarkSouls2Scholar) { bw.WriteInt32(0); } bw.ReserveVarint($"TimelinesOffset{cutIndex}"); if (version != MQBVersion.DarkSouls2Scholar) { bw.WriteInt64(0); } foreach (Timeline timeline in Timelines) { timeline.WriteDispositions(bw, offsetsByDispos, allCustomData, customDataValueOffsets); } }
internal override void Write(BinaryWriterEx bw, int id) { long start = bw.Position; bw.ReserveVarint("NameOffset"); bw.WriteByte((byte)Type); bw.WriteByte(0); bw.WriteInt16((short)id); bw.WriteInt16(ModelIndex); bw.WriteInt16(0); bw.WriteVector3(Position); bw.WriteVector3(Rotation); bw.WriteVector3(Scale); bw.WriteUInt32s(DrawGroups); bw.WriteInt32(Unk44); bw.WriteInt32(Unk48); bw.WriteInt32(Unk4C); bw.WriteInt32(Unk50); bw.WriteUInt32s(DispGroups); bw.WriteInt32(Unk64); bw.WriteInt32(0); bw.WriteByte(Unk6C); bw.WriteByte(0); bw.WriteByte(Unk6E); bw.WriteByte(0); bw.ReserveVarint("TypeDataOffset"); if (bw.VarintLong) { bw.WriteInt64(0); } long nameStart = bw.Position; int namePad = bw.VarintLong ? 0x20 : 0x2C; bw.FillVarint("NameOffset", nameStart - start); bw.WriteUTF16(MSB.ReambiguateName(Name), true); if (bw.Position - nameStart < namePad) { bw.Position += namePad - (bw.Position - nameStart); } bw.Pad(bw.VarintSize); bw.FillVarint("TypeDataOffset", bw.Position - start); WriteTypeData(bw); }
internal void Write(BinaryWriterEx bw, EMEVD.Game format, int index) { bw.WriteVarint(ID); bw.ReserveVarint($"Event{index}NameOffset"); if (format < EMEVD.Game.Bloodborne) { bw.WriteInt32(0); } }
internal virtual void Write(BinaryWriterEx bw, List <T> entries) { bw.WriteInt32(Version); if (bw.VarintLong) { bw.WriteInt32(entries.Count + 1); bw.ReserveVarint("ParamNameOffset"); } else { bw.ReserveVarint("ParamNameOffset"); bw.WriteInt32(entries.Count + 1); } for (int i = 0; i < entries.Count; i++) { bw.ReserveVarint($"EntryOffset{i}"); } bw.ReserveVarint("NextParamOffset"); bw.FillVarint("ParamNameOffset", bw.Position); bw.WriteUTF16(Name, true); bw.Pad(bw.VarintSize); int index = 0; Type type = null; for (int i = 0; i < entries.Count; i++) { if (type != entries[i].GetType()) { type = entries[i].GetType(); index = 0; } bw.FillVarint($"EntryOffset{i}", bw.Position); entries[i].Write(bw, index); bw.Pad(bw.VarintSize); index++; } }
internal override void Write(BinaryWriterEx bw, int id) { long start = bw.Position; bw.ReserveVarint("NameOffset"); bw.WriteInt32(EventID); bw.WriteByte((byte)Type); bw.WriteByte(0); bw.WriteInt16((short)id); bw.ReserveVarint("TypeDataOffset"); if (!bw.VarintLong) { bw.WriteInt32(0); bw.WriteInt32(0); } bw.FillVarint("NameOffset", bw.Position - start); bw.WriteUTF16(Name, true); bw.Pad(bw.VarintSize); bw.FillVarint("TypeDataOffset", bw.Position - start); WriteTypeData(bw); }
internal override void Write(BinaryWriterEx bw, int index) { long start = bw.Position; bw.WriteInt16(PartIndex); bw.WriteInt16((short)Bones.Count); if (bw.VarintLong) { bw.WriteInt32(0); } bw.ReserveVarint("BonesOffset"); bw.FillVarint("BonesOffset", bw.Position - start); foreach (Bone bone in Bones) { bone.Write(bw); } }
internal void Write(BinaryWriterEx bw, Game format, int eventIndex) { bw.WriteVarint(ID); bw.WriteVarint(Instructions.Count); bw.ReserveVarint($"Event{eventIndex}InstrsOffset"); bw.WriteVarint(Parameters.Count); if (format < Game.Scholar) { bw.ReserveInt32($"Event{eventIndex}ParamsOffset"); } else if (format < Game.DarkSouls3) { bw.ReserveInt32($"Event{eventIndex}ParamsOffset"); bw.WriteInt32(0); } else { bw.ReserveInt64($"Event{eventIndex}ParamsOffset"); } bw.WriteUInt32((uint)RestBehavior); bw.WriteInt32(0); }
protected override void Write(BinaryWriterEx bw) { bool bigEndian = Format == Game.DarkSouls1BE; bool is64Bit = Format >= Game.Bloodborne; bool unk06 = Format >= Game.DarkSouls3; 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(unk06); 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); }
protected override void Write(BinaryWriterEx bw) { bw.BigEndian = BigEndian; bw.VarintLong = Version == MQBVersion.DarkSouls2Scholar; bw.WriteASCII("MQB "); bw.WriteSByte((sbyte)(BigEndian ? -1 : 0)); bw.WriteByte(0); bw.WriteSByte((sbyte)(Version == MQBVersion.DarkSouls2Scholar ? -1 : 0)); bw.WriteByte(0); bw.WriteUInt32((uint)Version); switch (Version) { case MQBVersion.DarkSouls2: bw.WriteInt32(0x14); break; case MQBVersion.DarkSouls2Scholar: bw.WriteInt32(0x28); break; case MQBVersion.Bloodborne: bw.WriteInt32(0x20); break; case MQBVersion.DarkSouls3: bw.WriteInt32(0x24); break; default: throw new NotImplementedException($"Missing header size for version {Version}."); } bw.ReserveVarint("ResourcePathsOffset"); if (Version == MQBVersion.DarkSouls2Scholar) { bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); } else if (Version >= MQBVersion.Bloodborne) { bw.WriteInt32(1); bw.WriteInt32(0); bw.WriteInt32(0); if (Version >= MQBVersion.DarkSouls3) { bw.WriteInt32(0); } } bw.WriteFixStrW(Name, 0x40, 0x00); bw.WriteSingle(Framerate); bw.WriteInt32(Resources.Count); bw.WriteInt32(Cuts.Count); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); var allCustomData = new List <CustomData>(); var customDataValueOffsets = new List <long>(); for (int i = 0; i < Resources.Count; i++) { Resources[i].Write(bw, i, allCustomData, customDataValueOffsets); } var offsetsByDispos = new Dictionary <Disposition, long>(); for (int i = 0; i < Cuts.Count; i++) { Cuts[i].Write(bw, Version, offsetsByDispos, i, allCustomData, customDataValueOffsets); } for (int i = 0; i < Cuts.Count; i++) { Cuts[i].WriteTimelines(bw, Version, i); } for (int i = 0; i < Cuts.Count; i++) { Cuts[i].WriteTimelineCustomData(bw, i, allCustomData, customDataValueOffsets); } for (int i = 0; i < Cuts.Count; i++) { Cuts[i].WriteDisposOffsets(bw, offsetsByDispos, i); } bw.FillVarint("ResourcePathsOffset", bw.Position); for (int i = 0; i < Resources.Count; i++) { bw.ReserveVarint($"ResourcePathOffset{i}"); } bw.WriteUTF16(ResourceDirectory, true); for (int i = 0; i < Resources.Count; i++) { if (Resources[i].Path == null) { bw.FillVarint($"ResourcePathOffset{i}", 0); } else { bw.FillVarint($"ResourcePathOffset{i}", bw.Position); bw.WriteUTF16(Resources[i].Path, true); } } // I know this is weird, but trust me. if (Version >= MQBVersion.Bloodborne) { bw.WriteInt16(0); bw.Pad(4); } for (int i = 0; i < allCustomData.Count; i++) { allCustomData[i].WriteSequences(bw, i, customDataValueOffsets[i]); } for (int i = 0; i < allCustomData.Count; i++) { allCustomData[i].WriteSequencePoints(bw, i); } }
internal void Write(BinaryWriterEx bw, NGPVersion version) { long start = bw.Position; bw.WriteInt32(Unk00); bw.ReserveInt32("MeshLength"); bw.WriteInt32(Unk08); if (version == NGPVersion.Scholar) { bw.WriteInt32(0); } bw.WriteVector3(BoundingBoxMin); bw.WriteVector3(BoundingBoxMax); bw.WriteInt32(Vertices.Count); bw.WriteInt16((short)Faces.Count); bw.WriteInt16((short)Struct4s.Count); bw.WriteInt16(Unk30); bw.WriteInt16(Unk32); bw.WriteByte(1); bw.WriteByte(0); bw.WriteByte(0); bw.WriteByte(0); if (version == NGPVersion.Scholar) { bw.WriteInt64(0); } bw.ReserveVarint("VerticesOffset"); bw.ReserveVarint("Struct2sOffset"); bw.ReserveVarint("FacesOffset"); bw.ReserveVarint("Struct4sOffset"); bw.ReserveVarint("Struct5sOffset"); bw.ReserveVarint("Struct6sOffset"); bw.FillVarint("VerticesOffset", bw.Position); foreach (Vector3 vertex in Vertices) { bw.WriteVector3(vertex); } bw.Pad(bw.VarintSize); bw.FillVarint("Struct2sOffset", bw.Position); foreach (int struct2 in Struct2s) { bw.WriteInt32(struct2); } bw.Pad(bw.VarintSize); bw.FillVarint("FacesOffset", bw.Position); foreach (Face face in Faces) { face.Write(bw); } bw.Pad(bw.VarintSize); bw.FillVarint("Struct4sOffset", bw.Position); foreach (Struct4 struct4 in Struct4s) { struct4.Write(bw); } bw.Pad(bw.VarintSize); bw.FillVarint("Struct5sOffset", bw.Position); short index = 0; Struct5Root.Write(bw, ref index); bw.Pad(bw.VarintSize); bw.FillVarint("Struct6sOffset", bw.Position); index = 0; int faceIndexIndex = 0; Struct5Root.WriteFaceIndices(bw, ref index, ref faceIndexIndex); bw.Pad(bw.VarintSize); bw.FillInt32("MeshLength", (int)(bw.Position - start)); }
protected override void Write(BinaryWriterEx bw) { bw.BigEndian = BigEndian; bw.VarintLong = Version == NGPVersion.Scholar; bw.WriteASCII("NVG2"); bw.WriteUInt16((ushort)Version); bw.WriteInt16(0); bw.WriteInt32(Meshes.Count); bw.WriteInt32(StructAs.Count); bw.WriteInt32(StructBs.Count); bw.WriteInt32(StructCs.Count); bw.WriteInt32(StructDs.Count); bw.WriteInt32(Unk1C); bw.ReserveVarint("OffsetA"); bw.ReserveVarint("OffsetB"); bw.ReserveVarint("OffsetC"); bw.ReserveVarint("OffsetD"); for (int i = 0; i < Meshes.Count; i++) { bw.ReserveVarint($"MeshOffset{i}"); } void writeMeshes() { for (int i = 0; i < Meshes.Count; i++) { bw.Pad(bw.VarintSize); bw.FillVarint($"MeshOffset{i}", bw.Position); Meshes[i].Write(bw, Version); } } if (Version == NGPVersion.Vanilla) { writeMeshes(); } bw.Pad(bw.VarintSize); bw.FillVarint("OffsetA", bw.Position); foreach (StructA structA in StructAs) { structA.Write(bw); } bw.Pad(bw.VarintSize); bw.FillVarint("OffsetB", bw.Position); foreach (StructB structB in StructBs) { structB.Write(bw); } bw.Pad(bw.VarintSize); bw.FillVarint("OffsetC", bw.Position); bw.WriteInt32s(StructCs); bw.Pad(bw.VarintSize); bw.FillVarint("OffsetD", bw.Position); bw.WriteInt16s(StructDs); if (Version == NGPVersion.Scholar) { writeMeshes(); } }