Example #1
0
 internal override void WriteTypeData(BinaryWriterEx bw)
 {
     bw.WriteInt64(UnkT00);
     bw.WriteNull(0x18, false);
 }
Example #2
0
 internal void WriteHeader(BinaryWriterEx bw, int i)
 {
     bw.WriteInt64(ID);
     bw.ReserveInt64($"RowOffset{i}");
     bw.ReserveInt64($"NameOffset{i}");
 }
Example #3
0
 internal override void WriteTypeData(BinaryWriterEx bw)
 {
     bw.WriteInt64(UnkT00);
 }
Example #4
0
        /// <summary>
        /// Serializes file data to a stream.
        /// </summary>
        protected 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 = BigEndian;
            void WriteFormat()
            {
                bw.WriteByte((byte)(BigEndian ? 0xFF : 0x00));
                bw.WriteByte(Format2D);
                bw.WriteByte(Format2E);
                bw.WriteByte(Format2F);
            }

            // DeS, DS1
            if ((Format2D & 0x7F) < 3)
            {
                bw.ReserveUInt32("StringsOffset");
                bw.ReserveUInt16("DataStart");
                bw.WriteInt16(Unk06);
                bw.WriteInt16(Unk08);
                bw.WriteUInt16((ushort)Rows.Count);
                bw.WriteFixStr(ID, 0x20, 0x20);
                WriteFormat();
            }
            // DS2
            else if ((Format2D & 0x7F) == 3)
            {
                bw.ReserveUInt32("StringsOffset");
                bw.WriteInt16(0);
                bw.WriteInt16(Unk06);
                bw.WriteInt16(Unk08);
                bw.WriteUInt16((ushort)Rows.Count);
                bw.WriteFixStr(ID, 0x20, 0x20);
                WriteFormat();
                bw.ReserveUInt32("DataStart");
                bw.WriteInt32(0);
                bw.WriteInt32(0);
                bw.WriteInt32(0);
            }
            // SotFS, BB
            else if ((Format2D & 0x7F) == 4)
            {
                bw.ReserveUInt32("StringsOffset");
                bw.WriteInt16(0);
                bw.WriteInt16(Unk06);
                bw.WriteInt16(Unk08);
                bw.WriteUInt16((ushort)Rows.Count);
                bw.WriteFixStr(ID, 0x20, 0x00);
                WriteFormat();
                bw.ReserveInt64("DataStart");
                bw.WriteInt64(0);
            }
            // DS3, SDT
            else
            {
                bw.ReserveUInt32("StringsOffset");
                bw.WriteInt16(0);
                bw.WriteInt16(Unk06);
                bw.WriteInt16(Unk08);
                bw.WriteUInt16((ushort)Rows.Count);
                bw.WriteInt32(0);
                bw.ReserveInt64("IDOffset");
                bw.WritePattern(0x14, 0x00);
                WriteFormat();
                bw.ReserveInt64("DataStart");
                bw.WriteInt64(0);
            }

            for (int i = 0; i < Rows.Count; i++)
            {
                Rows[i].WriteHeader(bw, Format2D, i);
            }

            if ((Format2D & 0x7F) < 3)
            {
                bw.FillUInt16("DataStart", (ushort)bw.Position);
            }
            else if ((Format2D & 0x7F) == 3)
            {
                bw.FillUInt32("DataStart", (uint)bw.Position);
            }
            else
            {
                bw.FillInt64("DataStart", bw.Position);
            }

            for (int i = 0; i < Rows.Count; i++)
            {
                Rows[i].WriteCells(bw, Format2D, i, layout);
            }

            bw.FillUInt32("StringsOffset", (uint)bw.Position);

            if ((Format2D & 0x7F) > 4)
            {
                bw.FillInt64("IDOffset", bw.Position);
                bw.WriteASCII(ID, true);
            }

            for (int i = 0; i < Rows.Count; i++)
            {
                Rows[i].WriteName(bw, Format2D, i);
            }
        }
Example #5
0
                internal void WriteDefaultValue(BinaryWriterEx bw)
                {
                    if (ValueToAssert != null)
                    {
                        WriteAssertValue(bw);
                    }
                    else if (DefaultValue == null)
                    {
                        switch (Type)
                        {
                        case ParamType.aob:
                            for (int i = 0; i < AobLength; i++)
                            {
                                bw.WriteByte(0);
                            }
                            break;

                        case ParamType.b:
                        case ParamType.u8:
                        case ParamType.x8: bw.WriteByte(0); break;

                        case ParamType.s8: bw.WriteSByte(0); break;

                        case ParamType.u16:
                        case ParamType.x16: bw.WriteUInt16(0); break;

                        case ParamType.s16: bw.WriteInt16(0); break;

                        case ParamType.u32:
                        case ParamType.x32: bw.WriteUInt32(0); break;

                        case ParamType.s32: bw.WriteInt32(0); break;

                        case ParamType.u64:
                        case ParamType.x64: bw.WriteUInt64(0); break;

                        case ParamType.s64: bw.WriteInt64(0); break;

                        case ParamType.f32: bw.WriteSingle(0); break;

                        case ParamType.f64: bw.WriteDouble(0); break;

                        default: throw new Exception($"Invalid ParamTemplate ParamType: {Type.ToString()}");
                        }
                    }
                    else
                    {
                        switch (Type)
                        {
                        case ParamType.aob:
                            var assertAob = (byte[])DefaultValue;
                            bw.WriteBytes(assertAob);
                            break;

                        case ParamType.b:
                        case ParamType.u8:
                        case ParamType.x8: bw.WriteByte((byte)DefaultValue); break;

                        case ParamType.s8: bw.WriteSByte((sbyte)DefaultValue); break;

                        case ParamType.u16:
                        case ParamType.x16: bw.WriteUInt16((ushort)DefaultValue); break;

                        case ParamType.s16: bw.WriteInt16((short)DefaultValue); break;

                        case ParamType.u32:
                        case ParamType.x32: bw.WriteUInt32((uint)DefaultValue); break;

                        case ParamType.s32: bw.WriteInt32((int)DefaultValue); break;

                        case ParamType.u64:
                        case ParamType.x64: bw.WriteUInt64((ulong)DefaultValue); break;

                        case ParamType.s64: bw.WriteInt64((long)DefaultValue); break;

                        case ParamType.f32: bw.WriteSingle((float)DefaultValue); break;

                        case ParamType.f64: bw.WriteDouble((double)DefaultValue); break;

                        default: throw new Exception($"Invalid ParamTemplate ParamType: {Type.ToString()}");
                        }
                    }
                }
Example #6
0
 internal void WriteHeader(BinaryWriterEx bw, int i)
 {
     bw.WriteInt64(ID);
     bw.ReserveInt64($"AnimationOffset{i}");
 }
Example #7
0
        /// <summary>
        /// Serializes file data to a stream.
        /// </summary>
        protected override void Write(BinaryWriterEx bw)
        {
            if (AppliedParamdef == null)
            {
                throw new InvalidOperationException("Params cannot be written without applying a paramdef.");
            }

            bw.BigEndian = BigEndian;
            void WriteFormat()
            {
                bw.WriteByte((byte)(BigEndian ? 0xFF : 0x00));
                bw.WriteByte(Format2D);
                bw.WriteByte(Format2E);
                bw.WriteByte(Format2F);
            }

            // DeS, DS1
            if ((Format2D & 0x7F) < 3)
            {
                bw.ReserveUInt32("StringsOffset");
                bw.ReserveUInt16("DataStart");
                bw.WriteInt16(Unk06);
                bw.WriteInt16(Unk08);
                bw.WriteUInt16((ushort)Rows.Count);
                bw.WriteFixStr(ParamType, 0x20, (byte)((Format2D & 0x7F) < 2 ? 0x20 : 0x00));
                WriteFormat();
            }
            // DS2
            else if ((Format2D & 0x7F) == 3)
            {
                bw.ReserveUInt32("StringsOffset");
                bw.WriteInt16(0);
                bw.WriteInt16(Unk06);
                bw.WriteInt16(Unk08);
                bw.WriteUInt16((ushort)Rows.Count);
                bw.WriteFixStr(ParamType, 0x20, 0x20);
                WriteFormat();
                bw.ReserveUInt32("DataStart");
                bw.WriteInt32(0);
                bw.WriteInt32(0);
                bw.WriteInt32(0);
            }
            // SotFS, BB
            else if ((Format2D & 0x7F) == 4)
            {
                bw.ReserveUInt32("StringsOffset");
                bw.WriteInt16(0);
                bw.WriteInt16(Unk06);
                bw.WriteInt16(Unk08);
                bw.WriteUInt16((ushort)Rows.Count);
                bw.WriteFixStr(ParamType, 0x20, 0x00);
                WriteFormat();
                bw.ReserveInt64("DataStart");
                bw.WriteInt64(0);
            }
            // DS3, SDT
            else
            {
                bw.ReserveUInt32("StringsOffset");
                bw.WriteInt16(0);
                bw.WriteInt16(Unk06);
                bw.WriteInt16(Unk08);
                bw.WriteUInt16((ushort)Rows.Count);
                bw.WriteInt32(0);
                bw.ReserveInt64("IDOffset");
                bw.WritePattern(0x14, 0x00);
                WriteFormat();
                bw.ReserveInt64("DataStart");
                bw.WriteInt64(0);
            }

            for (int i = 0; i < Rows.Count; i++)
            {
                Rows[i].WriteHeader(bw, Format2D, i);
            }

            if ((Format2D & 0x7F) < 2)
            {
                bw.WritePattern(0x20, 0x00);
            }
            if ((Format2D & 0x7F) < 3)
            {
                bw.FillUInt16("DataStart", (ushort)bw.Position);
            }
            else if ((Format2D & 0x7F) == 3)
            {
                bw.FillUInt32("DataStart", (uint)bw.Position);
            }
            else
            {
                bw.FillInt64("DataStart", bw.Position);
            }

            for (int i = 0; i < Rows.Count; i++)
            {
                Rows[i].WriteCells(bw, Format2D, i);
            }

            bw.FillUInt32("StringsOffset", (uint)bw.Position);

            if ((Format2D & 0x7F) > 4)
            {
                bw.FillInt64("IDOffset", bw.Position);
                bw.WriteASCII(ParamType, true);
            }

            for (int i = 0; i < Rows.Count; i++)
            {
                Rows[i].WriteName(bw, Format2D, Format2E, i);
            }
            // DeS and BB sometimes (but not always) include some useless padding here
        }
Example #8
0
 internal void Write(BinaryWriterEx bw)
 {
     bw.WriteInt64(StartOffset);
     bw.WriteInt64(EndOffset);
 }
Example #9
0
        /// <summary>
        /// Serializes file data to a stream.
        /// </summary>
        protected override void Write(BinaryWriterEx bw)
        {
            bw.BigEndian = BigEndian;
            bool wide = Version == FMGVersion.DarkSouls3;

            bw.WriteByte(0);
            bw.WriteBoolean(bw.BigEndian);
            bw.WriteByte((byte)Version);
            bw.WriteByte(0);

            bw.ReserveInt32("FileSize");
            bw.WriteByte(1);
            bw.WriteByte((byte)(Version == FMGVersion.DemonsSouls ? 0xFF : 0x00));
            bw.WriteByte(0);
            bw.WriteByte(0);
            bw.ReserveInt32("GroupCount");
            bw.WriteInt32(Entries.Count);

            if (wide)
            {
                bw.WriteInt32(0xFF);
            }

            if (wide)
            {
                bw.ReserveInt64("StringOffsets");
            }
            else
            {
                bw.ReserveInt32("StringOffsets");
            }

            if (wide)
            {
                bw.WriteInt64(0);
            }
            else
            {
                bw.WriteInt32(0);
            }

            int groupCount = 0;

            Entries.Sort((e1, e2) => e1.ID.CompareTo(e2.ID));
            for (int i = 0; i < Entries.Count; i++)
            {
                bw.WriteInt32(i);
                bw.WriteInt32(Entries[i].ID);
                while (i < Entries.Count - 1 && Entries[i + 1].ID == Entries[i].ID + 1)
                {
                    i++;
                }
                bw.WriteInt32(Entries[i].ID);

                if (wide)
                {
                    bw.WriteInt32(0);
                }

                groupCount++;
            }
            bw.FillInt32("GroupCount", groupCount);

            if (wide)
            {
                bw.FillInt64("StringOffsets", bw.Position);
            }
            else
            {
                bw.FillInt32("StringOffsets", (int)bw.Position);
            }

            for (int i = 0; i < Entries.Count; i++)
            {
                if (wide)
                {
                    bw.ReserveInt64($"StringOffset{i}");
                }
                else
                {
                    bw.ReserveInt32($"StringOffset{i}");
                }
            }

            for (int i = 0; i < Entries.Count; i++)
            {
                string text = Entries[i].Text;

                if (wide)
                {
                    bw.FillInt64($"StringOffset{i}", text == null ? 0 : bw.Position);
                }
                else
                {
                    bw.FillInt32($"StringOffset{i}", text == null ? 0 : (int)bw.Position);
                }

                if (text != null)
                {
                    bw.WriteUTF16(Entries[i].Text, true);
                }
            }

            bw.FillInt32("FileSize", (int)bw.Position);
        }
Example #10
0
            internal void Write(BinaryWriterEx bw, long nameOffset, int version, bool longOffsets)
            {
                bw.WriteUInt32(Unk00);
                bw.WriteUInt32(Unk04);
                bw.WriteUInt32(Unk08);
                bw.WriteUInt32(Unk0C);

                if (longOffsets)
                {
                    bw.WriteInt64(nameOffset);
                }
                else
                {
                    bw.WriteInt32((int)nameOffset);
                }

                bw.WriteUInt32((uint)Type);
                bw.WriteBoolean(Unk1C);
                bw.WriteByte(DiffuseColor.R);
                bw.WriteByte(DiffuseColor.G);
                bw.WriteByte(DiffuseColor.B);
                bw.WriteSingle(DiffusePower);
                bw.WriteByte(SpecularColor.R);
                bw.WriteByte(SpecularColor.G);
                bw.WriteByte(SpecularColor.B);
                bw.WriteBoolean(CastShadows);
                bw.WriteSingle(SpecularPower);
                bw.WriteSingle(ConeAngle);
                bw.WriteSingle(Unk30);
                bw.WriteSingle(Unk34);
                bw.WriteVector3(Position);
                bw.WriteVector3(Rotation);
                bw.WriteInt32(Unk50);
                bw.WriteSingle(Unk54);
                bw.WriteSingle(Radius);
                bw.WriteInt32(Unk5C);
                bw.WriteInt32(0);
                bw.WriteBytes(Unk64);
                bw.WriteSingle(Unk68);
                bw.WriteByte(ShadowColor.R);
                bw.WriteByte(ShadowColor.G);
                bw.WriteByte(ShadowColor.B);
                bw.WriteByte(ShadowColor.A);
                bw.WriteSingle(Unk70);
                bw.WriteSingle(FlickerIntervalMin);
                bw.WriteSingle(FlickerIntervalMax);
                bw.WriteSingle(FlickerBrightnessMult);
                bw.WriteInt32(Unk80);
                bw.WriteBytes(Unk84);
                bw.WriteSingle(Unk88);
                bw.WriteInt32(0);
                bw.WriteSingle(Unk90);
                bw.WriteInt32(0);
                bw.WriteSingle(Unk98);
                bw.WriteSingle(NearClip);
                bw.WriteBytes(UnkA0);
                bw.WriteSingle(Sharpness);
                bw.WriteInt32(0);
                bw.WriteSingle(UnkAC);

                if (longOffsets)
                {
                    bw.WriteInt64(0);
                }
                else
                {
                    bw.WriteInt32(0);
                }

                bw.WriteSingle(Width);
                bw.WriteSingle(UnkBC);
                bw.WriteBytes(UnkC0);
                bw.WriteSingle(UnkC4);

                if (version >= 16)
                {
                    bw.WriteSingle(UnkC8);
                    bw.WriteSingle(UnkCC);
                    bw.WriteSingle(UnkD0);
                    bw.WriteSingle(UnkD4);
                    bw.WriteSingle(UnkD8);
                    bw.WriteInt32(UnkDC);
                    bw.WriteSingle(UnkE0);
                    bw.WriteInt32(0);
                }
            }
Example #11
0
        /// <summary>
        /// Writes BND4 data to a BinaryWriterEx.
        /// </summary>
        internal override void Write(BinaryWriterEx bw)
        {
            bw.BigEndian = BigEndian;

            bw.WriteASCII("BND4");
            bw.WriteBoolean(Flag1);
            bw.WriteBoolean(Flag2);
            bw.WriteByte(0);
            bw.WriteByte(0);

            bw.WriteInt32(0x10000);
            bw.WriteInt32(Files.Count);
            bw.WriteInt64(0x40);
            bw.WriteFixStr(Timestamp, 8);
            bw.WriteInt64(Binder.FileHeaderSize(Format));
            bw.ReserveInt64("DataStart");

            bw.WriteBoolean(Unicode);
            bw.WriteByte((byte)Format);
            bw.WriteByte(Extended);
            bw.WriteByte(0);

            bw.WriteInt32(0);
            if (Extended == 4)
            {
                bw.ReserveInt64("HashGroups");
            }
            else
            {
                bw.WriteInt64(0);
            }

            for (int i = 0; i < Files.Count; i++)
            {
                WriteFile(Files[i], bw, i, Format);
            }

            if (Binder.HasName(Format))
            {
                for (int i = 0; i < Files.Count; i++)
                {
                    BinderFile file = Files[i];
                    bw.FillUInt32($"FileName{i}", (uint)bw.Position);
                    if (Unicode)
                    {
                        bw.WriteUTF16(file.Name, true);
                    }
                    else
                    {
                        bw.WriteShiftJIS(file.Name, true);
                    }
                }
            }

            if (Extended == 4)
            {
                uint groupCount = 0;
                for (uint p = (uint)Files.Count / 7; p <= 100000; p++)
                {
                    if (SFUtil.IsPrime(p))
                    {
                        groupCount = p;
                        break;
                    }
                }

                if (groupCount == 0)
                {
                    throw new InvalidOperationException("Hash group count not determined in BND4.");
                }

                var hashLists = new List <PathHash> [groupCount];
                for (int i = 0; i < groupCount; i++)
                {
                    hashLists[i] = new List <PathHash>();
                }

                for (int i = 0; i < Files.Count; i++)
                {
                    var  pathHash = new PathHash(i, Files[i].Name);
                    uint group    = pathHash.Hash % groupCount;
                    hashLists[group].Add(pathHash);
                }

                for (int i = 0; i < groupCount; i++)
                {
                    hashLists[i].Sort((ph1, ph2) => ph1.Hash.CompareTo(ph2.Hash));
                }

                var hashGroups = new List <HashGroup>();
                var pathHashes = new List <PathHash>();

                int count = 0;
                foreach (List <PathHash> hashList in hashLists)
                {
                    int index = count;
                    foreach (PathHash pathHash in hashList)
                    {
                        pathHashes.Add(pathHash);
                        count++;
                    }

                    hashGroups.Add(new HashGroup(index, count - index));
                }

                bw.Pad(0x8);
                bw.FillInt64("HashGroups", bw.Position);
                bw.ReserveInt64("PathHashes");
                bw.WriteUInt32(groupCount);
                bw.WriteInt32(0x00080810);

                foreach (HashGroup hashGroup in hashGroups)
                {
                    hashGroup.Write(bw);
                }

                // No padding after section 1
                bw.FillInt64("PathHashes", bw.Position);
                foreach (PathHash pathHash in pathHashes)
                {
                    pathHash.Write(bw);
                }
            }

            bw.FillInt64("DataStart", bw.Position);
            for (int i = 0; i < Files.Count; i++)
            {
                BinderFile file = Files[i];
                if (file.Bytes.LongLength > 0)
                {
                    bw.Pad(0x10);
                }

                bw.FillUInt32($"FileData{i}", (uint)bw.Position);

                int compressedSize = file.Bytes.Length;

                if (Binder.IsCompressed(file.Flags))
                {
                    if (Format == Binder.Format.x2E)
                    {
                        byte[] bytes = DCX.Compress(file.Bytes, DCX.Type.DemonsSoulsEDGE);
                        bw.WriteBytes(bytes);
                        compressedSize = bytes.Length;
                    }
                    else
                    {
                        compressedSize = SFUtil.WriteZlib(bw, 0x9C, file.Bytes);
                    }
                }
                else
                {
                    bw.WriteBytes(file.Bytes);
                }

                bw.FillInt64($"CompressedSize{i}", compressedSize);
            }
        }
Example #12
0
 // Writes a placeholder in the source object and updates the local offset
 public void WritePlaceholder(BinaryWriterEx bw, uint sectionBaseOffset)
 {
     SourceLocalOffset = (uint)bw.Position - SourceObject.SectionOffset - sectionBaseOffset;
     bw.WriteInt64(sectionBaseOffset);
 }
Example #13
0
 internal override void WriteTypeData(BinaryWriterEx bw)
 {
     bw.WriteInt64(UnkT00);
     bw.WritePattern(0x18, 0x00);
 }
Example #14
0
        /// <summary>
        /// Serializes file data to a stream.
        /// </summary>
        protected override void Write(BinaryWriterEx bw)
        {
            bw.BigEndian = BigEndian;

            bw.ReserveInt32("FileSize");
            bw.WriteInt16((short)(Version >= 201 ? 0xFF : 0x30));
            bw.WriteInt16(Unk06);
            bw.WriteInt16((short)Fields.Count);

            if (Version == 101)
            {
                bw.WriteInt16(0x8C);
            }
            else if (Version == 102)
            {
                bw.WriteInt16(0xAC);
            }
            else if (Version == 103)
            {
                bw.WriteInt16(0x6C);
            }
            else if (Version == 104)
            {
                bw.WriteInt16(0xB0);
            }
            else if (Version == 201)
            {
                bw.WriteInt16(0xD0);
            }

            bw.WriteFixStr(ParamType, 0x20, (byte)(Version >= 201 ? 0x00 : 0x20));
            bw.WriteSByte((sbyte)(BigEndian ? -1 : 0));
            bw.WriteBoolean(Unicode);
            bw.WriteInt16(Version);
            if (Version >= 201)
            {
                bw.WriteInt64(0x38);
            }

            for (int i = 0; i < Fields.Count; i++)
            {
                Fields[i].Write(bw, this, i);
            }

            long descriptionsStart = bw.Position;

            for (int i = 0; i < Fields.Count; i++)
            {
                Fields[i].WriteDescription(bw, this, i);
            }

            if (Version >= 104)
            {
                long descriptionsLength = bw.Position - descriptionsStart;
                if (descriptionsLength % 0x10 != 0)
                {
                    bw.WritePattern((int)(0x10 - descriptionsLength % 0x10), 0x00);
                }
            }
            else
            {
                bw.Pad(0x10);
            }
            bw.FillInt32("FileSize", (int)bw.Position);
        }
Example #15
0
        /// <summary>
        /// Serializes file data to a stream.
        /// </summary>
        protected override void Write(BinaryWriterEx bw)
        {
            if (AppliedParamdef == null)
            {
                throw new InvalidOperationException("Params cannot be written without applying a paramdef.");
            }

            bw.BigEndian = BigEndian;

            bw.ReserveUInt32("StringsOffset");
            if (Format2D.HasFlag(FormatFlags1.Flag01) && Format2D.HasFlag(FormatFlags1.IntDataOffset) || Format2D.HasFlag(FormatFlags1.LongDataOffset))
            {
                bw.WriteInt16(0);
            }
            else
            {
                bw.ReserveUInt16("DataStart");
            }
            bw.WriteInt16(Unk06);
            bw.WriteInt16(ParamdefDataVersion);
            bw.WriteUInt16((ushort)Rows.Count);
            if (Format2D.HasFlag(FormatFlags1.OffsetParamType))
            {
                bw.WriteInt32(0);
                bw.ReserveInt64("ParamTypeOffset");
                bw.WritePattern(0x14, 0x00);
            }
            else
            {
                // This padding heuristic isn't completely accurate, not that it matters
                bw.WriteFixStr(ParamType, 0x20, (byte)(Format2D.HasFlag(FormatFlags1.Flag01) ? 0x20 : 0x00));
            }
            bw.WriteByte((byte)(BigEndian ? 0xFF : 0x00));
            bw.WriteByte((byte)Format2D);
            bw.WriteByte((byte)Format2E);
            bw.WriteByte(ParamdefFormatVersion);
            if (Format2D.HasFlag(FormatFlags1.Flag01) && Format2D.HasFlag(FormatFlags1.IntDataOffset))
            {
                bw.ReserveUInt32("DataStart");
                bw.WriteInt32(0);
                bw.WriteInt32(0);
                bw.WriteInt32(0);
            }
            else if (Format2D.HasFlag(FormatFlags1.LongDataOffset))
            {
                bw.ReserveInt64("DataStart");
                bw.WriteInt64(0);
            }

            for (int i = 0; i < Rows.Count; i++)
            {
                Rows[i].WriteHeader(bw, this, i);
            }

            // This is probably pretty stupid
            if (Format2D == FormatFlags1.Flag01)
            {
                bw.WritePattern(0x20, 0x00);
            }

            if (Format2D.HasFlag(FormatFlags1.Flag01) && Format2D.HasFlag(FormatFlags1.IntDataOffset))
            {
                bw.FillUInt32("DataStart", (uint)bw.Position);
            }
            else if (Format2D.HasFlag(FormatFlags1.LongDataOffset))
            {
                bw.FillInt64("DataStart", bw.Position);
            }
            else
            {
                bw.FillUInt16("DataStart", (ushort)bw.Position);
            }

            for (int i = 0; i < Rows.Count; i++)
            {
                Rows[i].WriteCells(bw, this, i);
            }

            bw.FillUInt32("StringsOffset", (uint)bw.Position);

            if (Format2D.HasFlag(FormatFlags1.OffsetParamType))
            {
                bw.FillInt64("ParamTypeOffset", bw.Position);
                bw.WriteASCII(ParamType, true);
            }

            for (int i = 0; i < Rows.Count; i++)
            {
                Rows[i].WriteName(bw, this, i);
            }
            // DeS and BB sometimes (but not always) include some useless padding here
        }
Example #16
0
            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));
            }
Example #17
0
        internal override void Write(BinaryWriterEx bw)
        {
            bw.WriteASCII("TAE ");
            bw.WriteByte(0);
            bw.WriteByte(0);
            bw.WriteByte(0);
            bw.WriteByte(0xFF);
            bw.WriteInt32(0x1000D);
            bw.ReserveInt32("FileSize");
            bw.WriteInt64(0x40);
            bw.WriteInt64(1);
            bw.WriteInt64(0x50);
            bw.WriteInt64(0x80);
            bw.WriteInt64(Unk30);
            bw.WriteInt64(0);
            bw.WriteBytes(Flags);
            bw.WriteInt64(1);
            bw.WriteInt32(ID);
            bw.WriteInt32(Animations.Count);
            bw.ReserveInt64("AnimsOffset");
            bw.ReserveInt64("AnimGroupsOffset");
            bw.WriteInt64(0xA0);
            bw.WriteInt64(Animations.Count);
            bw.ReserveInt64("FirstAnimOffset");
            bw.WriteInt64(1);
            bw.WriteInt64(0x90);
            bw.WriteInt32(ID);
            bw.WriteInt32(ID);
            bw.WriteInt64(0x50);
            bw.WriteInt64(0);
            bw.WriteInt64(0xB0);
            bw.ReserveInt64("SkeletonName");
            bw.ReserveInt64("SibName");
            bw.WriteInt64(0);
            bw.WriteInt64(0);

            bw.FillInt64("SkeletonName", bw.Position);
            bw.WriteUTF16(SkeletonName, true);
            bw.Pad(0x10);

            bw.FillInt64("SibName", bw.Position);
            bw.WriteUTF16(SibName, true);
            bw.Pad(0x10);

            Animations.Sort((a1, a2) => a1.ID.CompareTo(a2.ID));

            bw.FillInt64("AnimsOffset", bw.Position);
            var animOffsets = new List <long>(Animations.Count);

            for (int i = 0; i < Animations.Count; i++)
            {
                animOffsets.Add(bw.Position);
                Animations[i].WriteHeader(bw, i);
            }

            bw.FillInt64("AnimGroupsOffset", bw.Position);
            bw.ReserveInt64("AnimGroupsCount");
            bw.ReserveInt64("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.WriteInt64(animOffsets[firstIndex]);
                groupCount++;
            }
            bw.FillInt64("AnimGroupsCount", groupCount);
            if (groupCount == 0)
            {
                bw.FillInt64("AnimGroupsOffset", 0);
            }
            else
            {
                bw.FillInt64("AnimGroupsOffset", groupStart);
            }

            bw.FillInt64("FirstAnimOffset", bw.Position);
            for (int i = 0; i < Animations.Count; i++)
            {
                Animations[i].WriteBody(bw, i);
            }

            for (int i = 0; i < Animations.Count; i++)
            {
                Animations[i].WriteAnimFile(bw, i);

                long timeStart = bw.Position;
                Animations[i].WriteTimes(bw, i);

                var eventHeaderOffsets = Animations[i].WriteEventHeaders(bw, i, timeStart);

                Animations[i].WriteEventData(bw, i);

                Animations[i].WriteEventGroupHeaders(bw, i);

                Animations[i].WriteEventGroupData(bw, i, eventHeaderOffsets);
            }

            bw.FillInt32("FileSize", (int)bw.Position);
        }
Example #18
0
            internal void Write(BinaryWriterEx bw, List <File> files)
            {
                bw.BigEndian = BigEndian;
                bw.WriteASCII("BHF4");
                bw.WriteBoolean(Flag1);
                bw.WriteBoolean(Flag2);
                bw.WriteByte(0);
                bw.WriteByte(0);
                bw.WriteInt32(0x10000);
                bw.WriteInt32(files.Count);
                bw.WriteInt64(0x40);
                bw.WriteASCII(Timestamp.PadRight(8, '\0'));
                if (Format == 0x0C || Format == 0x30)
                {
                    bw.WriteInt64(0x18);
                }
                else if (Format == 0x2E || Format == 0x74)
                {
                    bw.WriteInt64(0x24);
                }
                else if (Format == 0x3E)
                {
                    bw.WriteInt64(0x28);
                }
                bw.WriteInt64(0);

                bw.WriteBoolean(Unicode);
                bw.WriteByte(Format);
                bw.WriteByte(Extended);
                bw.WriteByte(0);

                bw.WriteInt32(0);
                if (Extended == 4)
                {
                    bw.ReserveInt64("HashGroups");
                }
                else
                {
                    bw.WriteInt64(0);
                }

                for (int i = 0; i < files.Count; i++)
                {
                    FileHeader.Write(bw, files[i], i, Format);
                }

                for (int i = 0; i < files.Count; i++)
                {
                    File file = files[i];
                    bw.FillInt32($"FileName{i}", (int)bw.Position);
                    if (Unicode)
                    {
                        bw.WriteUTF16(file.Name, true);
                    }
                    else
                    {
                        bw.WriteShiftJIS(file.Name, true);
                    }
                }

                if (Extended == 4)
                {
                    uint groupCount = 0;
                    for (uint p = (uint)files.Count / 7; p <= 100000; p++)
                    {
                        if (Util.IsPrime(p))
                        {
                            groupCount = p;
                            break;
                        }
                    }

                    if (groupCount == 0)
                    {
                        throw new InvalidOperationException("Hash group count not determined in BXF4.");
                    }

                    var hashLists = new List <PathHash> [groupCount];
                    for (int i = 0; i < groupCount; i++)
                    {
                        hashLists[i] = new List <PathHash>();
                    }

                    for (int i = 0; i < files.Count; i++)
                    {
                        var  pathHash = new PathHash(i, files[i].Name);
                        uint group    = pathHash.Hash % groupCount;
                        hashLists[group].Add(pathHash);
                    }

                    for (int i = 0; i < groupCount; i++)
                    {
                        hashLists[i].Sort((ph1, ph2) => ph1.Hash.CompareTo(ph2.Hash));
                    }

                    var hashGroups = new List <HashGroup>();
                    var pathHashes = new List <PathHash>();

                    int count = 0;
                    foreach (List <PathHash> hashList in hashLists)
                    {
                        int index = count;
                        foreach (PathHash pathHash in hashList)
                        {
                            pathHashes.Add(pathHash);
                            count++;
                        }

                        hashGroups.Add(new HashGroup(index, count - index));
                    }

                    bw.Pad(0x8);
                    bw.FillInt64("HashGroups", bw.Position);
                    bw.ReserveInt64("PathHashes");
                    bw.WriteUInt32(groupCount);
                    bw.WriteInt32(0x00080810);

                    foreach (HashGroup hashGroup in hashGroups)
                    {
                        hashGroup.Write(bw);
                    }

                    // No padding after section 1
                    bw.FillInt64("PathHashes", bw.Position);
                    foreach (PathHash pathHash in pathHashes)
                    {
                        pathHash.Write(bw);
                    }
                }
            }
Example #19
0
 internal void Write(BinaryWriterEx bw)
 {
     bw.WriteInt64(Unk1);
 }
Example #20
0
        /// <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);
        }