This version (2021/04/29 21:54) was approved by zdimension.The Previously approved version (2019/08/30 06:41) is available.Diff

Entire Level File Formats

TR1 Level Format

What follows is the physical .PHD and .TUB file layout, byte for byte.

This is not a “real” C/C++ structure, in that some arrays are variable-length, with the length being defined by another element of the structure.
uint32_t Version; // version (4 bytes)
uint32_t NumImages; // number of texture images (4 bytes)
tr_image8 Images8[NumImages]; // 8-bit (palettized) images (NumImages * 65536 bytes)
uint32_t Unused; // supposed to be the level number but TOM2PC didn't allow changing it, always 0 (4 bytes)
uint16_t NumRooms; // number of rooms (2 bytes)
tr_room Rooms[NumRooms]; // room list (variable length)
uint32_t NumFloorData; // number of floor data uint16_t's to follow (4 bytes)
uint16_t FloorData[NumFloorData]; // floor data (NumFloorData * 2 bytes)
uint32_t NumMeshData; // number of uint16_t's of mesh data to follow (=Meshes[]) (4 bytes)
tr_mesh Meshes[NumMeshPointers]; // note that NumMeshPointers comes AFTER Meshes[]
uint32_t NumMeshPointers; // number of mesh pointers to follow (4 bytes)
uint32_t MeshPointers[NumMeshPointers]; // mesh pointer list (NumMeshPointers * 4 bytes)
uint32_t NumAnimations; // number of animations to follow (4 bytes)
tr_animation Animations[NumAnimations]; // animation list (NumAnimations * 32 bytes)
uint32_t NumStateChanges; // number of state changes to follow (4 bytes)
tr_state_change StateChanges[NumStateChanges]; // state-change list (NumStructures * 6 bytes)
uint32_t NumAnimDispatches; // number of animation dispatches to follow (4 bytes)
tr_anim_dispatch AnimDispatches[NumAnimDispatches]; // animation-dispatch list list (NumAnimDispatches * 8 bytes)
uint32_t NumAnimCommands; // number of animation commands to follow (4 bytes)
tr_anim_command AnimCommands[NumAnimCommands]; // animation-command list (NumAnimCommands * 2 bytes)
uint32_t NumMeshTrees; // number of MeshTrees to follow (4 bytes)
tr_meshtree_node MeshTrees[NumMeshTrees]; // MeshTree list (NumMeshTrees * 4 bytes)
uint32_t NumFrames; // number of words of frame data to follow (4 bytes)
uint16_t Frames[NumFrames]; // frame data (NumFrames * 2 bytes)
uint32_t NumModels; // number of models to follow (4 bytes)
tr_model Models[NumModels]; // model list (NumModels * 18 bytes)
uint32_t NumStaticMeshes; // number of StaticMesh data records to follow (4 bytes)
tr_staticmesh StaticMeshes[NumStaticMeshes]; // StaticMesh data (NumStaticMesh * 32 bytes)
uint32_t NumObjectTextures; // number of object textures to follow (4 bytes) (after AnimatedTextures in TR3)
tr_object_texture ObjectTextures[NumObjectTextures]; // object texture list (NumObjectTextures * 20 bytes) (after AnimatedTextures in TR3)
uint32_t NumSpriteTextures; // number of sprite textures to follow (4 bytes)
tr_sprite_texture SpriteTextures[NumSpriteTextures]; // sprite texture list (NumSpriteTextures * 16 bytes)
uint32_t NumSpriteSequences; // number of sprite sequences records to follow (4 bytes)
tr_sprite_sequence SpriteSequences[NumSpriteSequences]; // sprite sequence data (NumSpriteSequences * 8 bytes)
uint32_t NumCameras; // number of camera data records to follow (4 bytes)
tr_camera Cameras[NumCameras]; // camera data (NumCameras * 16 bytes)
uint32_t NumSoundSources; // number of sound source data records to follow (4 bytes)
tr_sound_source SoundSources[NumSoundSources]; // sound source data (NumSoundSources * 16 bytes)
uint32_t NumBoxes; // number of box data records to follow (4 bytes)
tr_box Boxes[NumBoxes]; // box data (NumBoxes * 20 bytes [TR1 version])
uint32_t NumOverlaps; // number of overlap records to follow (4 bytes)
uint16_t Overlaps[NumOverlaps]; // overlap data (NumOverlaps * 2 bytes)
uint16_t GroundZone[2*NumBoxes]; // ground zone data
uint16_t GroundZone2[2*NumBoxes]; // ground zone 2 data
uint16_t FlyZone[2*NumBoxes]; // fly zone data
uint16_t GroundZoneAlt[2*NumBoxes]; // ground zone data (alternate rooms?)
uint16_t GroundZoneAlt2[2*NumBoxes]; // ground zone 2 data (alternate rooms?)
uint16_t FlyZoneAlt[2*NumBoxes]; // fly zone data (alternate rooms?)
uint32_t NumAnimatedTextures; // number of animated texture records to follow (4 bytes)
uint16_t AnimatedTextures[NumAnimatedTextures]; // animated texture data (NumAnimatedTextures * 2 bytes)
uint32_t NumEntities; // number of entities to follow (4 bytes)
tr_entity Entities[NumEntities]; // entity list (NumEntities * 22 bytes [TR1 version])
uint8_t LightMap[32 * 256]; // light map (8192 bytes)
tr_colour Palette[256]; // 8-bit palette (768 bytes)
uint16_t NumCinematicFrames; // number of cinematic frame records to follow (2 bytes)
tr_cinematic_frame CinematicFrames[NumCinematicFrames]; // (NumCinematicFrames * 16 bytes)
uint16_t NumDemoData; // number of demo data records to follow (2 bytes)
uint8_t DemoData[NumDemoData]; // demo data (NumDemoData bytes)
int16_t SoundMap[256]; // sound map (512 bytes)
uint32_t NumSoundDetails; // number of sound-detail records to follow (4 bytes)
tr_sound_details SoundDetails[NumSoundDetails]; // sound-detail list (NumSoundDetails * 8 bytes)
uint32_t NumSamples; // number of uint8_t's in Samples (4 bytes)
uint8_t Samples[NumSamples]; // array of uint8_t's -- embedded sound samples in Microsoft WAVE format (NumSamples bytes)
uint32_t NumSampleIndices; // number of sample indices to follow (4 bytes)
uint32_t SampleIndices[NumSampleIndices]; // sample indices (NumSampleIndices * 4 bytes)

TR2 Level Format

What follows is the physical .TR2 file layout, byte for byte.

This is not a “real” C/C++ structure, in that some arrays are variable-length, with the length being defined by another element of the structure.
uint32_t Version; // version (4 bytes)
tr_colour Palette[256]; // 8-bit palette (768 bytes)
tr_colour4 Palette16[256]; //  (1024 bytes)
uint32_t NumImages; // number of texture images (4 bytes)
tr_teximage8 Images8[NumImages]; // 8-bit (palettized) images (NumImages * 65536 bytes)
tr_teximage16 Images16[NumImages]; // 16-bit (ARGB) images (NumImages * 131072 bytes)
uint32_t Unused; // supposed to be the level number but TOM2PC didn't allow changing it, always 0 (4 bytes)
uint16_t NumRooms; // number of rooms (2 bytes)
tr2_room Rooms[NumRooms]; // room list (variable length)
uint32_t NumFloorData; // number of floor data uint16_t's to follow (4 bytes)
uint16_t FloorData[NumFloorData]; // floor data (NumFloorData * 2 bytes)
uint32_t NumMeshData; // number of uint16_t's of mesh data to follow (=Meshes[]) (4 bytes)
tr_mesh Meshes[NumMeshPointers]; // note that NumMeshPointers comes AFTER Meshes[]
uint32_t NumMeshPointers; // number of mesh pointers to follow (4 bytes)
uint32_t MeshPointers[NumMeshPointers]; // mesh pointer list (NumMeshPointers * 4 bytes)
uint32_t NumAnimations; // number of animations to follow (4 bytes)
tr_animation Animations[NumAnimations]; // animation list (NumAnimations * 32 bytes)
uint32_t NumStateChanges; // number of state changes to follow (4 bytes)
tr_state_change StateChanges[NumStateChanges]; // state-change list (NumStructures * 6 bytes)
uint32_t NumAnimDispatches; // number of animation dispatches to follow (4 bytes)
tr_anim_dispatch AnimDispatches[NumAnimDispatches]; // animation-dispatch list list (NumAnimDispatches * 8 bytes)
uint32_t NumAnimCommands; // number of animation commands to follow (4 bytes)
tr_anim_command AnimCommands[NumAnimCommands]; // animation-command list (NumAnimCommands * 2 bytes)
uint32_t NumMeshTrees; // number of MeshTrees to follow (4 bytes)
tr_meshtree_node MeshTrees[NumMeshTrees]; // MeshTree list (NumMeshTrees * 4 bytes)
uint32_t NumFrames; // number of words of frame data to follow (4 bytes)
uint16_t Frames[NumFrames]; // frame data (NumFrames * 2 bytes)
uint32_t NumModels; // number of models to follow (4 bytes)
tr_model Models[NumModels]; // model list (NumModels * 18 bytes)
uint32_t NumStaticMeshes; // number of StaticMesh data records to follow (4 bytes)
tr_staticmesh StaticMeshes[NumStaticMeshes]; // StaticMesh data (NumStaticMesh * 32 bytes)
uint32_t NumObjectTextures; // number of object textures to follow (4 bytes)
tr_object_texture ObjectTextures[NumObjectTextures]; // object texture list (NumObjectTextures * 20 bytes) (after AnimatedTextures in TR3)
uint32_t NumSpriteTextures; // number of sprite textures to follow (4 bytes)
tr_sprite_texture SpriteTextures[NumSpriteTextures]; // sprite texture list (NumSpriteTextures * 16 bytes)
uint32_t NumSpriteSequences; // number of sprite sequences records to follow (4 bytes)
tr_sprite_sequence SpriteSequences[NumSpriteSequences]; // sprite sequence data (NumSpriteSequences * 8 bytes)
uint32_t NumCameras; // number of camera data records to follow (4 bytes)
tr_camera Cameras[NumCameras]; // camera data (NumCameras * 16 bytes)
uint32_t NumSoundSources; // number of sound source data records to follow (4 bytes)
tr_sound_source SoundSources[NumSoundSources]; // sound source data (NumSoundSources * 16 bytes)
uint32_t NumBoxes; // number of box data records to follow (4 bytes)
tr2_box Boxes[NumBoxes]; // box data (NumBoxes * 8 bytes)
uint32_t NumOverlaps; // number of overlap records to follow (4 bytes)
uint16_t Overlaps[NumOverlaps]; // overlap data (NumOverlaps * 2 bytes)
int16_t Zones[10*NumBoxes]; // zone data (NumBoxes * 20 bytes)
uint32_t NumAnimatedTextures; // number of animated texture records to follow (4 bytes)
uint16_t AnimatedTextures[NumAnimatedTextures]; // animated texture data (NumAnimatedTextures * 2 bytes)
uint32_t NumEntities; // number of entities to follow (4 bytes)
tr2_entity Entities[NumEntities]; // entity list (NumEntities * 24 bytes)
uint8_t LightMap[32 * 256]; // light map (8192 bytes)
uint16_t NumCinematicFrames; // number of cinematic frame records to follow (2 bytes)
tr_cinematic_frame CinematicFrames[NumCinematicFrames]; // (NumCinematicFrames * 16 bytes)
uint16_t NumDemoData; // number of demo data records to follow (2 bytes)
uint8_t DemoData[NumDemoData]; // demo data (NumDemoData bytes)
int16_t SoundMap[370]; // sound map (740 bytes)
uint32_t NumSoundDetails; // number of sound-detail records to follow (4 bytes)
tr_sound_details SoundDetails[NumSoundDetails]; // sound-detail list (NumSoundDetails * 8 bytes)
uint32_t NumSampleIndices; // number of sample indices to follow (4 bytes)
uint32_t SampleIndices[NumSampleIndices]; // sample indices (NumSampleIndices * 4 bytes)

TR3 Level Format

What follows is the physical Tomb Raider III .TR2 file layout, byte for byte.

This is not a “real” C/C++ structure, in that some arrays are variable-length, with the length being defined by another element of the structure.
uint32_t Version; // version (4 bytes)
tr_colour Palette[256]; // 8-bit palette (768 bytes)
tr_colour4 Palette16[256]; //  (1024 bytes)
uint32_t NumImages; // number of texture images (4 bytes)
tr_image8 Images8[NumImages]; // 8-bit (palettized) images (NumImages * 65536 bytes)
tr_image16 Images16[NumImages]; // 16-bit (ARGB) images (NumImages * 131072 bytes) (absent from TR1)
// "VICT.TR2" stops here, nothing after
uint32_t Unused; // supposed to be the level number but TOM2PC didn't allow changing it, always 0 (4 bytes)
uint16_t NumRooms; // number of rooms (2 bytes)
tr3_room Rooms[NumRooms]; // room list (variable length)
uint32_t NumFloorData; // number of floor data uint16_t's to follow (4 bytes)
uint16_t FloorData[NumFloorData]; // floor data (NumFloorData * 2 bytes)
uint32_t NumMeshData; // number of uint16_t's of mesh data to follow (=Meshes[]) (4 bytes)
tr_mesh Meshes[NumMeshPointers]; // note that NumMeshPointers comes AFTER Meshes[]
uint32_t NumMeshPointers; // number of mesh pointers to follow (4 bytes)
uint32_t MeshPointers[NumMeshPointers]; // mesh pointer list (NumMeshPointers * 4 bytes)
uint32_t NumAnimations; // number of animations to follow (4 bytes)
tr_animation Animations[NumAnimations]; // animation list (NumAnimations * 32 bytes)
uint32_t NumStateChanges; // number of state changes to follow (4 bytes)
tr_state_change StateChanges[NumStateChanges]; // state-change list (NumStructures * 6 bytes)
uint32_t NumAnimDispatches; // number of animation dispatches to follow (4 bytes)
tr_anim_dispatch AnimDispatches[NumAnimDispatches]; // animation-dispatch list list (NumAnimDispatches * 8 bytes)
uint32_t NumAnimCommands; // number of animation commands to follow (4 bytes)
tr_anim_command AnimCommands[NumAnimCommands]; // animation-command list (NumAnimCommands * 2 bytes)
uint32_t NumMeshTrees; // number of MeshTrees to follow (4 bytes)
tr_meshtree_node MeshTrees[NumMeshTrees]; // MeshTree list (NumMeshTrees * 4 bytes)
uint32_t NumFrames; // number of words of frame data to follow (4 bytes)
uint16_t Frames[NumFrames]; // frame data (NumFrames * 2 bytes)
uint32_t NumModels; // number of models to follow (4 bytes)
tr_model Models[NumModels]; // model list (NumModels * 18 bytes)
uint32_t NumStaticMeshes; // number of StaticMesh data records to follow (4 bytes)
tr_staticmesh StaticMeshes[NumStaticMeshes]; // StaticMesh data (NumStaticMesh * 32 bytes)
uint32_t NumSpriteTextures; // number of sprite textures to follow (4 bytes)
tr_sprite_texture SpriteTextures[NumSpriteTextures]; // sprite texture list (NumSpriteTextures * 16 bytes)
uint32_t NumSpriteSequences; // number of sprite sequences records to follow (4 bytes)
tr_sprite_sequence SpriteSequences[NumSpriteSequences]; // sprite sequence data (NumSpriteSequences * 8 bytes)
uint32_t NumCameras; // number of camera data records to follow (4 bytes)
tr_camera Cameras[NumCameras]; // camera data (NumCameras * 16 bytes)
uint32_t NumSoundSources; // number of sound source data records to follow (4 bytes)
tr_sound_source SoundSources[NumSoundSources]; // sound source data (NumSoundSources * 16 bytes)
uint32_t NumBoxes; // number of box data records to follow (4 bytes)
tr2_box Boxes[NumBoxes]; // box data (NumBoxes * 8 bytes)
uint32_t NumOverlaps; // number of overlap records to follow (4 bytes)
uint16_t Overlaps[NumOverlaps]; // overlap data (NumOverlaps * 2 bytes)
int16_t Zones[10*NumBoxes]; // zone data (NumBoxes * 20 bytes)
uint32_t NumAnimatedTextures; // number of animated texture records to follow (4 bytes)
uint16_t AnimatedTextures[NumAnimatedTextures]; // animated texture data (NumAnimatedTextures * 2 bytes)
uint32_t NumObjectTextures; // number of object textures to follow (4 bytes) (after AnimatedTextures in TR3)
tr_object_texture ObjectTextures[NumObjectTextures]; // object texture list (NumObjectTextures * 20 bytes)
uint32_t NumEntities; // number of entities to follow (4 bytes)
tr2_entity Entities[NumEntities]; // entity list (NumEntities * 24 bytes)
uint8_t LightMap[32 * 256]; // light map (8192 bytes)
uint16_t NumCinematicFrames; // number of cinematic frame records to follow (2 bytes)
tr_cinematic_frame CinematicFrames[NumCinematicFrames]; // (NumCinematicFrames * 16 bytes)
uint16_t NumDemoData; // number of demo data records to follow (2 bytes)
uint8_t DemoData[NumDemoData]; // demo data (NumDemoData bytes)
int16_t SoundMap[370]; // sound map (740 bytes)
uint32_t NumSoundDetails; // number of sound-detail records to follow (4 bytes)
tr3_sound_details SoundDetails[NumSoundDetails]; // sound-detail list (NumSoundDetails * 8 bytes)
uint32_t NumSampleIndices; // number of sample indices to follow (4 bytes)  +
uint32_t SampleIndices[NumSampleIndices]; // sample indices (NumSampleIndices * 4 bytes)

TR4 Level Format

What follows is the physical Tomb Raider IV .TR4 file layout, byte for byte.

This is not a “real” C/C++ structure, in that some arrays are variable-length, with the length being defined by another element of the structure.
uint32_t Version; // version (4 bytes)
uint16_t NumRoomImages; // number of non.bumpmapped room images (2 bytes)
uint16_t NumObjImages; // number of object images (2 bytes)
uint16_t NumBumpmaps; // number of bump-mapped room images (2 bytes)
uint32_t Image32_UncompSize; // uncompressed size (in bytes) of the 32-bit textures chunk (4 bytes)
uint32_t Image32_CompSize; // compressed size (in bytes) of the 32-bit textures chunk (4 bytes)
uint8_t Image32_Compressed[Image32_CompSize]; // zlib-compressed 32-bit textures chunk (Image32_CompSize bytes)
{
    tr4_image32 Image32[NumRoomImages + NumObjImages + NumBumpmaps];
}
uint32_t Image16_UncompSize; // uncompressed size (in bytes) of the 16-bit textures chunk (4 bytes)
uint32_t Image16_CompSize; // compressed size (in bytes) of the 16-bit textures chunk (4 bytes)
uint8_t Image16_Compressed[Image32_CompSize]; // zlib-compressed 16-bit textures chunk (Image16_CompSize bytes)
{
    tr_image16 Image16[NumRoomImages + NumObjImages + NumBumpmaps];
}
uint32_t Image32Misc_UncompSize; // uncompressed size (in bytes) of the 32-bit misc textures chunk (4 bytes), should always be 524288
uint32_t Image32Misc_CompSize; // compressed size (in bytes) of the 32-bit misc textures chunk (4 bytes)
uint8_t Image32Misc_Compressed[Image32Misc_CompSize]; // zlib-compressed 32-bit misc textures chunk (Image32Misc_CompSize bytes)
{
    tr4_image32 Image32Misc[2];
}
uint32_t LevelData_UncompSize; // uncompressed size (in bytes) of the level data chunk (4 bytes)
uint32_t LevelData_CompSize; // compressed size (in bytes) of the level data chunk (4 bytes)
uint8_t LevelData_Compressed[LevelData_CompSize]; // zlib-compressed level data chunk (LevelData_CompSize bytes)
{
    uint32_t Unused; // supposed to be the level number but TOM2PC didn't allow changing it, always 0 (4 bytes)
    uint16_t NumRooms; // number of rooms (2 bytes)
    tr4_room Rooms[NumRooms]; // room list (variable length)
    uint32_t NumFloorData; // number of floor data uint16_t's to follow (4 bytes)
    uint16_t FloorData[NumFloorData]; // floor data (NumFloorData * 2 bytes)
    uint32_t NumMeshData; // number of uint16_t's of mesh data to follow (=Meshes[]) (4 bytes)
    tr4_mesh Meshes[NumMeshPointers]; // note that NumMeshPointers comes AFTER Meshes[]
    uint32_t NumMeshPointers; // number of mesh pointers to follow (4 bytes)
    uint32_t MeshPointers[NumMeshPointers]; // mesh pointer list (NumMeshPointers * 4 bytes)
    uint32_t NumAnimations; // number of animations to follow (4 bytes)
    tr4_animation Animations[NumAnimations]; // animation list (NumAnimations * 40 bytes)
    uint32_t NumStateChanges; // number of state changes to follow (4 bytes)
    tr_state_change StateChanges[NumStateChanges]; // state-change list (NumStructures * 6 bytes)
    uint32_t NumAnimDispatches; // number of animation dispatches to follow (4 bytes)
    tr_anim_dispatch AnimDispatches[NumAnimDispatches]; // animation-dispatch list list (NumAnimDispatches * 8 bytes)
    uint32_t NumAnimCommands; // number of animation commands to follow (4 bytes)
    tr_anim_command AnimCommands[NumAnimCommands]; // animation-command list (NumAnimCommands * 2 bytes)
    uint32_t NumMeshTrees; // number of MeshTrees to follow (4 bytes)
    tr_meshtree_node MeshTrees[NumMeshTrees]; // MeshTree list (NumMeshTrees * 4 bytes)
    uint32_t NumFrames; // number of words of frame data to follow (4 bytes)
    uint16_t Frames[NumFrames]; // frame data (NumFrames * 2 bytes)
    uint32_t NumModels; // number of models to follow (4 bytes)
    tr_model Models[NumModels]; // model list (NumModels * 18 bytes)
    uint32_t NumStaticMeshes; // number of StaticMesh data records to follow (4 bytes)
    tr_staticmesh StaticMeshes[NumStaticMeshes]; // StaticMesh data (NumStaticMesh * 32 bytes)
    uint8_t SPR[3]; // S P R (0x53, 0x50, 0x52)
    uint32_t NumSpriteTextures; // number of sprite textures to follow (4 bytes)
    tr_sprite_texture SpriteTextures[NumSpriteTextures]; // sprite texture list (NumSpriteTextures * 16 bytes)
    uint32_t NumSpriteSequences; // number of sprite sequences records to follow (4 bytes)
    tr_sprite_sequence SpriteSequences[NumSpriteSequences]; // sprite sequence data (NumSpriteSequences * 8 bytes)
    uint32_t NumCameras; // number of camera data records to follow (4 bytes)
    tr_camera Cameras[NumCameras]; // camera data (NumCameras * 16 bytes)
    uint32_t NumFlybyCameras; // number of flyby camera data records to follow (4 bytes)
    tr4_flyby_camera FlybyCameras[NumFlybyCameras]; // flyby camera data (NumFlybyCameras * 40 bytes)
    uint32_t NumSoundSources; // number of sound source data records to follow (4 bytes)
    tr_sound_source SoundSources[NumSoundSources]; // sound source data (NumSoundSources * 16 bytes)
    uint32_t NumBoxes; // number of box data records to follow (4 bytes)
    tr2_box Boxes[NumBoxes]; // box data (NumBoxes * 8 bytes)
    uint32_t NumOverlaps; // number of overlap records to follow (4 bytes)
    uint16_t Overlaps[NumOverlaps]; // overlap data (NumOverlaps * 2 bytes)
    int16_t Zones[10*NumBoxes]; // zone data (NumBoxes * 20 bytes)
    uint32_t NumAnimatedTextures; // number of animated texture records to follow (4 bytes)
    uint16_t AnimatedTextures[NumAnimatedTextures]; // animated texture data (NumAnimatedTextures * 2 bytes)
    uint8_t AnimatedTexturesUVCount;
    uint8_t TEX[3]; // T E X (0x54, 0x45, 0x58)
    uint32_t NumObjectTextures; // number of object textures to follow (4 bytes) (after AnimatedTextures in TR3)
    tr4_object_texture ObjectTextures[NumObjectTextures]; // object texture list (NumObjectTextures * 38 bytes)
    uint32_t NumEntities; // number of entities to follow (4 bytes)
    tr4_entity Entities[NumEntities]; // entity list (NumEntities * 24 bytes)
    uint32_t NumAIObjects; // number of AI objects to follow (4 bytes)
    tr4_ai_object AIObjects[NumAIObjects]; // AI objects list (NumAIObjects * 24 bytes)
    uint16_t NumDemoData; // number of demo data records to follow (2 bytes)
    uint8_t DemoData[NumDemoData]; // demo data (NumDemoData bytes)
    int16_t SoundMap[370]; // sound map (740 bytes)
    uint32_t NumSoundDetails; // number of sound-detail records to follow (4 bytes)
    tr3_sound_details SoundDetails[NumSoundDetails]; // sound-detail list (NumSoundDetails * 8 bytes)
    uint32_t NumSampleIndices; // number of sample indices to follow (4 bytes)  +
    uint32_t SampleIndices[NumSampleIndices]; // sample indices (NumSampleIndices * 4 bytes)
    uint8_t Separator[6]; // 6 0x00 bytes
}
uint32_t NumSamples; // number of sound samples (4 bytes)
tr4_sample Samples[NumSamples]; // sound samples (this is the last part, so you can simply read until EOF)

TR5 Level Format

What follows is the physical Tomb Raider V .TRC file layout, byte for byte.

This is not a “real” C/C++ structure, in that some arrays are variable-length, with the length being defined by another element of the structure.
uint32_t Version; // version (4 bytes)
uint16_t NumRoomImages; // number of non-bumpmapped room images (2 bytes)
uint16_t NumObjImages; // number of object images (2 bytes)
uint16_t NumBumpmaps; // number of bumpmaps (2 bytes)
uint32_t Image32_UncompSize; // uncompressed size (in bytes) of the 32-bit textures chunk (4 bytes)
uint32_t Image32_CompSize; // compressed size (in bytes) of the 32-bit textures chunk (4 bytes)
uint8_t Image32_Compressed[Image32_CompSize]; // zlib-compressed 32-bit textures chunk (Image32_CompSize bytes)
{
    tr4_image32 Image32[NumRoomImages + NumObjImages + NumBumpmaps];
}
uint32_t Image16_UncompSize; // uncompressed size (in bytes) of the 16-bit textures chunk (4 bytes)
uint32_t Image16_CompSize; // compressed size (in bytes) of the 16-bit textures chunk (4 bytes)
uint8_t Image16_Compressed[Image32_CompSize]; // zlib-compressed 16-bit textures chunk (Image16_CompSize bytes)
{
    tr_image16 Image16[NumRoomImages + NumObjImages + NumBumpmaps];
}
uint32_t Image32Misc_UncompSize; // uncompressed size (in bytes) of the 32-bit misc textures chunk (4 bytes), should always be 786432
uint32_t Image32Misc_CompSize; // compressed size (in bytes) of the 32-bit misc textures chunk (4 bytes)
uint8_t Image32Misc_Compressed[Image32Misc_CompSize]; // zlib-compressed 32-bit misc textures chunk (Image32Misc_CompSize bytes)
{
    tr4_image32 Image32Misc[3];
}
uint16_t LaraType;
uint16_t WeatherType;
uint8_t Padding[28];
uint32_t LevelData_UncompSize; // uncompressed size (in bytes) of the level data chunk (4 bytes)
uint32_t LevelData_CompSize; // compressed size (in bytes) of the level data chunk, equal to LevelData_UncompSize (4 bytes)
// NOT COMPRESSED
uint32_t LevelNumber; // supposed to be the level number but TOM2PC didn't allow changing it, always 0 (4 bytes)
uint16_t NumRooms; // number of rooms (2 bytes)
tr5_room Rooms[NumRooms]; // room list (variable length)
uint32_t NumFloorData; // number of floor data uint16_t's to follow (4 bytes)
uint16_t FloorData[NumFloorData]; // floor data (NumFloorData * 2 bytes)
uint32_t NumMeshData; // number of uint16_t's of mesh data to follow (=Meshes[]) (4 bytes)
tr4_mesh Meshes[NumMeshPointers]; // note that NumMeshPointers comes AFTER Meshes[]
uint32_t NumMeshPointers; // number of mesh pointers to follow (4 bytes)
uint32_t MeshPointers[NumMeshPointers]; // mesh pointer list (NumMeshPointers * 4 bytes)
uint32_t NumAnimations; // number of animations to follow (4 bytes)
tr4_animation Animations[NumAnimations]; // animation list (NumAnimations * 40 bytes)
uint32_t NumStateChanges; // number of state changes to follow (4 bytes)
tr_state_change StateChanges[NumStateChanges]; // state-change list (NumStructures * 6 bytes)
uint32_t NumAnimDispatches; // number of animation dispatches to follow (4 bytes)
tr_anim_dispatch AnimDispatches[NumAnimDispatches]; // animation-dispatch list list (NumAnimDispatches * 8 bytes)
uint32_t NumAnimCommands; // number of animation commands to follow (4 bytes)
tr_anim_command AnimCommands[NumAnimCommands]; // animation-command list (NumAnimCommands * 2 bytes)
uint32_t NumMeshTrees; // number of MeshTrees to follow (4 bytes)
tr_meshtree_node MeshTrees[NumMeshTrees]; // MeshTree list (NumMeshTrees * 4 bytes)
uint32_t NumFrames; // number of words of frame data to follow (4 bytes)
uint16_t Frames[NumFrames]; // frame data (NumFrames * 2 bytes)
uint32_t NumModels; // number of models to follow (4 bytes)
tr_model Models[NumModels]; // model list (NumModels * 18 bytes)
uint32_t NumStaticMeshes; // number of StaticMesh data records to follow (4 bytes)
tr_staticmesh StaticMeshes[NumStaticMeshes]; // StaticMesh data (NumStaticMesh * 32 bytes)
uint8_t SPR[4]; // S P R \0 (0x53, 0x50, 0x52, 0x00)
uint32_t NumSpriteTextures; // number of sprite textures to follow (4 bytes)
tr_sprite_texture SpriteTextures[NumSpriteTextures]; // sprite texture list (NumSpriteTextures * 16 bytes)
uint32_t NumSpriteSequences; // number of sprite sequences records to follow (4 bytes)
tr_sprite_sequence SpriteSequences[NumSpriteSequences]; // sprite sequence data (NumSpriteSequences * 8 bytes)
uint32_t NumCameras; // number of camera data records to follow (4 bytes)
tr_camera Cameras[NumCameras]; // camera data (NumCameras * 16 bytes)
uint32_t NumFlybyCameras; // number of flyby camera data records to follow (4 bytes)
tr4_flyby_camera FlybyCameras[NumFlybyCameras]; // flyby camera data (NumFlybyCameras * 40 bytes)
uint32_t NumSoundSources; // number of sound source data records to follow (4 bytes)
tr_sound_source SoundSources[NumSoundSources]; // sound source data (NumSoundSources * 16 bytes)
uint32_t NumBoxes; // number of box data records to follow (4 bytes)
tr2_box Boxes[NumBoxes]; // box data (NumBoxes * 8 bytes)
uint32_t NumOverlaps; // number of overlap records to follow (4 bytes)
uint16_t Overlaps[NumOverlaps]; // overlap data (NumOverlaps * 2 bytes)
int16_t Zones[10*NumBoxes]; // zone data (NumBoxes * 20 bytes)
uint32_t NumAnimatedTextures; // number of animated texture records to follow (4 bytes)
uint16_t AnimatedTextures[NumAnimatedTextures]; // animated texture data (NumAnimatedTextures * 2 bytes)
uint8_t AnimatedTexturesUVCount;
uint8_t TEX[4]; // T E X \0 (0x54, 0x45, 0x58, 0x00)
uint32_t NumObjectTextures; // number of object textures to follow (4 bytes) (after AnimatedTextures in TR3)
tr4_object_texture ObjectTextures[NumObjectTextures]; // object texture list (NumObjectTextures * 38 bytes)
uint32_t NumEntities; // number of entities to follow (4 bytes)
tr4_entity Entities[NumEntities]; // entity list (NumEntities * 24 bytes)
uint32_t NumAIObjects; // number of AI objects to follow (4 bytes)
tr4_ai_object AIObjects[NumAIObjects]; // AI objects list (NumAIObjects * 24 bytes)
uint16_t NumDemoData; // number of demo data records to follow (2 bytes)
uint8_t DemoData[NumDemoData]; // demo data (NumDemoData bytes)
int16_t SoundMap[450]; // sound map (740 bytes)
uint32_t NumSoundDetails; // number of sound-detail records to follow (4 bytes)
tr3_sound_details SoundDetails[NumSoundDetails]; // sound-detail list (NumSoundDetails * 8 bytes)
uint32_t NumSampleIndices; // number of sample indices to follow (4 bytes)  +
uint32_t SampleIndices[NumSampleIndices]; // sample indices (NumSampleIndices * 4 bytes)
uint8_t Separator[6]; // 6 0xCD bytes
uint32_t NumSamples; // number of sound samples (4 bytes)
tr4_sample Samples[NumSamples]; // sound samples (this is the last part, so you can simply read until EOF)

LaraType:

  • 0 — Normal
  • 3 — Catsuit
  • 4 — Divesuit
  • 6 — Invisible

WeatherType:

  • 0 — Normal
  • 1 — Rain
  • 2 — Snow

Changes in TR1 vs. TR2

  • TR1 has no colour table or 16-bit palette before the start of the textures; it also lacks 16-bit textures.
  • In TR1, [tr2_room_vertex] has after its [tr_vertex] struct only the first light intensity, and not the attributes or the second intensity.
  • In TR1, after SectorData, there is only the first light intensity, and not the second one or the lighting mode.
  • In TR1, [tr2_room_light] has only one of:
    • uint16_t Diffuse1/2
    • uint32_t Unknown1/2
  • In TR1, [tr_room_staticmesh] does not have two light intensities, but only one.
  • “Boxes” objects are rectangles whose four horizontal-coordinate values are uint8_ts in TR2 and int32_t's in TR1.
  • “Zones” objects have 10 int16_ts in TR2, but 6 int16_ts in TR1
  • In TR1, [tr_entity] is like the TR2 version, but with only one light intensity.
  • The TR1 colour table has the same format as the TR2 colour table, but it is located between the LightMap and the cinematic frames.
  • SoundMap is 370 int16_ts in TR2, but 256 int16_ts in TR1.
  • Between SoundDetails and SampleIndices, TR1 has all the level’s sound samples, in the form of embedded Microsoft WAVE files. Just before these samples is the total number of bytes in those sound samples, which is a int32_t.

Changes in TR2 vs. TR3

  • After the two room-light intensities, TR2 has a lighting-mode value, which TR3 lacks.
  • Also in [tr3_room], TR3 has 3 extra bytes at the end, which are WaterScheme, ReverbInfo and null filler.
  • Finally, in TR2, the [tr_object_texture] data is before the [tr_sprite_texture] data. In TR3, it is before the [tr2_entity] data.

Changes in TR3 vs. TR4

  • There are no more 8-bit and 16-bit palettes.
  • There are no more 8-bit textures.
  • There are now 32-bit textures.
  • Texture atlases are now divided into three parts: non-bumpmapped room texture atlases, model texture atlases and bumpmapped room texture atlases.
  • Level file divided in several chunks, with each chunk compressed using zlib:
    • Chunk 1: 32-bit texture atlases.
    • Chunk 2: 16-bit texture atlases.
    • Chunk 3: 32-bit sky and font graphics.
    • Chunk 4: Level data.
  • Each compressed chunk is preceded by its uncompressed size and compressed size uint32_ts.
  • After last compressed chunk, there are now all audio samples, sequentially stored in this manner:
struct tr4_sample
{
    uint32_t  UncompressedSize;
    uint32_t  CompressedSize;
        char  WaveFile[];       // Embedded sample in MS-ADPCM or PCM WAV format.
}
  • Room Light structure has completely changed:
    • Colour is no longer stored in [tr_colour4] format, rather [tr_colour].
    • There is new field LightType, which specifies light mode or fog bulb mode.
    • After LightType, there is a uint8_t Filler value of 0xFF.
    • Intensity is now uint8_t.
    • Instead of Fade, there is a set of 4 float values: In, Out, Length and CutOff.
    • There are also three float values defining light direction.
  • There are now two dedicated structures for mesh faces, bearing extra field Lighting.
  • There is now FlybyCameras block before SoundSources block.
  • Cinematic Frames are replaced with AI Data block.
  • Meaning of fields in [tr_sprite_texture] has changed.
  • In addition, the NumSpriteTextures field is preceeded by the 3 ASCII bytes SPR.
  • Meshes have no longer colored tris / quads. So, NumColoredRectangles, ColoredRectangles[], NumColoredTriangles, ColoredTriangles[] no longer exist in the tr4_mesh structure.
  • The NumObjectTextures field is now preceeded by 4 ASCII bytes \0TEX
  • [tr4_object_texture] struct is used instead of [tr_object_texture].
  • [tr4_animation] struct is used instead of [tr_animation].
  • There is no lightmap.
  • TR4 levels have an additional 6 bytes at the end of the uncompressed Level data that seem to be always 0.

Changes in TR4 vs. TR5

Differences between “normal” TRs and Demos

  • Presumably as a form of copy protection, the demo versions of some of the TR games use levels that are slightly different from those in the retail versions. However, those that have been found are all data rearrangements, as explained below.
  • The TR1 and Unfinished Business (.TUB) demos have their palettes moved to between the SpriteSequences and the Cameras.
  • The TR2 “Wall” demo, and maybe also its “Venice” demo, has its LightMap (8K) moved to between the SpriteSequences and the Cameras. It also has its SampleIndices content replaced by the soundfiles, though the associated number of them remains unchanged (the number of indices becomes the number of samples).
  • That demo also has its own version of TOMBPC.DAT, called DEMOPC.DAT, which appears to have the exact same format as TOMBPC.DAT.
  • The Version field of TR4 levels is 0x00345254 (“TR4\0”) for normal game and 0x63345254 (“TR4c”) for demo.

No rearrangements are known for the TR3 demos.

trs/file_formats.txt · Last modified: 2021/04/29 21:53 (external edit)
Back to top
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0