From 445bb22fb42a26b9d3873be72c444389c04aeae5 Mon Sep 17 00:00:00 2001 From: ddidderr Date: Sat, 22 Aug 2026 18:39:29 +0200 Subject: [PATCH] fix(audio): restore recovered mechanism sounds Play the original WAVE resource for both movement edges of each flipper and centralize gameplay event sound selection. Replace guessed control and mechanism mappings with the resource numbers recovered from the Win16 call sites. Keep synthetic ball search silent because it has no original trigger. Test Plan: - cargo fmt --check - cargo test - cargo clippy --all-targets --all-features -- -D warnings - git diff --cached --check --- tdkpin-rs/src/app.rs | 18 ++-------- tdkpin-rs/src/game.rs | 82 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 77 insertions(+), 23 deletions(-) diff --git a/tdkpin-rs/src/app.rs b/tdkpin-rs/src/app.rs index e9520f7..3be0fd9 100644 --- a/tdkpin-rs/src/app.rs +++ b/tdkpin-rs/src/app.rs @@ -191,21 +191,9 @@ impl App { } fn play_event(&self, event: Event) { - let id = match event { - Event::Flipper => 2001, - Event::Launch => 2016, - Event::Bumper => 2002, - Event::Target => 2006, - Event::Wheel => 2004, - Event::Robot => 2007, - Event::Lock => 2017, - Event::Media => 2022, - Event::ExtraBall => 2019, - Event::Nudge | Event::BallSearch => 2021, - Event::Tilt => 2015, - Event::Drain => 2013, - }; - self.assets.play(id, self.saved.settings.sounds); + if let Some(id) = event.sound_resource() { + self.assets.play(id, self.saved.settings.sounds); + } } fn finish_game(&mut self) { diff --git a/tdkpin-rs/src/game.rs b/tdkpin-rs/src/game.rs index 5487cdf..d778e0b 100644 --- a/tdkpin-rs/src/game.rs +++ b/tdkpin-rs/src/game.rs @@ -41,12 +41,12 @@ pub struct Controls { #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Event { - Flipper, + FlipperMove, Launch, Bumper, Target, Wheel, - Robot, + ClawCapture, Lock, Media, ExtraBall, @@ -56,6 +56,28 @@ pub enum Event { Drain, } +impl Event { + /// Original Win16 WAVE resource selected by this gameplay transition. + /// Events without an evidenced original sound deliberately return `None`. + pub const fn sound_resource(self) -> Option { + match self { + Self::FlipperMove => Some(2021), + Self::Launch => Some(2002), + Self::Bumper => Some(2004), + Self::Target => Some(2006), + Self::Wheel => Some(2011), + Self::ClawCapture => Some(2015), + Self::Lock => Some(2017), + Self::Media => Some(2022), + Self::ExtraBall => Some(2007), + Self::Nudge => Some(2019), + Self::Tilt => Some(2020), + Self::Drain => Some(2008), + Self::BallSearch => None, + } + } +} + #[derive(Clone, Copy, Debug, Default)] pub struct Flippers { pub left_raised: bool, @@ -202,10 +224,11 @@ impl Game { let old_flippers = self.flippers; self.flippers.left_raised = controls.left_flipper && !self.tilted; self.flippers.right_raised = controls.right_flipper && !self.tilted; - if (self.flippers.left_raised && !old_flippers.left_raised) - || (self.flippers.right_raised && !old_flippers.right_raised) - { - events.push(Event::Flipper); + if self.flippers.left_raised != old_flippers.left_raised { + events.push(Event::FlipperMove); + } + if self.flippers.right_raised != old_flippers.right_raised { + events.push(Event::FlipperMove); } if self.ball.in_launcher && !self.tilted { @@ -503,7 +526,7 @@ impl Game { self.ball.velocity = vec2(-125.0, 60.0); self.target_cooldown = 0.3; self.robot_animation = 1.0; - events.push(Event::Robot); + events.push(Event::ClawCapture); } if (151.0..=220.0).contains(&position.x) && (187.0..=205.0).contains(&position.y) { @@ -884,11 +907,54 @@ mod tests { }, ); let (left, right) = game.flipper_segments(); - assert!(events.contains(&Event::Flipper)); + assert_eq!( + events + .iter() + .filter(|event| **event == Event::FlipperMove) + .count(), + 2 + ); assert_eq!(left.end, LEFT_FLIPPER_RAISED_TIP); assert_eq!(right.end, RIGHT_FLIPPER_RAISED_TIP); } + #[test] + fn each_flipper_edge_has_the_recovered_movement_sound() { + let mut game = Game::new(1); + let raised = Controls { + left_flipper: true, + right_flipper: true, + ..Controls::default() + }; + + let press_events = game.update(1.0 / 60.0, 3, raised); + assert_eq!( + press_events, + [Event::FlipperMove, Event::FlipperMove], + "each original move_flipper call starts WAVE 2021" + ); + assert!(game.update(1.0 / 60.0, 3, raised).is_empty()); + + let release_events = game.update(1.0 / 60.0, 3, Controls::default()); + assert_eq!( + release_events, + [Event::FlipperMove, Event::FlipperMove], + "the original also plays the sound while returning" + ); + assert_eq!(Event::FlipperMove.sound_resource(), Some(2021)); + } + + #[test] + fn recovered_control_sounds_use_the_original_resource_numbers() { + assert_eq!(Event::Launch.sound_resource(), Some(2002)); + assert_eq!(Event::Wheel.sound_resource(), Some(2011)); + assert_eq!(Event::Nudge.sound_resource(), Some(2019)); + assert_eq!(Event::Tilt.sound_resource(), Some(2020)); + assert_eq!(Event::Drain.sound_resource(), Some(2008)); + assert_eq!(Event::ClawCapture.sound_resource(), Some(2015)); + assert_eq!(Event::BallSearch.sound_resource(), None); + } + #[test] fn drain_clears_latched_tilt() { let mut game = Game::new(1);