fix(ui): preserve the original canvas and display styling

High-DPI sizing and a resizable client allowed the 640x460 canvas to be placed
inside a much taller window, producing the large internal black band captured in
the gameplay recording. Open an aspect-correct fixed 960x690 client with high-DPI
framebuffer scaling disabled, giving every platform a predictable 1.5x canvas.

Use exact active-table patches for the cyan score fields and derive transparent
numeral glyphs from the recovered Win16 bitmap font. Fill the complete display
slots, move the KBytes readout clear of its border, and place shortcuts on a
readable footer so no dynamic text is clipped or left over an inactive panel.

Test Plan:
- `cargo fmt -- --check` -- passed
- `cargo test --all-targets` -- passed
- `cargo clippy --all-targets -- -D warnings` -- passed
- launched the Linux window and confirmed a 960x690 client with no letterbox,
  full-width cyan fields, recovered score digits, and readable footer -- passed
- `git diff --check` -- passed
This commit is contained in:
2026-08-22 17:03:46 +02:00
parent cf2c839f83
commit e815391980
5 changed files with 92 additions and 28 deletions
+18
View File
@@ -14,6 +14,7 @@ pub struct Assets {
pub robot: Texture2D,
pub magnet: Texture2D,
pub ball: Texture2D,
pub digits: Texture2D,
sounds: Vec<(u16, Sound)>,
}
@@ -54,6 +55,8 @@ impl Assets {
include_bytes!("../assets/original/images/bitmap_00101.png"),
include_bytes!("../assets/original/images/bitmap_00102.png"),
);
let digits =
monochrome_texture(include_bytes!("../assets/original/images/bitmap_00500.png"));
let sound_bytes: [(u16, &[u8]); 16] = [
(
@@ -139,6 +142,7 @@ impl Assets {
robot,
magnet,
ball,
digits,
sounds,
}
}
@@ -182,3 +186,17 @@ fn masked_texture(color_bytes: &[u8], mask_bytes: &[u8]) -> Texture2D {
texture.set_filter(FilterMode::Nearest);
texture
}
fn monochrome_texture(bytes: &[u8]) -> Texture2D {
let mut image =
Image::from_file_with_format(bytes, None).expect("embedded monochrome bitmap must decode");
let (pixels, remainder) = image.bytes.as_chunks_mut::<4>();
assert!(remainder.is_empty());
for pixel in pixels {
pixel[3] = u8::MAX - pixel[0];
pixel[..3].fill(u8::MAX);
}
let texture = Texture2D::from_image(&image);
texture.set_filter(FilterMode::Nearest);
texture
}