Table of Contents

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:

WeatherType:

Changes in TR1 vs. TR2

Changes in TR2 vs. TR3

Changes in TR3 vs. TR4

struct tr4_sample
{
    uint32_t  UncompressedSize;
    uint32_t  CompressedSize;
        char  WaveFile[];       // Embedded sample in MS-ADPCM or PCM WAV format.
}

Changes in TR4 vs. TR5

Differences between “normal” TRs and Demos

No rearrangements are known for the TR3 demos.