Car files
Stunts cars are made of four different resource files. For the original Stunts cars, all of the car graphics are stored in the compressed st*.p3s, stda*.pvs, stdb*.pvs files ('*' stands for a four-letter abbreviation shared by files of the same car). On many custom cars, .p3s and .pvs files are replaced by their uncompressed counterparts, with extensions .3sh and .vsh respectively. The fourth file, car*.res, contains numerical and text parameters, including data about car performance essential to the creation of tuned cars.
Graphics files (.p3s/.pvs)
Different aspects of a car's appearance are stored in each of the graphic files:
- st*.p3s - 3d shape resource file that stores the graphical 3D models of the car, including their colour data.
- stda*.pvs - Bitmap resource file that contains the dashboard image, including the shifting stick's base.
- stdb*.pvs - Bitmap resource file that contains the shifting knob. For the Corvette, it also stores the digital speedometer graphics.
Each of the files contain a number of independent resources, used on different places or in-game situations. Here a rundown of those resources contained within each file will be presented. For an explanation of internal structure of the resources, applicable to all files here discussed, check the Resource file format article. It is important to emphasize all graphics files are compressed, and thus any visualization or edition of the original cars' graphics calls for prior decompression. As a consequence, custom cars with modified graphics have the compressed .p3s and .pvs files substituted by their uncompressed .3sh and .vsh counterparts.
3D shapes (st*.p3s)
Standard st*.p3s files contain seven 3D shape resources, each being used in different circumstances:
- car0 shape is the one used in the car selection screen. It is richly detailed for Stunts usual standards, and has pretty high internal resolution.
- car1 shape corresponds to the car actually rendered on-track. Its resolution is much smaller than the car0 shape, the scaling down factor being 1:20, thus explaining why many fine details seen on the "showroom" car are not seen on-track.
- car2 shape is the very long distance model, used only for the initial zoom-in animation that precedes the "Fasten your seatbelt!" message at the start of a race. It has very low resolution, to the point of being barely recognizable.
- exp0, exp1, exp2 and exp3 aren't really proper 3D shapes, but rather individual lines and polygons that make up the bits of debris seen after a crash.
Dashboard static parts (stda*.pvs)
A car dashboard is composed by a number of separate bitmaps, not of them being used by all cars:
- !cg0 and !eg0 are alternative palettes for non-VGA graphic modes.
- dash is the base panel of the dashboard, covering most of its drawn area.
- dast complements the top of the dash bitmap with curved areas, as seen on the Indy for instance. Since all bitmap resources correspond, naturally, to rectangular areas, there's an additional bitmap, dasm, which acts as an alpha mask in order to have the proper looks of a curved surface instead of a rectangular block.
- roof is the strip seen atop above the windshield for a number of cars - for instance, the ones containing "PORSCHE" or "JAGUAR" inscriptions on the IMSA cars.
- whl2 is the centered steering wheel bitmap. The internal pixel coordinates of it are used to define steering wheel dot positions in the car*.res.
- whl1 and whl3 are graphics for the wheel steered left and right respectively.
- ins2 corresponds to the meters - tachometer and/or analog speedometer. Although the bitmap itself is redundant for all default cars, since the meter graphics are included in dash as well, ins2 has an actual purpose: define the internal coordinates for speedometer/tachometer needle render, controlled by car*.res.
- ins1 and ins3 are complementary graphics corresponding to small sections of the dashboard uncovered when the wheel is steered left or right (and so they are complementary to whl1 and whl3, in that order). Since the images are not rectangular, alpha masks inm1 and inm3 are needed, just like dasm was for dast.
- gbox is the shifting stick base. Coordinates for shifting knob positions are defined within the reference frame of this bitmap.
Dashboard moving parts (stdb*.pvs)
The stdb*.pvs file contains a few auxiliary bitmaps that are not rendered all the time or change position within the screen often:
- !cg0 and !eg0 are alternative palettes for non-VGA graphic modes.
- dot is the blue steering wheel dot. As every non-rectangular bitmap, it calls for an alpha mask, in this case called dota.
- dot1 and dot2 are strange versions of dot with a tiny palette-like strip inserted into its top. They are involved in the rendering of the dot at off-center wheel positions.
- gnob is the shifting gear knob, and gnab, its alpha mask.
- From dig0 to dig9 there are individually-stored digits for Corvette-style digital speedometers. Their rendering is not completely straightforward, as those digits do not are not placed over the dashboard as a rectangular block and yet there are no alpha masks.
All the dashboard moving parts are positioned according to various car*.res parameters, as described in the Car parameters article. The vector-drawn speedometer and tachometer needles are controlled by car*.res as well.
Editing and combining car graphics
Graphic files of different cars are independent, and thus can be mixed freely when constructing a new car. The main point of concern when doing so usually is adjusting car*.res so that moving parts of the dashboard behave properly. The classical example of this mix-and-match approach is Alan Rotoi's famous Melange. The actual edition of the graphics was a long-standing goal of the community that for many years was deemed impossible due the lack of information about the format employed by the developers to compress the files. In March 2008, this riddle was finally solved by dstien, and since then the possibilities for modding have grown a lot (see Tools section further down the article). As mentioned before, cars with custom graphics use uncompressed .3sh and .vsh resource files . Stunts 1.1 is able to read these uncompressed files correctly; however, if there are any compressed (.p3s and .pvs) files for the same car (that is, sharing the four-letter abbreviation) in the game folder these will be loaded in expense of the uncompressed files.
Car behaviour (car*.res)
All adjustable aspects of a car behaviour are stored in car*.res, a miscellaneous data resource file. It contains both physics data, such as power curves, and visual parameters, like car height in cockpit view or speedometer behaviour. Also, the file contains the text data displayed at the car selection screen. Data in car*.res may be read and modified by any hex editor, or more conveniently by a specially-designed graphical editor (see the Tools section ahead).
The structure of car*.res actually consists of four resources:
- simd, which contains all the numerical parameters;
- edes, a text resource containing the description displayed in the car selection screen;
- gsna, the 4-letter scoreboard abbreviation stored as a text resource; and
- gnam, the scoreboard car name.
Only the simd chunk is of fixed length (306 bytes) while the other three are variable-length ASCIIZ strings. While the order in which these chunk indices and their corresponding file sections is irrelevant to Stunts, all of the original cars have come with the simd chunk content first, resulting in the positions of car parameters appearing absolute (that is, relative to the beginning of the file). However, new cars or cars modified with new tools may not follow this order. More info in the Tools section.
The function of a large fraction of car*.res hex addresses was elucidated over the years, allowing modifications of many car aspects. Here is a quick reference for those addresses, originally based on the chart available at Lukas Loehrer's site. A more throughout discussion on the effects and quirks of the parameters is available at Car parameters; clicking on a parameter description will lead to the corresponding entry there. In the following table, "simd offset" refers to the actual position of the parameter within the simd chunk, that is, the way Stunts interprets the file. "Absolute offset" refers to the position relative to the beginning of the file in the cases in which the simd chunk contents have been placed first:
simd offset | Absolute offset | Function |
---|---|---|
000h | 26h | Number of gears |
001h | 27h | *"Purple" byte |
002h | 28h/29h | Car mass |
004h | 2Ah/2Bh | Braking effectiveness |
006h | 2Ch/2Dh | Idle rpm |
008h | 2Eh/2Fh | Downshift rpm (auto transm.) |
00Ah | 30h/31h | Upshift rpm (auto transm.) |
00Ch | 32h/33h | Maximum rpm |
00Eh | 34h/35h | *"Yellow" word |
010h | 36h-41h | Gear ratios |
01Ch | 42h/43h | *Unknown. Horizontal gear knob tabulation? |
01Eh | 44h/45h | Shift pattern centre line |
020h | 46h-5Ch | Shifting knob positions |
038h | 5Eh/5Fh | Aerodynamic resistance |
03Ah | 60h | Idle rpm torque |
03Bh | 61h-C7h | Torque curve |
0A2h | C8h/C9h | *"Blue" word |
0A4h | CAh/CBh | Grip |
0A6h | CCh-D9h | *"Red" words (7 of them. Defaults: 238, 184, 0, 32, 16, 12, 8) |
0B4h | DAh/DBh | Air grip |
0B6h | DCh-E3h | Surface grip modifiers |
0BEh | E4h-EDh | *"Orange" words (5 of them. Defaults: 0, 32, 192, 128, 64). More surf. grip? |
0C8h | EEh-F5h | Dimensions for car-car collisions |
0D0h | F6h/F7h | Car height (from inside view) |
0D2h | F8h-10Fh | Wheel coordinates / external dimensions |
0EAh | 110h-14Dh | Steering wheel dot movement |
128h | 14Eh-223h | Speedometer needle movement |
12Eh | 154h-159h | Digital speedometer |
1FEh | 224h-329h | Rev. meter needle movement |
32Eh-EOF | Text data (car selection screen and high score table) |
- Fields marked with a star (*) are either not used by the game or its impact on behaviour is unknown. The colour names have been given by Cas for easier reference. Only red #5 has been used on a mod to change the instrument needle colour.
Version compatibility
Cars that use graphic files from Stunts 1.0 do not work properly on 1.1 versions, and vice-versa. Attempting to exchange cars between versions will cause crashes in the car selection screen due to file format incompatibilities. The simpler and naturally uncompressed car*.res files may be exchanged between versions, although car performance won't be the same due to the known differences between game versions in that respect.
Tools
The car*.res files can be read and edited by any hex-editor or text editor able to display files in hexadecimal mode - HT and Vim are examples of each case). A more convenient alternative are graphical hex-editors designed especially for Stunts car hacking. Mark Nailwood's Car Blaster, by far the most used of those, has resources such as tags on useful bytes and comparison between cars. Other editors include 4D Sports Driving Car Editor / CarEdit3 and Winedit.
It should be noted that modified cars are not recognized by the original RPL Info tool, created by Lukas Loehrer.
In 2008, dstien started development of stuntstools, a set of programs that allow decompression of packed resource files and manipulation of the resources contained within. stuntstools' flagship application, stressed, revolutionized custom car creation by making edition of in-game 3D shapes and bitmaps possible. Starting from revision 59, stressed can also be used to modify CAR*.RES parameters as raw binary data.
Since 2020, it's also possible to edit these files using CarWorks. With it, the parameters can be edited directly and semantically, without any calculation being required, just filling the corresponding number field.
Tool-Format compatibility
The tool that's used to edit these files can have an impact on the order of the chunk content sections and their indices and then, some tools may not be able to properly read or edit the resulting file.
Original cars: For these cars, the indices are in the order edes, gnam, gsna, simd, but the actual chunks are stored like simd, edes, gsna, gnam, for some inexplicable reason. This results in compatibility with all tools, but difficulty to calculate the chunk lengths at load time, because of the inconsistency.
Car Blaster: This tool only reads and modifies the simd parameters and assumes that such chunk is positioned first. If it is not, it will misinterpret the file and potentially destroy the contents. It is incapable of detecting if a car file has a different chunk order. However, it doesn't care about the index order.
Stressed: With this tool, you can read and save the chunks in any order. Whatever the order is, the indices are stored in the same order as the chunks. Stunts will read the file always, but to preserve compatibility with Car Blaster, care should be taken to ensure that simd is stored first.
CarWorks: Like with Stressed, any order of the chunks will be read without a problem. When saving files, CarWorks will store both the chunks and their indices in the order simd, gnam, gsna, edes. This order is different from the original, but is more consistent and ensures that simd is located first, thus providing compatibility with Car Blaster. It does not, however, allow the user to set a custom ordering of the resource chunks.