Was this your idea or the agent's? Because it feels peculiar to essentially describe JPEG, modulo the entropy coding, without mentioning its name. It was released in 1992 -- before C+C. Which makes me wonder why Westwood didn't just use JPEG too...
Fun fact, DCT's inventor: https://en.wikipedia.org/wiki/Nasir_Ahmed_(engineer)
Would love to see something like this ported to similar systems such as Amiga, Mega Drive and Neo Geo. All 68K, all tile based.
Also seeing that gameplay at the end, absolutely wonderful. Would not have figured it was even remotely possible on a system like that, but there it is.
Retro Gaming
Computer Science
Videogames
Video Codec
7 min read
Jul 30, 2026
--
I like porting DOS-era games to the Atari ST β a home computer launched in 1985 and mostly obsolete by 1995, the year Westwoodβs Command & Conquer arrived. When I started a port of that RTS classic, cutscenes were not on the critical path. The game core came first. Experienced players often skip the videos anyway, and it was not obvious an ST port even needed them.
Command & Conquerβs iconic 1995 intro video, rendered in 16 colors using the STV codec. CRT filter for aura.
What was obvious: Westwoodβs video format (VQA, for Vector Quantized Animation) was never going to work out of the box on a low-end ST. Designed for the VGA graphics of its day, VQA videos are 320Γ200 pixels, 256 colors, and run at 15 frames per second. The ST, on the other hand, supports only 16 colors and uses a more complicated video memory layout. I wrote more about that while porting DOOM to the ST. It canβt display VQA videos directly; theyβd have to be converted using a process called βchunky-to-planarβ (c2p). Achieving 15 fps would be out of reach for an 8 MHz Atari ST, so I did the wise thing and decided not to embark on such a foolish endeavor.
Except Iβm really bad at resisting temptations. The idea of FMV on an Atari ST kept creeping into my thoughts until I finally gave in. That is how STV started β less a product requirement than an excuse to squeeze an old CPU the way hackers used to.
I studied Westwoodβs VQA and kept the useful idea: a codebook of tiles, with frames mostly sending indices into that dictionary. Beyond that, the ST wanted different geometry.
VQAβs small tiles (4Γ2) looked like a poor fit. Two observations pushed me toward 8Γ8.
From earlier experiments I already knew that eight horizontal pixels are a natural unit on this machine. The 68000 has an instruction called `movep` that can update those eight pixels as four bytes, without the bit twiddling a naive planar write would need. Height eight made sense out of practical considerations: a 200-pixel column holds 25 tiles, which fits in a single 32-bit skip mask. Fitting things into a single register is good if you want performance on old hardware.
Each codebook entry is 32 bytes, ready to be copied directly into video RAM using the Motorola 68000βs famous **movep** instruction. Encoding happens on a modern host; the Atariβs job is simply to throw these tiles on screen as fast as possible.
Gory details. Jump ahead if you prefer the narrative.
Letβs start with the main idea: A frame is drawn column by column. For each column the stream carries a 32-bit skip mask, then 16-bit codebook indices only for the tiles that change, compared to the previous frame:
column 0 column 1 β¦ column 39
βββββββββββββ βββββββββββββ βββββββββββββ
β skip mask β β skip mask β β¦ β skip mask β
β (uint32) β β (uint32) β β (uint32) β
βββββββββββββ€ βββββββββββββ€ βββββββββββββ€
β idx,β¦ β β idx,β¦ β β¦ β idx,β¦ β
β (uint16; β β (uint16; β β (uint16; β
β changed β β changed β β changed β
β only) β β only) β β only) β
βββββββββββββ βββββββββββββ βββββββββββββ
Fullscreen video has no spare cycles for copying a whole framebuffer every frame. So the player uses ping-pong buffering: two screens β front and back β flipped on vertical blank. A skipped tile keeps what is already in the back buffer, which is not the previous frame but the one before that β frame Nβ2. The encoder needs to take this into account but the player can work very efficiently.
I didnβt know at first what the real bottleneck would be. At the bit rates I used, disk streaming turned out not to be an issue β I wasnβt streaming from floppy, after all. What mattered was drawing tiles as cheaply as possible. The hot path is mostly moving memory, and bandwidth is tight: avoid redundant reads and writes, and keep as much as you can in registers. Itβs one of those times where smart algorithms lose to dumb assembly code well-adapted to the hardware.
Press enter or click to view image in full size
Block artefacts, normally something we avoid. They originate from assembling the picture from codebook of tiles, some of which match better than others.
A static codebook would not survive a cutscene. Faces move, lighting shifts, logos slam onto the screen β the dictionary has to learn new tiles as the clip unfolds. I knew a dynamic codebook was necessary. By default it holds 2048 tiles (conveniently, exactly 64 KB at 32 bytes per tile). What I did not know was the update budget: how many of those entries could the player afford to replace each frame?
On the ST, updating the codebook is relatively inexpensive. Copying a few tiles into RAM each frame is negligible compared to the cost of rendering the video itself. As a result, the limit of about 32 updated tiles per frame was chosen less to protect CPU time, and more to control compression: each replacement uses up bitstream bandwidth, so the encoder must prioritize updates for the greatest quality. In practice, even higher rates β up to 128 updated tiles per frame β are possible, and videos remain smooth.
The intro video, the 16-color palette, and the codebook in a single visualization. Notice the palette changes and how tiles are replaced.
Sound went through a similar reality check. While porting C&C I first tried Westwoodβs ADPCM-compressed audio. Decoding it on the ST was possible, but it maxed out the low-end machines.
The easier path won: 12.5 kHz, 8-bit mono PCM, played straight through the Atari STEβs DMA sound hardware with no transcoding on the target. The encoder does the work; the player mostly shoves samples into a DMA buffer and lets the hardware run. In practice, thereβs also volume adaption and mixing of samples playing at the same time, but the CPU load is quite low.
The format and the player have to stay dead simple. That does not mean the encoder has to be. Most of the interesting engineering lives on the host side, where you can afford YUV math, frequency-domain metrics, and codebook policy that would be absurd at 8 MHz.
A few of the tricks:
None of that complexity shows up in the player. It only sees indices, skip bits, and the occasional codebook patch.
The choice of an optimal color palette has been subject to a lot of research. I donβt claim to have the best solution, but using a technique called Simulated Annealing allows me to find a near-optimal palette according to a well-define cost function.
Coming up with good 16-color palettes is still not ideal. Cutscenes want more color than the hardware has, and no amount of clever dithering fully hides a weak palette.
Palette switches between frames are another sharp edge. The codebook is suddenly invalidated and has to catch up over the next few frames. Transitions appear a little blurry.
Finally, the encoder has to be fast enough to run inside the remix-web app, in the browser, where people convert their game data. Thatβs not a very tight constraint, but still one that shouldnβt be forgotten.
The breakthrough was the intro: Westwood logo, metallic Command & Conquer mark, a couple of explosions. When that held together on the ST, I posted it on Twitter. After that, the rest felt less like a gamble.
Westwood and Command & Conquer logo. Notice how the tiles in the codebook are sequentially replaced after the palette change.
I expected this to be hard. With a simple player β planar tiles, skip masks, ping-pong buffers, DMA PCM β and a smarter encoder behind it, STV was more approachable than I had feared.
Imagine a slightly different 1990s: CD-based, 16-color Atari ST games with real FMV. The hardware was never the natural home for that genre. With the right split between a dumb player and a clever encoder, it gets surprisingly close.
With this idea in mind, I present to you STV-versions of the two game trailers that were included on the CD-ROMs of Command & Conquerβs 1996 prequel, Red Alert.
Blade Runner (Westwood, 1997).
Lands of Lore: Guardians of Destiny (Wetswood, 1997).
STV exists because a C&C port left a gap I could not stop poking at. If you like algorithms and old stories about wringing performance out of thin silicon, that gap is a fun place to visit.
Some Command & Conquer gameplay on the Atari ST, in beautiful 16 colors
If you want to see where this is headed β or just play some 16-color Command & Conquer on an Atari ST, TT or Falcon (or in an emulator like Hatari) β the work-in-progress port lives on itch.io: Command & Conquer for Atari ST.