Difference between revisions of "HAR File Format (.AF)"

From WTFwiki
Jump to navigation Jump to search
 
(15 intermediate revisions by 5 users not shown)
Line 39: Line 39:
 
=== Animation Header ===
 
=== Animation Header ===
 
{| border="1"
 
{| border="1"
|Unknown Data || 8 BYTES || Zero padding?
+
|X Start || 1 SIGNED WORD || Initial X position of sprite (unless spawned from another animation)
 +
|-
 +
|Y Start || 1 SIGNED WORD || Initial Y position of sprite (unless spawned from another animation)
 +
|-
 +
|Unknown Data || 4 BYTES || ??? - Seems to be [00 00 00 00] in all AF and BK files. Maybe just UDWORD null ?
 
|-
 
|-
 
|Overlay Amount || 1 WORD || TODO
 
|Overlay Amount || 1 WORD || TODO
Line 76: Line 80:
 
There then follow N sprites, where N is the frame count specified in the animation header, followed by the animation footer.
 
There then follow N sprites, where N is the frame count specified in the animation header, followed by the animation footer.
  
==== Sprite Header ====
+
See [[Sprite format]] for the format of the sprites.
 
 
{| border='1'
 
|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.
 
 
 
<!--
 
A table of loaded sprite data is maintained. Each loaded frame with a non-zero index is stored into the table in entry number (index + frame number). When the sprite loading code is called, if the g_indexOfReusedSprite value is not -1, and the loaded sprite has ''data missing'' == 0, ''width'' != 0, ''index'' != 0, the data in the file apart from the index will be ignored, and the sprite at the corresponding index in the reuse table will be used instead.
 
-->
 
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
 
<ol start="0">
 
<li>Set X to DATA</li>
 
<li><ul><li>While DATA is greater than 0</li><ul><li>Read 1 BYTE</li><li>Store that byte as the pixel at X,Y in the sprite</li><li>Increment X</li><li>Decrement DATA</li></ul></ul></li>
 
<li>Set Y to DATA</li>
 
<li>End of sprite data</li>
 
</ol>
 
  
 
== Move Footer ==
 
== Move Footer ==
Line 146: Line 111:
 
|Unknown 13|| 1 BYTE|| Next animation to play?
 
|Unknown 13|| 1 BYTE|| Next animation to play?
 
|-
 
|-
|Unknown 14|| 1 BYTE||
+
|Unknown 14|| 1 BYTE|| Animation Category
 +
* 0 - Misc.
 +
* 2 - Close Quarters/Throw
 +
* 4 - Crouching?
 +
* 5 - Standing?
 +
* 6 - Standing? Walking backward?
 +
* 7 - Airborne
 +
* 8 - Projectile
 +
* 9 - Basic
 +
* 11 - Victory/Defeat
 +
* 12 - Scrap
 +
* 13 - Destruction
 +
 
 +
These are just educated guesses, but they are definitely used by OMF to decide which animation to play when a player uses a specific key combo.
 
|-
 
|-
|Unknown 15|| 1 BYTE|| [[HAR_File_Format#Animation_Categories|Animation categories]]
+
|Unknown 15|| 1 BYTE||
 
|-
 
|-
 
|Unknown 16|| 1 BYTE|| Stamina damage?
 
|Unknown 16|| 1 BYTE|| Stamina damage?
Line 169: Line 147:
 
|}
 
|}
  
==Fighter Footer==
+
==Footer==
  
 
{|border='1'
 
{|border='1'
|Junk? || 30 BYTES || The first 9 bytes of this are always 0. Bytes 0x19-0x1B are ignored and overwritten.
+
|Unknown || 1 BYTE || ??? - 0 in all known AF/BK files. An animation tag of 's0' does not seem to play the sound stored in this byte.
 +
|-
 +
|Sounds || 29 BYTES(?) || Sound mapping table - when an animation string contains a tag like 's<n>', OMF looks at the Nth element of this table, which contains the ID of the sample to play from SOUNDS.DAT (numbered starting from 1, not 0). For example, INTRO.BK contains multiple instances of the 's1' tag. Position 1 in this table for INTRO.BK contains '15', which is the ID of the thunderclap sound in SOUNDS.DAT.
 +
 
 +
For all known AF files, the last 5 bytes are FGHED, which correspond to sounds 70, 71, 72, 69 and 68.
 
|}
 
|}
  

Latest revision as of 18:16, 8 January 2013

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. Multiplied by 3.6 after loading
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. Outside tournament mode, used value = 256 * (upward speed / 256 + jump height (in advanced menu) / 100)
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

There then follow a number of blocks. Each block starts with a one byte animation number.

Animation Number 1 BYTES Unique Identifier for animation (less than 70), end of animations (>= 70)

If this value is less than 70, then an Animation and a Move footer follows. A value of 70 or higher marks the end of animations, and the fighter footer follows.

Animation

Animation Header

X Start 1 SIGNED WORD Initial X position of sprite (unless spawned from another animation)
Y Start 1 SIGNED WORD Initial Y position of sprite (unless spawned from another animation)
Unknown Data 4 BYTES ??? - Seems to be [00 00 00 00] in all AF and BK files. Maybe just UDWORD null ?
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, followed by the animation footer.

See Sprite format for the format of the sprites.

Move Footer

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 Animation Category
  • 0 - Misc.
  • 2 - Close Quarters/Throw
  • 4 - Crouching?
  • 5 - Standing?
  • 6 - Standing? Walking backward?
  • 7 - Airborne
  • 8 - Projectile
  • 9 - Basic
  • 11 - Victory/Defeat
  • 12 - Scrap
  • 13 - Destruction

These are just educated guesses, but they are definitely used by OMF to decide which animation to play when a player uses a specific key combo.

Unknown 15 1 BYTE
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

Footer

Unknown 1 BYTE ??? - 0 in all known AF/BK files. An animation tag of 's0' does not seem to play the sound stored in this byte.
Sounds 29 BYTES(?) Sound mapping table - when an animation string contains a tag like 's<n>', OMF looks at the Nth element of this table, which contains the ID of the sample to play from SOUNDS.DAT (numbered starting from 1, not 0). For example, INTRO.BK contains multiple instances of the 's1' tag. Position 1 in this table for INTRO.BK contains '15', which is the ID of the thunderclap sound in SOUNDS.DAT.

For all known AF files, the last 5 bytes are FGHED, which correspond to sounds 70, 71, 72, 69 and 68.

Sample Implementations

Sample python parser for .af and .bk files

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 is 250 for all known AF files, and is required to be >= 70.
  • The last 5 bytes in the file are the string 'FGHED'. This is the case for all known AF files.