Rage Racer PC
Rage Racer PC brings Rage Racer to PC.
- Type: PC port
- Game: Rage Racer
- Runs on Linux, macOS and Windows
- By khasinski
- Latest release 0.6.5-alpha, 2026-09-09
- Source: https://github.com/khasinski/rage-racer-pc
README
Rage Racer PC
Native Windows, Linux and macOS port of Rage Racer (PAL / Europe,
SCES-006.50). It contains the complete game, platform packaging and runtime
compatibility layer.
Running a release
Extract the whole archive, then open Rage Racer.app on macOS, Rage-Racer.exe on Windows, or rage-racer on Linux. Select your legally obtained Rage Racer CUE (with its BIN tracks alongside it), Track 01 BIN, or CHD when prompted. Native assets are imported automatically and the game starts with the modern renderer. No separate launcher or extractor is required.
Press F10 to switch to enhanced classic rendering. Video settings are in
rage-port.ini; see the classic renderer guide for
resolution, widescreen and FPS examples. No game data is supplied in the archive.
Build from source
The project uses CMake and its pinned PSY-Z compatibility layer:
git clone --recurse-submodules https://github.com/khasinski/rage-racer-pc.git
cd rage-racer-pc
cmake -S . -B build/release -DCMAKE_BUILD_TYPE=Release
cmake --build build/release --parallel
The native game, importer, tools and in-tree tests require a C17 compiler; vendored dependencies retain the language standard selected by their upstream build files.
Linux desktop builds need SDL's Wayland and/or X11 XRandR development
dependencies. Check CMake's final SDL summary for wayland or xrandr;
the dependency list used by releases is in
the Linux workflow. A build missing both
can report a fallback 60 Hz even on a 120 Hz desktop. The modern renderer logs
its SDL video driver and selected refresh rate when video.fps=vsync.
For local development, provide a legally obtained disc image through the runtime disc setting (paths may be relative or absolute):
RAGE_PORT_DISC_CUE="/path/to/Rage Racer (Europe).cue" ./build/release/rage-racer
The resulting executable is build/release/rage-racer on Linux,
build/release/Rage Racer.app on macOS and build/release/Release/rage-racer.exe
with the Visual Studio generator on Windows. Release downloads are supplied
as ZIP archives for macOS arm64, Linux x86-64 and Windows x86-64. Every archive
contains the documented rage-port.ini modern-renderer preset.
Scenario files
race-scenario.ini can launch a race through the normal asset-loading flow
without manually navigating the menus:
./rage-racer --scenario race-scenario.ini
./rage-racer --scenario custom.ini --set race.class=3 --set race.course=2
--set section.key=value options override values from the INI file. The
optional grid contains
the eleven rival car IDs in retail start-position order; -1 leaves a slot
empty. The player retains the normal starting position.
--set race.variant=N selects a zero-based asset variant within the chosen
car's catalog range before loading its assets. Omitting it preserves the
normal car setup; out-of-range values are ignored with a diagnostic.
The launcher passes this file directly to the game as --scenario; it no
longer expands it into a collection of environment variables.
For repeatable local runs, the native rage-scenario tool provides checked
short options for the common race values and forwards them to that same public
interface. It does not create a second scenario format:
./build/rage-scenario race-scenario.ini --binary ./build/release/rage-racer \
--class 3 --course 2 --car 9 --dry-run
After the race, after_finish = menu (the default) leaves the replay and
result screens to the retail flow but stops scenario automation, returning
control to the player. Use repeat to launch the configured race again or
exit to close the port after leaving the result screens. The same setting is
available as --after-finish menu|repeat|exit.
The scenario file accepts every launch setting below. Numeric class, course and car values are the retail zero-based indices.
| Section | Setting | Values / meaning |
|---|---|---|
race | mode | grand-prix, time-attack |
race | series | grand-prix, extra-gp; time attack always uses Grand Prix |
race | class | 0 to 5 |
race | course | 0 to 3 |
race | car | 0 to 12 |
race | transmission | default, automatic, manual; original per-car restrictions still apply |
race | after_finish | menu, repeat, exit |
race | grid | default, or exactly 11 comma-separated car IDs; -1 leaves a slot empty |
boot | direct | true skips race-selection menus; false drives the normal menus |
boot | skip_sequences | Skip the opening FMV and Grand Prix prologue when true |
start | player_track_point | Player track-point index |
start | rival_track_points | Up to 11 comma-separated point indices; - keeps the retail pose |
start | player_x, player_z | Exact world coordinates; both must be present |
start | player_heading | Optional exact heading used with player_x / player_z |
start | camera | Initial retail camera-view index |
start | freeze | Reapply the configured diagnostic placement every frame |
For renderer and rear-view debugging, scenarios may start cars at exact points of the loaded track:
[start]
player_track_point = 120
rival_track_points = 118,116,114,112,110,108,106,104,102,100,98
# Reapply these positions every frame for deterministic rendering diagnostics.
freeze = true
The engine recalculates world position, height, heading, track section and lap
progress from these indices. A - entry keeps that rival's retail grid pose.
Native frame replay
Renderer bugs can be reproduced without navigating the game again. This debug
function is disabled in the shipped configuration. Set
[diagnostics] marker_capture = true, then press M in modern mode to write
markers/marker-N-world.bin, the displayed images, the legacy scene record and
a text dump of the native draw spans. The world file contains the exact
renderer-neutral cameras, transforms, materials and mesh instances used for
that frame; it contains no disc assets. With the default
marker_capture = false, pressing M has no diagnostic side effects.
Build and replay it offscreen with:
cmake --build build/release --target rage-frame-replay
build/release/rage-frame-replay markers/marker-0-world.bin \
--assets build/release/native-assets \
--output marker-0-replay.ppm \
--draws marker-0-replay.txt
Use --width and --height to match the captured target. A legacy marker's
exact camera can be applied to another compatible world snapshot with
--camera-scene markers/marker-0-scene.bin. --probe X,Y lists every clipped
native triangle covering a pixel, including its depth, material, source mesh
and authored bias. Automated diagnostics.modern_dump_scene = true captures
the same .world.bin and .draws.txt sidecars next to a modern frame dump.
Runtime requirements
- macOS on Apple Silicon (arm64), a glibc-based x86-64 Linux distribution, or 64-bit Windows 10/11
- A legally obtained Rage Racer disc image: a
.cuesheet with all referenced track files, a Track 01.bin, or a CHD Movies are decoded in process, so no external tools are needed.
On first launch the port looks for a .cue, .bin or .chd image next to the
executable and uses it when one is there. Otherwise it opens a native file
picker and remembers the answer. The compiled C importer converts the selected
disc's models, textures and sky directly into renderer-native data in memory;
there is no setup command, asset download, Python runtime or classic-renderer
fallback. To pick a different disc later, start the game with
--set disc.choose=1, or pin one with [disc] image in rage-port.ini.
Normal runtime settings are read from rage-port.ini. Use --config FILE for
an alternative file and --set section.key=value for an individual override.
There are exactly two renderer modes. classic presents the faithful
PS1-compatible output. modern presents native RenderWorld geometry with a
normal depth buffer, configurable internal scale, optional 16:9 presentation,
an interpolated frame rate and FXAA. It never falls back to captured PS1 3D.
The supplied file defaults to modern:
[video]
renderer = modern
internal_scale = 4
aspect = 16:9
fps = vsync
post = fxaa
toggle_renderer_key = F10
The complete normal runtime configuration is listed below. Every option can be
placed in rage-port.ini or supplied as --set section.key=value.
Video settings:
| Setting | Values |
|---|---|
renderer | classic, modern |
internal_scale | 0.5 to 16 |
aspect | auto, 4:3, 16:9 |
fps | logic, vsync, or an integer from 1 to 1000 |
draw_distance | 0 to 16 |
texture_filter | nearest, linear |
post | none, fxaa |
grading | off, vibrant |
toggle_renderer_key | an SDL key name, such as F10 |
Display, content and storage settings:
| Section | Setting | Values / meaning | Shipped value |
|---|---|---|---|
hud | anchor | center, edges | edges |
hud | show_lap_times | true, false | true |
hud | show_time_limit | true, false | true |
camera | chase_turn_lookahead | 0 to 1; 0 is retail | 0 |
modern | assets | Optional explicit prebuilt native-asset cache for renderer development, or disc; omitted always imports from the selected disc | omitted |
modern | ray_tracing | Experimental hybrid rays: off, shadows, reflections, full. May cause visual artifacts and substantially reduce performance. | full |
modern | mirror_distance | 0.25 to 8, capped at the main view distance | 1 |
timing | standard | auto, pal, ntsc | auto |
content | car_names | international, japanese | international |
content | prologue | international, japanese | international |
disc | image | Path to a CUE, Track 01 BIN or CHD | remembered picker choice |
disc | choose | true opens the picker again | false |
mods | directory | Extracted-asset or semantic mod directory | omitted |
Diagnostic settings:
| Setting | Values / meaning | Shipped value |
|---|---|---|
log | auto, or an explicit log path | auto |
marker_capture | Enables the M-key frame/world debug bundle | false |
marker_history | Retains 16 preceding frames when marker capture is enabled | false |
marker_probe_x, marker_probe_y | Optional modern-target pixel to list overlapping native triangles in each marker | -1, -1 |
performance | Logs average modern renderer costs every 120 frames | false |
Input-device settings:
| Setting | Values / meaning | Shipped value |
|---|---|---|
analog | Enable analog gamepads as NeGcon devices | true |
wheel | Enable raw SDL racing wheels | true |
wheel_steering_axis | SDL axis index 0 to 31 | 0 |
wheel_steering_inverted | true, false | false |
wheel_throttle_axis | SDL axis index 0 to 31 | 2 |
wheel_brake_axis | SDL axis index 0 to 31 | 3 |
wheel_pedals_inverted | true, false | true |
wheel_cross_button | SDL button index 0 to 63, or -1 | 0 |
wheel_square_button | SDL button index 0 to 63, or -1 | 1 |
wheel_circle_button | SDL button index 0 to 63, or -1 | 2 |
wheel_triangle_button | SDL button index 0 to 63, or -1 | 3 |
wheel_l1_button | SDL button index 0 to 63, or -1 | 4 |
wheel_r1_button | SDL button index 0 to 63, or -1 | 5 |
wheel_start_button | SDL button index 0 to 63, or -1 | 9 |
force_feedback | true, false | true |
ffb_gain | Master strength, 0 to 1 | 0.55 |
ffb_center | Speed-weighted centering, 0 to 1 | 0.80 |
ffb_slide | How light the wheel goes in a slide, 0 to 1 | 0.70 |
ffb_collision | Impact kick, 0 to 1 | 0.75 |
ffb_road | Crests and camber, 0 to 1 | 0.25 |
ffb_damper | Resistance to a fast hand, 0 to 1 | 0.20 |
ffb_min_force | Lifts weak torque over wheel friction, 0 to 1 | 0.06 |
ffb_soft_lock | Wall past the game's steering lock, 0 to 1 | 0.85 |
ffb_engine | Engine vibration, 0 to 1 | 0 |
ffb_invert | true, false | false |
Each of the steering, throttle and brake axes accepts _deadzone
(0..0.99), _saturation (0.01..1), _linearity (-2..2) and _scaling
(0.01..10). Defaults are 0, 1, 0, 1, except
steering_linearity = 0.5. The 16 keyboard keys up, right, down, left,
cross, circle, square, triangle, l1, r1, l2, r2, select,
start, l3 and r3 accept SDL key names and are listed with their defaults
under Controls.
The legacy disc.cue name, video.bloom no-op and documented
RAGE_PORT_* automation environment variables remain accepted for old test
setups, but new configuration should use the keys above.
nearest retains the hard texel edges of the source artwork. linear smooths
texture sampling in the enhanced 3D renderers and in the final 2D presentation. The
checked-in rage-port.ini documents the remaining sections and their ranges.
Raw racing wheels are supported even when SDL does not classify them as a
gamepad. They use the game's NeGcon analog path; wheel_steering_axis,
wheel_throttle_axis, wheel_brake_axis, pedal inversion and the face/shift
button indexes can be adjusted under [input]. The defaults follow common
Logitech layouts, while keyboard input remains available for menus.
A wheel that can play a constant force gets one, built from the car's steering,
speed, slide and impacts. Pause the race and confirm the FFB row to turn it
on or off; left and right on that row change the strength in steps of 5
percent. The choice is saved next to the remembered disc path. The other
ffb_* scales stay in [input]. A gamepad takes the same impacts as rumble.
On a wheel with no constant-force support, and on macOS where most rims have
no force-feedback driver, the effect stays off and the race runs as before.
In modern or enhanced classic 16:9, [hud] anchor = edges moves the corner HUD into the added
widescreen area; use center for the retail 4:3 positions. Set
show_lap_times or show_time_limit to false to hide those race displays.
The third-person chase camera can look into a turn as the car steers. Adjust
[camera] chase_turn_lookahead from 0 (retail camera) to 1 (up to roughly
30 degrees at full steering lock). It is optional and defaults to the unchanged
retail camera (0).
Set [content] car_names = japanese to use the Japanese-release model names:
Alouette, Instinct, Victoire, Tempest and Dragone. This changes labels only;
the cars, save data and handling remain identical.
Set [content] prologue = japanese for the longer Japanese-release Grand Prix
prologue text. The English narration is recorded into Track 02 of the Japanese
disc, not the executable, so it plays when a legally obtained NTSC-J CUE/CHD is
selected. With a PAL disc the extended text uses the PAL instrumental track.
Modern mode imports its renderer-native assets automatically from the selected
disc. Developers can still select a prebuilt cache with
[modern] assets = /path/to/native-assets; an explicitly configured missing or
incompatible cache is an error, so a typo cannot silently change the rendered
content.
Press F10 while playing to switch between classic and modern rendering
without restarting the race; the key is configurable as
[video] toggle_renderer_key. F4 goes full screen and back.
In the modern renderer the rear-view mirror is a native second camera. It renders the complete semantic track and traffic scene into its own small color and depth target, reflects it left-to-right, and composites it under the original HUD frame. It does not reuse the PS1 mirror ordering table, GTE matrix, or classic visibility list.
The port keeps
game saves and the selected disc location in the user's local application data.
For compatibility with older portable releases, an existing bu00 directory
beside the executable takes priority (beside the .app bundle on macOS). The
game does not create a portable directory automatically. Otherwise memory-card
saves are regular files in the bu00 subdirectory: under
~/Library/Application Support/Rage Racer/ on macOS,
${XDG_STATE_HOME:-$HOME/.local/state}/rage-racer/ on Linux, and
%APPDATA%\Rage Racer\ on Windows. They no longer depend on the directory
from which the executable was launched.
Each normal launch appends diagnostics to rage-racer.log in the platform's
application-state directory. Configure [diagnostics] log to choose another
file. The disc can likewise be pinned with [disc] image; the older cue key,
RAGE_PORT_LOG_PATH and RAGE_PORT_DISC_CUE overrides remain available for
automation.
Rage Racer uses mixed-mode CD audio. For the complete soundtrack, select a CUE or CHD that describes Track 01 and audio Tracks 02–17. Selecting Track 01 BIN directly is supported and provides the game, FMVs and all modern-renderer assets, but it cannot describe the separate CD-audio tracks. Keep all BIN files referenced by the CUE together and prefer that full CUE on first run.
日本版について
日本版(NTSC-J)のディスクでも動作しますが、一部のメッセージは表示されません。 メモリーカードの確認、車の説明、ネジコンの調整画面の説明などが空欄になります。
このポートは欧州版の実行ファイルを移植したものです。欧州版はアルファベットの フォントから一文字ずつ文章を組み立てますが、日本版は同じビデオメモリの位置に、 文章そのものを描いた画像を置いています。日本版のディスクには欧州版が必要とする フォントが存在しないため、これらのメッセージは描画されません。
画面の配置の問題ではなく、二つの版がテキストを別の方法で持っているためです。 それ以外のメニュー、レース、動画は日本版でも問題なく動作します。
About the Japanese release
An NTSC-J disc runs, but the messages the game builds from its shared text sheet stay blank: the memory card prompts, the car descriptions, and the NeGcon calibration instructions.
The port carries the European executable. That one keeps an alphabet at a fixed place in video memory and sets a message one letter at a time. The Japanese release puts whole pre-drawn Japanese sentences in that same place instead, so the alphabet the European code looks for is not on the disc at all and those messages draw nothing. It is not a matter of where the text sits on screen; the two releases hold text in different ways. Everything else runs.
Controls
Gamepad
A connected gamepad is driven as a NeGcon, the analog controller the game was
built around. The left stick steers in proportion to how far it is pushed and
the triggers meter the throttle and the brake, while the d-pad still steers at
full lock so either input can be used. Dead zone and steering sensitivity are
the game's own NeGcon settings, adjustable in the OPTIONS menu as "play" and
"max twist". Set [input] analog = false to keep a pad on the digital
mapping instead.
The response of each axis can be shaped, using the same four settings and the
same ranges DuckStation gives a NeGcon, so values can be copied between them.
The axes are steering, throttle and brake, which are the twist and the I
and II buttons of a real NeGcon:
[input]
steering_deadzone = 0.1
steering_linearity = 0.5
deadzone runs 0 to 0.99 and saturation 0.01 to 1, both as fractions of the
travel. scaling runs 0.01 to 10. linearity runs -2 to 2 and is an exponent
rather than a fraction: 0 is a straight line, above it softens the middle of
the throw, below it sharpens it. Steering defaults to 0.5; throttle and brake
remain linear at 0. A value out of range is reported and ignored.
These sit in front of the game's own NeGcon dead zone and twist range, which stay where they always were, in the OPTIONS menu.
Keyboard
The default bindings emulate the original PlayStation pad:
| Game action | Default key |
|---|---|
Accelerate (CROSS) | X |
Brake / reverse (SQUARE) | Z |
Change camera (TRIANGLE) | S |
Handbrake (CIRCLE) | D |
| Steer | Arrow keys |
| Shift down (` |