Renderboy
Renderboy is a software renderer I wrote in C and x86 assembly for my game Ring Village. It runs on real DOS machines in VGA mode 13h (320×200, 256 colours), and I also ported it to Windows and to the web with Emscripten.
An early prototype of Renderboy draws my short narrative game Did You See It?, which you can play in your browser.
Details
- Quake-style span rendering. Large walls and floors go through an edge/surface span pass modelled on Quake's. It works out the nearest surface at every pixel first, so each pixel is textured only once, and it shares edges between neighbouring polygons. Small models use a depth-tested pass, with separate passes for sprites and UI.
- Perspective-correct texturing. One true divide every 16 pixels, with cheaper paths for floors and ceilings (one divide per row) and orthographic views (one per polygon).
- One camera from first person to overhead. A single setting blends from full perspective to orthographic.
- Doorways as portals. Each doorway's opening is drawn into a stencil, the space beyond is drawn through a placement transform, and an extra clip plane removes geometry in front of the door. This is a portal graph, which accomplishes the same thing as Quake's BSP.
- Hand-scheduled Pentium assembly. The inner texture loop pairs instructions for the Pentium's two pipelines and computes each texel address a pixel early. It also starts the next block's divide on the FPU while the integer loop runs, the same trick Quake uses, for about 6 cycles a pixel.
- Fixed-point where it counts. Vertex work uses 32-bit floats and pixel work uses 16.16 fixed point. The x87 FPU drops to 24-bit precision around the hot code, which roughly halves the cost of a divide on a Pentium.
- Palette lighting tables. Light levels for the 256-colour palette are generated offline in the Oklab colour space, so shading is a single table lookup.
Performance
I benchmark on an emulated Pentium II 400 running real MS-DOS 6.22 in 86Box. A Quake-sized test level with six models runs at 100 fps at 320×200. For a rough comparison, Quake's own timedemo runs at about 90 fps on the same machine, though it's a different scene. Profiling was super important here, so I built support code that lets the modern Tracy profiler open captures from a program running on a DOS machine.