summaryrefslogtreecommitdiff
path: root/include/save.h
diff options
context:
space:
mode:
authorfig02 <fig02srl@gmail.com>2025-06-04 14:38:33 -0400
committerGitHub <noreply@github.com>2025-06-04 14:38:33 -0400
commit28cc9d68cfe4a037eb232d5465b84a943539bca3 (patch)
tree4001d36dccb035576f3cbf17cf9a548cdc9c5b3f /include/save.h
parente8b708a4480e568f409c8e53986c2e96595b9405 (diff)
Remove "z64" prefix from all headers (#2518)
* z64 - a * z64 - b * z64 - c * z64 - d * z64 - e * z64 - f * z64 - g * z64 - h * z64 - i * z64 - l * z64 - m * z64 - o * z64 - p * z64 - q * z64 - r * z64 - s * z64 - t * z64 - v * restore file * fix merge * fix merge --------- Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>
Diffstat (limited to 'include/save.h')
-rw-r--r--include/save.h1000
1 files changed, 1000 insertions, 0 deletions
diff --git a/include/save.h b/include/save.h
new file mode 100644
index 000000000..a4e99546f
--- /dev/null
+++ b/include/save.h
@@ -0,0 +1,1000 @@
+#ifndef SAVE_H
+#define SAVE_H
+
+#include "ultra64.h"
+#include "versions.h"
+#include "inventory.h"
+#include "z_math.h"
+
+typedef enum ZTargetSetting {
+ /* 0 */ Z_TARGET_SETTING_SWITCH,
+ /* 1 */ Z_TARGET_SETTING_HOLD
+} ZTargetSetting;
+
+typedef enum Language {
+#if OOT_NTSC
+ /* 0 */ LANGUAGE_JPN,
+ /* 1 */ LANGUAGE_ENG,
+#else
+ /* 0 */ LANGUAGE_ENG,
+ /* 1 */ LANGUAGE_GER,
+ /* 2 */ LANGUAGE_FRA,
+#endif
+ /* */ LANGUAGE_MAX
+} Language;
+
+// `_FORCE` means that this request will respond to `forceRisingButtonAlphas`.
+// If set, the buttons will also raise alphas but will also account for disabled buttons
+
+typedef enum HudVisibilityMode {
+ /* 0 */ HUD_VISIBILITY_NO_CHANGE,
+ /* 1 */ HUD_VISIBILITY_NOTHING,
+ /* 2 */ HUD_VISIBILITY_NOTHING_ALT, // Identical to HUD_VISIBILITY_NOTHING
+ /* 3 */ HUD_VISIBILITY_HEARTS_FORCE, // See above
+ /* 4 */ HUD_VISIBILITY_A,
+ /* 5 */ HUD_VISIBILITY_A_HEARTS_MAGIC_FORCE, // See above
+ /* 6 */ HUD_VISIBILITY_A_HEARTS_MAGIC_MINIMAP_FORCE, // See above
+ /* 7 */ HUD_VISIBILITY_ALL_NO_MINIMAP_BY_BTN_STATUS, // Only raises button alphas if not disabled
+ /* 8 */ HUD_VISIBILITY_B,
+ /* 9 */ HUD_VISIBILITY_HEARTS_MAGIC,
+ /* 10 */ HUD_VISIBILITY_B_ALT, // Identical to HUD_VISIBILITY_B
+ /* 11 */ HUD_VISIBILITY_HEARTS,
+ /* 12 */ HUD_VISIBILITY_A_B_MINIMAP,
+ /* 13 */ HUD_VISIBILITY_HEARTS_MAGIC_FORCE, // See above
+ /* 50 */ HUD_VISIBILITY_ALL = 50, // Only raises button alphas if not disabled
+ /* 52 */ HUD_VISIBILITY_NOTHING_INSTANT = 52
+} HudVisibilityMode;
+
+typedef enum MagicState {
+ /* 0x0 */ MAGIC_STATE_IDLE, // Regular gameplay
+ /* 0x1 */ MAGIC_STATE_CONSUME_SETUP, // Sets the speed at which magic border flashes
+ /* 0x2 */ MAGIC_STATE_CONSUME, // Consume magic until target is reached or no more magic is available
+ /* 0x3 */ MAGIC_STATE_METER_FLASH_1, // Flashes border and freezes Dark Link
+ /* 0x4 */ MAGIC_STATE_METER_FLASH_2, // Flashes border and draws yellow magic to preview target consumption
+ /* 0x5 */ MAGIC_STATE_RESET, // Reset colors and return to idle
+ /* 0x6 */ MAGIC_STATE_METER_FLASH_3, // Flashes border with no additional behaviour
+ /* 0x7 */ MAGIC_STATE_CONSUME_LENS, // Magic slowly consumed by lens.
+ /* 0x8 */ MAGIC_STATE_STEP_CAPACITY, // Step `magicCapacity` to full capacity
+ /* 0x9 */ MAGIC_STATE_FILL, // Add magic until magicFillTarget is reached.
+ /* 0xA */ MAGIC_STATE_ADD // Add requested magic
+} MagicState;
+
+typedef enum MagicChangeType {
+ /* 0 */ MAGIC_CONSUME_NOW, // Consume Magic immediately without preview
+ /* 1 */ MAGIC_CONSUME_WAIT_NO_PREVIEW, // Sets consume target but waits to consume. No yellow magic preview to target consumption. Unused
+ /* 2 */ MAGIC_CONSUME_NOW_ALT, // Identical behaviour to MAGIC_CONSUME_NOW. Unused
+ /* 3 */ MAGIC_CONSUME_LENS, // Lens consumption
+ /* 4 */ MAGIC_CONSUME_WAIT_PREVIEW, // Sets consume target but waits to consume. Draws yellow magic to target consumption
+ /* 5 */ MAGIC_ADD // Sets a target to add magic
+} MagicChangeType;
+
+#define MAGIC_NORMAL_METER 0x30
+#define MAGIC_DOUBLE_METER (2 * MAGIC_NORMAL_METER)
+
+typedef struct ItemEquips {
+ /* 0x00 */ u8 buttonItems[4];
+ /* 0x04 */ u8 cButtonSlots[3];
+ /* 0x08 */ u16 equipment; // a mask where each nibble corresponds to a type of equipment `EquipmentType`, and each nibble is a piece `EquipValue*`
+} ItemEquips; // size = 0x0A
+
+typedef struct Inventory {
+ /* 0x00 */ u8 items[24];
+ /* 0x18 */ s8 ammo[16];
+ /* 0x28 */ u16 equipment; // a mask where each nibble corresponds to a type of equipment `EquipmentType`, and each bit to an owned piece `EquipInv*`
+ /* 0x2C */ u32 upgrades;
+ /* 0x30 */ u32 questItems;
+ /* 0x34 */ u8 dungeonItems[20];
+ /* 0x48 */ s8 dungeonKeys[19];
+ /* 0x5B */ s8 defenseHearts;
+ /* 0x5C */ s16 gsTokens;
+} Inventory; // size = 0x5E
+
+typedef struct Checksum {
+ /* 0x00 */ u16 value;
+} Checksum; // size = 0x02
+
+typedef struct SavedSceneFlags {
+ /* 0x00 */ u32 chest;
+ /* 0x04 */ u32 swch;
+ /* 0x08 */ u32 clear;
+ /* 0x0C */ u32 collect;
+ /* 0x10 */ u32 unk;
+ /* 0x14 */ u32 rooms;
+ /* 0x18 */ u32 floors;
+} SavedSceneFlags; // size = 0x1C
+
+typedef struct HorseData {
+ /* 0x00 */ s16 sceneId;
+ /* 0x02 */ Vec3s pos;
+ /* 0x08 */ s16 angle;
+} HorseData; // size = 0x0A
+
+/**
+ * The respawn mode names refer to the perceived player movement when respawning
+ * "down": being on ground
+ * "return": coming from the ground
+ * "top": coming from the air
+ */
+typedef enum RespawnMode {
+ /* 0x00 */ RESPAWN_MODE_DOWN, /* Normal Void Outs */
+ /* 0x01 */ RESPAWN_MODE_RETURN, /* Grotto Returnpoints */
+ /* 0x02 */ RESPAWN_MODE_TOP, /* Farore's Wind */
+ /* 0x03 */ RESPAWN_MODE_MAX
+} RespawnMode;
+
+typedef struct RespawnData {
+ /* 0x00 */ Vec3f pos;
+ /* 0x0C */ s16 yaw;
+ /* 0x0E */ s16 playerParams;
+ /* 0x10 */ s16 entranceIndex;
+ /* 0x12 */ u8 roomIndex;
+ /* 0x13 */ s8 data;
+ /* 0x14 */ u32 tempSwchFlags;
+ /* 0x18 */ u32 tempCollectFlags;
+} RespawnData; // size = 0x1C
+
+typedef struct FaroresWindData {
+ /* 0x00 */ Vec3i pos;
+ /* 0x0C */ s32 yaw;
+ /* 0x10 */ s32 playerParams;
+ /* 0x14 */ s32 entranceIndex;
+ /* 0x18 */ s32 roomIndex;
+ /* 0x1C */ s32 set;
+ /* 0x20 */ s32 tempSwchFlags;
+ /* 0x24 */ s32 tempCollectFlags;
+} FaroresWindData; // size = 0x28
+
+typedef enum TimerState {
+ /* 0x0 */ TIMER_STATE_OFF,
+ /* 0x1 */ TIMER_STATE_ENV_HAZARD_INIT, // Init env timer that counts down, total time based on health, resets on void-out, kills at 0
+ /* 0x2 */ TIMER_STATE_ENV_HAZARD_PREVIEW, // Display initial time, keep it fixed at the screen center
+ /* 0x3 */ TIMER_STATE_ENV_HAZARD_MOVE, // Move to top-left corner
+ /* 0x4 */ TIMER_STATE_ENV_HAZARD_TICK, // Counting down
+ /* 0x5 */ TIMER_STATE_DOWN_INIT, // Init timer that counts down
+ /* 0x6 */ TIMER_STATE_DOWN_PREVIEW, // Display initial time, keep it fixed at the screen center
+ /* 0x7 */ TIMER_STATE_DOWN_MOVE, // Move to top-left corner
+ /* 0x8 */ TIMER_STATE_DOWN_TICK, // Counting down
+ /* 0xA */ TIMER_STATE_STOP = 10,
+ /* 0xB */ TIMER_STATE_UP_INIT, // Init timer that counts up
+ /* 0xC */ TIMER_STATE_UP_PREVIEW, // Display initial time, keep it fixed at the screen center
+ /* 0xD */ TIMER_STATE_UP_MOVE, // Move to top-left corner
+ /* 0xE */ TIMER_STATE_UP_TICK, // Counting up
+ /* 0xF */ TIMER_STATE_UP_FREEZE // Stop counting the timer
+} TimerState;
+
+typedef enum SubTimerState {
+ /* 0x0 */ SUBTIMER_STATE_OFF,
+ /* 0x1 */ SUBTIMER_STATE_DOWN_INIT, // Init timer that counts down
+ /* 0x2 */ SUBTIMER_STATE_DOWN_PREVIEW, // Display initial time, keep it fixed at the screen center
+ /* 0x3 */ SUBTIMER_STATE_DOWN_MOVE, // Move to top-left corner
+ /* 0x4 */ SUBTIMER_STATE_DOWN_TICK, // Counting down
+ /* 0x5 */ SUBTIMER_STATE_RESPAWN, // Time is up, trigger a transition, reset button items, spoil trade quest items
+ /* 0x6 */ SUBTIMER_STATE_STOP, // Time is up, stop counting
+ /* 0x7 */ SUBTIMER_STATE_UP_INIT, // Init timer that counts up
+ /* 0x8 */ SUBTIMER_STATE_UP_PREVIEW, // Display initial time, keep it fixed at the screen center
+ /* 0x9 */ SUBTIMER_STATE_UP_MOVE, // Move to top-left corner
+ /* 0xA */ SUBTIMER_STATE_UP_TICK // Counting up
+} SubTimerState;
+
+typedef enum TimerId {
+ /* 0 */ TIMER_ID_MAIN, // Takes priority in both counting and drawing. See `timerState` and `timerSeconds`
+ /* 1 */ TIMER_ID_SUB, // See `subTimerState` and `subTimerSeconds`
+ /* 2 */ TIMER_ID_MAX
+} TimerId;
+
+#define MARATHON_TIME_LIMIT 240 // 4 minutes
+
+#define ENV_HAZARD_TEXT_TRIGGER_HOTROOM (1 << 0)
+#define ENV_HAZARD_TEXT_TRIGGER_UNDERWATER (1 << 1)
+
+typedef enum WorldMapArea {
+ /* 0 */ WORLD_MAP_AREA_HYRULE_FIELD,
+ /* 1 */ WORLD_MAP_AREA_KAKARIKO_VILLAGE,
+ /* 2 */ WORLD_MAP_AREA_GRAVEYARD,
+ /* 3 */ WORLD_MAP_AREA_ZORAS_RIVER,
+ /* 4 */ WORLD_MAP_AREA_KOKIRI_FOREST,
+ /* 5 */ WORLD_MAP_AREA_SACRED_FOREST_MEADOW,
+ /* 6 */ WORLD_MAP_AREA_LAKE_HYLIA,
+ /* 7 */ WORLD_MAP_AREA_ZORAS_DOMAIN,
+ /* 8 */ WORLD_MAP_AREA_ZORAS_FOUNTAIN,
+ /* 9 */ WORLD_MAP_AREA_GERUDO_VALLEY,
+ /* 10 */ WORLD_MAP_AREA_LOST_WOODS,
+ /* 11 */ WORLD_MAP_AREA_DESERT_COLOSSUS,
+ /* 12 */ WORLD_MAP_AREA_GERUDOS_FORTRESS,
+ /* 13 */ WORLD_MAP_AREA_HAUNTED_WASTELAND,
+ /* 14 */ WORLD_MAP_AREA_MARKET,
+ /* 15 */ WORLD_MAP_AREA_HYRULE_CASTLE,
+ /* 16 */ WORLD_MAP_AREA_DEATH_MOUNTAIN_TRAIL,
+ /* 17 */ WORLD_MAP_AREA_DEATH_MOUNTAIN_CRATER,
+ /* 18 */ WORLD_MAP_AREA_GORON_CITY,
+ /* 19 */ WORLD_MAP_AREA_LON_LON_RANCH,
+ /* 20 */ WORLD_MAP_AREA_QUESTION_MARK, // Windmill/Dampé's Grave (and a Lon Lon Ranch cutscene). Labeled as "?"
+ /* 21 */ WORLD_MAP_AREA_GANONS_CASTLE,
+ /* 22 */ WORLD_MAP_AREA_MAX // also grottos and fairy's/great fairy's fountains (scenes with varying locations)
+} WorldMapArea;
+
+// offsets in SavePlayerData and SaveContext/Save
+typedef struct SavePlayerData {
+ /* 0x00 0x001C */ char newf[6]; // string "ZELDAZ"
+ /* 0x06 0x0022 */ u16 deaths;
+ /* 0x08 0x0024 */ u8 playerName[8];
+ /* 0x10 0x002C */ s16 n64ddFlag;
+ /* 0x12 0x002E */ s16 healthCapacity; // "max_life"
+ /* 0x14 0x0030 */ s16 health; // "now_life"
+ /* 0x16 0x0032 */ s8 magicLevel; // 0 for no magic/new load, 1 for magic, 2 for double magic
+ /* 0x17 0x0033 */ s8 magic; // current magic available for use
+ /* 0x18 0x0034 */ s16 rupees;
+ /* 0x1A 0x0036 */ u16 swordHealth;
+ /* 0x1C 0x0038 */ u16 naviTimer;
+ /* 0x1E 0x003A */ u8 isMagicAcquired;
+ /* 0x1F 0x003B */ char unk_3B[0x01];
+ /* 0x20 0x003C */ u8 isDoubleMagicAcquired;
+ /* 0x21 0x003D */ u8 isDoubleDefenseAcquired;
+ /* 0x22 0x003E */ u8 bgsFlag;
+ /* 0x23 0x003F */ u8 ocarinaGameRoundNum;
+ /* 0x24 0x0040 */ ItemEquips childEquips;
+ /* 0x2E 0x004A */ ItemEquips adultEquips;
+ /* 0x38 0x0054 */ u32 unk_54; // this may be incorrect, currently used for alignment
+ /* 0x3C 0x0058 */ char unk_58[0x0E];
+ /* 0x4A 0x0066 */ s16 savedSceneId;
+} SavePlayerData;
+
+// offsets in SaveInfo and SaveContext/Save
+typedef struct SaveInfo {
+ /* 0x0000 0x001C */ SavePlayerData playerData; // "S_Private"
+ /* 0x004C 0x0068 */ ItemEquips equips;
+ /* 0x0058 0x0074 */ Inventory inventory;
+ /* 0x00B8 0x00D4 */ SavedSceneFlags sceneFlags[124];
+ /* 0x0E48 0x0E64 */ FaroresWindData fw;
+ /* 0x0E70 0x0E8C */ char unk_E8C[0x10];
+ /* 0x0E80 0x0E9C */ s32 gsFlags[6];
+ /* 0x0E98 0x0EB4 */ char unk_EB4[0x4];
+ /* 0x0E9C 0x0EB8 */ s32 highScores[7];
+ /* 0x0EB8 0x0ED4 */ u16 eventChkInf[14]; // "event_chk_inf"
+ /* 0x0ED4 0x0EF0 */ u16 itemGetInf[4]; // "item_get_inf"
+ /* 0x0EDC 0x0EF8 */ u16 infTable[30]; // "inf_table"
+ /* 0x0F18 0x0F34 */ char unk_F34[0x04];
+ /* 0x0F1C 0x0F38 */ u32 worldMapAreaData; // "area_arrival"
+ /* 0x0F20 0x0F3C */ char unk_F3C[0x4];
+ /* 0x0F24 0x0F40 */ u8 scarecrowLongSongSet;
+ /* 0x0F25 0x0F41 */ u8 scarecrowLongSong[0x360];
+ /* 0x1285 0x12A1 */ char unk_12A1[0x24];
+ /* 0x12A9 0x12C5 */ u8 scarecrowSpawnSongSet;
+ /* 0x12AA 0x12C6 */ u8 scarecrowSpawnSong[0x80];
+ /* 0x132A 0x1346 */ char unk_1346[0x02];
+ /* 0x132C 0x1348 */ HorseData horseData;
+ /* 0x1336 0x1352 */ Checksum checksum; // "check_sum"
+} SaveInfo;
+
+typedef struct Save {
+ /* 0x00 */ s32 entranceIndex;
+ /* 0x04 */ s32 linkAge; // 0: Adult; 1: Child (see enum `LinkAge`)
+ /* 0x08 */ s32 cutsceneIndex;
+ /* 0x0C */ u16 dayTime; // "zelda_time"
+ /* 0x10 */ s32 nightFlag;
+ /* 0x14 */ s32 totalDays;
+ /* 0x18 */ s32 bgsDayCount; // increments with totalDays, can be cleared with `Environment_ClearBgsDayCount`
+ /* 0x1C */ SaveInfo info; // "information"
+} Save;
+
+typedef struct SaveContext {
+ /* 0x0000 */ Save save; // "memory"
+ /* 0x1354 */ s32 fileNum; // "file_no"
+ /* 0x1358 */ char unk_1358[0x0004];
+ /* 0x135C */ s32 gameMode;
+ /* 0x1360 */ s32 sceneLayer; // "counter"
+ /* 0x1364 */ s32 respawnFlag; // "restart_flag"
+ /* 0x1368 */ RespawnData respawn[RESPAWN_MODE_MAX]; // "restart_data"
+ /* 0x13BC */ f32 entranceSpeed;
+ /* 0x13C0 */ u16 entranceSound;
+ /* 0x13C2 */ char unk_13C2[0x0001];
+ /* 0x13C3 */ u8 retainWeatherMode;
+ /* 0x13C4 */ s16 dogParams;
+ /* 0x13C6 */ u8 envHazardTextTriggerFlags;
+ /* 0x13C7 */ u8 showTitleCard;
+ /* 0x13C8 */ s16 nayrusLoveTimer;
+ /* 0x13CA */ char unk_13CA[0x0002];
+ /* 0x13CC */ s16 rupeeAccumulator;
+ /* 0x13CE */ s16 timerState; // See `TimerState`
+ /* 0x13D0 */ s16 timerSeconds;
+ /* 0x13D2 */ s16 subTimerState; // See `SubTimerState`
+ /* 0x13D4 */ s16 subTimerSeconds;
+ /* 0x13D6 */ s16 timerX[TIMER_ID_MAX];
+ /* 0x13DA */ s16 timerY[TIMER_ID_MAX];
+ /* 0x13DE */ char unk_13DE[0x0002];
+ /* 0x13E0 */ u8 seqId;
+ /* 0x13E1 */ u8 natureAmbienceId;
+ /* 0x13E2 */ u8 buttonStatus[5];
+ /* 0x13E7 */ u8 forceRisingButtonAlphas; // if btn alphas are updated through Interface_DimButtonAlphas, instead update them through Interface_RaiseButtonAlphas
+ /* 0x13E8 */ u16 nextHudVisibilityMode; // triggers the hud to change visibility mode to the requested value. Reset to HUD_VISIBILITY_NO_CHANGE when target is reached
+ /* 0x13EA */ u16 hudVisibilityMode; // current hud visibility mode
+ /* 0x13EC */ u16 hudVisibilityModeTimer; // number of frames in the transition to a new hud visibility mode. Used to step alpha
+ /* 0x13EE */ u16 prevHudVisibilityMode; // used to store and recover hud visibility mode for pause menu and text boxes
+ /* 0x13F0 */ s16 magicState; // determines magic meter behavior on each frame
+ /* 0x13F2 */ s16 prevMagicState; // used to resume the previous state after adding or filling magic
+ /* 0x13F4 */ s16 magicCapacity; // maximum magic available
+ /* 0x13F6 */ s16 magicFillTarget; // target used to fill magic. Target can either be full capacity (Magic_Fill, magic upgrades), or the saved magic amount (loading a file, game over)
+ /* 0x13F8 */ s16 magicTarget; // target for magic to step to when adding or consuming magic
+ /* 0x13FA */ u16 eventInf[4]; // "event_inf"
+ /* 0x1402 */ u16 mapIndex; // intended for maps/minimaps but commonly used as the dungeon index
+ /* 0x1404 */ u16 minigameState;
+ /* 0x1406 */ u16 minigameScore; // "yabusame_total"
+ /* 0x1408 */ char unk_1408[0x0001];
+ /* 0x1409 */ u8 language; // NTSC 0: Japanese; 1: English | PAL 0: English; 1: German; 2: French (see enum `Language`)
+ /* 0x140A */ u8 soundSetting; // 0: Stereo; 1: Mono; 2: Headset; 3: Surround (see enum `SoundSetting`)
+ /* 0x140B */ char unk_140B[0x0001];
+ /* 0x140C */ u8 zTargetSetting; // 0: Switch; 1: Hold (see enum `ZTargetSetting`)
+ /* 0x140E */ u16 forcedSeqId; // immediately start playing the sequence if set
+ /* 0x1410 */ u8 cutsceneTransitionControl; // context dependent usage: can either trigger a delayed fade or control fill alpha
+ /* 0x1411 */ char unk_1411[0x0001];
+ /* 0x1412 */ u16 nextCutsceneIndex;
+ /* 0x1414 */ u8 cutsceneTrigger;
+ /* 0x1415 */ u8 chamberCutsceneNum;
+ /* 0x1416 */ u16 nextDayTime; // "next_zelda_time"
+ /* 0x1418 */ u8 transFadeDuration;
+ /* 0x1419 */ u8 transWipeSpeed;
+ /* 0x141A */ u16 skyboxTime;
+ /* 0x141C */ u8 dogIsLost;
+ /* 0x141D */ u8 nextTransitionType;
+ /* 0x141E */ char unk_141E[0x0002];
+ /* 0x1420 */ s16 worldMapArea;
+ /* 0x1422 */ s16 sunsSongState; // controls the effects of suns song
+ /* 0x1424 */ s16 healthAccumulator;
+} SaveContext; // size = 0x1428
+
+typedef enum ButtonStatus {
+ /* 0x00 */ BTN_ENABLED,
+ /* 0xFF */ BTN_DISABLED = 0xFF
+} ButtonStatus;
+
+typedef enum ChamberCutsceneNum {
+ /* 0 */ CHAMBER_CS_FOREST,
+ /* 1 */ CHAMBER_CS_FIRE,
+ /* 2 */ CHAMBER_CS_WATER,
+ /* 3 */ CHAMBER_CS_SPIRIT,
+ /* 4 */ CHAMBER_CS_SHADOW,
+ /* 5 */ CHAMBER_CS_LIGHT
+} ChamberCutsceneNum;
+
+typedef enum HighScores {
+ /* 0x00 */ HS_HBA, // horseback archery
+ /* 0x01 */ HS_POE_POINTS,
+ /* 0x02 */ HS_FISHING,
+ /* 0x03 */ HS_HORSE_RACE,
+ /* 0x04 */ HS_MARATHON,
+ /* 0x05 */ HS_UNK_05,
+ /* 0x06 */ HS_DAMPE_RACE
+} HighScores;
+
+// the score value for the fishing minigame also stores many flags.
+#define HS_FISH_LENGTH_CHILD 0x7F // mask for record length of catch as child.
+#define HS_FISH_LENGTH_ADULT 0x7F000000 // mask for record length of catch as adult.
+#define HS_FISH_PLAYED_CHILD 0x100 // set when first talking to owner as child
+#define HS_FISH_PLAYED_ADULT 0x200 // set when first talking to owner as adult
+#define HS_FISH_PRIZE_CHILD 0x400 // won the Piece of Heart
+#define HS_FISH_PRIZE_ADULT 0x800 // won the Golden Scale
+#define HS_FISH_STOLE_HAT 0x1000 // Pond owner is visibly bald as Adult Link.
+#define HS_FISH_CHEAT_CHILD 0x80 // used Sinking Lure as child to catch record fish
+#define HS_FISH_CHEAT_ADULT 0x80000000 // used Sinking Lure as adult to catch record fish
+#define HS_FISH_PLAYED 0x10000 // incremented for every play. controls weather.
+
+typedef enum SunsSongState {
+ /* 0 */ SUNSSONG_INACTIVE,
+ /* 1 */ SUNSSONG_START, // the suns ocarina effect signals that the song has finished playing
+ /* 2 */ SUNSSONG_SPEED_TIME, // suns was played where time passes, speed up the advancement of time
+ /* 3 */ SUNSSONG_SPECIAL // time does not advance, but signals the song was played. used for freezing redeads
+} SunsSongState;
+
+typedef enum GameMode {
+ /* 0 */ GAMEMODE_NORMAL,
+ /* 1 */ GAMEMODE_TITLE_SCREEN,
+ /* 2 */ GAMEMODE_FILE_SELECT, // Note: only instance type transitions swap to file select
+ /* 3 */ GAMEMODE_END_CREDITS
+} GameMode;
+
+typedef enum SceneLayer {
+ /* 0 */ SCENE_LAYER_CHILD_DAY,
+ /* 1 */ SCENE_LAYER_CHILD_NIGHT,
+ /* 2 */ SCENE_LAYER_ADULT_DAY,
+ /* 3 */ SCENE_LAYER_ADULT_NIGHT,
+ /* 4 */ SCENE_LAYER_CUTSCENE_FIRST
+} SceneLayer;
+
+#define IS_CUTSCENE_LAYER (gSaveContext.sceneLayer >= SCENE_LAYER_CUTSCENE_FIRST)
+
+typedef enum LinkAge {
+ /* 0 */ LINK_AGE_ADULT,
+ /* 1 */ LINK_AGE_CHILD
+} LinkAge;
+
+
+#define LINK_IS_ADULT (gSaveContext.save.linkAge == LINK_AGE_ADULT)
+#define LINK_IS_CHILD (gSaveContext.save.linkAge == LINK_AGE_CHILD)
+
+#define YEARS_CHILD 5
+#define YEARS_ADULT 17
+#define LINK_AGE_IN_YEARS (!LINK_IS_ADULT ? YEARS_CHILD : YEARS_ADULT)
+
+#define CLOCK_TIME(hr, min) ((s32)(((hr) * 60 + (min)) * (f32)0x10000 / (24 * 60) + 0.5f))
+
+#define IS_DAY (gSaveContext.save.nightFlag == 0)
+#define IS_NIGHT (gSaveContext.save.nightFlag == 1)
+
+#define SLOT(item) gItemSlots[item]
+#define INV_CONTENT(item) gSaveContext.save.info.inventory.items[SLOT(item)]
+#define AMMO(item) gSaveContext.save.info.inventory.ammo[SLOT(item)]
+#define BEANS_BOUGHT AMMO(ITEM_MAGIC_BEAN + 1)
+
+#define ALL_EQUIP_VALUE(equip) ((s32)(gSaveContext.save.info.inventory.equipment & gEquipMasks[equip]) >> gEquipShifts[equip])
+#define CUR_EQUIP_VALUE(equip) ((s32)(gSaveContext.save.info.equips.equipment & gEquipMasks[equip]) >> gEquipShifts[equip])
+#define OWNED_EQUIP_FLAG(equip, value) (gBitFlags[value] << gEquipShifts[equip])
+#define OWNED_EQUIP_FLAG_ALT(equip, value) ((1 << (value)) << gEquipShifts[equip])
+#define CHECK_OWNED_EQUIP(equip, value) (gSaveContext.save.info.inventory.equipment & OWNED_EQUIP_FLAG(equip, value))
+#define CHECK_OWNED_EQUIP_ALT(equip, value) (gSaveContext.save.info.inventory.equipment & gBitFlags[(value) + (equip) * 4])
+
+#define SWORD_EQUIP_TO_PLAYER(swordEquip) (swordEquip)
+#define SHIELD_EQUIP_TO_PLAYER(shieldEquip) (shieldEquip)
+#define TUNIC_EQUIP_TO_PLAYER(tunicEquip) ((tunicEquip) - 1)
+#define BOOTS_EQUIP_TO_PLAYER(bootsEquip) ((bootsEquip) - 1)
+
+#define CUR_UPG_VALUE(upg) ((s32)(gSaveContext.save.info.inventory.upgrades & gUpgradeMasks[upg]) >> gUpgradeShifts[upg])
+#define CAPACITY(upg, value) gUpgradeCapacities[upg][value]
+#define CUR_CAPACITY(upg) CAPACITY(upg, CUR_UPG_VALUE(upg))
+
+#define CHECK_QUEST_ITEM(item) (gSaveContext.save.info.inventory.questItems & gBitFlags[item])
+#define CHECK_DUNGEON_ITEM(item, dungeonIndex) (gSaveContext.save.info.inventory.dungeonItems[dungeonIndex] & gBitFlags[item])
+
+#define GET_GS_FLAGS(index) \
+ ((gSaveContext.save.info.gsFlags[(index) >> 2] & gGsFlagsMasks[(index) & 3]) >> gGsFlagsShifts[(index) & 3])
+#define SET_GS_FLAGS(index, value) \
+ (gSaveContext.save.info.gsFlags[(index) >> 2] |= (value) << gGsFlagsShifts[(index) & 3])
+
+#define HIGH_SCORE(score) (gSaveContext.save.info.highScores[score])
+
+#define B_BTN_ITEM ((gSaveContext.buttonStatus[0] == ITEM_NONE) \
+ ? ITEM_NONE \
+ : (gSaveContext.save.info.equips.buttonItems[0] == ITEM_GIANTS_KNIFE) \
+ ? ITEM_SWORD_BIGGORON \
+ : gSaveContext.save.info.equips.buttonItems[0])
+
+#define C_BTN_ITEM(button) ((gSaveContext.buttonStatus[(button) + 1] != BTN_DISABLED) \
+ ? gSaveContext.save.info.equips.buttonItems[(button) + 1] \
+ : ITEM_NONE)
+
+
+/*
+ *
+ * SaveContext flags
+ *
+ */
+
+
+/*
+ * SaveContext.eventChkInf
+ */
+
+#define EVENTCHKINF_INDEX(flag) ((flag) >> 4)
+#define EVENTCHKINF_MASK(flag) (1 << ((flag) & 0xF))
+
+#define GET_EVENTCHKINF(flag) (gSaveContext.save.info.eventChkInf[EVENTCHKINF_INDEX(flag)] & EVENTCHKINF_MASK(flag))
+#define SET_EVENTCHKINF(flag) (gSaveContext.save.info.eventChkInf[EVENTCHKINF_INDEX(flag)] |= EVENTCHKINF_MASK(flag))
+#define CLEAR_EVENTCHKINF(flag) (gSaveContext.save.info.eventChkInf[EVENTCHKINF_INDEX(flag)] &= ~EVENTCHKINF_MASK(flag))
+
+// EVENTCHKINF 0x00-0x0F
+#define EVENTCHKINF_INDEX_0 0
+#define EVENTCHKINF_00_UNUSED 0x00 // flag is set in the debug save, but has no functionality
+#define EVENTCHKINF_01_UNUSED 0x01 // flag is set in the debug save, but has no functionality
+#define EVENTCHKINF_MIDO_DENIED_DEKU_TREE_ACCESS 0x02
+#define EVENTCHKINF_03 0x03
+#define EVENTCHKINF_04 0x04
+#define EVENTCHKINF_05 0x05
+#define EVENTCHKINF_07 0x07
+#define EVENTCHKINF_09 0x09
+#define EVENTCHKINF_0A 0x0A
+#define EVENTCHKINF_0B 0x0B
+#define EVENTCHKINF_0C 0x0C
+#define EVENTCHKINF_0F 0x0F
+#define EVENTCHKINF_TALKED_TO_MALON_FIRST_TIME 0x10
+#define EVENTCHKINF_11 0x11
+#define EVENTCHKINF_RECEIVED_WEIRD_EGG 0x12
+#define EVENTCHKINF_TALON_WOKEN_IN_CASTLE 0x13
+#define EVENTCHKINF_TALON_RETURNED_FROM_CASTLE 0x14
+#define EVENTCHKINF_TALKED_TO_CHILD_MALON_AT_RANCH 0x15
+#define EVENTCHKINF_CAN_LEARN_EPONAS_SONG 0x16
+#define EVENTCHKINF_EPONA_OBTAINED 0x18
+#define EVENTCHKINF_1B 0x1B
+#define EVENTCHKINF_1C 0x1C
+#define EVENTCHKINF_1D 0x1D
+#define EVENTCHKINF_HORSE_RACE_COW_UNLOCK 0x1E
+#define EVENTCHKINF_20 0x20
+#define EVENTCHKINF_21 0x21
+#define EVENTCHKINF_22 0x22
+#define EVENTCHKINF_23 0x23
+#define EVENTCHKINF_25 0x25
+#define EVENTCHKINF_2A 0x2A
+#define EVENTCHKINF_2B 0x2B
+#define EVENTCHKINF_2C 0x2C
+#define EVENTCHKINF_2D 0x2D
+#define EVENTCHKINF_2F 0x2F
+#define EVENTCHKINF_30 0x30
+#define EVENTCHKINF_31 0x31
+#define EVENTCHKINF_32 0x32
+#define EVENTCHKINF_GAVE_LETTER_TO_KING_ZORA 0x33
+#define EVENTCHKINF_37 0x37
+#define EVENTCHKINF_38 0x38
+#define EVENTCHKINF_39 0x39
+#define EVENTCHKINF_OPENED_JABU_JABU 0x3A
+#define EVENTCHKINF_3B 0x3B
+#define EVENTCHKINF_DEFEATED_NABOORU_KNUCKLE 0x3C
+
+// EVENTCHKINF 0x40
+#define EVENTCHKINF_INDEX_40 EVENTCHKINF_INDEX(EVENTCHKINF_40)
+#define EVENTCHKINF_40 0x40
+
+#define EVENTCHKINF_41 0x41
+#define EVENTCHKINF_42 0x42
+#define EVENTCHKINF_43 0x43
+#define EVENTCHKINF_45 0x45
+#define EVENTCHKINF_48 0x48
+#define EVENTCHKINF_49 0x49
+#define EVENTCHKINF_4A 0x4A
+#define EVENTCHKINF_OPENED_DOOR_OF_TIME 0x4B
+#define EVENTCHKINF_4C 0x4C
+#define EVENTCHKINF_CREATED_RAINBOW_BRIDGE 0x4D
+#define EVENTCHKINF_CAUGHT_BY_CASTLE_GUARDS 0x4E // set but unused
+#define EVENTCHKINF_REVEALED_MASTER_SWORD 0x4F // Cutscene in Temple of Time when entering the Master Sword chamber for the first time
+#define EVENTCHKINF_50 0x50
+#define EVENTCHKINF_51 0x51
+#define EVENTCHKINF_52 0x52
+#define EVENTCHKINF_54 0x54
+#define EVENTCHKINF_55 0x55
+#define EVENTCHKINF_59 0x59
+#define EVENTCHKINF_5A 0x5A
+#define EVENTCHKINF_5B 0x5B
+#define EVENTCHKINF_5C 0x5C
+#define EVENTCHKINF_65 0x65
+#define EVENTCHKINF_DRAINED_WELL 0x67
+#define EVENTCHKINF_68 0x68
+#define EVENTCHKINF_RESTORED_LAKE_HYLIA 0x69
+#define EVENTCHKINF_TALON_WOKEN_IN_KAKARIKO 0x6A
+
+// EVENTCHKINF 0x6B
+#define EVENTCHKINF_INDEX_TALON_RETURNED_FROM_KAKARIKO EVENTCHKINF_INDEX(EVENTCHKINF_TALON_RETURNED_FROM_KAKARIKO)
+#define EVENTCHKINF_TALON_RETURNED_FROM_KAKARIKO 0x6B
+
+#define EVENTCHKINF_6E 0x6E
+#define EVENTCHKINF_6F 0x6F
+#define EVENTCHKINF_BEGAN_GOHMA_BATTLE 0x70
+#define EVENTCHKINF_BEGAN_KING_DODONGO_BATTLE 0x71
+#define EVENTCHKINF_BEGAN_PHANTOM_GANON_BATTLE 0x72
+#define EVENTCHKINF_BEGAN_VOLVAGIA_BATTLE 0x73
+#define EVENTCHKINF_BEGAN_MORPHA_BATTLE 0x74
+#define EVENTCHKINF_BEGAN_TWINROVA_BATTLE 0x75
+#define EVENTCHKINF_BEGAN_BARINADE_BATTLE 0x76
+#define EVENTCHKINF_BEGAN_BONGO_BONGO_BATTLE 0x77
+#define EVENTCHKINF_BEGAN_GANONDORF_BATTLE 0x78
+#define EVENTCHKINF_80 0x80
+#define EVENTCHKINF_82 0x82
+#define EVENTCHKINF_PAID_BACK_KEATON_MASK 0x8C
+#define EVENTCHKINF_PAID_BACK_SKULL_MASK 0x8D
+#define EVENTCHKINF_PAID_BACK_SPOOKY_MASK 0x8E
+#define EVENTCHKINF_PAID_BACK_BUNNY_HOOD 0x8F
+
+// EVENTCHKINF 0x90-0x93
+// Carpenters rescued from Gerudo Fortress
+#define EVENTCHKINF_INDEX_CARPENTERS_RESCUED 0x9
+#define EVENTCHKINF_CARPENTER_0_RESCUED 0x90
+#define EVENTCHKINF_CARPENTER_1_RESCUED 0x91
+#define EVENTCHKINF_CARPENTER_2_RESCUED 0x92
+#define EVENTCHKINF_CARPENTER_3_RESCUED 0x93
+
+#define EVENTCHKINF_CARPENTERS_ALL_RESCUED_MASK \
+ (EVENTCHKINF_MASK(EVENTCHKINF_CARPENTER_0_RESCUED) | EVENTCHKINF_MASK(EVENTCHKINF_CARPENTER_1_RESCUED) | \
+ EVENTCHKINF_MASK(EVENTCHKINF_CARPENTER_2_RESCUED) | EVENTCHKINF_MASK(EVENTCHKINF_CARPENTER_3_RESCUED))
+
+#define GET_EVENTCHKINF_CARPENTERS_ALL_RESCUED() \
+ ((gSaveContext.save.info.eventChkInf[EVENTCHKINF_INDEX_CARPENTERS_RESCUED] & EVENTCHKINF_CARPENTERS_ALL_RESCUED_MASK) == (EVENTCHKINF_CARPENTERS_ALL_RESCUED_MASK))
+
+#define GET_EVENTCHKINF_CARPENTERS_ALL_RESCUED2() \
+ ((gSaveContext.save.info.eventChkInf[EVENTCHKINF_INDEX_CARPENTERS_RESCUED] & (EVENTCHKINF_CARPENTERS_ALL_RESCUED_MASK | 0xF0) & EVENTCHKINF_CARPENTERS_ALL_RESCUED_MASK) == (EVENTCHKINF_CARPENTERS_ALL_RESCUED_MASK))
+
+#define ENDAIKU_CARPENTER_RESCUED_MASK(carpenterType) (1 << (carpenterType))
+
+#define ENDAIKU_IS_CARPENTER_RESCUED(carpenterType) \
+ gSaveContext.save.info.eventChkInf[EVENTCHKINF_INDEX_CARPENTERS_RESCUED] & \
+ ENDAIKU_CARPENTER_RESCUED_MASK(carpenterType)
+
+#define ENDAIKU_SET_CARPENTER_RESCUED(carpenterType) \
+ gSaveContext.save.info.eventChkInf[EVENTCHKINF_INDEX_CARPENTERS_RESCUED] |= \
+ ENDAIKU_CARPENTER_RESCUED_MASK((carpenterType))
+
+#define GET_EVENTCHKINF_CARPENTERS_RESCUED_FLAGS() \
+ gSaveContext.save.info.eventChkInf[EVENTCHKINF_INDEX_CARPENTERS_RESCUED] & EVENTCHKINF_CARPENTERS_ALL_RESCUED_MASK
+
+#define EVENTCHKINF_94 0x94
+#define EVENTCHKINF_95 0x95
+#define EVENTCHKINF_96 0x96
+#define EVENTCHKINF_9C 0x9C
+#define EVENTCHKINF_A0 0xA0
+#define EVENTCHKINF_A1 0xA1
+#define EVENTCHKINF_A3 0xA3
+#define EVENTCHKINF_A4 0xA4
+#define EVENTCHKINF_A5 0xA5
+#define EVENTCHKINF_A6 0xA6
+#define EVENTCHKINF_A7 0xA7
+#define EVENTCHKINF_A8 0xA8
+#define EVENTCHKINF_A9 0xA9
+#define EVENTCHKINF_AA 0xAA
+#define EVENTCHKINF_AC 0xAC
+#define EVENTCHKINF_AD 0xAD
+#define EVENTCHKINF_B0 0xB0
+#define EVENTCHKINF_B1 0xB1
+#define EVENTCHKINF_B2 0xB2
+#define EVENTCHKINF_B3 0xB3
+#define EVENTCHKINF_B4 0xB4
+#define EVENTCHKINF_B5 0xB5
+#define EVENTCHKINF_B6 0xB6
+#define EVENTCHKINF_B7 0xB7
+#define EVENTCHKINF_B8 0xB8
+#define EVENTCHKINF_B9 0xB9
+#define EVENTCHKINF_BA 0xBA
+#define EVENTCHKINF_BB 0xBB
+#define EVENTCHKINF_BC 0xBC
+#define EVENTCHKINF_BD 0xBD
+#define EVENTCHKINF_BE 0xBE
+#define EVENTCHKINF_BF 0xBF
+#define EVENTCHKINF_C0 0xC0
+#define EVENTCHKINF_C1 0xC1
+#define EVENTCHKINF_C3 0xC3
+#define EVENTCHKINF_C4 0xC4
+#define EVENTCHKINF_C5 0xC5
+#define EVENTCHKINF_C6 0xC6
+#define EVENTCHKINF_C7 0xC7
+#define EVENTCHKINF_C8 0xC8
+#define EVENTCHKINF_C9 0xC9
+
+// EVENTCHKINF 0xD0-0xD6
+#define EVENTCHKINF_INDEX_SONGS_FOR_FROGS EVENTCHKINF_INDEX(EVENTCHKINF_SONGS_FOR_FROGS_CHOIR)
+#define EVENTCHKINF_SONGS_FOR_FROGS_CHOIR 0xD0
+#define EVENTCHKINF_SONGS_FOR_FROGS_ZL 0xD1
+#define EVENTCHKINF_SONGS_FOR_FROGS_EPONA 0xD2
+#define EVENTCHKINF_SONGS_FOR_FROGS_SUNS 0xD3
+#define EVENTCHKINF_SONGS_FOR_FROGS_SARIA 0xD4
+#define EVENTCHKINF_SONGS_FOR_FROGS_SOT 0xD5
+#define EVENTCHKINF_SONGS_FOR_FROGS_STORMS 0xD6
+
+// EVENTCHKINF 0xDA-0xDE
+#define EVENTCHKINF_INDEX_SKULLTULA_REWARD 0xD
+#define EVENTCHKINF_SKULLTULA_REWARD_10 0xDA
+#define EVENTCHKINF_SKULLTULA_REWARD_20 0xDB
+#define EVENTCHKINF_SKULLTULA_REWARD_30 0xDC
+#define EVENTCHKINF_SKULLTULA_REWARD_40 0xDD
+#define EVENTCHKINF_SKULLTULA_REWARD_50 0xDE
+
+
+/*
+ * SaveContext.itemGetInf
+ */
+
+#define ITEMGETINF_INDEX(flag) ((flag) >> 4)
+#define ITEMGETINF_MASK(flag) (1 << ((flag) & 0xF))
+
+#define GET_ITEMGETINF(flag) (gSaveContext.save.info.itemGetInf[ITEMGETINF_INDEX(flag)] & ITEMGETINF_MASK(flag))
+#define SET_ITEMGETINF(flag) (gSaveContext.save.info.itemGetInf[ITEMGETINF_INDEX(flag)] |= ITEMGETINF_MASK(flag))
+
+#define ITEMGETINF_TALON_BOTTLE 0x02
+#define ITEMGETINF_03 0x03
+#define ITEMGETINF_04 0x04
+#define ITEMGETINF_05 0x05
+#define ITEMGETINF_06 0x06
+#define ITEMGETINF_07 0x07
+#define ITEMGETINF_08 0x08
+#define ITEMGETINF_09 0x09
+#define ITEMGETINF_0A 0x0A
+#define ITEMGETINF_DEKU_HEART_PIECE 0x0B
+#define ITEMGETINF_0C 0x0C
+#define ITEMGETINF_0D 0x0D
+#define ITEMGETINF_0E 0x0E
+#define ITEMGETINF_0F 0x0F
+#define ITEMGETINF_10 0x10
+#define ITEMGETINF_11 0x11
+#define ITEMGETINF_12 0x12
+#define ITEMGETINF_13 0x13
+#define ITEMGETINF_15 0x15
+#define ITEMGETINF_16 0x16
+#define ITEMGETINF_17 0x17
+
+// ITEMGETINF 0x18-0x1A
+#define ITEMGETINF_INDEX_18_19_1A 1
+#define ITEMGETINF_18 0x18
+#define ITEMGETINF_19 0x19
+#define ITEMGETINF_1A 0x1A
+
+#define ITEMGETINF_1B 0x1B
+#define ITEMGETINF_1C 0x1C
+#define ITEMGETINF_1D 0x1D
+#define ITEMGETINF_FOREST_STAGE_STICK_UPGRADE 0x1E
+// This flag is shared by two events; It is set when obtaining the Deku Nut upgrade at the Forest Stage and when obtaining Poachers Saw.
+// This will make obtaining the Deku Nut upgrade impossible if Poachers Saw is obtained first.
+// This flag is never read for the Poachers Saw event, so the overlap only causes an issue for the Deku Nut Upgrade. It will not prevent obtaining Poachers Saw.
+#define ITEMGETINF_FOREST_STAGE_NUT_UPGRADE 0x1F
+#define ITEMGETINF_23 0x23
+#define ITEMGETINF_24 0x24
+#define ITEMGETINF_25 0x25
+#define ITEMGETINF_26 0x26
+#define ITEMGETINF_2A 0x2A
+#define ITEMGETINF_2C 0x2C
+#define ITEMGETINF_2E 0x2E
+#define ITEMGETINF_30 0x30
+#define ITEMGETINF_31 0x31
+#define ITEMGETINF_38 0x38
+#define ITEMGETINF_39 0x39
+#define ITEMGETINF_3A 0x3A
+#define ITEMGETINF_3B 0x3B
+#define ITEMGETINF_3F 0x3F
+
+
+/*
+ * SaveContext.infTable
+ */
+
+#define INFTABLE_INDEX(flag) ((flag) >> 4)
+#define INFTABLE_MASK(flag) (1 << ((flag) & 0xF))
+
+#define GET_INFTABLE(flag) (gSaveContext.save.info.infTable[INFTABLE_INDEX(flag)] & INFTABLE_MASK(flag))
+#define SET_INFTABLE(flag) (gSaveContext.save.info.infTable[INFTABLE_INDEX(flag)] |= INFTABLE_MASK(flag))
+#define CLEAR_INFTABLE(flag) (gSaveContext.save.info.infTable[INFTABLE_INDEX(flag)] &= ~INFTABLE_MASK(flag))
+
+// INFTABLE 0x0-0xF
+#define INFTABLE_INDEX_0 0
+#define INFTABLE_00 0x00
+#define INFTABLE_01 0x01
+#define INFTABLE_03 0x03
+#define INFTABLE_05 0x05
+#define INFTABLE_0C 0x0C
+#define INFTABLE_0E 0x0E
+#define INFTABLE_10 0x10
+#define INFTABLE_15 0x15
+#define INFTABLE_17 0x17
+#define INFTABLE_19 0x19
+#define INFTABLE_1E 0x1E
+#define INFTABLE_22 0x22
+#define INFTABLE_24 0x24
+#define INFTABLE_26 0x26
+#define INFTABLE_28 0x28
+#define INFTABLE_2A 0x2A
+#define INFTABLE_2B 0x2B
+#define INFTABLE_2E 0x2E
+#define INFTABLE_2F 0x2F
+#define INFTABLE_30 0x30
+#define INFTABLE_41 0x41
+#define INFTABLE_47 0x47
+#define INFTABLE_51 0x51
+#define INFTABLE_59 0x59
+#define INFTABLE_61 0x61
+#define INFTABLE_66 0x66
+#define INFTABLE_6A 0x6A
+#define INFTABLE_6C 0x6C
+#define INFTABLE_71 0x71
+#define INFTABLE_76 0x76
+#define INFTABLE_77 0x77
+#define INFTABLE_TALKED_TO_TALON_IN_RANCH_HOUSE 0x7E
+#define INFTABLE_TALKED_TO_MALON_FIRST_TIME 0x84
+#define INFTABLE_TOLD_EPONA_IS_SCARED 0x85
+#define INFTABLE_MALON_SPAWNED_AT_HYRULE_CASTLE 0x8B
+#define INFTABLE_8C 0x8C
+#define INFTABLE_8D 0x8D
+#define INFTABLE_8E 0x8E
+#define INFTABLE_94 0x94
+#define INFTABLE_97 0x97
+#define INFTABLE_9A 0x9A
+#define INFTABLE_A2 0xA2
+#define INFTABLE_AB 0xAB
+#define INFTABLE_B0 0xB0
+#define INFTABLE_B1 0xB1
+#define INFTABLE_B4 0xB4
+#define INFTABLE_B6 0xB6
+#define INFTABLE_B7 0xB7
+#define INFTABLE_B8 0xB8
+#define INFTABLE_B9 0xB9
+#define INFTABLE_BC 0xBC
+#define INFTABLE_C0 0xC0
+#define INFTABLE_C1 0xC1
+#define INFTABLE_C2 0xC2
+#define INFTABLE_C3 0xC3
+#define INFTABLE_C4 0xC4
+#define INFTABLE_C5 0xC5
+#define INFTABLE_C6 0xC6
+#define INFTABLE_C7 0xC7
+#define INFTABLE_C8 0xC8
+#define INFTABLE_C9 0xC9
+#define INFTABLE_CA 0xCA
+#define INFTABLE_CB 0xCB
+#define INFTABLE_CC 0xCC
+#define INFTABLE_CD 0xCD
+#define INFTABLE_CE 0xCE
+#define INFTABLE_D0 0xD0
+#define INFTABLE_D2 0xD2
+#define INFTABLE_D4 0xD4
+#define INFTABLE_D6 0xD6
+#define INFTABLE_D8 0xD8
+#define INFTABLE_D9 0xD9
+#define INFTABLE_E0 0xE0
+#define INFTABLE_E3 0xE3
+#define INFTABLE_E6 0xE6
+#define INFTABLE_EB 0xEB
+#define INFTABLE_F0 0xF0
+#define INFTABLE_F4 0xF4
+#define INFTABLE_F8 0xF8
+#define INFTABLE_FC 0xFC
+#define INFTABLE_109 0x109
+#define INFTABLE_10A 0x10A
+#define INFTABLE_10B 0x10B
+#define INFTABLE_10C 0x10C
+#define INFTABLE_10D 0x10D
+#define INFTABLE_10E 0x10E
+#define INFTABLE_10F 0x10F
+#define INFTABLE_113 0x113
+#define INFTABLE_11A 0x11A
+#define INFTABLE_11E 0x11E
+#define INFTABLE_124 0x124
+#define INFTABLE_129 0x129
+#define INFTABLE_12A 0x12A
+#define INFTABLE_138 0x138
+#define INFTABLE_139 0x139
+#define INFTABLE_140 0x140
+#define INFTABLE_141 0x141
+#define INFTABLE_142 0x142
+#define INFTABLE_143 0x143
+#define INFTABLE_144 0x144
+#define INFTABLE_145 0x145
+#define INFTABLE_146 0x146
+#define INFTABLE_147 0x147
+#define INFTABLE_160 0x160
+#define INFTABLE_161 0x161
+#define INFTABLE_162 0x162
+#define INFTABLE_163 0x163
+#define INFTABLE_164 0x164
+#define INFTABLE_166 0x166
+#define INFTABLE_16A 0x16A
+#define INFTABLE_16C 0x16C
+#define INFTABLE_170 0x170
+#define INFTABLE_171 0x171
+#define INFTABLE_172 0x172
+#define INFTABLE_176 0x176
+#define INFTABLE_178 0x178
+#define INFTABLE_17C 0x17C
+#define INFTABLE_17F 0x17F
+#define INFTABLE_190 0x190
+#define INFTABLE_191 0x191
+#define INFTABLE_HAS_DEKU_STICK_UPGRADE 0x192
+#define INFTABLE_HAS_DEKU_NUT_UPGRADE 0x193
+#define INFTABLE_195 0x195
+#define INFTABLE_196 0x196
+#define INFTABLE_197 0x197
+#define INFTABLE_198 0x198
+
+// INFTABLE 0x199-0x19F
+#define INFTABLE_INDEX_199_19A_19B_19C_19D_19E_19F 25
+#define INFTABLE_199 0x199
+#define INFTABLE_19A 0x19A
+#define INFTABLE_19B 0x19B
+#define INFTABLE_19C 0x19C
+#define INFTABLE_19D 0x19D
+#define INFTABLE_19E 0x19E
+#define INFTABLE_19F 0x19F
+
+// INFTABLE 0x1A0-0x1AF
+#define INFTABLE_INDEX_1AX 26
+#define INFTABLE_1A0_SHIFT 0
+#define INFTABLE_1A1_SHIFT 1
+#define INFTABLE_1A2_SHIFT 2
+#define INFTABLE_1A3_SHIFT 3
+#define INFTABLE_1A4_SHIFT 4
+#define INFTABLE_1A5_SHIFT 5
+#define INFTABLE_1A6_SHIFT 6
+#define INFTABLE_1A7_SHIFT 7
+#define INFTABLE_1A8_SHIFT 8
+#define INFTABLE_1A9_SHIFT 9
+#define INFTABLE_1AB_SHIFT 11
+#define INFTABLE_1AD_SHIFT 13
+
+// INFTABLE 0x1D0-0x1DF
+#define INFTABLE_INDEX_1DX INFTABLE_INDEX(INFTABLE_1D0)
+#define INFTABLE_1D0 0x1D0
+
+
+/*
+ * SaveContext.eventInf
+ */
+
+#define EVENTINF_INDEX(flag) ((flag) >> 4)
+#define EVENTINF_MASK(flag) (1 << ((flag) & 0xF))
+
+#define GET_EVENTINF(flag) (gSaveContext.eventInf[EVENTINF_INDEX(flag)] & EVENTINF_MASK(flag))
+#define SET_EVENTINF(flag) (gSaveContext.eventInf[EVENTINF_INDEX(flag)] |= EVENTINF_MASK(flag))
+#define CLEAR_EVENTINF(flag) (gSaveContext.eventInf[EVENTINF_INDEX(flag)] &= ~EVENTINF_MASK(flag))
+
+// EVENTINF 0x00-0x0F
+// Ingo Race, Lon Lon Ranch minigames, and Horseback Archery minigame flags
+#define EVENTINF_INDEX_HORSES 0
+// EVENTINF 0x00-0x03 reserved for IngoRaceState
+#define EVENTINF_INGO_RACE_STATE_MASK (0xF << 0x00)
+typedef enum IngoRaceState {
+ /* 0 */ INGO_RACE_STATE_OFFER_RENTAL,
+ /* 1 */ INGO_RACE_STATE_HORSE_RENTAL_PERIOD,
+ /* 2 */ INGO_RACE_STATE_RACING,
+ /* 3 */ INGO_RACE_STATE_PLAYER_LOSE,
+ /* 4 */ INGO_RACE_STATE_FIRST_WIN,
+ /* 5 */ INGO_RACE_STATE_TRAPPED_WIN_UNUSED,
+ /* 6 */ INGO_RACE_STATE_TRAPPED_WIN_EPONA, // Ingo Traps you in Lon Lon
+ /* 7 */ INGO_RACE_STATE_REMATCH
+} IngoRaceState;
+
+#define EVENTINF_INGO_RACE_HORSETYPE 0x04
+#define EVENTINF_INGO_RACE_LOST_ONCE 0x05
+#define EVENTINF_INGO_RACE_SECOND_RACE 0x06
+// Used in z_en_ta (Talon) to store Cucco game winning status
+// and in z_en_ge1 (Gerudo) to store archery in-progress status
+#define EVENTINF_HORSES_08 0x08
+#define EVENTINF_CUCCO_GAME_WON EVENTINF_HORSES_08
+// Used in z_en_ta (Talon) and z_en_ma3 (Malon) to store minigame finishing status
+#define EVENTINF_HORSES_0A 0x0A
+#define EVENTINF_CUCCO_GAME_FINISHED EVENTINF_HORSES_0A
+#define EVENTINF_INGO_RACE_0F 0x0F // unused?
+
+// "InRaceSeq"
+#define GET_EVENTINF_INGO_RACE_STATE() (gSaveContext.eventInf[EVENTINF_INDEX_HORSES] & EVENTINF_INGO_RACE_STATE_MASK)
+
+#define SET_EVENTINF_INGO_RACE_STATE(v) \
+ gSaveContext.eventInf[EVENTINF_INDEX_HORSES] = \
+ (gSaveContext.eventInf[EVENTINF_INDEX_HORSES] & ~EVENTINF_INGO_RACE_STATE_MASK) | (v)
+
+#define GET_EVENTINF_INGO_RACE_FLAG(flag) \
+ ((gSaveContext.eventInf[EVENTINF_INDEX_HORSES] & EVENTINF_MASK(flag)) >> ((flag) & 0xF))
+
+#define SET_EVENTINF_INGO_RACE_FLAG(flag) \
+ gSaveContext.eventInf[EVENTINF_INDEX_HORSES] = \
+ (gSaveContext.eventInf[EVENTINF_INDEX_HORSES] & 0xFFFF) | EVENTINF_MASK(flag)
+
+#define WRITE_EVENTINF_INGO_RACE_FLAG(flag, v) \
+ gSaveContext.eventInf[EVENTINF_INDEX_HORSES] = \
+ (gSaveContext.eventInf[EVENTINF_INDEX_HORSES] & ~EVENTINF_MASK(flag)) | ((v) << ((flag) & 0xF))
+
+#define GET_EVENTINF_INGO_RACE_HORSETYPE() GET_EVENTINF_INGO_RACE_FLAG(EVENTINF_INGO_RACE_HORSETYPE)
+#define WRITE_EVENTINF_INGO_RACE_HORSETYPE(v) WRITE_EVENTINF_INGO_RACE_FLAG(EVENTINF_INGO_RACE_HORSETYPE, v)
+
+#define WRITE_EVENTINF_INGO_RACE_0F(v) WRITE_EVENTINF_INGO_RACE_FLAG(EVENTINF_INGO_RACE_0F, v)
+
+// Is the running man race active
+#define EVENTINF_MARATHON_ACTIVE 0x10
+
+// EVENTINF 0x20-0x24
+#define EVENTINF_INDEX_HAGGLING_TOWNSFOLK 0x2
+#define EVENTINF_HAGGLING_TOWNSFOLK_MESG_0 0x20
+#define EVENTINF_HAGGLING_TOWNSFOLK_MESG_1 0x21
+#define EVENTINF_HAGGLING_TOWNSFOLK_MESG_2 0x22
+#define EVENTINF_HAGGLING_TOWNSFOLK_MESG_3 0x23
+#define EVENTINF_HAGGLING_TOWNSFOLK_MESG_4 0x24
+
+#define EVENTINF_HAGGLING_TOWNSFOLK_MASK \
+ (EVENTINF_MASK(EVENTINF_HAGGLING_TOWNSFOLK_MESG_0) | EVENTINF_MASK(EVENTINF_HAGGLING_TOWNSFOLK_MESG_1) | \
+ EVENTINF_MASK(EVENTINF_HAGGLING_TOWNSFOLK_MESG_2) | EVENTINF_MASK(EVENTINF_HAGGLING_TOWNSFOLK_MESG_3) | \
+ EVENTINF_MASK(EVENTINF_HAGGLING_TOWNSFOLK_MESG_4))
+
+#define GET_EVENTINF_ENMU_TALK_FLAGS() \
+ gSaveContext.eventInf[EVENTINF_INDEX_HAGGLING_TOWNSFOLK] & EVENTINF_HAGGLING_TOWNSFOLK_MASK
+
+#define SET_EVENTINF_ENMU_TALK_FLAGS(talkFlags) \
+ gSaveContext.eventInf[EVENTINF_INDEX_HAGGLING_TOWNSFOLK] |= (talkFlags);
+
+#define RESET_EVENTINF_ENMU_TALK_FLAGS() \
+ gSaveContext.eventInf[EVENTINF_INDEX_HAGGLING_TOWNSFOLK] &= ~(EVENTINF_HAGGLING_TOWNSFOLK_MASK);
+
+#define EVENTINF_30 0x30
+
+void SaveContext_Init(void);
+
+extern SaveContext gSaveContext;
+
+#endif