BFI: Difference between revisions
Jump to navigation
Jump to search
m (reorg games) |
(reveal the mystery) |
||
Line 9: | Line 9: | ||
bytes 8.. chunk payload | bytes 8.. chunk payload | ||
A BFI file begins with the following header: | A BFI file begins with the following 960 (0x3C0) bytes header: | ||
bytes 0-3 file signature: 'BF&I' | bytes 0-3 ( +0) file signature: 'BF&I' | ||
bytes 4-7 total file size | bytes 4-7 ( +4) total file size | ||
bytes 8-11 | bytes 8-11 ( +8) offset of the first frame in file | ||
bytes 12-15 frame count | bytes 12-15 ( +C) frame count | ||
bytes 16-43 unknown | bytes 16-19 ( +10) unknown | ||
bytes 44-47 video width | bytes 20-23 ( +14) largest frame chunk size | ||
bytes 48-51 video height | bytes 24-27 ( +18) unknown (perhaps video compression type) | ||
bytes 52-55 | bytes 28-31 ( +1C) framerate | ||
bytes 56-59 number of | bytes 32-43 ( +20) unknown | ||
bytes 60-827 256 RGB triplets (6-bit VGA palette values) | bytes 44-47 ( +2C) video width | ||
bytes 828-831 audio sample rate | bytes 48-51 ( +30) video height | ||
bytes 832-835 audio channels (?) | bytes 52-55 ( +34) first used palette entry index | ||
bytes 836-959 unknown | bytes 56-59 ( +38) number of used palette entries | ||
bytes 60-827 ( +3C) 256 RGB triplets (6-bit VGA palette values) | |||
bytes 828-831 (+33C) audio sample rate | |||
bytes 832-835 (+340) audio channels (?) | |||
bytes 836-959 (+344) unknown | |||
The media frames | The media frames started at file offset specified in bytes 4-7 of the header. Each frame is packaged inside a chunk with the fourcc 'IVAS' (possibly Interleaved Video and Sound). A IVAS chunk has the following payload: | ||
bytes 0-11 | bytes 0-3 ( +0) unknown (video compression type?) | ||
bytes 12-15 | bytes 4-7 ( +4) offset of the audio data (from chunk header!) | ||
bytes | bytes 8-11 ( +8) unknown (always zero) | ||
bytes | bytes 12-15 ( +C) offset of the video data (from chunk header!) | ||
bytes .. unsigned, 8-bit [[PCM]] audio data (size = offset_of_the_video - offset_of_the_audio) | |||
bytes .. encoded video data | |||
The | == Video compression == | ||
The video always encoded as palettized, 8-bit data. Single palette used for the entrie movie. Raster compression based on mixed [[LZ]] and [[RLE]] coding. | |||
Compressed stream begins with 4-byte value, representing final unpacked size of the data, then followed by compression codes. | |||
Decompression algo: | |||
read next byte of the input | |||
code = top two bits of the byte | |||
length = lower 6 bytes of the byte | |||
code is ... | |||
0 : normal chain | |||
if length is zero, read two more bytes of the length | |||
copy next (length) bytes of the input to the output | |||
1 : back chain | |||
if length is zero, read one more byte of the length AND two bytes of the offset | |||
else, read one byte of the offset | |||
copy (length) dwords from (output - offset) to the output | |||
(note, that data may overlap, so don't use memmove() function here, just bare by-dword copying!) | |||
2 : skip chain | |||
if length is zero, read two more bytes of the length | |||
if length still zero, finish the decompression | |||
leave (length) bytes of the output unchanged from the last frame | |||
3 : fill chain | |||
if length is zero, read two more bytes of the length | |||
color = next two bytes of the input | |||
fill (length) words of the output with (color) | |||
repeat until stop code encountered or whole output generated | |||
== Games Using BFI == | == Games Using BFI == |
Revision as of 05:21, 8 March 2007
- Extensions: bfi
- Company: Tsunami Media
- Samples: http://samples.mplayerhq.hu/game-formats/bfi/
Multimedia-heavy games by Tsunami use a multimedia format with the extension .bfi. All multi-byte numbers are little endian. The general FourCC chunk format is as follows:
bytes 0-3 chunk type bytes 4-7 chunk size, including 8-byte preamble bytes 8.. chunk payload
A BFI file begins with the following 960 (0x3C0) bytes header:
bytes 0-3 ( +0) file signature: 'BF&I' bytes 4-7 ( +4) total file size bytes 8-11 ( +8) offset of the first frame in file bytes 12-15 ( +C) frame count bytes 16-19 ( +10) unknown bytes 20-23 ( +14) largest frame chunk size bytes 24-27 ( +18) unknown (perhaps video compression type) bytes 28-31 ( +1C) framerate bytes 32-43 ( +20) unknown bytes 44-47 ( +2C) video width bytes 48-51 ( +30) video height bytes 52-55 ( +34) first used palette entry index bytes 56-59 ( +38) number of used palette entries bytes 60-827 ( +3C) 256 RGB triplets (6-bit VGA palette values) bytes 828-831 (+33C) audio sample rate bytes 832-835 (+340) audio channels (?) bytes 836-959 (+344) unknown
The media frames started at file offset specified in bytes 4-7 of the header. Each frame is packaged inside a chunk with the fourcc 'IVAS' (possibly Interleaved Video and Sound). A IVAS chunk has the following payload:
bytes 0-3 ( +0) unknown (video compression type?) bytes 4-7 ( +4) offset of the audio data (from chunk header!) bytes 8-11 ( +8) unknown (always zero) bytes 12-15 ( +C) offset of the video data (from chunk header!) bytes .. unsigned, 8-bit PCM audio data (size = offset_of_the_video - offset_of_the_audio) bytes .. encoded video data
Video compression
The video always encoded as palettized, 8-bit data. Single palette used for the entrie movie. Raster compression based on mixed LZ and RLE coding. Compressed stream begins with 4-byte value, representing final unpacked size of the data, then followed by compression codes.
Decompression algo:
read next byte of the input code = top two bits of the byte length = lower 6 bytes of the byte code is ... 0 : normal chain if length is zero, read two more bytes of the length copy next (length) bytes of the input to the output 1 : back chain if length is zero, read one more byte of the length AND two bytes of the offset else, read one byte of the offset copy (length) dwords from (output - offset) to the output (note, that data may overlap, so don't use memmove() function here, just bare by-dword copying!) 2 : skip chain if length is zero, read two more bytes of the length if length still zero, finish the decompression leave (length) bytes of the output unchanged from the last frame 3 : fill chain if length is zero, read two more bytes of the length color = next two bytes of the input fill (length) words of the output with (color) repeat until stop code encountered or whole output generated