===============================================================================================
TOMB RAIDER LEVEL EDITING TEXTUREASSIGN PROGRAM:
  TEXTURE / SPRITE LIST FORMAT
Copylefted Bitshifter 2000/05/08
Modified: 2000/05/25
===============================================================================================
General characteristics:

Data structures follow that of TR3 and are directly usable in TR2 level files.
All structured TR data definitions are taken from the Rosetta but have been included
 here as references, with comments from yours truly.

File is binary (non-human readable) and
 chunky (does not have structured data in the C++ sense, has to be 
 walked to be read.)

Extension selected for that type of file is *.TRT .
The version to which it applies is the first long in the file and is either the version
 of the level being edited or in the case of a brand new list, from the choice of the maker.

When dealing with primitive versions like Demo TR2 and TR1, the structures will
 not change, so as to make writing porting application to upper version
 easier. Instead some data might be set to either zero values or
 some flag value (to be determined). What will be read and used will
 be determined by the version as noted in the list file. 

Note: TR1 is not presently supported.
	Only TR2 has been tested presently.
-------------------------------------------------------------------------
Complete File Structure
-------------------------------------------------------------------------

bitu32		Version		: identical to version value for all TR
				: level file  (4 bytes)
bitu16		Type		: flag value for Demo, CD version and Gold
				: where applicable. (2 byte)
				: There are no such index in level file,
				: it has to be figured out programmatically
				: by actually walking the level and detecting
				: the presence and type of data at certain
				: points.

bit16		numChar		: number of characters in the filename
				: (2 bytes). Number will be exact lenght
				: plus 2 bytes to get the "/0" at the end.
Chr[numChar]	texturefilename	: filename of corresponding 8bits texture
				: bitmap (numChar x 1 bytes) + 2 bytes.
				: ASCII values limited to 32-127 (20-7F).
				: Those last two bytes will be filed with
				: the zero terminated string end char. "/0"
				: I use Get/Put on file opened for Binary
				: so the buffer size has to be fixed in 
				: advance, hence this kludge.

bit16		numChar		: number of characters in the filename
				: (2 bytes). Number will be exact lenght
				: plus 2 bytes to get the "/0" at the end.
Chr[numChar]	levelfilename	: filename of corresponding level file
				: (numChar x 1 bytes) + 2 bytes.
				: ASCII values limited to 32-127 (20-7F).
				: Those last two bytes will be filed with
				: the zero terminated string end char. "/0"
				: In case of brand new texture list, may be
				: zero length.

bitu32		numObjText	: number of object textures to follow
				:(4 bytes)
tr2_object_texture[numObjText]	: object texture list (numObjText x 20 bytes)

bitu32		numAnimText	: number of animated texture records to
				: follow  (4 bytes)		
bitu16		AnimatedTextures[numAnimText]
				: animated texture data (numAnimText x 2 bytes)
				: There is no structure for AnimatedTextures
				: since it is only a list of offsets 
				: into the texture list itself.

bitu32		numSpriteTextures
				: number of sprites textures to follow
				: (4 bytes)
tr2_sprite_texture[numSpriteTextures] 
				: sprite texture list 
				: (numSpriteTextures x 16 bytes)

bitu32		numSpriteSequence
				: number of sprite sequence records
				: to follow (4 bytes)
tr2_sprite_sequence[numSpriteSequence] 
				: sprite sequence data 

===============================================================================================
TR DATA STRUCTURES

The following data structures are from the TextureAssign
 program, written in VisualBasic 6.0 and can be translated
 to C structure easily.
These are not C++ structures since they vary in size depending
 on the number of items in them.
A file using those types of structure is called a chunky file.

Structures that are needed later are defined first, 
 before those that include them.
---------------------------------------------------------
' 4 bytes
Public Type tr2_object_texture_vert
    Xcoordinate As Byte		'bitu8
    Xpixel As Byte		'bitu8
    Ycoordinate As Byte		'bitu8
    Ypixel As Byte		'bitu8
End Types
---------------------------------------------------------
' 20 bytes
Public Type tr2_object_texture
    Attribute As Integer	'bitu16
    TileIndex As Integer	'bitu16
    Vertices(1 To 4) As tr2_object_texture_vert
End Type
---------------------------------------------------------
There is no structure for Texture Animations.
Do not use an array to read and write this since an array
 has an item number at the beginning (which is already
 given previously) plus some program (like VB) round UP
 the array itself with zeros if the array does not ends
 up on a DWord boundary (is not evenly divisible by 4).
The data is written this way:
Bit32 numAnimText
Bit16	number of animations in this chunck
Bit16		number of offset of first animation
		(exact value -1)
Bit16			offset No 1
Bit16			offset no ....
Bit16		number of offset of second animation
		(exact value -1)
Bit16			offset No 1
Bit16			offset no ....
....an on...
---------------------------------------------------------
' 16 bytes
Public Type tr2_sprite_texture
    Tile As Integer             'bitu16
    X As Byte                   'bitu8
    Y As Byte                   'bitu8
    Width As Integer            'bitu16
    Height As Integer           'bitu16
    LeftSide As Integer         'bit16
    TopSide  As Integer         'bit16
    RightSide As Integer        'bit16
    BottomSide As Integer       'bit16
End Type
---------------------------------------------------------
' 8 bytes
Public Type tr2_sprite_sequence
    ObjectID As Long            'bit32
    NegativeLength As Integer   'bit16
    Offset As Integer           'bit16
End Type
=========================================================
ROSETTA REFERENCES
These, cited directly from the Rosetta, have been included
 to ease the work of any programmers. When in doubt, refer
 back to the original Rosetta.
---------------------------------------------------------
Version: 
Every level file (.PHD, .TUB, .TR2) begins with a bitu32
 version number.  This seems to be used by the engine to
 guarantee compatibility between various level editor versions
 and the game engine version.  More generally, it can be used
 to determine what sort of level is being read.
  Here are the known (observed) values for the version header: 

        0x00000020    Tomb Raider 1, Gold, Unfinished Business 
        0x0000002d    Tomb Raider 2 
        0xFF080038    Tomb Raider 3 
        0xFF180038    Tomb Raider 3 
---------------------------------------------------------
Palette: This consists of 256 tr2_colour structs, one for each
 palette entry. However, the individual colour values range
 from 0 to 63; they must be multiplied by 4 to get the
 correct values. 

This used for all 8-bit colour, such as 8-bit textures. 
---------------------------------------------------------
Object-texture vertex structure. It specifies a vertex
 location in textile coordinates. 
The Xpixel and Ypixel are the actual coordinates of the
 vertex's pixel. 
The Xcoordinate and Ycoordinate values depend on where the
 other vertices are in the object texture strip relative to
 one another.
If the object texture is used to specify a triangle,
 then the fourth vertex's values will all be zero. 

Comments:-------------------------
(1)Low means this value is nearest the upper left corner
 of the texture strip.
(255)High means it's the farthest from.
Textures are sometime "flipped", that is the Lo and Hi values
are not always in the default order (X1 Lo and X3 High).
This seems to have something to do with the way the texture
 is displayed on the polygon. In the level analysed, 
 only flipping around a vertical (called "Horizontal Flip",
 from the way I figured out the flip direction using a small
 cardboard model) axis has been seen.
But the TextureAssign can flip a texture around an horizontal
 axis (called "Vertical Flip"). A texure can be both flipped
 horizontally and vertically.
But it gets better with triangular textures.
More anon.
----------------------------------
 
typedef struct { 	// 4 bytes 
    bitu8 Xcoordinate; 	// 1 if Xpixel is the low value,
			 255 if Xpixel is the high value
				 in the object texture 
    bitu8 Xpixel; 
    bitu8 Ycoordinate; 	// 1 if Ypixel is the low value,
			 255 if Ypixel is the high value
			 in the object texture 
    bitu8 Ypixel; 
    } tr2_object_texture_vert; 
 
Object texture structure. 
These, the contents of ObjectTextures[], are used for
 specifying texture mapping for the world geometry and for mesh objects. 

typedef struct { // 20 bytes 
bitu16 Attribute;  // 0 means that a texture is all-opaque, and that transparency 
                                // information is ignored. 
                                // 1 means that transparency information is used. In 8-bit colour, 
                                // index 0 is the transparent colour, while in 16-bit colour, the 
                                // top bit (0x8000) is the alpha channel
				// (1 = opaque, 0 = transparent). 
                                // 2 (only in TR3) means that the opacity (alpha)
				// is equal to the intensity; 
                                // the brighter the colour, the more opaque it is.
				// The intensity is probably calculated 
                                // as the maximum of the individual color values. 
    bitu16 Tile; // index into textile list 
    tr2_object_texture_vert Vertices[4]; // the four corners of the texture 
    } tr2_object_texture; 


---------------------------------------------------------
Animated Textures: 

Animated textures describe sets of object textures that are
 cycled through to produce texture animations; they are a set
 of bit16's with the following format
 (not a "real" C/C++ structure): 

bit16 NumAnimatedTextures 
struct { 
    bit16 NumTextureIDs; // Actually, this is the number of texture ID's - 1. 
    bit16 TextureIDs[NumTextureIDs + 1]; // offsets into ObjectTextures[], in animation order. 
    } AnimatedTextures[NumAnimatedTextures]; 

If a texture belongs to an animated-texture group, it
 will automatically be animated by the engine.
 The animation framerate is most likely hardcoded.

---------------------------------------------------------
Sprites: 

These are "billboard" objects that are always rendered
 perpendicular to the view direction. These are used for
 text and explosion effects and similar things; they are
 also used for some scenery objects and pickup items, though
 this use gets less as one goes from TR1 to TR3. The various
 "Sides" below are the positions of the sprite sides relative
 to the sprite's overall position, measured in TR's
 world-coordinate units. 

typedef struct { // 16 bytes 
    bitu16 Tile; 
    bitu8 x; 
    bitu8 y; 
    bitu16 Width;        // actually (Width * 256) + 255 
    bitu16 Height;       // actually (Height * 256) + 255 
    bit16 LeftSide; 
    bit16 TopSide; 
    bit16 RightSide; 
    bit16 BottomSide; 
    } tr2_sprite_texture; 
  
---------------------------------------------------------  
Sprite Sequences: 
These are collections of sprites that are referred to as
 a group. The members of this group can be cycled through
 (animated sprites such as flames) or selected in other
 ways (text). Some sequences have only one member;
 this is done so as to access all the sprites in the same way. 

typedef struct { // 8 bytes 
    bit32 ObjectID; // Item identifier (matched in Items[]) 
    bit16 NegativeLength; // negative of "how many sprites are in this sequence" 
    bit16 Offset; // where (in sprite texture list) this sequence starts 
    } tr2_sprite_sequence; 
---------------------------------------------------------
Comments:-------------------------
This has been included as it is possible the light map has
 to be transfered with the texture information.
----------------------------------
LightMap: 
A 32*256 array of bitu8's which is apparently for applying
 light to 8-bit colour, in some documentation called
 "ColourMap". The current palette index and lighting value
 are used to calculate an index to this table, which is a
 table of palette indices. 

The Tomb Raider series' software rendering, like that of
 most real-time-3D games, uses 8-bit colour for speed and
 low bulk; however, there is the serious problem of how to
 do lighting with 8-bit colour, because doing it directly
 is computationally expensive. The usual solution is to
 arrange the palettes' colours in ramps, which the engine
 then follows in the appropriate directions. However, the TR
 series' palettes generally lack such neat ramps. 

But the TR series has a more general solution, one that does
 not require palettes to have colour ramps. It uses
 precalculated lighting tables, the "ColourMap" objects.
 These contain translations of a colour value and a lighting
 value, listed by palette index. The translation goes as
 follows: 

n = ColourMap[256 * k + i]; 

where i is the original palette index, k is determined from
 the lighting value, and n is the new palette index.
 The lighting index k varies from 0 to 31, and the corresponding
 lighting value is, for TR1, 

2 - k / 16 

and for TR2 and TR3, 

2 - (k + 1) / 16 

This may be associated with the curious fact of the lighting
 values in the data files increasing in the "wrong" direction
 in TR1 and TR2, with 0 being full brightness and greater values
 being darker. 
  

======================END OF FILE============================
 