From 1b0eb20ce25d803703e3e5abd4e11fd41f3d2f5a Mon Sep 17 00:00:00 2001 From: KillzXGaming Date: Sun, 1 Sep 2019 17:21:36 -0400 Subject: [PATCH] read and write USD1 section. Add support for reading/writing unknown sections for bflyt --- .../FileFormats/Layout/CAFE/BFLYT.cs | 194 ++++++++++++++++-- .../FileFormats/Layout/Common.cs | 14 +- 2 files changed, 189 insertions(+), 19 deletions(-) diff --git a/File_Format_Library/FileFormats/Layout/CAFE/BFLYT.cs b/File_Format_Library/FileFormats/Layout/CAFE/BFLYT.cs index e534e4a5..daedb0c2 100644 --- a/File_Format_Library/FileFormats/Layout/CAFE/BFLYT.cs +++ b/File_Format_Library/FileFormats/Layout/CAFE/BFLYT.cs @@ -236,8 +236,11 @@ namespace LayoutBXLYT.Cafe public TXL1 TextureList { get; set; } public MAT1 MaterialList { get; set; } public FNL1 FontList { get; set; } - // private List Sections; - // public List Panes = new List(); + public CNT1 Container { get; set; } + public USD1 UserData { get; set; } + + //As of now this should be empty but just for future proofing + private List UnknownSections = new List(); public int TotalPaneCount() { @@ -324,7 +327,7 @@ namespace LayoutBXLYT.Cafe string Signature = reader.ReadString(4, Encoding.ASCII); uint SectionSize = reader.ReadUInt32(); - SectionCommon section = new SectionCommon(); + SectionCommon section = new SectionCommon(Signature); switch (Signature) { case "lyt1": @@ -379,8 +382,6 @@ namespace LayoutBXLYT.Cafe SetPane(windowPanel, parentPane); currentPane = windowPanel; break; - case "cnt1": - break; case "pas1": if (currentPane != null) parentPane = currentPane; @@ -409,23 +410,20 @@ namespace LayoutBXLYT.Cafe currentGroupPane = parentGroupPane; parentGroupPane = currentGroupPane.Parent; break; + /* case "cnt1": + Container = new CNT1(reader, this); + break;*/ case "usd1": + UserData = new USD1(reader, this); break; //If the section is not supported store the raw bytes default: section.Data = reader.ReadBytes((int)SectionSize - 8); + UnknownSections.Add(section); break; } - //Check if we reached the end or not - long endPos = reader.Position; - if (reader.Position < pos + SectionSize) - { - int size = (int)(endPos - pos); - section.Data = reader.ReadBytes(size); - } section.SectionSize = SectionSize; - reader.SeekBegin(pos + SectionSize); } } @@ -476,6 +474,18 @@ namespace LayoutBXLYT.Cafe WritePanes(writer, RootPane, this, ref sectionCount); WriteGroupPanes(writer, RootGroup, this, ref sectionCount); + if (UserData != null) + { + WriteSection(writer, "usd1", UserData, () => UserData.Write(writer, this)); + sectionCount++; + } + + foreach (var section in UnknownSections) + { + WriteSection(writer, section.Signature, section, () => section.Write(writer, this)); + sectionCount++; + } + //Write the total section count using (writer.TemporarySeek(0x10, System.IO.SeekOrigin.Begin)) { @@ -535,8 +545,6 @@ namespace LayoutBXLYT.Cafe writer.WriteSignature(magic); writer.Write(uint.MaxValue); WriteMethod?.Invoke(); - if (section != null && section.Data != null) - writer.Write(section.Data); long endPos = writer.Position; @@ -548,6 +556,18 @@ namespace LayoutBXLYT.Cafe } } + public class CNT1 : SectionCommon + { + public CNT1(FileReader reader, Header header) + { + + } + + public override void Write(FileWriter writer, BxlytHeader header) + { + + } + } public class TexCoord { @@ -1069,6 +1089,150 @@ namespace LayoutBXLYT.Cafe } } + public class USD1 : SectionCommon + { + public List Entries = new List(); + + public USD1(FileReader reader, Header header) + { + long startPos = reader.Position - 8; + + ushort numEntries = reader.ReadUInt16(); + reader.ReadUInt16(); //padding + + for (int i = 0; i < numEntries; i++) + Entries.Add(new UserDataEntry(reader, startPos, header)); + } + + public override void Write(FileWriter writer, BxlytHeader header) + { + long startPos = writer.Position - 8; + + writer.Write((ushort)Entries.Count); + writer.Write((ushort)0); + + for (int i = 0; i < Entries.Count; i++) + Entries[i].Write(writer, startPos, header); + } + } + + public class UserDataEntry + { + public string Name { get; set; } + public DataType Type { get; private set; } + public byte Unknown { get; set; } + + private object data; + + public string GetString() + { + return (string)data; + } + + public float[] GetFloats() + { + return (float[])data; + } + + public int[] GetInts() + { + return (int[])data; + } + + public void SetStrings(string[] value) + { + data = value; + Type = DataType.String; + } + + public void GetFloats(float [] value) + { + data = value; + Type = DataType.Float; + } + + public void GetInts(int[] value) + { + data = value; + Type = DataType.Int; + } + + public UserDataEntry(FileReader reader, long startPos, Header header) + { + long pos = reader.Position; + + uint nameOffset = reader.ReadUInt32(); + uint dataOffset = reader.ReadUInt32(); + uint dataLength = reader.ReadUInt16(); + Type = reader.ReadEnum(false); + Unknown = reader.ReadByte(); + + reader.SeekBegin(pos + nameOffset); + Name = reader.ReadZeroTerminatedString(); + + reader.SeekBegin(pos + dataOffset); + switch (Type) + { + case DataType.String: + data = reader.ReadString((int)dataLength); + break; + case DataType.Int: + data = reader.ReadInt32s((int)dataLength); + break; + case DataType.Float: + data = reader.ReadSingles((int)dataLength); + break; + } + } + + public void Write(FileWriter writer, long startPos, BxlytHeader header) + { + long pos = writer.Position; + + writer.Write(0); //nameOffset + writer.Write(0); //dataOffset + writer.Write(GetDataLength()); + writer.Write(Type, false); + writer.Write(Unknown); + + writer.WriteUint32Offset(pos + 4, pos); + switch (Type) + { + case DataType.String: + writer.Write((string)data); + break; + case DataType.Int: + writer.Write((int[])data); + break; + case DataType.Float: + writer.Write((float[])data); + break; + } + + writer.WriteUint32Offset(pos, pos); + writer.WriteString(Name); + writer.Align(4); + } + + private int GetDataLength() + { + if (data is string) + return ((string)data).Length; + else if (data is int[]) + return ((int[])data).Length; + else if (data is float[]) + return ((float[])data).Length; + return 0; + } + + public enum DataType : byte + { + String, + Int, + Float, + } + } + public class PIC1 : PAN1 { public override string Signature { get; } = "pic1"; diff --git a/File_Format_Library/FileFormats/Layout/Common.cs b/File_Format_Library/FileFormats/Layout/Common.cs index 73a25ad5..4019582a 100644 --- a/File_Format_Library/FileFormats/Layout/Common.cs +++ b/File_Format_Library/FileFormats/Layout/Common.cs @@ -206,14 +206,20 @@ namespace LayoutBXLYT internal byte[] Data { get; set; } + public SectionCommon() + { + + } + + public SectionCommon(string signature) + { + Signature = signature; + } + public virtual void Write(FileWriter writer, BxlytHeader header) { - writer.WriteSignature(Signature); if (Data != null) - { - writer.Write(Data.Length + 8); writer.Write(Data); - } } }