Archive for the ‘Game Video’ Category

Final words about Escape from Haunted House formats

Wednesday, March 17th, 2021

Since I don’t like my work to go completely to waste I decided to document the formats on a separate page in this blog.

I’m not sure these formats are that fitting to be documented in The Wiki since they’re in an archive and not standalone. But since I’m too lazy to find a proper wiki for game formats and register there I dumped it here instead.

More words on the same game format

Sunday, March 14th, 2021

In my last post I said something about video compression but now I have much clearer picture in my head so I’d better document it a bit.

So it turns out bitmaps and videos share the same compression methods (just 1 and 3, 0 and 5 are video-only) and they’re even more interesting than at the first glance.

  • Compression 0 is simple stream with 8- or 16-bit opcodes with follow-up pixel data. Top two bits mean operation – skip, error, copy, repeat; next bit signals whether actual operation length is 5 or 13 bits; next bits are obviously operation size.
  • Compression 1 is tiling compression. Frame data is split into three chunks with first two starting with chunk size. First chunk is bit flags telling which 40×40 tiles in the frame are updated (this chunk can be ignored). Second chunk contains its own tile dimensions and tile metadata (one bit signals that tile is coded, 3 additional bits tell tile type). The last chunk contains tile contents in form of pixels and pattern data. Tile can be skipped, filled with single colour, filled with raw pixels, or it can be filled with 2-16 colours (with all intermediate values allowed) using 1-4 bits as index.
  • Compression 3 is LZ77-like and works on two lines at once. It reads a code using static codebook (one for intra-frames, another one for inter-frames), for code 0 is for literal (reads and output two pixel values, one for each line), all other code values are treated as copy length which is followed by offset (and in case of inter frame also direction bit telling if data should be copied from start to end or from end to start).
  • Compression 5 is virtually the same as compression 1 but tile type takes 4 bits now to fit operation 8 (copy tile from the same place in some previous frame).
    1. Indeed, this game turned out to have very original formats.

Some words on yet another game format

Saturday, March 13th, 2021

In my recent post about video in Russian quests I said that the Russian adventure games I looked at used standard video formats (except for one game employing custom-modified FLIC). Well, now I can say there’s one game with an original format.

Escape from the Haunted House as its English version is known (unlike the original Russian title which translates to Spectre of the Old Park—because the goal of the game is to escape haunted house naturally) is a Myst or 7th Guest clone which means it should use animations for scene transitions and it has lots of them.

Almost all game resources are stored in a single 600 MB file in a peculiar format: unlike the usual fixed-size record pointing at actual resources, here you have 16-bit tag followed by the tag-speficic data (may be none, may be 1-128 bytes, may be some arbitrary size declared in fixed-size header). And 90% of the data are animations.

Animations by themselves are rather peculiar. First you have a header starting with " AN 0.90" (or some other floating point number), then you have a palette, chunk table and actual chunks. Audio is 5-bit DPCM (one bit for difference sign and four bits to update step index) which actually codes sample as x[i] = x[i - 1] * 2 - x[i - 2] + delta, I don’t remember seeing audio coding like this even if it’s rather simple.

Video coding employs RLE and static codebooks (depending on coding method) and some second pass to output image data in specific form. Nothing really complicated but quite original.

The problem with binary specification was the way it’s written (it’s fun to force Ghidra to decompile a function which it turns back into data because the code is self-modifying), particularly first I managed to locate a function to create those IMV data archives and only then its counterpart for loading data from archive. And after extracting data I found which type corresponds to animations and which functions handle it.

At least this all turned out to be even more original than I was asking for.

Looking at AVX format

Tuesday, March 9th, 2021

Since I had been looking at video files in various games I’ve decided to look at AVX format in Jack Orlando, a Polish adventure game.

The format is not very complicated but somewhat WTFy. It combines audio track compressed with IMA ADPCM and RLE-compressed video. The format is organised into chunks (audio, video, palette update). Sound easy enough?

Well, here are WTFy bits:

  • audio violates chunking structure: file starts with 32-bit word to signal this is video file, then you always have ~110kB of audio data (that starts with its own header) and only then you have video header and chunks;
  • speaking of which, video frames are packed together with audio chunks so after reading/decoding one you have audio data without the usual chunk header (you can have standalone audio chunk of course);
  • oh, and another thing—the video file header seems to list number of audio frames (which is usually several times larger than the number of video frames);
  • another fun fact about video header: it may occur several times throughout the file;
  • and another fun fact: while the format is paletted, palette can be either 24-bit (I’ve seen that only in intro) or 16-bit (all other files, which are predominantly short game over animations). And by 16-bit palette I mean 256-colour palette with actual colours represented in RGB565, I’ve never seen that before;
  • as a cherry on top of that sometimes chunks start earlier or later than you’d expect from declared size.

And if you thought video compression would be sane, think again:

  • actual data is compressed in two passes: first it groups data into coded segments in the form (1 byte - number of skipped pixels, 1 byte - number of coded pixels, 0-254 bytes - actual pixels) and then all that data is RLE coded (0xFF – escape flag after which run value and run count bytes follow, otherwise byte value should be copied as is);
  • since this is too easy it also uses pixel value 0 as skip value;
  • plus there’s a global offset in the beginning of the chunk telling from which pixel to start decoding;
  • plus there are two video chunk types that seem to differ only in one header field being missing in one of them;
  • and the actual video is 640×480 but it is coded as 1024×480 with right part of the frame being blank.

Some game formats are interesting but this one borders with being unbearably interesting.

Videos in Russian quests – FLIC and Indeo

Friday, February 19th, 2021

It should be obvious by the fact that in ex-USSR countries there are usually “quest games” or simply “quests” instead of adventure games that Sierra games were favoured way more than anything else (while Germany seems to be more Lucas Arts land). But unlike either of these companies, Russian quest games history is much more limited both in time and quantity.

There are just a couple of games that can be called Russian quests. They appeared in 1997-1998 and remembered dearly up to this day. Almost anything coming has been forgotten and for good reasons too.

First I’d like to give a short review of the games:

Looking at fabulous game format

Sunday, February 14th, 2021

Since I need some distraction from VGM-XVD formats, I decided to look at some simple game format and somehow my eyes turned to Fable. This is a point-and-click adventure from 1996 from a studio that made only this game. Overall it could’ve been better with a better beginning, no whiplash-inducing ending and no aliens in the premise so it does not resemble a bad imitation of Might and Magic series.

Anyway, the game contains three videos: 50-second logos+opening, 3-minute intro and 50-second ending (it may be different for North American release but I’ve not seen that version). And the compression employed there turned out to be interesting.

It looks like they took PCX RLE for the inspiration but they made it more complex: depending on top bits you can have run, skip or raw copy. And raw copy is where it gets interesting. During decoding of the whole video file the raw pixel sequences are added to the special buffer which can be used later to copy pixels from. This reminds me somewhat of VPx golden frame which could be updated in some versions with fresh decoded blocks and referenced even many frames later.

And here is why I like to look at those old formats—they sometimes offer an interesting coding approach while modern codecs seem to be made from the standard blocks.

A quick glance at Bink Audio

Tuesday, February 2nd, 2021

Since my attention was drawn to this format (and binary specification was provided as well) I’ve briefly looked at it—and a brief look should be enough.

From what I see it’s the same Bink Audio but in its own container instead of Bink. It has 24-byte header, a table of 16-bit audio block sizes and actual audio data (each frame may be prefixed with 0x99 0x99 but I’m not sure since I’ve not seen a single file in that format).

Frame header:

  • 1FCB magic;
  • one byte of version (version 2 groups audio frames together, previous one does not);
  • one byte with number of blocks per frame;
  • two-byte sampling rate;
  • four-byte variable, probably frame length in samples;
  • four-byte unknown variable, maybe suggested input buffer size?
  • four-byte unknown variable
  • four-byte variable, number of frames in seek table.

So as expected it’s nothing special.

A look on FutureVision formats

Saturday, January 23rd, 2021

As you all know, this is a studio known primarily for the Harvester game and while that’s not a game I’d like to play I still decided to take a look at it. What do you know, the formats for both music and video are documented. The music format is supported by Game Audio Player since ages and the video format was documented on The Wiki more than a decade ago by the guy responsible for reverse engineering most game formats, Vladimir Gneushev (or simply VAG). And yet there are nuances in them…

Music format is based on IMA ADPCM with minimalistic file header and the default predictor. Which means it needs some time to adapt to the actual coming signal amplitudes. In result the old format description based on reverse engineering recommends skipping first 7-57 bytes right after the header because of the garbage sound it produces. When I looked into the binary reference (an adventure that will be described in an upcoming post), it turned out that in certain cases they simply zero out the first 50 decoded samples.

Video format is rather typical of its time: divide frame into 4×4 blocks, depending on coded flags either skip updating it, read full block data, or read two colours and 16-bit pattern telling how to paint them in a block. No additional compression, even audio is stored as PCM. There is one thing though: the lowest row should not be decoded (and the game does not do it either). It is probably an encoder bug but e.g. for skip frames it codes just bit flags that all should be zero and yet last byte there contains some non-zero garbage. Or in a frame containing changes and not just skip blocks you also have some weird block flags that would signal you need to read block data past the end of the input frame data. This does not matter much since most of the videos in the game have not just 320×200 resolution but also large black borders as well. The only exception is credits.fst which is 640×400. Another fun fact is that I got a North American version and (since the company is North American as well) it has virginlogo.fst with Merit Studios logo (plus some videos mention the company as Future Vision and others as DigiFX Interactive). I know they had changed name in the process and had different European publisher but it’s still fun discrepancy.

Meanwhile I’ve also documented DERF format used in Stupid Invaders game (video format there is based on 8×8 DCT for block coding and motion compensation that involved block division and transforms like flipping the source, which may be in the same frame too). While neither of the codecs is complicated it is still a nice change from looking at the mainstream codecs of today (it’s not that there are many non-mainstream codecs survived to look at either).

A curious Smacker-related bug

Friday, January 22nd, 2021

Here’s a thing that has been bothering me since I tested my Smacker decoder for NihAV.

It decoded various test files fine except for one game: Toonstruck.

A Quick Review of Actimagine Video Codecs

Sunday, August 23rd, 2020

Now that (as I believe) I’ve fixed remaining reconstruction bugs in VX decoder, why not do a quick comparison of various video codecs developed by Actimagine and see how they differ (if at all).

There seem to be the following codecs:

  • Actimagine (VX)
  • Mobiclip (Mods)
  • Mobiclip (Moflex for 3DS also there’s a version of it for PC known as Mobiclip HD)

And while they all are based on H.264 with finer block partitioning, there are some differences as well.

Proper structure. The original VX codec used quantiser derived from FPS and all frames were encoded in the same way, while the latter codecs have I-frames and quantisers are transmitted for each frame (as delta for non-keyframes).

References and motion compensation. VX had three previous frames as reference ones, later codecs increased that number to five. VX had fullpel motion compensation, later codecs use halfpel MC.

Data coding. VX relied on Elias Gamma’ codes for all codes except coefficient coding, later codecs use codebooks for most coded values. Also while VX coded residue in 4×4 blocks in H.264 way (starting from the end and with tail of ones coded explicitly), newer codecs use separable transforms and the usual (zero run, coefficient level) coding. Additionally only nine coding modes out of twenty four have survived after VX (intra prediction, MC with motion vectors coded and splits).

Overall, while all those codecs are related, there are large differences between VX and later Mobiclip variants and the only differenced between Mobiclip variants are colourspace (Mods uses YCoCg model, HD uses the proper YUV model), quantiser being clipped to 12-52 range, and block mode codebooks being different.

As I mentioned before, somebody has reverse-engineered decoders for Mobiclip (and a quick check on codebooks used tells me that Mobiclip HD and 3DS versions are the same) so if somebody needs them it should not be that hard to write a decoder.