Skip to content

rush2-xbox 1.2.0 — how to take a N64Recomp game to UWP

Choose a tag to compare

@jajdp jajdp released this 18 Oct 09:28
· 2 commits to main since this release

This is a recipe, not a game. It describes how to take a title of the N64Recomp + RT64
family to an Xbox Series in Developer Mode, using Rush 2: Extreme Racing USA as the real case.
Nothing of the game is here.

What changed: the launch was never the console

Until this release the documentation said that a launch takes minutes because the driver needs
180–190 s to build some of the pipelines, and that caching one is impossible on this console. The
second half is true. The first was a symptom — and the two real causes are measured, named and
written up:

1. The mipmap addressing modes. On the RDP it is normal for the higher mipmap levels to be
marked CLAMP while the lower ones are WRAP: there is nothing to repeat on a two-texel level. RT64
compares the modes of every level, and when they differ it drops the native sampler and emits a
shader that branches per sample. On an Xbox Series that shader costs ~200 s of pipeline creation
against 0.3 s for the plain one — seven of them ate 1 337 s of a 1 448 s launch. Taking
level 0's mode for every level: worst shader 262 s → 8.8 s, and the image is identical.

2. The first frame was waiting for the ubershader. State::fullSync() joins the threads that
create its eight pipelines before rendering anything; the first costs 26.8 s here and the other
seven are free. While the game thread sits in that join there is no workload, no present, and so
no logo, no interface and no loading bar — that was the 27 seconds of black screen before the
logo. And a counter says no draw call ever falls back to the ubershader: those seconds were
spent on a pipeline that does not draw a triangle.

before after
first frame on screen ~28 s ~0 s
the game, running ~50 s ~22 s
whole launch 5–6 min ~20 s

Two more things worth taking: how to find out which pipeline is the expensive one — log
psoDesc.PS.BytecodeLength next to the creation time and match it against the compiled .dxil
sizes — and how to show something while the shaders compile, when the only thing available is
clearColor over rectangles.

What is in the zip

Everything the v1.2.0 tag contains — 14 files: the five-step build recipe with the reasoning
beside each decision, one patch against RT64's plume (MIT) kept as a record of a dead end, and the
documentation in English and Spanish.

rush2-xbox-1.2.0.zip
SHA-256  ba7ff11484064f9b3b2865001b3abd9929d9f82248a3e628f197a95123881b61

What is still open

The port plays, at 59 FPS, and the owner confirmed this release on an Xbox Series X. Left on the
table: the game never opens the Controller Pak (#5), the boost pads are missing upstream and
not here (#3), a remnant of the sky fault shows as light triangles in the top-left corner on
tight curves (#6), and a playthrough from start to finish is still untested (#1).

The two decisions that are not obvious

The game's libraries cannot be built with the Visual Studio generator. MSBuild has no ClangCL
toolset for "Application Type = UWP" — asking for it with WindowsStore gives MSB8020 — and
cl.exe breaks the ecosystem, which is written for clang. The way is Ninja + clang-cl, with the
libraries as a desktop target: what makes them UWP is the _UWP macro from the patches, and the
only real WindowsStore project is the appx one.

The UWP dependency bundle has one branch per engine. Taking the wrong one leaves the link
unfinished with uwp_PickMultipleFiles unresolved.

And five startup traps the next game will hit too

SDL_INIT_HAPTIC does not exist in WinRT's SDL, and the game's own if (SDL_Init(...) > 0) check
never catches the -1 — so it ends up with no video, hanging on the window, with no message;
Windows.Gaming.Input has to be asked for or there is no controller; FOLDERID_LocalAppData is not
LocalState, and portable mode is no way around it; LocalState does not exist until the first
launch; and the container's stderr is invalid, so writing to it is a fail-fast — which is what
made the game vanish mid-race, with no exception, no dump and no message.

License

MIT, as N64Recomp and RT64 are. Nothing of the game project is here: it publishes no
license. The UWP forks the recipe builds on are worleydl's.

Rush 2: Extreme Racing USA is © Midway. Not affiliated with them, with Microsoft, or with the
authors of N64Recomp, RT64, the game project or the UWP forks. Rights holders:
jajdpmail@gmail.com.