This version (2017/04/24 02:02) was approved by zdimension.The Previously approved version (2017/03/25 17:04) is available.Diff

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 header; // Always 0x3E8 (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 ?
         * 3 Single shot.?
         * 4 Combat?
         */
        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 weapons;
        uint8_t unknown2;
    } 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;
    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 puzzle[4];
    uint8_t keys[4];
    uint8_t pickup; // the pickup item
    uint8_t levelInitDataCRC; // not implemented, always 0
    // 10240 bytes starting from now
    uint8_t roomsAreSwapped;
    uint8_t flipFlags[10]; // = (FlipFlag & 0xFF00) >> 8
    uint16_t cameraFlagsZoneIndexes[cameraCount];
    // items block here todo
#pragma pack(push, 8)  
    struct
    {
        int16_t itemID;
        int16_t handStatus;
        WeaponID currentWeapon;
        int16_t nextWeapon;
        int16_t climbFallSpeedOverride;
        int16_t underwaterState;
        int16_t unknown1;
        int16_t collisionFrame;
        int16_t collisionAxis;
        int16_t air;
        int16_t swimToDiveKeypressDuration;
        int16_t deadTime;
        int16_t underwaterCurrentStrength;
        int16_t unknown2;
        Vertex4 *wallPosition;
#pragma pack(push, 1)
        struct MeshTree
        {
            int32_t replacedMeshesBits;
            MESH_HEADER *meshes[15];
        } laraMeshTree;
#pragma pack(pop)
        ITEM *enemy;
        Vertex2YX enemyLookRot;
        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 0xFFFFFFFF (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

ID Level Filename Camera count Items Secrets Puzzle Key
1 2 3 4 1 2 3 4
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.
trs/savegame/tr1.txt · Last modified: 2017/04/24 02:02 (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