Last Updated September 19, 2004
The visual items in Locomotion are presumed stored in the g1x.dat files in the data directory and as individual dat files in the objdata directory.
The Locomotion dat files are similar in many respects to the dat files of RCT2. The dat files begin with a sixteen byte "DAT File Header". The first four
bytes are flags. The next eight bytes are the ASCII characters of the file
name (padded with trailing spaces as needed). The next four bytes are a checksum.
The DAT File Header is followed by an encoded data chunk. It is the same
type of encoding as described on the SV6/SC6 page. (The first byte specifies
the type of encoding; the next four bytes are the size.) The remainder of
the description here is based on the decoded file. This is a "work in progress"!
I am using the following model for the Dat file structure:
DAT File Header |
Object Header |
String Table(s) |
Group Info |
Optional |
Image Directory |
Graphics Data |
Presumably, every object has a DAT File Header, Object Header (different for each object type) and a String Table.
DAT File Header: The high two bits of the first byte of the Flags is used to determine if this is a standard (original="10",) or (possibly) custom object (bits ="00"). The lower six bits of the first byte determine the "Type" of the object as described below. The remainder of Flags can be ignored.The last byte of Flags is 0x11 for original Locomotion files.
Flags : longword
filename : 8 bytes
checksum : longword
The Checksum is calculated by starting with the value 0xF369A75B. Read one byte at a time from the decoded file. Start with the first byte of the file, then skip the next three bytes. Then read the eight bytes of the Filename. Skip the four bytes of the checksum (you're calculating it now!). Then process each byte of the remainder of the (decoded) file.
Each byte is processed by XOR'ing it with the low byte of CheckSum. Then CheckSum is rotated left by eleven bits.
Object Type |
Description | Obj Header Size |
String Tables | Group(s) | "Optional" | Images | Example |
0x00 |
interface (button images) | 0x18 | 1 | No | No | Yes | INTERDEF.dat |
0x01 |
sounds | 0x0C | 1 | No | ? | No-has "sounds"? | SNDTR1.dat |
0x02 |
currency | 0x0C | 3 | No | No | Yes | CURRDOLL.dat |
0x03 |
exhaust/spark/steam | 0x28 | 1 | No | ? | ? | STEAM.dat |
0x04 |
rocks (vertical faces) | 0x06 | 1 | No | No | Yes | LSROCK.dat |
0x05 |
water | 0x0E | 1 | No | ? | ? | WATER1.dat |
0x06 |
grass/rock/sand | 0x1E | 1 | Yes | No | Yes | GRASS1.dat |
0x07 |
town names | 0x1A | 1 | No | ? | ? | ATOWNNAM.dat |
0x08 |
resources (eg grain, coal) | 0x1F | 4 | No | No | Yes | COAL.dat |
0x09 |
fence/wall | 0x0A | 1 | No | No | Yes | FENCE1.dat |
0x0A |
train signals | 0x1E | 2 | No | No | Yes | SIGS.dat |
0x0B |
level crossing signals | 0x12 | 1 | No | No | Yes | LCROSS1.dat |
0x0C |
street lights | 0x0C | 1 | No | No | Yes | SLIGHT1.dat |
0x0D |
tunnel | 0x06 | 1 | No | No | Yes | TUNNEL1.dat |
0x0E |
bridge | 0x2C | 1 | No | No | Yes | BRDGGIRD.dat |
0x0F |
train station | 0AE | 1 | No | Yes | Yes | TRSTAT1.dat |
0x10 |
track extras(3rd rail, electric) | 0x12 | 1 | No | No | Yes | TREX3RL.dat |
0x11 |
track (narrow/standard) | 0x36 | 1 | Yes | No | Yes | trackst.dat |
0x12 |
road station | 0x6E | 1 | Yes | Yes | Yes | RDSTAT1.dat |
0x13 |
road extras (overhead electric) | 0x12 | 1 | No | No | Yes | RDEXCAT1.dat |
0x14 |
road | 0x30 | 1 | Yes | No | Yes | ROADONE.dat |
0x15 |
airport | 0xBA | 1 | No | Yes | Yes | AIRPORT1.dat |
0x16 |
dock | 0x28 | 1 | No | Yes | Yes | SHIPST1.dat |
0x17 |
vehicles | 0x15E | 1 | Yes-after addtl data | No | Yes | BALDWIN1.dat |
0x18 |
trees | 0x4C | 1 | No | No | Yes | BEECH.dat |
0x19 |
snow | 0x06 | 1 | No | No | Yes | SNOW.dat |
0x1A |
climate | 0x0A | 1 | No | No | No | CLIM1.dat |
0x1B |
hill shapes | 0x0E | 1 | No | ? | ? | HS1.dat |
0x1C |
buildings | 0xBE | 1 | Yes-after addtl data | No | Yes | BLDALP1.dat |
0x1D |
scaffolding | 0x12 | 1 | No | No | Yes | SCAFDEF.dat |
0x1E |
industry(factory/farm, etc) | 0xF4 | 8 | Yes-after addtl data | ? | ? | FARM.dat |
0x1F |
region (US/UK/ALP) | 0x12 | 1 | Yes, and "0xFF" at end of group data | No | Yes | REGUS.dat |
0x20 |
competitors | 0x39 | 2 | No | No | Yes | COMP1.dat |
0x21 |
Scenario text | 0x06 | 2 | No | No | No | STEX000.dat |
Object Header: Following the DAT File Header is a "Object Header" which is a different structure (and size) for each object type. None of the Locomotion object headers have been determined yet.
String Table(s): Folowing the Object Header
is a string table containing text in different languages.Each string begins
with a byte to specify the language. The following table is the definitions used in RCT2
Code | Language | Used in Locomotion |
0 | British English | Yes |
1 | American English | Yes |
2 | French | Yes |
3 | German | Yes |
4 | Spanish | Yes |
5 | Italian | Yes |
6 | Dutch | No |
7 | Swedish | No |
9 | Korean? | Yes |
10 | Chinese | No |
11 | Chinese | Yes |
13 | Portugese | No |
The string immediately follows that byte and is null terminated. An 0xFF for the Language code indicates the end of the strings.
Group Info: a sixteen byte structure. There is a four byte value. This is followed by an eight byte string indicating which scenery group file this item belongs to (if any). That is followed by a 4-byte value. There are often several of these groups. Read the next long word in the file - if it is less than 0x22 then it is another group structure, otherwise, it is part of the image directory.
Flag : longword
FileName : 8 bytes
Checksum: longword = 0
Image directory: First is a 4-byte value which specifies how many images are in the file. Then a 4-byte value which specifies the length of the scan line graphic data (starting after the image directory). Then there is a sixteen byte entry for each image. It uses the same format as the csg1i.dat file of RCT1.
TGraphicRecord = record
StartAddress : longword;
Width, Height, Xoffset, Yoffset : smallint; // signed two byte variables
Flags : word;
unused : word // to pad the structure to 16 bytes
end;
StartAddress points to the start of the scan line index in the file. It is an offset rather than an absolute address - the first scan line index has a StartAddress of 00000000.