Last updated: Thursday August 21, 1997
See the History section for info on what was added/changed/etc.

I have now started work on TrlEd, a level editor for Tomb Raider, so I probably won't update this page for awhile.

This page is dedicated to gathering as much information as possible about the Tomb Raider level (.phd) file format, and also creating a level editor for Tomb Raider. If you think you can help, let me know at splat@primenet.com.

The following are the things contained in the .phd file. This information was gathered from title.phd and level2.phd from the first Tomb Raider demo. Keep in mind any of this information could be wrong. The names of each section are (educated) guesses based on some strings found in the .exe (see the misc. section).

Table of contents:


1.0 Basic definitions, typedef's, etc.

Note: A vector defines a point in 3D space with x, y, and z coordinates. A vertex is usually a combination of a vector, a normal, light data, etc. Keep in mind some of the definitions might not be exactly right (I might call a normal a vertex, or whatever).
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned long u_long;

typedef struct
{
    short x;
    short y;
    short z;
} vector_t;

typedef struct
{
    short vertices[4]; //indexes to some vertices
    short texture; //object texture #
} face4_t; //rectangle

typedef struct
{
    short vertices[3]; //indexes to some vertices
    short texture; //object texture #
} face3_t; //triangle

//offset 0
long version; //version of the .phd file, must be 0x20 for tr1

2.0 Texture stuff

2.1 Texture tiles

Definiton: Texture tiles are 256*256 pixel tiles that contain textures (pictures rendered on surfaces like meshes, walls, sprites).
typedef struct
{
    u_char tile[256*256];
} textile_t;

//offset 0x4 - this is the same in all .phd files
long numtextiles;
textile_t textiles[numtextiles];
Textures seem to be referenced by a tile # and various x and y offsets inside that tile. Also, it seems that every surface doesn't require a texture, it can be a solid color, like the sunglasses and headphones. How this is done is unknown.


2.2 Object Textures

Definition: Object textures "select" a section of a texture tile. They do not contain actual graphical data.
typedef struct
{
    short something;    //don't mess with this something :)
    short tile;         //texture tile #
    u_char something;   //maybe blurring, like with sprites?
    u_char ulx;         //upper left corner x
    u_char something;
    u_char uly;         //upper left corner y
    u_char something;
    u_char urx;         //upper right corner x
    u_char something;
    u_char ury;         //upper right corner y
    u_char something;
    u_char lrx;         //lower right corner x
    u_char something;
    u_char lry;         //lower right corner y
    u_char something;
    u_char llx;         //lower left corner x
    u_char something;
    u_char lly;         //lower left corner y
} objtexture_t;

//offset 0x31fb8 in title.phd
long numobjtextures;
objtexture_t objtextures[numobjtextures];
Object textures are referenced by meshes and room textures. They "select" a section (texture) of a tile. The texture will be shrunk or stretched by the engine to fit the surface it is supposed to be rendered on. The section doesn't have to be rectangular, but it should be to be.


2.3 Sprite Textures

Definition: Sprite textures "select" a section of a texture tile, and also allow you to shrink/stretch/blur? that section. They do not contain actual graphical data.

Note: The sprite texture information is not entirely correct right now.

typedef struct
{
    short tile;         //texture tile #
    u_char ulx;         //upper left corner x
    u_char uly;         //upper left corner y
    u_char something;   //might have something to do with blurring the texture
    u_char lrx;         //lower right corner x
    u_char something;   //0 = blurry
    u_char lry;         //lower right corner y
    //the modify numbers stretch or shrink the texture by pixels from the
    //modify side, + = shrink, - = stretch
    short leftmodify;
    short topmodify;
    short rightmodify;
    short bottommodify;
} spritetexture_t;

//offset 0x321c4 in title.phd
long numspritetextures;
spritetexture_t spritetextures[numspritetextures];
The blurring is just a guess. The textures look blurred (bigger pixels) when these are changed (lower number = more blur), but it might be something totally different. The object textures might do the same kind of thing (not tested yet).


3.0 Room stuff

Definiton: Rooms are all of the physical structures in the level.

Note: Rooms are pretty complicated, but they are the most essential part needed to create levels for Tomb Raider, so they will be given top priority.

Note: Everything in this section relates to level2.phd from the first Tomb Raider demo. Since rooms are not totally understood, I will list file offsets to the things I have some idea about.

Note: If I refer to the "first room", I am talking about the room that you push the block through to get to the area with the gold and silver keys (it is the first room in level2.phd).

There seems to be 7 different data areas for each room (from the misc. section). I can identify 4 areas (sort of), and I will create separate sections for each one once they are more understood.

Here are the areas I have identified, the names may not be the same as used by Tomb Raider. Most of this is speculative, with little or no complete testing.

-room texture vertices
-faces (indices to vertices)
-visibility info?
-room walls (solid parts)


3.1 Room textures

Definiton: Room textures are used to define which textures are rendered at what position for a room. They do not contain actual graphical data. Room textures contain references to the Object textures, and not the texture tiles themselves.

typedef struct
{
    vector_t vector;
    u_char something;
    u_char colormap; //colormap # for this vertex
} rtvertex_t;

//offset 0xd0022 in level2.phd
short numroomtexturevertices;
roomtexurevertex_t roomtexturevertices[numroomtexturevertices];
short numrectangles;
face4_t rectangles[numrectangles];
short numtriangles; //this may be incorrect
face3_t triangles[numtriangles]; //this may be incorrect

4.0 Mesh and Bone stuff

4.1 Meshes

Definiton: The meshes are 3D objects that aren't physically part of the level like Lara, enemies, doors?, all of the spinning objects in title.phd, etc. The mesh vertices extend from the 0, 0, 0 point of the mesh.

Note: 3D objects are constructed using geometric primitives. Usually they are triangles, but the meshes seem to use rectangles. Keep in mind that they might use more than one primitive like the room textures do.

typedef struct
{
    long something;
    short something;
    long something;
    short numvertices;
    vector_t vertices[numvertices];
    short numsomethings;
    vector_t something[numsomethings]; //this has something to do with
                                       //lighting, may not be correct
    short numrectangles;
    face4_t rectangles[numrectangles];
} mesh_t;

//offset 0x301fc in title.phd
long meshdatasize;
u_char meshdata[meshdatasize*2];

meshdata contains mesh_t structures. See the mesh pointers
section for offsets to each mesh.

4.2 Mesh Pointers

Definition: Mesh pointers contain the offset of a mesh, with offset 0 being the first byte of the mesh data. Mesh pointers are referenced by the mesh infos.
//offset 0x3178c in title.phd
long nummeshpointers;
long meshpointers[nummeshpointers];

4.3 Mesh Infos

Definition: Mesh infos do something.

Note: This section is not entirely correct yet.
typedef struct
{
    long something;
    short nummeshes;
    short firstmesh; //first mesh number
    u_char something[10];
} meshinfo_t;

//offset 0x31f44 in title.phd
long nummeshinfos;
meshinfo_t meshinfos[nummeshinfos];

4.4 Bones

Note: This section is not entirely understood yet, so it might be wrong.

Definition: Bones define the way the meshes move. They give the meshes a wide range of motion (John Carmack even metioned something about implementing a skeletal (bone) structure for the models (meshes) in Trininty in a recent .plan update).

The bones seem to be VERY complicated, so it will probably be awhile before
they are understood (if ever).

5.0 Color palette stuff

5.1 Color Palette

Descripton: The color palette holds the RGB values for each color (Tomb Raider uses 256 colors).
typedef struct
{
    u_char red;
    u_char green;
    u_char blue;
} rgbtriple;

//offset 0x328b4 in title.phd
rgbtriple palette[256];

5.2 Colormaps

Definition: The colormaps are used to define the brightness level of each color (like in Doom). Each byte in a colormap represents the actual palette index for that color. For example, colormap[0] would contain the palette index for color 0.
typedef struct
{
    u_char colormap[256];
} colormap_t;

//offset 0x32c28 in title.phd
colormap_t colormaps[34]; //34 may not be actual number
Colormaps are referenced by rooms.


6.0 Sound stuff

Sounds are referenced by the sound infos, not the samples themselves. There seems to be some sound related data before 0x34e2c, unknown.

6.1 Samples

Definition: The samples are the sounds (.wav files).
//offset 0x34e70 in title.phd
long cbsampledata; //size of all the sound samples, in bytes
u_char sampledata[cbsampledata]; //sample data (.WAV files), sound offset 0 here

6.2 Sound infos

Definition: Sound infos contain information about each sound that is played in the game.
typedef struct
{
    short soundsample;  //number of sample to be played for this sound info
    short volume;       //maximum volume = 0x7fff (can't be negative)
    short something;    //these may be channel or priority related
    short something;
} soundinfo_t;

//offset 0x34e2c in title.phd
long numsoundinfos;
soundinfo_t soundinfos[numsoundinfos];

6.3 Sound directory

Definition: This section contains offsets to each sample, with offset 0 starting at sounddata.
//offset 0x4d2c6 in title.phd
long numsamples; //number of sound samples
long sampleoffsets[numsounds]; //offset to each sample

7.0 Misc.

Here are some things I found in the exe. As far as I know these strings are used by game_malloc() when it can't allocate enough memory for something.

Sprite Textures
Object Textures
Mesh Pointers
Meshes
Anims
Structs
Ranges
Commands
Bones
Frames
Room Textures
Room Infos
Room Mesh
Room Door
Room Floor
Room Lights
Room Static
Mesh Infos
Floor Data
ITEMS!!
Cameras
Boxes
Overlaps
GroundZone
FlyZone
Animating Texture Ranges
Cinematic Frames
LoadDemo Buffer
SaveDemo Buffer
Cinematic Effects
Mummy Head Turn
Extra Door stuff
Effects_Array
Creature Data
Creature LOT
Sample Infos
Samples
Sample Offsets
Rolling Ball Stuff

History

Thursday August 21, 1997: (new) Wednesday August 13, 1997: Sunday August 10, 1997: