Psygnosis YOP: Difference between revisions

From MultimediaWiki
Jump to navigation Jump to search
m (sound details)
(FFmpeg/Libav have this format)
 
(5 intermediate revisions by 3 users not shown)
Line 1: Line 1:
* Extension: yop
* Extension: yop
* Company: [[Psygnosis]]
* Company: [[Psygnosis]]
* Samples: http://samples.mplayerhq.hu/game-formats/yop/


YOP is an [[FMV]] video format used in the computer game [http://www.mobygames.com/game/city-of-lost-children The City of the Lost Children] by Psygnosis. Based on the very primitive pattern-based video compression and stock [[IMA ADPCM]] sound encoding.
YOP is an [[FMV]] video format used in the computer game [http://www.mobygames.com/game/city-of-lost-children The City of the Lost Children] by Psygnosis. The format uses very primitive pattern-based video compression and stock [[IMA ADPCM]] sound encoding.


== File Format ==
== File Format ==


File begins with the following 2048-bytes header:
A YOP file begins with the following 2048-bytes header:


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


For each frame:
For each frame:
  +  0 dword Unknown_0          -- unused/ignored, some length?
  +  0 UI32  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, mono, 1840 samples per frame
  +xxx UI8  Sound[SoundLen]    -- ADPCM-encoded sound data, mono, 22050Hz, 1840 samples per frame
  +yyy byte  Video[...]          -- encoded video data, variable length
  +yyy UI8  Video[...]          -- encoded video data, variable length
  +zzz byte  Padding[...]        -- unused/padding
  +zzz UI8  Padding[...]        -- unused/padding
  ---- total frame size is FrameSize * 2048
  ---- total frame size is FrameSize * 2048


* All numbers are little-endian.
===Notes===
* 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.
* All multi-byte numbers are little-endian.
* Each frame comes with it's own palette part, updating PalColors entries starting from FirstColor1 for odd and FirstColor2 for even frames respectively.
* Both file header and each frame chunk are aligned/padded to 2048-byte boundaries.
* IMA decoding context initialized to zero at the beginning of the playback and then updated by successive frames
* Frame chunks have a fixed size (FrameSize * 2048), even if the actual payload size is much smaller.
* Each frame comes with its own palette part, updating PalColors entries starting from FirstColor1 for odd and FirstColor2 for even frames respectively.
* The IMA ADPCM audio decoding context (predictor and step index) is initialized to zero at the beginning of the playback and maintained across successive frames.


== Video Compression ==
== Video Compression ==
Video frame broken on 2x2 macroblocks and each macroblock decoded using the following algorighm:
A video frame is broken into 2x2 macroblocks and each macroblock is decoded using the following algorithm:


  tag = next nibble
  tag = next nibble
Line 58: Line 61:
   D : aaaa
   D : aaaa
   E : abbb
   E : abbb
   F : read next tag and copy previously drawn block located at the following coordinates (in pixels) relatively to the current block:
   F : read next tag and copy previously drawn block located at the following coordinates (in pixels) relative to the current block:
   tag is:
   tag is:
     0 : -4:-4
     0 : -4:-4
Line 77: Line 80:
     F : -2: 0
     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)".
* 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.
* Tags are 4-bit nibbles, processed starting from the high one (bits 4..7), then lower (bits 0..3). However, complete bytes are consumed from the bytesteam, thus pixel bytes do not overlap with the tags.


[[Category:Game Formats]]
[[Category:Game Formats]]
[[Category:Video Codecs]]

Latest revision as of 12:28, 22 December 2011

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

File Format

A YOP file begins with the following 2048-bytes header:

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

For each frame:

+  0 UI32  Unknown_0           -- unused/ignored, some length?
+  4 RGB   Palette[PalColors]  -- palette part for this frame, 6 bits per component
+xxx UI8   Sound[SoundLen]     -- ADPCM-encoded sound data, mono, 22050Hz, 1840 samples per frame
+yyy UI8   Video[...]          -- encoded video data, variable length
+zzz UI8   Padding[...]        -- unused/padding
---- total frame size is FrameSize * 2048

Notes

  • All multi-byte numbers are little-endian.
  • Both file header and each frame chunk are aligned/padded to 2048-byte boundaries.
  • Frame chunks have a fixed size (FrameSize * 2048), even if the actual payload size is much smaller.
  • Each frame comes with its own palette part, updating PalColors entries starting from FirstColor1 for odd and FirstColor2 for even frames respectively.
  • The IMA ADPCM audio decoding context (predictor and step index) is initialized to zero at the beginning of the playback and maintained across successive frames.

Video Compression

A video frame is broken into 2x2 macroblocks and each macroblock is decoded using the following algorithm:

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) relative 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 bytes are consumed from the bytesteam, thus pixel bytes do not overlap with the tags.