Saves (GTA SA)

From GTAMods Wiki
Revision as of 13:17, 8 December 2007 by Seemann (talk | contribs) (Block 9: Markers)
Jump to navigation Jump to search

Introduction

This article deals with the format of a saved game file for Grand Theft Auto: San Andreas (GTASA). It is specifically geared towards the PC version(s) but much of it may be applicable to console versions too.

Location and Format Overview

By default, GTASA places its saved game files into the folder "GTA San Andreas User Files" which is located in the current user's Documents folder. The location of this folder varies depending upon the version of Windows installed. Some typical locations for a user with an account named "Fred" would be:

  • C:\My Documents\GTA San Andreas User Files -- Windows 98 Example
  • C:\Documents and Settings\Fred\My Documents\GTA San Andreas User Files -- Windows XP Example
  • C:\Users\Fred\Documents\GTA San Andreas User Files -- Windows Vista Example

Obviously those locations can vary based upon different Windows configurations or installation options. Note also that the executable can be modified to use a different file location through the use of a hex editor and special registry key in a process outlined at GTAForums

The save files themselves are named in the format GTASAsfX.b where X represents the in-game slot number. So, the game saved in slot 1 will be stored in the save file GTASAsf1.b and the game saved in slot 5 will be stored in the save file GTASAsf5.b. There are 8 slots available in the game (1-8). GTASA save files are always 0x31800 bytes long (202,752 in decimal) and are not compressed or encoded in any way.

Format Details

A GTASA save file consists of 28 "blocks" of data followed by some duplicated data for padding and then ending with a checksum value. Each of these elements is described below.

Data Blocks

Each data block consists of the 5 characters BLOCK followed by a variable amount of data; in general, each block has its own unique internal format. The format descriptions in this article only deal with those internal block formats which follow the initial BLOCK identifier and all offsets start at the byte following the BLOCK identifier for the given block.

Note that many of the blocks contain data structures. These structures are aligned along 4-byte boundaries; thus if there's a field with size 1 or 2 bytes in the end of structure, there are also additional unused bytes present at the end of the structure which pad it to fill the remaining space. This type of gap can also occur in the middle of a structure. The convention used by this article is to mark such gaps as an array of bytes with the description (Align) .

Block 0: Miscellaneous

Game "meta-information" giving the overall state of things. This block has a constant length of 0x138 bytes

OFFSET  TYPE      DESCRIPTION
0x0000  dword     version ID (checksum of a string describing the time of compilation. See note 1 below)
0x0004  char[100] save name (long names are truncated on the save/load screen. See note 2 below)
0x0068  byte      current mission pack
0x0069  byte[3]   (Align)
0x006C  dword     current town (island) (used when a replay playback is started/finished)
0x0070  float[3]  camera coordinates (x,y,z)
0x007C  dword     length (ms) of in-game minute
0x0080  dword     weather timer
0x0084  byte      current in-game month
0x0085  byte      current in-game month day
0x0086  byte      game hour
0x0087  byte      game minute
0x0088  byte      weekday
0x0089  byte      current in-game month (copy)
0x008A  byte      current in-game month day (copy)
0x008B  byte      game hour (copy)
0x008C  byte      game minute (copy)
0x008D  byte      time copy flag (See note 3 below)
0x008E  word      (unknown) 
0x0090  byte      has ever cheated flag
0x0091  byte[3]   (Align)
0x0094  dword     global timer
0x0098  float     game speed
0x009C  float     (unknown) (FPS?)
0x00A0  float     tick time (time of an iteration of the major game loop)
0x00A4  dword     number of the frames processed from the beginning of the game
0x00A8  word      (unknown)
0x00AA  word      (unknown)
0x00AC  word      weather ID 
0x00B0  dword     (unknown) 
0x00B4  dword     (unknown)
0x00B8  dword     (unknown)
0x00BC  dword     vehicle camera view (opcode 09AD)
0x00C0  dword     onfoot camera view
0x00C4  dword     current interior
0x00C8  byte      (unknown)
0x00CC  dword     original interior color (?)
0x00D0  byte      interior color flag (?)
0x00D4  dword     (unknown)
0x00D8  dword     changed interior color (?)
0x00DC  dword     (unknown)
0x00E0  byte      riot mode flag (opcode 06C8)
0x00E1  byte      (unknown)
0x00E4  dword     max wanted level
0x00E8  dword     max chaos (See note 4 below)
0x00EC  byte      (unknown)
0x00ED  byte      is german lang (?) (opcode 040C)
0x00EE  byte      (unknown)
0x011C  byte      times left to display a cinematic camera help (see note 5 below)
0x011E  word      SYSTEMTIME wYear
0x0120  word      SYSTEMTIME wMonth
0x0122  word      SYSTEMTIME wDayOfWeek
0x0124  word      SYSTEMTIME wDay
0x0126  word      SYSTEMTIME wHour
0x0128  word      SYSTEMTIME wMinute
0x012A  word      SYSTEMTIME wSecond
0x012C  word      SYSTEMTIME wMilliseconds
0x0130  dword     Player target marker handle (handle of the red target icon in the map menu)
0x0134  byte      Boolean: the vehicle stealing help was shown (See note 6 below)
0x0135  byte      Boolean: All taxis have nitro (opcode 0572 flag)
0x0136  byte      Boolean: Prostitutes pay you (opcode 0A3D flag)
0x0137  byte      (Align)

Notes:

  1. Version 2.0 of GTASA will not load a save file if the Version ID String does not match its own Version ID String. Thus if a game was played on a version 1.x exe using the exact same set of mission scripts as a version 2.0 installation, the version 2.0 game will refuse to load the save unless this ID is changed. Version 1.x exes make no Version ID String check and will attempt to load any non-corrupted save. Some known Version ID String values (listed as consecutive bytes):
    • 0x75 0x81 0xDA 0x35 -- Version 1.00 Unmodified EXE
    • 0x83 0xE5 0xF3 0x65 -- Version 1.00 Modified EXE
    • 0x58 0xBE 0x6E 0x9A -- Version 1.01 Unmodified EXE
    • 0x5E 0x76 0x45 0x93 -- Version 1.01 Modified EXE
    • 0xF6 0x8D 0x14 0xFD -- Version 2.00 Unmodified EXE
  2. While the save name can be changed here to pretty much anything, that name will not persist the next time the game is saved, even if no missions were completed during the play session. This is because each time the game is saved this name string is reset based upon the GXT entry for the Last Mission Passed key stored in Block 15.
  3. Time copy flag shows whether the time data was saved using opcode 0253.
  4. Chaos is a value need to be gained to get one more star. MaxChaos is a limit for current wanted level.
  5. This is a number of how much times the cinematic camera help (about switching display modes) will be shown. Initially this value equals to 2. When it reaches zero, the help does not appear on cinematic camera enabling.
  6. This is a flag, which is set to 1 when player first time stealing a vehicle and get a help message about it, to prevent displaying this message again.

Block 1: Script

Information pertaining to the Mission Scripts in use when the game was saved. Includes all global variables and information about running threads including thread pointers and local variables. A minor size difference between the MAIN section of the version 1 and version 2 scripts is the primary cause of incompatibility between version 1 and version 2 saves because it forces the other threads to be at slightly different memory locations. One can adjust the thread pointers in this block and (if converting from 1 to 2) the Version ID String from block 0 to convert a save between the two versions; this applies to either completely unmodded or identically-modded installations of v1 and v2.

As the first section in this block can vary in size, offsets given are from the current section.

OFFSET  TYPE                      DESCRIPTION
0x0000  dword                     Size of Global Variable space
0x0004  dword[]                   Global Variable Space -- every var is 4 bytes; the types can vary
 ...
0x0000  ExternalScriptTrigger[70] each is 0x14 bytes in size; see details below
0x0578  dword                     OnMissionFlag offset  -- address of the global variable set by opcode 0180
0x057C  dword                     time when last mission was passed (when either opcode 0318 or 0595 is executed)
0x0580  byte[898]                 (unknown) + main.scm parameters (missions count, main size, etc)
 ...
0x0000  dword                     Number of Running Threads
0x0004  Thread[]                  Thread structures -- each is 0x106 bytes in size; see details below
ExternalScriptTrigger
  0x00   word                     Index in the script.img 
  0x02   byte                     Attach type (actor or object)
  0x03   byte                     Type? -- only for ObjectTrigger
  0x04   dword                    Status?
  0x08   dword                    Radius -- vary only for ObjectTrigger (ActorTrigger uses a pre-defined radius of 5.0)
  0x0C   word                     modelID
  0x0E   word                     priority
  0x10   dword                    (unknown)
  0x14                            end

Note:

  • These triggers are created with opcodes 0928, 0929
Thread Structure:
  0x00  word                      Index/Handle
  0x02  byte[224]                 Thread Memory Dump -- see details below
  0xE2  byte[36]                  Relative Addresses -- see details below
Thread Memory Dump:
  0x00  dword                     Next Pointer
  0x04  dword                     Previous Pointer
  0x08  char[8]                   Thread Name
  0X10  dword                     Absolute Base Address
  0x14  dword                     Absolute IP
  0x18  dword[8]                  Absolute Return Stack
  0x38  word                      Stack Pointer
  0x3C  dword[32]                 Local Variables
  0xBC  dword[2]                  Local Timers
  0xC4  byte                      (Unknown)
  0xC5  byte                      'if' statement result
  0xC6  byte                      (Unknown)
  0xC7  byte                      Is External Script
  0xC8  byte                      (Unknown)
  0xC9  byte                      (Unknown)
  0xCA  byte[2]                   (Align)
  0xCC  dword                     Wakeup Time
  0xD0  word                      'if' parameter
  0xD2  byte                      'not' flag
  0xD3  byte                      'wb_check' flag
  0xD4  byte[4]                   (Unknown)
  0xD8  dword                     Skip Scene Pos (opcode 0707)
  0xDC  byte                      Is Mission
  0xDD  byte[3]                   (Align)
  0xE0                            end
Relative Addresses              -- Necessary here because the absolute addresses used in-game depend on memory layout
  0x00  dword                      Relative IP
  0x04  dword[8]                   Relative Return Stack

Block 2: Players & Objects

Information about players (commonly only one) and mission-script placed objects such as doors, etc.

OFFSET  TYPE       DESCRIPTION
0x0000  dword      Number of Players
0x0004  Player[]   Player structures -- each is 0x228 bytes in size; see details below
0x0000  dword      Number of Objects
0x0004  Object[]   Object structures -- each is 0x3C bytes in size; see details below
Player Structure:
  0x0000  dword      Handle of a player actor
  0x0004  dword      Model ID
  0x0008  dword      PedType
  
  0x000C  dword      size of the following data (0x18C)
  0x0010  float[3]   X, Y, Z
  0x001C  float      Health
  0x0020  float      Armor
  0x0024  Weapon[13] Weapon Structure -- each is 0x1C in size; see details below
  0x0190  byte       Ped reference (normally 2)
  0x0191  byte       Current weapon slot
  0x0192  byte[6]    (unknown)
  0x0198  byte       melee style 1?
  0x0199  byte       melee style 2?
  0x019A  byte[2]    (Align)
  
  0x019C  dword      size of the following data (0x84)
  0x01A0  dword      chaos
  0x01A4  dword      wanted level
  0x01A8  dword      CRC32 of filename for Torso model
  0x01AC  dword      CRC32 of filename for Head model
  0x01B0  dword      CRC32 of filename for (unknown)
  0x01B4  dword      CRC32 of filename for Legs model
  0x01B8  dword      CRC32 of filename for Feet model
  0x01BC  dword      CRC32 of filename for Chain model
  0x01C0  dword      CRC32 of filename for Watch model
  0x01C4  dword      CRC32 of filename for Shades model
  0x01C8  dword      CRC32 of filename for Hat model
  0x01CC  dword      CRC32 of filename for Special model
  0x01D0  dword      CRC32 of filename for Torso texture
  0x01D4  dword      CRC32 of filename for Head texture
  0x01D8  dword      CRC32 of filename for Legs texture
  0x01DC  dword      CRC32 of filename for Feet texture
  0x01E0  dword      CRC32 of filename for Upper Left Arm Tattoo texture
  0x01E4  dword      CRC32 of filename for Lower Left Arm Tattoo texture
  0x01E8  dword      CRC32 of filename for Upper Right Arm Tattoo texture
  0x01EC  dword      CRC32 of filename for Lower Right Arm Tattoo texture
  0x01F0  dword      CRC32 of filename for Back Tattoo texture
  0x01F4  dword      CRC32 of filename for Left Chest Tattoo texture
  0x01F8  dword      CRC32 of filename for Right Chest Tattoo texture
  0x01FC  dword      CRC32 of filename for Stomach Tattoo texture
  0x0200  dword      CRC32 of filename for Lower Back Tattoo texture
  0x0204  dword      CRC32 of filename for Chain texture
  0x0208  dword      CRC32 of filename for Watch texture
  0x020C  dword      CRC32 of filename for Shades texture
  0x0210  dword      CRC32 of filename for Hat texture
  0x0214  dword      CRC32 of filename for Special texture
  0x0218  float      Body Fat (used for current body type)
  0x022C  float      Body Muscle (used for current body type)
  0x0224  byte[4]    Align
Weapon Structure:
  0x00  dword        Weapon Type
  0x04  dword        (unknown) possibly Weapon state
  0x08  dword        (unknown) possibly Ammo in clip
  0x0C  dword        Weapon Ammo
  0x10  dword        (unknown) possibly Shots fired
  0x14  byte[8]      (unknown)
Object Structure:
  0x00  dword        Handle
  0x04  dword        Model ID
  0x08  dword        constant 48
  0x0C  float[3]     X, Y, Z
  0x18  byte[3]      CXYZ.right.xyz
  0x1B  byte[3]      CXYZ.top.xyz
  0x1E  byte[30]     (unknown)

Block 3: Garages

Information defining all garages (including bomb shops, pay & sprays, etc.) and also describing the cars stored in safehouse garages. This block can vary in size although in the unmodified game it will always be 0x23C7 bytes because there are 50 garages defined. The 80 saved vehicles (4 each in 20 garages) is a fixed number and probably cannot be exceeded. Also, the arrangement of the Garage Car structures in the save is non-intuitive: they follow the pattern Garage 1/Car 1, Garage 2/Car 1, ... Garage 20/Car 1, Garage 1/Car 2, Garage 2/Car 2 ...

OFFSET  TYPE          DESCRIPTION
0x0000  dword         Number of Garages 
0x0004  byte          Free Bombs
0x0005  byte          Free Resprays (opcode 0335)
0x0006  byte          Boolean: Respray Garages enabled (opcode 0A14)
0x0007  byte[32]      (Unknown) 
0x0027  GrgCar[20][4] Garage Car structures -- each is 0x40 bytes in size; see details below
0x1427  Garage[]      Garage structures -- each is 0x50 bytes in size; see details below
Garage Car Structure (GrgCar):
  0x00  float[3]      Coordinates (x,y,z)
  0x0c  byte[4]       (Unknown)
  0x10  byte          Car Flags
  0x11  byte          (Unknown)
  0x12  word          Vehicle Model ID
  0x14  word[15]      Installed Vehicle Mods (see veh_mods.ide)
  0x32  byte[4]       Primary Color, Secondary Color, Tertiary Color, (Unknown) Quaternary Color?
  0x36  byte          Radio Station
  0x37  byte[2]       Vehicle Variation
  0x39  byte          Bomb Type
  0x3A  byte          Paintjob
  0x3B  byte          Nitrous Count
  0x3C  byte[3]       Vector Rotation
  0x3F  byte          (unknown) Align
Garage Structure:
  0x00  byte          Garage Type
  0x01  byte[2]       Door Flags
  0x03  byte          (Unknown) Align
  0x04  float         X Coordinate for Lower Left Front
  0x08  float         Y Coordinate for Lower Left Front
  0x0c  float         Z Coordinate for Floor
  0x10  float[4]      Rotation (Quaternion Rx, Ry, Rz, Rw)
  0x20  float         Z Coordinate for Ceiling
  0x24  float         Width (dimension parallel to door in xy plane)
  0x28  float         Depth (dimension perpendicular to door in xy plane)
  0x2c  float         Minimum X Coordinate
  0x30  float         Maximum X Coordinate
  0x34  float         Minimum Y Coordinate
  0x38  float         Maximum Y Coordinate
  0x3c  float         Door is Open = 1
  0x40  float         (Unknown)door timer/timestamp?
  0x44  char[8]       Garage Name -- can be used by mission script to access garage
  0x4c  word          (Unknown) Possibly Original Type
Door Flags (hex value of bit) 
  offset 0x01  
    0x01      door is open flag (0x3c changes door)
  offset 0x02
    0x01      used mod shop (?)
    0x02      inactive door
    0x04      used Pay'n'Spray (?)
    0x08      small door (reflective?)
    0x10      up and in door
    0x20      camera follows player
    0x40      door is closed flag (0x3c changes door)
    0x80      girlfriend PnS
Car Flags (hex value of bit)
    0x01      bulletproof
    0x02      fireproof
    0x04      explosion proof
    0x08      damage proof 
    0x10      5th immunity
    0x20      bass boost
    0x40      hydraulics
    0x80      nitrous flag
Bomb Types
    1         5 sec detonator (garage type 2)
    2         ignition bomb unarmed (garage type 3)
    3         remote detonator (garage type 4)
    5         ignition bomb armed (garage type 3)

Block 4: Wasted/Busted

Unknown data. Block can vary in size depending on number of entries; number of entries may be zero.

OFFSET  TYPE            DESCRIPTION
0x0000  dword           Number of Block4Struct structures
0x0004  byte            Boolean: Lose stuff after wasted (opcode 08DD)
0x0005  byte            Boolean: Lose stuff after busted (opcode 08DE)
0x0006  byte            unknown Wasted_Busted Flag
0x0007  dword           unknown Wasted_Busted time
0x000B  Block4Struct[]  unknown structures (UNUSED?) -- see details below
Block4Struct structure:
 0x0000  byte[12]        (unknown)
 0x000C  byte[4]         (unknown)
 0x0010  end

Block 5: Disabled Pathnode Cubes

  0    dword           count
  4                    entries
  
Entry structure:
  0    float[6]        x1,x2,y1,y2,z1,z2
 18    byte[4]         bools that somehow indicate which pathtypes are enabled
 1c                    end
  • Note: these structures somehow related to opcodes 0606, 0607

Block 6: Pickups

0x0000   Pickup[620]     Pickups
0x4D80   word            Number of pickups being picked up (up to 20)
0x4D82   byte            Weapon pickup message counter (see note 1 below)
0x4D83   dword[20]       Pickups being picked up (they don't exist, but could be checked by opcode 0214
0x4DD3                   end
Pickup structure:
  0    float           current asset value
  8    dword           ammo (or max asset value)
  c    dword           unknown (timer?)
 10    word[3]         x,y,z, all multiplied by 8
 16    word            asset rate
 18    word            model
 1a    word            unknown (handle?)
 1c    byte            type
 1d    byte            unknown (flags?)
 20                    end

Flags:

  • 0x01 used pickups?
  • 0x02 dropped jetpack?
  • 0x04 switched weapon?
  • 0x08 collected pickup?
  • 0x10 can buy property
  • 0x20 can't buy property

Notes:

  1. When you walk across over a weapon pickup having a weapon of same type, the game will propose you to replace this slot with new weapon by pressing Action key. Initially number of this message showing times equals to 10. Each time you see the message, this counter is decreased. This field stores how much times left to display the message.

Block 7: (Unused)

 (Usually empty)

Block 8: Restart Locations

OFFSET  TYPE          DESCRIPTION
0x000   word          Wasted structures number
0x002   Restart[]     Wasted structures
0x000   word          Busted structures number
0x002   Restart[]     Busted structures
0x000   byte[55]      (Unknown)
Restart structure:
  0x000   float[3]      coords
  0x00C   float         heading
  0x010   dword         town (island)
  0x014   end

Block 9: Markers

OFFSET  TYPE           DESCRIPTION
0x0000  Markers[175]   Marker structures -- each is 0x28 bytes in size, see details below
0x1B58  end 
Marker structure:
  0x000  dword         color
  0x004  dword         entity handle this marker is attached to (opcodes 0186, 0187, etc)
  0x008  float[3]      position X,Y,Z
  0x014  word          index?
  0x016  byte[2]       (Align)
  0x018  float         sphere radius
  0x01C  word          icon size
  0x01E  byte[2]       (Align)
  0x020  dword         (unknown)
  0x024  dword         Icon ID
  0x025  byte[2]       unknown flags
  0x027  byte          (Align)
  0x028  end

Block 10: Zones

This block contains information about map zones in three arrays. The first array is for size and location information for the zones as initially defined in the data file info.zon. The second array contains entries for each of the uniquely-named zones defined in the first array and stores information about things like gang densities and popcycle.dat group info for each zone. Much of this info is set by specific opcodes such as 076C, 076A, 0767, and 0874.) The ID number for a given entry in the first array refers to an entry in the second array. The third array is another size/location array similar to the first but based on the data file map.zon.

One interesting note about this block is that a small amount of corruption here causes the "Taxi Glitch" situation where the taxi mission always tells you there are no fares nearby no matter where you are. The problem is that the first entry of the first array (the SAN_AND zone describing the entire map) gets mangled and the taxi mission references that zone to pick a passenger. For more on this glitch and how to fix it, see the GTAForums thread on it.

OFFSET  TYPE        DESCRIPTION
0x0000  dword       current town (island)
0x0004  word        Number of entries for first ZoneInfo Array
0x0006  word        Number of entries for ZonePop Array
0x0008  word        Number of entries for second ZoneInfo Array
0x000A  ZoneInfo[]  Array populated from file data/info.zon
 ...
0x0000  ZonePop[]   Array of gang density and popcycle info 
 ...
0x0000  ZoneInfo[]  Array populated from file data/map.zon
 ...
0x0000  byte[104]   (Unknown)
ZoneInfo Structure:
  0x00  char[8]     zone name 
  0x08  char[8]     zone gxt key (for name displayed on-screen)
  0x10  word[3]     x1,y1,z1 (rounded to ints)
  0x16  word[3]     x2,y2,z2 (rounded to ints)
  0x1C  word        id
  0x1E  byte        type
  0x1F  byte        island
  0x20  (end)
ZonePop Structure:
  0x00  byte        Gang 0 Density (set by opcode 076C)
  0x01  byte        Gang 1 Density (set by opcode 076C)
  0x02  byte        Gang 2 Density (set by opcode 076C)
  0x03  byte        Gang 3 Density (set by opcode 076C)
  0x04  byte        Gang 4 Density (set by opcode 076C)
  0x05  byte        Gang 5 Density (set by opcode 076C)
  0x06  byte        Gang 6 Density (set by opcode 076C)
  0x07  byte        Gang 7 Density (set by opcode 076C)
  0x08  byte        Gang 8 Density (set by opcode 076C)
  0x09  byte        Gang 9 Density (set by opcode 076C)
  0x0A  byte        Zone "Wealth" (set by opcode 076A)
  0x0B  byte[4]     RBGA color of zone on map/radar
  0x0F  byte        Popcycle Group (set by opcode 0767)
  0x10  byte        Ped-related (set by opcode 0874)
  0x11  (end)

Block 11: Gang Weapons

OFFSET  TYPE            DESCRIPTION
0x0000  GangWeapons[10] GangWeapons structures -- each is 0x10 bytes in size; see details below
0x00a0  (end)
GangWeapons[]           
  0x00  byte[4]         unused
  0x04  dword           weaponID A
  0x08  dword           weaponID B
  0x0c  dword           weaponID C
  0x10  (end)

Notes:

  1. Data can be changed by opcode 0237

Block 12: Car Generators

  0    dword           count
  6                    car generators
---- numberplates:
  0    dword           num entries used
  4    Numplate[15]    number plates
 f4                    end
Car generator structure:
  0    word            handle (0..499)
  2    word            model
  4    byte[2]         colors
  6    word[3]         x,y,z, all multiplied by 8
  c    byte            heading/360*256
  d    byte            alarm chance
  e    byte            locked chance
  f    byte            flags: bit 2=force spawn, bit 8=player owned
 12    word            monetary value
 16    dword           timer
 1c    word            cars to generate
 22                    end
  
Numplate structure:
  0    dword           car generator handle
  4    char[8]         numberplate string
 10                    end

Block 13: (Unused)

(Usually Empty)

Block 14: (Unused)

(Usually Empty)

Block 15: Player data

 00    dword           size of block (always 28h)
 04    dword           money
 08    word            (unknown)
 0A    byte            is wasted_or_busted flag
 0C    dword           (unknown)
 10    dword           amount of money shown on screen
 ...
 20    byte            infinite run (opcode 0330)
 21    byte            fast reload (opcode 0331) 
 22    byte            fireproof (055D)
 23    byte            unknown(health)
 24    byte            max armor (opcode 055F)
 ...
 2c                    end

Block 16: Stats

  0    float[82]       float stats (numbered 0..81 in scm)
148    dword[223]      int stats (numbered 120..342 in scm)
4c4    dword[32]
544    char[8]         last mission passed (gxt key)
54c    byte[56]
584    dword[100]
714    byte[128]
794                    end

Block 17: Police trigger zones

OFFSET  TYPE                   DESCRIPTION
0x0000  dword                  Number of Police trigger zones 
0x0004  PoliceTriggerZone[210] Trigger structures -- each is 0x20 bytes in size; see details below
0x1A44                         end
PoliceTriggerZone
  0x0000  dword                trigger last activation time
  0x0004  word[2]              player vehicle zone point 1 (x,y) -- all multiplied by 8
  0x0008  word[2]              player vehicle zone point 2 (x,y) -- all multiplied by 8
  0x000C  word[2]              police vehicle 1 zone point 1 (x,y) -- all multiplied by 8
  0x0010  word[2]              police vehicle 1 zone point 2 (x,y) -- all multiplied by 8
  0x0014  word[2]              police vehicle 2 zone point 1 (x,y) -- all multiplied by 8
  0x0018  word[2]              police vehicle 2 zone point 2 (x,y) -- all multiplied by 8
  0x001C  byte                 type -- unknown meaning, various requirements for the trigger to be activated
  0x001D  byte[3]              (align)
  0x0020                       end

Notes:

  1. Police trigger zone is a special zone consisting of 3 rectangles. When player drive into the first rectangle (defined by 2 ends of the rectange diagonal set by the first 2 XY pairs) having a certain wanted level (depends on the 'type' field), two police cars appear there: one in the second rectangle, the second car in the third rectangle. These rectangles are defined in the same manner as the player's one.
  2. Trigger zone can be created using opcode 04F8
  3. Trigger zone is activated only once per 40 seconds (the first field is used to control this).
  4. http://www.gtaforums.com/index.php?showtopic=260803

Block 18: Models

66cc                    end

Block 19: Ped Acquaintances

OFFSET  TYPE                       DESCRIPTION
0x000   PedAcquaintance[32]        PedAcquaintance structures, each is 20 bytes in size -- see details below
0x280   end
PedAcquaintance -- See notes below
  0x00  dword    respect bitmask
  0x04  dword    like bitmask
  0x08  dword    (unused)
  0x0C  dword    dislike bitmask
  0x10  dword    hate bitmask
  • This structure stores information about how a ped of given pedtype (each entry in PedAcquaintance[32] is separate pedtype, starting from 0 (PLAYER1) to 31 (MISSION8)) behaves toward any ped of other type. Five dwords in this structure (only four of them are used) are the bitmasks, where a bit sets a flag of acquaintance type (respect, like, dislike, hate) to the pedtype of given index (=number of bit). Say, if the 4th bit (counting from zero) in PedAcquaintance[5].respect is set, it means that a ped of type CIVFEMALE (pedtype=5) respects a ped of type CIVMALE (pedtype=4).
  • These structures are filled with data from the file ped.dat. The acquaintances flags could be changed via scripts (using opcode 0746 and similar).

Block 20: Tags

  0    dword           total number of the tags 
  4    byte[]          tags paint status (0-255)

Block 21: IPL

 00    dword
 04    byte[255]       (mostly unknown)
 05    byte            BARRIERS1         v1 Barriers to SF
 06    byte            BARRIERS2         v1 Barriers to LV
 2D    byte            CRACK             v2 Pre-Yay Ka-Boom Boom Factory (45)
 31    byte            TRUTHSFARM        v1 Crops at Truth's Farm (49)
 3E    byte            CRACK             v1 Pre-Yay Ka-Boom Boom Factory (62)
 3E    byte            TRUTHSFARM        v2 Crops at Truth's Farm (62)
 3F    byte            BARRIERS1         v2 Barriers to SF (63)
 40    byte            BARRIERS2         v2 Barriers to LV (64)
 52    byte            CARTER            v2 1st Floor of Smoke's Palace (82)
 7F    byte            CARTER            v1 1st Floor of Smoke's Palace (127)
103                    end

Block 22: Shopping

  0    dword           count
  4                    entries (8 bytes each)
----
  0    dword           size
  4                    bytes

Block 23: Gang wars

  0    dword           size of block (always 58h)
  4    byte            enable gang wars (opcode 0879)
 5c                    end

Block 24: Unique Stunt Jumps

OFFSET  TYPE        DESCRIPTION
0x0000  dword       Number of Unique Stunt Jumps (USJ)
0x0004  StuntJump[] Jump structures -- each is 0x44 bytes in size; see details below
StuntJump -- See note below
  0x00  float[3]    Start zone point 1 (x,y,z)
  0x0C  float[3]    Start zone point 2 (x,y,z)
  0x18  float[3]    Land zone point 1 (x,y,z)
  0x24  float[3]    Land zone point 2 (x,y,z)
  0x30  float[3]    Camera coordinates (x,y,z)
  0x3C  dword       Reward amount (can be negative)
  0x40  byte        Boolean: is USJ done
  0x41  byte        Boolean: is USJ found
  0x42  byte[2]     (Align)

The starting and landing zones are cubes; each is defined by 2 points -- point 1 is the lower, left, front of the cube and point 2 is the upper, right, rear. These cubes are aligned with the coordinate axes and not rotated at all. If a vehicle enters the starting zone while airborne, the USJ triggers (and is marked as 'found'); if the vehicle then lands inside the landing zone, the USJ is successful (and is marked as 'done') and the reward is given.

Block 25: ENEX Connections

  0    dword           count
  4                    array of words
----
  Structure:
  0    word            source id
  2    word            flags
  4    word            destination id
----
Followed by a weird array:
1. Read a word.
2. If it is -1, you've reached the end of this block.
3. Otherwise, it's an index. Read two more words for this entry and go back to 1.

Block 26: Missions data

0x000 Structure[14]   -- see details below
0xEE0 byte            availables cities number (stat 181)
0xEE1 byte            least favorite radio (stat 327)
0xEE2 byte            current weapon skill (stat 328)
0xEE3 byte            weapon skill levels (stat 329)
0xEE4 byte            "Local Liquor Store" mission accomplished  (stat 318)
0xEE5 byte            playing time (stat 320)
0xEE6 byte            pilot ranking (stat 330)
0xEE7 byte            strongest gang  (stat 331)
0xEE8 byte            2nd strongest gang (stat 332)
0xEE9 byte            3rd strongest gang (stat 333)
0xEEA byte            "Mike Toreno" mission accomplished (stat 311)
0xEEB byte            least favorite gang (stat 323)
0xEEC byte            "A Home In The Hills" mission accomplished  (stat 308)
0xEED byte            "Robbing Uncle Sam" mission accomplished  (stat 310)
0xEEE byte            (stat 335)
0xEEF byte            gang strength (stat 336)
0xEF0 byte            territory under control (stat 337)
0xEF1 byte            "Drive-thru" mission accomplished (stat 302)
0xEF2 byte            "Are you going to San Fierro?" mission accomplished  (stat 338)
0xEF3 byte            "High Noon" mission accomplished (stat 339)
0xEF4 byte            "The Green Sabre" mission accomplished  (stat 340)
0xEF5 byte            (stat 341)
0xEF6 byte            (stat 342)
0xEF7 byte            month day when the stats above were updated
0xEF8 byte            hour when the stats above were updated
0xEF9 byte            hours to the next stats update (commonly 24 or 168)
0xEFA byte            updating flag (1,2,3)
0xEFB byte            last updated stat (in accordance with the given order)
0xEFC                 end
Structure:
0x000 byte[20]
0x014    dword[8]
0x034    dword[40]
0x0D4    dword[15]
0x110    end

Block 27: Entrance markers

Template:ClassTableHeader |0x00||CEntranceMarker[5]||entrance markers||can be created by opcode 0A40 Template:ClassTableFooter


CEntranceMarker Template:ClassTableHeader |0x00||dword||existance status |- |0x04||float[3]||position|| |- |0x10||dword||color R|| |- |0x14||dword||color G|| |- |0x18||dword||color B|| Template:ClassTableFooter

Padding

Following the last data block is a variable amount of padding. Since every save file is exactly 0x31800 bytes in length this padding is necessary to fill the space between the data blocks which start the file and the checksum value which ends it. Because GTASA internally uses a buffer of 0xC800 bytes for writing a save, each byte of padding data is simply a repetition of the data located 0xC800 bytes before it. While it is not strictly necessary to follow this convention for the padding when writing a modified save file, it is consistent with the original game and makes modifications harder to detect.

Checksum

The final four bytes of a save file are an unsigned integer checksum value. This checksum is simply the sum of all the preceding 0x317FC bytes. If the checksum value does not match the calculated sum of those bytes, the game will consider the save file to be "corrupted" and refuse to load it. Thus, any time you make any changes to a save file you must remember to update the checksum when you are finished.