BRP: Difference between revisions

From MultimediaWiki
Jump to navigation Jump to search
(Video chunks and audio; removed part about AO and MAD1 as it also uses ALCD/AVCF)
(link fix)
 
(10 intermediate revisions by 5 users not shown)
Line 1: Line 1:
* Extensions: BRP
* Extensions: brp
* Company: [[Argonaut Games]]
* Company: [[Argonaut Games]]
* Samples:
** Alien Odyssey: [http://samples.mplayerhq.hu/game-formats/brp/alienodyssey/ http://samples.mplayerhq.hu/game-formats/brp/alienodyssey/]
** FX Fighter: [http://samples.mplayerhq.hu/game-formats/brp/fxfighter/ http://samples.mplayerhq.hu/game-formats/brp/fxfighter/]


At least 2 games use an animation format with the extension .brp: [http://www.mobygames.com/game/dos/fx-fighter FX Fighter] and [http://www.mobygames.com/game/dos/alien-odyssey Alien Odyssey], both by Argonaut. The general container formats used in both games are similar, but differing fourccs inside may indicate that the games used different video coding algorithms (which are presently unknown).
At least 2 games use an animation format with the extension .brp: [http://www.mobygames.com/game/dos/fx-fighter FX Fighter] and [http://www.mobygames.com/game/dos/alien-odyssey Alien Odyssey], both by Argonaut. The general container formats used in both games are similar, but differing fourccs inside may indicate that the games used different video coding algorithms (which are presently unknown). All multi-byte numbers are little endian.


All multi-byte numbers are little endian. The fourcc chunk format is as follows:
== File Format ==


  bytes 0-3    chunk size, not including 12-byte preamble
BRP files consist of multi-stream chunks, where video and audio located in separate, but interleaved streams.
  bytes 4-7    chunk type
  bytes 8-11  unknown
  bytes 12..   chunk payload


A BRP file begins with the following header:
File begins with following 12-byte header:
  dword signature - "BRPP"
  dword streams  - number of streams in file
  dword unknown  - unknown, but equal to 640*480


  bytes 0-3    file signature: 'BRPP'
File header followed by stream headers:
   bytes 4-7    version number
   dword signature      - stream [[FOURCC]]
   bytes 8-11  unknown, but always seems to be 307200 in decimal which,
   dword index          - logical index of the stream
              for trivia, is the product of 640 * 480
   dword unknown1        -
   bytes 12-15  fourcc: 'BVID', possibly a file sub-type
   dword unknown2        -
   bytes 16-31  unknown
   dword plsize          - size of the following payload data
   bytes 32-35  total number of video frames in file
   byte payload[plsize] - stream-specific payload
   bytes 36-39 video width
  bytes 40-43  video height
  bytes 44-47  possibly video depth (8-bit, palettized video)


There are 2 known versions: 1 and 2. The version 1 file proceeds as follows:
Finally, actual data chunks follows, each one starts with chunk header:
  dword index      - logical index of the stream chunk belongs to
  dword unknown
  dword size      - size of the chunk data
  byte  data[size] - stream-specific chunk data


   bytes 48-55  unknown
== Streams ==
=== BVID Stream ===
The video stream. Stream header payload:
  dword unknown1
  dword width    - width of the frame
  dword height   - height of the frame
  dword unknown2


A version 2 file header proceeds with a BASF chunk which appears to have an unknown 8-byte payload. This is followed by a 'ASF\0' chunk which has an 0x18-byte payload. Bytes 8-15 of this payload appear to be the 8 bytes of the DOS base filename (e.g., file 'foo.brp' would contain 'foo' with 5 0s after). The rest of the payload is unknown. The next 4 bytes of a v2 header contains the length of the remainder of the header, minus 12 bytes. An audio sample rate sits occupies 2 bytes in the space 16 bytes after these four bytes. The rest of the header is unknown. However, the presence of what looks like an audio sampling rate strongly indicates that these files carry audio data.
Each BVID's chunk data started with another [[FOURCC]], indicates chunk format:
==== PAL8 Chunk ====
  word start          - first color to update
  word count          - number of colors to update
  byte rgb[count * 3] - [[RGB]] triplets


Following the header is a 'PAL8' chunk (presumably, this would only occur in a 8-bit file if other bit depth files exist). This chunk contains full 8-bit RGB palette triplets.
==== AVCF Chunk ====


The video frames follow the header and palette chunk. In F/X Fighter, there are 2 frame types: AVCF and ALCD. Based on their relative occurrence frequencies, AVCF frames may be intracoded while ALCD frames
Intraframe 2x2 [[VQ]], similar to one used in [[AVS]].
are intercoded.


The following chunk types are currently known:
==== ALCD Chunk ====


  PAL8            8-bit palette, range 0-255
Interframe 2x2 [[VQ]], similar to one used in [[AVS]].
   MAD1           contains sub-chunks using different codecs like RLE-compression
 
  AVCF            vector quantized keyframe (similar to the algorithm used in Creature Shock)
==== RLED, RLEF Chunks ====
  ALCD            vector quantized deltaframe
 
 
Rle-compressed frame.
In the examined files only either the MAD1 or the AVCF/ALCD types are used throughout one file.
   while not all output processed
    count = next byte of the input
    pixel = next byte of the input
    if count is zero
      skip (pixel) bytes of ouput
    else
      fill count of bytes of output with pixel
 
==== MAD1 Chunk ====
 
'''TODO'''
 
This chunk type is made up of several subchunks. Each subchunk is identified by a single byte after which the subchunk data follows. Note that the size of each subchunk is not stored, you need to correctly process each subchunk to get to the next one.
 
These subchunk types are currently known:
 
* 0x02: RLE-type algorithm
* 0x03: unknown, first two bytes are some size (of output?)
* 0x05: half-resolution frame, scaled to full resolution (e.g. for a 320x200 BRP this would be 160x100 pixels upscaled to 320x200)
* 0x06: full frame, read width*height bytes of data
* 0x07: block copy / motion vectors
* 0xFF: marks end of MAD1 chunk
 
===== 0x02 algorithm =====
 
  while input left
    get a byte from the input
    count = upper 2 bits of the byte
    skip = lower 6 bits of the byte
    if skip is 0x3F, skip 0x3E pixels in the output buffer
    else
      skip 'skip' pixels in the output buffer
      while count is greater than zero
        get a byte from the input as 'bitbuffer'
        repeat the following four times
          get next 2 bits from 'bitbuffer' ('bitbuffer' & 3) as 'code'
          do one of the following according to 'code'
            0: skip the next pixel in the output buffer
            1: repeat the last output pixel
            2: copy the pixel from output[output_positon - width] to the output buffer
            3: copy next pixel from the input buffer
 
=== BASF Stream ===
Audio Stream. Stream header payload:
 
'''TODO'''
 
Audio is compressed using one- or two-point [[PCM#Differential_PCM|DPCM]].
Samples chunk starts with the following header:
  dword unknown1
  dword unknown2
  dword unknown3
  dword unknown4
  dword unknown5
 
Header continues with one or more encoded 64 samples blocks. Each 64 samples broken on two 32-sample groups, each group holds signed 4-bit delta nibbles of even and odd samples respectively (or left and right channel ones in case of stereo sound). Single 32-samples block occupy 17 bytes and have following layout:
  bits 0..1 unused
          2 flag      - non-zero value indicates two-point [[PCM#Differential_PCM|DPCM]]
          3 unused
      4..7 scale    - delta scale factor
    8..135 nibbles[] - 32 4-bit nibbles, first nibble in bits 4..7 of the byte and second - bits 0..3, etc.
 
For one-point encoding each new sample calculated using this simple formula:
  sample[n] = ((sample[n - 1] << 4) + (nibble << scale)) >> 4


Details of the audio compression scheme are currently unknown. The audio chunks are apparently not preceeded by an ASCII chunk type name.
Two-point scheme takes in to account two previous samples:
  sample[n] = ((sample[n - 1] << 5) - (sample[n - 2] << 4) + (nibble << scale)) >> 4
    
    
[[Category:Game Formats]]
[[Category:Game Formats]]

Latest revision as of 16:58, 31 August 2006

At least 2 games use an animation format with the extension .brp: FX Fighter and Alien Odyssey, both by Argonaut. The general container formats used in both games are similar, but differing fourccs inside may indicate that the games used different video coding algorithms (which are presently unknown). All multi-byte numbers are little endian.

File Format

BRP files consist of multi-stream chunks, where video and audio located in separate, but interleaved streams.

File begins with following 12-byte header:

 dword signature - "BRPP"
 dword streams   - number of streams in file
 dword unknown   - unknown, but equal to 640*480

File header followed by stream headers:

 dword signature       - stream FOURCC
 dword index           - logical index of the stream
 dword unknown1        -
 dword unknown2        -
 dword plsize          - size of the following payload data
 byte  payload[plsize] - stream-specific payload

Finally, actual data chunks follows, each one starts with chunk header:

 dword index      - logical index of the stream chunk belongs to
 dword unknown
 dword size       - size of the chunk data
 byte  data[size] - stream-specific chunk data

Streams

BVID Stream

The video stream. Stream header payload:

  dword unknown1
  dword width    - width of the frame
  dword height   - height of the frame
  dword unknown2

Each BVID's chunk data started with another FOURCC, indicates chunk format:

PAL8 Chunk

 word start          - first color to update
 word count          - number of colors to update
 byte rgb[count * 3] - RGB triplets

AVCF Chunk

Intraframe 2x2 VQ, similar to one used in AVS.

ALCD Chunk

Interframe 2x2 VQ, similar to one used in AVS.

RLED, RLEF Chunks

Rle-compressed frame.

 while not all output processed
   count = next byte of the input
   pixel = next byte of the input
   if count is zero
     skip (pixel) bytes of ouput
   else
     fill count of bytes of output with pixel

MAD1 Chunk

TODO

This chunk type is made up of several subchunks. Each subchunk is identified by a single byte after which the subchunk data follows. Note that the size of each subchunk is not stored, you need to correctly process each subchunk to get to the next one.

These subchunk types are currently known:

  • 0x02: RLE-type algorithm
  • 0x03: unknown, first two bytes are some size (of output?)
  • 0x05: half-resolution frame, scaled to full resolution (e.g. for a 320x200 BRP this would be 160x100 pixels upscaled to 320x200)
  • 0x06: full frame, read width*height bytes of data
  • 0x07: block copy / motion vectors
  • 0xFF: marks end of MAD1 chunk
0x02 algorithm
 while input left
   get a byte from the input
   count = upper 2 bits of the byte
   skip = lower 6 bits of the byte
   if skip is 0x3F, skip 0x3E pixels in the output buffer
   else
     skip 'skip' pixels in the output buffer
     while count is greater than zero
       get a byte from the input as 'bitbuffer'
       repeat the following four times
         get next 2 bits from 'bitbuffer' ('bitbuffer' & 3) as 'code'
         do one of the following according to 'code'
           0: skip the next pixel in the output buffer
           1: repeat the last output pixel
           2: copy the pixel from output[output_positon - width] to the output buffer
           3: copy next pixel from the input buffer

BASF Stream

Audio Stream. Stream header payload:

TODO

Audio is compressed using one- or two-point DPCM. Samples chunk starts with the following header:

 dword unknown1
 dword unknown2
 dword unknown3
 dword unknown4
 dword unknown5

Header continues with one or more encoded 64 samples blocks. Each 64 samples broken on two 32-sample groups, each group holds signed 4-bit delta nibbles of even and odd samples respectively (or left and right channel ones in case of stereo sound). Single 32-samples block occupy 17 bytes and have following layout:

 bits 0..1 unused
         2 flag      - non-zero value indicates two-point DPCM
         3 unused
      4..7 scale     - delta scale factor
    8..135 nibbles[] - 32 4-bit nibbles, first nibble in bits 4..7 of the byte and second - bits 0..3, etc.

For one-point encoding each new sample calculated using this simple formula:

 sample[n] = ((sample[n - 1] << 4) + (nibble << scale)) >> 4

Two-point scheme takes in to account two previous samples:

 sample[n] = ((sample[n - 1] << 5) - (sample[n - 2] << 4) + (nibble << scale)) >> 4