fix(ui): restore original presentation scale

The recovered client enlarged the 640x460 canvas to 960x690 and shrank the
score glyphs, so artwork and numeric displays no longer matched the original
pixel presentation. Restore the native window dimensions and title, render
score digits at their recovered 16x28 size, and align the score fields to the
original layout. Update the user and reconstruction documentation accordingly.

Test Plan:
- `cargo test --workspace --all-targets --all-features` -- passed, 52 tests
- `cargo clippy --workspace --all-targets --all-features -- -D warnings` -- passed
- `rumdl check --flavor commonmark CHANGELOG.md README.md RECONSTRUCTION.md` -- passed
- `git diff --cached --check` -- passed
- `cargo +nightly fmt --all -- --check` -- baseline fails on existing import formatting in touched and untouched Rust files
- `prettier --check CHANGELOG.md README.md RECONSTRUCTION.md --prose-wrap always --print-width 80` -- baseline fails on existing whole-file formatting in README.md and RECONSTRUCTION.md
This commit is contained in:
2026-08-23 06:08:11 +02:00
parent a70331fb8c
commit aef404c834
5 changed files with 20 additions and 12 deletions
+8
View File
@@ -5,3 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Fixed
- 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.
+3 -3
View File
@@ -5,9 +5,9 @@ Machine**. It uses the extracted original artwork and sound, recreates the
playfield as a fixed-step simulation, and runs from the same source on Linux,
macOS, and Windows.
The game opens at 960x690, an exact 1.5x enlargement of its original 640x460
canvas, so modern desktop scaling cannot distort or vertically offset the
pixel-art presentation.
The game opens at the original 640x460 canvas size and presents every artwork
pixel one-for-one. The fixed, non-high-DPI client prevents desktop scaling from
distorting or vertically offsetting the pixel-art presentation.
The original program is not required at runtime. All required game assets are
embedded in the executable at build time.
+1 -1
View File
@@ -29,7 +29,7 @@ implementation.
| Numeric scoring | Recovered gameplay values | Static scores come from the initialized 175-object ledger. Dynamic bumper progression, target-bank completion, diamond awards, 10k-160k lock bonuses, 310k transfer, six effect values, multiball mode, and all four media thresholds are transcribed from `1000:b476`, `1000:c4e1`, `1000:bc36`, and live state probes. |
| High scores | Compatible import | The original 276-byte table is decoded as ten `IWIK`-XOR-obfuscated little-endian scores plus ten 22-byte names, sorted, then migrated to portable JSON. |
| Configuration | Behaviorally compatible | Sound, language, and five detail levels are retained. Storage moves from a local Win16 INI file to the platform user-data directory. |
| Windows UI shell | Deliberately modernized | Win16 menus, modal dialogs, GDI blitting, and multimedia timers are replaced by an aspect-correct 960x690 native window with keyboard overlays. The visible game and original help remain at 640x460 logical pixels. |
| Windows UI shell | Deliberately modernized | Win16 menus, modal dialogs, GDI blitting, and multimedia timers are replaced by a fixed native window with keyboard overlays. The visible game and original help render one-for-one at the original 640x460 pixels. |
## Extracted asset inventory
+5 -5
View File
@@ -550,7 +550,7 @@ impl App {
},
);
}
self.draw_right_aligned_digits(&game.bonus.to_string(), 610.0, 240.0);
self.draw_right_aligned_digits(&game.bonus.to_string(), 605.0, 233.0);
let media_level = game.player().media_level;
if media_level > 0 {
@@ -599,8 +599,8 @@ impl App {
for (index, player) in game.players.iter().enumerate() {
self.draw_right_aligned_digits(
&player.score.to_string(),
610.0,
280.0 + index as f32 * 44.0,
605.0,
277.0 + index as f32 * 44.0,
);
}
}
@@ -608,8 +608,8 @@ impl App {
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));
let width = f32::from(digit_count) * 16.0;
self.draw_digits(digits, vec2(right - width, y), vec2(16.0, 28.0));
}
fn draw_digits(&self, digits: &str, position: Vec2, digit_size: Vec2) {
+3 -3
View File
@@ -11,12 +11,12 @@ use app::App;
use macroquad::prelude::*;
use simulation::{Request, Simulation, usage};
const WINDOW_WIDTH: i32 = 960;
const WINDOW_HEIGHT: i32 = 690;
const WINDOW_WIDTH: i32 = 640;
const WINDOW_HEIGHT: i32 = 460;
fn window_conf() -> Conf {
Conf {
window_title: "TDK Pinball Machine".to_owned(),
window_title: "TDK Pinball Machine 1.00".to_owned(),
window_width: WINDOW_WIDTH,
window_height: WINDOW_HEIGHT,
window_resizable: false,