Files
rijads 1ce01d4481 Import the game files from a browser on first start
When /app0/rct2/Data/g1.dat is missing, the title shows a screen with an address and a QR code
and receives the RollerCoaster Tycoon 2 folder from a PC or phone: src/port/upload.c (the DOOM
port's server, keeping subfolders now) stores each file below the game's own folders (Data,
ObjData, Scenarios, Tracks, Landscapes; every part a plain name) and takes a ZIP file of the
folder, which the screen unpacks with libzip. The screen draws with SDL and fonts rendered from
DejaVu Sans at build time (tools/make-font.py), since OpenRCT2 cannot draw before the game files
are there; it starts the game once they are complete.

tools/send.py sends a folder or a ZIP file the way the page does. Console test plans can point
the game at another folder (game) and remove test folders (remove); test/console-import.cfg
imports into /app0/rct2-import. On the console the screen worked and received the Data folder
before the PS5 went to rest; the transfer ran at 2.2 MB/s, so the server now asks for a 1 MiB
receive buffer and writes whole 256 KiB chunks.
2026-10-05 00:14:45 +02:00

62 lines
2.5 KiB
Python

#!/usr/bin/env python3
"""Renders printable ASCII in DejaVu Sans into a C header for the import screen, which draws text
before RCT2's own fonts exist: make-font.py <header>. For each font (body, title) the header has an
8-bit coverage atlas, one row of cells, and for each character from ' ' to '~' its cell's x and
width, its advance, and where the cell starts relative to the pen (0, or less for a character
that reaches back). The header is left alone when it would not change."""
import sys
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont
FONTS = {
"body": ("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 30),
"title": ("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 52),
}
CHARACTERS = [chr(c) for c in range(32, 127)]
def render(path, size):
font = ImageFont.truetype(path, size)
ascent, descent = font.getmetrics()
height = ascent + descent
cells = []
x = 0
for character in CHARACTERS:
advance = round(font.getlength(character))
left, _, right, _ = font.getbbox(character)
start = min(0, left)
width = max(advance, right) - start + 1
cells.append((x, width, advance, start))
x += width
atlas = Image.new("L", (x, height), 0)
draw = ImageDraw.Draw(atlas)
for character, (cell_x, _, _, start) in zip(CHARACTERS, cells):
draw.text((cell_x - start, 0), character, font=font, fill=255)
return atlas, cells
def main():
lines = ["/* Generated by tools/make-font.py from DejaVu Sans (Bitstream Vera licence). */"]
for name, (path, size) in FONTS.items():
atlas, cells = render(path, size)
lines.append(f"static const int font_{name}_width = {atlas.width};")
lines.append(f"static const int font_{name}_height = {atlas.height};")
lines.append("/* Cell x, cell width, advance, cell start relative to the pen; ' ' to '~'. */")
lines.append(f"static const short font_{name}_glyphs[][4] = {{")
lines.extend(f" {{{x}, {w}, {a}, {s}}}," for x, w, a, s in cells)
lines.append("};")
lines.append(f"static const unsigned char font_{name}_pixels[] = {{")
data = atlas.tobytes()
for i in range(0, len(data), 32):
lines.append(" " + ",".join(str(b) for b in data[i:i + 32]) + ",")
lines.append("};")
text = "\n".join(lines) + "\n"
target = Path(sys.argv[1])
if not target.exists() or target.read_text() != text:
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text(text, newline="\n")
main()