Example #1
0
 private protected override void WriteTypeData(BinaryWriterEx bw)
 {
     bw.WriteInt32(0);
     bw.WriteSByte(BreakTerm);
     bw.WriteSByte(NetSyncType);
     bw.WriteInt16(0);
     bw.WriteInt16(InitAnimID);
     bw.WriteInt16(UnkT0E);
     bw.WriteInt32(UnkT10);
     bw.WriteInt32(0);
     bw.WriteInt32(0);
 }
Example #2
0
 private protected override void WriteTypeData(BinaryWriterEx bw)
 {
     bw.WriteByte(MaxNum);
     bw.WriteSByte(GenType);
     bw.WriteInt16(LimitNum);
     bw.WriteInt16(MinGenNum);
     bw.WriteInt16(MaxGenNum);
     bw.WriteSingle(MinInterval);
     bw.WriteSingle(MaxInterval);
     bw.WriteByte(InitialSpawnCount);
     bw.WriteByte(0);
     bw.WriteByte(0);
     bw.WriteByte(0);
     bw.WriteSingle(UnkT14);
     bw.WriteSingle(UnkT18);
     bw.WriteInt32(0);
     bw.WriteInt32(0);
     bw.WriteInt32(0);
     bw.WriteInt32(0);
     bw.WriteInt32(0);
     bw.WriteInt32s(SpawnPointIndices);
     bw.WriteInt32(0);
     bw.WriteInt32(0);
     bw.WriteInt32(0);
     bw.WriteInt32(0);
     bw.WriteInt32s(SpawnPartIndices);
     bw.WriteInt32(0);
     bw.WriteInt32(0);
     bw.WriteInt32(0);
     bw.WriteInt32(0);
     bw.WriteInt32(0);
     bw.WriteInt32(0);
     bw.WriteInt32(0);
     bw.WriteInt32(0);
 }
Example #3
0
                internal void WriteValue(BinaryWriterEx bw, object value)
                {
                    switch (Type)
                    {
                    case ParamType.aob: bw.WriteBytes((byte[])value); break;

                    case ParamType.b: bw.WriteBoolean((bool)value); break;

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

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

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

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

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

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

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

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

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

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

                    default: throw new Exception($"Invalid ParamTemplate ParamType: {Type.ToString()}");
                    }
                }
Example #4
0
            internal void Write(BinaryWriterEx bw, GameType game)
            {
                if (game == GameType.BB)
                {
                    bw.WriteInt32(RagdollParamID);
                    bw.WriteInt16(DamageAnimID);
                    bw.WriteByte(NPCPartGroupIndex);
                    bw.WriteByte(Unknown);
                    bw.WriteSByte(UnknownBB);
                    bw.WriteByte(0);
                    bw.WriteByte(0);
                    bw.WriteByte(0);
                    bw.WriteInt32(0);
                }
                else
                {
                    bw.WriteInt16((short)RagdollParamID);
                    bw.WriteInt16(DamageAnimID);
                    bw.WriteByte(NPCPartGroupIndex);
                    bw.WriteByte(Unknown);
                    bw.WriteByte(0);
                    bw.WriteByte(0);

                    if (game == GameType.DS3)
                    {
                        bw.WriteInt64(0);
                    }
                }
            }
Example #5
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);
        }
Example #6
0
                internal void WriteValue(BinaryWriterEx bw, object value)
                {
                    switch (Type)
                    {
                    case ParamType.aob: bw.WriteBytes((byte[])value); break;

                    case ParamType.b: bw.WriteBoolean((bool)value); break;

                    case ParamType.u8:
                    case ParamType.x8:
                        bw.WriteByte(Convert.ToByte(value)); break;

                    case ParamType.s8:
                        bw.WriteSByte(Convert.ToSByte(value)); break;

                    case ParamType.u16:
                    case ParamType.x16:
                        bw.WriteUInt16(Convert.ToUInt16(value)); break;

                    case ParamType.s16:
                        bw.WriteInt16(Convert.ToInt16(value)); break;

                    case ParamType.u32:
                    case ParamType.x32:
                        bw.WriteUInt32(Convert.ToUInt32(value)); break;

                    case ParamType.s32:
                        bw.WriteInt32(Convert.ToInt32(value)); break;

                    case ParamType.u64:
                    case ParamType.x64:
                        bw.WriteUInt64(Convert.ToUInt64(value)); break;

                    case ParamType.s64:
                        bw.WriteInt64(Convert.ToInt64(value)); break;

                    case ParamType.f32:
                        bw.WriteSingle(Convert.ToSingle(value)); break;

                    case ParamType.f64:
                        bw.WriteDouble(Convert.ToDouble(value)); break;

                    default:
                        throw new Exception($"Invalid ParamTemplate ParamType: {Type.ToString()}");
                    }
                }
Example #7
0
            /// <summary>
            /// Packs an enumeration of arg values into a byte array for use in an instruction.
            /// </summary>
            public void PackArgs(IEnumerable <object> args, bool bigEndian = false)
            {
                using (var ms = new MemoryStream())
                {
                    var bw = new BinaryWriterEx(bigEndian, ms);
                    foreach (object arg in args)
                    {
                        switch (arg)
                        {
                        case byte ub:
                            bw.WriteByte(ub); break;

                        case ushort us:
                            bw.Pad(2);
                            bw.WriteUInt16(us); break;

                        case uint ui:
                            bw.Pad(4);
                            bw.WriteUInt32(ui); break;

                        case sbyte sb:
                            bw.WriteSByte(sb); break;

                        case short ss:
                            bw.Pad(2);
                            bw.WriteInt16(ss); break;

                        case int si:
                            bw.Pad(4);
                            bw.WriteInt32(si); break;

                        case float f:
                            bw.Pad(4);
                            bw.WriteSingle(f); break;

                        case long sl:
                            bw.Pad(8);
                            bw.WriteInt64(sl); break;

                        default:
                            throw new NotSupportedException($"Unsupported argument type: {arg.GetType()}");
                        }
                    }
                    ArgData = bw.FinishBytes();
                }
            }
Example #8
0
        private void Write(BinaryWriterEx bw)
        {
            bw.BigEndian = BigEndian;
            bw.WriteASCII("BHD5");
            bw.WriteSByte((sbyte)(BigEndian ? 0 : -1));
            bw.WriteBoolean(Unk05);
            bw.WriteByte(0);
            bw.WriteByte(0);
            bw.WriteInt32(1);
            bw.ReserveInt32("FileSize");
            bw.WriteInt32(Buckets.Count);
            bw.ReserveInt32("BucketsOffset");

            if (Format >= Game.DarkSouls2)
            {
                bw.WriteInt32(Salt.Length);
                bw.WriteASCII(Salt);
            }

            bw.FillInt32("BucketsOffset", (int)bw.Position);
            for (int i = 0; i < Buckets.Count; i++)
            {
                Buckets[i].Write(bw, i);
            }

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

            for (int i = 0; i < Buckets.Count; i++)
            {
                for (int j = 0; j < Buckets[i].Count; j++)
                {
                    Buckets[i][j].WriteHashAndKey(bw, Format, i, j);
                }
            }

            bw.FillInt32("FileSize", (int)bw.Position);
        }
Example #9
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);
        }
Example #10
0
            internal void Write(BinaryWriterEx bw, List <LayoutMember> layout, float uvFactor)
            {
                foreach (LayoutMember member in layout)
                {
                    switch (member.Semantic)
                    {
                    case LayoutSemantic.Position:
                        if (member.Type == LayoutType.Float3)
                        {
                            bw.WriteVector3(Position);
                        }
                        else if (member.Type == LayoutType.Float4)
                        {
                            bw.WriteVector3(Position);
                            bw.WriteSingle(0);
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                        break;

                    case LayoutSemantic.BoneWeights:
                        if (member.Type == LayoutType.Byte4A)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteSByte((sbyte)Math.Round(BoneWeights[i] * sbyte.MaxValue));
                            }
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteSByte((sbyte)Math.Round(BoneWeights[i] * sbyte.MaxValue));
                            }
                        }
                        else if (member.Type == LayoutType.UVPair)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteInt16((short)Math.Round(BoneWeights[i] * short.MaxValue));
                            }
                        }
                        else if (member.Type == LayoutType.Short4toFloat4A)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteInt16((short)Math.Round(BoneWeights[i] * short.MaxValue));
                            }
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                        break;

                    case LayoutSemantic.BoneIndices:
                        if (member.Type == LayoutType.Byte4B)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteByte((byte)BoneIndices[i]);
                            }
                        }
                        else if (member.Type == LayoutType.ShortBoneIndices)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteUInt16((ushort)BoneIndices[i]);
                            }
                        }
                        else if (member.Type == LayoutType.Byte4E)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteByte((byte)BoneIndices[i]);
                            }
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                        break;

                    case LayoutSemantic.Normal:
                        if (member.Type == LayoutType.Float3)
                        {
                            bw.WriteSingle(Normal.X);
                            bw.WriteSingle(Normal.Y);
                            bw.WriteSingle(Normal.Z);
                        }
                        else if (member.Type == LayoutType.Float4)
                        {
                            bw.WriteVector4(Normal);
                        }
                        else if (member.Type == LayoutType.Byte4A)
                        {
                            bw.WriteByte((byte)Math.Round(Normal.X * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.Y * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.Z * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.W * 127 + 127));
                        }
                        else if (member.Type == LayoutType.Byte4B)
                        {
                            bw.WriteByte((byte)Math.Round(Normal.X * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.Y * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.Z * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.W * 127 + 127));
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            bw.WriteByte((byte)Math.Round(Normal.X * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.Y * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.Z * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.W * 127 + 127));
                        }
                        else if (member.Type == LayoutType.Short4toFloat4A)
                        {
                            bw.WriteInt16((short)Math.Round(Normal.X * 32767));
                            bw.WriteInt16((short)Math.Round(Normal.Y * 32767));
                            bw.WriteInt16((short)Math.Round(Normal.Z * 32767));
                            bw.WriteInt16((short)Math.Round(Normal.W * 32767));
                        }
                        else if (member.Type == LayoutType.Short4toFloat4B)
                        {
                            bw.WriteUInt16((ushort)Math.Round(Normal.X * 32767 + 32767));
                            bw.WriteUInt16((ushort)Math.Round(Normal.Y * 32767 + 32767));
                            bw.WriteUInt16((ushort)Math.Round(Normal.Z * 32767 + 32767));
                            bw.WriteUInt16((ushort)Math.Round(Normal.W * 32767 + 32767));
                        }
                        else if (member.Type == LayoutType.Byte4E)
                        {
                            bw.WriteByte((byte)Math.Round(Normal.X * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.Y * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.Z * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Normal.W * 127 + 127));
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                        break;

                    case LayoutSemantic.UV:
                        Vector3 uv = uvQueue.Dequeue() * uvFactor;
                        if (member.Type == LayoutType.Float2)
                        {
                            bw.WriteSingle(uv.X);
                            bw.WriteSingle(uv.Y);
                        }
                        else if (member.Type == LayoutType.Float3)
                        {
                            bw.WriteVector3(uv);
                        }
                        else if (member.Type == LayoutType.Float4)
                        {
                            bw.WriteSingle(uv.X);
                            bw.WriteSingle(uv.Y);

                            uv = uvQueue.Dequeue() * uvFactor;
                            bw.WriteSingle(uv.X);
                            bw.WriteSingle(uv.Y);
                        }
                        else if (member.Type == LayoutType.Byte4A)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == LayoutType.Byte4B)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == LayoutType.Short2toFloat2)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == LayoutType.UV)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == LayoutType.UVPair)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));

                            uv = uvQueue.Dequeue() * uvFactor;
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == LayoutType.Short4toFloat4B)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                            bw.WriteInt16((short)Math.Round(uv.Z));
                            bw.WriteInt16(0);
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                        break;

                    case LayoutSemantic.Tangent:
                        Vector4 tangent = tangentQueue.Dequeue();
                        if (member.Type == LayoutType.Float4)
                        {
                            bw.WriteVector4(tangent);
                        }
                        else if (member.Type == LayoutType.Byte4A)
                        {
                            bw.WriteByte((byte)Math.Round(tangent.X * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.Y * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.Z * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.W * 127 + 127));
                        }
                        else if (member.Type == LayoutType.Byte4B)
                        {
                            bw.WriteByte((byte)Math.Round(tangent.X * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.Y * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.Z * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.W * 127 + 127));
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            bw.WriteByte((byte)Math.Round(tangent.X * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.Y * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.Z * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.W * 127 + 127));
                        }
                        else if (member.Type == LayoutType.Short4toFloat4A)
                        {
                            bw.WriteInt16((short)Math.Round(tangent.X * 32767));
                            bw.WriteInt16((short)Math.Round(tangent.Y * 32767));
                            bw.WriteInt16((short)Math.Round(tangent.Z * 32767));
                            bw.WriteInt16((short)Math.Round(tangent.W * 32767));
                        }
                        else if (member.Type == LayoutType.Byte4E)
                        {
                            bw.WriteByte((byte)Math.Round(tangent.X * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.Y * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.Z * 127 + 127));
                            bw.WriteByte((byte)Math.Round(tangent.W * 127 + 127));
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                        break;

                    case LayoutSemantic.Bitangent:
                        if (member.Type == LayoutType.Byte4A)
                        {
                            bw.WriteByte((byte)Math.Round(Bitangent.X * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Bitangent.Y * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Bitangent.Z * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Bitangent.W * 127 + 127));
                        }
                        else if (member.Type == LayoutType.Byte4B)
                        {
                            bw.WriteByte((byte)Math.Round(Bitangent.X * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Bitangent.Y * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Bitangent.Z * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Bitangent.W * 127 + 127));
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            bw.WriteByte((byte)Math.Round(Bitangent.X * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Bitangent.Y * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Bitangent.Z * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Bitangent.W * 127 + 127));
                        }
                        else if (member.Type == LayoutType.Byte4E)
                        {
                            bw.WriteByte((byte)Math.Round(Bitangent.X * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Bitangent.Y * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Bitangent.Z * 127 + 127));
                            bw.WriteByte((byte)Math.Round(Bitangent.W * 127 + 127));
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                        break;

                    case LayoutSemantic.VertexColor:
                        FLVER.VertexColor color = colorQueue.Dequeue();
                        if (member.Type == LayoutType.Float4)
                        {
                            bw.WriteSingle(color.R);
                            bw.WriteSingle(color.G);
                            bw.WriteSingle(color.B);
                            bw.WriteSingle(color.A);
                        }
                        else if (member.Type == LayoutType.Byte4A)
                        {
                            bw.WriteByte((byte)Math.Round(color.A * 255));
                            bw.WriteByte((byte)Math.Round(color.R * 255));
                            bw.WriteByte((byte)Math.Round(color.G * 255));
                            bw.WriteByte((byte)Math.Round(color.B * 255));
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            bw.WriteByte((byte)Math.Round(color.R * 255));
                            bw.WriteByte((byte)Math.Round(color.G * 255));
                            bw.WriteByte((byte)Math.Round(color.B * 255));
                            bw.WriteByte((byte)Math.Round(color.A * 255));
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                        break;

                    default:
                        throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                    }
                }
            }
Example #11
0
            internal void Write(BinaryWriterEx bw, List <CustomData> allCustomData, List <long> customDataValueOffsets)
            {
                bw.WriteFixStrW(Name, 0x40, 0x00);
                bw.WriteUInt32((uint)Type);
                bw.WriteInt32(Type == DataType.Color ? 3 : 0);

                int length = -1;

                if (Type == DataType.String)
                {
                    length = SFEncoding.UTF16.GetByteCount((string)Value + '\0');
                    if (length % 0x10 != 0)
                    {
                        length += 0x10 - length % 0x10;
                    }
                }
                else if (Type == DataType.Custom)
                {
                    length = ((byte[])Value).Length;
                    if (length % 4 != 0)
                    {
                        throw new InvalidDataException($"Unexpected custom data custom length: {length}");
                    }
                }
                else if (Type == DataType.Color)
                {
                    length = 4;
                }

                long valueOffset = bw.Position;

                switch (Type)
                {
                case DataType.Bool: bw.WriteBoolean((bool)Value); break;

                case DataType.SByte: bw.WriteSByte((sbyte)Value); break;

                case DataType.Byte: bw.WriteByte((byte)Value); break;

                case DataType.Short: bw.WriteInt16((short)Value); break;

                case DataType.Int: bw.WriteInt32((int)Value); break;

                case DataType.UInt: bw.WriteUInt32((uint)Value); break;

                case DataType.Float: bw.WriteSingle((float)Value); break;

                case DataType.String:
                case DataType.Custom:
                case DataType.Color: bw.WriteInt32(length); break;

                default: throw new NotImplementedException($"Unimplemented custom data type: {Type}");
                }

                if (Type == DataType.Bool || Type == DataType.SByte || Type == DataType.Byte)
                {
                    bw.WriteByte(0);
                    bw.WriteInt16(0);
                }
                else if (Type == DataType.Short)
                {
                    bw.WriteInt16(0);
                }

                // This is probably wrong for the 64-bit format
                bw.WriteInt32(0);
                bw.ReserveInt32($"SequencesOffset[{allCustomData.Count}]");
                bw.WriteInt32(Sequences.Count);
                bw.WriteInt32(0);
                bw.WriteInt32(0);

                if (Type == DataType.String)
                {
                    bw.WriteFixStrW((string)Value, length, 0x00);
                }
                else if (Type == DataType.Custom)
                {
                    bw.WriteBytes((byte[])Value);
                }
                else if (Type == DataType.Color)
                {
                    var color = (Color)Value;
                    valueOffset = bw.Position;
                    bw.WriteByte(color.R);
                    bw.WriteByte(color.G);
                    bw.WriteByte(color.B);
                    bw.WriteByte(0);
                }

                allCustomData.Add(this);
                customDataValueOffsets.Add(valueOffset);
            }
Example #12
0
            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];
                    CellType     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 == CellType.s8)
                    {
                        bw.WriteSByte((sbyte)value);
                    }
                    else if (type == CellType.u8 || type == CellType.x8)
                    {
                        bw.WriteByte((byte)value);
                    }
                    else if (type == CellType.s16)
                    {
                        bw.WriteInt16((short)value);
                    }
                    else if (type == CellType.u16 || type == CellType.x16)
                    {
                        bw.WriteUInt16((ushort)value);
                    }
                    else if (type == CellType.s32)
                    {
                        bw.WriteInt32((int)value);
                    }
                    else if (type == CellType.u32 || type == CellType.x32)
                    {
                        bw.WriteUInt32((uint)value);
                    }
                    else if (type == CellType.f32)
                    {
                        bw.WriteSingle((float)value);
                    }
                    else if (type == CellType.dummy8)
                    {
                        bw.WriteBytes((byte[])value);
                    }
                    else if (type == CellType.fixstr)
                    {
                        bw.WriteFixStr((string)value, entry.Size);
                    }
                    else if (type == CellType.fixstrW)
                    {
                        bw.WriteFixStrW((string)value, entry.Size);
                    }
                    else if (type == CellType.b8)
                    {
                        byte b = 0;
                        int  k;
                        for (k = 0; k < 8; k++)
                        {
                            if (j + k >= layout.Count || layout[j + k].Type != CellType.b8)
                            {
                                break;
                            }

                            if ((bool)Cells[j + k].Value)
                            {
                                b |= (byte)(1 << k);
                            }
                        }
                        j += k - 1;
                        bw.WriteByte(b);
                    }
                    else if (type == CellType.b32)
                    {
                        byte[] b = new byte[4];
                        int    k;
                        for (k = 0; k < 32; k++)
                        {
                            if (j + k >= layout.Count || layout[j + k].Type != CellType.b32)
                            {
                                break;
                            }

                            if ((bool)Cells[j + k].Value)
                            {
                                b[k / 8] |= (byte)(1 << (k % 8));
                            }
                        }
                        j += k - 1;
                        bw.WriteBytes(b);
                    }
                }
            }
Example #13
0
            internal void Write(BinaryWriterEx bw)
            {
                long start = bw.Position;

                bw.ReserveInt64("NameOffset");
                bw.WriteUInt32((uint)Type);
                bw.WriteInt32(ID);
                bw.WriteInt32(modelIndex);
                bw.WriteInt32(0);
                bw.ReserveInt64("PlaceholderOffset");
                bw.WriteVector3(Position);
                bw.WriteVector3(Rotation);
                bw.WriteVector3(Scale);

                bw.WriteUInt32(DrawGroup1);
                bw.WriteUInt32(DrawGroup2);
                bw.WriteUInt32(DrawGroup3);
                bw.WriteUInt32(DrawGroup4);
                bw.WriteUInt32(DispGroup1);
                bw.WriteUInt32(DispGroup2);
                bw.WriteUInt32(DispGroup3);
                bw.WriteUInt32(DispGroup4);

                bw.WriteInt32(UnkF01);
                bw.WriteInt32(UnkF02);
                bw.WriteInt32(UnkF03);
                bw.WriteInt32(UnkF04);
                bw.WriteInt32(UnkF05);
                bw.WriteInt32(UnkF06);
                bw.WriteInt32(UnkF07);
                bw.WriteInt32(UnkF08);
                bw.WriteInt32(UnkF09);
                bw.WriteInt32(UnkF10);
                bw.WriteInt32(UnkF11);
                bw.WriteInt32(UnkF12);
                bw.WriteInt32(UnkF13);
                bw.WriteInt32(UnkF14);
                bw.WriteInt32(UnkF15);
                bw.WriteInt32(UnkF16);
                bw.WriteInt32(UnkF17);
                bw.WriteInt32(UnkF18);
                bw.WriteInt32(0);

                bw.ReserveInt64("BaseDataOffset");
                bw.ReserveInt64("TypeDataOffset");
                bw.ReserveInt64("UnkOffset1");
                bw.ReserveInt64("UnkOffset2");

                bw.FillInt64("NameOffset", bw.Position - start);
                bw.WriteUTF16(Name, true);
                if (Placeholder == null)
                {
                    bw.FillInt64("PlaceholderOffset", 0);
                }
                else
                {
                    bw.FillInt64("PlaceholderOffset", bw.Position - start);
                    bw.WriteUTF16(Placeholder, true);
                }
                bw.Pad(8);

                bw.FillInt64("BaseDataOffset", bw.Position - start);
                bw.WriteInt32(EventEntityID);

                bw.WriteSByte(LightID);
                bw.WriteSByte(FogID);
                bw.WriteSByte(ScatterID);
                bw.WriteSByte(LensFlareID);

                bw.WriteInt32(0);

                bw.WriteSByte(LanternID);
                bw.WriteSByte(LodParamID);
                bw.WriteSByte(UnkB0E);
                bw.WriteBoolean(IsShadowDest);

                bw.WriteBoolean(IsShadowOnly);
                bw.WriteBoolean(DrawByReflectCam);
                bw.WriteBoolean(DrawOnlyReflectCam);
                bw.WriteBoolean(UseDepthBiasFloat);

                bw.WriteBoolean(DisablePointLightEffect);
                bw.WriteByte(UnkB15);
                bw.WriteByte(UnkB16);
                bw.WriteByte(UnkB17);

                bw.WriteInt32(UnkB18);
                bw.WriteInt32(UnkB1C);
                bw.WriteInt32(UnkB20);
                bw.WriteInt32(UnkB24);
                bw.WriteInt32(UnkB28);
                bw.WriteInt32(-1);
                bw.WriteInt32(UnkB30);
                bw.WriteInt32(UnkB34);
                bw.WriteInt32(UnkB38);
                bw.WriteInt32(0);

                bw.FillInt64("TypeDataOffset", bw.Position - start);
                if (UnkOffset1Delta == 0)
                {
                    bw.FillInt64("UnkOffset1", 0);
                }
                else
                {
                    bw.FillInt64("UnkOffset1", bw.Position - start + UnkOffset1Delta);
                }

                if (UnkOffset2Delta == 0)
                {
                    bw.FillInt64("UnkOffset2", 0);
                }
                else
                {
                    bw.FillInt64("UnkOffset2", bw.Position - start + UnkOffset2Delta);
                }

                WriteSpecific(bw);
            }
Example #14
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 #15
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 #16
0
            internal void WriteCells(BinaryWriterEx bw, byte format2D, int index)
            {
                if ((format2D & 0x7F) < 4)
                {
                    bw.FillUInt32($"RowOffset{index}", (uint)bw.Position);
                }
                else
                {
                    bw.FillInt64($"RowOffset{index}", bw.Position);
                }

                int bitOffset = -1;

                PARAMDEF.DefType bitType  = PARAMDEF.DefType.u8;
                uint             bitValue = 0;

                for (int i = 0; i < Cells.Count; i++)
                {
                    Cell             cell  = Cells[i];
                    object           value = cell.Value;
                    PARAMDEF.Field   field = cell.Def;
                    PARAMDEF.DefType type  = field.DisplayType;

                    if (type == PARAMDEF.DefType.s8)
                    {
                        bw.WriteSByte((sbyte)value);
                    }
                    else if (type == PARAMDEF.DefType.s16)
                    {
                        bw.WriteInt16((short)value);
                    }
                    else if (type == PARAMDEF.DefType.s32)
                    {
                        bw.WriteInt32((int)value);
                    }
                    else if (type == PARAMDEF.DefType.f32)
                    {
                        bw.WriteSingle((float)value);
                    }
                    else if (type == PARAMDEF.DefType.fixstr)
                    {
                        bw.WriteFixStr((string)value, field.ArrayLength);
                    }
                    else if (type == PARAMDEF.DefType.fixstrW)
                    {
                        bw.WriteFixStrW((string)value, field.ArrayLength * 2);
                    }
                    else if (ParamUtil.IsBitType(type))
                    {
                        if (field.BitSize == -1)
                        {
                            if (type == PARAMDEF.DefType.u8)
                            {
                                bw.WriteByte((byte)value);
                            }
                            else if (type == PARAMDEF.DefType.u16)
                            {
                                bw.WriteUInt16((ushort)value);
                            }
                            else if (type == PARAMDEF.DefType.u32)
                            {
                                bw.WriteUInt32((uint)value);
                            }
                            else if (type == PARAMDEF.DefType.dummy8)
                            {
                                bw.WriteBytes((byte[])value);
                            }
                        }
                        else
                        {
                            if (bitOffset == -1)
                            {
                                bitOffset = 0;
                                bitType   = type == PARAMDEF.DefType.dummy8 ? PARAMDEF.DefType.u8 : type;
                                bitValue  = 0;
                            }

                            uint shifted = 0;
                            if (bitType == PARAMDEF.DefType.u8)
                            {
                                shifted = (byte)value;
                            }
                            else if (bitType == PARAMDEF.DefType.u16)
                            {
                                shifted = (ushort)value;
                            }
                            else if (bitType == PARAMDEF.DefType.u32)
                            {
                                shifted = (uint)value;
                            }
                            // Shift left first to clear any out-of-range bits
                            shifted    = shifted << (32 - field.BitSize) >> (32 - field.BitSize - bitOffset);
                            bitValue  |= shifted;
                            bitOffset += field.BitSize;

                            bool write = false;
                            if (i == Cells.Count - 1)
                            {
                                write = true;
                            }
                            else
                            {
                                PARAMDEF.Field   nextField = Cells[i + 1].Def;
                                PARAMDEF.DefType nextType  = nextField.DisplayType;
                                int bitLimit = ParamUtil.GetBitLimit(bitType);
                                if (!ParamUtil.IsBitType(nextType) || nextField.BitSize == -1 || bitOffset + nextField.BitSize > bitLimit ||
                                    (nextType == PARAMDEF.DefType.dummy8 ? PARAMDEF.DefType.u8 : nextType) != bitType)
                                {
                                    write = true;
                                }
                            }

                            if (write)
                            {
                                bitOffset = -1;
                                if (bitType == PARAMDEF.DefType.u8)
                                {
                                    bw.WriteByte((byte)bitValue);
                                }
                                else if (bitType == PARAMDEF.DefType.u16)
                                {
                                    bw.WriteUInt16((ushort)bitValue);
                                }
                                else if (bitType == PARAMDEF.DefType.u32)
                                {
                                    bw.WriteUInt32(bitValue);
                                }
                            }
                        }
                    }
                    else
                    {
                        throw new NotImplementedException($"Unsupported field type: {type}");
                    }
                }
            }
Example #17
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);
        }
Example #18
0
        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);
            }
        }
Example #19
0
 private static void WriteSByteNorm(BinaryWriterEx bw, float value)
 => bw.WriteSByte((sbyte)Math.Round(value * 127));
Example #20
0
            internal void Write(BinaryWriterEx bw, BufferLayout layout, int vertexSize, int version)
            {
                var tangentQueue = new Queue <Vector4>(Tangents);
                var colorQueue   = new Queue <Color>(Colors);
                var uvQueue      = new Queue <Vector3>(UVs);

                float uvFactor = 1024;

                foreach (BufferLayout.Member member in layout)
                {
                    switch (member.Semantic)
                    {
                    case BufferLayout.MemberSemantic.Position:
                        if (member.Type == BufferLayout.MemberType.Float3)
                        {
                            bw.WriteVector3(Position);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.BoneWeights:
                        if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteSByte((sbyte)(BoneWeights[i] * sbyte.MaxValue));
                            }
                        }
                        else if (member.Type == BufferLayout.MemberType.Short4toFloat4A)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteInt16((short)(BoneWeights[i] * short.MaxValue));
                            }
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.BoneIndices:
                        if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteByte((byte)BoneIndices[i]);
                            }
                        }
                        else if (member.Type == BufferLayout.MemberType.ShortBoneIndices)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteUInt16((ushort)BoneIndices[i]);
                            }
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4E)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteByte((byte)BoneIndices[i]);
                            }
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.Normal:
                        if (member.Type == BufferLayout.MemberType.Float4)
                        {
                            bw.WriteVector4(Normal);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4A)
                        {
                            bw.WriteByte((byte)(Normal.X * 127 + 127));
                            bw.WriteByte((byte)(Normal.Y * 127 + 127));
                            bw.WriteByte((byte)(Normal.Z * 127 + 127));
                            bw.WriteByte((byte)(Normal.W * 127 + 127));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            bw.WriteByte((byte)(Normal.X * 127 + 127));
                            bw.WriteByte((byte)(Normal.Y * 127 + 127));
                            bw.WriteByte((byte)(Normal.Z * 127 + 127));
                            bw.WriteByte((byte)(Normal.W * 127 + 127));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            bw.WriteByte((byte)(Normal.X * 127 + 127));
                            bw.WriteByte((byte)(Normal.Y * 127 + 127));
                            bw.WriteByte((byte)(Normal.Z * 127 + 127));
                            bw.WriteByte((byte)(Normal.W * 127 + 127));
                        }
                        else if (member.Type == BufferLayout.MemberType.Short4toFloat4B)
                        {
                            bw.WriteInt16((short)(Normal.X * 32767 + 32767));
                            bw.WriteInt16((short)(Normal.Y * 32767 + 32767));
                            bw.WriteInt16((short)(Normal.Z * 32767 + 32767));
                            bw.WriteInt16((short)(Normal.W * 32767 + 32767));
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.UV:
                        Vector3 uv = uvQueue.Dequeue() * uvFactor;
                        if (member.Type == BufferLayout.MemberType.Float2)
                        {
                            bw.WriteSingle(uv.X);
                            bw.WriteSingle(uv.Y);
                        }
                        else if (member.Type == BufferLayout.MemberType.Float3)
                        {
                            bw.WriteVector3(uv);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4A)
                        {
                            bw.WriteInt16((short)uv.X);
                            bw.WriteInt16((short)uv.Y);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            bw.WriteInt16((short)uv.X);
                            bw.WriteInt16((short)uv.Y);
                        }
                        else if (member.Type == BufferLayout.MemberType.Short2toFloat2)
                        {
                            bw.WriteInt16((short)uv.X);
                            bw.WriteInt16((short)uv.Y);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            bw.WriteInt16((short)uv.X);
                            bw.WriteInt16((short)uv.Y);
                        }
                        else if (member.Type == BufferLayout.MemberType.UV)
                        {
                            bw.WriteInt16((short)uv.X);
                            bw.WriteInt16((short)uv.Y);
                        }
                        else if (member.Type == BufferLayout.MemberType.UVPair)
                        {
                            bw.WriteInt16((short)uv.X);
                            bw.WriteInt16((short)uv.Y);

                            uv = uvQueue.Dequeue() * uvFactor;
                            bw.WriteInt16((short)uv.X);
                            bw.WriteInt16((short)uv.Y);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.Tangent:
                        Vector4 tangent = tangentQueue.Dequeue();
                        if (member.Type == BufferLayout.MemberType.Byte4A)
                        {
                            bw.WriteByte((byte)(tangent.X * 127 + 127));
                            bw.WriteByte((byte)(tangent.Y * 127 + 127));
                            bw.WriteByte((byte)(tangent.Z * 127 + 127));
                            bw.WriteByte((byte)(tangent.W * 127 + 127));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            bw.WriteByte((byte)(tangent.X * 127 + 127));
                            bw.WriteByte((byte)(tangent.Y * 127 + 127));
                            bw.WriteByte((byte)(tangent.Z * 127 + 127));
                            bw.WriteByte((byte)(tangent.W * 127 + 127));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            bw.WriteByte((byte)(tangent.X * 127 + 127));
                            bw.WriteByte((byte)(tangent.Y * 127 + 127));
                            bw.WriteByte((byte)(tangent.Z * 127 + 127));
                            bw.WriteByte((byte)(tangent.W * 127 + 127));
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.UnknownVector4A:
                        if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            bw.WriteBytes(UnknownVector4);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            bw.WriteBytes(UnknownVector4);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.VertexColor:
                        Color color = colorQueue.Dequeue();
                        if (member.Type == BufferLayout.MemberType.Float4)
                        {
                            bw.WriteSingle(color.R);
                            bw.WriteSingle(color.G);
                            bw.WriteSingle(color.B);
                            bw.WriteSingle(color.A);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4A)
                        {
                            bw.WriteByte((byte)(color.A * 255));
                            bw.WriteByte((byte)(color.R * 255));
                            bw.WriteByte((byte)(color.G * 255));
                            bw.WriteByte((byte)(color.B * 255));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            bw.WriteByte((byte)(color.R * 255));
                            bw.WriteByte((byte)(color.G * 255));
                            bw.WriteByte((byte)(color.B * 255));
                            bw.WriteByte((byte)(color.A * 255));
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
            }
Example #21
0
            internal void Write(BinaryWriterEx bw)
            {
                long start = bw.Position;

                bw.ReserveInt64("DescOffset");
                bw.ReserveInt64("NameOffset");
                bw.WriteInt32(ModelLocalID);
                bw.WriteUInt32((uint)Type);
                bw.WriteInt32(ID);
                bw.WriteInt32(modelIndex);
                bw.ReserveInt64("PlaceholderOffset");
                bw.WriteVector3(Position);
                bw.WriteVector3(Rotation);
                bw.WriteVector3(Scale);

                bw.WriteUInt32s(DrawGroups);
                bw.WriteUInt32s(DispGroups);
                bw.WriteUInt32s(BackreadGroups);
                bw.WriteInt32(UnkFA4);

                bw.ReserveInt64("BaseDataOffset");
                bw.ReserveInt64("TypeDataOffset");
                bw.ReserveInt64("UnkOffset1");
                bw.ReserveInt64("UnkOffset2");

                bw.FillInt64("DescOffset", bw.Position - start);
                bw.WriteUTF16(Description, true);
                bw.FillInt64("NameOffset", bw.Position - start);
                bw.WriteUTF16(Name, true);
                if (Placeholder == null)
                {
                    bw.FillInt64("PlaceholderOffset", 0);
                }
                else
                {
                    bw.FillInt64("PlaceholderOffset", bw.Position - start);
                    bw.WriteUTF16(Placeholder, true);
                }
                bw.Pad(8);

                bw.FillInt64("BaseDataOffset", bw.Position - start);
                bw.WriteInt32(EventEntityID);

                bw.WriteSByte(OldLightID);
                bw.WriteSByte(OldFogID);
                bw.WriteSByte(OldScatterID);
                bw.WriteSByte(OldLensFlareID);

                bw.WriteInt32(0);

                bw.WriteSByte(OldLanternID);
                bw.WriteSByte(OldLodParamID);
                bw.WriteSByte(UnkB0E);
                bw.WriteBoolean(OldIsShadowDest);

                bw.FillInt64("TypeDataOffset", bw.Position - start);
                if (UnkOffset1Delta == 0)
                {
                    bw.FillInt64("UnkOffset1", 0);
                }
                else
                {
                    bw.FillInt64("UnkOffset1", bw.Position - start + UnkOffset1Delta);
                }

                if (UnkOffset2Delta == 0)
                {
                    bw.FillInt64("UnkOffset2", 0);
                }
                else
                {
                    bw.FillInt64("UnkOffset2", bw.Position - start + UnkOffset2Delta);
                }

                WriteSpecific(bw);
            }
Example #22
0
            internal void Write(BinaryWriterEx bw, List <LayoutMember> layout, float uvFactor)
            {
                foreach (LayoutMember member in layout)
                {
                    if (member.Semantic == LayoutSemantic.Position)
                    {
                        if (member.Type == LayoutType.Float3)
                        {
                            bw.WriteVector3(Position);
                        }
                        else if (member.Type == LayoutType.Float4)
                        {
                            bw.WriteVector3(Position);
                            bw.WriteSingle(0);
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                    }
                    else if (member.Semantic == LayoutSemantic.BoneWeights)
                    {
                        if (member.Type == LayoutType.Byte4A)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteSByte((sbyte)Math.Round(BoneWeights[i] * 127));
                            }
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteByte((byte)Math.Round(BoneWeights[i] * 255));
                            }
                        }
                        else if (member.Type == LayoutType.UVPair)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteInt16((short)Math.Round(BoneWeights[i] * 32767));
                            }
                        }
                        else if (member.Type == LayoutType.Short4toFloat4A)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteInt16((short)Math.Round(BoneWeights[i] * 32767));
                            }
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                    }
                    else if (member.Semantic == LayoutSemantic.BoneIndices)
                    {
                        if (member.Type == LayoutType.Byte4B)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteByte((byte)BoneIndices[i]);
                            }
                        }
                        else if (member.Type == LayoutType.ShortBoneIndices)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteUInt16((ushort)BoneIndices[i]);
                            }
                        }
                        else if (member.Type == LayoutType.Byte4E)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteByte((byte)BoneIndices[i]);
                            }
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                    }
                    else if (member.Semantic == LayoutSemantic.Normal)
                    {
                        if (member.Type == LayoutType.Float3)
                        {
                            bw.WriteVector3(Normal);
                        }
                        else if (member.Type == LayoutType.Float4)
                        {
                            bw.WriteVector3(Normal);
                            bw.WriteSingle(NormalW);
                        }
                        else if (member.Type == LayoutType.Byte4A)
                        {
                            WriteByteNormVector3(bw, Normal);
                            bw.WriteByte((byte)NormalW);
                        }
                        else if (member.Type == LayoutType.Byte4B)
                        {
                            WriteByteNormVector3(bw, Normal);
                            bw.WriteByte((byte)NormalW);
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            WriteByteNormVector3(bw, Normal);
                            bw.WriteByte((byte)NormalW);
                        }
                        else if (member.Type == LayoutType.Short4toFloat4A)
                        {
                            WriteShortNormVector3(bw, Normal);
                            bw.WriteInt16((short)NormalW);
                        }
                        else if (member.Type == LayoutType.Short4toFloat4B)
                        {
                            WriteUShortNormVector3(bw, Normal);
                            bw.WriteInt16((short)NormalW);
                        }
                        else if (member.Type == LayoutType.Byte4E)
                        {
                            WriteByteNormVector3(bw, Normal);
                            bw.WriteByte((byte)NormalW);
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                    }
                    else if (member.Semantic == LayoutSemantic.UV)
                    {
                        Vector3 uv = uvQueue.Dequeue() * uvFactor;
                        if (member.Type == LayoutType.Float2)
                        {
                            bw.WriteSingle(uv.X);
                            bw.WriteSingle(uv.Y);
                        }
                        else if (member.Type == LayoutType.Float3)
                        {
                            bw.WriteVector3(uv);
                        }
                        else if (member.Type == LayoutType.Float4)
                        {
                            bw.WriteSingle(uv.X);
                            bw.WriteSingle(uv.Y);

                            uv = uvQueue.Dequeue() * uvFactor;
                            bw.WriteSingle(uv.X);
                            bw.WriteSingle(uv.Y);
                        }
                        else if (member.Type == LayoutType.Byte4A)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == LayoutType.Byte4B)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == LayoutType.Short2toFloat2)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == LayoutType.UV)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == LayoutType.UVPair)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));

                            uv = uvQueue.Dequeue() * uvFactor;
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == LayoutType.Short4toFloat4B)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                            bw.WriteInt16((short)Math.Round(uv.Z));
                            bw.WriteInt16(0);
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                    }
                    else if (member.Semantic == LayoutSemantic.Tangent)
                    {
                        Vector4 tangent = tangentQueue.Dequeue();
                        if (member.Type == LayoutType.Float4)
                        {
                            bw.WriteVector4(tangent);
                        }
                        else if (member.Type == LayoutType.Byte4A)
                        {
                            WriteByteNormVector4(bw, tangent);
                        }
                        else if (member.Type == LayoutType.Byte4B)
                        {
                            WriteByteNormVector4(bw, tangent);
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            WriteByteNormVector4(bw, tangent);
                        }
                        else if (member.Type == LayoutType.Short4toFloat4A)
                        {
                            WriteShortNormVector4(bw, tangent);
                        }
                        else if (member.Type == LayoutType.Byte4E)
                        {
                            WriteByteNormVector4(bw, tangent);
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                    }
                    else if (member.Semantic == LayoutSemantic.Bitangent)
                    {
                        if (member.Type == LayoutType.Byte4A)
                        {
                            WriteByteNormVector4(bw, Bitangent);
                        }
                        else if (member.Type == LayoutType.Byte4B)
                        {
                            WriteByteNormVector4(bw, Bitangent);
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            WriteByteNormVector4(bw, Bitangent);
                        }
                        else if (member.Type == LayoutType.Byte4E)
                        {
                            WriteByteNormVector4(bw, Bitangent);
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                    }
                    else if (member.Semantic == LayoutSemantic.VertexColor)
                    {
                        VertexColor color = colorQueue.Dequeue();
                        if (member.Type == LayoutType.Float4)
                        {
                            color.WriteFloatRGBA(bw);
                        }
                        else if (member.Type == LayoutType.Byte4A)
                        {
                            color.WriteByteARGB(bw);
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            color.WriteByteRGBA(bw);
                        }
                        else
                        {
                            throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                        }
                    }
                    else
                    {
                        throw new NotImplementedException($"Write not implemented for {member.Type} {member.Semantic}.");
                    }
                }
            }