First of all I’d like to blame Peter Ross for ignoring this peculiar format from his favourite company. Apparently he prefers to dig Lead instead.
Anyway, as I was scraping bottom of the barrel for FMV game formats to support in na_game_tool
(and I still haven’t found good candidates for some letters, a rant about it will come later), I encountered a game called Psychic Detective.
It stores video in large .str
files with some external means to signal where a segment starts and what format it has (as it may switch between 160×120 and 320×240 video and 11kHz stereo and 22kHz mono audio).
Audio is bog standard IMA ADPCM, video is while being intra-frame only is much more curious.
First of all, it employs vector quantisation with the same approach as Cinepak: there is a codebook of 2×2 blocks that get scaled to 4×4 output block, there is a codebook of 2×2 sub-blocks used to compose 4×4 output blocks, there are block mode bits telling whether it’s one- or four-vector block, and finally there are vector indices. And for larger (320×240) videos there is even a second codebook that replaces four-vector codebook after a provided line, a lot like Cinepak slices. The main difference is the structure: while Cinepak has more flexible frame structure with chunks for codebook updates, indices and such, here all data is stored in the fixed order with its sizes transmitted in the frame header.
Oh, and there’s another minor detail: frames simultaneously code 8-bit paletted and YUV video (rendered as 15- or 16-bit RGB). This is achieved by transmitting actual palette and duplicating codebook information first as palette indices and then as YUV blocks (so the decoder can decide which one to use). Also YUV to RGB conversion is simplified to look a lot like Cinepak formula as well.
I keep repeating the same thing again and again because it still holds true: those old codecs are much more interesting to look at because sometimes you find out crazy methods like this one.
Please fully RE sonarc lossless audio decoder and post all info on wiki. Its of most essential importance for our community.
That makes perfect sense, thanks for the pointer.
Meanwhile the other codec you referred me to is so large that it took Ghidra about an hour for initial analysis. It will take me even more time for sure…
You mean the latest .dll ones? On my very modern laptop analysis was pretty fast with latest Ghidra
Mine was not the beefiest one when I bought it back in 2010, so some things are rather slow there.
I’ve been neglecting a lot of stuff lately 🙁 Every now and then I get a burst of motivation and crack open a PE file.
Oh and mono and stereo audio in the same file… I wonder what they were thinking!
The file consists of many different scenes, in different formats as well. The information about what formats to use is probably stored in the accompanying index file but I haven’t figured it out.
And if you wonder about the game engine, it’s rather modern. They licenses something called RTkernel and video playback consists of spawning half a dozen threads (for GUI, control events, decoding and so on) with message channels used to pass information between them all, one of those messages being what image format to use. So essentially I first saw audio chunk, got a hunch it’s IMA ADPCM, found the usual step table and tracked video decoding from it; the rest is for more curious people to investigate.