Пример #1
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}.");
                    }
                }
            }
Пример #2
0
 private static void WriteUShortNorm(BinaryWriterEx bw, float value)
 => bw.WriteUInt16((ushort)Math.Round(value * 32767 + 32767));
Пример #3
0
            internal void WriteCells(BinaryWriterEx bw, PARAM parent, int index)
            {
                if (parent.Format2D.HasFlag(FormatFlags1.LongDataOffset))
                {
                    bw.FillInt64($"RowOffset{index}", bw.Position);
                }
                else
                {
                    bw.FillUInt32($"RowOffset{index}", (uint)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}");
                    }
                }
            }
Пример #4
0
 public override void Write(HKX hkx, HKXSection section, BinaryWriterEx bw, uint sectionBaseOffset, HKXVariation variation)
 {
     bw.WriteUInt16(data);
 }
Пример #5
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)
                        {
                            WriteByteNormXYZ(bw, Normal);
                            bw.WriteByte((byte)NormalW);
                        }
                        else if (member.Type == LayoutType.Byte4B)
                        {
                            WriteByteNormXYZ(bw, Normal);
                            bw.WriteByte((byte)NormalW);
                        }
                        else if (member.Type == LayoutType.Short2toFloat2)
                        {
                            bw.WriteByte((byte)NormalW);
                            WriteSByteNormZYX(bw, Normal);
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            WriteByteNormXYZ(bw, Normal);
                            bw.WriteByte((byte)NormalW);
                        }
                        else if (member.Type == LayoutType.Short4toFloat4A)
                        {
                            WriteShortNormXYZ(bw, Normal);
                            bw.WriteInt16((short)NormalW);
                        }
                        else if (member.Type == LayoutType.Short4toFloat4B)
                        {
                            WriteUShortNormXYZ(bw, Normal);
                            bw.WriteInt16((short)NormalW);
                        }
                        else if (member.Type == LayoutType.Byte4E)
                        {
                            WriteByteNormXYZ(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)
                        {
                            WriteByteNormXYZW(bw, tangent);
                        }
                        else if (member.Type == LayoutType.Byte4B)
                        {
                            WriteByteNormXYZW(bw, tangent);
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            WriteByteNormXYZW(bw, tangent);
                        }
                        else if (member.Type == LayoutType.Short4toFloat4A)
                        {
                            WriteShortNormXYZW(bw, tangent);
                        }
                        else if (member.Type == LayoutType.Byte4E)
                        {
                            WriteByteNormXYZW(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)
                        {
                            WriteByteNormXYZW(bw, Bitangent);
                        }
                        else if (member.Type == LayoutType.Byte4B)
                        {
                            WriteByteNormXYZW(bw, Bitangent);
                        }
                        else if (member.Type == LayoutType.Byte4C)
                        {
                            WriteByteNormXYZW(bw, Bitangent);
                        }
                        else if (member.Type == LayoutType.Byte4E)
                        {
                            WriteByteNormXYZW(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.WriteByteRGBA(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}.");
                    }
                }
            }
Пример #6
0
        internal override void Write(BinaryWriterEx bw)
        {
            if (layout == null)
            {
                throw new InvalidOperationException("Params cannot be written without a layout.");
            }

            Rows.Sort((r1, r2) => r1.ID.CompareTo(r2.ID));

            bw.BigEndian = 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);
            }
        }
Пример #7
0
            internal void WriteCells(BinaryWriterEx bw, byte format2D, int i, Layout layout)
            {
                if ((format2D & 0x7F) < 4)
                {
                    bw.FillUInt32($"RowOffset{i}", (uint)bw.Position);
                }
                else
                {
                    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.");
                    }

                    void WriteBools(CellType boolType, int fieldSize)
                    {
                        byte[] b = new byte[fieldSize];
                        int    k;

                        for (k = 0; k < fieldSize * 8; k++)
                        {
                            if (j + k >= layout.Count || layout[j + k].Type != boolType)
                            {
                                break;
                            }

                            if ((bool)Cells[j + k].Value)
                            {
                                b[k / 8] |= (byte)(1 << (k % 8));
                            }
                        }
                        j += k - 1;
                        bw.WriteBytes(b);
                    }

                    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)
                    {
                        WriteBools(type, 1);
                    }
                    else if (type == CellType.b16)
                    {
                        WriteBools(type, 2);
                    }
                    else if (type == CellType.b32)
                    {
                        WriteBools(type, 4);
                    }
                }
            }
Пример #8
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)Math.Round(BoneWeights[i] * sbyte.MaxValue));
                            }
                        }
                        else if (member.Type == BufferLayout.MemberType.Short4toFloat4A)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteInt16((short)Math.Round(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)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 == BufferLayout.MemberType.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 == BufferLayout.MemberType.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 == BufferLayout.MemberType.Short4toFloat4B)
                        {
                            bw.WriteInt16((short)Math.Round(Normal.X * 32767 + 32767));
                            bw.WriteInt16((short)Math.Round(Normal.Y * 32767 + 32767));
                            bw.WriteInt16((short)Math.Round(Normal.Z * 32767 + 32767));
                            bw.WriteInt16((short)Math.Round(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)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == BufferLayout.MemberType.Short2toFloat2)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == BufferLayout.MemberType.UV)
                        {
                            bw.WriteInt16((short)Math.Round(uv.X));
                            bw.WriteInt16((short)Math.Round(uv.Y));
                        }
                        else if (member.Type == BufferLayout.MemberType.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
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.Tangent:
                        Vector4 tangent = tangentQueue.Dequeue();
                        if (member.Type == BufferLayout.MemberType.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 == BufferLayout.MemberType.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 == BufferLayout.MemberType.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
                        {
                            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)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 == BufferLayout.MemberType.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();
                        }
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
            }
Пример #9
0
        /// <summary>
        /// Serializes file data to a stream.
        /// </summary>
        internal 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
        }
Пример #10
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];
                    string       type  = entry.Type;
                    object       value = cell.Value;

                    if (entry.Name != cell.Name || type != cell.Type)
                    {
                        throw new FormatException("Layout does not match cells.");
                    }

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

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

                            if ((bool)Cells[j + k].Value)
                            {
                                b[k / 8] |= (byte)(1 << (k % 8));
                            }
                        }
                        j += k - 1;
                        bw.WriteBytes(b);
                    }
                }
            }
Пример #11
0
        internal override void Write(BinaryWriterEx bw)
        {
            if (layout == null)
            {
                throw new InvalidOperationException("Params cannot be written without a layout.");
            }

            Rows.Sort((r1, r2) => r1.ID.CompareTo(r2.ID));

            bw.BigEndian = false;

            bw.ReserveInt32("NameOffset");
            bw.WriteInt16(0);
            bw.WriteInt16(Unk1);
            bw.WriteInt16(Unk2);
            bw.WriteUInt16((ushort)Rows.Count);

            if (FixStrID)
            {
                bw.WriteFixStr(ID, 0x20);
            }
            else
            {
                bw.WriteInt32(0);
                bw.ReserveInt32("IDOffset");
                bw.WriteInt32(0);
                bw.WriteInt32(0);
                bw.WriteInt32(0);
                bw.WriteInt32(0);
                bw.WriteInt32(0);
                bw.WriteInt32(0);
            }

            bw.WriteByte(0);
            bw.WriteByte(Unk3);
            bw.WriteByte(Unk4);
            bw.WriteByte(0);

            bw.ReserveInt64("DataStart");
            bw.WriteInt32(0);
            bw.WriteInt32(0);

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

            bw.FillInt64("DataStart", bw.Position);

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

            bw.FillInt32("NameOffset", (int)bw.Position);
            if (FixStrID)
            {
                if (Unk4 == 6)
                {
                    bw.WriteShiftJIS(Name, true);
                }
                else if (Unk4 == 7)
                {
                    bw.WriteUTF16(Name, true);
                }
            }
            else
            {
                bw.WriteShiftJIS(Name, true);
                bw.FillInt32("IDOffset", (int)bw.Position);
                bw.WriteASCII(ID, true);
            }

            for (int i = 0; i < Rows.Count; i++)
            {
                Rows[i].WriteName(bw, i, Unk4);
            }
        }
Пример #12
0
        protected override void Write(BinaryWriterEx bw)
        {
            bw.WriteASCII("FXR\0");
            bw.WriteInt16(0);
            bw.WriteUInt16((ushort)Version);
            bw.WriteInt32(1);
            bw.WriteInt32(ID);
            bw.ReserveInt32("Section1Offset");
            bw.WriteInt32(1);
            bw.ReserveInt32("Section2Offset");
            bw.WriteInt32(Section1Tree.Section2s.Count);
            bw.ReserveInt32("Section3Offset");
            bw.ReserveInt32("Section3Count");
            bw.ReserveInt32("Section4Offset");
            bw.ReserveInt32("Section4Count");
            bw.ReserveInt32("Section5Offset");
            bw.ReserveInt32("Section5Count");
            bw.ReserveInt32("Section6Offset");
            bw.ReserveInt32("Section6Count");
            bw.ReserveInt32("Section7Offset");
            bw.ReserveInt32("Section7Count");
            bw.ReserveInt32("Section8Offset");
            bw.ReserveInt32("Section8Count");
            bw.ReserveInt32("Section9Offset");
            bw.ReserveInt32("Section9Count");
            bw.ReserveInt32("Section10Offset");
            bw.ReserveInt32("Section10Count");
            bw.ReserveInt32("Section11Offset");
            bw.ReserveInt32("Section11Count");
            bw.WriteInt32(1);
            bw.WriteInt32(0);

            if (Version == FXRVersion.Sekiro)
            {
                bw.ReserveInt32("Section12Offset");
                bw.WriteInt32(Section12s.Count);
                bw.ReserveInt32("Section13Offset");
                bw.WriteInt32(Section13s.Count);
                bw.ReserveInt32("Section14Offset");
                bw.WriteInt32(0);
                bw.WriteInt32(0);
                bw.WriteInt32(0);
            }

            bw.FillInt32("Section1Offset", (int)bw.Position);
            Section1Tree.Write(bw);
            bw.Pad(0x10);

            bw.FillInt32("Section2Offset", (int)bw.Position);
            Section1Tree.WriteSection2s(bw);
            bw.Pad(0x10);

            bw.FillInt32("Section3Offset", (int)bw.Position);
            List <Section2> section2s = Section1Tree.Section2s;
            var             section3s = new List <Section3>();

            for (int i = 0; i < section2s.Count; i++)
            {
                section2s[i].WriteSection3s(bw, i, section3s);
            }
            bw.FillInt32("Section3Count", section3s.Count);
            bw.Pad(0x10);

            bw.FillInt32("Section4Offset", (int)bw.Position);
            var section4s = new List <Section4>();

            Section4Tree.Write(bw, section4s);
            Section4Tree.WriteSection4s(bw, section4s);
            bw.FillInt32("Section4Count", section4s.Count);
            bw.Pad(0x10);

            bw.FillInt32("Section5Offset", (int)bw.Position);
            int section5Count = 0;

            for (int i = 0; i < section4s.Count; i++)
            {
                section4s[i].WriteSection5s(bw, i, ref section5Count);
            }
            bw.FillInt32("Section5Count", section5Count);
            bw.Pad(0x10);

            bw.FillInt32("Section6Offset", (int)bw.Position);
            section5Count = 0;
            var section6s = new List <FFXDrawEntityHost>();

            for (int i = 0; i < section4s.Count; i++)
            {
                section4s[i].WriteSection6s(bw, i, ref section5Count, section6s);
            }
            bw.FillInt32("Section6Count", section6s.Count);
            bw.Pad(0x10);

            bw.FillInt32("Section7Offset", (int)bw.Position);
            var section7s = new List <FFXProperty>();

            for (int i = 0; i < section6s.Count; i++)
            {
                section6s[i].WriteSection7s(bw, i, section7s);
            }
            bw.FillInt32("Section7Count", section7s.Count);
            bw.Pad(0x10);

            bw.FillInt32("Section8Offset", (int)bw.Position);
            var section8s = new List <Section8>();

            for (int i = 0; i < section7s.Count; i++)
            {
                section7s[i].WriteSection8s(bw, i, section8s);
            }
            bw.FillInt32("Section8Count", section8s.Count);
            bw.Pad(0x10);

            bw.FillInt32("Section9Offset", (int)bw.Position);
            var section9s = new List <Section9>();

            for (int i = 0; i < section8s.Count; i++)
            {
                section8s[i].WriteSection9s(bw, i, section9s);
            }
            bw.FillInt32("Section9Count", section9s.Count);
            bw.Pad(0x10);

            bw.FillInt32("Section10Offset", (int)bw.Position);
            var section10s = new List <Section10>();

            for (int i = 0; i < section6s.Count; i++)
            {
                section6s[i].WriteSection10s(bw, i, section10s);
            }
            bw.FillInt32("Section10Count", section10s.Count);
            bw.Pad(0x10);

            bw.FillInt32("Section11Offset", (int)bw.Position);
            int section11Count = 0;

            for (int i = 0; i < section3s.Count; i++)
            {
                section3s[i].WriteSection11s(bw, i, ref section11Count);
            }
            for (int i = 0; i < section6s.Count; i++)
            {
                section6s[i].WriteSection11s(bw, i, ref section11Count);
            }
            for (int i = 0; i < section7s.Count; i++)
            {
                section7s[i].WriteSection11s(bw, i, ref section11Count);
            }
            for (int i = 0; i < section8s.Count; i++)
            {
                section8s[i].WriteSection11s(bw, i, ref section11Count);
            }
            for (int i = 0; i < section9s.Count; i++)
            {
                section9s[i].WriteSection11s(bw, i, ref section11Count);
            }
            for (int i = 0; i < section10s.Count; i++)
            {
                section10s[i].WriteSection11s(bw, i, ref section11Count);
            }
            bw.FillInt32("Section11Count", section11Count);
            bw.Pad(0x10);

            if (Version == FXRVersion.Sekiro)
            {
                bw.FillInt32("Section12Offset", (int)bw.Position);
                bw.WriteInt32s(Section12s);
                bw.Pad(0x10);

                bw.FillInt32("Section13Offset", (int)bw.Position);
                bw.WriteInt32s(Section13s);
                bw.Pad(0x10);

                bw.FillInt32("Section14Offset", (int)bw.Position);
            }
        }