Files
irrlichtandClaude Opus 5 335962800f Reorganize assets; switch the HUD to the Micro Chat font
Source packs move to assets/packs (untouched), maps to assets/maps, and the
palette/sketch leftovers from the 8-bit era go. tools/mkfont.py repacks
VEXED's Micro Chat sheet (8-column grid, 8x10 cells) into the CP437 atlas
layout the font loader already reads, cropped to 8x9 so the HUD can use an
8 px line height. The CGA atlas is dropped in its favor.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 19:47:33 +02:00

69 lines
2.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""Repack VEXED's Micro Chat sheet into the game's CP437 atlas layout.
Source: assets/fonts/Micro-Chat-All/Micro-Chat.png — an 8-column grid with 1 px
gray grid lines, 8×10 cells, black glyphs on transparent; the glyph order comes
from the "Supported Glyphs (PNG Order)" block in Micro-Chat-Info.md.
Output: a 32×8-cell atlas (codepoint = index, like the CGA sheet) with white glyphs
on opaque black, so game/src/font.rs loads it unchanged. Cells are cropped to source
rows 1..9 (umlaut dots down to descenders): 8×9 px.
python3 tools/mkfont.py
"""
from PIL import Image
SRC = "assets/fonts/Micro-Chat-All/Micro-Chat.png"
INFO = "assets/fonts/Micro-Chat-All/Micro-Chat-Info.md"
OUT = "assets/fonts/micro-chat-8x9.png"
CELL_W, CELL_H = 8, 10 # source cell
STRIDE_X, STRIDE_Y = 9, 11 # cell + grid line
CROP_TOP, OUT_H = 1, 9 # keep source rows 1..9
# Same table as font::cp437 — the accented slots the game may ask for.
CP437 = {
'Ç': 128, 'ü': 129, 'é': 130, 'ä': 132, 'à': 133, 'å': 134, 'ç': 135,
'ë': 137, 'è': 138, 'ï': 139, 'î': 140, 'ì': 141, 'Ä': 142, 'Å': 143,
'É': 144, 'ö': 148, 'ò': 149, 'û': 150, 'ù': 151, 'Ö': 153, 'Ü': 154,
'á': 160, 'í': 161, 'ó': 162, 'ú': 163, 'ñ': 164, 'Ñ': 165, 'ß': 225,
}
CP437.update({chr(c): c for c in range(32, 127)})
def source_cells():
block = open(INFO, encoding="utf-8").read()
block = block.split("## Supported Glyphs (PNG Order)")[1].split("``")[1]
cells = {}
for row, line in enumerate(block.strip("\n").split("\n")):
for col, ch in enumerate(line):
cells[ch] = (col, row)
return cells
def main():
src = Image.open(SRC).convert("RGBA")
cells = source_cells()
out = Image.new("RGB", (32 * CELL_W, 8 * OUT_H), (0, 0, 0))
missing = []
for ch, code in sorted(CP437.items(), key=lambda kv: kv[1]):
if ch not in cells:
missing.append(ch)
continue
if ch == " ":
continue # the sheet marks the space cell with a bar; ours must be blank
col, row = cells[ch]
x0, y0 = 1 + col * STRIDE_X, 1 + row * STRIDE_Y + CROP_TOP
for y in range(OUT_H):
for x in range(CELL_W):
r, g, b, a = src.getpixel((x0 + x, y0 + y))
if a > 0 and r < 100:
out.putpixel(((code % 32) * CELL_W + x, (code // 32) * OUT_H + y), (255, 255, 255))
out.save(OUT)
print(f"wrote {OUT}; missing: {''.join(missing) or '-'}")
if __name__ == "__main__":
main()