The Apogee Throwback Pack

The Apogee Throwback Pack

Not enough ratings
ROTT Map Specs - A detailed explanation of the map format for ROTT.
By jeffpiatt
This will give you all the
information you need to create level editors, graphic editors, or anything else
you want to for the ROTT file formats.
   
Award
Favorite
Favorited
Unfavorite
Rise of the Triad Version 1.1 Hacker Info
Welcome to the Rise of the Triad Hacker Help file. This will give you all the
information you need to create level editors, graphic editors, or anything else
you want to for the ROTT file formats.

We do respectfully request that you do not modify the levels for the shareware
version of Rise of the Triad. The authors worked hard on the game and if there
are lots of free levels available for the shareware version, a user will have
far less incentive to order the full game. So please respect our wishes, and
only create levels for the registered version. (And we took so much trouble to
put those handy Alternate Level selections in the Registered Setup, too!)

If you want to play user-created levels of ROTT, please buy the full version
of the game from us. This will ensure more quality products in the future and
more open support from Apogee Software.

Happy Hacking :)

NOTE: v1.2 will be the first shipping registered version. There are no public
released registered versions of v1.0 & v1.1.

RTL & RTC File format:
----------------------
Rise of the Triad (ROTT) uses two file extensions for levels data, RTL
and RTC. RTC indicates that the file is for Comm-bat (multiplayer) play
only and does not contain any enemies or exits. RTL indicates the file
can can be used for both Comm-bat and standard game levels. In Comm-bat,
the enemies in RTL maps in standard play are not present during Comm-bat
games and the exit and entrance arches behave like teleporters. Other than
these differences, the two files are alike.

The RTL/RTC file format changed with the release of ROTT version 1.1.
Since the shareware version of ROTT cannot use alternate levels, this
should not be a problem for map designers. The new format is much more
formal. If any changes are made in the format in the future, the first 8
bytes of the file will inform you if it is compatible with your editor/viewer.

The RTL/RTC file is broken into three sections: Version info, Header block,
and Data block.


RTL/RTC version info

This 8 byte block of data indicates what type of file it is and which
version of the RTL/RTC file format it is.

Offset Size Description
-------------------------------------------------------------
0 4 Format signature
4 4 Version number

Format signature :

This is used to indicate what type of levels are contained within the
file. This is a null-terminated string containing either "RTL" or "RTC".

Version number :

0101h for version 1.1. If this value is higher, it indicates that the file
format has changed. This is NOT the ROTT version.


RTL/RTC Header block

The header block contains an array of 100 structures with the following
format:

Offset Size Explanation
-------------------------------------------------------------
0 4 Used flag
4 4 CRC
8 4 RLEWtag
12 4 MapSpecials
12 4 Offset in file of Wall plane
16 4 Offset in file of Sprite plane
20 4 Offset in file of Info plane
24 4 Length of Wall plane
28 4 Length of Sprite plane
32 4 Length of Info plane
36 24 Name of level


Used flag :

This is non-zero if a map exists at this position.

CRC :

This value is used to determine if all the players in a multiplayer game
are using the same maps. You can use any method you like to calculate this
value.

RLEWtag :

This is the run-length encoding tag used for compressing and decompressing
the map data. The use of this will be described below.

MapSpecials :

This is used for flags that describe special conditions for the level.
Currently only one flag is used. If Bit 0 is set, then all the pushwalls
will be activated in Comm-bat mode. This is done in case there are player
start locations within hidden areas and the player would be trapped until
a pushwall was activated.

Offsets :

The Wall, Sprite, and Info plane offsets are each absolute offsets of the
data from the beginning of the file.

Lengths :

The Wall, Sprite, and Info plane lengths are each lengths of the
uncompressed data.

Name of level :

This is a null-terminated string containing the name of the level.
Although there is 24 bytes available, level names should be at most 22
bytes long.

RTL/RTC Data block

When expanded, ROTT maps contain 3 planes of 128 by 128 word sized data.
They are stored in the RTL/RTC files as 3 blocks of run-length encoded
data. The procedure for decompressing them is as follows:

1) Allocate 128 * 128 words of memory (32768 bytes)
2) Read one word from compressed block
3) If word is equal to RLEWTag, then the next two words are a compressed
run of data. The first word is the number of words to write.
The second word is the value to write map.
If word was not equal to RLEWTag, then simply write that word
to the map.
4) Go back to 2 until all data is written.

Here's an example of the procedure in C.


/*---------------------------------------------------------------------
Function: RLEW_Expand

Run-length encoded word decompression.
---------------------------------------------------------------------*/

void RLEW_Expand
(
unsigned short *source,
unsigned short *dest,
long length,
unsigned short rlewtag
)

{
unsigned short value;
unsigned short count;
unsigned short *end;

end = dest + length;

while( dest < end );
{
value = *source;
source++;

if ( value != rlewtag )
{
//
// uncompressed data
//
*dest = value;
dest++;
}
else
{
//
// compressed string
//
count = *source;
source++;

value = *source;
source++;

//
// expand the data
//
while( count > 0 )
{
*dest = value;
dest++;
count--;
}
}
}
}


Here is sample code for loading a ROTT map.


#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
#include <io.h>

/*---------------------------------------------------------------------
Map constants
---------------------------------------------------------------------*/

#define MAXLEVELNAMELENGTH 23
#define ALLOCATEDLEVELNAMELENGTH 24
#define NUMPLANES 3
#define NUMHEADEROFFSETS 100
#define MAPWIDTH 128
#define MAPHEIGHT 128
#define MAP_SPECIAL_TOGGLE_PUSHWALLS 0x0001

#define WALL_PLANE 0
#define SPRITE_PLANE 1
#define INFO_PLANE 2

/*---------------------------------------------------------------------
Type definitions
---------------------------------------------------------------------*/

typedef struct
{
unsigned long used;
unsigned long CRC;
unsigned long RLEWtag;
unsigned long MapSpecials;
unsigned long planestart[ NUMPLANES ];
unsigned long planelength[ NUMPLANES ];
char Name[ ALLOCATEDLEVELNAMELENGTH ];
} RTLMAP;


/*---------------------------------------------------------------------
Global variables
---------------------------------------------------------------------*/

unsigned short *mapplanes[ NUMPLANES ];


/*---------------------------------------------------------------------
Macros
---------------------------------------------------------------------*/

#define MAPSPOT( x, y, plane ) \
( mapplanes[ plane ][ MAPWIDTH * ( y ) + ( x ) ] )

#define WALL_AT( x, y ) ( MAPSPOT( ( x ), ( y ), WALL_PLANE ) )
#define SPRITE_AT( x, y ) ( MAPSPOT( ( x ), ( y ), SPRITE_PLANE ) )
#define INFO_AT( x, y ) ( MAPSPOT( ( x ), ( y ), INFO_PLANE