BRP

From MultimediaWiki
Jump to navigation Jump to search

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