Angles and fixed-point arithmetic
Apache's renderer uses a full unsigned 32-bit turn: 0x40000000 is 90 degrees, 0x80000000 is 180 degrees, and addition wraps at one revolution. Model matrices use signed Q31 components. Terrain and object positions use integers; the realistic helicopter model works in floating point and converts its results for the renderer.
Trigonometry files
The game loads four little-endian tables. If they are absent, initialise_trig_tables_ generates and saves them. Running that original generation path produces exactly the supplied files: 30,724 entries, no differences. The reference harness intercepts the save boundary, so it never rewrites the installation.
| File | Entries | Input | Stored output |
|---|---|---|---|
| SINCOS.TBL | 10,241 | i / 8192 turns |
sin(angle) × (2³¹−1) |
| ARCSIN.TBL | 8,193 | i / 8192 |
angle scaled to 2³²−1 per turn |
| ARCCOS.TBL | 8,193 | i / 8192 |
angle scaled to 2³²−1 per turn |
| ARCTAN.TBL | 4,097 | i / 4096 |
angle scaled to 2³²−1 per turn |
The sine file contains a complete revolution plus another quarter, including the last endpoint. Cosine reads the same storage with a quarter-turn offset. Matrix construction rounds a 32-bit angle to the nearest of 8,192 samples, giving steps of 0.0439453125 degrees. The inverse functions recover signs and quadrants around their positive-domain tables.
The generator uses 6.28318530718 for a full turn in radians and 0.15915494309188485 for its reciprocal. Floating results are truncated toward zero. Against mathematical sine, the largest stored sine error is about 1.000082 integer units, or 4.657 × 10⁻¹⁰ after normalisation. This is the table-value error; the larger visual limitation is sampling the input angle in finite steps. The inverse tables have a maximum difference of about one stored angular unit.
tools/math_tables.py records every file hash, the largest mathematical error, its index and the comparison with original execution in tables.json.
Multiplication and conversion
A typical Q31 product is formed with a signed 32×32 multiply, then shifted and rounded using the next bit. For an exact signed product p, the result is (p + 2³⁰) >> 31. The positive half-way bias matters when translating negative products; rounding an absolute magnitude and restoring its sign is not equivalent.
The Watcom helper __CHP temporarily changes the x87 rounding mode to truncation, runs FRNDINT, and restores the control word. It leaves the rounded value on the floating-point stack. This helper appears throughout the physics and instrument code before integer stores. It does not return an ordinary integer in EAX.
The flight model also uses x87 sine, cosine and tangent directly. The renderer's table quantisation should not be applied to those calculations.