diff --git a/tdkpin-rs/src/app.rs b/tdkpin-rs/src/app.rs index 8a6fbbf..dd76719 100644 --- a/tdkpin-rs/src/app.rs +++ b/tdkpin-rs/src/app.rs @@ -375,6 +375,8 @@ impl App { #[allow(clippy::cast_precision_loss, clippy::too_many_lines)] fn draw_game(&self) { + // Resource 998 is the original game's resting playfield. Resource 997 + // contains exact lit-state patches used below for the active displays. draw_texture(&self.assets.inactive_table, 0.0, 0.0, WHITE); let Some(game) = &self.game else { return; @@ -409,53 +411,6 @@ impl App { ); } - for (index, center) in [vec2(205.0, 47.0), vec2(234.0, 50.0), vec2(262.0, 53.0)] - .into_iter() - .enumerate() - { - if game.top_targets[index] { - draw_line( - center.x - 7.0, - center.y + 9.0, - center.x + 5.0, - center.y - 10.0, - 7.0, - YELLOW, - ); - } - } - let side_colors = [RED, ORANGE, YELLOW, GREEN, SKYBLUE]; - for (index, y) in [180.0, 195.0, 210.0, 225.0, 240.0].into_iter().enumerate() { - let color = if game.side_targets[index] { - side_colors[index] - } else { - Color::from_rgba(38, 38, 38, 255) - }; - draw_circle(286.0, y, 5.0, color); - } - for (index, lit) in game.wheel_holes.iter().enumerate() { - if *lit { - let angle = index as f32 / 8.0 * std::f32::consts::TAU; - draw_circle( - 114.0 + angle.cos() * 29.0, - 79.0 + angle.sin() * 29.0, - 6.0, - YELLOW, - ); - } - } - for index in 0..4 { - draw_circle( - 155.0 + index as f32 * 14.0, - 214.0, - 5.0, - if index < usize::from(game.lock_lights) { - WHITE - } else { - DARKGRAY - }, - ); - } for (index, bumper) in BUMPERS.into_iter().enumerate() { if game.bumper_flash[index] > 0.0 { draw_circle_lines(bumper.center.x, bumper.center.y, 17.0, 3.0, WHITE); @@ -488,7 +443,7 @@ impl App { draw_texture_ex( &self.assets.plunger, 314.0, - 406.0, + 426.0, WHITE, DrawTextureParams { dest_size: Some(vec2(21.0, 18.0)), @@ -497,43 +452,6 @@ impl App { }, ); } - - for (start, end) in [ - (vec2(103.0, 397.0), vec2(58.0, 374.0)), - (vec2(210.0, 397.0), vec2(256.0, 374.0)), - ] { - draw_line(start.x, start.y, end.x, end.y, 22.0, BLACK); - draw_circle(start.x, start.y, 11.0, BLACK); - } - let (left, right) = game.flippers(); - for flipper in [left, right] { - draw_line( - flipper.start.x, - flipper.start.y, - flipper.end.x, - flipper.end.y, - 18.0, - Color::from_rgba(32, 32, 32, 255), - ); - draw_line( - flipper.start.x, - flipper.start.y - 1.0, - flipper.end.x, - flipper.end.y - 1.0, - 12.0, - LIGHTGRAY, - ); - draw_line( - flipper.start.x, - flipper.start.y - 3.0, - flipper.end.x, - flipper.end.y - 3.0, - 3.0, - WHITE, - ); - draw_circle(flipper.start.x, flipper.start.y, 9.0, DARKGRAY); - draw_circle(flipper.start.x, flipper.start.y - 1.0, 6.0, GRAY); - } draw_texture( &self.assets.ball, game.ball.position.x - 8.0, @@ -555,80 +473,89 @@ impl App { }, ); } - draw_rectangle( - 340.0, - 444.0, - 292.0, - 14.0, - Color::from_rgba(214, 214, 214, 235), - ); - draw_text("F1 HELP F2 SETUP", 347.0, 455.0, 10.0, BLACK); } #[allow(clippy::cast_precision_loss)] fn draw_displays(&self, game: &Game) { - draw_texture_ex( - &self.assets.active_table, - 371.0, - 233.0, - WHITE, - DrawTextureParams { - dest_size: Some(vec2(244.0, 34.0)), - source: Some(Rect::new(371.0, 233.0, 244.0, 34.0)), - ..Default::default() - }, - ); - self.draw_digits( - &format!("{:07}", game.bonus), - vec2(458.0, 240.0), - vec2(10.0, 18.0), - ); + for region in [ + Rect::new(383.0, 72.0, 140.0, 136.0), + Rect::new(545.0, 170.0, 9.0, 9.0), + Rect::new(372.0, 233.0, 238.0, 29.0), + ] { + draw_texture_ex( + &self.assets.active_table, + region.x, + region.y, + WHITE, + DrawTextureParams { + dest_size: Some(vec2(region.w, region.h)), + source: Some(region), + ..Default::default() + }, + ); + } + self.draw_right_aligned_digits(&game.bonus.to_string(), 610.0, 240.0); let media_level = game.player().media_level; if media_level > 0 { let index = usize::from(media_level.saturating_sub(1).min(3)); draw_texture(&self.assets.media[index], 380.0, 72.0, WHITE); } - draw_text( - format!("{:07} KBytes", game.player().score / 1_000), - 395.0, - 205.0, - 14.0, - WHITE, - ); + + let row_y = 277.0 + game.current_player as f32 * 44.0; + for region in [ + Rect::new(373.0, row_y + 4.0, 9.0, 9.0), + Rect::new(473.0, row_y, 137.0, 29.0), + ] { + draw_texture_ex( + &self.assets.active_table, + region.x, + region.y, + WHITE, + DrawTextureParams { + dest_size: Some(vec2(region.w, region.h)), + source: Some(region), + ..Default::default() + }, + ); + } + let displayed_balls = game + .player() + .balls + .saturating_sub(1) + .saturating_add(game.player().extra_balls) + .min(6); + for ball in 0..displayed_balls { + let x = 392.0 + f32::from(ball) * 8.0; + draw_texture_ex( + &self.assets.active_table, + x, + row_y + 22.0, + WHITE, + DrawTextureParams { + dest_size: Some(vec2(3.0, 3.0)), + source: Some(Rect::new(x, row_y + 22.0, 3.0, 3.0)), + ..Default::default() + }, + ); + } for (index, player) in game.players.iter().enumerate() { - let y = 274.0 + index as f32 * 44.0; - if index == game.current_player { - draw_texture_ex( - &self.assets.active_table, - 472.0, - y, - WHITE, - DrawTextureParams { - dest_size: Some(vec2(143.0, 30.0)), - source: Some(Rect::new(472.0, y, 143.0, 30.0)), - ..Default::default() - }, - ); - } - self.draw_digits( - &format!("{:09}", player.score), - vec2(480.0, y + 6.0), - vec2(10.0, 18.0), + self.draw_right_aligned_digits( + &player.score.to_string(), + 610.0, + 280.0 + index as f32 * 44.0, ); - for ball in 0..6 { - let lit = ball < usize::from(player.balls + player.extra_balls); - draw_circle( - 397.0 + ball as f32 * 8.0, - y + 27.0, - 2.4, - if lit { GREEN } else { DARKGRAY }, - ); - } } } + fn draw_right_aligned_digits(&self, digits: &str, right: f32, y: f32) { + let digit_count = u16::try_from(digits.bytes().filter(u8::is_ascii_digit).count()) + .expect("a display value has at most ten digits"); + let width = f32::from(digit_count) * 10.0; + self.draw_digits(digits, vec2(right - width, y), vec2(10.0, 18.0)); + } + fn draw_digits(&self, digits: &str, position: Vec2, digit_size: Vec2) { let mut x = position.x; for digit in digits.bytes() { diff --git a/tdkpin-rs/src/game.rs b/tdkpin-rs/src/game.rs index 9db9dce..9c610a9 100644 --- a/tdkpin-rs/src/game.rs +++ b/tdkpin-rs/src/game.rs @@ -547,13 +547,6 @@ impl Game { } self.finished = true; } - - pub fn flippers(&self) -> (Segment, Segment) { - ( - flipper_segment(vec2(103.0, 397.0), self.left_flipper_angle), - flipper_segment(vec2(210.0, 397.0), self.right_flipper_angle), - ) - } } fn flipper_segment(pivot: Vec2, angle: f32) -> Segment {