Stoatworks Labs

Pilot

A ZX Spectrum tape loader for Resolume

Betav0.1.0Plugin & ModuleC++ / GLSL
Pilot — A ZX Spectrum tape loader for Resolume
No screenshot — this one is configuration inside another application.

What it does

An FFGL effect for Resolume Arena and Avenue. Most reveal transitions are a shape moving across a frame — a wipe, a circle, a slab of noise. This one is an address order. The ZX Spectrum's display file is not stored top to bottom: the byte holding a pixel lives at third × 2048 + line × 256 + character row × 32 + column, so filling it from the start of the tape to the end produces the pattern it produces, and nobody chose it.

Three things fall out of that without being designed. The picture does not wipe down the screen: it arrives in three thirds, each filling in as an eight-line interleave — the venetian blind everybody who watched a Spectrum load remembers. The colour arrives last and all at once, because the 768 attribute bytes sit after the 6144 bytes of picture, so the image lands in monochrome and colours in over the final 11% of the load. And the border is the loading signal rather than decoration: the beam paints the tape's current half-cycle as it scans, so the stripes are horizontal and there are baud ÷ 50 pairs of them down the picture.

Progress is the load. Scrub it by hand in Manual, or let Sync run it: at Clip time the tape really does run at the baud rate — 6912 bytes at 1500 baud is 37 seconds — while Beat and Bar land a whole load on Resolume's tempo. Four machines set the rate and the border: ZX 48 with the 48K ROM's red and cyan pilot then yellow and blue data, a ZX 128 turbo loader, a C64 turbo's whole-border flash and an Amstrad, with Baud trimming any of them from a quarter to four times its own rate.

Error Rate fails blocks at random, and a failed block prints R Tape loading error, 0:1 in the Spectrum's own words over whatever had arrived, holds it, and restarts the load. The failures are seeded, so scrubbing back over one shows the same one again. Background decides what an address that has not arrived yet shows: the power-on Paper, as a real machine did, black, or the live clip — which turns the whole thing into a colour-and-quantise transition over the picture.

  • The Spectrum's display-file address order as the reveal: three thirds, each an eight-line interleave
  • Monochrome first, colour last, because the attribute bytes come after the bitmap
  • A border that is the loading signal: baud ÷ 50 stripe pairs, pilot colours then data colours
  • Four loaders — ZX 48, ZX 128, C64 turbo and Amstrad — with a Baud trim from ×¼ to ×4
  • Manual, Clip time, Beat and Bar sync, with Clip time running at the real baud rate
  • Seeded block failures with the Spectrum's own loading-error report
  • Power-on Ink, Paper and Bright, and a Paper, Black or live-clip background for what has not arrived
  • Mix 0 is a byte-exact bypass
  • Universal macOS bundle and a Windows x64 DLL

Where it stands

v0.1.0, and honestly early. Everything is measured by an offline harness that drives the real plugin class headlessly, and ten of its twelve check groups open no GL context at all: the address order agrees with an independently written nested loop for all 6144 addresses, bitwise; the rendered frame matches the order table for all 49,152 pixels at 1920×1080 and at 640×480, at six points in the load, with zero disagreements; no attribute byte is revealed before byte 6144; the border advances by exactly 16 half-cycles per byte on every machine, with the same stripe count at 1080 rows as at 240; the failure rate matches 1/r within four standard errors over 20,000 draws at five rates; ten deliberately broken models are all detected; all 14 controls measurably change the picture, and Mix 0 is byte-identical to the input. Render cost on macOS is 0.09 ms/frame at 720p, 0.21 at 1080p and 0.36 at 4K — about 2% of a 60 fps frame — because the two expensive passes run at 256×192 and 32×24 whatever the composition is. It has not yet been loaded into Resolume on macOS, so how the parameters present in the inspector and how Arena's own textures behave are untested. On Windows it has: a build of this source loads, registers and renders in Resolume Arena 7.27.1 on software rendering (win-lab, no GPU), passing all nine of the fleet's host checks with every parameter as declared. The universal build has never run on Intel. Only the ZX 48 models a documented loading routine; the other three machines are looks in the same shape, and none has been compared against a real tape or an emulator. Baud drives the border and the Clip time period but not the reveal in Manual, on purpose. A cell's colours are recomputed every frame, so on moving footage they change during the load. There is a user guide and a browser demo, which is a port rather than the plugin; no OpenFX port and no factory presets. Check it in your own rig before trusting it in a show.

Watch it running

Pilot video thumbnail

Nothing loads from YouTube until you press play.Watch it there instead