The TD4 and save game files in RCT are compressed with a Run Length Encoding
technique. The uncompressed files have a fixed length and contain a lot of
"00" bytes. The author apparently choose this compression technique to deal
with those long runs of zeros. The useful data does not compress well with
this technique but it is quick and simple. The last four bytes of the files
contain a checksum. When you decode a file, omit these last four bytes. When
you encode a file, calculate the checksum and
add those four bytes onto the end of the file.
DECODING
START
1) read a byte (B) from the file
2) Test the most significant bit (MSB) of that byte
2a) if MSB=0 then B is a counter of how many bytes to copy. Execute the following
loop: for COUNTER = 1 to B+1 {read a byte from the file and copy it to your
target data stream.}
2b) however, if MSB=1 then B is flag to duplicate data. Read the next byte
and copy it (-B+1) times to your target data stream.
3) if end of file not reached (remember to omit the last four bytes as they
are a checksum) goto START
*******************************
For example, imagine a file containing the following data (no checksum)
00 47 FF 6F 05 64 20 6A 6F 62 21
The initial 00 indicates that the next 1 byte goes into your target stream:
"47"
The next byte is FF which indicates the next byte should be copied 2 times:
"6F 6F"
The next byte is 05 which indicates the next 6 bytes should go into the target:
"64 20 6A 6F 62 21"
This gives "47 6F 6F 64 20 6A 6F 62 21" which is the ASCII code for "Good
job!". This example shows how a compressed message of 11 bytes is decompressed
to a message of 9 bytes. As mentioned, this is not a good technique for general
compression but it works well for long runs of "00" bytes.
To compress a file, just reverse the process. You should limit the copies
to a maximum of 125 bytes as this is a size limit in the internal RCT program.
The following is a Delphi unit. It is called with a file name (including
path) and fills the previously created TMemoryStream object with the decoded
contents of that file. Although it uses TD4 in the variable names, it will
work with SV4 files as well.