// chunk5Setup: bit-perfect C transliteration of chunk5 // SetupViewProjection (chunk5.s lines 203-432) and its math // dependencies in chunk4 (cos table at $141A, L177B/L1778 lookups, // ZPScale multiplier). // // Produces the same int16 3x3 rotation matrix the original Apple II // FS2 stores at $78..$89, given the same inputs ($6C/$6D 16-bit // "yaw" -> X-axis, $6E/$6F "pitch" -> Z-axis, $70/$71 "bank" -> // Y-axis, ViewDirection byte). The disassembly's input labels are // mislabeled vs standard aviation -- see SESSION_RECOVERY.md. // // Validated cell-for-cell against `port/bin/fs2trace --matrix` (the // 6502 emulator running the actual chunk5 binary). #ifndef CHUNK5_SETUP_H #define CHUNK5_SETUP_H #include // Run SetupViewProjection with the supplied inputs. Output is the // 3x3 matrix as it appears at $78..$89 (post-L6301 col shifts: // col 0 >>= 1, col 2 >>= 2). Each output is int16 in chunk5's R // (camera-to-world) layout, ready to be mirrored into // CameraT.rotChunk5 / writableRam[$78..$89]. // // Inputs: // yaw16 = $6C/$6D 16-bit signed (X-axis rotation in chunk5 conv) // pitch16 = $6E/$6F 16-bit signed (Z-axis rotation) // bank16 = $70/$71 16-bit signed (Y-axis rotation) // vd = $0A70 ViewDirection byte // radarView = $0836 RadarView flag (1 = radar view) void chunk5SetupViewProjection(int16_t yaw16, int16_t pitch16, int16_t bank16, uint8_t vd, uint8_t radarView, int16_t outMatrix[3][3]); // Lower-level primitives, exposed for unit tests. All match their // 6502 counterparts cell-for-cell (validated by chunk5SetupSelfTest). // L177B: cos lookup. byteAngle is the 8-bit angle (256 = full // circle); subByte gives sub-byte fractional precision via linear // interpolation against the next entry. Result is Q1.15 cos(angle). int16_t chunk5L177B(uint8_t byteAngle, uint8_t subByte); // L1778: sin lookup. Equivalent to L177B(byteAngle - 64, subByte) // since sin(x) = cos(x - 90 deg). int16_t chunk5L1778(uint8_t byteAngle, uint8_t subByte); // ScaleC2ByC4 / ZPScale: 16-bit signed Q-format multiply with // chunk4's specific rounding pattern (chunk4.s lines 1565-1744). int16_t chunk5ScaleC2ByC4(int16_t a, int16_t b); // Self-test: sweeps a few input combinations through the cascade // and aborts if any cell deviates from the known oracle output. // Returns 0 on success, non-zero on failure. int chunk5SetupSelfTest(void); #endif