(FFVII PC) The **ab files

  • Thread starter Thread starter nfitc1
  • Start date Start date
Status
Not open for further replies.
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]
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
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]
Code:
A9 C9 00 C1
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.
 
Last edited:
8) Good progress! I'd help but bogged down with 100 things.  Good luck with it :)
 
Last edited:
Come on Square, give us the bloody source code (when you find it).
 
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).
The PSX equivalent is the actual battle model (*.LZS) file section named Model Settings Data by Akari (a nomenclature I carried over into my battle model breakdowns on the forums and wiki).

I didn't get a chance to dig around at all last night, but I'll try to make time to do so tonight. This will certainly make custom battle models with proper animations much easier to create. Glad I could nudge you into uncovering a crucial part of the battle module :)
 
Little late of a reply, but I dived into the exe and discovered which codes take how many parameters. Here's a translation of Cloud's 74 scripts:

Code: [Select]
Code:
0: 00 FE C01: 01 FE C02: E5 06 F13: B3(F9) 03 ED E3 EE4: B3(F9) 04 E4 E3 EE5: 0F F2 E5 EE6: 10 11 F2 E5 EE7: 12 F2 E5 EE8: 05 E5 EE9: AB(0190, 0000) 08 F4(0F) F3 FA E5 A6 EE10: 13 E5 EE11: 18 19 E5 EE12: B4 02 F113: 95 07 FE C014: C4(0190, 06) 07 FE C015: E7(00) F116: 04 FA E5 EE17: E8 FC 03 ED E6 EA 0C 0D EC 0E 04 FA E5 EE18: E5 C4(0190, 06) 12 E7(00) F119: 10 FE C020: FC F0 D8(00, 001A) 1A D1(04B0, 0000, 04) F0 1B F7(01) 1E 1C FA F0 1D E5 EE21: FC 03 ED F7(10) 1F 04 FA E5 EE22: FC F0 D8(00, 001A) 1A D1(04B0, 0000, 04) F0 1B F7(01) 1E 9E23: F7(01) 22 23 FA F0 1D E5 EE24: FC F0 D8(00, 001A) 1A D1(04B0, 0000, 04) F0 1B F7(01) 1E 9E25: E5 BD(04B0, 0000) F0 F7(03) 22 9E26: E5 BD(04B0, 0000) F0 F7(03) 24 9E27: E5 BD(04B0, 0000) F0 F7(03) 29 1C FA F0 1D E5 EE28: FC F0 D8(00, 001A) 1A CC(04) CB(FF, 03E8, FE, FE, 00, 08, 08) 1B 1E F7(03) F4(06) F3 1C FA F0 1D E5 EE29: E8 FC 03 ED E6 EA 0C 0D EC 0E 04 FA E5 EE30: E8 FC 03 ED A4 EA 0C 0D EC 0E 04 FA E5 EE31: E8 FC 03 ED A5 EA 0C 0D EC F4(0F) F3 0E 04 FA E5 EE32: E8 FC 03 ED D8(06, 0015) 09 EA EB F4(0A) F3 04 FA E5 EE33: E8 FC 03 ED D8(06, 0015) 0A EA EB F4(0A) F3 04 FA E5 EE34, 35: FC F0 D8(00, 001A) 1A D1(04B0, 0000, 04) F0 1B F7(01) D8(01, 02D6) 16 F4(06) F3 26 FA F0 1D E5 EE36: FC F0 D8(00, 001A) 1A D1(04B0, 0000, 04) F0 1B F7(01) 1E 1C FA F0 1D E5 EE37: FC 03 ED F7(10) 1F 04 FA E5 EE38: FC 03 ED F7(01) 14 F4(3C) F3 04 FA E5 EE39: FC 03 ED F7(01) 14 F4(5A) F3 04 FA E5 EE40, 41: FC F0 D8(00, 001A) 1A D1(04B0, 0000, 04) F0 1B F7(10) 20 27 FA F0 1D E5 EE42, 43: FC F0 D8(00, 001A) 1A D1(04B0, 0000, 04) F0 1B F7(10) 21 28 FA F0 1D E5 EE44, 45: FC 03 ED F7(13) 15 04 FA E5 EE46-59: 00 FE C060: E8 FC 00 E0 EA F4(19) F3 EC F0 D8(00, 001A) 2C D1(04B0, 0000, 04) F0 2D D8(06, 0030) 2E FA F0 2F E5 EE61: E8 FC 00 E0 EA F4(19) F3 EC F0 D8(00, 001A) 2C D1(04B0, 0000, 04) F0 2D 2E FA F0 2F E5 EE62: E8 FC 00 E0 EA F4(19) F3 EC 2C 9E63: E8 FC 00 E0 EA F4(19) F3 EC F0 2C D8(00, 001A) FB(0640, 0000) F0 2D D8(19, 0030) A8(26, 08) 2E FA F0 E5 EE64, 65: E8 FC 00 E0 EA F4(19) F3 EC 2C E5 EE66: E8 FC 00 E0 EA F4(19) F3 EC 2C 2D 2D 2E FA E5 EE67: EC E5 EE68: EC 2D E5 EE69: E8 FC 00 E0 EA F4(19) F3 EC F0 D8(00, 001A) 2C D1(04B0, 0000, 04) F0 2D D8(06, 0030) 2E FA F0 2F E5 EE70 - 73: 00 FE C0
There are lots of duplicates (most of them dummied), but we can tell some things from a few of them.
Anim 0 is normal idle animation. Anim 1 is near-death idle animation. 2 is dead, 3 is hop forward, 4 is hop back, etc. This only applies to player characters.

9E, F1, EE, FF, C1, A2 and "FE C0" (which is weird because FE with anything else does nothing) are effective ends of scripts.
C1 loops back to the beginning and starts at the first C9 in the script. You could make a stupid script like "<blah> C1 <blah> C9 <blah>" and it would skip the chunk between C1 and C9, but there'd be no way to go to it and run those commands. There are better ways to do what you would need anyway.

Most of these commands take battle type into account. They'll choose what to do based on which side attack or preemp attack is being used. That seems to be the primary difference between the three types of side attacks.

9A, 9B, 9F, B0, B1, B2, B7, BA, BB, C0, CD, D2, D3, D9, DA, DB, EF, and F5 are unused even though some of them have fully working functions.
 
Last edited:
I admit that I know nothing about such things, but I've been eagerly anticipating LB's progress and NFITC1 is probably one of the coolest people I've had the pleasure of interacting with.  Forward progress Ho!!!!  Every now and then the reality of how freaking much VII has been dissected and broken down sets in.  I'm excited to see what comes from this!
 
NFITC1: Great framework info. Thanks very much for jumping into this.

xLostWingx: Though I've been very busy with the new house I just moved into, I haven't at all dropped my intention to continue this thread (my email inbox is always kept clean of everything but items of the utmost importance, and the notification concerning this thread is currently one of only three items therein), until its information is useable in simplifying my custom playable character battle models. I'm finally starting to get back on track with some free time for projects like Adamant, so hopefully I'll take a few hours to sit down and map some things out more extensively very soon. In the meantime, anyone with a little free time and interest is encouraged to do the same.
 
Last edited:
Good to know LB.  I understand that this is a game of patience, trial and error, and whatever else it involves.  I'm no progammer nor do I think I could even make to case to consider myself a hobbyist.  I usually just skim through or skip over the code that accompanies many posts.  If we ever need to conduct a cognitive, academic, or behavioral assessment of...ok no...there is no way for me to use my professional expertise to aid this or any project in Scripting and Engineering.  But I certainly am an interested observer, and it is good to know you're committed to continuing to work with VII, especially since your work revolves around the PSX version.  Keep up the good work, and I'm very glad to see the collaboration between yourself and other qhimm members!
 
Hey nfitc1, I have a soldier 1st class **da file and model (with Zack head and sword) that uses a controllable enemy **ab file (I have a Reno, rude, Rufus, dyne etc) taken from grimmys battle lgp in his shinra mod. The animations such as idle, attack, getting hit etc work fine, just needs a couple animations added, changed, could u help. Think ur the only person who can.
 
I did some things on enemies da and ab files, however if I could help you here depends on what exactly you want to do?

Badaway, thanks, Nfitc1. With the wiki and threads like this one I figured out many things I dreamt of.
 
hey quid when im casing magic he does the pose of soldier first class when casting sleepel n stuff but doesnt stick his arm out like the 1st class also give him magic cast pose for items and maybe change animation for 2x and 4x cut as soldier 1st class has 2 animations for these. but ive never hexed before so its really hard to understand.
 
But do you want this character to be playable and replace a other party member or is it a enemy in battle?

If it is to play it, you don't necessary need to do hexa code in ab and da files, but you will need the kimera tool.
The most simple way for this one, replace Cloud's head with your Zack head, then the not so simple but doable part if you have the patience, rework Cloud's animations in kimera so that your Zack won't just be a 'Cloud clone' when he move.

If your Zack is for a enemy to fight and you don't want him to look like a clone of the first class SOLDIER when he move, same thing, but if you want to add him new moves as well, then yes you will need to do some hexadecimal.

I can help in the second case with the hexa code, send me your Zack 1st class files and I will put him some new animations templates that you will then be able to reshape in kimera for item throwing or other new moves, with corresponding new 'ab sequences' that you will later link to in the scene.bin with proud clod tool, or I can explain how to do it yourself,  but the kimera part of the job you will have to learn as it's something that can take time, and most likely be ready to fail a few times before you get it right, I sure failed more than a few times on my end.

Ah, if it's for the first case, a playable Zack, I can't help you to add him new moves, none that will actually be selectable in game anyway, with the enemies you can control their moves\attacks and corresponding animations with the scene.bin, however for the playable characters it's different and I woudn't even be sure where to start to add a new selectable command, if you think of things like that.
But the playable characters already have all the required animations to work as such, except for Sephiroth who lack death, cover, 2X 4X cut, poses for inflicted status, and maybe a few more other animations, so I really recommend you to use a already playable character template for that case, and as I said just rework it's animations in kimera to fit whatever way you see Zack moves and style.
 
Hey quid, my Zack already uses the animations of soldier first class enemy and is controllable, I just need to link the **ab file to a couple things in the **da like I said, but I don’t know how to hex, kimera  won’t work I already have animation of soldier 1st class working so no need to edit the actual animations just need to link **ab file magic cast script etc to magic cast animation of the **da file I think.
 
Ok, I replaced the animations called for magic, E.skill, and summon in your ab file to match the sequence done by the SOLDIER 1st.
I also replaced the items throwing with a quick and unique animation, the number 9, before it was set to the idle anim 0.
I cheched the file structure, though quikly but it seem good enough to get through the game, except for the death anim call which call a animation that doesn't exist, the number 10 in hexa, so the 16 but as you might know, your template anims goes from 0 to 15.
And I don't think that stuffs like manip, d.blow and others are all pointed to fitting animations either, but I looked only quickly as I work on my mod, so you will tell me what else might need a repointer.

A playable character death anim is only one frame so it's really not that much to do in kimera, I can add you this new 16 animation in the da and all you would have to do would be to rework it in a single frame that match, but tell me if you want to do it. Otherwise, you could get through the game if you manage without your 'Zack\Cloud' ever falling to 0hp, or you will likely get a freeze or a crash when that happen.
A other, dirtier solution would just be to point the death anim call to the idle anim and that would at least prevent the crash or freeze.

And, ah yeah, I am not 100% sure that I isolated the X2\X4 sequence in your ab, they are slighty different that in the files I studied, I will have to test them to be sure, so I didn't touch them for now. Anyway, the ab file with magic and items repointed:
https://ufile.io/42dlkx0m
 
thank u so much buddy i really appreciate it, I will test it now. :)
 
Thats amazing m8 cant believe u done that so good, he now has the magic cast pose and that item cast is amazing just puts his hand out :) what about magic cast pose for limits and as for the 2x cut i was thinking animation 11 and 12 also 11 and 12 for victory pose maybe but im just happy with what uve done, amazing work.
 
Last edited:
also i noticed when hes attacking he goes through enemy slightly whereas when i used the rufus ab he jump attacked for normal attack animation but didnt go close enough to enemy. dont know if u know anything about this though.
 
Status
Not open for further replies.
Back
Top