ID SOFTWARE · GPL RELEASES · 1990–2004
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.
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.
; 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%
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.
; 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
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;
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
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