コード例 #1
0
            internal void WriteData(BinaryWriterEx bw, int animIndex, int eventIndex, TAEFormat format)
            {
                CopyParametersToBytes(bw.BigEndian);

                bw.FillVarint($"EventDataOffset{animIndex}:{eventIndex}", bw.Position);
                bw.WriteInt32(Type);

                if (format != TAEFormat.DS1)
                {
                    bw.WriteInt32(Unk04);
                }

                if (format == TAEFormat.SDT && Type == 943)
                {
                    bw.WriteVarint(0);
                }
                else
                {
                    bw.WriteVarint(bw.Position + (bw.VarintLong ? 8 : 4));
                }

                bw.WriteBytes(ParameterBytes);

                if (format != TAEFormat.DS1)
                {
                    bw.Pad(0x10);
                }
            }
コード例 #2
0
            internal Dictionary <float, long> WriteTimes(BinaryWriterEx bw, int animIndex, TAEFormat format)
            {
                var times = new SortedSet <float>();

                foreach (Event evt in Events)
                {
                    times.Add(evt.StartTime);
                    times.Add(evt.EndTime);
                }

                bw.FillInt32($"TimesCount{animIndex}", times.Count);

                if (times.Count == 0)
                {
                    bw.FillVarint($"TimesOffset{animIndex}", 0);
                }
                else
                {
                    bw.FillVarint($"TimesOffset{animIndex}", bw.Position);
                }

                var timeOffsets = new Dictionary <float, long>();

                foreach (float time in times)
                {
                    timeOffsets[time] = bw.Position;
                    bw.WriteSingle(time);
                }

                if (format != TAEFormat.DS1)
                {
                    bw.Pad(0x10);
                }

                return(timeOffsets);
            }
コード例 #3
0
 internal void WriteEventGroupData(BinaryWriterEx bw, int i, List <long> eventHeaderOffsets, TAEFormat format)
 {
     for (int j = 0; j < EventGroups.Count; j++)
     {
         EventGroups[j].WriteData(bw, i, j, eventHeaderOffsets, format);
     }
 }
コード例 #4
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();
            }
コード例 #5
0
            internal List <long> WriteEventHeaders(BinaryWriterEx bw, int animIndex, Dictionary <float, long> timeOffsets, TAEFormat format)
            {
                var eventHeaderOffsets = new List <long>(Events.Count);

                if (Events.Count > 0)
                {
                    bw.FillVarint($"EventHeadersOffset{animIndex}", bw.Position);
                    for (int i = 0; i < Events.Count; i++)
                    {
                        eventHeaderOffsets.Add(bw.Position);
                        Events[i].WriteHeader(bw, animIndex, i, timeOffsets, format);
                    }
                }
                else
                {
                    bw.FillVarint($"EventHeadersOffset{animIndex}", 0);
                }
                return(eventHeaderOffsets);
            }
コード例 #6
0
            internal void WriteAnimFile(BinaryWriterEx bw, int i, TAEFormat format)
            {
                bw.FillVarint($"AnimFileOffset{i}", bw.Position);
                bw.WriteVarint((int)MiniHeader.Type);


                bw.ReserveVarint("AnimFileNameOffsetOffset");
                if (format == TAEFormat.DES)
                {
                    bw.Pad(0x10);
                }
                bw.FillVarint("AnimFileNameOffsetOffset", bw.Position);

                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, format);

                if (!(format == TAEFormat.DES || 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 (!string.IsNullOrWhiteSpace(AnimFileName))
                {
                    bw.WriteUTF16(AnimFileName, true);

                    if (format != TAEFormat.DS1)
                    {
                        bw.Pad(0x10);
                    }
                }
            }
コード例 #7
0
 internal abstract void WriteInner(BinaryWriterEx bw, TAEFormat format);
コード例 #8
0
 internal abstract void ReadInner(BinaryReaderEx br, TAEFormat format);