Пример #1
0
            internal void WriteAnimFile(BinaryWriterEx bw, int i, TAEFormat format)
            {
                bw.FillVarint($"AnimFileOffset{i}", bw.Position);
                bw.WriteVarint((int)MiniHeader.Type);
                bw.WriteVarint(bw.Position + (bw.VarintLong ? 8 : 4));
                bw.ReserveVarint("AnimFileNameOffset");

                //if (AnimFileReference)
                //{
                //    bw.WriteInt32(ReferenceID);

                //    bw.WriteBoolean(UnkReferenceFlag1);
                //    bw.WriteBoolean(ReferenceIsTAEOnly);
                //    bw.WriteBoolean(ReferenceIsHKXOnly);
                //    bw.WriteBoolean(LoopByDefault);
                //}
                //else
                //{
                //    bw.WriteBoolean(UnkReferenceFlag1);
                //    bw.WriteBoolean(ReferenceIsTAEOnly);
                //    bw.WriteBoolean(ReferenceIsHKXOnly);
                //    bw.WriteBoolean(LoopByDefault);

                //    bw.WriteInt32(ReferenceID);
                //}

                MiniHeader.WriteInner(bw);

                if (format != TAEFormat.DS1)
                {
                    bw.WriteVarint(0);
                    bw.WriteVarint(0);
                }
                else
                {
                    bw.WriteVarint(0);

                    if (MiniHeader.Type == MiniHeaderType.ImportOtherAnim)
                    {
                        bw.WriteVarint(0);
                    }
                }

                bw.FillVarint("AnimFileNameOffset", bw.Position);
                if (AnimFileName != "")
                {
                    bw.WriteUTF16(AnimFileName, true);

                    if (format != TAEFormat.DS1)
                    {
                        bw.Pad(0x10);
                    }
                }
            }
Пример #2
0
            internal Animation(BinaryReaderEx br, TAEFormat format,
                               out bool lastEventNeedsParamGen, out long animFileOffset,
                               out long lastEventParamOffset)
            {
                lastEventNeedsParamGen = false;
                lastEventParamOffset   = 0;
                ID = br.ReadVarint();
                long offset = br.ReadVarint();

                br.StepIn(offset);
                {
                    int  eventCount;
                    long eventHeadersOffset;
                    int  eventGroupCount;
                    long eventGroupsOffset;
                    long timesOffset;

                    if (format == TAEFormat.DS1)
                    {
                        eventCount         = br.ReadInt32();
                        eventHeadersOffset = br.ReadVarint();
                        eventGroupCount    = br.ReadInt32();
                        eventGroupsOffset  = br.ReadVarint();
                        br.ReadInt32();                   // Times count
                        timesOffset    = br.ReadVarint(); // Times offset
                        animFileOffset = br.ReadVarint();

                        //For DeS assert 5 int32 == 0 here
                    }
                    else
                    {
                        eventHeadersOffset = br.ReadVarint();
                        eventGroupsOffset  = br.ReadVarint();
                        timesOffset        = br.ReadVarint(); // Times offset
                        animFileOffset     = br.ReadVarint();
                        eventCount         = br.ReadInt32();
                        eventGroupCount    = br.ReadInt32();
                        br.ReadInt32(); // Times count
                        br.AssertInt32(0);
                    }

                    var eventHeaderOffsets    = new List <long>(eventCount);
                    var eventParameterOffsets = new List <long>(eventCount);
                    Events = new List <Event>(eventCount);
                    br.StepIn(eventHeadersOffset);
                    {
                        for (int i = 0; i < eventCount; i++)
                        {
                            eventHeaderOffsets.Add(br.Position);
                            Events.Add(Event.Read(br, out long pOffset, format));
                            eventParameterOffsets.Add(pOffset);

                            if (i > 0)
                            {
                                //  Go to previous event's parameters
                                br.StepIn(eventParameterOffsets[i - 1]);
                                {
                                    // Read the space between the previous event's parameter start and the start of this event data.
                                    long gapBetweenEventParamOffsets = eventParameterOffsets[i] - eventParameterOffsets[i - 1];
                                    // Subtract to account for the current event's type and offset
                                    Events[i - 1].ReadParameters(br, (int)(gapBetweenEventParamOffsets - (br.VarintLong ? 16 : 8)));
                                }
                                br.StepOut();
                            }
                        }
                    }
                    br.StepOut();

                    if (eventCount > 0)
                    {
                        if (eventGroupsOffset == 0)
                        {
                            lastEventNeedsParamGen = true;
                            lastEventParamOffset   = eventParameterOffsets[eventCount - 1];
                        }
                        else
                        {
                            // Go to last event's parameters
                            br.StepIn(eventParameterOffsets[eventCount - 1]);
                            {
                                // Read the space between the last event's parameter start and the start of the event groups.
                                Events[eventCount - 1].ReadParameters(br, (int)(eventGroupsOffset - eventParameterOffsets[eventCount - 1]));
                            }
                            br.StepOut();
                        }
                    }

                    EventGroups = new List <EventGroup>(eventGroupCount);
                    br.StepIn(eventGroupsOffset);
                    {
                        for (int i = 0; i < eventGroupCount; i++)
                        {
                            EventGroups.Add(new EventGroup(br, eventHeaderOffsets, format));
                        }
                    }
                    br.StepOut();

                    br.StepIn(animFileOffset);
                    {
                        var miniHeaderType = br.ReadEnum32 <MiniHeaderType>();

                        if (br.VarintLong)
                        {
                            br.AssertInt32(0);
                        }

                        br.AssertVarint(br.Position + (br.VarintLong ? 8 : 4));
                        long animFileNameOffset = br.ReadVarint();

                        //if (AnimFileReference)
                        //{
                        //    ReferenceID = br.ReadInt32();

                        //    UnkReferenceFlag1 = br.ReadBoolean();
                        //    ReferenceIsTAEOnly = br.ReadBoolean();
                        //    ReferenceIsHKXOnly = br.ReadBoolean();
                        //    LoopByDefault = br.ReadBoolean();
                        //}
                        //else
                        //{
                        //    UnkReferenceFlag1 = br.ReadBoolean();
                        //    ReferenceIsTAEOnly = br.ReadBoolean();
                        //    ReferenceIsHKXOnly = br.ReadBoolean();
                        //    LoopByDefault = br.ReadBoolean();

                        //    ReferenceID = br.ReadInt32();
                        //}

                        if (miniHeaderType == MiniHeaderType.Standard)
                        {
                            MiniHeader = new AnimMiniHeader.Standard();
                        }
                        else if (miniHeaderType == MiniHeaderType.ImportOtherAnim)
                        {
                            MiniHeader = new AnimMiniHeader.ImportOtherAnim();
                        }
                        else
                        {
                            throw new NotImplementedException($"{nameof(AnimMiniHeader)} type not implemented yet.");
                        }

                        MiniHeader.ReadInner(br);

                        if (format != TAEFormat.DS1)
                        {
                            br.AssertVarint(0);
                            br.AssertVarint(0);
                        }
                        else
                        {
                            br.AssertVarint(0);

                            if (MiniHeader.Type == MiniHeaderType.ImportOtherAnim)
                            {
                                br.AssertVarint(0);
                            }
                        }

                        if (animFileNameOffset < br.Length && animFileNameOffset != timesOffset)
                        {
                            if (br.GetInt64(animFileNameOffset) != 1)
                            {
                                var floatCheck = br.GetSingle(animFileNameOffset);
                                if (!(floatCheck >= 0.016667f && floatCheck <= 100))
                                {
                                    AnimFileName = br.GetUTF16(animFileNameOffset);
                                }
                            }
                        }

                        AnimFileName = AnimFileName ?? "";

                        // When Reference is false, there's always a filename.
                        // When true, there's usually not, but sometimes there is, and I cannot figure out why.
                        // Thus, this stupid hack to achieve byte-perfection.
                        //var animNameCheck = AnimFileName.ToLower();
                        //if (!(animNameCheck.EndsWith(".hkt")
                        //    || (format == TAEFormat.SDT && animNameCheck.EndsWith("hkt"))
                        //    || animNameCheck.EndsWith(".hkx")
                        //    || animNameCheck.EndsWith(".sib")
                        //    || animNameCheck.EndsWith(".hkxwin")))
                        //    AnimFileName = "";
                    }
                    br.StepOut();
                }
                br.StepOut();
            }