Ejemplo n.º 1
0
 public static FontInfo Read(Stream stream) =>
 BinaryMapping.ReadObject <FontInfo>(stream);
Ejemplo n.º 2
0
 public static SaveKh3 Read(Stream stream) =>
 BinaryMapping.ReadObject(new BinaryReader(stream), new SaveKh3()) as SaveKh3;
Ejemplo n.º 3
0
        private Motion(Stream stream)
        {
            stream.Position += ReservedSize;

            var header = BinaryMapping.ReadObject <Header>(stream);

            IsRaw   = header.Version == 1;
            UnkFlag = header.Unk04 != 0;

            if (IsRaw)
            {
                var raw = BinaryMapping.ReadObject <RawMotionInternal>(stream);
                Raw = new RawMotion
                {
                    BoneCount       = raw.BoneCount,
                    Unk28           = raw.Unk28,
                    Unk2c           = raw.Unk2c,
                    BoundingBoxMinX = raw.BoundingBoxMinX,
                    BoundingBoxMinY = raw.BoundingBoxMinY,
                    BoundingBoxMinZ = raw.BoundingBoxMinZ,
                    BoundingBoxMinW = raw.BoundingBoxMinW,
                    BoundingBoxMaxX = raw.BoundingBoxMaxX,
                    BoundingBoxMaxY = raw.BoundingBoxMaxY,
                    BoundingBoxMaxZ = raw.BoundingBoxMaxZ,
                    BoundingBoxMaxW = raw.BoundingBoxMaxW,
                    FrameLoop       = raw.FrameLoop,
                    FrameEnd        = raw.FrameEnd,
                    FramePerSecond  = raw.FramePerSecond,
                    FrameCount      = raw.FrameCount
                };

                var reader = new BinaryReader(stream);
                Raw.Matrices = new List <Matrix4x4[]>(raw.TotalFrameCount);
                for (var i = 0; i < raw.TotalFrameCount; i++)
                {
                    var matrices = new Matrix4x4[Raw.BoneCount];
                    for (var j = 0; j < Raw.BoneCount; j++)
                    {
                        matrices[j] = ReadMatrix(reader);
                    }

                    Raw.Matrices.Add(matrices);
                }

                if (raw.Unk2c > 0)
                {
                    stream.Position = ReservedSize + raw.Unk2c;
                    Raw.Matrices2   = new Matrix4x4[raw.TotalFrameCount];
                    for (var j = 0; j < Raw.Matrices2.Length; j++)
                    {
                        Raw.Matrices2[j] = ReadMatrix(reader);
                    }
                }
                else
                {
                    Raw.Matrices2 = new Matrix4x4[0];
                }
            }
            else
            {
                var reader = new BinaryReader(stream);
                var motion = BinaryMapping.ReadObject <InterpolatedMotionInternal>(stream);
                Interpolated = new InterpolatedMotion
                {
                    BoneCount       = motion.BoneCount,
                    TotalFrameCount = motion.TotalFrameCount,
                    Unk48           = motion.Unk48,
                    BoundingBoxMinX = motion.BoundingBoxMinX,
                    BoundingBoxMinY = motion.BoundingBoxMinY,
                    BoundingBoxMinZ = motion.BoundingBoxMinZ,
                    BoundingBoxMinW = motion.BoundingBoxMinW,
                    BoundingBoxMaxX = motion.BoundingBoxMaxX,
                    BoundingBoxMaxY = motion.BoundingBoxMaxY,
                    BoundingBoxMaxZ = motion.BoundingBoxMaxZ,
                    BoundingBoxMaxW = motion.BoundingBoxMaxW,
                    FrameLoop       = motion.FrameLoop,
                    FrameEnd        = motion.FrameEnd,
                    FramePerSecond  = motion.FramePerSecond,
                    FrameCount      = motion.FrameCount,
                    Unk98           = motion.Unk98,
                    Unk9c           = motion.Unk9c,
                };

                stream.Position         = ReservedSize + motion.StaticPoseOffset;
                Interpolated.StaticPose = Enumerable
                                          .Range(0, motion.StaticPoseCount)
                                          .Select(x => BinaryMapping.ReadObject <StaticPoseTable>(stream))
                                          .ToList();

                stream.Position = ReservedSize + motion.ModelBoneAnimationOffset;
                Interpolated.ModelBoneAnimation = Enumerable
                                                  .Range(0, motion.ModelBoneAnimationCount)
                                                  .Select(x => BinaryMapping.ReadObject <BoneAnimationTableInternal>(stream))
                                                  .Select(Map)
                                                  .ToList();

                stream.Position = ReservedSize + motion.IKHelperAnimationOffset;
                Interpolated.IKHelperAnimation = Enumerable
                                                 .Range(0, motion.IKHelperAnimationCount)
                                                 .Select(x => BinaryMapping.ReadObject <BoneAnimationTableInternal>(stream))
                                                 .Select(Map)
                                                 .ToList();

                stream.Position = ReservedSize + motion.TimelineOffset;
                var estimatedTimelineCount = (motion.KeyFrameOffset - motion.TimelineOffset) / 8;
                var rawTimeline            = Enumerable
                                             .Range(0, estimatedTimelineCount)
                                             .Select(x => BinaryMapping.ReadObject <TimelineTableInternal>(stream))
                                             .ToList();

                stream.Position = ReservedSize + motion.KeyFrameOffset;
                var keyFrames = Enumerable
                                .Range(0, motion.KeyFrameCount)
                                .Select(x => reader.ReadSingle())
                                .ToList();

                stream.Position = ReservedSize + motion.TransformationValueOffset;
                var estimatedKeyFrameCount = (motion.TangentOffset - motion.TransformationValueOffset) / 4;
                var transformationValues   = Enumerable
                                             .Range(0, estimatedKeyFrameCount)
                                             .Select(x => reader.ReadSingle())
                                             .ToList();

                stream.Position = ReservedSize + motion.TangentOffset;
                var estimatedTangentCount = (motion.IKChainOffset - motion.TangentOffset) / 4;
                var tangentValues         = Enumerable
                                            .Range(0, estimatedTangentCount)
                                            .Select(x => reader.ReadSingle())
                                            .ToList();

                stream.Position       = ReservedSize + motion.IKChainOffset;
                Interpolated.IKChains = Enumerable
                                        .Range(0, motion.IKChainCount)
                                        .Select(x => BinaryMapping.ReadObject <IKChainTable>(stream))
                                        .ToList();

                stream.Position = ReservedSize + motion.Table8Offset;
                var estimatedTable8Count = (motion.Table7Offset - motion.Table8Offset) / 0x30;
                Interpolated.Table8 = Enumerable
                                      .Range(0, estimatedTable8Count)
                                      .Select(x => BinaryMapping.ReadObject <UnknownTable8>(stream))
                                      .ToList();

                stream.Position     = ReservedSize + motion.Table7Offset;
                Interpolated.Table7 = Enumerable
                                      .Range(0, motion.Table7Count)
                                      .Select(x => BinaryMapping.ReadObject <UnknownTable7>(stream))
                                      .ToList();

                stream.Position     = ReservedSize + motion.Table6Offset;
                Interpolated.Table6 = Enumerable
                                      .Range(0, motion.Table6Count)
                                      .Select(x => BinaryMapping.ReadObject <UnknownTable6>(stream))
                                      .ToList();

                stream.Position        = ReservedSize + motion.IKHelperOffset;
                Interpolated.IKHelpers = Enumerable
                                         .Range(0, motion.TotalBoneCount - motion.BoneCount)
                                         .Select(x => BinaryMapping.ReadObject <IKHelperTable>(stream))
                                         .ToList();

                stream.Position     = ReservedSize + motion.JointIndexOffset;
                Interpolated.Joints = Enumerable
                                      .Range(0, motion.TotalBoneCount + 1)
                                      .Select(x => BinaryMapping.ReadObject <JointTable>(stream))
                                      .ToList();

                Interpolated.Timeline = rawTimeline
                                        .Select(x => new TimelineTable
                {
                    Interpolation  = (Interpolation)(x.Time & 3),
                    KeyFrame       = keyFrames[Math.Min(keyFrames.Count - 1, x.Time >> 2)],
                    Value          = transformationValues[Math.Min(transformationValues.Count - 1, x.ValueIndex)],
                    TangentEaseIn  = tangentValues[x.TangentIndexEaseIn],
                    TangentEaseOut = tangentValues[x.TangentIndexEaseOut],
                })
                                        .ToList();

                stream.Position     = ReservedSize + motion.FooterOffset;
                Interpolated.Footer = BinaryMapping.ReadObject <FooterTable>(stream);

                stream.Position = ReservedSize + motion.UnknownTable1Offset;
            }
        }
Ejemplo n.º 4
0
 public void Write(Stream stream) =>
 BinaryMapping.WriteObject(stream.FromBegin(), this);
Ejemplo n.º 5
0
        public TextureFooterData(Stream stream)
        {
            var shouldEmitDMYAtFirst = false;
            var index = -1;

            while (stream.Position < stream.Length)
            {
                ++index;

                var tag = Encoding.ASCII.GetString(stream.ReadBytes(4));
                if (tag == "_KN5")
                {
                    ShouldEmitDMYAtFirst = (index == 1) && shouldEmitDMYAtFirst;
                    ShouldEmitKN5        = true;

                    UnkFooter = stream.ReadBytes();
                    break;
                }

                var length  = stream.ReadInt32();
                var nextTag = stream.Position + length;

                var subStreamPos = Convert.ToInt32(stream.Position);

                if (tag == "UVSC")
                {
                    UvscList.Add(BinaryMapping.ReadObject <UvScroll>(stream));
                }
                else if (tag == "TEXA")
                {
                    var header = BinaryMapping.ReadObject <TextureAnimation>(stream);

                    stream.Position  = subStreamPos + header.OffsetSlotTable;
                    header.SlotTable = Enumerable.Range(0, 1 + header.MaximumSlotIndex - header.BaseSlotIndex)
                                       .Select(_ => stream.ReadInt16())
                                       .ToArray();

                    stream.Position = subStreamPos + header.OffsetAnimationTable;
                    var frameGroupOffsetList = Enumerable.Range(0, header.NumAnimations)
                                               .Select(idx => stream.ReadUInt32())
                                               .ToArray();

                    header.FrameGroupList = frameGroupOffsetList
                                            .Select(
                        firstPosition =>
                    {
                        stream.Position      = subStreamPos + firstPosition;
                        var indexedFrameList = new Dictionary <int, TextureFrame>();
                        var idx = 0;
                        while (true)
                        {
                            if (indexedFrameList.ContainsKey(idx))
                            {
                                break;
                            }

                            var frame             = BinaryMapping.ReadObject <TextureFrame>(stream);
                            indexedFrameList[idx] = frame;
                            if (frame.FrameControl == TextureFrameControl.Jump || frame.FrameControl == TextureFrameControl.Stop)
                            {
                                idx += frame.FrameIndexDelta;
                                stream.Seek(TextureFrame.SizeInBytes * (-1 + frame.FrameIndexDelta), SeekOrigin.Current);
                            }
                            else
                            {
                                idx++;
                            }
                        }
                        return(new TextureFrameGroup
                        {
                            IndexedFrameList = indexedFrameList,
                        });
                    }
                        )
                                            .ToArray();

                    header.SpriteImage = stream
                                         .SetPosition(subStreamPos + header.OffsetSpriteImage)
                                         .ReadBytes(header.SpriteStride * header.SpriteHeight * header.NumSpritesInImageData);

                    TextureAnimationList.Add(header);
                }
                else if (tag == "_DMY")
                {
                    shouldEmitDMYAtFirst |= (index == 0) ? true : false;
                }

                stream.Position = nextTag;
            }
        }
Ejemplo n.º 6
0
 public static IEnumerable <Entry> Read(Stream stream) => Enumerable
 .Range(0, (int)(stream.Length / 0x20))
 .Select(_ => BinaryMapping.ReadObject <Entry>(stream));
Ejemplo n.º 7
0
        public static void ReadMeshData(Stream stream, Pmo pmo, int MeshNumber = 0)
        {
            // Go to mesh position.
            if (MeshNumber == 0)
            {
                stream.Seek(pmo.header.MeshOffset0, SeekOrigin.Begin);
            }
            else
            {
                stream.Seek(pmo.header.MeshOffset1, SeekOrigin.Begin);
            }

            UInt16 VertCnt = 0xFFFF;

            while (VertCnt > 0)
            {
                MeshChunks meshChunk = new MeshChunks();
                meshChunk.MeshNumber = MeshNumber;

                meshChunk.SectionInfo = BinaryMapping.ReadObject <MeshSection>(stream);

                // Exit if Vertex Count is zero.
                if (meshChunk.SectionInfo.VertexCount <= 0)
                {
                    break;
                }

                meshChunk.TextureID = meshChunk.SectionInfo.TextureID;
                VertexFlags flags = GetFlags(meshChunk.SectionInfo);

                bool isColorFlagRisen = flags.UniformDiffuseFlag;

                if (pmo.header.SkeletonOffset != 0)
                {
                    meshChunk.SectionInfo_opt1 = BinaryMapping.ReadObject <MeshSectionOptional1>(stream);
                }
                if (isColorFlagRisen)
                {
                    meshChunk.SectionInfo_opt2 = BinaryMapping.ReadObject <MeshSectionOptional2>(stream);
                }
                if (meshChunk.SectionInfo.TriangleStripCount > 0)
                {
                    meshChunk.TriangleStripValues = new UInt16[meshChunk.SectionInfo.TriangleStripCount];
                    for (int i = 0; i < meshChunk.SectionInfo.TriangleStripCount; i++)
                    {
                        meshChunk.TriangleStripValues[i] = stream.ReadUInt16();
                    }
                }

                // Get Formats.
                CoordinateFormat TexCoordFormat       = flags.TextureCoordinateFormat;
                CoordinateFormat VertexPositionFormat = flags.PositionFormat;
                CoordinateFormat WeightFormat         = flags.WeightFormat;
                ColorFormat      ColorFormat          = flags.ColorFormat;
                UInt32           SkinningWeightsCount = flags.SkinningWeightsCount;
                BinaryReader     r = new BinaryReader(stream);
                long             positionAfterHeader = stream.Position;

                if (meshChunk.SectionInfo.TriangleStripCount > 0)
                {
                    int vertInd = 0;
                    for (int p = 0; p < meshChunk.SectionInfo.TriangleStripCount; p++)
                    {
                        for (int s = 0; s < (meshChunk.TriangleStripValues[p] - 2); s++)
                        {
                            if (s % 2 == 0)
                            {
                                meshChunk.Indices.Add(vertInd + s + 0);
                                meshChunk.Indices.Add(vertInd + s + 1);
                                meshChunk.Indices.Add(vertInd + s + 2);
                            }
                            else
                            {
                                meshChunk.Indices.Add(vertInd + s + 0);
                                meshChunk.Indices.Add(vertInd + s + 2);
                                meshChunk.Indices.Add(vertInd + s + 1);
                            }
                        }

                        vertInd += meshChunk.TriangleStripValues[p];
                    }
                }
                else
                {
                    if (flags.Primitive == PrimitiveType.PRIMITIVE_TRIANGLE_STRIP)
                    {
                        for (int s = 0; s < (meshChunk.SectionInfo.VertexCount - 2); s++)
                        {
                            if (s % 2 == 0)
                            {
                                meshChunk.Indices.Add(s + 0);
                                meshChunk.Indices.Add(s + 1);
                                meshChunk.Indices.Add(s + 2);
                            }
                            else
                            {
                                meshChunk.Indices.Add(s + 1);
                                meshChunk.Indices.Add(s + 0);
                                meshChunk.Indices.Add(s + 2);
                            }
                        }
                    }
                }

                for (int v = 0; v < meshChunk.SectionInfo.VertexCount; v++)
                {
                    long vertexStartPos       = stream.Position;
                    int  vertexIncreaseAmount = 0;

                    if (pmo.header.SkeletonOffset != 0 && WeightFormat != CoordinateFormat.NO_VERTEX)
                    {
                        for (int i = 0; i < (SkinningWeightsCount + 1); i++)
                        {
                            switch (WeightFormat)
                            {
                            case CoordinateFormat.NORMALIZED_8_BITS:
                                meshChunk.jointWeights.Add(stream.ReadByte() / 127.0f);
                                break;

                            case CoordinateFormat.NORMALIZED_16_BITS:
                                meshChunk.jointWeights.Add(stream.ReadUInt16() / 32767.0f);
                                break;

                            case CoordinateFormat.FLOAT_32_BITS:
                                meshChunk.jointWeights.Add(stream.ReadFloat());
                                break;

                            case CoordinateFormat.NO_VERTEX:
                                break;
                            }
                        }
                    }

                    Vector2 currentTexCoord;

                    switch (TexCoordFormat)
                    {
                    case CoordinateFormat.NORMALIZED_8_BITS:
                        currentTexCoord.X = stream.ReadByte() / 127.0f;
                        currentTexCoord.Y = stream.ReadByte() / 127.0f;
                        meshChunk.textureCoordinates.Add(currentTexCoord);
                        break;

                    case CoordinateFormat.NORMALIZED_16_BITS:
                        vertexIncreaseAmount = ((0x2 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x1)) & 0x1);
                        stream.Seek(vertexIncreaseAmount, SeekOrigin.Current);

                        currentTexCoord.X = stream.ReadUInt16() / 32767.0f;
                        currentTexCoord.Y = stream.ReadUInt16() / 32767.0f;
                        meshChunk.textureCoordinates.Add(currentTexCoord);
                        break;

                    case CoordinateFormat.FLOAT_32_BITS:
                        vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3);
                        stream.Seek(vertexIncreaseAmount, SeekOrigin.Current);

                        currentTexCoord.X = stream.ReadFloat();
                        currentTexCoord.Y = stream.ReadFloat();
                        meshChunk.textureCoordinates.Add(currentTexCoord);
                        break;
                    }

                    switch (ColorFormat)
                    {
                    case Pmo.ColorFormat.NO_COLOR:
                        meshChunk.colors.Add(new Vector4(0xFF, 0xFF, 0xFF, 0xFF));
                        break;

                    case Pmo.ColorFormat.BGR_5650_16BITS:
                        stream.ReadUInt16();
                        break;

                    case Pmo.ColorFormat.ABGR_5551_16BITS:
                        stream.ReadUInt16();
                        break;

                    case Pmo.ColorFormat.ABGR_4444_16BITS:
                        stream.ReadUInt16();
                        break;

                    case Pmo.ColorFormat.ABGR_8888_32BITS:
                        vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3);
                        stream.Seek(vertexIncreaseAmount, SeekOrigin.Current);

                        Vector4 col;
                        col.X = stream.ReadByte();
                        col.Y = stream.ReadByte();
                        col.Z = stream.ReadByte();
                        col.W = stream.ReadByte();
                        meshChunk.colors.Add(col);
                        break;
                    }

                    Vector3 currentVertex;

                    // Handle triangles and triangle strips.
                    switch (VertexPositionFormat)
                    {
                    case CoordinateFormat.NORMALIZED_8_BITS:
                        currentVertex.X = r.ReadSByte() / 127.0f;
                        currentVertex.Y = r.ReadSByte() / 127.0f;
                        currentVertex.Z = r.ReadSByte() / 127.0f;
                        meshChunk.vertices.Add(currentVertex);
                        break;

                    case CoordinateFormat.NORMALIZED_16_BITS:
                        vertexIncreaseAmount = ((0x2 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x1)) & 0x1);
                        stream.Seek(vertexIncreaseAmount, SeekOrigin.Current);

                        currentVertex.X = (float)stream.ReadInt16() / 32767.0f;
                        currentVertex.Y = (float)stream.ReadInt16() / 32767.0f;
                        currentVertex.Z = (float)stream.ReadInt16() / 32767.0f;
                        meshChunk.vertices.Add(currentVertex);
                        break;

                    case CoordinateFormat.FLOAT_32_BITS:
                        vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3);
                        stream.Seek(vertexIncreaseAmount, SeekOrigin.Current);

                        currentVertex.X = stream.ReadFloat();
                        currentVertex.Y = stream.ReadFloat();
                        currentVertex.Z = stream.ReadFloat();
                        meshChunk.vertices.Add(currentVertex);
                        break;
                    }

                    stream.Seek(vertexStartPos + meshChunk.SectionInfo.VertexSize, SeekOrigin.Begin);

                    if (flags.Primitive == PrimitiveType.PRIMITIVE_TRIANGLE)
                    {
                        meshChunk.Indices.Add(v);
                    }
                }

                VertCnt = meshChunk.SectionInfo.VertexCount;
                pmo.Meshes.Add(meshChunk);

                // Find position of next data chunk.
                stream.Seek(positionAfterHeader + (meshChunk.SectionInfo.VertexCount * meshChunk.SectionInfo.VertexSize), SeekOrigin.Begin);
                stream.Seek(stream.Position % 4, SeekOrigin.Current);
            }
        }
Ejemplo n.º 8
0
 public static Signal Read(Stream stream) =>
 BinaryMapping.ReadObject <Signal>(stream);
Ejemplo n.º 9
0
 public static void Write(Stream stream, Signal entity) =>
 BinaryMapping.WriteObject(stream, entity);
Ejemplo n.º 10
0
 public static ReturnParameter Read(Stream stream) =>
 BinaryMapping.ReadObject <ReturnParameter>(stream);
Ejemplo n.º 11
0
 public static void Write(Stream stream, ReturnParameter entity) =>
 BinaryMapping.WriteObject(stream, entity);
Ejemplo n.º 12
0
        private static M4 ReadAsMap(Stream stream)
        {
            var header = BinaryMapping.ReadObject <SubModelMapHeader>(stream);

            if (header.Type != Map)
            {
                throw new NotSupportedException("Type must be 2 for maps");
            }

            var dmaChainMaps = For(header.DmaChainMapCount, () => BinaryMapping.ReadObject <DmaChainMap>(stream));

            stream.Position = header.Offset1;

            // The original game engine ignores header.Count1 for some reason
            var count1 = (short)((stream.ReadInt32() - header.Offset1) / 4);

            stream.Position -= 4;

            var alb2 = For(count1, () => stream.ReadInt32())
                       .Select(offset => ReadAlb2t2(stream.SetPosition(offset)).ToArray())
                       .ToList();

            stream.Position = header.Offset2;
            var offb1t2t2         = stream.ReadInt32();
            var unknownTableCount = (offb1t2t2 - header.Offset2) / 4 - 1;
            var unknownTable      = For(unknownTableCount, () => stream.ReadInt32())
                                    .ToArray();

            stream.Position = offb1t2t2;
            var alb1t2 = ReadAlb2t2(stream).ToList();

            var vifPackets = dmaChainMaps
                             .Select(dmaChain =>
            {
                var currentVifOffset = dmaChain.VifOffset;

                DmaTag dmaTag;
                var packet     = new List <byte>();
                var sizePerDma = new List <ushort>();
                do
                {
                    stream.Position = currentVifOffset;
                    dmaTag          = BinaryMapping.ReadObject <DmaTag>(stream);
                    var packets     = stream.ReadBytes(8 + 16 * dmaTag.Qwc);

                    packet.AddRange(packets);

                    sizePerDma.Add(dmaTag.Qwc);
                    currentVifOffset += 16 + 16 * dmaTag.Qwc;
                } while (dmaTag.TagId < 2);

                return(new VifPacketDescriptor
                {
                    VifPacket = packet.ToArray(),
                    TextureId = dmaChain.TextureIndex,
                    Unk08 = dmaChain.Unk08,
                    Unk0c = dmaChain.Unk0c,
                    DmaPerVif = sizePerDma.ToArray(),
                });
            })
                             .ToList();

            return(new M4
            {
                unk04 = header.Unk04,
                unk08 = header.Unk08,
                nextOffset = header.NextOffset,
                va4 = header.va4,
                count1 = header.Count1,

                alb1t2 = alb1t2.ToList(),
                alb2 = alb2,
                unknownTable = unknownTable,
                VifPackets = vifPackets
            });
        }
Ejemplo n.º 13
0
        private static void WriteAsMap(Stream stream, M4 mapModel)
        {
            var mapHeader = new SubModelMapHeader
            {
                Type             = Map,
                DmaChainMapCount = mapModel.VifPackets.Count,

                Unk04      = mapModel.unk04,
                Unk08      = mapModel.unk08,
                NextOffset = mapModel.nextOffset,
                va4        = mapModel.va4,
                Count1     = mapModel.count1, // in a form, ignored by the game engine
            };

            BinaryMapping.WriteObject(stream, mapHeader);

            var dmaChainMapDescriptorOffset = (int)stream.Position;

            stream.Position += mapModel.VifPackets.Count * 0x10;

            mapHeader.Offset1 = (int)stream.Position;
            stream.Position  += mapModel.alb2.Count * 4;
            var alb2Offsets = new List <int>();

            foreach (var alb2 in mapModel.alb2)
            {
                alb2Offsets.Add((int)stream.Position);
                WriteAlb2(stream, alb2);
            }

            var endAlb2Offset = Helpers.Align((int)stream.Position, 4);

            stream.Position = mapHeader.Offset1;
            foreach (var alb2Offset in alb2Offsets)
            {
                stream.Write(alb2Offset);
            }
            stream.Position = endAlb2Offset;

            mapHeader.Offset2 = endAlb2Offset;
            stream.Write(endAlb2Offset + 4 + mapModel.unknownTable.Length * 4);
            stream.Write(mapModel.unknownTable);
            WriteAlb2(stream, mapModel.alb1t2);

            stream.AlignPosition(0x10);

            var dmaChainVifOffsets = new List <int>();

            foreach (var dmaChainMap in mapModel.VifPackets)
            {
                var vifPacketIndex = 0;
                dmaChainVifOffsets.Add((int)stream.Position);

                foreach (var packetCount in dmaChainMap.DmaPerVif)
                {
                    BinaryMapping.WriteObject(stream, new DmaTag
                    {
                        Qwc     = packetCount,
                        Address = 0,
                        TagId   = packetCount > 0 ? 1 : 6,
                        Irq     = false,
                    });

                    var packetLength = packetCount * 0x10 + 8;
                    stream.Write(dmaChainMap.VifPacket, vifPacketIndex, packetLength);

                    vifPacketIndex += packetLength;
                }
            }

            stream.AlignPosition(0x80);
            stream.SetLength(stream.Position);

            stream.Position = dmaChainMapDescriptorOffset;
            for (var i = 0; i < mapModel.VifPackets.Count; i++)
            {
                var dmaChainMap = mapModel.VifPackets[i];
                BinaryMapping.WriteObject(stream, new DmaChainMap
                {
                    VifOffset    = dmaChainVifOffsets[i],
                    TextureIndex = dmaChainMap.TextureId,
                    Unk08        = dmaChainMap.Unk08,
                    Unk0c        = dmaChainMap.Unk0c
                });
            }

            stream.Position = 0;
            BinaryMapping.WriteObject(stream, mapHeader);
        }
Ejemplo n.º 14
0
 public void Write(Stream stream) =>
 BinaryMapping.WriteObject(stream, this);
Ejemplo n.º 15
0
 private static Bone ReadBone(Stream stream) => BinaryMapping.ReadObject <Bone>(stream);
Ejemplo n.º 16
0
 public static TSaveKhDDD Read <TSaveKhDDD>(Stream stream)
     where TSaveKhDDD : class, ISaveKhDDD =>
 BinaryMapping.ReadObject <TSaveKhDDD>(stream.SetPosition(0));
Ejemplo n.º 17
0
 private static void WriteBone(Stream stream, Bone bone) => BinaryMapping.WriteObject(stream, bone);
Ejemplo n.º 18
0
 public static void Write <TSaveKhDDD>(Stream stream, TSaveKhDDD save)
     where TSaveKhDDD : class, ISaveKhDDD
 {
     BinaryMapping.WriteObject(stream.FromBegin(), save);
 }
Ejemplo n.º 19
0
 public static void ReadHeader(Stream stream, Pmo pmo)
 {
     pmo.header = BinaryMapping.ReadObject <Header>(stream.SetPosition(0));
 }
Ejemplo n.º 20
0
        public void Write(Stream stream)
        {
            stream.MustWriteAndSeek();

            var header = new Header
            {
                MagicCode  = MagicCodeValidator,
                Unknown04  = Unknown04,
                SpriteDesc = new Section()
                {
                    Count = Sprites.Count
                },
                SpritePartDesc = new Section()
                {
                    Count = SpriteGroups.Sum(x => x.Count)
                },
                SpriteGroupDesc = new Section()
                {
                    Count = SpriteGroups.Count
                },
                AnimationDesc = new Section()
                {
                    Count = AnimationGroups.Sum(x => x.Animations.Count)
                },
                AnimationGroupDesc = new Section()
                {
                    Count = AnimationGroups.Count
                },
            };

            var index        = 0;
            var basePosition = stream.Position;

            stream.Position          = basePosition + MinimumLength;
            header.SpriteDesc.Offset = (int)(stream.Position - basePosition);

            header.SpritePartDesc.Offset = stream.WriteList(Sprites.Select(x => new RawSprite
            {
                U0          = x.Left,
                V0          = x.Top,
                U1          = x.Right,
                V1          = x.Bottom,
                UScroll     = x.UTranslation,
                VScroll     = x.VTranslation,
                ColorLeft   = x.ColorLeft,
                ColorTop    = x.ColorTop,
                ColorRight  = x.ColorRight,
                ColorBottom = x.ColorBottom,
            })) + header.SpriteDesc.Offset;
            header.SpriteGroupDesc.Offset = stream.WriteList(SpriteGroups.SelectMany(x => x)) + header.SpritePartDesc.Offset;

            index = 0;
            foreach (var spriteGroup in SpriteGroups)
            {
                BinaryMapping.WriteObject(stream, new RawSpriteGroup
                {
                    Start = (short)index,
                    Count = (short)spriteGroup.Count
                });

                index += spriteGroup.Count;
            }
            header.AnimationDesc.Offset      = SpriteGroups.Count * 4 + header.SpriteGroupDesc.Offset;
            header.AnimationGroupDesc.Offset = stream.WriteList(AnimationGroups.SelectMany(x => x.Animations)) + header.AnimationDesc.Offset;
            index = 0;
            foreach (var animGroup in AnimationGroups)
            {
                BinaryMapping.WriteObject(stream, new RawAnimationGroup
                {
                    AnimationIndex = (short)index,
                    Count          = (short)animGroup.Animations.Count,
                    Loop           = animGroup.DoNotLoop,
                    Flags          = animGroup.Unknown06,
                    FrameStart     = animGroup.LoopStart,
                    FrameEnd       = animGroup.LoopEnd,
                    X         = animGroup.LightPositionX,
                    Y         = animGroup.TextPositionY,
                    Size      = animGroup.TextScale,
                    Unknown1C = animGroup.UiPadding,
                    Unknown20 = animGroup.TextPositionX,
                });

                index += animGroup.Animations.Count;
            }

            var endPosition = stream.Position;

            stream.Position = basePosition;
            BinaryMapping.WriteObject(stream, header);
            stream.Position = endPosition;
        }
Ejemplo n.º 21
0
        public static void Write(Stream stream, Pmo pmo)
        {
            stream.Position = 0;
            bool hasSwappedToSecondModel = false;

            BinaryMapping.WriteObject <Pmo.Header>(stream, pmo.header);

            for (int i = 0; i < pmo.header.TextureCount; i++)
            {
                BinaryMapping.WriteObject <Pmo.TextureInfo>(stream, pmo.textureInfo[i]);
            }

            // Write Mesh Data.
            for (int j = 0; j < pmo.Meshes.Count; j++)
            {
                if (!hasSwappedToSecondModel && pmo.Meshes[j].MeshNumber == 1)
                {
                    hasSwappedToSecondModel = true;

                    for (uint b = 0; b < 0xC; b++)
                    {
                        stream.Write((byte)0x00);
                    }

                    for (uint b = 0; stream.Position % 0x10 != 0; b++)
                    {
                        stream.Write((byte)0x00);
                    }
                }

                MeshChunks chunk = pmo.Meshes[j];

                BinaryMapping.WriteObject <Pmo.MeshSection>(stream, chunk.SectionInfo);
                if (chunk.SectionInfo_opt1 != null)
                {
                    BinaryMapping.WriteObject <Pmo.MeshSectionOptional1>(stream, chunk.SectionInfo_opt1);
                }
                if (chunk.SectionInfo_opt2 != null)
                {
                    BinaryMapping.WriteObject <Pmo.MeshSectionOptional2>(stream, chunk.SectionInfo_opt2);
                }

                if (chunk.TriangleStripValues.Length > 0)
                {
                    for (int z = 0; z < chunk.TriangleStripValues.Length; z++)
                    {
                        stream.Write((ushort)chunk.TriangleStripValues[z]);
                    }
                }

                for (int k = 0; k < pmo.Meshes[j].SectionInfo.VertexCount; k++)
                {
                    long vertexStartPos       = stream.Position;
                    int  vertexIncreaseAmount = 0;

                    VertexFlags flags = Pmo.GetFlags(chunk.SectionInfo);

                    // Write Joints.
                    if (flags.WeightFormat != CoordinateFormat.NO_VERTEX)
                    {
                        for (int w = 0; w < flags.SkinningWeightsCount + 1; w++)
                        {
                            int currentIndex = w + (k * (flags.SkinningWeightsCount + 1));

                            switch (flags.WeightFormat)
                            {
                            case CoordinateFormat.NORMALIZED_8_BITS:
                                stream.Write((byte)(chunk.jointWeights[currentIndex] * 127.0f));
                                break;

                            case CoordinateFormat.NORMALIZED_16_BITS:
                                stream.Write((byte)(chunk.jointWeights[currentIndex] * 32767.0f));
                                break;

                            case CoordinateFormat.FLOAT_32_BITS:
                                StreamExtensions.Write(stream, chunk.jointWeights[currentIndex]);
                                break;
                            }
                        }
                    }

                    // Write Texture Coords.
                    switch (flags.TextureCoordinateFormat)
                    {
                    case CoordinateFormat.NORMALIZED_8_BITS:
                        stream.Write((byte)(chunk.textureCoordinates[k].X * 127.0f));
                        stream.Write((byte)(chunk.textureCoordinates[k].Y * 127.0f));
                        break;

                    case CoordinateFormat.NORMALIZED_16_BITS:
                        vertexIncreaseAmount = ((0x2 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x1)) & 0x1);
                        for (int a = 0; a < vertexIncreaseAmount; a++)
                        {
                            stream.Write((byte)0xAB);
                        }

                        stream.Write((ushort)(chunk.textureCoordinates[k].X * 32767.0f));
                        stream.Write((ushort)(chunk.textureCoordinates[k].Y * 32767.0f));
                        break;

                    case CoordinateFormat.FLOAT_32_BITS:
                        vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3);
                        for (int a = 0; a < vertexIncreaseAmount; a++)
                        {
                            stream.Write((byte)0xAB);
                        }

                        StreamExtensions.Write(stream, chunk.textureCoordinates[k].X);
                        StreamExtensions.Write(stream, chunk.textureCoordinates[k].Y);
                        break;
                    }

                    // Write colors.
                    switch (flags.ColorFormat)
                    {
                    case Pmo.ColorFormat.NO_COLOR:
                        break;

                    case Pmo.ColorFormat.BGR_5650_16BITS:
                        break;

                    case Pmo.ColorFormat.ABGR_5551_16BITS:
                        break;

                    case Pmo.ColorFormat.ABGR_4444_16BITS:
                        break;

                    case Pmo.ColorFormat.ABGR_8888_32BITS:
                        vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3);
                        for (int a = 0; a < vertexIncreaseAmount; a++)
                        {
                            stream.Write((byte)0xAB);
                        }

                        stream.Write((byte)(chunk.colors[k].X));
                        stream.Write((byte)(chunk.colors[k].Y));
                        stream.Write((byte)(chunk.colors[k].Z));
                        stream.Write((byte)(chunk.colors[k].W));
                        break;
                    }

                    // Write vertices.
                    switch (flags.PositionFormat)
                    {
                    case CoordinateFormat.NORMALIZED_8_BITS:
                        StreamExtensions.Write(stream, (sbyte)(chunk.vertices[k].X * 127.0f));
                        StreamExtensions.Write(stream, (sbyte)(chunk.vertices[k].Y * 127.0f));
                        StreamExtensions.Write(stream, (sbyte)(chunk.vertices[k].Z * 127.0f));
                        break;

                    case CoordinateFormat.NORMALIZED_16_BITS:
                        vertexIncreaseAmount = ((0x2 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x1)) & 0x1);
                        for (int a = 0; a < vertexIncreaseAmount; a++)
                        {
                            stream.Write((byte)0xAB);
                        }

                        StreamExtensions.Write(stream, (short)(chunk.vertices[k].X * 32767.0f));
                        StreamExtensions.Write(stream, (short)(chunk.vertices[k].Y * 32767.0f));
                        StreamExtensions.Write(stream, (short)(chunk.vertices[k].Z * 32767.0f));
                        break;

                    case CoordinateFormat.FLOAT_32_BITS:
                        vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3);
                        for (int a = 0; a < vertexIncreaseAmount; a++)
                        {
                            stream.Write((byte)0xAB);
                        }

                        StreamExtensions.Write(stream, chunk.vertices[k].X);
                        StreamExtensions.Write(stream, chunk.vertices[k].Y);
                        StreamExtensions.Write(stream, chunk.vertices[k].Z);
                        break;
                    }

                    int padding = ((int)vertexStartPos + chunk.SectionInfo.VertexSize) - (int)stream.Position;
                    for (int p = 0; p < padding; p++)
                    {
                        stream.Write((byte)0xAB);
                    }
                }

                // Remainder.
                uint remainder = (uint)stream.Position % 4;
                for (int p = 0; p < remainder; p++)
                {
                    stream.Write((byte)0x00);
                }

                if (j == (pmo.Meshes.Count - 1))
                {
                    for (uint b = 0; b < 0xC; b++)
                    {
                        stream.Write((byte)0x00);
                    }

                    for (uint b = 0; stream.Position % 0x10 != 0; b++)
                    {
                        stream.Write((byte)0x00);
                    }
                }
            }

            // Write textures.
            for (int t = 0; t < pmo.texturesData.Count; t++)
            {
                stream.Write(pmo.texturesData[t]);
            }

            if (pmo.header.SkeletonOffset != 0)
            {
                BinaryMapping.WriteObject <SkeletonHeader>(stream, pmo.skeletonHeader);

                for (int joint = 0; joint < pmo.jointList.Length; joint++)
                {
                    BinaryMapping.WriteObject <JointData>(stream, pmo.jointList[joint]);
                }
            }
        }
Ejemplo n.º 22
0
        private Coct(Stream stream)
            : this()
        {
            if (!IsValid(stream))
            {
                throw new InvalidDataException("Invalid header");
            }

            var header = BinaryMapping.ReadObject <Header>(stream.SetPosition(0));

            Depth = header.Depth;
            Type  = header.Type;

            var rawNodeList          = ReactCoctEntry <RawNode>(stream, header.Entries[1], NodeSize);
            var rawCollisionMeshList = ReactCoctEntry <RawCollisionMesh>(stream, header.Entries[2], MeshSize);
            var rawCollisionList     = ReactCoctEntry <RawCollision>(stream, header.Entries[3], PolygonSize);

            VertexList = ReadValueEntry <Vector4>(stream, header.Entries[4], Col4Size, ReadVector4);
            var planeList      = ReadValueEntry <Plane>(stream, header.Entries[5], Col5Size, ReadPlane);
            var boundingBoxes  = ReadValueEntry(stream, header.Entries[6], BoundingBoxSize, ReadBoundingBoxInt16);
            var attributesList = ReactCoctEntry <Attributes>(stream, header.Entries[7], AttributesSize);

            var collisionList = rawCollisionList
                                .Select(x => new Collision
            {
                Ground      = x.Ground,
                FloorLevel  = x.FloorLevel,
                Vertex1     = x.Vertex1,
                Vertex2     = x.Vertex2,
                Vertex3     = x.Vertex3,
                Vertex4     = x.Vertex4,
                Plane       = planeList[x.PlaneIndex],
                BoundingBox = x.BoundingBoxIndex >= 0 ? boundingBoxes[x.BoundingBoxIndex] : BoundingBoxInt16.Invalid,
                Attributes  = attributesList[x.AttributeIndex],
            })
                                .ToList();

            var collisionMeshList = rawCollisionMeshList
                                    .Select(x => new CollisionMesh
            {
                BoundingBox = x.BoundingBox,
                Collisions  = Enumerable.Range(x.CollisionStart, x.CollisionEnd - x.CollisionStart)
                              .Select(i => collisionList[i])
                              .ToList(),
                Visibility = x.Visibility,
                Group      = x.Group
            })
                                    .ToList();

            Nodes = rawNodeList
                    .Select(x => new CollisionNode
            {
                Child1      = x.Child1,
                Child2      = x.Child2,
                Child3      = x.Child3,
                Child4      = x.Child4,
                Child5      = x.Child5,
                Child6      = x.Child6,
                Child7      = x.Child7,
                Child8      = x.Child8,
                BoundingBox = x.BoundingBox,
                Meshes      = Enumerable.Range(x.CollisionMeshStart, x.CollisionMeshEnd - x.CollisionMeshStart)
                              .Select(i => collisionMeshList[i])
                              .ToList(),
            })
                    .ToList();
        }
Ejemplo n.º 23
0
        public void Write(Stream stream)
        {
            if (ShouldEmitDMYAtFirst)
            {
                // Some map files has style "_DMY" "_KN5". This is for that consistency.
                stream.Write(_DMY);
                stream.Write(0);
            }

            foreach (var item in TextureAnimationList)
            {
                var texaStream = new MemoryStream();

                {
                    item.NumAnimations = Convert.ToUInt16(item.FrameGroupList.Length);
                    var animationTable = new int[item.NumAnimations];

                    for (var pass = 1; pass <= 2; pass++)
                    {
                        texaStream.Position = 0;
                        BinaryMapping.WriteObject(texaStream, item);

                        item.OffsetSlotTable = Convert.ToInt32(texaStream.Position);
                        item.SlotTable.ToList().ForEach(texaStream.Write);

                        texaStream.AlignPosition(4);

                        item.OffsetAnimationTable = Convert.ToInt32(texaStream.Position);
                        texaStream.Write(animationTable);

                        foreach (var(group, groupIndex) in item.FrameGroupList.Select((group, groupIndex) => (group, groupIndex)))
                        {
                            animationTable[groupIndex] = Convert.ToInt32(texaStream.Position);

                            if (group.IndexedFrameList.Any())
                            {
                                int minIdx = group.IndexedFrameList.Keys.Min();
                                int maxIdx = group.IndexedFrameList.Keys.Max();

                                for (; minIdx <= maxIdx; minIdx++)
                                {
                                    group.IndexedFrameList.TryGetValue(minIdx, out TextureFrame frame);
                                    frame = frame ?? new TextureFrame();

                                    BinaryMapping.WriteObject(texaStream, frame);
                                }
                            }
                        }

                        texaStream.AlignPosition(16);
                        item.OffsetSpriteImage = Convert.ToInt32(texaStream.Position);

                        texaStream.Write(item.SpriteImage);
                        texaStream.AlignPosition(16);
                    }
                }

                stream.Write(_DMY);
                stream.Write(0);

                stream.Write(TEXA);
                stream.Write(Convert.ToUInt32(texaStream.Length));

                texaStream.Position = 0;
                texaStream.CopyTo(stream);
            }

            if (UvscList.Any())
            {
                // Before first "UVSC", "_DMY" has to be placed. This is for that consistency.

                stream.Write(_DMY);
                stream.Write(0);

                foreach (var item in UvscList)
                {
                    stream.Write(UVSC);
                    stream.Write(12);
                    BinaryMapping.WriteObject(stream, item);
                }
            }
            else if (TextureAnimationList.Any())
            {
                // Between "TEXA" and "_KN5", "_DMY" has to be placed. This is for that consistency.

                stream.Write(_DMY);
                stream.Write(0);
            }

            if (ShouldEmitKN5)
            {
                stream.Write(_KN5);
            }

            if (UnkFooter != null)
            {
                stream.Write(UnkFooter);
            }
        }
Ejemplo n.º 24
0
        public void Write(Stream stream)
        {
            var collisionList          = new List <Collision>();
            var collisionMeshList      = new List <RawCollisionMesh>();
            var collisionMeshGroupList = new List <RawNode>();

            foreach (var node in Nodes)
            {
                var start = node.Meshes.Count > 0 ? collisionMeshList.Count : 0;
                collisionMeshGroupList.Add(new RawNode
                {
                    Child1             = node.Child1,
                    Child2             = node.Child2,
                    Child3             = node.Child3,
                    Child4             = node.Child4,
                    Child5             = node.Child5,
                    Child6             = node.Child6,
                    Child7             = node.Child7,
                    Child8             = node.Child8,
                    BoundingBox        = node.BoundingBox,
                    CollisionMeshStart = (ushort)start,
                    CollisionMeshEnd   = (ushort)(start + node.Meshes.Count)
                });

                foreach (var mesh in node.Meshes)
                {
                    collisionMeshList.Add(new RawCollisionMesh
                    {
                        BoundingBox    = mesh.BoundingBox,
                        CollisionStart = (ushort)collisionList.Count,
                        CollisionEnd   = (ushort)(collisionList.Count + mesh.Collisions.Count),
                        Visibility     = mesh.Visibility,
                        Group          = mesh.Group
                    });

                    collisionList.AddRange(mesh.Collisions);
                }
            }

            var bbCache = new WriteCache <BoundingBoxInt16, string>(x => x.ToString());

            bbCache.AddConstant(BoundingBoxInt16.Invalid, -1);
            foreach (var item in collisionList)
            {
                bbCache.Add(item.BoundingBox);
            }

            var surfaceCache = new WriteCache <Attributes, int>(x => x.Flags);

            foreach (var item in collisionList)
            {
                surfaceCache.Add(item.Attributes);
            }

            var planeCache = new WriteCache <Plane, string>(x => x.ToString());

            foreach (var item in collisionList)
            {
                planeCache.Add(item.Plane);
            }

            var entries = new List <Entry>(8);

            AddEntry(entries, HeaderSize, 1);
            AddEntry(entries, Nodes.Count * NodeSize, 0x10);
            AddEntry(entries, collisionMeshList.Count * MeshSize, 0x10);
            AddEntry(entries, collisionList.Count * PolygonSize, 4);
            AddEntry(entries, VertexList.Count * Col4Size, 0x10);
            AddEntry(entries, planeCache.Count * Col5Size, 0x10);
            AddEntry(entries, bbCache.Count * BoundingBoxSize, 0x10);
            AddEntry(entries, surfaceCache.Count * AttributesSize, 4);

            stream.Position = 0;
            BinaryMapping.WriteObject(stream, new Header
            {
                MagicCode = MagicCode,
                Version   = 1,
                Depth     = Depth,
                Type      = Type,
                Entries   = entries.ToArray()
            });

            WriteCoctEntry(stream, collisionMeshGroupList);
            WriteCoctEntry(stream, collisionMeshList);
            WriteCoctEntry(stream, collisionList
                           .Select(x => new RawCollision
            {
                Ground           = x.Ground,
                FloorLevel       = x.FloorLevel,
                Vertex1          = x.Vertex1,
                Vertex2          = x.Vertex2,
                Vertex3          = x.Vertex3,
                Vertex4          = x.Vertex4,
                PlaneIndex       = planeCache[x.Plane],
                BoundingBoxIndex = bbCache[x.BoundingBox],
                AttributeIndex   = surfaceCache[x.Attributes],
            }));
            stream.AlignPosition(0x10);
            WriteValueEntry(stream, VertexList, WriteVector4);
            WriteValueEntry(stream, planeCache, WritePlane);
            WriteValueEntry(stream, bbCache, WriteBoundingBoxInt16);
            WriteCoctEntry(stream, surfaceCache);
        }
Ejemplo n.º 25
0
 public void Write(Stream stream) =>
 BinaryMapping.WriteObject(new BinaryWriter(stream), this);
Ejemplo n.º 26
0
 private static TSaveData Read <TSaveData>(Stream stream)
     where TSaveData : class, ISaveData =>
 BinaryMapping.ReadObject <TSaveData>(stream.FromBegin());
Ejemplo n.º 27
0
 private static TSaveKh2 Read <TSaveKh2>(Stream stream)
     where TSaveKh2 : class, ISaveKh2 =>
 BinaryMapping.ReadObject <TSaveKh2>(stream.FromBegin());
Ejemplo n.º 28
0
        private static DmaChainHeader WriteDmaChain(Stream stream, DmaChain dmaChain)
        {
            var dmaChainHeader = new DmaChainHeader
            {
                Unk00        = dmaChain.Unk00,
                TextureIndex = dmaChain.TextureIndex,
                Unk08        = dmaChain.Unk08,
                DmaLength    = dmaChain.DmaLength,
            };

            var dmaVifs = dmaChain.DmaVifs;

            var vifPacketOffsets = new List <int>();

            foreach (var dmaVif in dmaVifs)
            {
                vifPacketOffsets.Add((int)stream.Position);
                stream.Write(dmaVif.VifPacket);
            }

            dmaChainHeader.DmaOffset = (int)stream.Position;

            for (var i = 0; i < dmaVifs.Count; i++)
            {
                if (dmaVifs[i].BaseAddress > 0)
                {
                    BinaryMapping.WriteObject(stream, new DmaPacket
                    {
                        DmaTag = new DmaTag
                        {
                            Qwc     = (ushort)(dmaVifs[i].VifPacket.Length / 0x10),
                            TagId   = 3,
                            Irq     = false,
                            Address = vifPacketOffsets[i]
                        },
                        VifCode   = new VifCode {
                        },
                        Parameter = 0
                    });

                    for (var j = 0; j < dmaVifs[i].Alaxi.Length; j++)
                    {
                        BinaryMapping.WriteObject(stream, new DmaPacket
                        {
                            DmaTag = new DmaTag
                            {
                                Qwc     = 4,
                                TagId   = 3,
                                Irq     = false,
                                Address = dmaVifs[i].Alaxi[j]
                            },
                            VifCode   = DefaultVifCode,
                            Parameter = dmaVifs[i].BaseAddress + j * 4
                        });
                    }
                }

                BinaryMapping.WriteObject(stream, CloseDmaPacket);
            }

            var alv1 = new List <int>();

            foreach (var vif in dmaVifs)
            {
                alv1.AddRange(vif.Alaxi);
                alv1.Add(-1);
            }
            alv1.RemoveAt(alv1.Count - 1);

            dmaChainHeader.Count1aOffset = (int)stream.Position;
            stream.Write(alv1.Count);
            foreach (var alvItem in alv1)
            {
                stream.Write(alvItem);
            }

            stream.AlignPosition(0x10);

            return(dmaChainHeader);
        }
Ejemplo n.º 29
0
        private static void Write(Stream stream, InterpolatedMotion motion, bool unkFlag)
        {
            var valuePool    = new PoolValues <float>();
            var keyFramePool = new PoolValues <float>(motion.Timeline.Select(x => x.KeyFrame).Distinct().OrderBy(x => x));
            var tangentPool  = new PoolValues <float>();
            var rawTimeline  = new List <TimelineTableInternal>(motion.Timeline.Count);

            foreach (var item in motion.Timeline)
            {
                rawTimeline.Add(new TimelineTableInternal
                {
                    Time                = (short)(((int)item.Interpolation & 3) | (keyFramePool.GetIndex(item.KeyFrame) << 2)),
                    ValueIndex          = (short)valuePool.GetIndex(item.Value),
                    TangentIndexEaseIn  = (short)tangentPool.GetIndex(item.TangentEaseIn),
                    TangentIndexEaseOut = (short)tangentPool.GetIndex(item.TangentEaseOut),
                });
            }

            var writer = new BinaryWriter(stream);
            var header = new InterpolatedMotionInternal
            {
                BoneCount       = motion.BoneCount,
                TotalFrameCount = motion.TotalFrameCount,
                Unk48           = motion.Unk48,
                BoundingBoxMinX = motion.BoundingBoxMinX,
                BoundingBoxMinY = motion.BoundingBoxMinY,
                BoundingBoxMinZ = motion.BoundingBoxMinZ,
                BoundingBoxMinW = motion.BoundingBoxMinW,
                BoundingBoxMaxX = motion.BoundingBoxMaxX,
                BoundingBoxMaxY = motion.BoundingBoxMaxY,
                BoundingBoxMaxZ = motion.BoundingBoxMaxZ,
                BoundingBoxMaxW = motion.BoundingBoxMaxW,
                FrameLoop       = motion.FrameLoop,
                FrameEnd        = motion.FrameEnd,
                FramePerSecond  = motion.FramePerSecond,
                FrameCount      = motion.FrameCount,
                Unk98           = motion.Unk98,
                Unk9c           = motion.Unk9c,
            };

            stream.Write(new byte[ReservedSize], 0, ReservedSize);
            BinaryMapping.WriteObject(stream, new Header {
            });
            BinaryMapping.WriteObject(stream, new InterpolatedMotionInternal {
            });

            header.StaticPoseCount  = motion.StaticPose.Count;
            header.StaticPoseOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in motion.StaticPose)
            {
                BinaryMapping.WriteObject(stream, item);
            }

            header.ModelBoneAnimationCount  = motion.ModelBoneAnimation.Count;
            header.ModelBoneAnimationOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in motion.ModelBoneAnimation.Select(Map))
            {
                BinaryMapping.WriteObject(stream, item);
            }

            header.IKHelperAnimationCount  = motion.IKHelperAnimation.Count;
            header.IKHelperAnimationOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in motion.IKHelperAnimation.Select(Map))
            {
                BinaryMapping.WriteObject(stream, item);
            }

            header.TimelineOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in rawTimeline)
            {
                BinaryMapping.WriteObject(stream, item);
            }

            stream.AlignPosition(4);
            header.KeyFrameCount  = keyFramePool.Values.Count;
            header.KeyFrameOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in keyFramePool.Values)
            {
                writer.Write(item);
            }

            header.TransformationValueOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in valuePool.Values)
            {
                writer.Write(item);
            }

            header.TangentOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in tangentPool.Values)
            {
                writer.Write(item);
            }

            header.IKChainCount  = motion.IKChains.Count;
            header.IKChainOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in motion.IKChains)
            {
                BinaryMapping.WriteObject(stream, item);
            }

            header.Unk48 = (int)(stream.Position - ReservedSize);

            stream.AlignPosition(0x10);
            header.Table8Offset = (int)(stream.Position - ReservedSize);
            foreach (var item in motion.Table8)
            {
                BinaryMapping.WriteObject(stream, item);
            }

            stream.AlignPosition(0x10);
            header.Table7Count  = motion.Table7.Count;
            header.Table7Offset = (int)(stream.Position - ReservedSize);
            foreach (var item in motion.Table7)
            {
                BinaryMapping.WriteObject(stream, item);
            }

            header.Table6Count  = motion.Table6.Count;
            header.Table6Offset = (int)(stream.Position - ReservedSize);
            foreach (var item in motion.Table6)
            {
                BinaryMapping.WriteObject(stream, item);
            }

            stream.AlignPosition(0x10);
            header.TotalBoneCount = (short)(motion.BoneCount + motion.IKHelpers.Count);
            header.IKHelperOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in motion.IKHelpers)
            {
                BinaryMapping.WriteObject(stream, item);
            }

            header.JointIndexOffset = (int)(stream.Position - ReservedSize);
            foreach (var item in motion.Joints)
            {
                BinaryMapping.WriteObject(stream, item);
            }

            stream.AlignPosition(0x10);
            header.FooterOffset = (int)(stream.Position - ReservedSize);
            BinaryMapping.WriteObject(stream, motion.Footer);

            header.UnknownTable1Offset = (int)(stream.Position - ReservedSize);
            header.UnknownTable1Count  = 0;

            stream.AlignPosition(0x10);
            stream.SetLength(stream.Position);

            stream.SetPosition(ReservedSize);
            BinaryMapping.WriteObject(stream, new Header
            {
                Version   = 0,
                Unk04     = unkFlag ? 1 : 0,
                ByteCount = (int)(stream.Length - ReservedSize),
                Unk0c     = 0,
            });
            BinaryMapping.WriteObject(stream, header);
        }
Ejemplo n.º 30
0
 public static VpuHeader Header(Stream stream) =>
 BinaryMapping.ReadObject <VpuHeader>(stream);