Save file
There is one unfinished Okteta structure with some recognized values
Save file stores top scores, unlocked tracks/cars etc., sound volume (is setup.bin exists volumes from game.cfg
is not used), current language, camera settings, but it doesn't seem to store graphics quality
setup.bin is by default saved to save/card00, however when the game starts it checks for first cardXX folder with that file. IT may happen that there is no setup.bin file in card00 and one exists in card01. In this case game will use that file.
Time - time/60 = seconds.milliseconds; 2181/60 = 36.35
Names written in bold are described in detail below the main table
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | File size, 0x211C |
0x4 | 0x4 | Checksum |
0x8 | 0x16 | Cars, first one is unused to have same indexes in table and car ID |
0x1E | 0x2 | Zeroes, Last one could be used for next segments (track are 1-based, but arrays are 0-based, so this would be always zero) |
0x20 | 0x19 | Tracks, first one is unused to have same indexes in table and track ID |
0x39 | 0x3 | Zeroes |
0x3C | 0x16 | Cars???, seems unused, first one is unused to have same indexes in table and ??? ID |
0x52 | 0x2 | Zeroes |
0x54 | 0x19 | Tracks???, seems unused, first one is unused to have same indexes in table and ??? ID |
0x6D | 0x3 | Zeroes |
0x70 | 0x4 | Camera 1-4 (close/medium/chasing/auto) |
- | - | - |
0x78 | 0x4 | ??? (0/1) |
0x7C | 0x4 | Music volume |
0x80 | 0x4 | SFX volume |
0x84 | 0x4 | Graphics quality |
0x88 | 0x4 | x image offset, can be set to <-31, 31> in hidden menu but can be set to arbitrary value, unsigned |
0x8C | 0x4 | y image offset, can be set to <-31, 31> in hidden menu but can be set to arbitrary value, unsigned |
0x90 | 0x4 | Language id, in Polish version it's set to 1 |
- | - | - |
0xFA | 0x18 | Connections between tracks in Arcade mode, each is stored as byte (0/1), read from left to right, top to bottom on the map |
0x112 | 0x2 | Zeroes |
0x114 | 0x260 | Arcade mode, 19 records, first one is unused (18 tracks in arcade) |
0x374 | 0x320 | Arcade mode records, array with 100 elements |
0x694 | 0x888 | Time trial records, array of 26 elements (first and last one unused, first one is filled with default value, last one is zeroed) |
0xF1C | 0xB00 | Championship, array with 8 elements |
0x1A1C | 0x320 | looks like array of sorts, 25 elements of 0x20 bytes each, similar to Arcade |
0x1D3C | 0x20 | ???, probably should be empty |
0x1D5C | 0x50 | Championship money records, array with 10 elements |
0x1DAC | 0x50 | Championship score records, array with 10 elements |
0x1DFC | 0x320 | Stunts mode records, sorted array with 100 elements |
Checksum
Read whole file, set bytes 0x4-0x7 to 0 (whole checksum), then loop over all bytes hash = int(data[i]) + ( hash >> 0x1D | ((hash << 3) % 2^32))
Arcade mode (each element is 0x20 bytes long):
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | lap time, def 20 1C 00 00
|
0x4 | 0x4 | Player name, 3chars + \0, set to ...\x00 for empty scores
|
0x8 | 0x4 | total time, def A08C0000
|
0xC | 0x4 | Player name, 3chars + \0, set to ...\x00 for empty scores
|
0x10 | 0x4 | ???, def 0 |
0x14 | 0x4 | Player name, 3chars + \0, set to ...\x00 for empty scores
|
0x18 | 0x4 | Stunts score, def 0 |
0x1C | 0x4 | Player name, 3chars + \0, set to ...\x00 for empty scores
|
After first record there is empty one and after that second record. All of them are very close to records array, how it it inserted then?
Championship (each slot is 0x160 bytes long):
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | Indicate if save exists (0/1) |
0x4 | 0x4 | Player name, 3chars + \0 |
0x8 | 0x4 | Tour??? |
0xC | 0x4 | Money |
0x10 | 0x4 | Car id |
0x14 | 0x4 | ??? |
0x18 | 0x4 | ??? |
0x1C | 0x4 | ??? |
0x20 | 0xE0 | Car parts, array of 11 elements |
0x100 | 0x60 | Individual cars, array with 6 elements, 1st element is always player, unknown order of rest |
Car parts
Each is 0x10 bytes long, first and last part ids determine available parts: <first id, last id>
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | If the part was changed, set to 1 after each race, set to 0 when part was changed or with clean championship save |
0x4 | 0x4 | Current part id, 0 for unused |
0x8 | 0x4 | id of first part, 0 for unused |
0xc | 0x4 | id of last part, 0 for unused |
Order of parts in array:
No. | Name |
---|---|
0 | Unused |
1 | Unused |
2 | Unused |
3 | Shocks |
4 | Battery |
5 | Engine |
6 | Chassis |
7 | BMS |
8 | Brakes |
9 | Unused, might have been horns, set to (1, 0, 1, 5) |
10 | Gearbox |
11 | Boost |
12 | Tyres |
13 | Drive system |
Individual cars
Each element is 0x10 bytes long
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | Won races? |
0x4 | 0x4 | Score |
0x8 | 0x4 | Sponsor |
0xC | 0x4 | ??? Might be starting position |
0x1A1C stuff:
Element at last index is not used, races 1-20 are sorted from 20 to 1, so after 1st race there is one entry near end of the table (minus one unused entry)
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | lap time, def 20 1C 00 00
|
0x4 | 0x4 | Player name, 3chars + \0, set to ...\x00 for empty scores
|
0x8 | 0x4 | total time, def A08C0000
|
0xC | 0x4 | Player name, 3chars + \0, set to ...\x00 for empty scores
|
0x10 | 0x4 | ???, def 0 |
0x14 | 0x4 | Player name, 3chars + \0, set to ...\x00 for empty scores
|
0x18 | 0x4 | Stunts score, def 0 |
0x1C | 0x4 | Player name, 3chars + \0, set to ...\x00 for empty scores
|
Records:
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | Score, set to 0 for empty scores |
0x4 | 0x4 | Player name, 3chars + \0, set to ...\x00 for empty scores
|
Records for time trials
There are 26 elements, each one is 0x54 bytes long,
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | Unknown |
0x4 | 0x50 | Array of records, see singular record below |
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | Time, (saved as seconds/60) |
0x4 | 0x4 | Player name, 3chars + \0, set to ...\x00 for empty scores
|
Element 0 is unused and filled with default values (time 2 minutes, name...
), last one (element 25) is empty, all bytes are set to zero