Metaballs

Rendering & Graphics

Gooey blobs merging and splitting on a Super Nintendo, their glow computed by the legendary Quake III fast inverse square root — the union { float f; uint32_t i; } bit hack that reads a float's storage as an integer, mangles it with the magic constant 0x5f3759df, and reads it back as a float. Runs automatically; no joypad needed. Written in C and compiled with the llvm-mos-based 65816 toolchain (+mos-a16, 16-bit accumulator mode).

loading core…

Self-running demo — the blobs merge and split on their own.

Click the screen to focus, then watch. Tab away and it pauses.

What it is

Metaballs glow with a 1/distance falloff, so drawing them needs a reciprocal square root — normally a slow operation. Quake III famously computed it with a bit-level trick that treats the float's raw bytes as an integer:

float y = number;
i  = *(uint32_t*)&y;             // read the float's bits AS an int
i  = 0x5f3759df - (i >> 1);      // what the...?
y  = *(float*)&i;                // read the int's bits BACK AS a float
y  = y * (1.5 - x2*y*y);         // one Newton step -> 1/sqrt(x)

Halving the integer form of the bits roughly halves the exponent (a square root), and subtracting from the magic constant negates it (the reciprocal); one Newton step cleans up the estimate. Here it drives four blobs summed into a field. It stays bit-exact across every codegen mode.

Compiler stress-test

ItemWhat it exercises
type-punningThe trick reads a float's storage as an integer, mangles the bits, and reads them back as a float. That aliased load/store — the same four bytes interpreted two ways through a union — is the codegen path under test.
0x5f3759dfThe legendary magic constant from Quake III's source. Halving the integer bits approximates halving the exponent (a square root in log space); subtracting from the constant negates it (the reciprocal). On the 65816 it appears as the byte immediates #$5f #$37 #$59 #$df.
soft-floatThe 65816 has no floating-point unit, so every multiply is a runtime call (__mulsf3). The single Newton-Raphson refinement is written one operation per statement so the target never fuses a multiply-add differently from the host — keeping it bit-exact.
metaballsThe reciprocal-sqrt gives 1/dist falloff around each blob; summing four of them and thresholding the total yields gooey shapes that merge and split. The gate folds the raw float bits of the bit hack; host == default == +mos-a16 == +mos-xy16 == bsnes-jg, byte for byte.

Written in C with the llvm-mos 65816 toolchain and verified against bsnes-jg (and MAME where the SPC700 IPL is present). Hit Verify fidelity to reproduce the build gate's WRAM assert (gate hash 0xAEBE — a fold of the raw float bits of the bit hack over a sweep of inputs) live in this tab. No far pointers — the same source passes every way: host == default == +mos-a16 == +mos-xy16 == bsnes-jg, -verify clean.