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).
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
| Item | What it exercises |
|---|---|
| type-punning | The 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. |
| 0x5f3759df | The 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-float | The 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. |
| metaballs | The 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.