Archive for September, 2026

nihav-movrender: alpha release

Wednesday, September 30th, 2026

I’ve decided to make a code drop release of nihav-movrender just for the completeness sake. If you look at nihav.org you should be able to find its git bundle among the rest.

One of the hardest parts was to create some documentation for it, so I’ve put something into README.md, hopefully that will be enough for all zero people who want to try it. Essentially if you provide it with the name of input MOV file and output directory it will try to decode the former and create some files in the latter (and if you omit output directory, it will put them into the current directory and you’ll have yourself me to blame for that). For tweaking that behaviour you need to refer either to nihav-movrender --help or to the aforementioned documentation.

Even in the current imperfect form it solves the tasks I wanted it to solve: extract (and convert to more convenient format) more exotic QuickTime tracks, and merge otherwise less accessible tracks (panoramas or multiple description tracks). The only thing it can’t do is to merge video from King’s Quest VI intro but it is a special situation (multiple independent tracks with edit lists to boot) so it will require a special handling. Beside that I have no further development plans for nihav-movrender and I’ll probably return to REing obscure formats.

Announcing nihav-movrender

Friday, September 25th, 2026

I’m not yet ready to release it but it’s a good time to tell what I’ve been working on (and intend to keep working for a while).

There are many valid QT MOV files on discmaster that are not decoded (or recognised for that matter, probably exactly for the reason they cannot be decoded). Looking manually into them often shows some exotic content not understood by any program (not even by QuickTime itself these days): Flash, MIDI, PDF, PPT, QT version of Flash aka sprites and so on. And in order to get some useful content out of such files I’m developing nihav-movrender. In theory it should be able to do at least this:

  • extract various kinds of binary data;
  • decode some exotic formats;
  • assemble QTVR or navigable MOV panoramas from individual frames;
  • merge tracks with multiple descriptors into one.

Currently I have first two items done and the other two should be easier to deal with (unless I hit some unforeseen complication of course). Below I want to talk more about different content that MOV files in the wild were discovered to have and how my tool deals (or hopefully will deal) with them.

Binary files

MOV files can embed various binary files, in different forms too. So far I’ve encountered three formats—namely Flash, PDF and PPT—and they all been stored in different ways. Flash files have their own stream type handler and it’s single file in single frame (but there may be two or more tracks with Flash files). The only sample with PDF came as many video streams, each of type “pdf” and containing a single-page PDF file. PPT, on the other hand, came in a generic data stream of sub-type “@ppt” with document split into several frames. In either case extracting them is trivial.

Media files

Occasionally a whole multimedia file of other format gets wrapped into MOV, the main examples being DV (I’ve never seen such a file and I’m fine this way), MPEG-1 (rather common) and ASF/WMF (generated by Flip4Mac). I’m mentioning those mostly for the completeness sake as I’m not sure if I want to do anything with them.

Auxiliary streams

There are several of those, for instance there’s timecode stream (considering that usually it contains just one frame I doubt it’s of any real value). There’s Tween stream (short for “between”) which is used to provide smoother transitions for other tracks (usually sprites).

I also encountered skin streams (which seem to contain single PICT file) and Quartz Composer media, where data is represented as binary .plist (with embedded PNG images if that helps).

Sprite system

Initially I assumed it’s a simple object-based animation system (like Flash Animation) but in reality it’s an interactive system involving multiple tracks i.e. usually one stream contains sprite data for content animation and another one handles controls. And the text streams (which are also complex constructions of QT atoms) seem to contain action handlers and relate to the sprites. So I ended up simply dumping decoded or extracted sprite images plus text-based description of what goes on there.

The process of decoding the samples I collected was rather fun. Sprite images may come in various formats, including GIF, JPEG, PNG, TIFF, Macintosh PICT as well as QT-compressed (usually RLE) frames. What’s more, those PICT files may contain RLE data of various kinds (sometimes even with larger dimensions than the image itself) as well as QT-compressed data. So apparently some presentation frames are coded as a command set like “set foreground colour to blue; paint a rectangle with it; and now call QT RLE decoder to paint the text”. Currently I don’t handle this situation well, so either the rectangle or overlay text is returned but it’s still better than nothing. And there are funny situations like 1100×800 JPEG image embedded inside 640×480 PICT.

MIDI

This data is stored in QT Music Architecture format (with each event data aligned to 32-bit word for convenience), sample descriptor having instrument descriptions and packets simply containing 1KB of data, whatever actual time period it may cover. I wrote a simple converter to SMF format and the result sounds OK to me.

QTVR

This format is actually stored in two or three tracks: image data split into strips and coded as individual frames, QTVR data and (optionally) panorama data. Since looking at a sequence of scenery pieces is rather boring, I want to make my tool assemble one large panorama from them.

Oh, and before QTVR there were Navigable movies (the same thing but simpler and with panorama data stored in track user data). I’m aware of four such files, one of them being the only known file employing CD-Graphics codec.

Other

If you look into QuickTime File Format Specification (it’s like ISO-IEC 14496-12 but older and available for free), it mentions even more auxiliary stream formats like hot sport image track, hint tracks and such. And of course it mentions 3D images, which must’ve been a killer feature at the time.


That’s why I alluded to this format as both common (since its derivative called MP4 is still the major multimedia container, even MXF can’t rival it; and MOV itself was extremely widespread back in the day) and exotic—you can’t claim that most things I listed here are used in modern multimedia workflows on daily basis (beside embedding font files in Matroska of course).

And who knows, maybe this will help me discover some more formats hidden in those files. The whole trove of QuickDraw flavours alone made it worthy for me.

na_game_tool 0.6.0, AVI edition

Saturday, September 5th, 2026

What should follow a political rant that nobody would read? A release of a tool that nobody would use of course!

I’m indifferent to announce the release of na_game_tool version 0.6.0, now with AVI support. Beside being able to write output to AVI it can now also de-obfuscate some AVI files that employ some simple scheme (like XORing with a 32-bit counter). And in addition to that it can also reconstruct Smacker and audio files from AVIs (or IAVFs) used in Black Dahlia and Ripper games.

The rest of the newly-added formats are mostly those I found at discmaster.textfiles.com by searching for unknown files over several megabytes large (and filtering out corrupted samples, segments from the multi-part archives, etc). Despite discmaster not being updated anymore (you know whom to thank for the storage shortage), I’ve found enough to have another release in the future.

Meanwhile here are some short notes about some formats:

  • Elige Tu Muerte is extremely short but very FMV game: it’s a dozen of .mov files with animations plus 20kB .exe engine. You just click on one of four exits and 3D-rendered figure walks there to its demise (which should be obvious from the game title). The coding format is slightly more complex than normal RLE but still nothing to write a full post about;
  • Lords of the Realm VAS format is the one I halfway reverse-engineered from the files themselves and then found corresponding RLE decompression code in the binary specification to fill in the missing details. The main problem there is that it’s an overlay executable so some parts are not loaded by default and there are no references to the decompression functions;
  • Tie Break Tennis 98 intro file was reverse engineered from its contents because it was less effort than to manually load LE segment of the binary specification into Ghidra. After all it has just four opcodes (fill block, raw block, skip block, and palette) so guessing the whole structure was easy;
  • Gunmetal SBV gets another mention here by being the only wavelet video codec I’ve encountered in a game so far;
  • this time I had three formats that should’ve been video files in theory but turned out to be an archive of video and audio tracks in stand-alone formats, optionally with some commands telling how to play them. Those formats are AVI, SMS and Knowledge Adventure movie v3.

na_game_tool is available at the usual place in the usual format.

Now I can move to work on a different tool which would tackle a format that’s very widespread and extremely exotic at the same time.

Pride and downsides

Friday, September 4th, 2026

Late (and still great) Sir Pterry was a writer who wrote great footnotes as well as the books to contain them (name any other author who put a footnote even into the book title!). And while Thief of Time probably was not written for this particular footnote, it would’ve not been half as good without it:

Every society needs a cry like that, but only in a very few do they come out with the complete, unvarnished version, which is “Remember-the-Atrocity-Committed-Against-Us-Last-Time-That-Will-Excuse-the-Atrocity-That-We’re-About-to-Commit-Today! And So On! Hurrah!”

I think this describes the best the situation observed in this world as well: too many groups (from individuals to communities spanning many nations) think they were greatly wronged in the past and this excuses whatever they’re going to do. In the best case it’s merely against the perceived/appointed enemies, in the worst case it’s against everybody. Of course since those people think they’re right (or don’t think at all) they don’t want to understand that their enemies are likely to retaliate in the same way with the same reasoning.

The classic example would be Christianity with its usual claim about great persecutions during Diocletian times (not paying attention to how many religions were there and practiced legally while only a couple of them were forbidden—probably for being too peaceful). That apparently gave them right to pursue the competitors opponents in equally or even more cruel ways; and of course that has not stopped when neither the original opponents nor the Roman Empire were around.

Another classic example would be Israel. I whole-heartedly agree that Jews should not have been killed or persecuted just for being different (neither in 1938-1945 nor in other time periods) and they deserve their own state. What I don’t agree is that their tragedy gives them the right to behave in the same way as it was done unto them back in the day. Yet paradoxically enough currently Israel has an anti-Semitic government in both senses, hostile both to Palestinians and Jews except of very special sort (who don’t want to defend Israel by themselves). At least they’re not talking expanding their Lebensraum, otherwise the similarity would too much to bear. And no friendly country does not do much against it because of the unfortunate associations (even with a token ICC verdict against Netanyahu some European countries openly declared they won’t comply because it would be anti-Semitism). Mind you, I don’t have anything against the population itself beside the fact they elected this government (more than once) which may lead their country to destruction by pissing off allies and courting with enemies. But I’ll talk about USA a bit later.

Moving to Europe, there’s a Catholic version of Israel called Poland. Since most of the people do not have a reason to learn about it, here’s a short version: the golden years of it were when the Kingdom of Poland united with Grand Duchy of Lithuania forming Rzeczpospolita (essentially the word “republic” or “commonwealth” translated into Polish). With that union they got a lot of Ukrainian lands whose agricultural output was responsible for a good deal of Rzeczpospolita wealth. And yet, unlike Lithuanians, they treated Ukrainians badly for being of a different branch of Christianity (and maybe not having their own state). Eventually Ukrainians started an uprising, ending up with their own republic and dealing a mortal blow to Rzeczpospolita in a Pyrrhic victory—the weakened Poland was eventually conquered and split up between two European empires (Austro-Hungarian and German) and russia. Wiser people would’ve made some conclusions about tolerance and treating own population decently, Poles instead found no fault with them (because nobody does) and decided that it’s a martyrdom they have to bear because they’re special. So the next times they re-instated their republic it went the same way: mistreating non-Poles, suffering from the mistakes, only reinforcing them in their idea of martyr nation. And nowadays it looks like they’ve not learned anything, still holding 80-year old grudges against Ukrainians (because they dared to kill occupational Polish officers and settlers on Ukrainian territory) fuelling them into anti-Semitism level of hate. If you look you can see the news in any given week about Poles either beating Ukrainians for speaking Ukrainian (which sounds not that different from Polish BTW) or other Poles for mistaking them for Ukrainians. And those notions are instigated predominantly by their current president and the main opposition party who, unlike the government and many ordinary Poles, do not even formally condemn such behaviour.

And finally let’s talk about USA. It is hard to argue that they suffered any injustice beside being forced to pay taxes (some claim that taxes were rather the pretext and the real reason was prohibition of trade with French colonies from which rum distilleries in British colonies obtained cheap and abundant molasses; in either case it was about the money and unwillingness to give them away). So in order to be less ashamed about it they threw it some ideas about liberty and human rights in general (no slaves need apply) and started an uprising. Apparently this combination of being the first democratic republic (if you don’t count the ones appearing in Europe a century before) and reluctance to pay money gave them the main two pretexts for doing anything: being the missionaries of democracy (which compelled them to occupy various other lands at different times, democratic or not, as well as trying to annex Canada) and paying for something being a great offence. Or maybe rather “we could smuggle our greed under a pretence of higher moral ideals, we can do it again”. No wonder they spawn the ideologies like effective altruism (aka “I know better what to do with my money, don’t make me pay taxes”). I’ve started writing this post before the current USian president made a claim that he wants European countries to pay for the past military aid that Ukraine received for free before his term, but it’s definitely not against the trend. Timeo Danaos…

The sad thing those examples show is that such behaviour is not self-destructive (enough) and it can mutually subsist on the similar behaviour from the other side (think about the classic example of long-lasting blood feud from Romeo and Juliet Adventures of Huckleberry Finn) but its substrate (people infected with those ideas) will suffer even if they feel great and superior to everybody else. I’d recommend scepticism and clear thinking but I know that people don’t like to think in general, let alone about the things that would make them feel bad and less important.

Yet another FLI flavour

Wednesday, September 2nd, 2026

There’s an Argentinian game called La Mágica Aventura del Cine or (The Magical Movie Adventure in English language release) which has animations in ordinary and custom FLI format. The files are hidden inside large resource files along with .voc and other types with no obvious index (probably it is stored in accompanying .lod file which was not useful even after I uncompressed it). Anyway, custom FLIs have marker 0xAF66 with chunk types 110 (contiguous VGA palette) and 100 (LZ77-compressed frame). I’ve added support for it to na_game_tool but, like with Cross Racing Championship RoQ files, I won’t count it towards the total number of formats supported.

What’s curious is the compression scheme employed here. It is slightly more complex than classic LZSS since it has more modes of coding offset and length (8/13-bit offsets, 2/3/8/16-bit lengths). Nothing special but it looks almost the same as the compression employed in HNM except for one bit meaning inverted, LSB bitstream reading and large lengths handling. And like HNM there are two slightly different variants of the compression method used here as well: ordinary compressed files seem to use the version with 16-bit flags while frames (and some other, probably also image, formats) employ the version with 32-bit flags. I somewhat wonder if there was a widespread version of this particular compression format that got adapted by two different companies in the same way as LZSS.c from Haruhiko Okumura (which is so common that I often recognise the format even without looking at the binary specification).

In either case it’s time to move on, there are still two or three formats left to RE and implement for the na_game_tool release.