diff --git a/tdkpin-rs/CHANGELOG.md b/tdkpin-rs/CHANGELOG.md index 88533a8..fdb3eba 100644 --- a/tdkpin-rs/CHANGELOG.md +++ b/tdkpin-rs/CHANGELOG.md @@ -8,19 +8,31 @@ and this project adheres to ## [Unreleased] +## [1.1.0] - 2026-08-29 + +### Added + +- Add a static WebAssembly (WASM) browser build and web shell for TDK Pinball, + persisting settings and scores in browser localStorage. +- Add a standalone Axum and SQLite high-score service (`highscore-server`) for + an optional shared top-ten leaderboard, including an nginx reverse-proxy + configuration and API endpoints. +- Route the browser high-score table through the shared service when available, + retaining the local-storage fallback when offline or unconfigured. + ### Fixed +- Allow launcher input while tilted so a waiting ball in the shooter lane is not + stranded after a tilt, while retaining launch sound suppression. - Bundle the official Macroquad browser loader and WASM bootstrap locally so a CSP does not require inline JavaScript or code from `not-fl3.github.io`. -- Add the optional same-origin Axum/SQLite high-score service, browser - fetch/submit integration, and an nginx reverse-proxy example. Browser - settings retain their local-storage fallback, while the shared table is - returned by the service. +- Keep the web canvas centered at the original fixed 640x460 presentation size + instead of scaling with the browser viewport. - Seed the initial gameplay random stream from the startup clock so the first maximum-power launcher shot is not identical on every run. - Require an unconsumed record-148 contact before the effect-seven special - respawn, preventing a released reserve ball from being duplicated after - both multiball balls drain. + respawn, preventing a released reserve ball from being duplicated after both + multiball balls drain. - Apply type-4 entry latches only inside each target's registered broadphase, preventing an unrelated multiball slot from clearing an upper-left target's latch and causing repeated scoring while the ball remains there. @@ -40,13 +52,13 @@ and this project adheres to 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 including record 148's contact word, and - suppresses record 148 until the next broadphase-active type-4 record - reenables it. + effect-seven play grants one final `(17,23)/(0,3040)` ball without consuming a + marker, clears required state including record 148's contact word, 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. + 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 @@ -57,8 +69,8 @@ and this project adheres to 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. + 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 @@ -71,17 +83,17 @@ and this project adheres to 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. Each nested phase uses the binary's remainder first: `%32/2`, - `%32/4`, `%40/4`, `%16/4`, and `%144/8`. Move gameplay item frames to their - exact `(123,300)` destination. + chases, magnetic flashes, five-record strip, four-point chase, DAT801-809 item + progression, and the circular `WELCOME TO THE MACHINE` BITMAP500 marquee. Each + nested phase uses the binary's remainder first: `%32/2`, `%32/4`, `%40/4`, + `%16/4`, and `%144/8`. 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 +- 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: @@ -89,16 +101,16 @@ and this project adheres to 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. -- Correct the two relative slingshot initializer chains after records 55 and - 70: circles 56/58/71/73 and lines 57/59/72/74 now accumulate from each - preceding path endpoint exactly as the 175-record ledger specifies. The - flagless TDK companion lines also retain their zero contact/link field rather - than carrying unused synthetic head IDs. Record 57 additionally matches the - live original's `(75530,354765)/(3000,15)` to - `(77369,356597)/(1839,1832)` transition; symmetric record 72 matches - `(235348,356825)/(-3000,15)` to `(233253,358494)/(-2095,1669)`. + type-1/type-2 detection, including the registered five-pixel ball margin, and + retain unresolved candidates until the selected response phase. +- Correct the two relative slingshot initializer chains after records 55 and 70: + circles 56/58/71/73 and lines 57/59/72/74 now accumulate from each preceding + path endpoint exactly as the 175-record ledger specifies. The flagless TDK + companion lines also retain their zero contact/link field rather than carrying + unused synthetic head IDs. Record 57 additionally matches the live original's + `(75530,354765)/(3000,15)` to `(77369,356597)/(1839,1832)` transition; + symmetric record 72 matches `(235348,356825)/(-3000,15)` to + `(233253,358494)/(-2095,1669)`. - 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. @@ -107,11 +119,11 @@ and this project adheres to - 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. +- 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 @@ -119,9 +131,9 @@ and this project adheres to - 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. +- 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. - Treat record 148 as the special/multiball hole represented by player item 20; capturing it preserves all five lock-hole items and contacts instead of inventing an immediate wheel reset. Its exact 17x17 overlay-A Word-Quad at @@ -132,12 +144,12 @@ and this project adheres to - Render the five cumulative bumper-value lamps from original player items 1-5 at their recovered Word-Quad bounds as the value rises from 1,000 to 6,000. - Render the nine in-bank hit states for record heads 90/93/96/99/102 and - 109/112/115/118 from their exact overlay-A bounds until bank completion - rearms each three-line group. -- 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. It advances - only for an active ball, pauses in the launcher, and survives a normal drain. + 109/112/115/118 from their exact overlay-A bounds until bank completion rearms + each three-line group. +- 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. It advances only + for an active ball, pauses in the launcher, and survives a normal drain. - 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. A fifth lock captured @@ -148,9 +160,9 @@ and this project adheres to - 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. +- 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, @@ -158,8 +170,8 @@ and this project adheres to 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 +- 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 @@ -199,11 +211,12 @@ and this project adheres to - Match the original low-byte keyboard scans: both Ctrl keys operate the left flipper, both Enter keys operate the right, and the physical `0x1b` main-keyboard plus/right-bracket position starts or adds players. -- Dispatch add-player, nudge, and F12 sound-toggle actions on key release through - the original `1000:638e` timing rather than on their initial key press. +- Dispatch add-player, nudge, and F12 sound-toggle actions on key release + through the original `1000:638e` timing rather than on their initial key + press. - Enforce the original auxiliary-window input gate: F1 and F12 are ignored while - Help, HighScore, or name-entry UI is open instead of controlling the main - game through a child window. + Help, HighScore, or name-entry UI is open instead of controlling the main game + through a child window. - Route a single-ball type-3 completion during Tilt through `1000:ae6e` instead of granting a free launcher reset: lock holes consume the ball, while record 148 can still take its required-state special-respawn branch. @@ -219,18 +232,18 @@ and this project adheres to playback and restores bank, trigger, capture, nudge, tilt, and drain cues. Type-4 WAVE 2004 and bumper WAVE 2006 now precede their score mutations so a simultaneously crossed media marker leaves WAVE 2007 audible, as in the - monophonic original. A tilted drain suppresses WAVE 2008 before reset, while - a following flipper-release edge may still play WAVE 2021 after reset. + monophonic original. A tilted drain suppresses WAVE 2008 before reset, while a + following flipper-release edge may still play WAVE 2021 after reset. Bumper/TDK bank completion WAVE 2017 likewise precedes its 50,000 or 10,000..24,464 award, preserving the marker cue when that award crosses one. -- Advance media/extra-ball thresholds only from score additions, preserve - 32-bit score wrapping, and restore the ninth-diamond ordering: its 24,464 - award remains single, then ball-scoped double scoring and all three magnetic - fields activate before the collision's static score. Further completed banks - during that ball add 100,000 to the secondary score; a normal ball end clears - the multiplier, while effect seven's special respawn preserves it. Marker - comparisons retain the binary's signed-high/unsigned-low 32-bit ordering - after score wrap. +- Advance media/extra-ball thresholds only from score additions, preserve 32-bit + score wrapping, and restore the ninth-diamond ordering: its 24,464 award + remains single, then ball-scoped double scoring and all three magnetic fields + activate before the collision's static score. Further completed banks during + that ball add 100,000 to the secondary score; a normal ball end clears the + multiplier, while effect seven's special respawn preserves it. Marker + comparisons retain the binary's signed-high/unsigned-low 32-bit ordering after + score wrap. - 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. diff --git a/tdkpin-rs/Cargo.lock b/tdkpin-rs/Cargo.lock index 05f1093..2c13117 100644 --- a/tdkpin-rs/Cargo.lock +++ b/tdkpin-rs/Cargo.lock @@ -551,7 +551,7 @@ dependencies = [ [[package]] name = "tdkpin-rs" -version = "1.0.0" +version = "1.1.0" dependencies = [ "directories", "futures-util", diff --git a/tdkpin-rs/Cargo.toml b/tdkpin-rs/Cargo.toml index 0a374b5..ca0a5b7 100644 --- a/tdkpin-rs/Cargo.toml +++ b/tdkpin-rs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tdkpin-rs" -version = "1.0.0" +version = "1.1.0" edition = "2024" [dependencies] diff --git a/tdkpin-rs/web/tdkpin-rs.wasm b/tdkpin-rs/web/tdkpin-rs.wasm index 69dcca3..093bbcf 100755 Binary files a/tdkpin-rs/web/tdkpin-rs.wasm and b/tdkpin-rs/web/tdkpin-rs.wasm differ