Author Topic: Final Fantasy® VII battle animation formats exposed!  (Read 4999 times)

L. Spiro

  • *
  • Posts: 797
    • View Profile
    • http://www.memoryhacking.com/index.php
Hopefully that is what this thread will accomplish.

I did some poking around in the file formats today and did make some ground, but for every step forward there were 23 (approximately) steps back.

I don’t think I am going to get this format decoded on my own, so I am hoping to get others intrested in it.

Here is what we know:
Battle animation formats are the **da files stored in battle.lgp.  They are fully binary and they are also the same format as the ones used in magic.lgp (for summons).

A battle enemy has an ID which can be converted into two letters, starting with “aa”.  So enemy ID 5 is “af” and enemy ID 242 is “ji”.
All the files for an enemy in battle.lgp start with those first two letters.  The postfix is what determines the type of file it is in relation to the enemy.

**da files are animations.  **aa files are heirarchy files.
The details on these are covered in other posts and in other documents so I will move along directly to the **da files of intrest here.

The first 4 bytes of the **da file represent the numebr of animations in the file, even though some animations are blank and only 16 bytes long.  They are unknown at this time.

The animations follow.  Each animation has this header (this header is revised from documents you may have):

Code: [Select]
struct s_FF7AAanimHdr {
unsigned long rec_a; //0
unsigned long frames1; //4
unsigned long block_len; //8

unsigned short frames2; //12
unsigned short real_data_len; //14
unsigned char key; //15
} FF7AAanimHdr; //size = 17 bytes



frames1 and frames2 seem to always be the same number except in the dummy animations with only 16 bytes.  Most likely frames2 is the actual number of frames.

block_len is the length of the block from there until the next animation set.
This length includes frames2, real_data_len, and key.

real_data_len is the actual number of bytes that are contained within this animation starting after key.

key is a compression indicator which determines if first frame is packed by 12 bits, 10 bits, or 8 bits.
key:   Bits:
0   12
2   10
4   8


After this header comes the actual animation data for this animation.
A single frame has XYZ translations, XYZ rotations for the root bone, and then XYZ rotations for each of the bones in the model.

The data starts with 3 shorts, which are the translations for the first frame.
They are actually stored in reverse format of everything else in Final Fantasy® VII, for completely unknown reasons.
For all references, we use Cloud’s animation file, rtda.
The header of his first animation ends at 0x15, at which point his first frame begins (ON 0x15).  You see this: 00 00 FE 2E 00 00.
These are 3 shorts in reverse (little endian) format.
Reverse the bytes in each number individually:
00 00 -> 00 00
FE 2E -> 2E FE
00 00 -> 00 00

Now they are signed shorts indicating the X Y and Z translations for Cloud’s first frame (0, -466, 0).

What comes next is a series of rotations.
Rotations are stored in the number of bits determined by “key” and each bone has 3 rotations (XYZ).

So, if key is 0, each bone requires (12 * 3 / 8) bytes, or 4.5.
If key is 2, each bone requires (10 * 3 / 8) bytes, or 3.75.
If key is 4, each bone requires (8 * 3 / 8) bytes, or 3.

To decode these, first we need to declare a ceiling.  The ceiling is the total numbers that can be held by the number of bits in each bone.
Cloud’s key is 0, so each of the rotations in his bones is 12 bits.
The numbers 12 bits can hold ranges from 0 to 4095, which is 4096 total numbers.  So “Ceiling” is 4096 here.
For 10 bits it is 1024 and for 8 bits it is 256.

The start of Cloud’s rotations is 0x1B.
Every 12 bits from here is an X, Y, or Z (in that order).  Each XYZ triplet is a bone.
So, every 4.5 bytes is a bone.  His data is as follows:
00 00 00 00 0C 00 EC E0 00 F8 2F E5…
Break this into 12-bit groups:
000 000 000 C00 ECE 000 F82 FE5…

The equation to transform the groups into angles is:
(group) * 360 / Ceiling.
So let’s do this on each rotation.
000 = (0x000) * 360 / 4096 = 0
000 = (0x000) * 360 / 4096 = 0
000 = (0x000) * 360 / 4096 = 0
C00 = (0xC00) * 360 / 4096 = 270
ECE = (0xECE) * 360 / 4096 = 333.10546875
000 = (0x000) * 360 / 4096 = 0
F82 = (0xF82) * 360 / 4096 = 348.92578125
FE5 = (0xFE5) * 360 / 4096 = 357.626953125
…
His first bone is (0, 0, 0).
His second bone is (270, 333.10546875, 0).
His third bone is (348.92578125, 357.626953125, …).


NOTE: His FIRST bone is NOT part of his skeleton.  It is his root bone and it determines the facing direction of his entire body.  His actual bones start on the second bone I listed here.

The number of bones is (Character’s Bones + 1), because the first bone is not part of his skeleton; it is his root bone.

Cloud’s first frame is (6 + 4.5 * (23 + 1)), or 114 bytes.
It starts at 0x15, so the next frame begins at 0x87.



Now here are the things that I know.
The next frame starts with 00 05 00.
These bytes indicate the change in translation from his first frame.  His first frame’s translation was (0, -466, 0), so for this frame, it is (0, -461, 0) or (+0, +5, +0).
This seems fairly direct but it is only in this simple case.

Actually the offsets are stored in 7 bits, and those 7 bits are signed.
This means from one frame to the next, a character can move anywhere from -64 to 63 units.
So, 6F would move the character -17 units.
Each frame bases itself off the previous frame.

Unfortunately that is all I really know for sure.

The offsets for each frame after the first are only stored in 7 bits for the translations. The rotations are stored differently.
And, for the translations, I do not know what the 8th bit does.
I can set the 7 bits to whatever I want his position to be, but if I set the 8th bit he starts swirling around the map in large gaping circles.

When I mess with the data immediately after the offsets for the second frame it can cause drastic changes.
On one case his whole body started flattening.  The animation (including the flattening) was smooth and repeated fine.  He flattened more and more as the animation progressed and then the first frame was run again, where he was no longer flattened at all.


Other changes to only the second frame of data have resulted in a few frames where things are fine, then his arm breaks, then a few frames later his body shifts into all directions.

The data is not packed by means of compression; it is just stored in a different format.

At this point, I can not draw conclusive ideas on the formats in which they are stored.
But I know they are definitely NOT:
Compressed
Key Framed
Full Frames

I believe Cloud’s second frame is 82 bytes total, but here I have little more than poorly based calculations for that, so do not take my word for it.


Anyone want to jump in at all?


L. Spiro

mirex

  • *
  • Posts: 1645
    • View Profile
    • http://mirex.mypage.sk
Final Fantasy® VII battle animation formats exposed!
« Reply #1 on: 2004-10-12 08:09:41 »
I got an idea ... you said you can see uncompressed frames in the memory ... can you compare 1st with 2nd cloud's frame to see how many bones changed their rotations and how many rotations haven't changed ? Then maybe only changed rotations are stored in the 2nd frame data. This is only idea that comes to my mind right now.

L. Spiro

  • *
  • Posts: 797
    • View Profile
    • http://www.memoryhacking.com/index.php
Final Fantasy® VII battle animation formats exposed!
« Reply #2 on: 2004-10-12 10:02:00 »
I did that (it was also the first idea I got).

Here is the table I made:


Code: [Select]
0 0 0
0 0 0
0 0 0
0 0 0
466 461 -5
0 0 0
270 270 0
333.1055 333.1055 0
0 0 0
348.9258 348.9258 0
357.627 357.627 0
327.1289 327.1289 0
16.43555 16.43555 0
17.57813 17.57813 0
61.52344 61.52344 0
332.0508 332.0508 0
337.6758 337.6758 0
245.2148 245.2148 0
34.27734 34.45313 0.17579
90.08789 90.61523 0.52734
61.96289 63.10547 1.14258
74.88281 74.61914 -0.26367
42.53906 40.42969 -2.10937
335.2148 333.1934 -2.0214
322.2949 322.5586 0.2637
0. 0 0
0. 0 0
3.691406 3.691406 0
8.525391 8.525391 0
336.1816 336.1816 0
358.5059 358.5059 0
21.09375 21.09375 0
53.34961 53.34961 0
66.18164 67.06055 0.87891
0.5273438 1.142578 0.6152342
15.9082 16.52344 0.61524
56.25 56.77734 0.52734
242.0508 243.1934 1.1426
318.7793 319.7461 0.9668
338.2031 337.3242 -0.8789
0. 0 0
0. 0 0
354.7266 355.7813 1.0547
358.6816 358.1543 -0.5273
332.2266 332.1387 -0.0879
0. 0 0
229.043 229.043 0
0. 0 0
58.44727 58.88672 0.43945
313.6816 315.8789 2.1973
235.2832 237.1289 1.8457
24.96094 28.21289 3.25195
0. 0 0
0. 0 0
303.8379 300.6738 -3.1641
358.7695 359.0332 0.2637
68.20313 67.85156 -0.35157
298.916 299.8828 0.9668
358.418 356.748 -1.67
1.40625 2.8125 1.40625
0. 0 0
77.16797 77.16797 0
0. 0 0
31.46484 30.32227 -1.14257
270.3516 270.4395 0.0879
7.646484 7.470703 -0.175781
58.44727 60.20508 1.75781
0. 0 0
0. 0 0
331.2598 330.5566 -0.7032
349.3652 349.2773 -0.0879
5.976563 7.03125 1.054687
300.0586 300.0586 0
0. 0 0
0. 0 0


The first column is his first frame.
Second is his second frame.
Third is the amount by which it changed.

But it doesn’t work.

At least not so visibly.
When I changed the number to make him flatten it only changed some of the rotations per frame.
It seemed actually to shift them down one, by some number.
So one rotation lost about 2.235 or whatever and the rotation under it gained 2.55 or whatever (not the same loss as gain).

It only changed some of the rotations though.  I need to look to see if they are the rotations that are shown in my table as having changed.


L. Spiro

phaeron

  • *
  • Posts: 30
    • View Profile
Final Fantasy® VII battle animation formats exposed!
« Reply #3 on: 2004-10-16 06:36:08 »
Argh... I hadn't touched the anim data for about a year and a half and you suckered me back into looking at it tonight.

I translated the unknown part of Cloud's anim to bit form a long time ago and lined it up. Once you view it as a bitstream it's pretty apparent where the translations are because you have huge strings of zeroes. It looks to me like the second frame is ~39 bytes, the third ~40, the fourth ~39, and the rest about +/-5 from those for a total of 19 deltas + 1 key = 20 frames. 39 bytes for 34 axis deltas plus a translation comes out to a little over 8 bits per non-zero axis, which isn't out of line.

What I don't like is that (a) the translations have to be bitshifted to align, and (b) the really nutty things the game does when you flip single bits are in line with a variable-length coding scheme getting derailed temporarily. I tried comparing the deltas you listed again the bitstream, and didn't see an obvious correlation; you'd expect that the low bits of each delta would show up in sequence but that didn't seem to be the case.

By the way, the first three longs don't appear in the PSX data -- this is what I see in the start of the third record for CLOUD.LZS, which corresponds to the bone data you posted:
Code: [Select]

00000000: 14 00 56 03 00 00 00 FE-2E 00 00 00 00 00 00 0C

L. Spiro

  • *
  • Posts: 797
    • View Profile
    • http://www.memoryhacking.com/index.php
Final Fantasy® VII battle animation formats exposed!
« Reply #4 on: 2004-10-16 07:55:09 »
Each piece of data either points to the next piece in line or is part of a decryption scheme.

It is definitely a per-bit orientation.


I made this chart for myself bit since others may look into the format I will post it.


Code: [Select]
0: 01        45        AC        5A        F7        1B        9A        40        30        AD        08        B5        8B        87        9C        62        5E        81        67        53        A5        E1        4E        F2        9A        B0        F7        BA        01        97        29        E9        0B        91        88
   0    1    4    5    10   12   5    10   15   7    1    11   9    10   4    0    3    0    10   13   0    8    11   5    8    11   8    7    9    12   6    2    5    14   8    1    6    7    5    3    10   5    14   1    4    14   15   2    9    10   11   0    15   7    11   10   0    1    9    7    2    9    14   9    0    11   9    1    8    8
   0000 0001 0100 0101 1010 1100 0101 1010 1111 0111 0001 1011 1001 1010 0100 0000 0011 0000 1010 1101 0000 1000 1011 0101 1000 1011 1000 0111 1001 1100 0110 0010 0101 1110 1000 0001 0110 0111 0101 0011 1010 0101 1110 0001 0100 1110 1111 0010 1001 1010 1011 0000 1111 0111 1011 1010 0000 0001 1001 0111 0010 1001 1110 1001 0000 1011 1001 0001 1000 1000

1: 02        8B        58        B5        EE        37        34        80        61        5A        11        6B        17        0F        38        C4        BD        02        CE        A7        4B        C2        9D        E5        35        61        EF        74        03        2E        53        D2        17        23        10
   0    2    8    11   5    8    11   5    14   14   3    7    3    4    8    0    6    1    5    10   1    1    6    11   1    7    0    15   3    8    12   4    11   13   0    2    12   14   10   7    4    11   12   2    9    13   14   5    3    5    6    1    14   15   7    4    0    3    2    14   5    3    13   2    1    7    2    3    1    0
   0000 0010 1000 1011 0101 1000 1011 0101 1110 1110 0011 0111 0011 0100 1000 0000 0110 0001 0101 1010 0001 0001 0110 1011 0001 0111 0000 1111 0011 1000 1100 0100 1011 1101 0000 0010 1100 1110 1010 0111 0100 1011 1100 0010 1001 1101 1110 0101 0011 0101 0110 0001 1110 1111 0111 0100 0000 0011 0010 1110 0101 0011 1101 0010 0001 0111 0010 0011 0001 000

2: 05        16        B1        6B        DC        6E        69        00        C2        B4        22        D6        2E        1E        71        89        7A        05        9D        4E        97        85        3B        CA        6A        C3        DE        E8        06        5C        A7        A4        2E        46        20

   0    5    1    6    11   1    6    11   13   12   6    14   6    9    0    0    12   2    11   4    2    2    13   6    2    14   1    14   7    1    8    9    7    10   0    5    9    13   4    14   9    7    8    5    3    11   12   10   6    10   12   3    13   14   14   8    0    6    5    12   10   7    10   4    2    14   4    6    2    0
   0000 0101 0001 0110 1011 0001 0110 1011 1101 1100 0110 1110 0110 1001 0000 0000 1100 0010 1011 0100 0010 0010 1101 0110 0010 1110 0001 1110 0111 0001 1000 1001 0111 1010 0000 0101 1001 1101 0100 1110 1001 0111 1000 0101 0011 1011 1100 1010 0110 1010 1100 0011 1101 1110 1110 1000 0000 0110 0101 1100 1010 0111 1010 0100 0010 1110 0100 0110 0010 00

3: 0A        2D        62        D7        B8        DC        D2        01        85        68        45        AC        5C        3C        E3        12        F4        0B        3A        9D        2F        0A        77        94        D5        87        BD        D0        0C        B9        4F        48        5C        8C        40
   0    10   2    13   6    2    13   7    11   8    13   12   13   2    0    1    8    5    6    8    4    5    10   12   5    12   3    12   14   3    1    2    15   4    0    11   3    10   9    13   2    15   0    10   7    7    9    4    13   5    8    7    11   13   13   0    0    12   11   9    4    15   4    8    5    12   8    12   4    0
   0000 1010 0010 1101 0110 0010 1101 0111 1011 1000 1101 1100 1101 0010 0000 0001 1000 0101 0110 1000 0100 0101 1010 1100 0101 1100 0011 1100 1110 0011 0001 0010 1111 0100 0000 1011 0011 1010 1001 1101 0010 1111 0000 1010 0111 0111 1001 0100 1101 0101 1000 0111 1011 1101 1101 0000 0000 1100 1011 1001 0100 1111 0100 1000 0101 1100 1000 1100 0100 0

4: 14        5A        C5        AF        71        B9        A4        03        0A        D0        8B        58        B8        79        C6        25        E8        16        75        3A        5E        14        EF        29        AB        0F        7B        A0        19        72        9E        90        B9        18        8
   1    4    5    10   12   5    10   15   7    1    11   9    10   4    0    3    0    10   13   0    8    11   5    8    11   8    7    9    12   6    2    5    14   8    1    6    7    5    3    10   5    14   1    4    14   15   2    9    10   11   0    15   7    11   10   0    1    9    7    2    9    14   9    0    11    9   1    8    8
   0001 0100 0101 1010 1100 0101 1010 1111 0111 0001 1011 1001 1010 0100 0000 0011 0000 1010 1101 0000 1000 1011 0101 1000 1011 1000 0111 1001 1100 0110 0010 0101 1110 1000 0001 0110 0111 0101 0011 1010 0101 1110 0001 0100 1110 1111 0010 1001 1010 1011 0000 1111 0111 1011 1010 0000 0001 1001 0111 0010 1001 1110 1001 0000 1011 1001 0001 1000 1000

5: 28        B5        8B        5E        E3        73        48        06        15        A1        16        B1        70        F3        8C        4B        D0        2C        EA        74        BC        29        DE        53        56        1E        F7        40        32        E5        3D        21        72        31        0
   2    8    11   5    8    11   5    14   14   3    7    3    4    8    0    6    1    5    10   1    1    6    11   1    7    0    15   3    8    12   4    11   13   0    2    12   14   10   7    4    11   12   2    9    13   14   5    3    5    6    1    14   15   7    4    0    3    2    14   5    3    13   2    1    7    2    3    1    0
   0010 1000 1011 0101 1000 1011 0101 1110 1110 0011 0111 0011 0100 1000 0000 0110 0001 0101 1010 0001 0001 0110 1011 0001 0111 0000 1111 0011 1000 1100 0100 1011 1101 0000 0010 1100 1110 1010 0111 0100 1011 1100 0010 1001 1101 1110 0101 0011 0101 0110 0001 1110 1111 0111 0100 0000 0011 0010 1110 0101 0011 1101 0010 0001 0111 0010 0011 0001 000

6: 51        6B        16        BD        C6        E6        90        0C        2B        42        2D        62        E1        E7        18        97        A0        59        D4        E9        78        53        BC        A6        AC        3D        EE        80        65        CA        7A        42        E4        62        0
   5    1    6    11   1    6    11   13   12   6    14   6    9    0    0    12   2    11   4    2    2    13   6    2    14   1    14   7    1    8    9    7    10    0   5    9    13   4    14   9    7    8    5    3    11   12   10   6    10   12   3    13   14   14   8    0    6    5    12   10   7    10   4    2    14   4    6    2    0
   0101 0001 0110 1011 0001 0110 1011 1101 1100 0110 1110 0110 1001 0000 0000 1100 0010 1011 0100 0010 0010 1101 0110 0010 1110 0001 1110 0111 0001 1000 1001 0111 1010 0000 0101 1001 1101 0100 1110 1001 0111 1000 0101 0011 1011 1100 1010 0110 1010 1100 0011 1101 1110 1110 1000 0000 0110 0101 1100 1010 0111 1010 0100 0010 1110 0100 0110 0010 00

7: A2        D6        2D        7B        8D        CD        20        18        56        84        5A        C5        C3        CE        31        2F        40        B3        A9        D2        F0        A7        79        4D        58        7B        DD        00        CB        94        F4        85        C8        C4        0
   10   2    13   6    2    13   7    11   8    13   12   13   2    0    1    8    5    6    8    4    5    10   12   5    12   3    12   14   3    1    2    15   4    0    11   3    10   9    13   2    15   0    10   7    7    9    4    13   5    8    7    11   13   13   0    0    12   11   9    4    15   4    8    5    12   8    12   4    0
   1010 0010 1101 0110 0010 1101 0111 1011 1000 1101 1100 1101 0010 0000 0001 1000 0101 0110 1000 0100 0101 1010 1100 0101 1100 0011 1100 1110 0011 0001 0010 1111 0100 0000 1011 0011 1010 1001 1101 0010 1111 0000 1010 0111 0111 1001 0100 1101 0101 1000 0111 1011 1101 1101 0000 0000 1100 1011 1001 0100 1111 0100 1000 0101 1100 1000 1100 0100 0



It doesn’t show too well on the forums but I am sure you can get it all aligned properly in Notepad.

These are the bytes after 00 05 00 00.
Code: [Select]
Offset     Rot. Offsets The first frame
[00 05 00] [00 0]       [1 45 AC … 88]



This isn’t quite accurate but close.


The thing I notice is that there are 34 total changes in his rotations.
The bitstream starts as:

Code: [Select]
0000000101000101…
Now to make it more clear.

Code: [Select]
        |-34-|
0000000101000101…



We can go even further in this same path.
Depending on how you count, the first rotational change is on the 13th rotation.

Code: [Select]
000000010100010110101100…

Code: [Select]
        |-34-||13|
000000010100010110101100…



L. Spiro