Files
RP412/tools/pages
Cyd f32494f0b7 The VTV page tabs by hull
Thirty-eight cards in one run is a lot to read. The first letter of a
vehicle's two-letter art code is the hull the game actually draws it
with, and the console's class names are subdivisions of those five -
Bull and Roadblock are both 'b', Bug and Skeeter both 's' - so grouping
by the letter keeps kin together whatever the console called them.

Particles 6, Bugs 10, Mules 9, Bulls 8, Police 5, which is all of them.
The build prints a warning if any vehicle falls outside the five, so a
new hull cannot go missing from the page quietly. The tabs compose with
the armament filter and the search box rather than replacing them.
2026-08-07 11:05:25 -05:00
..
2026-08-07 11:05:25 -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.