Since I had nothing better to do and remembered about one mostly finished format, I decided to add its support to na_game_tool
. The game in question is called either Cydonia: Mars – The First Manned Mission or Lightbringer (with two variations of sub-title).
The main problem is that there may be different audio and video formats inside but you cannot easily detect them. The header contains only the dimensions (which can be any as long at it’s 640×320 as the game uses hard-coded dimensions in the decoder), number of video frames (also rather pointless as it does not really affect anything) and audio present flag (the only useful information there).
First annoyance is audio format detection. The simplest solution I could devise is looking at the first audio block size and depending on its size setting the format (22050 bytes means 11kHz mono, 44100 bytes are for 22kHz mono and 88200 bytes are for 22kHz stereo). As long as you don’t encounter those extra-short files with a single audio block of different size you should be fine.
Then, video. Game demo (and maybe some versions of the full game) uses paletted video while the full game (at least the version I could find) uses 16-bit video instead. So if you discover palette chunk before video it must be a paletted format. At least the compression schemes remain the same.
And what do you know, video compression is also annoying. Both compression methods employ LZ77-based algorithm with some variations. Method 3 always decodes 640*320 bytes (or twice as much for 16-bit video) and employs an additional code for leaving data unchanged from the previous frame. Method 2 uses the same coding method (minus the “keep previous data” code) to code inter frame data of variable length (without an end code apparently). Essentially if the next 24-bit code is a valid offset (which is coded as x+y*632
) then copy a block from the previous frame at the given position, otherwise decode block data (64 or 128 bytes depending on bit-depth). As I mentioned before, you don’t know compressed data size beforehand and you don’t have end-of-stream marker so you have to decode the needed amount of data as you paint the frame.
Overall, this is rather interesting video compression scheme but Paco also serves as an example of how not to design a container format. This reminds me of RoQ hack where the game engine used slightly different decoding mode if the filename was in a special list. And Nova Logic KDV but there it were different flavours in different games at least.