Ridge Racer Decompilation
Ridge Racer
OrigenPlayStation
TecnologíaDescompilación y Reconstrucción en C/C++
Disponible paraWindows, Linux
Ver proyecto oficialSobre el proyecto
Ridge Racer es un videojuego de carreras desarrollado y publicado por Namco de 1993. Se lanzó inicialmente en la placa de sistema arcade Namco System 22 y se transfirió a la consola PlayStation en 1994. Es el primer título de la serie Ridge Racer lanzada para arcades y consolas domésticas. El objetivo es terminar en primer lugar en una serie de carreras. La versión de PlayStation es compatible con el controlador NeGcon de Namco.
3 versiones de Ridge Racer
Estás viendo: Ridge Racer Decompilation
Información oficial del proyecto
rr-decomp
Matching decompilation of Ridge Racer (PlayStation 1, Namco, 1994 — Japan release,
RIDGERACER volume, SLPS-00001), and a static recompilation that runs it natively.
No game is distributed here, and none can be. There is no download that plays Ridge Racer: everything is built from
PSX.EXEand the game reads its data from the disc. You need your own legally-owned copy (SLPS-00001), dumped from your own disc, to build or verify anything. Without it, what is offered is the code and the notes.
No copyrighted game data is committed here — no disc image, no executable, no textures, no
audio, and no disassembly. asm/, assets/ and build/m0/asm/ are regenerated on your
machine from your own copy by python3 tools/setup.py — the same practice as every project
on decomp.dev.
Status
$ python3 tools/progress.py
game code: 408/408 functions in C, 186536/186536 bytes (100.00 %)
$ python3 build.py
build/PSX.EXE 31ec5d3616a0fdb456da27a984fc5b92259ff1f6 OK - matches the original
What that figure covers, exactly:
- All 408 game functions (
0x800121F4–0x8003FA9C, the code Namco wrote) are plain C insrc/fn/, one file per function. There is noINCLUDE_ASM, no__asm__and no inline MIPS anywhere insrc/. Each file is compiled by GCC 2.5.7 (-O2 -G0 -mips1 -msoft-float) through maspsx (ASPSX 2.21 mode). The result is linked, and the whole executable is compared with the original: byte-identical. - The PsyQ libraries (Sony's runtime, from
0x8003FA9C) stay assembly (asm/psyq.s, regenerated locally). They are not part of the game. - Data and rodata stay splat output (
asm/data/, regenerated locally).
tools/progress.py counts a function as done only if it has a C file in src/fn/. The
size column comes from the original's function table, not from the build.
History note. Until August 2026 this repo reported "949/949 byte-matching". That count came from transcribing the original MIPS into
__asm__blocks, so it matched by construction and proved nothing. It was replaced by the standard splat layout and an honest count: 23 % of functions and 5.6 % of instructions in real C. The figure above is that same honest count, now complete — every game function is real, compiled C.
Building the matching decomp
sh tools/toolchain.sh # once: GCC 2.5.7 PSX, binutils-mips, m2c (Linux/WSL)
cp /path/to/PSX.EXE . # SLPS-00001, sha1 31ec5d36...
python3 tools/setup.py # splat: asm/ (libs + data), assets/, build/m0/asm/
python3 build.py # compiles src/fn/*.c, links, checks the sha1
build.py reads RR_GCC (the compiler directory, /opt/decomp/gcc/2.5.7 by default).
maspsx is vendored in tools/maspsx (MIT). splat is pinned to 0.50.0 / spimdisasm 1.42.4
by tools/setup.py.
| path | what |
|---|---|
rr.yaml, symbol_addrs.txt, undefined_syms.txt | splat config of the matching build |
src/fn/*.c | the game, one file per function. func_80034050.c also holds func_8003446C: the two only match when compiled together (/* covers: */ marker) |
include/ | common.h, game.h, assembler macros |
tools/segments.py | regenerates the src/fn subsegments of rr.yaml |
tools/try.py | compiles one C file and diffs it against the original function |
tools/jtbl.py, tools/fixjtbl.py | jump tables (/* jtbl: … */ markers in the C files) |
tools/autodec.py, tools/perm_* | m2c drafts and decomp-permuter batches used while matching |
m0.yaml, m0_symbol_addrs.txt, m0_reloc_addrs.txt | listing for the native runtime (below). m0_symbol_addrs.txt also holds the descriptive names found so far (st_race_main, car_simulate, …) |
Notes from the matching
- The rodata boundary fix (
0x29E8 → 0x29F4) and the game/PsyQ seam at0x8003FA94, both found by the earlier pipeline, held. - The earlier belief that the game was built with four flag sets (
-O1and-O2, GCC 2.5.7 and 2.7.2) did not hold: every game function matches GCC 2.5.7-O2. The apparent-O1units were-O2register-allocation and scheduling effects that the C had not yet reproduced. - What it took for the last hundred functions, for anyone matching GCC 2.5.7: nested
assignments to fix operand order (
m = i + (m = m + 1)),do { } while (0)to raise a pseudo's allocation priority, dead stores to break CSE, statements repeated in each branch to reproduce cross-jumping, globals accessed as struct fields to pin the scheduler, implicit-intcallees for the delay-slotnopbefore ajal, andcc1 -dlgdumps to read the allocation order.
The native runtime
A second track runs alongside the decompilation: a static recompilation.
tools/recomp.py translates every MIPS instruction of PSX.EXE into C
mechanically, and tools/m0/ supplies a model of the hardware. The point is
not emulation — it is to have a native milestone that boots today, so that each
byte-matched function can replace its translated twin one at a time without
ever breaking the whole.
It is playable today — v0.1.0. It boots from your own disc image to the
loading screen, the title, the menu and a race; it draws, it plays the disc's
twelve Red Book audio tracks and synthesises the SPU's twenty-four voices, and
it takes a keyboard or a gamepad. Analogue steering and pedals go through the
neGcon protocol the 1994 game already speaks. It builds natively on Linux and,
with --windows, on Windows. CHANGELOG.md says what that
covers, what it does not, and which defects had to be found on the way.
See tools/m0/README.md
to build and run it, and RECOMP_NOTES.md for the defects
found along the way — the translator's own bugs were found by differential
testing against qemu-mipsel (114/116 functions bit-identical over 1856 cases),
and the GTE's against an independent second implementation (11 600 comparisons,
29 encodings).
Its listing comes from m0.yaml, written to build/m0/asm/ by tools/setup.py.
Nothing generated by this track is committed: game.c is the game's own code in
another notation, exactly as asm/ is.
Asset formats
MAP_RRM_FORMAT.md— track geometry file.TRACK_SPINE_FORMAT.md— the track centreline node tables inPSX.EXE. This closes the "Not found" item in the MAP.RRM writeup: there is no per-section transform because there is nothing to place. The track is a 20-byte-per-node polyline (D_8005A44C/D_8005B84C/D_8005CC4C) and MAP.RRM's quads are skinned along it. All three tables decode to closed loops.DISC_NOTES.md— disc layout.
Next steps
- Names: carry the descriptive names in
m0_symbol_addrs.txt(345 functions) intosrc/fnandsymbol_addrs.txt, and type the globals. - Group
src/fnback into the original translation units. - In the native runtime, replace the recompiled functions with the matched C, one at a time.
Transparency
Heavily AI-assisted: tooling, splitting and C conversions are driven by Anthropic's Claude
under human direction and review. Nothing here requires trust — with your own copy of the
game, python3 tools/setup.py && python3 build.py reproduces the result locally.
