Highlander FMV

From MultimediaWiki
Revision as of 02:27, 15 October 2022 by Kostya (talk | contribs) (fill description)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
  • Company: Lore Design Limited

This in an FMV format used in an unpublished PC game Highlander: The Last of the MacLeods. It contains 320x240 frames using fixed palette and 22kHz 8-bit PCM audio.

File format

FMV file contains a sequence of chunks prefixed with 4-byte chunk type and 32-bit little-endian chunk size. There are only four known chunk types:

  • FMV* - file header (no data)
  • AUD1 - PCM data
  • VID3 - video frame
  • END* - end of data

Video compression

Frame data is compressed twice with history-based compression (first 32 bits of the frame data are the size of compressed data) and contains commands to paint 4x4 blocks of the frame.

History-based compression

This is a simple compression method that reads flags (one byte at once, LSB first) and depending on flag value either reads new output value from the stream or reuses a value from history buffer:

 prev = 0;
 pprev = 0;
 while there's still data {
   flags = *src++;
   for (i = 0; i < 8; i++) {
     hist_idx = (pprev << 7) ^ prev;
     if ((flags >> i) & 1)
       hist[hist_idx] = *src++;
     *dst++ = hist[hist_idx];
     pprev = prev;
     prev = hist[hist_idx];
   }
 }

Block painting commands

There are nine commands to paint blocks in rather dithered form. First byte of the stream is command index, the following 1-16 bytes are pixel values:

  • 0 - read pixel value, fill block with it
  • 1 - read two pixel values, paint block as
 0 1 0 1
 1 0 1 0
 0 1 0 1
 1 0 1 0
  • 2 - read two pixel values, paint block as
 0 1 0 1
 1 1 1 1
 0 1 0 1
 1 1 1 1
  • 3 - read two pixel values, paint block as
 0 1 0 1
 0 0 0 0
 0 1 0 1
 0 0 0 0
  • 4 - read two pixel values, paint block as
 0 0 0 0
 0 1 0 1
 0 0 0 0
 0 1 0 1
  • 5 - read two pixel values, paint block as
 1 1 1 1
 0 1 0 1
 1 1 1 1
 0 1 0 1
  • 6 - read five pixel values, paint block as
 0 1 0 2
 1 3 1 4
 0 1 0 2
 2 4 2 4
  • 7 - read eight pixel values, paint block as
 0 1 2 3
 1 0 3 2
 4 5 6 7
 5 4 7 6
  • 8 - read 16 pixels for block contents