N
nfitc1
Guest
So I put my mind to it yesterday and I found out quite a bit about those elusive **ab files in the battle.lgp archive (I don't know the PSX equivalent). Thanks to DLPB who discovered that the death animations are set there, it got me wondering more about the structure of the entire file. Let me share what I've learned. Because I don't want to keep typing "**ab file" I'll refer to them as animation script files or script files or maybe just "ab".
Each model grouping (aa**, ab**, etc) has an ab file, even backgrounds. They are at least 8 bytes in size and contain lots of info on how to group animations stored in the associated **da files. The models are assigned to actors which each get a large chunk of memory to determine lots of things like position, orientation, height, model info, and a bunch of other stuff. The chunks for each model are 6892 bytes in size and exist for three player characters, the battle background model, and up to six enemy models. This chunk is where the bulk of the info in the ab file goes, just in different places.
There's also another actor-related chunk that is 116 bytes in size. This also gets a few settings from the ab file.
The ab files are broken up into three chunks:
Header:
This is what I know very little about. It has some things related to rotation of the model and possibly defines "front" and "up" for the model. I DO know where it all maps to in memory (at least on the PC version) and most of it goes into that chunk I just mentioned.
Code: [Select]
I grouped them like that because that's the way the game stores them or loads them. I assume they're all related. Right now, we only really know what byte 02 does. That's the death animation.
The first word determines what type of actor it is. Most enemies is just 1, backgrounds is 501h, player characters are 0h. There might be other values, I don't know.
Now the second group. Script headers. Just like it is in text files and AI script blocks, these point to a raw memory address within the file to a script that defines an animation group for an actor. These don't get stored anywhere. Instead they are translated, but I'll mention that later. There are no more than 74 scripts in these files. Players use all of these, while enemies typically need less than 20, though those are bosses.
The file group is the actual animation scripts. These are pretty powerful scripts that control a lot about the actors. For example, using an item plays three different animations from the da file. One is hopping foward, one is tossing the item, and the last is hopping back to position. These scripts will merge all three of the actions while setting new positions, orientations and, in some cases, speed and even volume.
There are 113 opcodes ranging from 8E - FF inclusive. Some take arguments some don't. I'm still going through them. If it comes across something less than 8E it will assume it's a defined animation and attempt to execute that animation index from the **da file. If it doesn't find it...well....bad things will happen. So codes, like B2 and C9, do absolutely nothing and are skipped over and even sometimes picked up later.
For example, most enemy animation 0 (the idle animation) scripts look like this:
Code: [Select]
A9 takes two parameters, but completely ignores the first one. The second one gets mapped to 0xBE1186 (It's probably safe to assume that's the **da animation that will serve as the idle animation for that actor).
Now we're at C1. It's function is to find the C9 value and treat that as the next code. It will then set the animation script location at the first C9 it finds in that script. So C9 and C1 are like a loop (although C9 by itself does nothing). There might be something similar to B2 because it doesn't have a function either.
If anyone wants to help me derive the functions of these codes or functions of the header values feel free. The function that handles all this starts at 0x41FBA4 with the individual opcode handler addresses starting at 0x4248C2. First one of those handles 8E, the second handles 8F and so forth. Some are shared like 9A and FB.
I almost forgot, the translations. For the script pointers and the few dwords in the header, they get translated into RAM addresses after being loaded into memory. So if something points at 0x190 within the file, it may get translated to 0x3492A8F or wherever that file's location ends up in memory. It will still point to the same location within the file that it pointed to before so all the unique pointers will point to different places. I hope I explained that adequately.
Each model grouping (aa**, ab**, etc) has an ab file, even backgrounds. They are at least 8 bytes in size and contain lots of info on how to group animations stored in the associated **da files. The models are assigned to actors which each get a large chunk of memory to determine lots of things like position, orientation, height, model info, and a bunch of other stuff. The chunks for each model are 6892 bytes in size and exist for three player characters, the battle background model, and up to six enemy models. This chunk is where the bulk of the info in the ab file goes, just in different places.
There's also another actor-related chunk that is 116 bytes in size. This also gets a few settings from the ab file.
The ab files are broken up into three chunks:
Header:
This is what I know very little about. It has some things related to rotation of the model and possibly defines "front" and "up" for the model. I DO know where it all maps to in memory (at least on the PC version) and most of it goes into that chunk I just mentioned.
Code: [Select]
Code:
ab address memory size 0x00 0xBE1178 word 0x02 0xBE119F byte 0x04 0xBE118A word 0x06 0xBE1180 word 0x08 0xBE1182 word 0x0A 0xBE1184 word 0x0C 0xBF23E6 word 0x0E 0xBF23E8 word 0x10 0xBF23EA word 0x12 0xBE11A3 byte 0x13 0xBE11A4 byte 0x14 0xBE11A5 byte 0x15 0xBE11A6 byte 0x16 0xBE11A7 byte 0x17 0xBE11A8 byte 0x18 0xBE11A9 byte 0x19 0xBE11AA byte 0x1A 0xBE11AB byte 0x1B 0xBE11AC byte 0x1C 0xBE11AD byte 0x1D 0xBE11AE byte 0x1E 0xBE11AF byte 0x1F 0xBE11B0 byte 0x20 0xBE11B1 byte 0x21 0xBE11B2 byte 0x22 align word 0x24 translate dword 0x28 translate dword 0x2C translate dword 0x30 translate dword 0x34 translate dword 0x38 translate dword 0x3C translate dword 0x40 translate dword 0x44 0xBF23C4 word ;address of last actual script pointer (others may follow, but they are ignored?) 0x46 0xBF23C6 word 0x48 0xBF23C8 word 0x4A 0xBF23CA word 0x4C 0xBF23CE word 0x4E 0xBF23D0 word 0x50 0xBF23D2 word 0x52 0xBF23D4 word 0x54 0xBF23D6 word 0x56 0xBF23D8 word 0x58 0xBF23DA word 0x5A 0xBF23DC word 0x5C 0xBF23DE word 0x5E 0xBF23E0 word 0x60 0xBF23E2 word 0x62 0xBF23E4 word 0x64 0xBF23F0 word 0x66 align word
The first word determines what type of actor it is. Most enemies is just 1, backgrounds is 501h, player characters are 0h. There might be other values, I don't know.
Now the second group. Script headers. Just like it is in text files and AI script blocks, these point to a raw memory address within the file to a script that defines an animation group for an actor. These don't get stored anywhere. Instead they are translated, but I'll mention that later. There are no more than 74 scripts in these files. Players use all of these, while enemies typically need less than 20, though those are bosses.
The file group is the actual animation scripts. These are pretty powerful scripts that control a lot about the actors. For example, using an item plays three different animations from the da file. One is hopping foward, one is tossing the item, and the last is hopping back to position. These scripts will merge all three of the actions while setting new positions, orientations and, in some cases, speed and even volume.
There are 113 opcodes ranging from 8E - FF inclusive. Some take arguments some don't. I'm still going through them. If it comes across something less than 8E it will assume it's a defined animation and attempt to execute that animation index from the **da file. If it doesn't find it...well....bad things will happen. So codes, like B2 and C9, do absolutely nothing and are skipped over and even sometimes picked up later.
For example, most enemy animation 0 (the idle animation) scripts look like this:
Code: [Select]
Code:
A9 C9 00 C1
Now we're at C1. It's function is to find the C9 value and treat that as the next code. It will then set the animation script location at the first C9 it finds in that script. So C9 and C1 are like a loop (although C9 by itself does nothing). There might be something similar to B2 because it doesn't have a function either.
If anyone wants to help me derive the functions of these codes or functions of the header values feel free. The function that handles all this starts at 0x41FBA4 with the individual opcode handler addresses starting at 0x4248C2. First one of those handles 8E, the second handles 8F and so forth. Some are shared like 9A and FB.
I almost forgot, the translations. For the script pointers and the few dwords in the header, they get translated into RAM addresses after being loaded into memory. So if something points at 0x190 within the file, it may get translated to 0x3492A8F or wherever that file's location ends up in memory. It will still point to the same location within the file that it pointed to before so all the unique pointers will point to different places. I hope I explained that adequately.
Last edited: