From 2c507b6ecb5aed884afb21e79f13ecb16e6adff4 Mon Sep 17 00:00:00 2001 From: xenia Date: Wed, 7 Feb 2024 22:52:21 +0100 Subject: [PATCH] Implement text rendering --- gen/fontgen.py | 82 ++++++++++++-------- xenrom/main.asm | 60 ++++++++++++-- xenrom/text.asm | 202 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 306 insertions(+), 38 deletions(-) diff --git a/gen/fontgen.py b/gen/fontgen.py index 237c74d..846f58d 100644 --- a/gen/fontgen.py +++ b/gen/fontgen.py @@ -2,22 +2,23 @@ import json import struct # generates: -# font_data.dat (binary file, expected to load at location 0xf000_0100) -# font_data.inc (fox32 assembly) -# font_data.inc defines constants -# N_CHARS: number of defined characters (u32) -# CHAR_TABLE: pointer to main char table (&Char) -# UNKNOWN_CHAR: pointer to unknown character (&Char) +# font_data.bin +# font_table.bin +# font_data.inc # # struct Char { # width: u8, height: u8, baseline: u8, -# data_ptr: &[u8], +# data_offset: offset into font_data # } (7 bytes) -DATA_FILE_ORIGIN = 0xf000_0100 +CODEPAGE = { + 0: None, + 128: 'Ξ', +} +for x in range(32, 127): + CODEPAGE[x] = chr(x) BASELINE = 7 -N_CHARS = 127 codepoints = json.load(open("ultlf/codepoints.json")) font_data = json.load(open("ultlf/data.json")) @@ -33,34 +34,51 @@ UNKNOWN = [ "# # #", ] -with open("xenrom/data/font_data.inc", "w") as inc, open("xenrom/data/font_data.dat", "wb") as dat: - table = b'' - char_data = b'' +SPACE = [" "] - for ch in [None] + list(range(N_CHARS)): - if ch in codepoints: - i = codepoints.index(ch) - glyph = font_data[i] - baseline = baselines[i] - if '?' in "".join(glyph): - print(f"Font doesn't have char {ch}") - glyph = UNKNOWN - baseline = 6 - else: +SCALE = 2 +def scale(glyph): + out = [] + for line in glyph: + line_scaled = "" + for ch in line: + line_scaled += ch * SCALE + out.extend([line_scaled] * SCALE) + return out + +with open("xenrom/data/font_table.dat", "wb") as table_file, open("xenrom/data/font_data.dat", "wb") as data_file, open("xenrom/data/font_data.inc", "w") as inc_file: + table = b'' + data = b'' + + for i in range(256): + ch = CODEPAGE.get(i, None) + unicode_codepoint = ord(ch) if ch is not None else None + if unicode_codepoint is None: glyph = UNKNOWN baseline = 6 - print(f"Couldn't find char {ch}") + elif unicode_codepoint == 32: + glyph = SPACE + baseline = 1 + else: + ultlf_idx = codepoints.index(unicode_codepoint) + glyph = font_data[ultlf_idx] + baseline = baselines[ultlf_idx] - table += struct.pack("BBBI", len(glyph[0]), len(glyph), baseline, DATA_FILE_ORIGIN + len(char_data)) + if "X" in "".join(glyph): + glyph = UNKNOWN + baseline = 6 + + glyph = scale(glyph) + baseline *= SCALE + + table += struct.pack("