Switch to the Dinowyde font with DINOBYTE for missing glyphs

Unicode glyph lookup instead of CP437 codes, rope and double-strand
frames with clean title ends, progress bars in eighth blocks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-05 15:32:42 +01:00
1 parent d99166a746
commit d76e74b4b0
11 files changed
+225 -65

No files matched your search

+15 -14
View File
@@ -1,4 +1,4 @@
// In-canvas user interface: CP437 windows with the DINOBYTE bitmap font.
// In-canvas user interface: text-mode windows with the Dinowyde bitmap font.
// All texts come from the language files (see i18n.rs).
use crate::game::*;
@@ -114,21 +114,22 @@ pub fn begin_ui() {
set_camera(&Camera2D { target: vec2(w * 0.5, h * 0.5), zoom: vec2(2.0 / w, 2.0 / h), ..Default::default() });
}
// bar made of CP437 block characters: full blocks, a half block, shaded rest
// bar made of block characters: full blocks, an eighth block for the rest, shaded background
const EIGHTHS: [char; 7] = ['▏', '▎', '▍', '▌', '▋', '▊', '▉'];
pub fn ascii_bar(gfx: &Gfx, x: f32, y: f32, cols: usize, frac: f32, col: Color, scale: f32) {
let f = frac.clamp(0.0, 1.0) * cols as f32;
let full = f.floor() as usize;
let half = f - full as f32 >= 0.5;
let eighths = (frac.clamp(0.0, 1.0) * cols as f32 * 8.0).round() as usize;
let (full, part) = (eighths / 8, eighths % 8);
let dim = Color::new(col.r * 0.35, col.g * 0.35, col.b * 0.35, col.a);
for k in 0..cols {
let px = x + k as f32 * GW * scale;
if k < full {
gfx.glyph(0xDB, px, y, scale, col);
} else if k == full && half {
gfx.glyph(0xB0, px, y, scale, dim);
gfx.glyph(0xDD, px, y, scale, col);
gfx.glyph('█', px, y, scale, col);
} else {
gfx.glyph(0xB0, px, y, scale, dim);
gfx.glyph('░', px, y, scale, dim);
if k == full && part > 0 {
gfx.glyph(EIGHTHS[part - 1], px, y, scale, col);
}
}
}
}
@@ -729,11 +730,11 @@ impl Ui {
let locked = !tools.iter().any(|&t| g.tool_allowed(t));
let r = tool_button(bx, by, bw, ti.icon, key, &label, has, self.open_cat == Some(c) || hovered, locked);
if has {
gfx.glyph(0x1F, bx + (bw - CW()) * 0.5, tb_y, S(), if pulse { WHITE } else { FRAME_HI });
gfx.glyph('▼', bx + (bw - CW()) * 0.5, tb_y, S(), if pulse { WHITE } else { FRAME_HI });
}
if tools.len() > 1 {
// small arrow: this button opens a row
gfx.glyph(0x1E, r.x + r.w - GW * SMALL() - 2.0 * px, r.y + 2.0 * px, SMALL(), if self.open_cat == Some(c) { FRAME_HI } else { DIM });
gfx.glyph('▲', r.x + r.w - GW * SMALL() - 2.0 * px, r.y + 2.0 * px, SMALL(), if self.open_cat == Some(c) { FRAME_HI } else { DIM });
}
self.touch_btns.push((r, TBtn::Cat(c)));
}
@@ -743,7 +744,7 @@ impl Ui {
let hovered = !touch_ui() && r.contains(vec2(mx, my));
draw_rectangle(r.x, r.y, r.w, r.h, if hovered || self.show_overview { Color::new(0.18, 0.13, 0.1, 1.0) } else { Color::new(0.1, 0.07, 0.07, 1.0) });
draw_rectangle_lines(r.x, r.y, r.w, r.h, 2.0 * px, if self.show_overview { FRAME_HI } else { Color::new(0.35, 0.28, 0.2, 1.0) });
gfx.glyph(0x02, bx + (bw - GW * TITLE()) * 0.5, by + 2.0 * px, TITLE(), FRAME_HI);
gfx.glyph('☻', bx + (bw - GW * TITLE()) * 0.5, by + 2.0 * px, TITLE(), FRAME_HI);
let ol = tr("cat.overview");
let maxc = ((bw - 2.0 * px) / (GW * SMALL())).floor() as usize;
let ol: String = ol.chars().take(maxc).collect();
@@ -755,7 +756,7 @@ impl Ui {
let hovered = !touch_ui() && r.contains(vec2(mx, my));
draw_rectangle(r.x, r.y, r.w, r.h, if hovered { Color::new(0.18, 0.13, 0.1, 1.0) } else { Color::new(0.1, 0.07, 0.07, 1.0) });
draw_rectangle_lines(r.x, r.y, r.w, r.h, 2.0 * px, Color::new(0.35, 0.28, 0.2, 1.0));
gfx.glyph(0xF0, bx + (bw - GW * TITLE()) * 0.5, by + 2.0 * px, TITLE(), FRAME_HI);
gfx.glyph('≡', bx + (bw - GW * TITLE()) * 0.5, by + 2.0 * px, TITLE(), FRAME_HI);
let ml = tr("cat.menu");
let maxc = ((bw - 2.0 * px) / (GW * SMALL())).floor() as usize;
let ml: String = ml.chars().take(maxc).collect();