示例#1
0
        protected override void OnParse(VoidPtr address)
        {
            bfloat *floatval = (bfloat *)address;
            bint    intval1  = *(bint *)(address + 80);

            floatEntries = new float[20];
            for (int i = 0; i < floatEntries.Length; i++)
            {
                floatEntries[i] = floatval[i];
            }
            intEntry1 = intval1;
        }
示例#2
0
        protected override void OnParse(VoidPtr address)
        {
            _unks = new List <float>();
            _hops = new List <float>();

            sMultiJump *hdr = (sMultiJump *)address;

            _unk1            = hdr->_unk1;
            _unk2            = hdr->_unk2;
            _unk3            = hdr->_unk3;
            _horizontalBoost = hdr->_horizontalBoost;

            if (hdr->hopFixed)
            {
                _hops.Add(*(bfloat *)hdr->_hopListOffset.Address);
            }
            else
            {
                bfloat *addr = (bfloat *)(BaseAddress + hdr->_hopListOffset);
                for (int i = 0; i < (_offset - hdr->_hopListOffset) / 4; i++)
                {
                    _hops.Add(*addr++);
                }
            }
            if (hdr->unkFixed)
            {
                _unks.Add(*(bfloat *)hdr->_unkListOffset.Address);
            }
            else
            {
                bfloat *addr = (bfloat *)(BaseAddress + hdr->_unkListOffset);
                for (int i = 0; i < ((hdr->hopFixed ? _offset : (int)hdr->_hopListOffset) - hdr->_unkListOffset) / 4; i++)
                {
                    _unks.Add(*addr++);
                }
            }
            if (hdr->turnFixed)
            {
                _turnFrames = *(bfloat *)hdr->_turnFrameOffset.Address;
            }
            else
            {
                _turnFrames = hdr->_turnFrameOffset;
            }
        }
        public override bool OnInitialize()
        {
            entries.Clear();
            if (_name == null || _name == "")
            {
                _name = ((int)Header->_ID).ToString("X");
            }

            bfloat *part2 = Header->part2;

            while (part2 < (System.bfloat *)((VoidPtr)Header) + WorkingUncompressed.Length)
            {
                entries.Add(*part2);
                part2++;
            }
            id           = Header->_ID;
            EventsOffset = Header->_EventsOffset;
            part2Offset  = Header->_part2Offset;
            unknown      = Header->_unknown;
            _name        = TrueID;
            return(true);
        }
示例#4
0
        protected override void OnWrite(VoidPtr address)
        {
            int off = 0;

            if (_hops.Count > 1)
            {
                off += _hops.Count * 4;
            }
            if (_unks.Count > 1)
            {
                off += _unks.Count * 4;
            }

            sMultiJump *header = (sMultiJump *)(address + off);

            RebuildAddress = header;

            bfloat *addr = (bfloat *)address;

            if (_unks.Count > 1)
            {
                header->_unkListOffset = Offset(addr);
                if (header->_unkListOffset > 0)
                {
                    Lookup(&header->_unkListOffset);
                }

                foreach (float f in _unks)
                {
                    *addr++ = f;
                }
            }
            else if (_unks.Count == 1)
            {
                *((bfloat *)&header->_unkListOffset) = _unks[0];
            }
            else
            {
                *((bfloat *)&header->_unkListOffset) = 0;
            }

            if (_hops.Count > 1)
            {
                header->_hopListOffset = Offset(addr);
                if (header->_hopListOffset > 0)
                {
                    Lookup(&header->_hopListOffset);
                }

                foreach (float f in _hops)
                {
                    *addr++ = f;
                }
            }
            else if (_hops.Count == 1)
            {
                *((bfloat *)&header->_hopListOffset) = _hops[0];
            }
            else
            {
                *((bfloat *)&header->_hopListOffset) = 0;
            }

            header->_unk1            = _unk1;
            header->_unk2            = _unk2;
            header->_unk3            = _unk3;
            header->_horizontalBoost = _horizontalBoost;

            if (header->turnFixed)
            {
                *(bfloat *)&header->_turnFrameOffset = _turnFrames;
            }
            else
            {
                header->_turnFrameOffset = (int)_turnFrames;
            }
        }
示例#5
0
        public static KeyframeCollection DecodeSRT0Keyframes(SRT0TextureEntry *entry, int numFrames)
        {
            KeyframeCollection kf = new KeyframeCollection(5, numFrames, 1, 1);

            if (entry == null)
            {
                return(kf);
            }

            bfloat * sPtr = (bfloat *)entry->Data;
            SRT0Code code = entry->Code;

            if (!code.NoScale)
            {
                if (code.ScaleIsotropic)
                {
                    if (code.FixedScaleX)
                    {
                        kf[0, 0, 1] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, AnimDataFormat.I12, 0, 1);
                    }
                }
                else
                {
                    if (code.FixedScaleX)
                    {
                        kf[0, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, AnimDataFormat.I12, 0);
                    }

                    if (code.FixedScaleY)
                    {
                        kf[0, 1] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, AnimDataFormat.I12, 1);
                    }
                }
            }

            if (!code.NoRotation)
            {
                if (code.FixedRotation)
                {
                    kf[0, 2] = *sPtr++;
                }
                else
                {
                    DecodeFrames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, AnimDataFormat.I12, 2);
                }
            }

            if (!code.NoTranslation)
            {
                if (code.FixedX)
                {
                    kf[0, 3] = *sPtr++;
                }
                else
                {
                    DecodeFrames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, AnimDataFormat.I12, 3);
                }

                if (code.FixedY)
                {
                    kf[0, 4] = *sPtr++;
                }
                else
                {
                    DecodeFrames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, AnimDataFormat.I12, 4);
                }
            }

            return(kf);
        }
示例#6
0
        private static void DecodeFrames(KeyframeCollection kf, void *dataAddr, AnimDataFormat format,
                                         params int[] arrays)
        {
            int   fCount;
            float vStep, vBase;

            switch (format)
            {
            case AnimDataFormat.I4:
            {
                I4Header *header = (I4Header *)dataAddr;
                fCount = header->_entries;
                vStep  = header->_step;
                vBase  = header->_base;

                foreach (int x in arrays)
                {
                    I4Entry *entry = header->Data;
                    for (int i = 0; i < fCount; i++, entry++)
                    {
                        kf.SetFrameValue(x, entry->FrameIndex, vBase + entry->Step * vStep, true)._tangent =
                            entry->Tangent;
                    }
                }

                break;
            }

            case AnimDataFormat.I6:
            {
                I6Header *header = (I6Header *)dataAddr;
                fCount = header->_numFrames;
                vStep  = header->_step;
                vBase  = header->_base;

                foreach (int x in arrays)
                {
                    I6Entry *entry = header->Data;
                    for (int i = 0; i < fCount; i++, entry++)
                    {
                        kf.SetFrameValue(x, entry->FrameIndex, vBase + entry->_step * vStep, true)._tangent =
                            entry->Tangent;
                    }
                }

                break;
            }

            case AnimDataFormat.I12:
            {
                I12Header *header = (I12Header *)dataAddr;
                fCount = header->_numFrames;

                foreach (int x in arrays)
                {
                    I12Entry *entry = header->Data;
                    for (int i = 0; i < fCount; i++, entry++)
                    {
                        kf.SetFrameValue(x, (int)entry->_index, entry->_value, true)._tangent = entry->_tangent;
                    }
                }

                break;
            }

            case AnimDataFormat.L1:
            {
                L1Header *header = (L1Header *)dataAddr;
                vStep = header->_step;
                vBase = header->_base;

                foreach (int x in arrays)
                {
                    byte *sPtr = header->Data;
                    for (int i = 0; i < kf.FrameLimit; i++)
                    {
                        kf.SetFrameValue(x, i, vBase + *sPtr++ *vStep, true).GenerateTangent();
                    }
                }

                break;
            }

            case AnimDataFormat.L2:
            {
                L1Header *header = (L1Header *)dataAddr;
                vStep = header->_step;
                vBase = header->_base;

                foreach (int x in arrays)
                {
                    bushort *sPtr = (bushort *)header->Data;
                    for (int i = 0; i < kf.FrameLimit; i++)
                    {
                        kf.SetFrameValue(x, i, vBase + *sPtr++ *vStep, true).GenerateTangent();
                    }
                }

                break;
            }

            case AnimDataFormat.L4:
            {
                foreach (int x in arrays)
                {
                    bfloat *sPtr = (bfloat *)dataAddr;
                    for (int i = 0; i < kf.FrameLimit; i++)
                    {
                        kf.SetFrameValue(x, i, *sPtr++, true).GenerateTangent();
                    }
                }

                break;
            }
            }
        }
示例#7
0
        public static KeyframeCollection DecodeCHR0Keyframes(CHR0Entry *entry, int numFrames)
        {
            KeyframeCollection kf = new KeyframeCollection(9, numFrames, 1, 1, 1);

            if (entry == null)
            {
                return(kf);
            }

            bfloat *       sPtr = (bfloat *)entry->Data;
            AnimationCode  code = entry->Code;
            AnimDataFormat format;

            if (code.HasScale)
            {
                format = code.ScaleDataFormat;
                if (code.IsScaleIsotropic)
                {
                    if (code.IsScaleZFixed)
                    {
                        kf[0, 0, 1, 2] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 0, 1, 2);
                    }
                }
                else
                {
                    if (code.IsScaleXFixed)
                    {
                        kf[0, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 0);
                    }

                    if (code.IsScaleYFixed)
                    {
                        kf[0, 1] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 1);
                    }

                    if (code.IsScaleZFixed)
                    {
                        kf[0, 2] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 2);
                    }
                }
            }

            if (code.HasRotation)
            {
                format = code.RotationDataFormat;
                if (code.IsRotationIsotropic)
                {
                    if (code.IsRotationZFixed)
                    {
                        kf[0, 3, 4, 5] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 3, 4, 5);
                    }
                }
                else
                {
                    if (code.IsRotationXFixed)
                    {
                        kf[0, 3] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 3);
                    }

                    if (code.IsRotationYFixed)
                    {
                        kf[0, 4] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 4);
                    }

                    if (code.IsRotationZFixed)
                    {
                        kf[0, 5] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 5);
                    }
                }
            }

            if (code.HasTranslation)
            {
                format = code.TranslationDataFormat;
                if (code.IsTranslationIsotropic)
                {
                    if (code.IsTranslationZFixed)
                    {
                        kf[0, 6, 7, 8] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 6, 7, 8);
                    }
                }
                else
                {
                    if (code.IsTranslationXFixed)
                    {
                        kf[0, 6] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 6);
                    }

                    if (code.IsTranslationYFixed)
                    {
                        kf[0, 7] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 7);
                    }

                    if (code.IsTranslationZFixed)
                    {
                        kf[0, 8] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 8);
                    }
                }
            }

            return(kf);
        }
示例#8
0
        private static int EncodeEntry(int index, AnimDataFormat format, KeyframeCollection kf, VoidPtr addr)
        {
            int           numFrames = kf.FrameLimit;
            KeyframeEntry frame, root = kf._keyArrays[index]._keyRoot;
            bfloat *      pVal = (bfloat *)addr;
            float         val, frameScale = numFrames <= 1 ? 1 : 1.0f / (numFrames - 1);
            float         min, max, stride, step;
            int           span, i;
            int           keyCount = kf._keyArrays[index]._keyCount;

            if (format == AnimDataFormat.L4)
            {
                //Use all frames, just in case not all frames are key.
                for (i = 0; i < numFrames; i++)
                {
                    *pVal++ = kf[i, index];
                }

                return(numFrames * 4);
            }

            if (format == AnimDataFormat.I12)
            {
                I12Header *header = (I12Header *)addr;
                *          header = new I12Header(keyCount, frameScale);

                I12Entry *entry = header->Data;
                for (frame = root._next; frame._index != -1; frame = frame._next)
                {
                    *entry++ = new I12Entry(frame._index, frame._value, frame._tangent);
                }

                return(keyCount * 12 + 8);
            }

            //Get floor/ceil/stride
            min = float.MaxValue;
            max = float.MinValue;
            for (frame = root._next; frame != root; frame = frame._next)
            {
                val = frame._value;

                if (val > max)
                {
                    max = val;
                }

                if (val < min)
                {
                    min = val;
                }
            }

            stride = max - min;

            if (format == AnimDataFormat.L1)
            {
                //Find best span
                span = EvalSpan(255, 32, min, stride, root, true);
                step = stride / span;

                L1Header *header = (L1Header *)addr;
                *         header = new L1Header(step, min);

                byte *dPtr = header->Data;
                for (i = 0; i < numFrames; i++)
                {
                    *dPtr++ = (byte)((kf[i, index] - min) / step + 0.5f);
                }

                //Fill remaining bytes
                while ((i++ & 3) != 0)
                {
                    *dPtr++ = 0;
                }

                return((8 + numFrames).Align(4));
            }

            if (format == AnimDataFormat.I4)
            {
                //Find best span
                span = EvalSpan(4095, 32, min, stride, root, false);
                step = stride / span;

                I4Header *header = (I4Header *)addr;
                *         header = new I4Header(keyCount, frameScale, step, min);

                I4Entry *entry = header->Data;

                for (frame = root._next; frame._index != -1; frame = frame._next)
                {
                    val  = (frame._value - min) / step;
                    val += val < 0 ? -0.5f : 0.5f;

                    *entry++ = new I4Entry(frame._index, (int)val, frame._tangent);
                }

                return(keyCount * 4 + 16);
            }

            if (format == AnimDataFormat.I6)
            {
                //Find best span
                span = EvalSpan(65535, 32, min, stride, root, false);
                step = stride / span;

                I6Header *header = (I6Header *)addr;
                *         header = new I6Header(keyCount, frameScale, step, min);

                I6Entry *entry = header->Data;

                for (frame = root._next; frame._index != -1; frame = frame._next)
                {
                    val  = (frame._value - min) / step;
                    val += val < 0 ? -0.5f : 0.5f;

                    *entry++ = new I6Entry(frame._index, (int)val, frame._tangent);
                }

                //Fill remaining bytes
                if ((keyCount & 1) != 0)
                {
                    entry->_data = 0;
                }

                return((keyCount * 6 + 16).Align(4));
            }

            return(0);
        }
示例#9
0
        public static KeyframeCollection DecodeCHR0Keyframes(CHR0Entry *entry, int numFrames)
        {
            KeyframeCollection kf   = new KeyframeCollection(numFrames);
            bfloat *           sPtr = (bfloat *)entry->Data;
            AnimationCode      code = entry->Code;
            AnimDataFormat     format;

            if (code.HasScale)
            {
                format = code.ScaleDataFormat;
                if (code.IsScaleIsotropic)
                {
                    if (code.IsScaleZFixed)
                    {
                        kf[KeyFrameMode.ScaleXYZ, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.ScaleXYZ);
                    }
                }
                else
                {
                    if (code.IsScaleXFixed)
                    {
                        kf[KeyFrameMode.ScaleX, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.ScaleX);
                    }

                    if (code.IsScaleYFixed)
                    {
                        kf[KeyFrameMode.ScaleY, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.ScaleY);
                    }

                    if (code.IsScaleZFixed)
                    {
                        kf[KeyFrameMode.ScaleZ, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.ScaleZ);
                    }
                }
            }

            if (code.HasRotation)
            {
                format = code.RotationDataFormat;
                if (code.IsRotationIsotropic)
                {
                    if (code.IsRotationZFixed)
                    {
                        kf[KeyFrameMode.RotXYZ, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.RotXYZ);
                    }
                }
                else
                {
                    if (code.IsRotationXFixed)
                    {
                        kf[KeyFrameMode.RotX, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.RotX);
                    }

                    if (code.IsRotationYFixed)
                    {
                        kf[KeyFrameMode.RotY, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.RotY);
                    }

                    if (code.IsRotationZFixed)
                    {
                        kf[KeyFrameMode.RotZ, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.RotZ);
                    }
                }
            }

            if (code.HasTranslation)
            {
                format = code.TranslationDataFormat;
                if (code.IsTranslationIsotropic)
                {
                    if (code.IsTranslationZFixed)
                    {
                        kf[KeyFrameMode.TransXYZ, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.TransXYZ);
                    }
                }
                else
                {
                    if (code.IsTranslationXFixed)
                    {
                        kf[KeyFrameMode.TransX, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.TransX);
                    }

                    if (code.IsTranslationYFixed)
                    {
                        kf[KeyFrameMode.TransY, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.TransY);
                    }

                    if (code.IsTranslationZFixed)
                    {
                        kf[KeyFrameMode.TransZ, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.TransZ);
                    }
                }
            }

            return(kf);
        }
示例#10
0
        public static KeyframeCollection DecodeSRT0Keyframes(SRT0TextureEntry *entry, int numFrames)
        {
            KeyframeCollection kf   = new KeyframeCollection(numFrames);
            bfloat *           sPtr = (bfloat *)entry->Data;
            SRT0Code           code = entry->Code;

            if (!code.NoScale)
            {
                if (code.ScaleIsotropic)
                {
                    if (code.FixedScaleX)
                    {
                        kf[KeyFrameMode.ScaleXYZ, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeSRT0Frames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, KeyFrameMode.ScaleXYZ);
                    }
                }
                else
                {
                    if (code.FixedScaleX)
                    {
                        kf[KeyFrameMode.ScaleX, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeSRT0Frames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, KeyFrameMode.ScaleX);
                    }
                    if (code.FixedScaleY)
                    {
                        kf[KeyFrameMode.ScaleY, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeSRT0Frames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, KeyFrameMode.ScaleY);
                    }
                }
            }
            if (!code.NoRotation)
            {
                if (code.FixedRotation)
                {
                    kf[KeyFrameMode.RotX, 0] = *sPtr++;
                }
                else
                {
                    DecodeSRT0Frames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, KeyFrameMode.RotX);
                }
            }

            if (!code.NoTranslation)
            {
                if (code.FixedX)
                {
                    kf[KeyFrameMode.TransX, 0] = *sPtr++;
                }
                else
                {
                    DecodeSRT0Frames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, KeyFrameMode.TransX);
                }
                if (code.FixedY)
                {
                    kf[KeyFrameMode.TransY, 0] = *sPtr++;
                }
                else
                {
                    DecodeSRT0Frames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, KeyFrameMode.TransY);
                }
            }

            return(kf);
        }
示例#11
0
        private static void DecodeCHR0Frames(KeyframeCollection kf, void *dataAddr, AnimDataFormat format, KeyFrameMode mode)
        {
            int   fCount;
            float vStep, vBase;

            switch (format)
            {
            case AnimDataFormat.I4:
            {
                I4Header *header = (I4Header *)dataAddr;
                fCount = header->_entries;
                vStep  = header->_step;
                vBase  = header->_base;

                I4Entry *entry = header->Data;
                for (int i = 0; i < fCount; i++, entry++)
                {
                    kf.SetFrameValue(mode, entry->FrameIndex, vBase + (entry->Step * vStep))._tangent = entry->Tangent;
                }
                break;
            }

            case AnimDataFormat.I6:
            {
                I6Header *header = (I6Header *)dataAddr;
                fCount = header->_numFrames;
                vStep  = header->_step;
                vBase  = header->_base;

                I6Entry *entry = header->Data;
                for (int i = 0; i < fCount; i++, entry++)
                {
                    kf.SetFrameValue(mode, entry->FrameIndex, vBase + (entry->_step * vStep))._tangent = entry->Tangent;
                }
                break;
            }

            case AnimDataFormat.I12:
            {
                I12Header *header = (I12Header *)dataAddr;
                fCount = header->_numFrames;

                I12Entry *entry = header->Data;
                for (int i = 0; i < fCount; i++, entry++)
                {
                    kf.SetFrameValue(mode, (int)entry->_index, entry->_value)._tangent = entry->_tangent;
                }
                break;
            }

            case AnimDataFormat.L1:
            {
                L1Header *header = (L1Header *)dataAddr;
                vStep = header->_step;
                vBase = header->_base;

                byte *sPtr = header->Data;
                for (int i = 0; i < kf.FrameCount; i++)
                {
                    kf[mode, i] = vBase + (*sPtr++ *vStep);
                }

                KeyframeEntry root = kf._keyRoots[(int)mode & 0xF];
                for (KeyframeEntry entry = root._next; entry != root; entry = entry._next)
                {
                    entry.GenerateTangent();
                }

                break;
            }

            case AnimDataFormat.L2:
            {
                L1Header *header = (L1Header *)dataAddr;
                vStep = header->_step;
                vBase = header->_base;

                bushort *sPtr = (bushort *)header->Data;
                for (int i = 0; i < kf.FrameCount; i++)
                {
                    kf[mode, i] = vBase + (*sPtr++ *vStep);
                }

                KeyframeEntry root = kf._keyRoots[(int)mode & 0xF];
                for (KeyframeEntry entry = root._next; entry != root; entry = entry._next)
                {
                    entry.GenerateTangent();
                }

                break;
            }

            case AnimDataFormat.L4:
            {
                bfloat *sPtr = (bfloat *)dataAddr;

                for (int i = 0; i < kf.FrameCount; i++)
                {
                    kf[mode, i] = *sPtr++;
                }

                KeyframeEntry root = kf._keyRoots[(int)mode & 0xF];
                for (KeyframeEntry entry = root._next; entry != root; entry = entry._next)
                {
                    entry.GenerateTangent();
                }

                break;
            }
            }
        }