The Payload Manager's port can stay dead after rest mode; the PS5Upload engine's launch route starts the title then. A plan's remove line now deletes a single file too.
The disc and name band of the radial menus and the hints bar take the darkest shade twice over, and their text has the font's outline, so they read over a busy park on a TV.
The import page and screen take GOG's offline installer: the setup .exe and its .bin file, chosen
or dropped together, or the whole download folder dropped. src/port/inno.c reads Inno Setup 5.5 to
6.4 (Unicode) after innoextract's reading of the format, including GOG Galaxy's layout, where each
game file sits under {tmp} in deflated parts named after their MD5. Chunks are read once, front to
back, with zlib or liblzma (xz 5.8.1, decoders only, from tools/build-deps.sh), and every file is
checked against its SHA-1. tools/test-inno.sh builds the reader for Linux and compares it with
innoextract: all 2457 game files of the Triple Thrill Pack installer match.
On the console the 554 MB installer arrives in about 50 s and unpacks on a thread in about 85 to
100 s. Creating files in the title's folder is the cost (about 35 ms each), so files are written in
place, and unfinished-import in the game folder keeps a half-unpacked folder from counting as
complete. A missing .bin is named and the .exe kept until it arrives; the screen clears its notes
when a new send starts and wraps them. The upload server also checks for a stop before every recv.
screenshots/: the title, the import screen during an upload and the page it serves, Six Flags
Magic Mountain with the button hints, both radial menus, and the rides list moved through with
the d-pad, taken on the console.
Taking them showed the import server stalling for a browser: it served one connection at a time
and waited up to 30 s for its request, and browsers open connections before they need them.
It now keeps up to eight waiting and serves whichever sends a request first (with one held idle,
a request is answered in 0.01 s); every import so far had used tools/send.py. A complete import
into an empty folder ran through with it. The import screen no longer shows an arrow at 0, 0,
where going full screen put the pointer; the game gets it back. Radial menus hide the pointer,
tooltips and the park's label while up (patches/openrct2 0013).
Rijad plays with the DualSense alone, so the SDL patches now read nothing else: the fork's USB
keyboard and TV remote input is removed, the on-screen keyboard (IME dialog) is the only keyboard,
and the mouse patch keeps only the pointer the game moves, with its cursor drawn in software
(patches/sdl 0004 and 0005, rewritten; 0006 is the touchpad patch as before). libSceMouse's stub
list goes with it.
On the console, the radial menu test and a new one that clicks a text box (console-ime) ran as
before. The sound works: Rijad heard it.
patches/openrct2 0010 to 0012 (see DEVELOPMENT.md, Changes to OpenRCT2 and Controls): the left
stick moves the pointer with a curve, acceleration and friction over buttons; the d-pad jumps
between buttons, through lists, sliders and dropdowns; Circle goes back; L1/R1 switch tabs;
Options and Triangle show the build tools and park windows in radial menus; while building track
or a bridge path the d-pad picks the piece, Cross builds and Square removes; the d-pad raises
scenery; the bottom toolbar lists what the buttons do.
Test plans for each, run on the console; the older plans no longer press Triangle to close
windows (it opens the park windows now), and the quick menu and pointer plans are gone.
A reply goes out as two sends, head and body. With Nagle the body waited until the sender
acknowledged the head, which Windows delays by up to 200 ms, so every file cost about 105 ms
on top of its data. With TCP_NODELAY a complete import into an empty title (2457 files,
671 MB) took about 2.5 minutes instead of 7, and the game then started from the imported files.
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.
OpenRCT2 draws one frame per 40 Hz game tick unless uncap_fps is on, which judders on a 60 Hz
TV. With it on (interpolated frames, paced by the VideoOut flip) a park runs at 56 to 58 frames
per second while scrolling and zooming. The console test harness logs the frame rate every 300
frames; test/console-perf.cfg measures it in a park.
- OpenRCT2 patch: a PS5 platform UI context. The Linux one looked for zenity through popen, which
crashed when saving a new game.
- The stubs leave out libkernel_sys and libkernel_web as well: functions bound to them are null
in a game process. What the game used from them (openat, unlinkat, readlink, pathconf, fork)
is implemented in the runtime instead, so linking now fails on any such import.
- SDL and OpenRCT2 patches: USB keyboards type text; the IME dialog starts with the text being
edited and replaces it.
- tools/symbolize.sh names crash report frames from the linked ELF ps5-link keeps.
- test/console-save.cfg starts a scenario and saves it.
- SDL: the driver loads the keyboard, IME and mouse modules itself (main no longer does), reads
USB and Bluetooth mice through libSceMouse, draws the cursor in software, reports the DualSense
touchpad, and decodes IME results from UTF-16. Stubs for libSceMouse and libSceCommonDialog
are generated from src/runtime/stubs.
- OpenRCT2: a gamepad pointer (left stick and touchpad move it, Cross and Square click, Circle
speeds it up), the right stick scrolls, default controller shortcuts on the PS5, and the
16-bit wchar_t conversion fixed (ICU and OpenRCT2 are now built with U_SIZEOF_WCHAR_T=2, which
fixes the garbled scenario names).
- Console tests: plan lines input (scripted pad input through PS5_PadCallback) and point (put
the pointer somewhere); plans for the pointer, starting a new game and the in-game controls.
- Runtime: stdio output goes to the log file and the kernel log (the console's printf writes
nowhere visible); exit ends the title through sceSystemServiceLoadExec (the exit system call
gets it killed with SIGSYS); realpath on stat (the libc's fails with EPERM, which broke libc++'s
relative and with it OpenRCT2's case-insensitive file lookups); threads get 2 MiB of stack (the
console's default is 64 KiB); folder listing keeps nullfs entries, whose inode is 0.
- The game relinks when the runtime changes.
- main loads the keyboard and IME dialog modules (their imports are null otherwise), selects
SDL's software renderer, and writes a first-run config with the interface at 2x.
- The documentation (changelog) is packaged into the data folder.
- Console tests: plan lines list, stat, realpath and arg; the harness logs the renderer and how
much of each captured frame is lit. tools/klog.py records the kernel log; tools/deploy.py
--eboot uploads only the executable.
Spike for the native PS5 title (PPSA99728). OpenRCT2 with the software renderer compiles and
links into a signed module; nothing has run on the console yet.
- tools/ps5-cc, ps5-c++ and ps5-link: clang 18 for x86_64-sie-ps5, and links that produce real
PS5 modules (prospero-lld, native-app linker layout, ps5-native-tool), so configure checks see
what the console offers.
- src/runtime: malloc from a direct-memory mspace, a sandbox-safe opendir family and scandir,
and the libc functions libc++ and the libraries need that the console's libc lacks.
- tools/build-deps.sh: zlib, libpng, zstd, libzip, Ogg, Vorbis, FLAC, nlohmann/json, ICU 78.3
(filtered to OpenRCT2's five code pages) and ps5-payload-dev's SDL2, pinned by SHA-256.
- tools/build-host.sh: the Linux build that makes OpenRCT2's data folder.
- patches/openrct2: the PS5 title supplies main.