internal void Write(BinaryWriterEx bw) { bw.WriteInt32(RegionIndex); bw.WriteInt32(Unk04); }
internal override void WriteTypeData(BinaryWriterEx bw) { bw.WriteInt32(UnkT00); bw.WriteInt32(UnkT04); bw.WritePattern(0x1C, 0x00); }
internal void WriteCells(BinaryWriterEx bw, int i, Layout layout) { bw.FillInt64($"RowOffset{i}", bw.Position); for (int j = 0; j < layout.Count; j++) { Cell cell = Cells[j]; Layout.Entry entry = layout[j]; string type = entry.Type; object value = cell.Value; if (entry.Name != cell.Name || type != cell.Type) { throw new FormatException("Layout does not match cells."); } if (type == "s8") { bw.WriteSByte((sbyte)value); } else if (type == "u8" || type == "x8") { bw.WriteByte((byte)value); } else if (type == "s16") { bw.WriteInt16((short)value); } else if (type == "u16" || type == "x16") { bw.WriteUInt16((ushort)value); } else if (type == "s32") { bw.WriteInt32((int)value); } else if (type == "u32" || type == "x32") { bw.WriteUInt32((uint)value); } else if (type == "f32") { bw.WriteSingle((float)value); } else if (type == "dummy8") { bw.WriteBytes((byte[])value); } else if (type == "fixstr") { bw.WriteFixStr((string)value, entry.Size); } else if (type == "fixstrW") { bw.WriteFixStrW((string)value, entry.Size); } else if (type == "b8") { byte b = 0; int k; for (k = 0; k < 8; k++) { if (j + k >= layout.Count || layout[j + k].Type != "b8") { break; } if ((bool)Cells[j + k].Value) { b |= (byte)(1 << k); } } j += k - 1; bw.WriteByte(b); } else if (type == "b32") { byte[] b = new byte[4]; int k; for (k = 0; k < 32; k++) { if (j + k >= layout.Count || layout[j + k].Type != "b32") { break; } if ((bool)Cells[j + k].Value) { b[k / 8] |= (byte)(1 << (k % 8)); } } j += k - 1; bw.WriteBytes(b); } } }
// <summary> // Convert the internal format to PC tpf format // </summary> public void PS4ToPC() { // Need to create a DDS Header BinaryWriterEx bw = new BinaryWriterEx(false); bw.WriteASCII("DDS "); bw.WriteInt32(124); bw.WriteUInt32(659463); // Flags bw.WriteUInt32((uint)Header.Height); bw.WriteUInt32((uint)Header.Width); bw.WriteUInt32(((uint)Header.Width * (uint)Header.Height) / 2); // Dummy pitch size bw.WriteUInt32(1); // Depth bw.WriteUInt32(Mipmaps); for (int i = 0; i < 11; i++) { bw.WriteInt32(0); } // Pixel format bw.WriteInt32(32); bw.WriteInt32(4); // Flags (compressed) bool writeExtendedHeader = false; if (Header.DXGIFormat == 71 || Header.DXGIFormat == 72) { bw.WriteASCII("DXT1"); } else if (Header.DXGIFormat == 73 || Header.DXGIFormat == 74 || Header.DXGIFormat == 75) { bw.WriteASCII("DXT3"); } else if (Header.DXGIFormat == 76 || Header.DXGIFormat == 77 || Header.DXGIFormat == 78) { bw.WriteASCII("DXT5"); } else if (Header.DXGIFormat == 79 || Header.DXGIFormat == 80 || Header.DXGIFormat == 81) { bw.WriteASCII("ATI1"); } else if (Header.DXGIFormat == 82 || Header.DXGIFormat == 83 || Header.DXGIFormat == 84) { bw.WriteASCII("ATI2"); } else { bw.WriteASCII("DX10"); writeExtendedHeader = true; } bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteUInt32(0x401008); // Caps if (Cubemap) { bw.WriteUInt32(0xFE00); } else { bw.WriteUInt32(0); } bw.WriteUInt32(0); bw.WriteUInt32(0); bw.WriteUInt32(0); // DX10 extended header if (writeExtendedHeader) { bw.WriteInt32(Header.DXGIFormat); bw.WriteUInt32(3); // 2D texture if (Cubemap) { bw.WriteUInt32(0x4); } else { bw.WriteUInt32(0); } bw.WriteUInt32(1); // Array Size bw.WriteUInt32(0); // Misc } // Next attempt to unswizzle the texture byte[] unswizzled = new byte[Bytes.Length]; for (int i = 0; i < unswizzled.Length; i++) { unswizzled[i] = Bytes[i]; } uint blockSize = 16; if (Header.DXGIFormat == 71 || Header.DXGIFormat == 72 || Header.DXGIFormat == 79 || Header.DXGIFormat == 80 || Header.DXGIFormat == 81) { blockSize = 8; } int mipBase = 0; int mipBaseSrc = 0; for (int miplevel = 0; miplevel < Mipmaps; miplevel++) { uint bytesPerLine = Math.Max((uint)Header.Width >> miplevel, 1) * blockSize / 4; int heightBlock = Math.Max((Header.Height / 4) >> miplevel, 1); int widthBlock = Math.Max((Header.Width / 4) >> miplevel, 1); // Convert swizzled to linear strided int index = 0; for (int y = 0; y < heightBlock; y++) { for (int x = 0; x < widthBlock; x++) { int mx = x; int my = y; if (widthBlock > 1 && heightBlock > 1) { MapBlockPosition(x, y, widthBlock, 2, out mx, out my); } if (widthBlock > 2 && heightBlock > 2) { MapBlockPosition(mx, my, widthBlock, 4, out mx, out my); } if (widthBlock > 4 && heightBlock > 4) { MapBlockPosition(mx, my, widthBlock, 8, out mx, out my); } int destinationIndex = (int)blockSize * (my * widthBlock + mx); for (int i = 0; i < blockSize; i++) { unswizzled[mipBase + destinationIndex + i] = Bytes[mipBaseSrc + index]; index += 1; } } } mipBase += index; if (index < 512) { mipBaseSrc += 512; } else { mipBaseSrc += index; } } // Append the rest of the original texture and update bw.WriteBytes(unswizzled); Bytes = bw.FinishBytes(); }
internal void Write(BinaryWriterEx bw) { bw.WriteInt32(0); bw.WriteInt32(Unk04); bw.WriteInt32(4); bw.WriteInt32(4); WriteMarker(bw, 0xA3); bw.WriteShiftJISLengthPrefixed(Name, 0xA3); bw.WriteShiftJISLengthPrefixed(Type.ToString().ToLower(), 0x04); bw.WriteInt32(1); bw.WriteInt32(0); bw.ReserveInt32("ValueSize"); int valueStart = (int)bw.Position; if (Type == ParamType.Bool) { bw.WriteByte(0); } else if (Type == ParamType.Int || Type == ParamType.Int2) { bw.WriteByte(1); } else if (Type == ParamType.Float || Type == ParamType.Float2 || Type == ParamType.Float3 || Type == ParamType.Float4) { bw.WriteByte(2); } bw.WriteByte(0x10); bw.WriteByte(0); bw.WriteByte(0); bw.WriteInt32(1); if (Type == ParamType.Bool) { WriteMarker(bw, 0xC0); } else if (Type == ParamType.Int || Type == ParamType.Int2) { WriteMarker(bw, 0xC5); } else if (Type == ParamType.Float || Type == ParamType.Float2 || Type == ParamType.Float3 || Type == ParamType.Float4) { WriteMarker(bw, 0xCA); } if (Type == ParamType.Bool || Type == ParamType.Float || Type == ParamType.Int) { bw.WriteInt32(1); } else if (Type == ParamType.Float2 || Type == ParamType.Int2) { bw.WriteInt32(2); } else if (Type == ParamType.Float3) { bw.WriteInt32(3); } else if (Type == ParamType.Float4) { bw.WriteInt32(4); } if (Type == ParamType.Int) { bw.WriteInt32((int)Value); } else if (Type == ParamType.Int2) { bw.WriteInt32s((int[])Value); } else if (Type == ParamType.Bool) { bw.WriteBoolean((bool)Value); } else if (Type == ParamType.Float) { bw.WriteSingle((float)Value); } else if (Type == ParamType.Float2) { bw.WriteSingles((float[])Value); } else if (Type == ParamType.Float3) { bw.WriteSingles((float[])Value); } else if (Type == ParamType.Float4) { bw.WriteSingles((float[])Value); } bw.FillInt32("ValueSize", (int)bw.Position - valueStart); bw.WriteByte(4); bw.Pad(4); bw.WriteInt32(0); }
internal override void Write(BinaryWriterEx bw) { if (layout == null) { throw new InvalidOperationException("Params cannot be written without a layout."); } Rows.Sort((r1, r2) => r1.ID.CompareTo(r2.ID)); bw.BigEndian = false; bw.ReserveInt32("NameOffset"); bw.WriteInt16(0); bw.WriteInt16(Unk1); bw.WriteInt16(Unk2); bw.WriteUInt16((ushort)Rows.Count); if (FixStrID) { bw.WriteFixStr(ID, 0x20); } else { bw.WriteInt32(0); bw.ReserveInt32("IDOffset"); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); } bw.WriteByte(0); bw.WriteByte(Unk3); bw.WriteByte(Unk4); bw.WriteByte(0); bw.ReserveInt64("DataStart"); bw.WriteInt32(0); bw.WriteInt32(0); for (int i = 0; i < Rows.Count; i++) { Rows[i].WriteHeader(bw, i); } bw.FillInt64("DataStart", bw.Position); for (int i = 0; i < Rows.Count; i++) { Rows[i].WriteCells(bw, i, layout); } bw.FillInt32("NameOffset", (int)bw.Position); if (FixStrID) { if (Unk4 == 6) { bw.WriteShiftJIS(Name, true); } else if (Unk4 == 7) { bw.WriteUTF16(Name, true); } } else { bw.WriteShiftJIS(Name, true); bw.FillInt32("IDOffset", (int)bw.Position); bw.WriteASCII(ID, true); } for (int i = 0; i < Rows.Count; i++) { Rows[i].WriteName(bw, i, Unk4); } }
internal override void Write(BinaryWriterEx bw, int id) { base.Write(bw, id); bw.WriteInt32(SoundType); bw.WriteInt32(SoundID); }
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 Write(BinaryWriterEx bw, List <Section3> section3s) { int index = section3s.Count; bw.WriteInt16(11); bw.WriteByte(0); bw.WriteByte(1); bw.WriteInt32(0); bw.WriteInt32(Unk08); bw.WriteInt32(0); bw.WriteInt32(Unk10); bw.WriteInt32(0); bw.WriteInt32(1); bw.WriteInt32(0); bw.ReserveInt32($"Section3Section11Offset1[{index}]"); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(Unk38); bw.WriteInt32(0); bw.WriteInt32(1); bw.WriteInt32(0); bw.ReserveInt32($"Section3Section11Offset2[{index}]"); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); section3s.Add(this); }
internal void Write(BinaryWriterEx bw, List <FFXDrawEntityHost> section6s) { int index = section6s.Count; bw.WriteInt16(Unk00); bw.WriteBoolean(Unk02); bw.WriteBoolean(Unk03); bw.WriteInt32(Unk04); bw.WriteInt32(Section11s1.Count); bw.WriteInt32(Section10s.Count); bw.WriteInt32(Properties1.Count); bw.WriteInt32(Section11s2.Count); bw.WriteInt32(0); bw.WriteInt32(Properties2.Count); bw.ReserveInt32($"Section6Section11sOffset[{index}]"); bw.WriteInt32(0); bw.ReserveInt32($"Section6Section10sOffset[{index}]"); bw.WriteInt32(0); bw.ReserveInt32($"Section6Section7sOffset[{index}]"); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); section6s.Add(this); }
protected override void Write(BinaryWriterEx bw) { bw.WriteASCII("FXR\0"); bw.WriteInt16(0); bw.WriteUInt16((ushort)Version); bw.WriteInt32(1); bw.WriteInt32(ID); bw.ReserveInt32("Section1Offset"); bw.WriteInt32(1); bw.ReserveInt32("Section2Offset"); bw.WriteInt32(Section1Tree.Section2s.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 (Version == FXRVersion.Sekiro) { bw.ReserveInt32("Section12Offset"); bw.WriteInt32(Section12s.Count); bw.ReserveInt32("Section13Offset"); bw.WriteInt32(Section13s.Count); bw.ReserveInt32("Section14Offset"); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(0); } bw.FillInt32("Section1Offset", (int)bw.Position); Section1Tree.Write(bw); bw.Pad(0x10); bw.FillInt32("Section2Offset", (int)bw.Position); Section1Tree.WriteSection2s(bw); bw.Pad(0x10); bw.FillInt32("Section3Offset", (int)bw.Position); List <Section2> section2s = Section1Tree.Section2s; var section3s = new List <Section3>(); for (int i = 0; i < section2s.Count; i++) { section2s[i].WriteSection3s(bw, i, section3s); } bw.FillInt32("Section3Count", section3s.Count); bw.Pad(0x10); bw.FillInt32("Section4Offset", (int)bw.Position); var section4s = new List <Section4>(); Section4Tree.Write(bw, section4s); Section4Tree.WriteSection4s(bw, section4s); bw.FillInt32("Section4Count", section4s.Count); bw.Pad(0x10); bw.FillInt32("Section5Offset", (int)bw.Position); int section5Count = 0; for (int i = 0; i < section4s.Count; i++) { section4s[i].WriteSection5s(bw, i, ref section5Count); } bw.FillInt32("Section5Count", section5Count); bw.Pad(0x10); bw.FillInt32("Section6Offset", (int)bw.Position); section5Count = 0; var section6s = new List <FFXDrawEntityHost>(); for (int i = 0; i < section4s.Count; i++) { section4s[i].WriteSection6s(bw, i, ref section5Count, section6s); } bw.FillInt32("Section6Count", section6s.Count); bw.Pad(0x10); bw.FillInt32("Section7Offset", (int)bw.Position); var section7s = new List <FFXProperty>(); for (int i = 0; i < section6s.Count; i++) { section6s[i].WriteSection7s(bw, i, section7s); } bw.FillInt32("Section7Count", section7s.Count); bw.Pad(0x10); bw.FillInt32("Section8Offset", (int)bw.Position); var section8s = new List <Section8>(); for (int i = 0; i < section7s.Count; i++) { section7s[i].WriteSection8s(bw, i, section8s); } bw.FillInt32("Section8Count", section8s.Count); bw.Pad(0x10); bw.FillInt32("Section9Offset", (int)bw.Position); var section9s = new List <Section9>(); for (int i = 0; i < section8s.Count; i++) { section8s[i].WriteSection9s(bw, i, section9s); } bw.FillInt32("Section9Count", section9s.Count); bw.Pad(0x10); bw.FillInt32("Section10Offset", (int)bw.Position); var section10s = new List <Section10>(); for (int i = 0; i < section6s.Count; i++) { section6s[i].WriteSection10s(bw, i, section10s); } bw.FillInt32("Section10Count", section10s.Count); bw.Pad(0x10); bw.FillInt32("Section11Offset", (int)bw.Position); int section11Count = 0; for (int i = 0; i < section3s.Count; i++) { section3s[i].WriteSection11s(bw, i, ref section11Count); } for (int i = 0; i < section6s.Count; i++) { section6s[i].WriteSection11s(bw, i, ref section11Count); } for (int i = 0; i < section7s.Count; i++) { section7s[i].WriteSection11s(bw, i, ref section11Count); } for (int i = 0; i < section8s.Count; i++) { section8s[i].WriteSection11s(bw, i, ref section11Count); } for (int i = 0; i < section9s.Count; i++) { section9s[i].WriteSection11s(bw, i, ref section11Count); } for (int i = 0; i < section10s.Count; i++) { section10s[i].WriteSection11s(bw, i, ref section11Count); } bw.FillInt32("Section11Count", section11Count); bw.Pad(0x10); if (Version == FXRVersion.Sekiro) { bw.FillInt32("Section12Offset", (int)bw.Position); bw.WriteInt32s(Section12s); bw.Pad(0x10); bw.FillInt32("Section13Offset", (int)bw.Position); bw.WriteInt32s(Section13s); bw.Pad(0x10); bw.FillInt32("Section14Offset", (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 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); }
internal override void Write(BinaryWriterEx bw, int id) { base.Write(bw, id); bw.WriteInt32(0); bw.WriteInt32(0); }
internal override void Write(BinaryWriterEx bw) { bw.BigEndian = false; bw.WriteInt32(0); bw.ReserveInt32("FileSize"); int fileStart = (int)bw.Position; bw.WriteInt32(0); bw.WriteInt32(3); WriteMarker(bw, 0x01); bw.WriteInt32(0); bw.WriteInt32(0x1C); bw.WriteInt32(1); bw.WriteInt32(2); WriteMarker(bw, 0xB0); bw.WriteInt32(4); bw.WriteASCII("MTD "); WriteMarker(bw, 0x34); bw.WriteInt32(0x3E8); WriteMarker(bw, 0x01); bw.WriteInt32(0); bw.ReserveInt32("DataSize"); bw.WriteInt32(2); bw.WriteInt32(4); int dataStart = (int)bw.Position; WriteMarker(bw, 0xA3); bw.WriteShiftJISLengthPrefixed(ShaderPath, 0xA3); bw.WriteShiftJISLengthPrefixed(Description, 0x03); bw.WriteInt32(1); bw.WriteInt32(0); bw.ReserveInt32("ParamSize"); bw.WriteInt32(3); bw.WriteInt32(4); WriteMarker(bw, 0xA3); bw.WriteInt32(0); int paramStart = (int)bw.Position; WriteMarker(bw, 0x03); bw.WriteInt32(Params.Count); foreach (Param internalEntry in Params) { internalEntry.Write(bw); } WriteMarker(bw, 0x03); bw.WriteInt32(Textures.Count); foreach (Texture externalEntry in Textures) { externalEntry.Write(bw); } WriteMarker(bw, 0x04); bw.WriteInt32(0); WriteMarker(bw, 0x04); bw.WriteInt32(0); WriteMarker(bw, 0x04); bw.WriteInt32(0); int position = (int)bw.Position; bw.FillInt32("FileSize", position - fileStart); bw.FillInt32("DataSize", position - dataStart); bw.FillInt32("ParamSize", position - paramStart); }
internal override void Write(BinaryWriterEx bw, int id) { base.Write(bw, id); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt32(ThinkParamID); bw.WriteInt32(NPCParamID); bw.WriteInt32(TalkID); bw.WriteSingle(UnkT14); bw.WriteInt32(CharaInitID); bw.WriteInt32(CollisionIndex); bw.WriteInt32(0); bw.WriteInt32(0); bw.WriteInt16s(MovePointIndices); bw.WriteInt32(DefaultStandbyAnimation); bw.WriteInt32(UnkT3C); }
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]); } }