Table of Contents

TR1

When loading a save game, classic TR games read the name and number and then load everything after that directly into the game RAM, without checking anything. That's why savegames from original versions don't work in multipatched versions (and make the game crash). It also makes the “struct-ification” of the format very hard, as it would need decompiling the whole game (which is already being done for TR1 by some awesome people). The way the game works also makes the savegames extremely level-dependent, at least for the entity info part (which is yet to be documented here) as when creating a new game, the game simply loads the level data in RAM, and when saving it writes that down in a file. Understanding a savegame file completely therefore requires having the original level file the savegame is for.
struct TR1Savegame // 10675 bytes
{
    uint8_t saveName[75]; // ASCII C string; null-terminated (there is always random data after \0, it is ignored); for accents see String Array section of TOMBPC.DAT page
    uint32_t saveNumber; // game clips it to 16 bits
    uint8_t unknown2[15];
    // First level use block 0, second use block 1... so that at the end of the game,
    // it sums up everything and/or checks if you found all secrets, etc
    struct
    {
        uint16_t ammoPistols; // Always 1000
        uint16_t ammoMagnums; // 65,535 means unlimited
        uint16_t ammoUzis;
        uint16_t ammoShotgun;
        uint8_t smallMedipacks; // 255 means unlimited
        uint8_t largeMedipacks;
        uint8_t numScionPieces;
        /* 0 None
         * 1 Climbing
         * 2 Draw weapon
         * 3 Holster weapon
         * 4 Combat (i.e. holding a weapon)
         */
        uint8_t handStatus;
        /* 0 None
         * 1 Pistols
         * 2 Magnums
         * 3 Uzis
         * 4 Shotgun
         */
        uint8_t weapon; // current held weapon
        /* 00000001 Level unlocked
         * 00000010 Pistols
         * 00000100 Magnums
         * 00001000 Uzis
         * 00010000 Shotgun
         * 00100000 Midas Hand
         */
        uint8_t flags;
        uint8_t _padding;
    } levelInitData[21]; // for the 21 levels (315 bytes)
    uint32_t elapsedTime; // in game ticks (1/30th of a second), so divide by 30 for time in seconds
    uint32_t kills;
    uint16_t secretsFound; // bitmask of the discovered secrets of the current level
    uint16_t levelNumber; // First level = 1
    uint8_t numPickups;
    uint8_t unlimitedAmmo; // Enabled = 1
    uint8_t hasItem141; // From decompiled game source.
    uint8_t hasItem142; // Strangely, those (unknown) items aren't present in any official TR1 level
    uint8_t puzzles[4];
    uint8_t keys[4];
    uint8_t leadBar;
    uint8_t levelInitDataCRC; // not implemented, always 0
    // 10240 bytes starting from now
    uint8_t roomsAreSwapped;
    uint8_t flipFlags[10]; // = (FlipFlag & 0xFF00)>> 8
    uint16_t cameraFlagsZoneIndices[cameraCount];
    // items block here todo
#pragma pack(push, 8)
    struct
    {
        int16_t itemID;
        int16_t handStatus;
        WeaponID currentWeapon;
        WeaponID requestedWeapon;
        int16_t climbFallSpeedOverride;
        int16_t underwaterState;
        int16_t unknown1;
        int16_t collisionFrame;
        int16_t collisionAxis;
        int16_t air; // game ticks of air left
        int16_t swimToDiveKeypressDuration; // game ticks
        int16_t deadTime; // game ticks
        int16_t underwaterCurrentStrength;
        int16_t spasmEffectCounter; // e.g. when Lara is hit by lightning
        Vertex4 *spasmSource; // from which direction Lara is hit
#pragma pack(push, 1)
        struct MeshTree
        {
            int32_t replacedMeshesBits;
            MESH_HEADER *meshes[15];
        } laraMeshTree;
#pragma pack(pop)
        ITEM *enemy;
        Vertex2YX weaponTargetVector;
        int16_t yRotationSpeed;
        int16_t movementAngle;
        Vertex2YXZ headRotation;
        Vertex2YXZ torsoRotation;
        AimInfo aimInfoLeft;
        AimInfo aimInfoRight;
        Ammo pistolAmmo;
        Ammo magnumAmmo;
        Ammo uziAmmo;
        Ammo shotgunAmmo;
        struct RoutePlanner
        {
            BoxNode *node;
            uint16_t head;
            uint16_t tail;
            uint16_t searchNumber;
            int16_t blockMask;
            int16_t stepHeight;
            int16_t dropHeight;
            int16_t flyHeight;
            int16_t zoneCount;
            int16_t destinationBox;
            uint16_t searchOverride;
            Vertex4 searchTarget;
        } aiInfo;
    } lara; // 236 bytes
#pragma pack(pop)
    int32_t postFxFunc; // this is usually -1 (and the last occurence of that in the file) so you can align it to that (replace the items blocks above by a filler block) so that Lara is aligned to postFxFunc
    int32_t animFxTime;
};
 
enum WeaponID : int16_t
{
    None = 0,
    Pistols = 1,
    Autopistols = 2,
    Uzis = 3,
    Shotgun = 4,
};
 
struct Vertex2
{
    int16_t x;
    int16_t y;
    int16_t z;
};
 
struct Vertex2YX
{
    int16_t y;
    int16_t x;
};
 
struct Vertex2YXZ
{
    int16_t y;
    int16_t x;
    int16_t z;
};
 
struct Vertex4
{
    int32_t x;
    int32_t y;
    int32_t z;
};
 
struct Ammo
{
    int32_t ammo;
    int32_t hits;
    int32_t misses;
};
 
#pragma pack(push, 8)
struct AimInfo
{
    ANIM_FRAME *weaponAnimData;
    int16_t frame;
    int16_t aiming;
    Vertex2YXZ aimRotation;
    int16_t shootTimeout;
};
#pragma pack(pop)
The xxxxCount values are available in the table below.

Identifications

Levels

IDLevelFilenameCamera countItems SecretsPuzzleKey
12341234
0 Lara's Home GYM 1 1 0
1 Caves LEVEL1 2 60 3
2 City of Vilcabamba LEVEL2 6 95 3 Gold Idol Silver Key
3 Lost Valley LEVEL3A 6 64 5 Machine Cog
4 Tomb of Qualopec LEVEL3B 10 77 3
5 St. Francis' Folly LEVEL4 14 107 4 Neptune Key Atlas Key Damocles Key Thor Key
6 Colosseum LEVEL5 10 86 3 Rusty Key
7 Palace Midas LEVEL6 7 136 3 Gold Bar
8 The Cistern LEVEL7A 7 112 3 Gold Key Silver Key Rusty Key
9 Tomb of Tihocan LEVEL7B 15 88 2 Gold Key Rusty Key Rusty Key
10 City of Khamoon LEVEL8A 3 93 3 Saphire Key
11 Obelisk of Khamoon LEVEL8B 8 103 3 Eye of Horus Scarab Seal of Anubis Ankh Saphire Key
12 Sanctuary of the Scion LEVEL8C 12 74 1 Ankh Scarab Gold Key
13 Natla's Mines LEVEL10A 15 101 3 Fuse Pyramid Key
14 Atlantis LEVEL10B 6 192 3
15 The Great Pyramid LEVEL10C 2 129 3
16 Cut Scene 1 CUT1 1 3 N/A
17 Cut Scene 2 CUT2 0 1
18 Cut Scene 3 CUT3 0 4
19 Cut Scene 4 CUT4 0 6
20 Title TITLE 0 1
21 Current Position CURRENT
The level “Current Position” (ID 21) seems to have been used internally during the development of the game, and its purposes are unknown. Its file “CURRENT.PHD” isn't present in any of the official releases. TODO: Check in the betas.