diff --git a/tdkpin-rs/PARITY_AUDIT.md b/tdkpin-rs/PARITY_AUDIT.md new file mode 100644 index 0000000..ac11d4d --- /dev/null +++ b/tdkpin-rs/PARITY_AUDIT.md @@ -0,0 +1,83 @@ +# Rust player-experience parity audit + +Audit date: 2026-08-23 + +## Decision + +The Rust rewrite passes the reconstructed-binary requirements for the same game +and player experience at the 640x460 logical gameplay boundary. No known raw, +placeholder, guessed, partial, or unverified gameplay unit remains in the Rust +path. This is a semantic and presentation result, not a claim that a native +Rust executable is a byte-identical Win16 implementation. + +The authoritative source is the preserved executable with SHA-256 +`a9022f1894e3e6e21fc42e8f6c932f7c549ca77f63aaa0c488bb9d55d9d0174c`, +the complete readable C under `../original/reconstructed/`, and the zero-gap C +ledger in `../original/C_RECONSTRUCTION_FINAL_AUDIT.md`. + +## Requirement matrix + +| Requirement | Binary/C basis | Rust evidence | Result | +| --- | --- | --- | --- | +| Original presentation | All 63 resources round-trip; DAT/bitmap bounds and GDI call sites are reconstructed | Original images/samples are embedded; loading, attract, game, panel, target, effect-seven, high-score, and name-entry scenarios export 640x460 frames | Verified | +| Collision inventory | All 175 initialized records are typed in `OBJECTS.tsv`; raw scan order is address-linked | 109 type-2 lines, 40 type-1 circles, all type-3/4 mechanisms, layer masks, response fields, and initial activity are represented; relative chains 54-59 and 69-74 have record-exact tests | Verified | +| Fixed-point/Real48 physics | `1000:c79c` and Borland runtime arithmetic are reconstructed; the DOS reference probe is bit-exact | 10 ms millipixel steps, both speed clamps, four board bounds, first-record selection, signed dot-product tangent response, spin, auxiliary kick, and dynamic-ball transfer use exact-width arithmetic | Verified | +| Live collision behavior | Stopped Wine probes expose position, velocity, and six-byte spin | Rails, circles, bumper, record 2, record 57, and record 72 have exact expected transitions in Rust and C tests | Verified | +| Timer ordering | `1000:eab1` fixes 5/4/3/2/1 substeps, ball-slot order, countdowns, mechanisms, flippers, and Tilt decay | Timer-batch, collision-break, per-slot, target-rotation, panel, claw, countdown, and Tilt tests cover the recovered callback order | Verified | +| Attract mode | Raw `1000:01b7-063b` distinguishes quotient and remainder outputs; marquee GDI lifetime is reconstructed | `%32/2`, `%32/4`, `%40/4`, `%16/4`, `%144/8`, magnetic `%32`, and six-callback marquee cycles are tested and rendered | Verified | +| Inputs | `1000:638e/6bf8` define low-byte scans, Key-Up actions, auxiliary-window gate, launcher impulses, nudges, Tilt, and flipper latches | Both Ctrl/Enter aliases, both plus positions, release-time add/nudge/F12, held launcher, flipper rearm, and auxiliary-window blocking follow those paths | Verified | +| Rules and scoring | `1000:b476`, `1000:c4e1`, `1000:bc36`, `1000:ae6e`, and `1000:9e85` define awards and state transitions | Bank progression, ninth-diamond order, ball-scoped double, marker comparison, lock transfer, special hole, all seven effects, Type-3 Tilt finish, and score/sound ordering have focused tests | Verified | +| Multiball | Records 148, 174, and 175 plus timer collapse/spawn paths define ownership and lifetime | Deferred spawn, per-slot capture age, survivor promotion, no-third-ball guard, nudge, fifth-lock deferral/reset, special respawn, and contact clearing are tested | Verified | +| Player turns | `1000:ae6e` saves all record activity/contact mirrors and advances live players | Four-player bounds, add-before-launch, per-player rule state, final-ball high-score ordering, flipper key lifetime, and normal/special drain behavior are tested | Verified | +| Audio | Sixteen WAV resources and every in-image play/stop call are inventoried | Samples are unchanged; monophonic async replacement, full volume, Tilt suppression, threshold precedence, panel stops, and no-WAV-2022 behavior are represented | Verified | +| High scores/configuration | The 276-byte `IWIK` table, dialog 32514, HighScore child, and INI reads are reconstructed | Signed-high comparisons, all ten entries, 21-byte name semantics, OK/Cancel flow, localized help, original settings names/defaults, and screenshots are tested | Verified | +| Randomness | The Borland LCG, high-product `Random(n)`, Real48 result, and program-global seed are reconstructed | All gameplay draws use one exact stream; seeded traces are repeatable and the final seed continues across games | Verified | +| Stability/build | Native replacement must preserve finite state and compile on supported hosts | Production Linux build, 125 Rust tests, strict Clippy, two-minute finite autoplay, and Windows/macOS cross-target checks pass; native CI covers all three hosts | Verified | + +## Differential evidence + +- Record 2 special response: + `(157000,453000)/(0,3000)` publishes the special ball at + `(17000,23000)/(0,3040)` and continues to + `(16698,21191)/(-302,-1809)`. +- Record 57 left relative slingshot: + `(75530,354765)/(3000,15)` becomes + `(77369,356597)/(1839,1832)`, Real48 spin `-5.28` + (`83 5d 8f c2 f5 a8`). +- Record 72 right relative slingshot: + `(235348,356825)/(-3000,15)` becomes + `(233253,358494)/(-2095,1669)`, Real48 spin `+5.46` + (`83 86 eb 51 b8 2e`). +- Ordinary circle 155, the outer/inner shooter rails, bumper response, all four + claw terminals, moving flippers, Type-3/4 records, scoring, and multiball + also have focused C/Rust or Wine-backed tests documented in + `RECONSTRUCTION.md`. + +## Deliberate host substitutions + +- The native fixed window replaces ObjectWindows/Win16 ownership, but retains + the title, logical client size, original pixels, controls, modal gameplay + blocking, and visible flows. +- Portable JSON replaces writes to `HISCORES.DAT` and `TDKPIN.INI`; the original + files are imported, while table ordering, names, settings, and UI semantics + remain unchanged. F9/F10 expose additional viewers/settings without replacing + any original gameplay key. +- Windows and macOS were cross-checked in this Linux checkout; native execution + on those hosts is delegated to the repository's three-OS CI matrix. The + semantic core is platform-independent and has no target-specific branches. + +## Reproducible final gates + +```sh +cargo build --profile production +cargo test --workspace --all-targets --all-features +cargo clippy --workspace --all-targets --all-features -- -D warnings +cargo check --target x86_64-pc-windows-gnu +cargo check --target x86_64-apple-darwin +bash original/tools/test_reconstructed_c.sh +python3 original/tools/audit_reconstruction.py --require-complete +``` + +The C ledger gate reports zero raw, partial, restored, unknown, blocked, or +unclassified required units. The only files intentionally outside commits are +user diagnostic media in the repository root.