/// <summary> /// Writes BND0 data to a BinaryWriterEx. /// </summary> protected override void Write(BinaryWriterEx bw) { bw.BigEndian = false; bw.WriteASCII("BND\0"); if (Lite) { bw.ReserveInt32("FileSize"); bw.WriteInt32(Files.Count); bw.WriteInt32(0); } else { bw.WriteInt32(0xF7FF); bw.WriteInt32(0xD3); bw.ReserveInt32("FileSize"); bw.WriteInt32(Files.Count); bw.WriteInt32(0); bw.WriteByte(Flag1); bw.WriteByte(Flag2); bw.WriteByte(3); bw.WriteByte(0); bw.WriteInt32(0); bw.WriteInt32(0); } for (int i = 0; i < Files.Count; i++) { Files[i].Write(bw, Lite, i); } for (int i = 0; i < Files.Count; i++) { File file = Files[i]; bw.Pad(0x20); bw.FillInt32($"FileOffset{i}", (int)bw.Position); if (Lite) { bw.WriteInt32(file.Bytes.Length + 4); bw.WriteBytes(file.Bytes); } else { bw.WriteBytes(file.Bytes); } } bw.FillInt32("FileSize", (int)bw.Position); }
internal void WriteSection2S(BinaryWriterEx bw) { bw.FillInt32("Section1Section2sOffset", (int)bw.Position); for (int index = 0; index < this.States.Count; ++index) { this.States[index].Write(bw, index); } }
public void Write(BinaryWriterEx bw) { bw.WriteASCII("TEXI"); bw.ReserveInt32("TEXIDataSize"); bw.WriteInt32(Entries.Count); bw.WriteInt32(0); int start = (int)bw.Position; foreach ((int, int)entry in Entries) { bw.WriteInt32(entry.Item1); bw.WriteInt32(entry.Item2); bw.WriteInt32(0); bw.WriteInt32(0); } bw.Pad(0x10); bw.FillInt32("TEXIDataSize", (int)bw.Position - start); }
public void Write(BinaryWriterEx bw) { bw.WriteASCII("STR\0"); bw.ReserveInt32("STRDataSize"); bw.WriteInt32(strings.Values.Count); bw.WriteInt32(0); int start = (int)bw.Position; List <int> offsets = new List <int>(strings.Keys); offsets.Sort(); foreach (int offset in offsets) { bw.WriteUTF16(strings[offset], true); } bw.Pad(0x10); bw.FillInt32("STRDataSize", (int)bw.Position - start); }
internal Dictionary <float, long> WriteTimes(BinaryWriterEx bw, int animIndex, TAEFormat format) { var times = new SortedSet <float>(); foreach (Event evt in Events) { times.Add(evt.StartTime); times.Add(evt.EndTime); } bw.FillInt32($"TimesCount{animIndex}", times.Count); if (times.Count == 0) { bw.FillVarint($"TimesOffset{animIndex}", 0); } else { bw.FillVarint($"TimesOffset{animIndex}", bw.Position); } var timeOffsets = new Dictionary <float, long>(); foreach (float time in times) { timeOffsets[time] = bw.Position; bw.WriteSingle(time); } if (format != TAEFormat.DS1) { bw.Pad(0x10); } return(timeOffsets); }
protected override void Write(BinaryWriterEx bw) { bw.WriteASCII("TAE "); bw.BigEndian = BigEndian; bw.WriteBoolean(BigEndian); bw.WriteByte(0); bw.WriteByte(0); if (Format == TAEFormat.DS1) { bw.VarintLong = false; bw.WriteByte(0); } else { bw.VarintLong = true; bw.WriteByte(0xFF); } if (Format == TAEFormat.DS1) { bw.WriteInt32(0x1000B); } else if (Format == TAEFormat.DS3 || Format == TAEFormat.SOTFS) { bw.WriteInt32(0x1000C); } else if (Format == TAEFormat.SDT) { bw.WriteInt32(0x1000D); } bw.ReserveInt32("FileSize"); bw.WriteVarint(0x40); bw.WriteVarint(1); bw.WriteVarint(0x50); bw.WriteVarint(Format == TAEFormat.DS1 ? 0x70 : 0x80); if (Format == TAEFormat.DS1) { bw.WriteInt16(2); bw.WriteInt16(1); } else { bw.WriteVarint(EventBank); } bw.WriteVarint(0); //DeS also if (Format == TAEFormat.DS1) { bw.WriteInt64(0); bw.WriteInt64(0); bw.WriteInt64(0); } bw.WriteBytes(Flags); if (Format == TAEFormat.SOTFS) { bw.WriteByte(0); bw.WriteByte(1); } else { bw.WriteByte(1); bw.WriteByte(0); } for (int i = 0; i < 6; i++) { bw.WriteByte(0); } bw.WriteInt32(ID); bw.WriteInt32(Animations.Count); bw.ReserveVarint("AnimsOffset"); bw.ReserveVarint("AnimGroupsOffset"); bw.WriteVarint(Format == TAEFormat.DS1 ? 0x90 : 0xA0); bw.WriteVarint(Animations.Count); bw.ReserveVarint("FirstAnimOffset"); if (Format == TAEFormat.DS1) { bw.WriteInt32(0); } bw.WriteVarint(1); bw.WriteVarint(Format == TAEFormat.DS1 ? 0x80 : 0x90); if (Format == TAEFormat.DS1) { bw.WriteInt64(0); } bw.WriteInt32(ID); bw.WriteInt32(ID); bw.WriteVarint(0x50); bw.WriteInt64(0); bw.WriteVarint(Format == TAEFormat.DS1 ? 0x98 : 0xB0); bw.ReserveVarint("SkeletonName"); bw.ReserveVarint("SibName"); if (Format != TAEFormat.SOTFS) { bw.WriteVarint(0); bw.WriteVarint(0); } bw.FillVarint("SkeletonName", bw.Position); if (!string.IsNullOrEmpty(SkeletonName)) { bw.WriteUTF16(SkeletonName, true); if (Format != TAEFormat.DS1) { bw.Pad(0x10); } } bw.FillVarint("SibName", bw.Position); if (!string.IsNullOrEmpty(SibName)) { bw.WriteUTF16(SibName, true); if (Format != TAEFormat.DS1) { bw.Pad(0x10); } } Animations.Sort((a1, a2) => a1.ID.CompareTo(a2.ID)); var animOffsets = new List <long>(Animations.Count); if (Animations.Count == 0) { bw.FillVarint("AnimsOffset", 0); } else { bw.FillVarint("AnimsOffset", bw.Position); for (int i = 0; i < Animations.Count; i++) { animOffsets.Add(bw.Position); Animations[i].WriteHeader(bw, i); } } bw.FillVarint("AnimGroupsOffset", bw.Position); bw.ReserveVarint("AnimGroupsCount"); bw.ReserveVarint("AnimGroupsOffset"); int groupCount = 0; long groupStart = bw.Position; for (int i = 0; i < Animations.Count; i++) { int firstIndex = i; bw.WriteInt32((int)Animations[i].ID); while (i < Animations.Count - 1 && Animations[i + 1].ID == Animations[i].ID + 1) { i++; } bw.WriteInt32((int)Animations[i].ID); bw.WriteVarint(animOffsets[firstIndex]); groupCount++; } bw.FillVarint("AnimGroupsCount", groupCount); if (groupCount == 0) { bw.FillVarint("AnimGroupsOffset", 0); } else { bw.FillVarint("AnimGroupsOffset", groupStart); } if (Animations.Count == 0) { bw.FillVarint("FirstAnimOffset", 0); } else { bw.FillVarint("FirstAnimOffset", bw.Position); for (int i = 0; i < Animations.Count; i++) { Animations[i].WriteBody(bw, i, Format); } } for (int i = 0; i < Animations.Count; i++) { Animation anim = Animations[i]; anim.WriteAnimFile(bw, i, Format); Dictionary <float, long> timeOffsets = anim.WriteTimes(bw, i, Format); List <long> eventHeaderOffsets = anim.WriteEventHeaders(bw, i, timeOffsets); anim.WriteEventData(bw, i, Format); anim.WriteEventGroupHeaders(bw, i, Format); anim.WriteEventGroupData(bw, i, eventHeaderOffsets, Format); } bw.FillInt32("FileSize", (int)bw.Position); }
protected override void Write(BinaryWriterEx bw) { bw.WriteASCII("FXR\0"); bw.WriteInt16((short)0); bw.WriteUInt16((ushort)this.Version); bw.WriteInt32(1); bw.WriteInt32(this.Id); bw.ReserveInt32("Section1Offset"); bw.WriteInt32(1); bw.ReserveInt32("Section2Offset"); bw.WriteInt32(this.RootStateMachine.States.Count); bw.ReserveInt32("Section3Offset"); bw.ReserveInt32("Section3Count"); bw.ReserveInt32("Section4Offset"); bw.ReserveInt32("Section4Count"); bw.ReserveInt32("Section5Offset"); bw.ReserveInt32("Section5Count"); bw.ReserveInt32("Section6Offset"); bw.ReserveInt32("Section6Count"); bw.ReserveInt32("Section7Offset"); bw.ReserveInt32("Section7Count"); bw.ReserveInt32("Section8Offset"); bw.ReserveInt32("Section8Count"); bw.ReserveInt32("Section9Offset"); bw.ReserveInt32("Section9Count"); bw.ReserveInt32("Section10Offset"); bw.ReserveInt32("Section10Count"); bw.ReserveInt32("Section11Offset"); bw.ReserveInt32("Section11Count"); bw.WriteInt32(1); bw.WriteInt32(0); if (this.Version == Fxr3.FxrVersion.Sekiro) { bw.ReserveInt32("Section12Offset"); bw.WriteInt32(this.Section12S.Count); bw.ReserveInt32("Section13Offset"); bw.WriteInt32(this.Section13S.Count); bw.ReserveInt32("Section14Offset"); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); } bw.FillInt32("Section1Offset", (int)bw.Position); this.RootStateMachine.Write(bw); bw.Pad(16); bw.FillInt32("Section2Offset", (int)bw.Position); this.RootStateMachine.WriteSection2S(bw); bw.Pad(16); bw.FillInt32("Section3Offset", (int)bw.Position); List <Fxr3.FfxState> states = this.RootStateMachine.States; List <Fxr3.FfxTransition> section3S = new List <Fxr3.FfxTransition>(); for (int index = 0; index < states.Count; ++index) { states[index].WriteSection3S(bw, index, section3S); } bw.FillInt32("Section3Count", section3S.Count); bw.Pad(16); bw.FillInt32("Section4Offset", (int)bw.Position); List <Fxr3.FfxEffectCallA> section4S = new List <Fxr3.FfxEffectCallA>(); this.RootEffectCall.Write(bw, section4S); this.RootEffectCall.WriteSection4S(bw, section4S); bw.FillInt32("Section4Count", section4S.Count); bw.Pad(16); bw.FillInt32("Section5Offset", (int)bw.Position); int section5Count = 0; for (int index = 0; index < section4S.Count; ++index) { section4S[index].WriteSection5S(bw, index, ref section5Count); } bw.FillInt32("Section5Count", section5Count); bw.Pad(16); bw.FillInt32("Section6Offset", (int)bw.Position); section5Count = 0; List <Fxr3.FfxActionCall> section6S = new List <Fxr3.FfxActionCall>(); for (int index = 0; index < section4S.Count; ++index) { section4S[index].WriteSection6S(bw, index, ref section5Count, section6S); } bw.FillInt32("Section6Count", section6S.Count); bw.Pad(16); bw.FillInt32("Section7Offset", (int)bw.Position); List <Fxr3.FfxProperty> section7S = new List <Fxr3.FfxProperty>(); for (int index = 0; index < section6S.Count; ++index) { section6S[index].WriteSection7S(bw, index, section7S); } bw.FillInt32("Section7Count", section7S.Count); bw.Pad(16); bw.FillInt32("Section8Offset", (int)bw.Position); List <Fxr3.Section8> section8S = new List <Fxr3.Section8>(); for (int index = 0; index < section7S.Count; ++index) { section7S[index].WriteSection8S(bw, index, section8S); } bw.FillInt32("Section8Count", section8S.Count); bw.Pad(16); bw.FillInt32("Section9Offset", (int)bw.Position); List <Fxr3.Section9> section9S = new List <Fxr3.Section9>(); for (int index = 0; index < section8S.Count; ++index) { section8S[index].WriteSection9S(bw, index, section9S); } bw.FillInt32("Section9Count", section9S.Count); bw.Pad(16); bw.FillInt32("Section10Offset", (int)bw.Position); List <Fxr3.Section10> section10S = new List <Fxr3.Section10>(); for (int index = 0; index < section6S.Count; ++index) { section6S[index].WriteSection10S(bw, index, section10S); } bw.FillInt32("Section10Count", section10S.Count); bw.Pad(16); bw.FillInt32("Section11Offset", (int)bw.Position); int section11Count = 0; for (int index = 0; index < section3S.Count; ++index) { section3S[index].WriteSection11S(bw, index, ref section11Count); } for (int index = 0; index < section6S.Count; ++index) { section6S[index].WriteSection11S(bw, index, ref section11Count); } for (int index = 0; index < section7S.Count; ++index) { section7S[index].WriteSection11S(bw, index, ref section11Count); } for (int index = 0; index < section8S.Count; ++index) { section8S[index].WriteSection11S(bw, index, ref section11Count); } for (int index = 0; index < section9S.Count; ++index) { section9S[index].WriteSection11S(bw, index, ref section11Count); } for (int index = 0; index < section10S.Count; ++index) { section10S[index].WriteSection11S(bw, index, ref section11Count); } bw.FillInt32("Section11Count", section11Count); bw.Pad(16); if (this.Version != Fxr3.FxrVersion.Sekiro) { return; } bw.FillInt32("Section12Offset", (int)bw.Position); bw.WriteInt32s((IList <int>) this.Section12S); bw.Pad(16); bw.FillInt32("Section13Offset", (int)bw.Position); bw.WriteInt32s((IList <int>) this.Section13S); bw.Pad(16); bw.FillInt32("Section14Offset", (int)bw.Position); }
public static void FillFXR1Varint(this BinaryWriterEx bw, string name, int v) { bw.FillInt32(name, v); //bw.WriteFXR1Garbage(); }
public void WriteWithContext(BinaryWriterEx bw, EzSembleContext context) { bw.WriteASCII(ESDMagicByFormat[FormatType]); bw.BigEndian = (FormatType == ESDFormatType.BigEndian32Bit || FormatType == ESDFormatType.BigEndian64Bit); context.IsBigEndian = bw.BigEndian; bw.WriteInt32(1); bw.WriteInt32(DarkSoulsCount); bw.WriteInt32(DarkSoulsCount); bw.WriteInt32(0x54); bw.ReserveInt32("DataSize"); bw.WriteInt32(6); bw.WriteInt32(LongFormat ? 0x48 : 0x2C); bw.WriteInt32(1); bw.WriteInt32(LongFormat ? 0x20 : 0x10); bw.WriteInt32(StateGroups.Count); int stateSize = LongFormat ? 0x48 : 0x24; bw.WriteInt32(stateSize); bw.WriteInt32(StateGroups.Values.Sum(sg => sg.Count + (sg.Count == 1 ? 0 : 1))); bw.WriteInt32(LongFormat ? 0x38 : 0x1C); bw.ReserveInt32("ConditionCount"); bw.WriteInt32(LongFormat ? 0x18 : 0x10); bw.ReserveInt32("CommandCallCount"); bw.WriteInt32(LongFormat ? 0x10 : 0x8); bw.ReserveInt32("CommandArgCount"); bw.ReserveInt32("ConditionOffsetsOffset"); bw.ReserveInt32("ConditionOffsetsCount"); bw.ReserveInt32("NameBlockOffset"); bw.WriteInt32(Name == null ? 0 : Name.Length + 1); bw.ReserveInt32("UnkOffset1"); bw.WriteInt32(0); bw.ReserveInt32("UnkOffset2"); bw.WriteInt32(0); long dataStart = bw.Position; bw.WriteInt32(Unk6C); bw.WriteInt32(Unk70); bw.WriteInt32(Unk74); bw.WriteInt32(Unk78); bw.WriteInt32(Unk7C); if (LongFormat) { bw.WriteInt32(0); } ReserveVarint(bw, LongFormat, "StateGroupsOffset"); WriteVarint(bw, LongFormat, StateGroups.Count); ReserveVarint(bw, LongFormat, "NameOffset"); WriteVarint(bw, LongFormat, Name == null ? 0 : Name.Length + 1); long unkNull = DarkSoulsCount == 1 ? 0 : -1; WriteVarint(bw, LongFormat, unkNull); WriteVarint(bw, LongFormat, unkNull); // Collect and sort all the IDs so everything is definitely in the same order everywhere List <long> stateGroupIDs = StateGroups.Keys.ToList(); stateGroupIDs.Sort(); var stateIDs = new Dictionary <long, List <long> >(); foreach (long groupID in stateGroupIDs) { stateIDs[groupID] = StateGroups[groupID].Keys.ToList(); stateIDs[groupID].Sort(); } if (StateGroups.Count == 0) { FillVarint(bw, LongFormat, "StateGroupsOffset", -1); } else { FillVarint(bw, LongFormat, "StateGroupsOffset", bw.Position - dataStart); foreach (long groupID in stateGroupIDs) { WriteVarint(bw, LongFormat, groupID); ReserveVarint(bw, LongFormat, $"StateGroup{groupID}:StatesOffset1"); WriteVarint(bw, LongFormat, StateGroups[groupID].Count); ReserveVarint(bw, LongFormat, $"StateGroup{groupID}:StatesOffset2"); } } var stateOffsets = new Dictionary <long, Dictionary <long, long> >(); var weirdStateOffsets = new List <long[]>(); foreach (long groupID in stateGroupIDs) { stateOffsets[groupID] = new Dictionary <long, long>(); FillVarint(bw, LongFormat, $"StateGroup{groupID}:StatesOffset1", bw.Position - dataStart); FillVarint(bw, LongFormat, $"StateGroup{groupID}:StatesOffset2", bw.Position - dataStart); long firstStateOffset = bw.Position; foreach (long stateID in stateIDs[groupID]) { stateOffsets[groupID][stateID] = bw.Position - dataStart; StateGroups[groupID][stateID].WriteHeader(context, bw, LongFormat, groupID, stateID); } if (StateGroups[groupID].Count > 1) { weirdStateOffsets.Add(new long[] { firstStateOffset, bw.Position }); bw.Position += stateSize; } } // Make a list of every unique condition var conditions = new Dictionary <long, List <Condition> >(); foreach (long groupID in stateGroupIDs) { conditions[groupID] = new List <Condition>(); void addCondition(Condition cond) { if (!conditions[groupID].Any(c => ReferenceEquals(cond, c))) { conditions[groupID].Add(cond); foreach (Condition subCond in cond.Subconditions) { addCondition(subCond); } } } foreach (State state in StateGroups[groupID].Values) { foreach (Condition cond in state.Conditions) { addCondition(cond); } } } bw.FillInt32("ConditionCount", conditions.Values.Sum(group => group.Count)); // Yes, I do in fact want this to be keyed by reference var conditionOffsets = new Dictionary <Condition, long>(); foreach (long groupID in stateGroupIDs) { for (int i = 0; i < conditions[groupID].Count; i++) { Condition cond = conditions[groupID][i]; cond.MetaRefID = conditionOffsets[cond] = bw.Position - dataStart; cond.WriteHeader(context, bw, LongFormat, groupID, i, stateOffsets[groupID]); } } var commands = new List <CommandCall>(); foreach (long groupID in stateGroupIDs) { foreach (long stateID in stateIDs[groupID]) { StateGroups[groupID][stateID].WriteCommandCalls(context, bw, LongFormat, groupID, stateID, dataStart, commands); } for (int i = 0; i < conditions[groupID].Count; i++) { conditions[groupID][i].WriteCommandCalls(context, bw, LongFormat, groupID, i, dataStart, commands); } } bw.FillInt32("CommandCallCount", commands.Count); bw.FillInt32("CommandArgCount", commands.Sum(command => command.Arguments.Count)); for (int i = 0; i < commands.Count; i++) { commands[i].WriteArgs(context, bw, LongFormat, i, dataStart); } bw.FillInt32("ConditionOffsetsOffset", (int)(bw.Position - dataStart)); int conditionOffsetsCount = 0; foreach (long groupID in stateGroupIDs) { foreach (long stateID in stateIDs[groupID]) { conditionOffsetsCount += StateGroups[groupID][stateID].WriteConditionOffsets(bw, LongFormat, groupID, stateID, dataStart, conditionOffsets); } for (int i = 0; i < conditions[groupID].Count; i++) { conditionOffsetsCount += conditions[groupID][i].WriteConditionOffsets(bw, LongFormat, groupID, i, dataStart, conditionOffsets); } } bw.FillInt32("ConditionOffsetsCount", conditionOffsetsCount); foreach (long groupID in stateGroupIDs) { for (int i = 0; i < conditions[groupID].Count; i++) { conditions[groupID][i].WriteEvaluator(context, bw, LongFormat, groupID, i, dataStart); } } for (int i = 0; i < commands.Count; i++) { commands[i].WriteBytecode(context, bw, LongFormat, i, dataStart); } bw.FillInt32("NameBlockOffset", (int)(bw.Position - dataStart)); if (Name == null) { FillVarint(bw, LongFormat, "NameOffset", -1); } else { bw.Pad(2); FillVarint(bw, LongFormat, "NameOffset", bw.Position - dataStart); bw.WriteUTF16(Name, true); } bw.FillInt32("UnkOffset1", (int)(bw.Position - dataStart)); bw.FillInt32("UnkOffset2", (int)(bw.Position - dataStart)); bw.FillInt32("DataSize", (int)(bw.Position - dataStart)); if (DarkSoulsCount == 1) { bw.Pad(4); } else if (DarkSoulsCount == 2) { bw.Pad(0x10); } foreach (long[] offsets in weirdStateOffsets) { bw.Position = offsets[0]; byte[] bytes = new byte[stateSize]; bw.Stream.Read(bytes, 0, stateSize); bw.Position = offsets[1]; bw.WriteBytes(bytes); } LastSavedHash = bw.GetMD5HashOfStream(); Metadata = ESDMetadata.Generate(this); }