Call of Duty 4: FastFile Format

From COD Modding & Mapping Wiki
Jump to navigation Jump to search

*** Article and investigation in early progress ***

Preface

Be aware, FF files are little endian, so swap those bytes 'round!

The global file layout starts with a header. After which you get a list a model tag names, after which you get an index list. This list gives information about the rest of the file, which is a concatenation of files, most of which are reinterpreted. Each file is separated by the separation key: 0xFFFFFFFF. But be aware, each file itself can also contain such a sequence which is not meant to be the separation key! So it is necessary to understand each data type in the FF file.

Header

  • Byte 0-3: decompressed fastfile size minus 44 (0x2C)
  • Byte 4-7: about the total size of referenced data, e.g. the required memory for IWI textures if material files are in the ff
  • Byte 8-11: unknown, might be a flag
  • Byte 12-23: unknown
  • Byte 24-27: somehow related to ff size?
  • Byte 28-43: unknown
  • Byte 44-47: equal to number of entries in "1st index" and amount of (model tag/joint/notetrack) strings (times 4 for index length)
  • Byte 48-51: separator? (FF FF FF FF)
  • Byte 52-55: number of records* ("2nd index", times 8 for index length)
  • Byte 56-63: separator? (FF FF FF FF FF FF FF FF)
  • Byte 64-x: string list (xmodelsurfs?) --> not always, depends on the content (required offsets are in the FF header)*

* under re-investigation


Example: mp_backlot_load.ff

Contains:

  • 2x shaders
  • 3x materials
  • (1x fastfile name)


Materials:

  1. $victorybackdrop - mile_high_victory_screen.iwi (699,092 bytes)
  2. $defeatbackdrop - (none)
  3. $levelbriefing - loadscreen_mp_backlot.iwi (524,316 bytes)
-----------  [start of file and header]

71 03 00 00  Decompressed file size - 44 (hex: 371 + 2C = 39D; dec: 881 + 44 = 925)

B8 AA 12 00  Size of both IWI's the materials in FF point to - 56 (2x28, 28 bytes = IWI header)
             0x12AAB8          = 1,223,352
             699,092 + 524,316 = 1,223,408
             difference:                56

A4 00 00 00  Might be a flag

00 00 00 00  Unknown
00 00 00 00  Unknown
00 00 00 00  Unknown
E5 00 00 00  Size of fastfile in memory (that is at least without header and separators, and maybe more)
00 00 00 00  Unknown
00 00 00 00  Unknown
00 00 00 00  Unknown
00 00 00 00  Unknown

-----------  [end of header] (44 bytes), [start of index]

00 00 00 00  Unknown, is sometimes FF FF FF FF

06 00 00 00  Number of records in index (6)
FF FF FF FF  Separator

05 00 00 00  FF FF FF FF  1st: shader
05 00 00 00  FF FF FF FF  2nd: shader
04 00 00 00  FF FF FF FF  3rd: material
04 00 00 00  FF FF FF FF  4th: material
04 00 00 00  FF FF FF FF  5th: material
1F 00 00 00  FF FF FF FF  6th: rawfile
FF FF FF FF  Separator

-----------  [end of index]

Index

4 byte identifier (fastfile entry type), 4 byte offset (FF FF FF FF = -1, meaning right after the previous block?)

Separator (FF FF FF FF) after last 4-byte couple + 00 00 00 00 ?

Types

  • 00 00 00 01 - physpreset
  • 00 00 00 02 - xanim
  • 00 00 00 03 - xmodel
  • 00 00 00 04 - material
  • 00 00 00 05 - shader / techset
  • 00 00 00 06 - image?
  • 00 00 00 0B - map_ents (d3dbsp)
  • 00 00 00 0C - related to col_map_mp (d3dbsp)
  • 00 00 00 0E - related to game_map_mp (d3dbsp)
  • 00 00 00 10 - related to col_map_mp / gfx_map (d3dbsp)
  • 00 00 00 13 - font
  • 00 00 00 14 - menu
  • 00 00 00 16 - localized string asset
  • 00 00 00 17 - physpreset??
  • 00 00 00 19 - fx
  • 00 00 00 1F - raw file
  • 00 00 00 20 - stringtable (comma separated list)

Content

00 00 00 04

-----------  [start separation]

00 2B 01 01  First 4 bytes seem to be 4 (unsigned) char's.
             1st byte is so far always 0x00 (perhaps it's a short together with the second byte).
             2nd byte so far either 0x2B or 0x00, I think this is a length.
             3rd byte so far 0x01, when 0x00 (all 4) the content is only a number of 0x00's, then the filename (0x00 termination)
             4th byte either 0x00 or 0x01. Can be a length or a bool.
             Then 0x10 bytes of more header.
FF FF FF FF  Separator
00           When fourth byte is 01, there's a 0x00 following?             
             Then there's garbage (0xFF) and some shorts it looks of length in the second byte.
             Then more information...
02 00 0E E0  Often ends with this

-----------  [end separation]

00 00 00 05 (shader)

A shader consists of 3 levels. One, the top level, consists of a header (with a name inside). Then the next level is a pack of shaders, it has a header, shaders and at the end a name. Then the bottom level is the shader itself, it has a header (containing a name of the source file and the length of the data) and the raw shader data.

-----------  [start separation]

00 00 00 00  0x24 dwords of 0x00000000 and sometimes 0xFFFFFFFF (looks like 3x 0x30 in length)
?? ?? .. 00  Then (file) name (0x00 termination)

-----------  [start of shader pack]

             1 dword of reference? (sometimes 2)
             1 dword of some character length options / flags?
             3 dwords of references?
             1 dword of some character length options / flags?
FF FF FF FF  Separator
             0x19 dwords of some short length options / flags? For the first 05 entry? Or if the references above are 0xFFFFFFFF?
FF FF FF FF  Separator for the first 05 entry? Or if the references above are 0xFFFFFFFF?

-----------  [start of shader]

             2 dwords of references
FF FF FF FF  Separator
?? ?? 00 00  2 shorts, first short multiplied by 4 gives the length of the shader, second is a flag? When set no string follows?
?? ?? .. 00  String if previous second short is 00 00, 0x00 terminated (name of source file)
             Raw shader file (except the first 4 bytes, which, in the shader file, denotes the length of the file)
FF FF 00 00  which ends with this (always?)

-----------  [end of shader]

             Can either have more shaders (go back to [start of shader]) or shaders have ended

             Variable length of 'stuff' (often 0x08 (last shader pack) or 0x64 in length)
?? ?? .. 00  String, 0x00 terminated (probably in-game usage name)

-----------  [end of shader pack]

             Can either have more shader packs (go back to [start of shader pack]) or shader packs have ended

-----------  [end separation]

00 00 00 1F (rawfile)

A rawfile. Often a rawfile named right after the fastfile's name is implicitly added. It contains the errors thrown when it was compiling / linking.

-----------  [start separation]

64 00 00 00  Length of the file's content (example: decimal 100; does not count the string termination!)

FF FF FF FF  Separator

6D 6F 64 00  File name or if it's the last 1F-block FastFile name (example: mod.)
?? ?? .. 00  Plain text content of length above (string, terminated by 0x00)

-----------  [end separation OR end of file]

--CoDEmanX 22:09, 4 November 2009 (UTC)

--Daevius 14:24, 5 November 2009 (UTC)