HAR File Format (.AF)
The AF files contain all the information related to HARs; sprites, key-combos, projectile sprites, base damage, etc. The format is not entirely understood but a large portion has been dissected and understood. All AF files are broken up into the following sections:
Fighter Header
This contains the basic data about the HAR. Unmodified speeds, endurance, power, etc.
HAR Number | 1 WORD | Must be the same number as in the filename eg: FIGHTR1.AF |
Unknown Data | 2 bytes | ? Always 10 |
Endurance | 4 bytes | Max is 548,801,280. Above or below that results in permanantly stunned state. |
Unknown Data | 1 byte | ? Always 1 or 2 |
Power | 1 WORD | Damage Resistance, max is 8717. |
Forward Speed | 1 signed DWORD | Speed at which the HAR moves towards opponent |
Backward Speed | 1 signed DWORD | Speed at which HAR retreats from opponent |
Upward Speed | 1 signed DWORD | Initial jump speed, this should be negative |
Downward Speed | 1 signed DWORD | How quickly the HAR falls while being airborne, should be positive |
Unknown Data | 1 byte | ? Always 0x32 |
Unknown Data | 1 byte | ? Always 0x14 |
Animation
When reading in an animation, check if the next byte (the Animation Number) is less than 70. If its not less than 70, read in the fighter footer instead.
Animation Header
Animation Number | 1 BYTES | Unique Identifier for animation (less than 70) |
Unknown Data | 8 BYTES | Zero padding? |
Overlay Amount | 1 WORD | TODO |
Frame Count | 1 BYTE | How many frames in this animation |
Overlay Table | N DWORDS | TODO |
Animation String Header
String Length | 1 WORD | Length of the string |
String | N BYTES | Animation string |
Unknown Data | 1 BYTE | Nul terminator |
Number of Extra Strings | 1 BYTE | How many other animation strings there are |
There then follow N extra animation strings, where N was the number specified in the Animation String Header. The extra strings are stored as follows:
Extra Animation Strings
String Length | 1 WORD | Length of string |
String | N BYTES | Extra Animation String |
Unknown Data | 1 BYTE | Nul terminator |
Sprites
There then follow N sprites, where N is the frame count specified in the animation header.
Sprite Header
Length | 1 WORD | Length of sprite |
X Position | 1 SIGNED WORD | TODO |
Y Position | 1 SIGNED WORD | TODO |
Width | 1 WORD | Width of the sprite, in pixels |
Height | 1 WORD | Height of the sprite, in pixels |
Index | 1 BYTE | Index of the sprite in already-loaded images table |
Data missing | 1 BYTE | See below |
For animations 12, 13 and 14, the index field will be treated as if it were 0. If the index is 0, the data missing field will be treated as if it were 0.
If the data missing flag is zero, the sprite data will follow the sprite header, as length BYTEs. In either case, element index of the sprite reuse table is consulted. If that element is present, or if no graphics data were present in the file, the data from the sprite reuse table are used. Otherwise, that slot in the table is filled with the image data just read from the file.
Sprite Data
The sprite data is decoded thusly:
- Initalize X and Y to 0
- Read 1 WORD as P
- Modulus P by 4 to get OPCODE
- Integer divide P by 4 to get DATA
- Compare the OPCODE against the following and take that action
- Set X to DATA
- While DATA is greater than 0
- Read 1 BYTE
- Store that byte as the pixel at X,Y in the sprite
- Increment X
- Decrement DATA
- Set Y to DATA
- End of sprite data
The first 21 bytes of the animation footer have an unknown purpose. Some possiblities are listed.
Unknown 1 | 1 BYTE | |
Unknown 2 | 1 BYTE | |
Unknown 3 | 1 BYTE | Seems to be related to airborne attacks, possibly constraints for positioning (near wall, etc) |
Unknown 4 | 1 BYTE | |
Unknown 5 | 1 BYTE | |
Unknown 6 | 1 BYTE | |
Unknown 7 | 1 BYTE | |
Unknown 8 | 1 BYTE | |
Unknown 9 | 1 BYTE | |
Unknown 10 | 1 BYTE | |
Unknown 11 | 1 BYTE | |
Unknown 12 | 1 BYTE | |
Unknown 13 | 1 BYTE | Next animation to play? |
Unknown 14 | 1 BYTE | |
Unknown 15 | 1 BYTE | Animation categories |
Unknown 16 | 1 BYTE | Stamina damage? |
Unknown 17 | 1 BYTE | Seems to be related to throws, maybe velocity of victim? |
Unknown 18 | 1 BYTE | Damage (Value divided by 2.0) |
Unknown 19 | 1 BYTE | |
Unknown 20 | 1 BYTE | |
Unknown 21 | 1 BYTE | ? Multiplied by 4 after loading |
Move String | 21 BYTES | Move String NULL terminated (trailing data after the first NULL seems to be reusable to label animations) |
Footer String Length | 1 WORD | Length of footer string |
Footer String Length | N BYTES | Footer string |
Magic Number | 1 BYTE | Always 250 (indicates end of animations) |
Filler? | 9 BYTES | ? |
Footer Length | 1 WORD | - |
Footer | N BYTES | ?? |
Magic Numbers
To check if a file is a valid AF file, there are 2 magic sequences you can check for:
- Seek to the -31st byte (the 31st byte before the end of the file). The value MUST be 250.
- The last 5 bytes in the file are the string 'FGHED'. This is the case for all known AF files.