Files
tdkpin/tdkpin-rs/CHANGELOG.md
T
ddidderr 3dce159965 fix(physics): match live tangent response transitions
Correct the common projection to spin*0.4 + normal_velocity*response_tangent and seal line/circle behavior against current Wine one-substep traces. Preserve record-two's in-response special-respawn continuation, producing the live (16698,21191)/(-302,-1809) state after publishing (17000,23000)/(0,3040), and update the readable C evidence.

Test Plan:
- bash original/tools/test_reconstructed_c.sh
- python3 original/tools/audit_reconstruction.py --require-complete
- cargo test --all-targets
- cargo clippy --all-targets --all-features -- -D warnings
- rumdl check original/C_RECONSTRUCTION_FINAL_AUDIT.md tdkpin-rs/CHANGELOG.md tdkpin-rs/RECONSTRUCTION.md tdkpin-rs/README.md
- live Wine record 2 trace: /tmp/original-special-respawn.csv
- live Wine object 155 trace: /tmp/original-circle155-after.csv
- git diff --check
2026-08-23 19:42:23 +02:00

11 KiB

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

Fixed

  • Correct the common Real48 tangent projection to spin*0.4 + normal_velocity*response_tangent; live one-substep probes now match horizontal drain (-302,-1809), ordinary circle (94,564), and bumper (197,3096) transitions instead of rounding a bare coefficient away.
  • Gate dynamic record 174/175 impulse transfer on the other slot's capture age: a held ball remains velocity-stationary and the moving response retains its full normal velocity instead of always subtracting 1,000.
  • Restore 1000:ae6e's required-ball special respawn: armed or completed effect-seven play grants one final (17,23)/(0,3040) ball without consuming a marker, clears required state, and suppresses record 148 until the next broadphase-active type-4 record reenables it.
  • Replace the invented post-move y>470 fallback with the original pre-scan prediction bounds x<=0 || x>340000 || y<=0 || y>460000, including one-slot removal during multiball and next-substep handling after a response.
  • Remove the invented 180 ms whole-frame nudge shake; original nudges affect ball-slot velocities, sound, and Tilt state without moving the viewport.
  • Match SndPlaySound(SND_ASYNC|SND_NODEFAULT) playback: stop the previous WAV before every new resource and use full host mixer volume instead of an invented 72 percent attenuation/overlap.
  • Load and draw all DAT400-407 player/effect sprites at (55,79), preserving the original saved 14x14 wheel overlap at (84,77); selected bonuses, collect-bonus, and release-ball states are now visible.
  • Restore display blits from 1008:0996/1008:0b9e: 130x40 score fields at X=478, eight places ending at X=606, exact 139x31 configured-player rows, 11x11 active/status markers, 5x5 remaining-ball markers for every player, and strict signed score-status thresholds independent of media awards.
  • Import exact [Settings] Language, Speed, and singular Sound values from an adjacent/original TDKPIN.INI before creating portable JSON. Fresh installs now inherit the distributed German help setting; F12 is again a silent runtime-only toggle and cannot leak into a later save.
  • Replace modern high-score/name overlays with the reconstructed HighScore child: exact DAT993 360x300 background, heading/row coordinates, unpadded scores, and DIALOG 32514 caption, prompt, 21-character edit, OK, and Cancel. Escape now follows original Cancel semantics and empty names are accepted.
  • Restore the staged loading presentation by blitting original DAT994 over DAT995 at (202,328), height 13 and clipped width (stage-1)*7; correct the previously impossible Pascal-order C interpretation of a 328x202 blit.
  • Restore the original idle/attract timer animation: target and word-quad chases, magnetic flashes, five-record strip, four-point chase, DAT801-809 item progression, and the circular WELCOME TO THE MACHINE BITMAP500 marquee. Move gameplay item frames to their exact (123,300) destination.
  • Match central score/event side effects: every stored collision candidate clears its ball slot's capture age, Tilt suppresses all score and rule-record mutations, and active multiball doubles points before permanent Double can double them again.
  • Scan static, capture, trigger, magnetic, and dynamic record ranges in exact ID order with a separately tracked prediction. Preserve the raw scanner's first-detected-candidate quirk even when a later record is geometrically nearer, plus type-3 and dynamic-record broadphase behavior.
  • Run type-3/type-4 processing before response and position publication: captures now test the old position, contacted type-3 rims contribute radial candidates, triggers mutate the live motion first, and sensor IDs execute in binary order without Hold/Complete prematurely ending the record scan.
  • Apply the collision table's predicted-position broadphase bounds before type-1/type-2 detection, including the registered five-pixel ball margin, and retain unresolved candidates until the selected response phase.
  • Match rectangular type-4 magnetic gates to raw 1000:9b69: enter only when the previous position is inside, then deactivate when the newly predicted position exits any edge, replacing a swept-intersection approximation.
  • Decay the 16-bit tilt counter once per selected 50/40/30/20/10 ms detail callback, replacing an invented independent 30 ms accumulator.
  • Match the multiball nudge path's saved-slot behavior: consume the active formula's random draws, then add one shared fixed/random impulse to both slot velocity records instead of applying different formulas to each ball.
  • Restore auxiliary response thresholds/kicks for bumpers 51-53 and line records 55, 74, and 107, including weak-hit bumper scoring, WAVE 2019 on kicked unscored rails, and the original tilt suppression.
  • Preserve every collision record's +0x49 layer mask and select upper layer 1 or lower layer 2 from the ball's previous 250,000-millipixel Y boundary.
  • Match the original detail callback's slot-major integration order, stop a slot's remaining 10 ms substeps after its first collision/action, delay a newly requested second ball until the next callback, and retain ball-two identity while a captured/drained ball one is collapsed.
  • Run type-3 captures and type-4 triggers for both live ball slots, including per-slot capture age/contact ownership, exact captured-slot removal, survivor promotion, and the effect-seven ball-number guard against a third ball.
  • Spawn effect-seven ball 2 from record 148 at (17,23) with exact (0,3040) millipixel velocity, instead of launching a guessed second ball upward from the shooter lane.
  • Replace invented bumper outline/cooldown effects with the original per-record 5/20/10 callback countdowns and exact overlay-A render rectangles for bumpers 51-53 and targets 140-147/150-152.
  • Replace the free-running wheel animation with the original six-callback 91x90 target rotation, WAVE 2011 start, exact DAT600 frames/target positions, and state-6 rotation of the five per-player contact/item values.
  • Restore the complete 281-callback DAT600 panel sequence after the fifth lock hole, including physics suspension, contact/item cleanup, all nine image phases, and the original WAVE 2013/2012/stop boundaries.
  • Remove the invented attract-screen instruction panel and stop assigning the original F2/F3 keys to modern overlays. The idle view is the original table; optional settings/high-score viewers move to F10/F9.
  • Batch physics and flipper publication on the original 50/40/30/20/10-ms detail callbacks with exactly 5/4/3/2/1 internal 10-ms substeps, instead of exposing every substep on host render frames.
  • Separate flipper key flags from rendered/collision position so press/release edges and WAVE 2021 occur only when the detail timer processes them.
  • Add a bit-exact Borland Real48 core and route speed clamps, type-1 circles, type-2 segments, moving flippers, capture pulls, trigger randomization, and magnetic impulses through its original rounding behavior.
  • Preserve per-ball Real48 spin and use it in collision tangent response, so zero-spin C fixtures and retained-spin Wine traces are both represented.
  • Implement dynamic records 174/175 with bidirectional ball impulse transfer and the original post-collision speed clamp instead of a one-sided secondary bounce.
  • Split collision contact state into per-player 16-bit type-3 contact words and transient type-4 entry flags. Type-3 records now use the original deep-inside gate, v*0.9 +/-150 pull, stationary sound/contact publication, 5-step age progression to 300, and 99/2 completion sentinels.
  • Replace the live-fitted flipper transfer polynomials with the reconstructed 1000:7ed9 millipixel geometry gates, penetration, gain, response-record, velocity, and position calculations for both directions and both balls.
  • Preserve every gameplay millipixel across the float-only render projection so exact integer physics results are not changed when stored for drawing.
  • Restore launcher input to the setup scalar: each Down keydown subtracts 750 millipixels, release subtracts 1,500, then applies the recovered -3800 and -2280 clamp/jitter branches and the ten original decoration thresholds.
  • Apply the original independent 1.03 - Random * 0.08 X/Y velocity response after entering radius-bearing type-4 targets, preserving both motion and the subsequent shared PRNG sequence.
  • Check every player against the high-score table when their own last ball is lost, prefill the original TDK Pinball Player name, show the table before resuming the next player, and use the original signed-high/unsigned-low score ordering instead of selecting only the maximum score at whole-game end.
  • Preserve each player's complete rule-record state across turn changes instead of globally clearing wheel holes, top targets, 176 active/contact slots, selected effect, and multiball readiness on every drain.
  • Store lock-hole and effect awards in the original per-player secondary score instead of a global bonus. The fifth hole now transfers 310000 * score_multiplier, clears it, increments the multiplier and ball count, while effect 6 transfers the same display value and drain leaves it intact.
  • Replace the cooldown/float-meter nudge approximation with the original Left-Shift, keypad-3, and Space formulas using scalar 15, the shared Borland random stream, 32-bit velocity wrapping, and the decaying 16-bit +25 tilt counter with its randomized 30..39 threshold.
  • Replace the Xorshift gameplay RNG with the original Borland linear stream and unbiased Random(n) high-word mapping. Launcher variation, effect selection, claw terminals, and magnetic-field impulses now share the recovered sequence.
  • Restore the magnetic-field response as vx * 0.9 and a randomized -3800 * (1 - Random * 0.3) vertical impulse instead of a fixed upward speed.
  • Dispatch the original per-call-site sound sequences instead of assigning one guessed WAV to each logical event. This removes the nonexistent WAV 2022 playback and restores bank, trigger, capture, nudge, tilt, and drain cues.
  • Advance media/extra-ball thresholds only from score additions, preserve 32-bit score wrapping, and restore the ninth-diamond 24,464-point award plus the later double-score and secondary-score bank states.
  • Match the original 640x460 window, native 16x28 score glyphs, and TDK Pinball Machine 1.00 title so the recovered artwork is presented one-for-one instead of enlarged or resampled.