Ocarina of Time: Save Format

From z64 wiki
Jump to: navigation, search

Info

The Ocarina of Time save file consists of a simple 32 byte long header, and six 0x1450 byte long game files, in the order 1,2,3/1,2,3. The header can be freely edited. The individual game files cannot without recalculating the checksum.

File Header

Offset Data Type Length Usage Additional Info
0x00 Sound Options
0x01 Z-Target Options 0 for Switch, 1 for Hold
0x07 String 5 Contains the text "ZELDA"
0x0C uint32_t 4 0xABABABAB if debug, 0x00000000 if 1.0U+ (may be different for J/E)

Game Data

After the file header, there are 6 different game files, one backup for each save file to prevent file corruption. They are stored in the order 1-2-3, 1-2-3

RAM Offsets

Saves are created by simply copying a specific block of ram. Therefore, it's possible to determine what the values stored in the save file do by peeking into the RAM in-game instead of making multiple saves. To convert an offset from the start of the save file to a ram address, simply take the appropriate offset for your game (ex. 1.0 U, 11A5D0), and an offset from the following table (ex. Respawn Point, 0x0002), and add them together (11A5D2). To convert it into a cheat, prefix it with either 80 (modify 1 byte) or 81 (modify 2 bytes), and assign a value to it (ex. 8111A5D2 0000)

Save Data Relative to Ram
Debug E NTSC 1.0 NTSC 1.1 NTSC 1.2 PAL 1.0 PAL 1.1
15E660 11A5D0 11A790 11AC80 1183D0 118410

Checksum

Each segment of game data has a 16 bit checksum at offset 0x1352. It is generated by adding all previous 0x9A9 shorts together, and simply allowing the count to roll over. Values located past the checksum are stored to sram but are not copied back when loading the save, and thus go unused.

Game Data Format

Offset Data Type Length Usage Additional Info
0x0002 uint16_t 2 Entrance index Stores the entrance Link starts/respawns at. See Debug ROM: Exit List for a listing of all values. If not inside a dungeon when loading a save from file, this value defaults back to either 00BB (Deku Tree) or 0053 (Temple of Time)
0x0004 uint32_t 4 Age Modifier 0 = Adult Link, 1 = Child Link
0x001C String 6 Unknown Contains the string "ZELDAZ". If different, the save will be considered corrupt even if the checksum is valid
0x0022 Short 2 Death Counter
0x0024 String 8 Player Name If the player name is less than 8 characters, the remaining char values will be DF. Charsets vary by language.
0x002C uint32_t 4 Heart containers 0x10 is equivalent to 1 heart container
0x0030? ??? 1-2? Disk Drive Only flag Setting to 1 will flag the save as a Disk Drive only file. The file cannot be accessed normally (but can be forced), and will crash on copy/erase attempt on a release build
0x0032 uint32_t 4 Health 0x10 is equivalent to 1 full heart
0x0036 uint32_t 4 Rupees
0x003A uint16_t 2 Some clock? Increments every cycle, unless the game is paused. Resets whenever a new map is loaded
0x00D4 struct 0x1C * 101 Permanent Scene Flags Stores the permanent flags for all scenes. See below.
0x0E64 32? Farore's Wind Warp If modifying values in-game, the warp point must be unloaded for the new values to take effect
0x0E64 Long X Coordinate
0x0E68 Long Y Coordinate
0x0E6B Long Z Coordinate
0x0E72 Short Y-Axis Rotation Direction that Link Faces on returning
0x0E7A uint16_t Entrance Index Determines which scene Link is transported to. See Zelda 64 Scene Listings.
0x0E7F Map Number Determines which map of the scene to load
0x0E83 Warp Point Set 1 = Warp point set, 0 = unset.
0x1352 uint16_t 2 Checksum Checksum of previous 0x9A9 shorts (0x1352 bytes)

Permanent Scene Flags Format

The structure for the scene related save data. Located at offset 0xD4 into the save file. Each record is 0x1C bytes long. There are 101 records, one for each scene.

offset type use description
0000 Int32 Chest Flags Set exclusively by chest actors. see actor list for setting this value
0004 Int32 Switches Stores most other other dungeon progression related flags such as locked doors, switches.
0008 Int32 Room Clear Flags Stores the room clear flags, preventing most enemies from spawning. One bit is reserved for each room, thus giving a limit of 32 rooms.
000C Int32 Collectible Flags Stores whether a particular collectable item (like Heart Containers, Key Item) has been obtained permanently
0010 Int32 Unused
0014 Int64 Visited Rooms Stores what rooms have been visited, for when displaying the map screen in dungeons.

C structs/functions

Beware of endianess! Big endian (N64 native) assumed.

#define	LINK_ADULT	0
#define LINK_CHILD	1

typedef struct
{
    uint32_t	respawn_exit_n;	/* 0x0004 */
    uint32_t	age;		/* 0x0008 */
    uint8_t	__pad_00[0x014];/* 0x001C */
    char	str[5];		/* 0x0021   "ZELDA" in created file */
    uint8_t	__pad_01[0x001];/* 0x0022 */
    uint16_t	death_count;	/* 0x0024 */
    uint8_t	name[8];	/* 0x002C Special char encoding */
    uint8_t     __pad_02[0x006];/* 0x0032 */
    uint32_t    rupee_count;    /* 0x0036 */
    uint8_t	__pad_03[0x002];/* 0x0038 */
    uint16_t	scene_count;	/* 0x003A May be uint32_t */
    uint8_t	__pad_04[0xE2A];/* 0x0E64 */
    struct
    {
    	float		x, y, z;	/* 0x0E70 */
    	uint16_t	y_rot;		/* 0x0E72 */
    	uint8_t		__pad_00[0x8];	/* 0x0E7A */
    	uint16_t	scene_no;	/* 0x0E7C */
    	uint32_t	map_no;		/* 0x0E80 */
    	uint32_t	isset;		/* 0x0E84 */
    }
    farore_warp;
    uint8_t	__pad_05[0x4CE];/* 0x1352 */
    uint16_t	chksum;		/* 0x1354 */
    uint8_t	__pad_06[0x0FC];/* 0x1540 */
}
z_save_file;

typedef struct
{
    uint8_t sound_opt;
    uint8_t ztarget_opt;
    char tag[5]; /* "ZELDA" (not null terminated) */
    z_save_file files[3];
}
z_save;

void
calc_chksum( z_save_file *f )
{
    int16_t *data = (int16_t*)(f);
    int sum = 0;
    int i;
    
    f->chksum = 0;

    for( i = 0; i < 0x9A9; i++ )
    {
        sum += data[i];
        sum &= 0xFFFF;
    }
    
    f->chksum = (uint16_t)sum;
}