mirror of
https://github.com/lowbit/ps5-openrct2.git
synced 2026-10-18 02:01:00 +02:00
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.
62 lines
2.5 KiB
Python
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()
|