Wacky Wheels Track Format
Wacky Wheels stores its levels across multiple files, with a different aspect of the level in each file.
- 1 Level files
- 2 Other level-specific files
- 3 Tools
- 4 Credits
Map info – *.gam
These are ASCII text file with CRLF line terminators (DOS format). Files contain either 25 or 28 lines. (Some of the *.gam files that ship with Wacky Wheels are one line longer than they need to be, but the last line is empty.)
Lines 9 and 10 give the position of the start line, but the computer players get confused if you move the start line too far. I think the finish line is located using the *.pos files. The game might rely on the start line being in a relatively fixed position relative to the finish line.
|1||File name of the primary tile graphics file, with the leading a_ removed (e.g. f3.pcx designates a_f3.pcx)|
|2||File name of the secondary tile graphics file|
|3||File that selects properties for the primary tile graphics file (again with the leading a_ removed)|
|4||File that selects properties for the secondary graphics file|
|5||File name of the sky PCX file to use (using the full file name)|
|6||Always 1250 in the *.gam files that ship with the game. Unknown use.|
|7||Always 1500. Unknown use.|
|8||Always 1. Unknown use.|
|9||X position of the start line. X=0 is at the left edge of the map as viewed in the course preview screen. The right edge is near X=2048.|
|10||Y position of the start line. Y=0 is at the top edge of the map. The bottom edge is near Y=2048.|
|11–24||Unknown. These might be (X, Y) pairs of coordinates, but I can’t figure out what they do.|
|25||1 enables color cycling using the palette in beach.pcx; 0 disables it. See Color palettes. If set to 0, the remaining three lines are not necessary.|
|26||Delay between changing to the next color in the color cycles associated with palette indices 148 and 161–164. In a_f3.pcx, these indices are used to show water washing up onto the shore.|
|27||Delay between the end of the color cycle and restarting it, for palette indices 148 and 161–164.|
|28||Delay between changing to the next color for palette indices 168–175. There is no delay when restarting these color cycles.|
Map surface – *.m
The *.m files store the road surface a 64x64 grid of tiles. These files contain a 64x64 byte array (4096 bytes exactly) with each tile representing an index into the tileset. The tilesets are 320x200 images in PCX Format, split into 32x32 tiles. There are only 54 tiles per image (so in the *.m files, byte values 0–53 refer to tiles 0–53 in the first tileset, and byte values 54–106 refer to tiles 0–53 in the second tileset.)
Wrong way info – *.pos
The same as the background layer (*.m) except that instead of one byte per tile (8-bit number) there are two bytes per tile (16-bit number). So effectively every tile position has a 16-bit number starting at 1 and increasing as you get closer to the end of the track. The ‘wrong way’ message only flashes on the screen when the player moves to a tile location with a smaller number. Since the files that ship with the game are fairly coarse in this regard (only using numbers 0–30, and fairly large blocks of the map sharing the same number), there is some delay between successive ‘wrong way’ messages when driving around the track at low speed in the wrong direction.
Road path – *.rd
The ‘road’ files control the paths the computer players drive. The file begins with a UINT16LE containing the number of objects in the file, followed by that many objects. Each object is in the following structure:
|UINT16LE||x1||X-coordinate of current position|
|UINT16LE||y1||Y-coordinate of current position|
|UINT16LE||x2||X-coordinate of next destination|
|UINT16LE||y2||Y-coordinate of next destination|
|UINT16LE||angle||The angle given by the two (x, y) pairs above in seemingly arbitrary units. See below.|
|UINT16LE||compass_direction||Direction to face. Range is 0x00–0x07. 0x00 = S, 0x01 = SW, 0x02 = W, up to 0x07 = SE.|
|UINT16LE||distance||Distance between the current and next points|
The computer players drive in a straight line from (x1, y1) to (x2, y2) and then immediately appear at the (x1, y1) point of the next struct in the file. Generally, the (x2, y2) position of one struct should have the same coordinates as the (x1, y1) position in the next struct. If they aren’t, the computer players will drive in a series of line segments and teleport from the end of one line segment to the start of the next.
The angle and distance fields are apparently not used, but their values can be calculated automatically using a tool such as Camoto.
Calculating the angle
For angles, north is taken to be at the top of the map. The +y direction points down, or to the south.
The angle field is in units of degrees times 16/3 and is always positive: it ranges from 0 ≤ angle < 1920 (in decimal). The angle is zero when driving in the +X direction (due east). The +Y direction (south) is 480, west is 960, north is 1440, etc.
This angle can be calculated from the X and Y positions as follows:
angle = atan2(y2−y1, x2−x1)/π*960; if (angle < 0) angle = angle + 1920;
Calculating the compass direction
The compass_direction field can be calculated from the angle. The conversion is
compass_direction = (angle/240.0 + 6.5) % 8
where you use floating point division and then truncate the result in parentheses to an integer.
Instead of calculating compass_direction, you can set the variable any way you like, so that the computer players drive backwards, skid in the turns, spin, etc. If you hit a driver facing you, it counts as a head on collision, even if you are both traveling the same direction.
Calculating the distance
The distance field can be calculated as:
sqrt((x2 − x1)² + (y2 − y1)²)
Note that decimals are truncated, not rounded (i.e. in C, the result is simply cast to an int.)
Tile properties – *.sin
The structs in *.sin are 12 bytes long and arranged like this:
|UINT16LE||prop0_active||boolean telling if prop0 should be considered|
|UINT16LE||prop1_active||boolean telling if prop1 should be considered|
|UINT32LE||prop0||properties for color 0 in f_ma#.pcx|
|UINT16LE||prop1||properties for color 1 in f_ma#.pcx|
I think the boolean values can always be set to 1; the property won’t be used unless it’s selected in the appropriate a_ma*.pcx file. The properties select what type of ground or water that tile will be. See gamedata.txt for a listing that looks promising.
Where objects are placed – *.spw
Bytes 0–1 are a UINT16LE giving how many 12-byte structs follow:
|UINT16LE||objectid||Index of the *.sp file to read for the graphics. See Sprites for more details.|
|UINT16LE||unknown1||Unknown; always zero|
|UINT16LE||unknown2||Unknown; always zero|
|INT16LE||unknown3||Unknown; always zero. Setting this number to something other than zero causes the game to cycle through many graphics. Setting it to a small negative number causes it to cycle a few times and then stop on its normal graphic.|
Other level-specific files
These files also contain data for track number n:
- n.par: Contains the graphics used on the horizon (buildings, etc.). See Horizon graphics – *.par.
- n.bmc: Controls the computer player when driving on track n during demo mode. Only used for tracks 1–5 and 7. See BMC Format.
- SHRINKn.PCX: Track preview map. It should be possible to generate these files from n.m and the tile sets specified in n.gam.
The files BRONZEM.SP, SILVERM.SP, GOLDM.SP and BONUS*.SP contain the 5-track course previews. See *.sp. It should be possible to generate these files from SHRINK*.SP.
See Wacky Wheels Tools for a listing of viewers and editors for data in this format.
This format was reverse engineered by Phil Carter and Klas Arvidsson. If you find this information helpful in a project you’re working on, please give credit where credit is due. (A link back to this wiki would be nice too!)