Files
RP412/tools/pages
Cyd 5135476088 Track plans read as outlines, not hatching
Nearly every track is one model repeated: cn3, a wall bar whose gauge
image is two closed 25x5 rectangles. Five metres of wall thickness is
finer than the plan can resolve, so each bar was landing as two parallel
lines plus two end caps - several hundred times over, which is the
hatching that swamped the arenas. Collapse a thin closed quad to the
centreline between its short edges: one stroke for one wall.

Walls stacked to build height coincide seen from above, so draw each
distinct wall once. And drop placements standing alone more than 200
units from any other - fourteen tracks park a single bar at (1200,0,0)
well off the course, and that one placement stretched the frame to
twelve times the width of the track. The four tracks without it are
exactly the four that always framed correctly. A real branch keeps its
neighbours and stays: Paingod's second canyon is sixty bars out at
x=-400.
2026-08-07 11:05:16 -05:00
..
2026-08-07 10:27:26 -05:00
2026-08-07 10:27:26 -05:00
2026-08-07 10:27:26 -05:00
2026-08-07 10:27:26 -05:00

Regenerating the reference pages

docs/vtv-presets.html and docs/tracks.html are generated from assets/RP411/RPL4.RES, the gauge config, and the console's RPConfig.xml. Both are committed, so this is only needed when the resource file changes.

Both need a resource listing from the original tool, which is the authority for resource ids — the directory can be walked in file order, but the ids have holes (this file leaves 53 and 56 unassigned) so the walk has to be aligned against the listing:

Release\RPL4TOOL.exe -l assets\RP411\RPL4.RES > listing.txt   # ends in _getch(); close it
python tools\pages\extract_presets.py vtv.json listing.txt
python tools\pages\build_page.py     vtv.json docs\vtv-presets.html
python tools\pages\build_tracks.py   listing.txt docs\tracks.html

RPL4TOOL finishes with _getch() (RP_L4/RPL4TOOL.cpp), so with stdout redirected it writes the whole listing and then waits for a keypress — close it once the file stops growing.

What each reads

script reads writes
extract_presets.py RES, L4GAUGE.CFG, tools/console-config/RPConfig.xml, listing vtv.json
build_page.py vtv.json, GAUGE/s*.pcc silhouettes docs/vtv-presets.html
build_tracks.py RES, listing, RPConfig.xml, RPL4FE.cpp catalogs, tracks.css/js/tpl docs/tracks.html

build_tracks.py reads the front end's own kMaps / kFootballMaps arrays so the page cannot claim a track is offered when the menu does not offer it.

Two formats worth knowing

Control mappings. A vehicle's ControlsMappings List holds the resource ids of its L4 and Thrustmaster streams. Streams are named plainly, so there is nothing in a stream saying whose it is — resolve by id, never by which vehicle name sits nearest in the file. Records are 24 bytes and carry their own mode mask; bits 38 are ModePreset1..6.

Map instances. 76-byte records: class id at +0, position at +48, unit quaternion at +60. A few records are longer, so resync on an unexpected class id rather than trusting the stride. The quaternion doubles as a checksum — a mis-read almost never produces a unit one.