This commit is contained in:
randogoth 2026-08-31 16:01:14 +03:00
commit 19991bee2a
44 changed files with 4799 additions and 0 deletions

View file

@ -0,0 +1,99 @@
#!/usr/bin/env python3
"""
Generate src/logos_data.inc from the ANSI art files under logos/.
Each ANSI logo is converted into a NULL-terminated array of C string literals
so render.c can embed them directly without needing to parse files at runtime.
"""
from __future__ import annotations
import argparse
from pathlib import Path
LOGO_SOURCES = [
("logo_86_dos", "logos/86.ans"),
("logo_concurrentdos", "logos/concurrentdos.ans"),
("logo_dos", "logos/dos.ans"),
("logo_dosbian", "logos/dosbian.ans"),
("logo_dosbox", "logos/dosbox.ans"),
("logo_dosbox_staging", "logos/dosbox_staging.ans"),
("logo_dosbox_x", "logos/dosbox_x.ans"),
("logo_dr_dos", "logos/drdos.ans"),
("logo_freedos", "logos/freedos.ans"),
("logo_ms_dos", "logos/msdos.ans"),
("logo_novell_dos", "logos/novell.ans"),
("logo_pc_dos", "logos/ibmdos.ans"),
]
def split_lines(path: Path) -> list[bytes]:
"""Return the ANSI file as a list of raw lines without line endings."""
data = path.read_bytes()
# splitlines() handles CRLF/CR/LF and preserves empty lines.
return data.splitlines()
def to_c_literal(line: bytes) -> str:
"""Convert a raw line to a C string literal with escaped bytes."""
pieces = ['"']
for byte in line:
if byte == 0x5C: # backslash
pieces.append("\\\\")
elif byte == 0x22: # double quote
pieces.append('\\"')
elif byte == 0x07:
pieces.append("\\a")
elif byte == 0x08:
pieces.append("\\b")
elif byte == 0x09:
pieces.append("\\t")
elif byte == 0x0C:
pieces.append("\\f")
elif byte == 0x0B:
pieces.append("\\v")
elif 0x20 <= byte <= 0x7E:
pieces.append(chr(byte))
else:
pieces.append(f"\\x{byte:02x}")
pieces.append('"')
return "".join(pieces)
def generate(output: Path) -> None:
root = Path(__file__).resolve().parents[1]
lines = [
"/* Auto-generated by tools/generate_logos_data.py. Do not edit. */",
"",
]
for symbol, rel_path in LOGO_SOURCES:
logo_path = root / rel_path
if not logo_path.exists():
raise FileNotFoundError(f"Missing logo file: {logo_path}")
lines.append(f"static const char *const {symbol}[] = {{")
for raw_line in split_lines(logo_path):
lines.append(f" {to_c_literal(raw_line)},")
lines.append(" NULL,")
lines.append("};")
lines.append("")
output_path = root / output
output_path.write_text("\n".join(lines), encoding="utf-8")
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"-o",
"--output",
default="src/logos_data.inc",
type=Path,
help="Path to write the generated include (default: %(default)s)",
)
args = parser.parse_args()
generate(args.output)
if __name__ == "__main__":
main()