ID SOFTWARE · GPL RELEASES · 1990–2004

THE CARMACK ARCHIVE

Five specimens, all working. The throughline of the work: none of it makes anything fast. It deletes the work instead. Companion to the essay the work that never happens.

01

The Scroll / Commander Keen, 1990

No source released. Reconstructed by Fabien Sanglard. Overnight build, Softdisk, September 1990.

The EGA could not redraw the screen fast enough, so scrolling moved into hardware registers and only changed tiles were redrawn. ← → to scroll, or run it on auto. The bar is the redraw: adaptive stays near the floor.

full redraw repaints every visible tile, every frame
; the reconstruction:
; scroll via CRTC_START + Horizontal Pel Panning: zero pixel writes.
; on reaching the edge, jolt: compare tile IDs, redraw only mismatches.
; Keen 4-6: wrap at the 64K aperture, redraw the leading edge only.
redrawn = changed_tiles / total_tiles   ; ~16%, not 100%
02

The Ray / Wolfenstein 3D, 1992

id-Software/Wolf3D · WOLFSRC/WL_DR_A.ASM · "I was 21 years old when I wrote most of the code."

One ray per column, integer grid walk, no floating point unit, no division. WASD / arrows to walk the map. R toggles the rays, T toggles texture.

click the canvas first, then move
; WOLFSRC/WL_DR_A.ASM, AsmRefresh. the inner march:
vertentry:
 test [BYTE tilemap+si],0ffh
 jnz hitvert
passvert:
 add bx,[xtilestep]          ; 16.16 fixed point DDA
 ; ...
 jmp vertcheck
03

The Flicker / Quake, 1996

WinQuake/r_light.c:33, R_AnimateLight · twelve strings in QW/progs/world.qc

Quake's animated lighting is twelve text strings. Each frame: k = (time*10 % len); value = (map[k]-'a')*22. The flame height follows the string. Assign a style to each torch.

; WinQuake/r_light.c:33, R_AnimateLight
i = (int)(cl.time*10);
k = i % cl_lightstyle[j].length;
k = cl_lightstyle[j].map[k] - 'a';
k = k*22;
d_lightstylevalue[j] = k;
04

The Tree / Doom, 1993

id-Software/DOOM · linuxdoom-1.10/r_bsp.c:552 · verified against the raw source

One cross product per node sorts the map: near side always, far side only if visible. Drag the viewpoint and watch the draw order recompute on both the map and the tree.

; linuxdoom-1.10/r_bsp.c:552
side = R_PointOnSide (viewx, viewy, bsp);
R_RenderBSPNode (bsp->children[side]);       ; near: always
if (R_CheckBBox (bsp->bbox[side^1]))
    R_RenderBSPNode (bsp->children[side^1]); ; far: maybe
05

The Root / Quake III Arena, 1999

id-Software/Quake-III-Arena · code/game/q_math.c:552 · both comments intact

Float bits are piecewise log-linear, so an integer shift-and-subtract approximates a logarithm. Drag the input and watch the guess converge. The amber bars are error, on a log scale.

folklore: not his
; code/game/q_math.c:552
i  = * ( long * ) &y;              // evil floating point bit level hacking
i  = 0x5f3759df - ( i >> 1 );    // what the fuck?
y  = * ( float * ) &i;
y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration

← the essayhome