Legend Entertainment Q: Difference between revisions

From MultimediaWiki
Jump to navigation Jump to search
(fill some known details)
 
(update description)
Line 15: Line 15:
   4 bytes - offset to the frame data (palette and optional method signalling chunks are stored before that offset)
   4 bytes - offset to the frame data (palette and optional method signalling chunks are stored before that offset)
   1 byte  - frames per second
   1 byte  - frames per second
   3 bytes - ignored
   1 byte  - ignored
  2 bytes - some audio flags
   2 bytes - unknown
   2 bytes - unknown
   4 bytes - audio chunk size
   4 bytes - audio chunk size
Line 29: Line 30:
* <code>1</code> - VGA palette
* <code>1</code> - VGA palette
* <code>2</code> - video frame
* <code>2</code> - video frame
* <code>3</code> - video frame (probably with additional coordinates to update just the part of image)
* <code>3</code> - video frame (with additional coordinates to update just the part of image)
* <code>4</code> - video frame (probably with additional coordinates to update just the part of image)
* <code>4</code> - video frame (with additional coordinates to update just the part of image)
* <code>5</code> - up to 128 most common 16-bit patterns used by the following frames
* <code>5</code> - up to 128 most common 16-bit patterns used by the following frames
* <code>6</code> - a marker signalling different decoding algorithm (chunk size should be ignored)
* <code>6</code> - a marker signalling different decoding algorithm (chunk size should be ignored)
* <code>7</code> - a marker signalling different decoding algorithm (chunk size should be ignored)
* <code>7</code> - a marker signalling different decoding algorithm (chunk size should be ignored)
* <code>8</code> - RIFF WAV header
* <code>8</code> - RIFF WAV header
* <code>9</code> - unknown, probably another video frame chunk
* <code>9</code> - first part of interlaced frame (version 5 only)
* <code>10</code> - padding?
* <code>10</code> - padding?
* <code>11</code> - unknown, probably another video frame chunk
* <code>11</code> - second part of interlaced frame (version 5 only)


== Video compression ==
== Video compression ==
Line 43: Line 44:
Video frame is compressed as a sequence of 4x4 blocks using mainly [[Block Truncation Coding]] and reusing other frame blocks (either by not updating it or by copying some other frame block). The compressed data is essentially a stream of opcodes that tell how to decode the following block (or several blocks).
Video frame is compressed as a sequence of 4x4 blocks using mainly [[Block Truncation Coding]] and reusing other frame blocks (either by not updating it or by copying some other frame block). The compressed data is essentially a stream of opcodes that tell how to decode the following block (or several blocks).


Opcodes:
Opcodes (version 3):
 
* <code>xx xx (xx < 0xF8)</code> - fill the block with <code>xx</code> value
* <code>xx yy pppp (xx < 0xF8)</code> - fill the block using the 16-bit pattern <code>pppp</code> (top bit first) and colours <code>xx</code> and <code>yy</code>
* <code>0xF8</code> - TODO
* <code>0xF9 nn</code> - depending on previous block type either repeat previous block <code>nn</code> times or skip block <code>nn</code> times
* <code>0xFA nnnn</code> - copy the block after the current one using offset <code>nnnn</code>
* <code>0xFB nnnn</code> - copy the block before the current one using offset <code>nnnn</code>
* <code>0xFC yx</code> - copy the block using the motion vector with each nibble corresponding to the value in this table: <code>{ 0, 4, 8, 12, 16, 20, 24, 28, -32, -4, -8, -12, -16, -20, -24, -28 }</code>
* <code>0xFD nn</code> - copy the block after the current one using offset <code>nn</code>
* <code>0xFE nn</code> - copy the block before the current one using offset <code>nn</code>
* <code>0xFF</code> - leave the block unchanged
 
Opcodes (version 4 and 5):


* <code>xx xx (xx < 0xF8)</code> - fill the block with <code>xx</code> value
* <code>xx xx (xx < 0xF8)</code> - fill the block with <code>xx</code> value
Line 49: Line 63:
* <code>xx yy pppp (xx < 0xF8, pppp >= 0x8000)</code> - fill the block using the 16-bit pattern <code>pppp</code> (top bit first) and colours <code>xx</code> and <code>yy</code>
* <code>xx yy pppp (xx < 0xF8, pppp >= 0x8000)</code> - fill the block using the 16-bit pattern <code>pppp</code> (top bit first) and colours <code>xx</code> and <code>yy</code>
* <code>0xF8</code> - TODO
* <code>0xF8</code> - TODO
* <code>0xF9 nn</code> - repeat previous block <code>nn</code> times
* <code>0xF9 nn</code> - depending on previous block type either repeat previous block <code>nn</code> times or perform the same motion compensation as the previous block
* <code>0xFA nnnn</code> - copy the block at absolute 16-bit position <code>nnnn</code>
* <code>0xFA nnnn</code> - copy the block at absolute 16-bit position <code>nnnn</code>
* <code>0xFB</code> - see below
* <code>0xFB</code> - see below
Line 58: Line 72:


=== 0xFB opcode methods ===
=== 0xFB opcode methods ===
Depending on initialisation chunk (e.g. chunk type 7 being present in the beginning) this opcode invokes a different unpacking method.
Depending on initialisation chunk or version and frame type (version 4 with chunk type 7 being present in the beginning or version 5 for frame types 9 and 11 for mode 7, mode 6 otherwise) this opcode has a different meaning.
 
In either case it contains a number of blocks to process (two or more) and each block is processed in the same way.
 
==== Repeat block type sequence (mode 6) ====


==== Pattern blocks sequence (default?) ====
Depending on previously decoded block type a different action should be taken:


The following blocks contain only a 8- or 16-bit pattern (<code>00..7F</code> for pattern index <code>8000..FFFF</code> for actual pattern) and reuse colours from the last pattern block.
* fill block - read a one byte fill value for the current block
* 8-bit pattern block - read 8- or 16- pattern for the current block, reuse colours from the reference block
* 16-bit pattern block - read 16-bit pattern for the current block, reuse colours from the reference block
* various motion compensation block types - read the same data type (1-byte offset, 2-byte index, 1-byte motion vector code) and perform motion compensation


==== Raw blocks sequence (when chunk 7 is present) ====
==== Raw blocks sequence (mode 7) ====


If the data starts with byte value less than <code>0xF8</code> then the following 16 bytes are copied into the output block, otherwise fill block with several colours depending on the code:
If the data starts with byte value less than <code>0xF8</code> then the following 16 bytes are copied into the output block, otherwise fill block with several colours depending on the code:
Line 72: Line 93:
* <code>0xFA</code> - fill the block using 32-bit pattern (with 2 bits per pixel) and following 4 colours
* <code>0xFA</code> - fill the block using 32-bit pattern (with 2 bits per pixel) and following 4 colours
* <code>0xFB</code> - fill the block using 2x24-bit pattern (3 bits per pixel, each 4x2 block has its own 24-bit pattern) and following 5 colours
* <code>0xFB</code> - fill the block using 2x24-bit pattern (3 bits per pixel, each 4x2 block has its own 24-bit pattern) and following 5 colours
* <code>0xFC</code> - fill the block using 2x24-bit pattern and following 6 colours
* <code>0xFC</code> - fill the block using 2x24-bit pattern and following 6 colours
* <code>0xFD</code> - fill the block using 2x24-bit pattern and following 7 colours
* <code>0xFD</code> - fill the block using 2x24-bit pattern and following 7 colours
* <code>0xFE</code> - fill the block using 2x24-bit pattern and following 8 colours
* <code>0xFE</code> - fill the block using 2x24-bit pattern and following 8 colours
* <code>0xFF</code> - should not happen, skip
* <code>0xFF</code> - should not happen, skip


Line 115: Line 136:


== Games that use Q format ==
== Games that use Q format ==
* [https://www.mobygames.com/game/death-gate Death Gate]
* [https://www.mobygames.com/game/mission-critical Mission Critical]
* [https://www.mobygames.com/game/mission-critical Mission Critical]
* [https://www.mobygames.com/game/dos/shannara Shannara]
* [https://www.mobygames.com/game/dos/shannara Shannara]

Revision as of 09:31, 30 May 2021

  • Company: Legend Entertainment

The format stores paletted video and raw audio stream for some game cutscenes or animations (while others may be stored in FLIC format). The format consists of 26-byte header followed by a series of 6-byte chunk headers and optional chunk payload. All data is little-endian.

File header

 2 bytes - magic 0x6839
 1 byte  - version
 1 byte  - ignored
 2 bytes - width in blocks
 2 bytes - height in blocks
 1 byte  - block width (should be 4)
 1 byte  - block height (should be 4)
 2 bytes - number of frames
 4 bytes - offset to the frame data (palette and optional method signalling chunks are stored before that offset)
 1 byte  - frames per second
 1 byte  - ignored
 2 bytes - some audio flags
 2 bytes - unknown
 4 bytes - audio chunk size

Chunk types

Chunk header consists of 16-bit chunk type and 32-bit chunk size.

Chunk types:

  • 0xFFFF - end of stream
  • 0 - audio
  • 1 - VGA palette
  • 2 - video frame
  • 3 - video frame (with additional coordinates to update just the part of image)
  • 4 - video frame (with additional coordinates to update just the part of image)
  • 5 - up to 128 most common 16-bit patterns used by the following frames
  • 6 - a marker signalling different decoding algorithm (chunk size should be ignored)
  • 7 - a marker signalling different decoding algorithm (chunk size should be ignored)
  • 8 - RIFF WAV header
  • 9 - first part of interlaced frame (version 5 only)
  • 10 - padding?
  • 11 - second part of interlaced frame (version 5 only)

Video compression

Video frame is compressed as a sequence of 4x4 blocks using mainly Block Truncation Coding and reusing other frame blocks (either by not updating it or by copying some other frame block). The compressed data is essentially a stream of opcodes that tell how to decode the following block (or several blocks).

Opcodes (version 3):

  • xx xx (xx < 0xF8) - fill the block with xx value
  • xx yy pppp (xx < 0xF8) - fill the block using the 16-bit pattern pppp (top bit first) and colours xx and yy
  • 0xF8 - TODO
  • 0xF9 nn - depending on previous block type either repeat previous block nn times or skip block nn times
  • 0xFA nnnn - copy the block after the current one using offset nnnn
  • 0xFB nnnn - copy the block before the current one using offset nnnn
  • 0xFC yx - copy the block using the motion vector with each nibble corresponding to the value in this table: { 0, 4, 8, 12, 16, 20, 24, 28, -32, -4, -8, -12, -16, -20, -24, -28 }
  • 0xFD nn - copy the block after the current one using offset nn
  • 0xFE nn - copy the block before the current one using offset nn
  • 0xFF - leave the block unchanged

Opcodes (version 4 and 5):

  • xx xx (xx < 0xF8) - fill the block with xx value
  • xx yy ii (xx < 0xF8, ii < 0x80) - fill the block using the pattern from chunk type 5 with index ii (top bit first) and colours xx and yy
  • xx yy pppp (xx < 0xF8, pppp >= 0x8000) - fill the block using the 16-bit pattern pppp (top bit first) and colours xx and yy
  • 0xF8 - TODO
  • 0xF9 nn - depending on previous block type either repeat previous block nn times or perform the same motion compensation as the previous block
  • 0xFA nnnn - copy the block at absolute 16-bit position nnnn
  • 0xFB - see below
  • 0xFC mm - copy the block using the motion vector mm from the table below
  • 0xFD nn - copy the block after the current one using offset nn
  • 0xFE nn - copy the block before the current one using offset nn
  • 0xFF - leave the block unchanged

0xFB opcode methods

Depending on initialisation chunk or version and frame type (version 4 with chunk type 7 being present in the beginning or version 5 for frame types 9 and 11 for mode 7, mode 6 otherwise) this opcode has a different meaning.

In either case it contains a number of blocks to process (two or more) and each block is processed in the same way.

Repeat block type sequence (mode 6)

Depending on previously decoded block type a different action should be taken:

  • fill block - read a one byte fill value for the current block
  • 8-bit pattern block - read 8- or 16- pattern for the current block, reuse colours from the reference block
  • 16-bit pattern block - read 16-bit pattern for the current block, reuse colours from the reference block
  • various motion compensation block types - read the same data type (1-byte offset, 2-byte index, 1-byte motion vector code) and perform motion compensation

Raw blocks sequence (mode 7)

If the data starts with byte value less than 0xF8 then the following 16 bytes are copied into the output block, otherwise fill block with several colours depending on the code:

  • 0xF8 - should not happen, skip
  • 0xF9 - fill the block using 32-bit pattern (with 2 bits per pixel) and following 3 colours
  • 0xFA - fill the block using 32-bit pattern (with 2 bits per pixel) and following 4 colours
  • 0xFB - fill the block using 2x24-bit pattern (3 bits per pixel, each 4x2 block has its own 24-bit pattern) and following 5 colours
  • 0xFC - fill the block using 2x24-bit pattern and following 6 colours
  • 0xFD - fill the block using 2x24-bit pattern and following 7 colours
  • 0xFE - fill the block using 2x24-bit pattern and following 8 colours
  • 0xFF - should not happen, skip

Motion vectors table

Motion vectors are also used with the whole blocks so e.g. (-5, 8) means taking 4x4 block that is 5 blocks to the left and eight blocks down from the current one.

 ( 0,  8), ( 1,  8), ( 2,  8), ( 3,  8), ( 4,  8), ( 5,  8), ( 6,  8), ( 7,  8),
 (-8,  8), (-1,  8), (-2,  8), (-3,  8), (-4,  8), (-5,  8), (-6,  8), (-7,  8),
 ( 0,  9), ( 1,  9), ( 2,  9), ( 3,  9), ( 4,  9), ( 5,  9), ( 6,  9), ( 7,  9),
 (-8,  9), (-1,  9), (-2,  9), (-3,  9), (-4,  9), (-5,  9), (-6,  9), (-7,  9),
 ( 0,  2), ( 1,  2), ( 2,  2), ( 3,  2), ( 4,  2), ( 5,  2), ( 6,  2), ( 7,  2),
 (-8,  2), (-1,  2), (-2,  2), (-3,  2), (-4,  2), (-5,  2), (-6,  2), (-7,  2),
 ( 0,  3), ( 1,  3), ( 2,  3), ( 3,  3), ( 4,  3), ( 5,  3), ( 6,  3), ( 7,  3),
 (-8,  3), (-1,  3), (-2,  3), (-3,  3), (-4,  3), (-5,  3), (-6,  3), (-7,  3),
 ( 0,  4), ( 1,  4), ( 2,  4), ( 3,  4), ( 4,  4), ( 5,  4), ( 6,  4), ( 7,  4),
 (-8,  4), (-1,  4), (-2,  4), (-3,  4), (-4,  4), (-5,  4), (-6,  4), (-7,  4),
 ( 0,  5), ( 1,  5), ( 2,  5), ( 3,  5), ( 4,  5), ( 5,  5), ( 6,  5), ( 7,  5),
 (-8,  5), (-1,  5), (-2,  5), (-3,  5), (-4,  5), (-5,  5), (-6,  5), (-7,  5),
 ( 0,  6), ( 1,  6), ( 2,  6), ( 3,  6), ( 4,  6), ( 5,  6), ( 6,  6), ( 7,  6),
 (-8,  6), (-1,  6), (-2,  6), (-3,  6), (-4,  6), (-5,  6), (-6,  6), (-7,  6),
 ( 0,  7), ( 1,  7), ( 2,  7), ( 3,  7), ( 4,  7), ( 5,  7), ( 6,  7), ( 7,  7),
 (-8,  7), (-1,  7), (-2,  7), (-3,  7), (-4,  7), (-5,  7), (-6,  7), (-7,  7),
 ( 0, -8), ( 1, -8), ( 2, -8), ( 3, -8), ( 4, -8), ( 5, -8), ( 6, -8), ( 7, -8),
 (-8, -8), (-1, -8), (-2, -8), (-3, -8), (-4, -8), (-5, -8), (-6, -8), (-7, -8),
 ( 0, -9), ( 1, -9), ( 2, -9), ( 3, -9), ( 4, -9), ( 5, -9), ( 6, -9), ( 7, -9),
 (-8, -9), (-1, -9), (-2, -9), (-3, -9), (-4, -9), (-5, -9), (-6, -9), (-7, -9),
 ( 0, -2), ( 1, -2), ( 2, -2), ( 3, -2), ( 4, -2), ( 5, -2), ( 6, -2), ( 7, -2),
 (-8, -2), (-1, -2), (-2, -2), (-3, -2), (-4, -2), (-5, -2), (-6, -2), (-7, -2),
 ( 0, -3), ( 1, -3), ( 2, -3), ( 3, -3), ( 4, -3), ( 5, -3), ( 6, -3), ( 7, -3),
 (-8, -3), (-1, -3), (-2, -3), (-3, -3), (-4, -3), (-5, -3), (-6, -3), (-7, -3),
 ( 0, -4), ( 1, -4), ( 2, -4), ( 3, -4), ( 4, -4), ( 5, -4), ( 6, -4), ( 7, -4),
 (-8, -4), (-1, -4), (-2, -4), (-3, -4), (-4, -4), (-5, -4), (-6, -4), (-7, -4),
 ( 0, -5), ( 1, -5), ( 2, -5), ( 3, -5), ( 4, -5), ( 5, -5), ( 6, -5), ( 7, -5),
 (-8, -5), (-1, -5), (-2, -5), (-3, -5), (-4, -5), (-5, -5), (-6, -5), (-7, -5),
 ( 0, -6), ( 1, -6), ( 2, -6), ( 3, -6), ( 4, -6), ( 5, -6), ( 6, -6), ( 7, -6),
 (-8, -6), (-1, -6), (-2, -6), (-3, -6), (-4, -6), (-5, -6), (-6, -6), (-7, -6),
 ( 0, -7), ( 1, -7), ( 2, -7), ( 3, -7), ( 4, -7), ( 5, -7), ( 6, -7), ( 7, -7),
 (-8, -7), (-1, -7), (-2, -7), (-3, -7), (-4, -7), (-5, -7), (-6, -7), (-7, -7)

Games that use Q format