This version is outdated by a newer approved version.This version (2017/01/30 22:56) was approved by zdimension.
This is an old revision of the document!
TR4
original research by sapper, minor improvements by zdimension
struct tr4_savegame { uint8_t LevelName[40]; // CP437 C string; null-terminated (data after \0 is ignored) uint8_t unknown1[35]; int32_t SaveNumber; uint16_t Days; uint16_t Hours; uint16_t Minutes; uint16_t Seconds; int16_t LaraIndex; int16_t LaraArmAction; int16_t CurrentItemInHand; int16_t ChangeToItemInHand; int16_t ActiveWeapon; uint8_t unknown2[6]; int16_t LaraAir; uint8_t unknown3[20]; int16_t WeaponOnBack; uint8_t unknown3b[2]; int16_t LaraPoison1; int16_t LaraPoison2; uint8_t unknown3a[16]; uint8_t LaraSpecialStatus; // 0x4 = Normal; 0xC = Burning Lara; Anything other = save doesn't appear uint8_t unknown4[95]; int16_t LaraFacing; // Matches data for item below uint8_t unknown4a[108]; uint8_t Pistols; // 0 = missing; 9 = present uint8_t Uzis; // 0 = missing; 1 = present uint8_t Shotgun; // 0 = missing; 9 = present uint8_t Crossbow; // 0 = missing; 9 = present; 13 = combined with lasersight uint8_t GrenadeGun; // 0 = missing; 9 = present uint8_t Revolver; // 0 = missing; 1 = present; 5 = combined with lasersight uint8_t LaserSight; // 0 = missing or combined; 1 = present separated uint8_t Binoculars; uint8_t Crowbar; uint8_t MechanicalScarab; uint8_t SmallWaterSkin; int8_t LargeWaterSkin; uint8_t Examine[3]; uint8_t PuzzleItems[12]; uint8_t PuzzleItem1_4Combo; uint8_t PuzzleItem5_8Combo; uint8_t KeyItem1_8; uint8_t KeyItem9_12; uint8_t KeyItem1_4Combo; uint8_t KeyItem5_8Combo; uint8_t PickupItem1_4; uint8_t unknown5; uint8_t PickupItem1_4Combo; uint8_t unknown6; uint8_t QuestItem1_6; uint8_t unknown7; int16_t SmallMediPacks; // 65535 means unlimited int16_t LargeMediPacks; // 65535 means unlimited int16_t Flares; // 65535 means unlimited int16_t PistolAmmo; int16_t UziAmmo; int16_t RevolverAmmo; int16_t ShotgunAmmo[2]; // normal; wide, divide by 6 for real value int16_t GrenadeAmmo[3]; // normal; super; flash int16_t CrossbowAmmo[3]; // normal; poison; explosive int16_t MEchanicalScarabRemaining; uint8_t unknown8[57]; uint8_t LevelNumber; uint8_t unknown9; // clock?? uint32_t TimeTaken; // in game ticks (1/30th of a second), so divide by 30 for time in seconds uint32_t DistanceTravelled; // Divide by 419.15 for value in meters int32_t AmmoUsed; int32_t Hits; uint8_t unknown10[2]; uint8_t Secrets; uint8_t HealthPacksUsed; uint8_t unknown11[16]; uint16_t Kills; uint8_t unknown11a[11]; struct { uint8_t unused; uint8_t blue; uint8_t green; uint8_t red; } FogColour; int8_t AutoAimingForEnemy; uint8_t unknown12[172]; uint8_t TheGreatUnknown[]; // When reading a TR4 savegame, first jump to EOF - 8 and check if the string "NGLE" // is present. If that is the case, then it is a NGLE savegame. // It means that the "standard" TR4 save info (TheGreatUnknown) will have // a length of (file length) - (pos of TheGreatUnknown) - NGHeader.size #if NGLE struct { uint8_t data[size - 8]; uint8_t signature[4]; // ASCII string; always "NGLE" uint32_t size; } NGHeader; #endif };