Psygnosis YOP

From MultimediaWiki

(Difference between revisions)
Jump to: navigation, search
Revision as of 23:19, 30 January 2008
VAG (Talk | contribs)
(clarify palette, typo)
← Previous diff
Revision as of 00:03, 31 January 2008
VAG (Talk | contribs)
(sound details)
Next diff →
Line 27: Line 27:
+ 0 dword Unknown_0 -- unused/ignored, some length? + 0 dword Unknown_0 -- unused/ignored, some length?
+ 4 RGB Palette[PalColors] -- palette part for this frame, 6 bits per component + 4 RGB Palette[PalColors] -- palette part for this frame, 6 bits per component
- +xxx byte Sound[SoundLen] -- ADPCM-encoded sound data+ +xxx byte Sound[SoundLen] -- ADPCM-encoded sound data, mono, 1840 samples per frame
+yyy byte Video[...] -- encoded video data, variable length +yyy byte Video[...] -- encoded video data, variable length
+zzz byte Padding[...] -- unused/padding +zzz byte Padding[...] -- unused/padding
Line 36: Line 36:
* Worse, frame chunks has fixed size (FrameSize * 2048), even if the actual payload size is much smaller. * Worse, frame chunks has fixed size (FrameSize * 2048), even if the actual payload size is much smaller.
* Each frame comes with it's own palette part, updating PalColors entries starting from FirstColor1 for odd and FirstColor2 for even frames respectively. * Each frame comes with it's own palette part, updating PalColors entries starting from FirstColor1 for odd and FirstColor2 for even frames respectively.
 +* IMA decoding context initialized to zero at the beginning of the playback and then updated by successive frames
== Video Compression == == Video Compression ==

Revision as of 00:03, 31 January 2008

YOP is an FMV video format used in the computer game The City of the Lost Children by Psygnosis. Based on the very primitive pattern-based video compression and stock IMA ADPCM sound encoding.

File Format

File begins with the following 2048-bytes header:

+  0 word  Signature           -- "YO"
+  2 byte  Unknown_2           -- unused, but set to 1. Perhaps format version
+  3 byte  Unknown_3           -- unused, can be either 0 or 1. Format version minor?
+  4 word  NumFrames           -- number of frames
+  6 byte  Unknown_6           -- framerate?
+  7 byte  FrameSize           -- size of the single frame chunk in sectors (2048 bytes per sector)
+  8 word  Width               -- frame width
+  A word  Heigth              -- frame height
+  C byte  PalColors           -- number of colors in palette per frame *see notes*
+  D byte  FirstColor1         -- first color to update for odd frames (counting from 1)
+  E byte  FirstColor2         -- first color to update for even frames (counting from 1)
+  F byte  Unknown_C[3]        -- unused/zero
+ 12 word  SoundLen            -- size of the audio block for frame
+ 14 byte  Unknown_14[]        -- unknown/unused/padding to the next sector's boundary
+800 FRAME Frames[NumFrames]   -- video frames

For each frame:

+  0 dword Unknown_0           -- unused/ignored, some length?
+  4 RGB   Palette[PalColors]  -- palette part for this frame, 6 bits per component
+xxx byte  Sound[SoundLen]     -- ADPCM-encoded sound data, mono, 1840 samples per frame
+yyy byte  Video[...]          -- encoded video data, variable length
+zzz byte  Padding[...]        -- unused/padding
---- total frame size is FrameSize * 2048
  • All numbers are little-endian.
  • Both file header and each frame chunk are aligned/padded to the 2048-bytes boundary.
  • Worse, frame chunks has fixed size (FrameSize * 2048), even if the actual payload size is much smaller.
  • Each frame comes with it's own palette part, updating PalColors entries starting from FirstColor1 for odd and FirstColor2 for even frames respectively.
  • IMA decoding context initialized to zero at the beginning of the playback and then updated by successive frames

Video Compression

Video frame broken on 2x2 macroblocks and each macroblock decoded using the following algorighm:

tag = next nibble
tag is:
  0 : abcd
  1 : abca
  2 : abcb
  3 : abcc
  4 : abac
  5 : abaa
  6 : abab
  7 : abbc
  8 : aabc
  9 : aaba
  A : abba
  B : aabb
  C : aaab
  D : aaaa
  E : abbb
  F : read next tag and copy previously drawn block located at the following coordinates (in pixels) relatively to the current block:
  tag is:
    0 : -4:-4
    1 : -2:-4
    2 :  0:-4
    3 :  2:-4
    4 : -4:-2
    5 : -4: 0
    6 : -3:-3
    7 : -1:-3
    8 :  1:-3
    9 :  3:-3
    A : -3:-1
    B : -2:-2
    C :  0:-2
    D :  2:-2
    E :  4:-2
    F : -2: 0
  • abcc means "read byte a and use it to paint pixel 1 (top left), read byte b and paint pixel 2 (top right), read byte c and paint pixel 3 (bottom left) AND pixel 4 (bottom right)".
  • Tags are 4-bit nibbles, processed starting from the high one (bits 4..7), then lower (bits 0..3). However, complete byte read first, thus pixel bytes do not overlapped with the tags.
Personal tools