diff options
| author | Random <28494085+Random06457@users.noreply.github.com> | 2020-10-11 19:45:08 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-11 13:45:08 -0400 |
| commit | b010db7c19207f0e607d5ccaf0d1f2350dda3964 (patch) | |
| tree | 12dc8d3a3dfb57705ba907dd0af855662ed35bde /src | |
| parent | 9d3554220793d515230844f894ede66100bdc039 (diff) | |
Decompile z_sram.c (#431)
* Decompile z_sram.c
* rename Sram_CalcChecksum to Sram_WriteSaveSlot
* progress
* done i think
* add original name comments
* temp substructs
* minor fixes
* review
* review 2
* fix
Co-authored-by: fig <fig02srl@gmail.com>
Diffstat (limited to 'src')
27 files changed, 1103 insertions, 168 deletions
diff --git a/src/code/code_80097A00.c b/src/code/code_80097A00.c index b61559de6..457fe72ce 100644 --- a/src/code/code_80097A00.c +++ b/src/code/code_80097A00.c @@ -85,7 +85,7 @@ u8 Inventory_DeleteEquipment(GlobalContext* globalCtx, s16 equipment) { sp26 >>= gEquipShifts[equipment]; gSaveContext.equips.equipment &= gEquipNegMasks[equipment]; - gSaveContext.equipment ^= gBitFlags[sp26 - 1] << gEquipShifts[equipment]; + gSaveContext.inventory.equipment ^= gBitFlags[sp26 - 1] << gEquipShifts[equipment]; if (equipment == EQUIP_TUNIC) { gSaveContext.equips.equipment |= 0x0100; @@ -104,6 +104,6 @@ u8 Inventory_DeleteEquipment(GlobalContext* globalCtx, s16 equipment) { } void Inventory_ChangeUpgrade(s16 upgrade, s16 value) { - gSaveContext.upgrades &= gUpgradeNegMasks[upgrade]; - gSaveContext.upgrades |= value << gUpgradeShifts[upgrade]; + gSaveContext.inventory.upgrades &= gUpgradeNegMasks[upgrade]; + gSaveContext.inventory.upgrades |= value << gUpgradeShifts[upgrade]; } diff --git a/src/code/z_actor.c b/src/code/z_actor.c index b9638879b..4c90d800a 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -1949,10 +1949,10 @@ void func_800304B0(GlobalContext* globalCtx) { // Actor_InitContext void func_800304DC(GlobalContext* globalCtx, ActorContext* actorCtx, ActorEntry* actorEntry) { ActorOverlay* overlayEntry; - SaveSceneFlags* saveSceneFlags; + SavedSceneFlags* savedSceneFlags; s32 i; - saveSceneFlags = &gSaveContext.sceneFlags[globalCtx->sceneNum]; + savedSceneFlags = &gSaveContext.sceneFlags[globalCtx->sceneNum]; bzero(actorCtx, sizeof(*actorCtx)); @@ -1967,10 +1967,10 @@ void func_800304DC(GlobalContext* globalCtx, ActorContext* actorCtx, ActorEntry* overlayEntry++; } - actorCtx->flags.chest = saveSceneFlags->chest; - actorCtx->flags.swch = saveSceneFlags->swch; - actorCtx->flags.clear = saveSceneFlags->clear; - actorCtx->flags.collect = saveSceneFlags->collect; + actorCtx->flags.chest = savedSceneFlags->chest; + actorCtx->flags.swch = savedSceneFlags->swch; + actorCtx->flags.clear = savedSceneFlags->clear; + actorCtx->flags.collect = savedSceneFlags->collect; func_8002CDE4(globalCtx, &actorCtx->titleCtx); diff --git a/src/code/z_demo.c b/src/code/z_demo.c index 9210fe1d1..4c4401617 100644 --- a/src/code/z_demo.c +++ b/src/code/z_demo.c @@ -2009,7 +2009,7 @@ void Cutscene_HandleEntranceTriggers(GlobalContext* globalCtx) { Flags_SetEventChkInf(entranceCutscene->flag); Cutscene_SetSegment(globalCtx, entranceCutscene->segAddr); gSaveContext.cutsceneTrigger = 2; - gSaveContext.unk_13C7 = 0; + gSaveContext.showTitleCard = false; break; } } diff --git a/src/code/z_elf_message.c b/src/code/z_elf_message.c index d3552c419..6db1527b1 100644 --- a/src/code/z_elf_message.c +++ b/src/code/z_elf_message.c @@ -22,8 +22,8 @@ u32 ElfMessage_CheckCondition(ElfMessage* msg) { flag = 1 << (msg->byte1 & 0x0F); return ((msg->byte0 & 1) == 1) == ((flag & gSaveContext.eventChkInf[(msg->byte1 & 0xF0) >> 4]) != 0); case 2: - return ((msg->byte0 & 1) == 1) == - ((gSaveContext.dungeonItems[gSaveContext.mapIndex] & gBitFlags[msg->byte1 - ITEM_KEY_BOSS]) != 0); + return ((msg->byte0 & 1) == 1) == ((gSaveContext.inventory.dungeonItems[gSaveContext.mapIndex] & + gBitFlags[msg->byte1 - ITEM_KEY_BOSS]) != 0); case 4: return ((msg->byte0 & 1) == 1) == (msg->byte3 == INV_CONTENT(msg->byte1)); case 6: @@ -33,7 +33,7 @@ u32 ElfMessage_CheckCondition(ElfMessage* msg) { case 0x10: return ((msg->byte0 & 1) == 1) == (((gBitFlags[msg->byte3 - ITEM_BOOTS_KOKIRI] << gEquipShifts[EQUIP_BOOTS]) & - gSaveContext.equipment) != 0); + gSaveContext.inventory.equipment) != 0); case 0x20: return ((msg->byte0 & 1) == 1) == ((CHECK_QUEST_ITEM(msg->byte3 - ITEM_SONG_MINUET + QUEST_SONG_MINUET)) != 0); diff --git a/src/code/z_kankyo.c b/src/code/z_kankyo.c index 70b8e2c31..016743503 100644 --- a/src/code/z_kankyo.c +++ b/src/code/z_kankyo.c @@ -77,7 +77,7 @@ void func_800775D8() { } s32 func_800775E4() { - return gSaveContext.unk_14; + return gSaveContext.numDays; } void func_800775F0(u16 arg0) { diff --git a/src/code/z_lifemeter.c b/src/code/z_lifemeter.c index 64fe2e53e..63c535008 100644 --- a/src/code/z_lifemeter.c +++ b/src/code/z_lifemeter.c @@ -204,7 +204,7 @@ void Health_Draw(GlobalContext* globalCtx) { f32 sp144 = interfaceCtx->unk_22A * 0.1f; s32 curCombineModeSet = 0; u8* curBgImgLoaded = NULL; - s32 ddHeartCountMinusOne = gSaveContext.defenseHearts - 1; + s32 ddHeartCountMinusOne = gSaveContext.inventory.defenseHearts - 1; OPEN_DISPS(gfxCtx, "../z_lifemeter.c", 353); diff --git a/src/code/z_map_exp.c b/src/code/z_map_exp.c index c409d0cf8..68e68e0f3 100644 --- a/src/code/z_map_exp.c +++ b/src/code/z_map_exp.c @@ -46,7 +46,7 @@ void Map_SetFloorPalettesData(GlobalContext* globalCtx, s16 floor) { interfaceCtx->unk_140[i + 16] = 0; } - if (gSaveContext.dungeonItems[mapIndex] & gBitFlags[DUNGEON_MAP]) { + if (gSaveContext.inventory.dungeonItems[mapIndex] & gBitFlags[DUNGEON_MAP]) { interfaceCtx->unk_140[30] = 0; interfaceCtx->unk_140[31] = 1; } @@ -383,7 +383,7 @@ void Minimap_Draw(GlobalContext* globalCtx) { gDPSetCombineLERP(oGfxCtx->overlay.p++, 1, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0, 1, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0); - if (gSaveContext.dungeonItems[mapIndex] & gBitFlags[DUNGEON_MAP]) { + if (gSaveContext.inventory.dungeonItems[mapIndex] & gBitFlags[DUNGEON_MAP]) { gDPSetPrimColor(oGfxCtx->overlay.p++, 0, 0, 100, 255, 255, interfaceCtx->minimapAlpha); gDPLoadTextureBlock_4b(oGfxCtx->overlay.p++, interfaceCtx->mapSegment, G_IM_FMT_I, 96, 85, 0, @@ -395,7 +395,7 @@ void Minimap_Draw(GlobalContext* globalCtx) { 0, 0, 1024, 1024); } - if (gSaveContext.dungeonItems[mapIndex] & gBitFlags[DUNGEON_COMPASS]) { + if (gSaveContext.inventory.dungeonItems[mapIndex] & gBitFlags[DUNGEON_COMPASS]) { Minimap_DrawCompassIcons(globalCtx); // Draw icons for the player spawn and current position func_80094520(globalCtx->state.gfxCtx); MapMark_DrawConditionally(globalCtx); @@ -525,7 +525,7 @@ void Map_Update(GlobalContext* globalCtx) { case SCENE_HAKADANCH: case SCENE_ICE_DOUKUTO: interfaceCtx->unk_140[30] = 0; - if (gSaveContext.dungeonItems[mapIndex] & gBitFlags[DUNGEON_MAP]) { + if (gSaveContext.inventory.dungeonItems[mapIndex] & gBitFlags[DUNGEON_MAP]) { interfaceCtx->unk_140[31] = 1; } else { interfaceCtx->unk_140[31] = 0; diff --git a/src/code/z_parameter.c b/src/code/z_parameter.c index 97ef34dc4..87b078704 100644 --- a/src/code/z_parameter.c +++ b/src/code/z_parameter.c @@ -636,7 +636,7 @@ void func_80083108(GlobalContext* globalCtx) { Interface_LoadItemIcon1(globalCtx, 0); } else { - if (gSaveContext.items[SLOT_BOW] == ITEM_NONE) { + if (gSaveContext.inventory.items[SLOT_BOW] == ITEM_NONE) { gSaveContext.equips.buttonItems[0] = ITEM_NONE; } else { Interface_LoadItemIcon1(globalCtx, 0); @@ -752,7 +752,7 @@ void func_80083108(GlobalContext* globalCtx) { if (player->stateFlags1 & 0x00800000) { if ((gSaveContext.equips.buttonItems[0] != ITEM_NONE) && (gSaveContext.equips.buttonItems[0] != ITEM_BOW)) { - if (gSaveContext.items[SLOT_BOW] == ITEM_NONE) { + if (gSaveContext.inventory.items[SLOT_BOW] == ITEM_NONE) { gSaveContext.equips.buttonItems[0] = ITEM_NONE; } else { gSaveContext.equips.buttonItems[0] = ITEM_BOW; @@ -1154,7 +1154,7 @@ void Inventory_SwapAgeEquipment(void) { if (gSaveContext.adultEquips.buttonItems[0] == ITEM_NONE) { gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER; - if (gSaveContext.items[SLOT_NUT] != ITEM_NONE) { + if (gSaveContext.inventory.items[SLOT_NUT] != ITEM_NONE) { gSaveContext.equips.buttonItems[1] = ITEM_NUT; gSaveContext.equips.cButtonSlots[0] = SLOT_NUT; } else { @@ -1162,7 +1162,7 @@ void Inventory_SwapAgeEquipment(void) { } gSaveContext.equips.buttonItems[2] = ITEM_BOMB; - gSaveContext.equips.buttonItems[3] = gSaveContext.items[SLOT_OCARINA]; + gSaveContext.equips.buttonItems[3] = gSaveContext.inventory.items[SLOT_OCARINA]; gSaveContext.equips.cButtonSlots[1] = SLOT_BOMB; gSaveContext.equips.cButtonSlots[2] = SLOT_OCARINA; gSaveContext.equips.equipment = 0x1122; @@ -1179,7 +1179,8 @@ void Inventory_SwapAgeEquipment(void) { ((gSaveContext.equips.buttonItems[i] >= ITEM_WEIRD_EGG) && (gSaveContext.equips.buttonItems[i] <= ITEM_CLAIM_CHECK))) { osSyncPrintf("Register_Item_Pt(%d)=%d\n", i, gSaveContext.equips.cButtonSlots[i - 1]); - gSaveContext.equips.buttonItems[i] = gSaveContext.items[gSaveContext.equips.cButtonSlots[i - 1]]; + gSaveContext.equips.buttonItems[i] = + gSaveContext.inventory.items[gSaveContext.equips.cButtonSlots[i - 1]]; } } @@ -1209,7 +1210,8 @@ void Inventory_SwapAgeEquipment(void) { ((gSaveContext.equips.buttonItems[i] >= ITEM_WEIRD_EGG) && (gSaveContext.equips.buttonItems[i] <= ITEM_CLAIM_CHECK))) { osSyncPrintf("Register_Item_Pt(%d)=%d\n", i, gSaveContext.equips.cButtonSlots[i - 1]); - gSaveContext.equips.buttonItems[i] = gSaveContext.items[gSaveContext.equips.cButtonSlots[i - 1]]; + gSaveContext.equips.buttonItems[i] = + gSaveContext.inventory.items[gSaveContext.equips.cButtonSlots[i - 1]]; } } @@ -1222,7 +1224,7 @@ void Inventory_SwapAgeEquipment(void) { temp = gEquipMasks[EQUIP_SHIELD] & gSaveContext.equips.equipment; if (temp != 0) { temp >>= gEquipShifts[EQUIP_SHIELD]; - if (!(gBitFlags[temp + 3] & gSaveContext.equipment)) { + if (!(gBitFlags[temp + 3] & gSaveContext.inventory.equipment)) { gSaveContext.equips.equipment &= gEquipNegMasks[EQUIP_SHIELD]; } } @@ -1238,10 +1240,10 @@ void Interface_InitHorsebackArchery(GlobalContext* globalCtx) { } void func_800849EC(GlobalContext* globalCtx) { - gSaveContext.equipment |= gBitFlags[2] << gEquipShifts[EQUIP_SWORD]; - gSaveContext.equipment ^= 8 << gEquipShifts[EQUIP_SWORD]; + gSaveContext.inventory.equipment |= gBitFlags[2] << gEquipShifts[EQUIP_SWORD]; + gSaveContext.inventory.equipment ^= 8 << gEquipShifts[EQUIP_SWORD]; - if (gBitFlags[3] & gSaveContext.equipment) { + if (gBitFlags[3] & gSaveContext.inventory.equipment) { gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KNIFE; } else { gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS; @@ -1318,15 +1320,15 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { } osSyncPrintf(VT_FGCOL(YELLOW)); - osSyncPrintf("item_get_setting=%d pt=%d z=%x\n", item, slot, gSaveContext.items[slot]); + osSyncPrintf("item_get_setting=%d pt=%d z=%x\n", item, slot, gSaveContext.inventory.items[slot]); osSyncPrintf(VT_RST); if ((item >= ITEM_MEDALLION_FOREST) && (item <= ITEM_MEDALLION_LIGHT)) { - gSaveContext.questItems |= gBitFlags[item - ITEM_MEDALLION_FOREST + QUEST_MEDALLION_FOREST]; + gSaveContext.inventory.questItems |= gBitFlags[item - ITEM_MEDALLION_FOREST + QUEST_MEDALLION_FOREST]; osSyncPrintf(VT_FGCOL(YELLOW)); // Translates to: "Seals = %x" - osSyncPrintf("封印 = %x\n", gSaveContext.questItems); + osSyncPrintf("封印 = %x\n", gSaveContext.inventory.questItems); osSyncPrintf(VT_RST); if (item == ITEM_MEDALLION_WATER) { @@ -1335,53 +1337,53 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { return ITEM_NONE; } else if ((item >= ITEM_SONG_MINUET) && (item <= ITEM_SONG_STORMS)) { - gSaveContext.questItems |= gBitFlags[item - ITEM_SONG_MINUET + QUEST_SONG_MINUET]; + gSaveContext.inventory.questItems |= gBitFlags[item - ITEM_SONG_MINUET + QUEST_SONG_MINUET]; osSyncPrintf(VT_FGCOL(YELLOW)); // Translates to: "Musical scores = %x" - osSyncPrintf("楽譜 = %x\n", gSaveContext.questItems); + osSyncPrintf("楽譜 = %x\n", gSaveContext.inventory.questItems); // Translates to: "Musical scores = %x (%x) (%x)" - osSyncPrintf("楽譜 = %x (%x) (%x)\n", gSaveContext.questItems, + osSyncPrintf("楽譜 = %x (%x) (%x)\n", gSaveContext.inventory.questItems, gBitFlags[item - ITEM_SONG_MINUET + QUEST_SONG_MINUET], gBitFlags[item - ITEM_SONG_MINUET]); osSyncPrintf(VT_RST); return ITEM_NONE; } else if ((item >= ITEM_KOKIRI_EMERALD) && (item <= ITEM_ZORA_SAPPHIRE)) { - gSaveContext.questItems |= gBitFlags[item - ITEM_KOKIRI_EMERALD + QUEST_KOKIRI_EMERALD]; + gSaveContext.inventory.questItems |= gBitFlags[item - ITEM_KOKIRI_EMERALD + QUEST_KOKIRI_EMERALD]; osSyncPrintf(VT_FGCOL(YELLOW)); // Translates to: "Spiritual Stones = %x" - osSyncPrintf("精霊石 = %x\n", gSaveContext.questItems); + osSyncPrintf("精霊石 = %x\n", gSaveContext.inventory.questItems); osSyncPrintf(VT_RST); return ITEM_NONE; } else if ((item == ITEM_STONE_OF_AGONY) || (item == ITEM_GERUDO_CARD)) { - gSaveContext.questItems |= gBitFlags[item - ITEM_STONE_OF_AGONY + QUEST_STONE_OF_AGONY]; + gSaveContext.inventory.questItems |= gBitFlags[item - ITEM_STONE_OF_AGONY + QUEST_STONE_OF_AGONY]; osSyncPrintf(VT_FGCOL(YELLOW)); // Translates to: "Items = %x" - osSyncPrintf("アイテム = %x\n", gSaveContext.questItems); + osSyncPrintf("アイテム = %x\n", gSaveContext.inventory.questItems); osSyncPrintf(VT_RST); return ITEM_NONE; } else if (item == ITEM_SKULL_TOKEN) { - gSaveContext.questItems |= gBitFlags[item - ITEM_SKULL_TOKEN + QUEST_SKULL_TOKEN]; - gSaveContext.gsTokens++; + gSaveContext.inventory.questItems |= gBitFlags[item - ITEM_SKULL_TOKEN + QUEST_SKULL_TOKEN]; + gSaveContext.inventory.gsTokens++; osSyncPrintf(VT_FGCOL(YELLOW)); // Translates to: "N Coins = %x(%d)" - osSyncPrintf("Nコイン = %x(%d)\n", gSaveContext.questItems, gSaveContext.gsTokens); + osSyncPrintf("Nコイン = %x(%d)\n", gSaveContext.inventory.questItems, gSaveContext.inventory.gsTokens); osSyncPrintf(VT_RST); return ITEM_NONE; } else if ((item >= ITEM_SWORD_KOKIRI) && (item <= ITEM_SWORD_BGS)) { - gSaveContext.equipment |= gBitFlags[item - ITEM_SWORD_KOKIRI] << gEquipShifts[EQUIP_SWORD]; + gSaveContext.inventory.equipment |= gBitFlags[item - ITEM_SWORD_KOKIRI] << gEquipShifts[EQUIP_SWORD]; if (item == ITEM_SWORD_BGS) { gSaveContext.swordHealth = 8; if (ALL_EQUIP_VALUE(EQUIP_SWORD) == 0xF) { - gSaveContext.equipment ^= 8 << gEquipShifts[EQUIP_SWORD]; + gSaveContext.inventory.equipment ^= 8 << gEquipShifts[EQUIP_SWORD]; if (gSaveContext.equips.buttonItems[0] == ITEM_SWORD_KNIFE) { gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS; Interface_LoadItemIcon1(globalCtx, 0); @@ -1396,23 +1398,23 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { return ITEM_NONE; } else if ((item >= ITEM_SHIELD_DEKU) && (item <= ITEM_SHIELD_MIRROR)) { - gSaveContext.equipment |= (gBitFlags[item - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_SHIELD]); + gSaveContext.inventory.equipment |= (gBitFlags[item - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_SHIELD]); return ITEM_NONE; } else if ((item >= ITEM_TUNIC_KOKIRI) && (item <= ITEM_TUNIC_ZORA)) { - gSaveContext.equipment |= (gBitFlags[item - ITEM_TUNIC_KOKIRI] << gEquipShifts[EQUIP_TUNIC]); + gSaveContext.inventory.equipment |= (gBitFlags[item - ITEM_TUNIC_KOKIRI] << gEquipShifts[EQUIP_TUNIC]); return ITEM_NONE; } else if ((item >= ITEM_BOOTS_KOKIRI) && (item <= ITEM_BOOTS_HOVER)) { - gSaveContext.equipment |= (gBitFlags[item - ITEM_BOOTS_KOKIRI] << gEquipShifts[EQUIP_BOOTS]); + gSaveContext.inventory.equipment |= (gBitFlags[item - ITEM_BOOTS_KOKIRI] << gEquipShifts[EQUIP_BOOTS]); return ITEM_NONE; } else if ((item == ITEM_KEY_BOSS) || (item == ITEM_COMPASS) || (item == ITEM_DUNGEON_MAP)) { - gSaveContext.dungeonItems[gSaveContext.mapIndex] |= gBitFlags[item - ITEM_KEY_BOSS]; + gSaveContext.inventory.dungeonItems[gSaveContext.mapIndex] |= gBitFlags[item - ITEM_KEY_BOSS]; return ITEM_NONE; } else if (item == ITEM_KEY_SMALL) { - if (gSaveContext.dungeonKeys[gSaveContext.mapIndex] < 0) { - gSaveContext.dungeonKeys[gSaveContext.mapIndex] = 1; + if (gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] < 0) { + gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] = 1; return ITEM_NONE; } else { - gSaveContext.dungeonKeys[gSaveContext.mapIndex]++; + gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex]++; return ITEM_NONE; } } else if ((item == ITEM_QUIVER_30) || (item == ITEM_BOW)) { @@ -1485,28 +1487,28 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { Inventory_ChangeUpgrade(UPG_WALLET, 2); return ITEM_NONE; } else if (item == ITEM_STICK_UPGRADE_20) { - if (gSaveContext.items[slot] == ITEM_NONE) { + if (gSaveContext.inventory.items[slot] == ITEM_NONE) { INV_CONTENT(ITEM_STICK) = ITEM_STICK; } Inventory_ChangeUpgrade(UPG_STICKS, 2); AMMO(ITEM_STICK) = CAPACITY(UPG_STICKS, 2); return ITEM_NONE; } else if (item == ITEM_STICK_UPGRADE_30) { - if (gSaveContext.items[slot] == ITEM_NONE) { + if (gSaveContext.inventory.items[slot] == ITEM_NONE) { INV_CONTENT(ITEM_STICK) = ITEM_STICK; } Inventory_ChangeUpgrade(UPG_STICKS, 3); AMMO(ITEM_STICK) = CAPACITY(UPG_STICKS, 3); return ITEM_NONE; } else if (item == ITEM_NUT_UPGRADE_30) { - if (gSaveContext.items[slot] == ITEM_NONE) { + if (gSaveContext.inventory.items[slot] == ITEM_NONE) { INV_CONTENT(ITEM_NUT) = ITEM_NUT; } Inventory_ChangeUpgrade(UPG_NUTS, 2); AMMO(ITEM_NUT) = CAPACITY(UPG_NUTS, 2); return ITEM_NONE; } else if (item == ITEM_NUT_UPGRADE_40) { - if (gSaveContext.items[slot] == ITEM_NONE) { + if (gSaveContext.inventory.items[slot] == ITEM_NONE) { INV_CONTENT(ITEM_NUT) = ITEM_NUT; } Inventory_ChangeUpgrade(UPG_NUTS, 3); @@ -1522,7 +1524,7 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { } return ITEM_NONE; } else if (item == ITEM_STICK) { - if (gSaveContext.items[slot] == ITEM_NONE) { + if (gSaveContext.inventory.items[slot] == ITEM_NONE) { Inventory_ChangeUpgrade(UPG_STICKS, 1); AMMO(ITEM_STICK) = 1; } else { @@ -1532,7 +1534,7 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { } } } else if ((item == ITEM_STICKS_5) || (item == ITEM_STICKS_10)) { - if (gSaveContext.items[slot] == ITEM_NONE) { + if (gSaveContext.inventory.items[slot] == ITEM_NONE) { Inventory_ChangeUpgrade(UPG_STICKS, 1); AMMO(ITEM_STICK) = sAmmoRefillCounts[item - ITEM_STICKS_5]; } else { @@ -1543,7 +1545,7 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { } item = ITEM_STICK; } else if (item == ITEM_NUT) { - if (gSaveContext.items[slot] == ITEM_NONE) { + if (gSaveContext.inventory.items[slot] == ITEM_NONE) { Inventory_ChangeUpgrade(UPG_NUTS, 1); AMMO(ITEM_NUT) = ITEM_NUT; } else { @@ -1553,7 +1555,7 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { } } } else if ((item == ITEM_NUTS_5) || (item == ITEM_NUTS_10)) { - if (gSaveContext.items[slot] == ITEM_NONE) { + if (gSaveContext.inventory.items[slot] == ITEM_NONE) { Inventory_ChangeUpgrade(UPG_NUTS, 1); AMMO(ITEM_NUT) += sAmmoRefillCounts[item - ITEM_NUTS_5]; // Translates to: "Deku Nuts %d(%d)=%d BS_count=%d" @@ -1583,7 +1585,7 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { } return ITEM_NONE; } else if (item == ITEM_BOMBCHU) { - if (gSaveContext.items[slot] == ITEM_NONE) { + if (gSaveContext.inventory.items[slot] == ITEM_NONE) { INV_CONTENT(ITEM_BOMBCHU) = ITEM_BOMBCHU; AMMO(ITEM_BOMBCHU) = 10; return ITEM_NONE; @@ -1595,7 +1597,7 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { return ITEM_NONE; } } else if ((item == ITEM_BOMBCHUS_5) || (item == ITEM_BOMBCHUS_20)) { - if (gSaveContext.items[slot] == ITEM_NONE) { + if (gSaveContext.inventory.items[slot] == ITEM_NONE) { INV_CONTENT(ITEM_BOMBCHU) = ITEM_BOMBCHU; AMMO(ITEM_BOMBCHU) += sAmmoRefillCounts[item - ITEM_BOMBCHUS_5 + 8]; return ITEM_NONE; @@ -1660,7 +1662,7 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { } return ITEM_NONE; } else if (item == ITEM_BEAN) { - if (gSaveContext.items[slot] == ITEM_NONE) { + if (gSaveContext.inventory.items[slot] == ITEM_NONE) { INV_CONTENT(item) = item; AMMO(ITEM_BEAN) = 1; BEANS_BOUGHT = 1; @@ -1670,7 +1672,7 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { } return ITEM_NONE; } else if ((item == ITEM_HEART_PIECE_2) || (item == ITEM_HEART_PIECE)) { - gSaveContext.questItems += 1 << (QUEST_HEART_PIECE + 4); + gSaveContext.inventory.questItems += 1 << (QUEST_HEART_PIECE + 4); return ITEM_NONE; } else if (item == ITEM_HEART_CONTAINER) { gSaveContext.healthCapacity += 0x10; @@ -1712,8 +1714,8 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { return ITEM_NONE; } else if (item == ITEM_BOTTLE) { for (i = 0; i < 4; i++) { - if (gSaveContext.items[SLOT(item) + i] == ITEM_NONE) { - gSaveContext.items[SLOT(item) + i] = item; + if (gSaveContext.inventory.items[SLOT(item) + i] == ITEM_NONE) { + gSaveContext.inventory.items[SLOT(item) + i] = item; return ITEM_NONE; } } @@ -1727,7 +1729,7 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { } for (i = 0; i < 4; i++) { - if (gSaveContext.items[bottleSlot + i] == ITEM_BOTTLE) { + if (gSaveContext.inventory.items[bottleSlot + i] == ITEM_BOTTLE) { // Translates to: "Item_Pt(1)=%d Item_Pt(2)=%d Item_Pt(3)=%d Empty Bottle=%d Content=%d" osSyncPrintf("Item_Pt(1)=%d Item_Pt(2)=%d Item_Pt(3)=%d 空瓶=%d 中味=%d\n", gSaveContext.equips.cButtonSlots[0], gSaveContext.equips.cButtonSlots[1], @@ -1747,14 +1749,14 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { gSaveContext.buttonStatus[3] = BTN_ENABLED; } - gSaveContext.items[bottleSlot + i] = item; + gSaveContext.inventory.items[bottleSlot + i] = item; return ITEM_NONE; } } } else { for (i = 0; i < 4; i++) { - if (gSaveContext.items[bottleSlot + i] == ITEM_NONE) { - gSaveContext.items[bottleSlot + i] = item; + if (gSaveContext.inventory.items[bottleSlot + i] == ITEM_NONE) { + gSaveContext.inventory.items[bottleSlot + i] = item; return ITEM_NONE; } } @@ -1784,7 +1786,7 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { return ITEM_NONE; } - oldItem = gSaveContext.items[slot]; + oldItem = gSaveContext.inventory.items[slot]; osSyncPrintf("Item_Register(%d)=%d %d\n", slot, item, oldItem); INV_CONTENT(item) = item; @@ -1805,7 +1807,7 @@ u8 Item_CheckObtainability(u8 item) { } osSyncPrintf(VT_FGCOL(GREEN)); - osSyncPrintf("item_get_non_setting=%d pt=%d z=%x\n", item, slot, gSaveContext.items[slot]); + osSyncPrintf("item_get_non_setting=%d pt=%d z=%x\n", item, slot, gSaveContext.inventory.items[slot]); osSyncPrintf(VT_RST); if ((item >= ITEM_MEDALLION_FOREST) && (item <= ITEM_MEDALLION_LIGHT)) { @@ -1815,25 +1817,26 @@ u8 Item_CheckObtainability(u8 item) { } else if ((item >= ITEM_SWORD_KOKIRI) && (item <= ITEM_SWORD_BGS)) { if (item == ITEM_SWORD_BGS) { return ITEM_NONE; - } else if ((gBitFlags[item - ITEM_SWORD_KOKIRI] << gEquipShifts[EQUIP_SWORD]) & gSaveContext.equipment) { + } else if ((gBitFlags[item - ITEM_SWORD_KOKIRI] << gEquipShifts[EQUIP_SWORD]) & + gSaveContext.inventory.equipment) { return item; } else { return ITEM_NONE; } } else if ((item >= ITEM_SHIELD_DEKU) && (item <= ITEM_SHIELD_MIRROR)) { - if ((gBitFlags[item - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_SHIELD]) & gSaveContext.equipment) { + if ((gBitFlags[item - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_SHIELD]) & gSaveContext.inventory.equipment) { return item; } else { return ITEM_NONE; } } else if ((item >= ITEM_TUNIC_KOKIRI) && (item <= ITEM_TUNIC_ZORA)) { - if ((gBitFlags[item - ITEM_TUNIC_KOKIRI] << gEquipShifts[EQUIP_TUNIC]) & gSaveContext.equipment) { + if ((gBitFlags[item - ITEM_TUNIC_KOKIRI] << gEquipShifts[EQUIP_TUNIC]) & gSaveContext.inventory.equipment) { return item; } else { return ITEM_NONE; } } else if ((item >= ITEM_BOOTS_KOKIRI) && (item <= ITEM_BOOTS_HOVER)) { - if ((gBitFlags[item - ITEM_BOOTS_KOKIRI] << gEquipShifts[EQUIP_BOOTS]) & gSaveContext.equipment) { + if ((gBitFlags[item - ITEM_BOOTS_KOKIRI] << gEquipShifts[EQUIP_BOOTS]) & gSaveContext.inventory.equipment) { return item; } else { return ITEM_NONE; @@ -1904,13 +1907,13 @@ u8 Item_CheckObtainability(u8 item) { } for (i = 0; i < 4; i++) { - if (gSaveContext.items[bottleSlot + i] == ITEM_BOTTLE) { + if (gSaveContext.inventory.items[bottleSlot + i] == ITEM_BOTTLE) { return ITEM_NONE; } } } else { for (i = 0; i < 4; i++) { - if (gSaveContext.items[bottleSlot + i] == ITEM_NONE) { + if (gSaveContext.inventory.items[bottleSlot + i] == ITEM_NONE) { return ITEM_NONE; } } @@ -1919,7 +1922,7 @@ u8 Item_CheckObtainability(u8 item) { return ITEM_NONE; } - return gSaveContext.items[slot]; + return gSaveContext.inventory.items[slot]; } void Inventory_DeleteItem(u16 item, u16 invSlot) { @@ -1929,9 +1932,9 @@ void Inventory_DeleteItem(u16 item, u16 invSlot) { BEANS_BOUGHT = 0; } - gSaveContext.items[invSlot] = ITEM_NONE; + gSaveContext.inventory.items[invSlot] = ITEM_NONE; - osSyncPrintf("\nItem_Register(%d)\n", invSlot, gSaveContext.items[invSlot]); + osSyncPrintf("\nItem_Register(%d)\n", invSlot, gSaveContext.inventory.items[invSlot]); for (i = 1; i < 4; i++) { if (gSaveContext.equips.buttonItems[i] == item) { @@ -1944,9 +1947,9 @@ void Inventory_DeleteItem(u16 item, u16 invSlot) { s32 Inventory_ReplaceItem(GlobalContext* globalCtx, u16 oldItem, u16 newItem) { s16 i; - for (i = 0; i < ARRAY_COUNT(gSaveContext.items); i++) { - if (gSaveContext.items[i] == oldItem) { - gSaveContext.items[i] = newItem; + for (i = 0; i < ARRAY_COUNT(gSaveContext.inventory.items); i++) { + if (gSaveContext.inventory.items[i] == oldItem) { + gSaveContext.inventory.items[i] = newItem; // Translates to: "Item Purge (%d)" osSyncPrintf("アイテム消去(%d)\n", i); for (i = 1; i < 4; i++) { @@ -1964,7 +1967,7 @@ s32 Inventory_ReplaceItem(GlobalContext* globalCtx, u16 oldItem, u16 newItem) { } s32 Inventory_HasEmptyBottle(void) { - u8* items = gSaveContext.items; + u8* items = gSaveContext.inventory.items; if (items[SLOT_BOTTLE_1] == ITEM_BOTTLE) { return 1; @@ -1980,7 +1983,7 @@ s32 Inventory_HasEmptyBottle(void) { } s32 Inventory_HasSpecificBottle(u8 bottleItem) { - u8* items = gSaveContext.items; + u8* items = gSaveContext.inventory.items; if (items[SLOT_BOTTLE_1] == bottleItem) { return 1; @@ -1998,15 +2001,15 @@ s32 Inventory_HasSpecificBottle(u8 bottleItem) { void Inventory_UpdateBottleItem(GlobalContext* globalCtx, u8 item, u8 button) { osSyncPrintf("item_no=%x, c_no=%x, Pt=%x Item_Register=%x\n", item, button, gSaveContext.equips.cButtonSlots[button - 1], - gSaveContext.items[gSaveContext.equips.cButtonSlots[button - 1]]); + gSaveContext.inventory.items[gSaveContext.equips.cButtonSlots[button - 1]]); // Special case to only empty half of a Lon Lon Milk Bottle - if ((gSaveContext.items[gSaveContext.equips.cButtonSlots[button - 1]] == ITEM_MILK_BOTTLE) && + if ((gSaveContext.inventory.items[gSaveContext.equips.cButtonSlots[button - 1]] == ITEM_MILK_BOTTLE) && (item == ITEM_BOTTLE)) { item = ITEM_MILK_HALF; } - gSaveContext.items[gSaveContext.equips.cButtonSlots[button - 1]] = item; + gSaveContext.inventory.items[gSaveContext.equips.cButtonSlots[button - 1]] = item; gSaveContext.equips.buttonItems[button] = item; Interface_LoadItemIcon1(globalCtx, button); @@ -2023,7 +2026,7 @@ s32 Inventory_ConsumeFairy(GlobalContext* globalCtx) { bottleSlot = SLOT(ITEM_FAIRY); for (i = 0; i < 4; i++) { - if (gSaveContext.items[bottleSlot + i] == ITEM_FAIRY) { + if (gSaveContext.inventory.items[bottleSlot + i] == ITEM_FAIRY) { for (j = 1; j < 4; j++) { if (gSaveContext.equips.buttonItems[j] == ITEM_FAIRY) { gSaveContext.equips.buttonItems[j] = ITEM_BOTTLE; @@ -2035,7 +2038,7 @@ s32 Inventory_ConsumeFairy(GlobalContext* globalCtx) { } // Translates to: "Fairy Usage=%d" osSyncPrintf("妖精使用=%d\n", bottleSlot); - gSaveContext.items[bottleSlot + i] = ITEM_BOTTLE; + gSaveContext.inventory.items[bottleSlot + i] = ITEM_BOTTLE; return 1; } } @@ -3124,7 +3127,7 @@ void Interface_Draw(GlobalContext* globalCtx) { case SCENE_GANON_SONOGO: case SCENE_GANONTIKA_SONOGO: case SCENE_TAKARAYA: - if (gSaveContext.dungeonKeys[gSaveContext.mapIndex] >= 0) { + if (gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] >= 0) { // Small Key Icon gDPPipeSync(oGfxCtx->overlay.p++); gDPSetPrimColor(oGfxCtx->overlay.p++, 0, 0, 200, 230, 255, interfaceCtx->magicAlpha); @@ -3139,7 +3142,7 @@ void Interface_Draw(GlobalContext* globalCtx) { PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0); interfaceCtx->counterDigits[2] = 0; - interfaceCtx->counterDigits[3] = gSaveContext.dungeonKeys[gSaveContext.mapIndex]; + interfaceCtx->counterDigits[3] = gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex]; while (interfaceCtx->counterDigits[3] >= 10) { interfaceCtx->counterDigits[2]++; diff --git a/src/code/z_play.c b/src/code/z_play.c index 29cad2538..370005456 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -234,7 +234,7 @@ void Gameplay_Init(GlobalContext* globalCtx) { globalCtx->cameraPtrs[0]->uid = 0; globalCtx->activeCamera = 0; func_8005AC48(&globalCtx->mainCamera, 0xFF); - func_800A9D28(globalCtx, &globalCtx->sub_1F74); + Sram_Init(globalCtx, &globalCtx->sramCtx); func_80112098(globalCtx); func_80110F68(globalCtx); func_80110450(globalCtx); @@ -317,7 +317,7 @@ void Gameplay_Init(GlobalContext* globalCtx) { if (gSaveContext.nextDayTime != 0xFFFF) { if (gSaveContext.nextDayTime == 0x8001) { - gSaveContext.unk_14++; + gSaveContext.numDays++; gSaveContext.unk_18++; gSaveContext.dogIsLost = true; if (Inventory_ReplaceItem(globalCtx, ITEM_WEIRD_EGG, ITEM_CHICKEN) || @@ -1724,12 +1724,12 @@ s16 func_800C09D8(GlobalContext* globalCtx, s16 camId, s16 arg2) { } void Gameplay_SaveSceneFlags(GlobalContext* globalCtx) { - SaveSceneFlags* sceneFlags = &gSaveContext.sceneFlags[globalCtx->sceneNum]; + SavedSceneFlags* savedSceneFlags = &gSaveContext.sceneFlags[globalCtx->sceneNum]; - sceneFlags->chest = globalCtx->actorCtx.flags.chest; - sceneFlags->swch = globalCtx->actorCtx.flags.swch; - sceneFlags->clear = globalCtx->actorCtx.flags.clear; - sceneFlags->collect = globalCtx->actorCtx.flags.collect; + savedSceneFlags->chest = globalCtx->actorCtx.flags.chest; + savedSceneFlags->swch = globalCtx->actorCtx.flags.swch; + savedSceneFlags->clear = globalCtx->actorCtx.flags.clear; + savedSceneFlags->collect = globalCtx->actorCtx.flags.collect; } void Gameplay_SetRespawnData(GlobalContext* globalCtx, s32 respawnMode, s16 entranceIndex, s32 roomIndex, diff --git a/src/code/z_sram.c b/src/code/z_sram.c index 06517245f..1145bd9b3 100644 --- a/src/code/z_sram.c +++ b/src/code/z_sram.c @@ -1,25 +1,905 @@ #include "global.h" +#include "vt.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram/func_800A81A0.s") +// these are the main substructs of save context. +// we are going to hold off on splitting save context until later on, +// so these temporary structs will live here for now. -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram/func_800A82C8.s") +typedef struct { + /* 0x00 */ char newf[6]; // string "ZELDAZ" + /* 0x06 */ s16 deaths; + /* 0x08 */ char playerName[8]; + /* 0x10 */ s16 n64ddFlag; + /* 0x12 */ s16 healthCapacity; // "max_life" + /* 0x14 */ s16 health; // "now_life" + /* 0x16 */ s8 magicLevel; + /* 0x17 */ s8 magic; + /* 0x18 */ s16 rupees; + /* 0x1A */ u16 swordHealth; + /* 0x1C */ u16 naviTimer; + /* 0x1E */ u8 magicAcquired; + /* 0x1F */ u8 unk_1F; + /* 0x20 */ u8 doubleMagic; + /* 0x21 */ u8 doubleDefense; + /* 0x22 */ u8 bgsFlag; + /* 0x23 */ u8 ocarinaGameReward; + /* 0x24 */ ItemEquips childEquips; + /* 0x2E */ ItemEquips adultEquips; + /* 0x38 */ u32 unk_38; // this may be incorrect, currently used for alignement + /* 0x3C */ char unk_3C[0x0E]; + /* 0x4A */ s16 savedSceneNum; +} SavePlayerData; // size = 0x4C -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram/func_800A8484.s") +typedef struct { + /* 0x0000 */ SavePlayerData playerData; // "S_Private" substruct name + /* 0x004C */ ItemEquips equips; + /* 0x0058 */ Inventory inventory; + /* 0x00B8 */ SavedSceneFlags sceneFlags[124]; + /* 0x0E48 */ FaroresWindData fw; + /* 0x0E70 */ char unk_E70[0x10]; + /* 0x0E80 */ s32 gsFlags[6]; + /* 0x0E98 */ char unk_E98[0x10]; + /* 0x0EA8 */ s32 horseRaceRecord; + /* 0x0EAC */ char unk_EAC[0x0C]; + /* 0x0EB8 */ u16 eventChkInf[14]; // "event_chk_inf" + /* 0x0ED4 */ u16 itemGetInf[4]; // "item_get_inf" + /* 0x0EDC */ u16 infTable[30]; // "inf_table" + /* 0x0F18 */ char unk_F18[0x04]; + /* 0x0F1C */ u32 worldMapAreaData; // "area_arrival" + /* 0x0F20 */ char unk_F20[0x4]; + /* 0x0F24 */ u8 scarecrowCustomSongSet; + /* 0x0F25 */ u8 scarecrowCustomSong[0x360]; + /* 0x1285 */ char unk_1285[0x24]; + /* 0x12A9 */ u8 scarecrowSpawnSongSet; + /* 0x12AA */ u8 scarecrowSpawnSong[0x80]; + /* 0x132A */ char unk_132A[0x02]; + /* 0x132C */ HorseData horseData; + /* 0x1336 */ u16 checksum; // "check_sum" +} SaveInfo; // size = 0x1338 -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram/func_800A88D4.s") +typedef struct { + /* 0x00 */ s32 entranceIndex; + /* 0x04 */ s32 linkAge; // 0: Adult; 1: Child + /* 0x08 */ s32 cutsceneIndex; + /* 0x0C */ u16 dayTime; // "zelda_time" + /* 0x10 */ s32 nightFlag; + /* 0x14 */ s32 numDays; + /* 0x18 */ s32 unk_18; // increments with numDays, gets reset by goron for bgs and one other use + /* 0x1C */ SaveInfo info; // "information" +} Save; // size = 0x1354 -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram/func_800A8A20.s") +#define SAVE_PLAYER_DATA (*((SavePlayerData*)&gSaveContext.newf)) +#define SAVE_INFO (*((SaveInfo*)&gSaveContext.newf)) -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram/func_800A9258.s") +#define SLOT_SIZE (sizeof(SaveContext) + 0x28) +#define CHECKSUM_SIZE (sizeof(Save) / 2) -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram/func_800A96D0.s") +#define DEATHS OFFSETOF(SaveContext, deaths) +#define NAME OFFSETOF(SaveContext, playerName) +#define N64DD OFFSETOF(SaveContext, n64ddFlag) +#define HEALTH_CAP OFFSETOF(SaveContext, healthCapacity) +#define QUEST OFFSETOF(SaveContext, inventory.questItems) +#define DEFENSE OFFSETOF(SaveContext, inventory.defenseHearts) +#define HEALTH OFFSETOF(SaveContext, health) -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram/func_800A97F0.s") +#define SLOT_OFFSET(idx) (SLOT_SIZE * idx + 0x20) -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram/func_800A9A9C.s") +u16 gSramSlotOffsets[][3] = { + { + SLOT_OFFSET(0), + SLOT_OFFSET(1), + SLOT_OFFSET(2), + }, + { + SLOT_OFFSET(3), + SLOT_OFFSET(4), + SLOT_OFFSET(5), + }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram/func_800A9AD0.s") +char sZeldaMagic[] = { '\0', '\0', '\0', '\x98', '\x09', '\x10', '\x21', 'Z', 'E', 'L', 'D', 'A' }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram/func_800A9CD4.s") +SavePlayerData sNewSavePlayerData = { + { '\0', '\0', '\0', '\0', '\0', '\0' }, // newf + 0, // deaths + { 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E }, // playerName + 0, // n64ddFlag + 0x30, // healthCapacity + 0x30, // heartStatus + 0, // magicLevel + 0x30, // magic + 0, // rupees + 0, // swordHealth + 0, // naviTimer + 0, // magicAcquired + 0, // unk_1F + 0, // doubleMagic + 0, // doubleDefense + 0, // bgsFlag + 0, // ocarinaGameReward + { + { ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems + { SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots + 0, // equipment + }, // childEquips + { + { ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems + { SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots + 0, // equipment + }, // adultEquips + 0, // unk_38 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // unk_3C + 0x34, // savedSceneNum +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram/func_800A9D28.s") +ItemEquips sNewSaveEquips = { + { ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems + { SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots + 0x1100, // equipment +}; + +Inventory sNewSaveInventory = { + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, // items + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ammo + 0x1100, // equipment + 0, // upgrades + 0, // questItems + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // dungeonItems + { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }, // dungeonKeys + 0, // defenseHearts + 0, // gsTokens +}; + +u16 sNewSaveChecksum = 0; + +/** + * Initialize new save. + * This save has an empty inventory with 3 hearts and single magic. + */ +void Sram_InitNewSave(void) { + SaveContext* temp = &gSaveContext; + + bzero(&SAVE_INFO, sizeof(SaveInfo)); + gSaveContext.numDays = 0; + gSaveContext.unk_18 = 0; + + SAVE_PLAYER_DATA = sNewSavePlayerData; + gSaveContext.equips = sNewSaveEquips; + gSaveContext.inventory = sNewSaveInventory; + + temp->checksum = sNewSaveChecksum; + gSaveContext.horseData.scene = SCENE_SPOT00; + gSaveContext.horseData.pos.x = -1840; + gSaveContext.horseData.pos.y = 72; + gSaveContext.horseData.pos.z = 5497; + gSaveContext.horseData.angle = -0x6AD9; + gSaveContext.magicLevel = 0; + gSaveContext.infTable[29] = 1; + gSaveContext.sceneFlags[5].swch = 0x40000000; +} + +SavePlayerData sDebugSavePlayerData = { + { 'Z', 'E', 'L', 'D', 'A', 'Z' }, // newf + 0, // deaths + { 0x15, 0x12, 0x17, 0x14, 0x3E, 0x3E, 0x3E, 0x3E }, // playerName ( "LINK" ) + 0, // n64ddFlag + 0xE0, // healthCapacity + 0xE0, // health + 0, // magicLevel + 0x30, // magic + 150, // rupees + 8, // swordHealth + 0, // naviTimer + 1, // magicAcquired + 0, // unk_1F + 0, // doubleMagic + 0, // doubleDefense + 0, // bgsFlag + 0, // ocarinaGameReward + { + { ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems + { SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots + 0, // equipment + }, // childEquips + { + { ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems + { SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots + 0, // equipment + }, // adultEquips + 0, // unk_38 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // unk_3C + 0x51, // savedSceneNum +}; + +ItemEquips sDebugSaveEquips = { + { ITEM_SWORD_MASTER, ITEM_BOW, ITEM_BOMB, ITEM_OCARINA_FAIRY }, // buttonItems + { SLOT_BOW, SLOT_BOMB, SLOT_OCARINA }, // cButtonSlots + 0x1122, // equipment +}; + +Inventory sDebugSaveInventory = { + { ITEM_STICK, ITEM_NUT, ITEM_BOMB, ITEM_BOW, ITEM_ARROW_FIRE, ITEM_DINS_FIRE, + ITEM_SLINGSHOT, ITEM_OCARINA_FAIRY, ITEM_BOMBCHU, ITEM_HOOKSHOT, ITEM_ARROW_ICE, ITEM_FARORES_WIND, + ITEM_BOOMERANG, ITEM_LENS, ITEM_BEAN, ITEM_HAMMER, ITEM_ARROW_LIGHT, ITEM_NAYRUS_LOVE, + ITEM_BOTTLE, ITEM_POTION_RED, ITEM_POTION_GREEN, ITEM_POTION_BLUE, ITEM_POCKET_EGG, ITEM_WEIRD_EGG }, // items + { 50, 50, 10, 30, 1, 1, 30, 1, 50, 1, 1, 1, 1, 1, 1, 1 }, // ammo + 0x7777, // equipment + 0x125249, // upgrades + 0x1E3FFFF, // questItems + { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // dungeonItems + { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }, // dungeonKeys + 0, // defenseHearts + 0, // gsTokens +}; + +u16 sDebugSaveChecksum = 0; + +/** + * Initialize debug save. This is also used on the Title Screen + * This save has a mostly full inventory with 10 hearts and single magic. + * + * Some noteable flags that are set: + * Showed Mido sword/shield, met Deku Tree, Deku Tree mouth opened, + * used blue warp in Gohmas room, Zelda fled castle, light arrow cutscene watched, + * and set water level in Water Temple to lowest level. + */ +void Sram_InitDebugSave(void) { + SaveContext* temp = &gSaveContext; + + bzero(&SAVE_INFO, sizeof(SaveInfo)); + gSaveContext.numDays = 0; + gSaveContext.unk_18 = 0; + + SAVE_PLAYER_DATA = sDebugSavePlayerData; + gSaveContext.equips = sDebugSaveEquips; + gSaveContext.inventory = sDebugSaveInventory; + + temp->checksum = sDebugSaveChecksum; + gSaveContext.horseData.scene = SCENE_SPOT00; + gSaveContext.horseData.pos.x = -1840; + gSaveContext.horseData.pos.y = 72; + gSaveContext.horseData.pos.z = 5497; + gSaveContext.horseData.angle = -0x6AD9; + gSaveContext.infTable[0] |= 0x5009; + gSaveContext.eventChkInf[0] |= 0x123F; + gSaveContext.eventChkInf[8] |= 1; + gSaveContext.eventChkInf[12] |= 0x10; + + if (LINK_AGE_IN_YEARS == YEARS_CHILD) { + gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KOKIRI; + Inventory_ChangeEquipment(EQUIP_SWORD, 1); + if (gSaveContext.fileNum == 0xFF) { + gSaveContext.equips.buttonItems[1] = ITEM_SLINGSHOT; + gSaveContext.equips.cButtonSlots[0] = SLOT_SLINGSHOT; + Inventory_ChangeEquipment(EQUIP_SHIELD, 1); + } + } + + gSaveContext.entranceIndex = 0xCD; + gSaveContext.magicLevel = 0; + gSaveContext.sceneFlags[5].swch = 0x40000000; +} + +/** + * Copy save currently on the buffer to Save Context and complete various tasks to open the save. + * This includes: + * - Set proper entrance depending on where the game was saved + * - If health is less than 3 hearts, give 3 hearts + * - If either scarecrow song is set, copy them from save context to the proper location + * - Handle a case where the player saved and quit after zelda cutscene but didnt get the song + * - Give and equip master sword if player is adult and doesnt have kokiri sword (bug?) + * - Revert any trade items that spoil + */ +#ifdef NON_MATCHING +// regalloc differences at the end +void Sram_OpenSave(SramContext* sramCtx) { + static s16 dungeonEntrances[] = { + 0x0000, 0x0004, 0x0028, 0x0169, 0x0165, 0x0010, 0x0082, 0x0037, + 0x0098, 0x0088, 0x041B, 0x0008, 0x0486, 0x0467, 0x0179, 0x056C, + }; + u16 i; + u16 j; + u8* ptr; + + osSyncPrintf("個人File作成\n"); // Create personal file + i = gSramSlotOffsets[0][gSaveContext.fileNum]; + osSyncPrintf("ぽいんと=%x(%d)\n", i, gSaveContext.fileNum); // Point= + + MemCopy(&gSaveContext, sramCtx->readBuff + i, sizeof(Save)); + + osSyncPrintf(VT_FGCOL(YELLOW)); + osSyncPrintf("SCENE_DATA_ID = %d SceneNo = %d\n", gSaveContext.savedSceneNum, + ((void)0, gSaveContext.entranceIndex)); + + switch (gSaveContext.savedSceneNum) { + case SCENE_YDAN: + case SCENE_DDAN: + case SCENE_BDAN: + case SCENE_BMORI1: + case SCENE_HIDAN: + case SCENE_MIZUSIN: + case SCENE_JYASINZOU: + case SCENE_HAKADAN: + case SCENE_HAKADANCH: + case SCENE_ICE_DOUKUTO: + case SCENE_GANON: + case SCENE_MEN: + case SCENE_GERUDOWAY: + case SCENE_GANONTIKA: + gSaveContext.entranceIndex = dungeonEntrances[gSaveContext.savedSceneNum]; + break; + case SCENE_YDAN_BOSS: + gSaveContext.entranceIndex = 0; + break; + case SCENE_DDAN_BOSS: + gSaveContext.entranceIndex = 4; + break; + case SCENE_BDAN_BOSS: + gSaveContext.entranceIndex = 0x28; + break; + case SCENE_MORIBOSSROOM: + gSaveContext.entranceIndex = 0x169; + break; + case SCENE_FIRE_BS: + gSaveContext.entranceIndex = 0x165; + break; + case SCENE_MIZUSIN_BS: + gSaveContext.entranceIndex = 0x10; + break; + case SCENE_JYASINBOSS: + gSaveContext.entranceIndex = 0x82; + break; + case SCENE_HAKADAN_BS: + gSaveContext.entranceIndex = 0x37; + break; + case SCENE_GANON_SONOGO: + case SCENE_GANONTIKA_SONOGO: + case SCENE_GANON_BOSS: + case SCENE_GANON_FINAL: + case SCENE_GANON_DEMO: + gSaveContext.entranceIndex = 0x41B; + break; + + default: + if (gSaveContext.savedSceneNum != SCENE_LINK_HOME) { + gSaveContext.entranceIndex = (LINK_AGE_IN_YEARS == YEARS_CHILD) ? 0xBB : 0x5F4; + } else { + gSaveContext.entranceIndex = 0xBB; + } + break; + } + + osSyncPrintf("scene_no = %d\n", gSaveContext.entranceIndex); + osSyncPrintf(VT_RST); + + if (gSaveContext.health < 0x30) { + gSaveContext.health = 0x30; + } + + if (gSaveContext.scarecrowCustomSongSet) { + osSyncPrintf(VT_FGCOL(BLUE)); + osSyncPrintf("\n====================================================================\n"); + + MemCopy(gScarecrowCustomSongPtr, &gSaveContext.scarecrowCustomSong, 0x360); + + ptr = gScarecrowCustomSongPtr; + for (i = 0; i < 0x360; i++, ptr++) { + osSyncPrintf("%d, ", *ptr); + } + + osSyncPrintf("\n====================================================================\n"); + osSyncPrintf(VT_RST); + } + + if (gSaveContext.scarecrowSpawnSongSet) { + osSyncPrintf(VT_FGCOL(GREEN)); + osSyncPrintf("\n====================================================================\n"); + + MemCopy(gScarecrowSpawnSongPtr, &gSaveContext.scarecrowSpawnSong, 0x80); + + ptr = gScarecrowSpawnSongPtr; + for (i = 0; i < 0x80; i++, ptr++) { + osSyncPrintf("%d, ", *ptr); + } + + osSyncPrintf("\n====================================================================\n"); + osSyncPrintf(VT_RST); + } + + // if zelda cutscene has been watched but lullaby was not obtained, restore cutscene and take away letter + if ((gSaveContext.eventChkInf[4] & 1) && !CHECK_QUEST_ITEM(QUEST_SONG_LULLABY)) { + gSaveContext.eventChkInf[4] &= ~1; + INV_CONTENT(ITEM_LETTER_ZELDA) = ITEM_CHICKEN; + + for (i = 1; i < 4; i++) { + if (gSaveContext.equips.buttonItems[i] == ITEM_LETTER_ZELDA) { + gSaveContext.equips.buttonItems[i] = ITEM_CHICKEN; + } + } + } + + // check for owning kokiri sword.. to restore master sword? bug or debug feature? + if (LINK_AGE_IN_YEARS == YEARS_ADULT && !CHECK_OWNED_EQUIP(EQUIP_SWORD, 1)) { + gSaveContext.inventory.equipment |= gBitFlags[1] << gEquipShifts[EQUIP_SWORD]; + gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER; + gSaveContext.equips.equipment &= ~0xF; + gSaveContext.equips.equipment |= 2; + } + + for (i = 0; i < ARRAY_COUNT(gSpoilingItems); i++) { + if (INV_CONTENT(ITEM_TRADE_ADULT) == gSpoilingItems[i]) { + INV_CONTENT(gSpoilingItemReverts[i]) = gSpoilingItemReverts[i]; + + for (j = 1; j < 4; j++) { + if (gSaveContext.equips.buttonItems[j] == gSpoilingItems[i]) { + gSaveContext.equips.buttonItems[j] = gSpoilingItemReverts[i]; + } + } + } + } + + gSaveContext.magicLevel = 0; +} +#else +s16 dungeonEntrances[] = { + 0x0000, 0x0004, 0x0028, 0x0169, 0x0165, 0x0010, 0x0082, 0x0037, + 0x0098, 0x0088, 0x041B, 0x0008, 0x0486, 0x0467, 0x0179, 0x056C, +}; +#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram/Sram_OpenSave.s") +#endif + +/** + * Write the contents of the Save Context to a main and backup slot in SRAM. + * Note: The whole Save Context is written even though only the `save` substruct is read back later + */ +void Sram_WriteSave(s32 unused) { + u16 offset; + u16 checksum; + u16 j; + u16* ptr; + + gSaveContext.checksum = 0; + + ptr = (u16*)&gSaveContext; + checksum = 0; + j = 0; + + for (offset = 0; offset < CHECKSUM_SIZE; offset++) { + if (++j == 0x20U) { + j = 0; + } + checksum += *ptr++; + } + + gSaveContext.checksum = checksum; + + ptr = (u16*)&gSaveContext; + checksum = 0; + + for (offset = 0; offset < CHECKSUM_SIZE; offset++) { + if (++j == 0x20U) { + j = 0; + } + checksum += *ptr++; + } + + offset = gSramSlotOffsets[0][gSaveContext.fileNum]; + SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + offset, &gSaveContext, SLOT_SIZE, OS_WRITE); + + ptr = (u16*)&gSaveContext; + checksum = 0; + + for (offset = 0; offset < CHECKSUM_SIZE; offset++) { + if (++j == 0x20U) { + j = 0; + } + checksum += *ptr++; + } + + offset = gSramSlotOffsets[1][gSaveContext.fileNum]; + SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + offset, &gSaveContext, SLOT_SIZE, OS_WRITE); +} + +/** + * For all 3 slots, verify that the checksum is correct. If corrupted, attempt to load a backup save. + * If backup is also corrupted, default to a new save (or debug save for slot 0 on debug rom). + * + * After verifying all 3 saves, pass relevant data to File Select to be displayed. + */ +#ifdef NON_MATCHING +// There's a problem with how "offset" is loaded +void Sram_VerifyAndLoadAllSaves(FileChooseContext* fileChooseCtx, SramContext* sramCtx) { + u16 slotNum; // 0x72 + u16 oldChecksum; + u16 newChecksum; + u16 dayTime; // 0x66 + // u16* offPtr; + s32 offset; + u16 i; + u16 j; + u16* ptr; + + osSyncPrintf("SRAM START─LOAD\n"); + bzero(sramCtx->readBuff, SRAM_SIZE); + SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ); + + dayTime = gSaveContext.dayTime; + + for (slotNum = 0; slotNum < 3; slotNum++) { + offset = gSramSlotOffsets[0][slotNum]; + osSyncPrintf("ぽいんと=%x(%d) SAVE_MAX=%d\n", offset, gSaveContext.fileNum, sizeof(Save)); + MemCopy(&gSaveContext, sramCtx->readBuff + offset, sizeof(Save)); + + oldChecksum = gSaveContext.checksum; + gSaveContext.checksum = 0; + osSyncPrintf("\n============= S(%d) =============\n", slotNum); + + // j = 0; + newChecksum = 0; + ptr = (u16*)&gSaveContext; + for (i = 0; i < CHECKSUM_SIZE; i++) { + j += 2; + newChecksum += *ptr++; + } + + // SAVE checksum calculation + osSyncPrintf("\nSAVEチェックサム計算 j=%x mmm=%x ", newChecksum, oldChecksum); + + if (oldChecksum != newChecksum) { + // checksum didnt match, try backup save + osSyncPrintf("ERROR!!! = %x(%d)\n", offset, slotNum); + offset = gSramSlotOffsets[1][slotNum]; + MemCopy(&gSaveContext, sramCtx->readBuff + offset, sizeof(Save)); + + oldChecksum = gSaveContext.checksum; + gSaveContext.checksum = 0; + osSyncPrintf("================= BACK─UP ========================\n"); + + newChecksum = 0; + ptr = (u16*)&gSaveContext; + for (i = 0; i < CHECKSUM_SIZE; i++) { + j += 2; + newChecksum += *ptr++; + } + // (B) SAVE checksum calculation + osSyncPrintf("\n(B)SAVEチェックサム計算 j=%x mmm=%x ", newChecksum, oldChecksum); + + if (oldChecksum != newChecksum) { + // backup save didnt work, make new save + // offPtr = &gSramSlotOffsets[1][slotNum]; + osSyncPrintf("ERROR!!! = %x(%d+3)\n", offset, slotNum); + bzero(&gSaveContext.entranceIndex, sizeof(gSaveContext.entranceIndex)); + bzero(&gSaveContext.linkAge, sizeof(gSaveContext.linkAge)); + bzero(&gSaveContext.cutsceneIndex, sizeof(gSaveContext.cutsceneIndex)); + bzero(&gSaveContext.dayTime, sizeof(gSaveContext.dayTime)); + bzero(&gSaveContext.nightFlag, sizeof(gSaveContext.nightFlag)); + bzero(&gSaveContext.numDays, sizeof(gSaveContext.numDays)); + bzero(&gSaveContext.unk_18, sizeof(gSaveContext.unk_18)); + + if (slotNum == 0) { + Sram_InitDebugSave(); + gSaveContext.newf[0] = 'Z'; + gSaveContext.newf[1] = 'E'; + gSaveContext.newf[2] = 'L'; + gSaveContext.newf[3] = 'D'; + gSaveContext.newf[4] = 'A'; + gSaveContext.newf[5] = 'Z'; + osSyncPrintf("newf=%x,%x,%x,%x,%x,%x\n", gSaveContext.newf[0], gSaveContext.newf[1], + gSaveContext.newf[2], gSaveContext.newf[3], gSaveContext.newf[4], + gSaveContext.newf[5]); + } else { + Sram_InitNewSave(); + } + + osSyncPrintf("\n--------------------------------------------------------------\n"); + + j = 0; + newChecksum = 0; + ptr = (u16*)&gSaveContext; + for (i = 0; i < CHECKSUM_SIZE; i++) { + osSyncPrintf("%x ", *ptr); + if (++j == 0x20) { + osSyncPrintf("\n"); + j = 0; + } + newChecksum += *ptr++; + } + + gSaveContext.checksum = newChecksum; + osSyncPrintf("\nCheck_Sum=%x(%x)\n", gSaveContext.checksum, newChecksum); + + offset = gSramSlotOffsets[1][slotNum]; + SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + offset, &gSaveContext, SLOT_SIZE, OS_WRITE); + + osSyncPrintf("????#%x,%x,%x,%x,%x,%x\n", gSaveContext.newf[0], gSaveContext.newf[1], + gSaveContext.newf[2], gSaveContext.newf[3], gSaveContext.newf[4], gSaveContext.newf[5]); + osSyncPrintf("\nぽいんと=%x(%d+3) check_sum=%x(%x)\n", offset, slotNum, gSaveContext.checksum, + newChecksum); + } + + offset = gSramSlotOffsets[0][slotNum]; + SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + offset, &gSaveContext, SLOT_SIZE, OS_WRITE); + + osSyncPrintf("ぽいんと=%x(%d) check_sum=%x(%x)\n", offset, slotNum, gSaveContext.checksum, newChecksum); + } else { + // SAVE data OK! ! ! ! + osSyncPrintf("\nSAVEデータ OK!!!!\n"); + } + } + + bzero(sramCtx->readBuff, SRAM_SIZE); + SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ); + gSaveContext.dayTime = dayTime; + + osSyncPrintf("SAVECT=%x, NAME=%x, LIFE=%x, ITEM=%x, 64DD=%x, HEART=%x\n", DEATHS, NAME, HEALTH_CAP, QUEST, N64DD, + DEFENSE); + + MemCopy(&fileChooseCtx->deaths[0], sramCtx->readBuff + SLOT_OFFSET(0) + DEATHS, sizeof(fileChooseCtx->deaths[0])); + MemCopy(&fileChooseCtx->deaths[1], sramCtx->readBuff + SLOT_OFFSET(1) + DEATHS, sizeof(fileChooseCtx->deaths[0])); + MemCopy(&fileChooseCtx->deaths[2], sramCtx->readBuff + SLOT_OFFSET(2) + DEATHS, sizeof(fileChooseCtx->deaths[0])); + + MemCopy(&fileChooseCtx->fileNames[0], sramCtx->readBuff + SLOT_OFFSET(0) + NAME, + sizeof(fileChooseCtx->fileNames[0])); + MemCopy(&fileChooseCtx->fileNames[1], sramCtx->readBuff + SLOT_OFFSET(1) + NAME, + sizeof(fileChooseCtx->fileNames[0])); + MemCopy(&fileChooseCtx->fileNames[2], sramCtx->readBuff + SLOT_OFFSET(2) + NAME, + sizeof(fileChooseCtx->fileNames[0])); + + MemCopy(&fileChooseCtx->healthCapacities[0], sramCtx->readBuff + SLOT_OFFSET(0) + HEALTH_CAP, + sizeof(fileChooseCtx->healthCapacities[0])); + MemCopy(&fileChooseCtx->healthCapacities[1], sramCtx->readBuff + SLOT_OFFSET(1) + HEALTH_CAP, + sizeof(fileChooseCtx->healthCapacities[0])); + MemCopy(&fileChooseCtx->healthCapacities[2], sramCtx->readBuff + SLOT_OFFSET(2) + HEALTH_CAP, + sizeof(fileChooseCtx->healthCapacities[0])); + + MemCopy(&fileChooseCtx->questItems[0], sramCtx->readBuff + SLOT_OFFSET(0) + QUEST, + sizeof(fileChooseCtx->questItems[0])); + MemCopy(&fileChooseCtx->questItems[1], sramCtx->readBuff + SLOT_OFFSET(1) + QUEST, + sizeof(fileChooseCtx->questItems[0])); + MemCopy(&fileChooseCtx->questItems[2], sramCtx->readBuff + SLOT_OFFSET(2) + QUEST, + sizeof(fileChooseCtx->questItems[0])); + + MemCopy(&fileChooseCtx->n64ddFlags[0], sramCtx->readBuff + SLOT_OFFSET(0) + N64DD, + sizeof(fileChooseCtx->n64ddFlags[0])); + MemCopy(&fileChooseCtx->n64ddFlags[1], sramCtx->readBuff + SLOT_OFFSET(1) + N64DD, + sizeof(fileChooseCtx->n64ddFlags[0])); + MemCopy(&fileChooseCtx->n64ddFlags[2], sramCtx->readBuff + SLOT_OFFSET(2) + N64DD, + sizeof(fileChooseCtx->n64ddFlags[0])); + + MemCopy(&fileChooseCtx->heartStatus[0], sramCtx->readBuff + SLOT_OFFSET(0) + DEFENSE, + sizeof(fileChooseCtx->heartStatus[0])); + MemCopy(&fileChooseCtx->heartStatus[1], sramCtx->readBuff + SLOT_OFFSET(1) + DEFENSE, + sizeof(fileChooseCtx->heartStatus[0])); + MemCopy(&fileChooseCtx->heartStatus[2], sramCtx->readBuff + SLOT_OFFSET(2) + DEFENSE, + sizeof(fileChooseCtx->heartStatus[0])); + + MemCopy(&fileChooseCtx->nowLife[0], sramCtx->readBuff + SLOT_OFFSET(0) + HEALTH, sizeof(fileChooseCtx->nowLife[0])); + MemCopy(&fileChooseCtx->nowLife[1], sramCtx->readBuff + SLOT_OFFSET(1) + HEALTH, sizeof(fileChooseCtx->nowLife[0])); + MemCopy(&fileChooseCtx->nowLife[2], sramCtx->readBuff + SLOT_OFFSET(2) + HEALTH, sizeof(fileChooseCtx->nowLife[0])); + + osSyncPrintf("f_64dd=%d, %d, %d\n", fileChooseCtx->n64ddFlags[0], fileChooseCtx->n64ddFlags[1], + fileChooseCtx->n64ddFlags[2]); + osSyncPrintf("heart_status=%d, %d, %d\n", fileChooseCtx->heartStatus[0], fileChooseCtx->heartStatus[1], + fileChooseCtx->heartStatus[2]); + osSyncPrintf("now_life=%d, %d, %d\n", fileChooseCtx->nowLife[0], fileChooseCtx->nowLife[1], + fileChooseCtx->nowLife[2]); +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram/Sram_VerifyAndLoadAllSaves.s") +#endif + +void Sram_InitSave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) { + u16 offset; + u16 j; + u16* ptr; + u16 checksum; + + if (fileChooseCtx->btnIdx != 0) { + Sram_InitNewSave(); + } else { + Sram_InitDebugSave(); + } + + gSaveContext.entranceIndex = 0xBB; + gSaveContext.linkAge = 1; + gSaveContext.dayTime = 0x6AAB; + gSaveContext.cutsceneIndex = 0xFFF1; + + if (fileChooseCtx->btnIdx == 0) { + gSaveContext.cutsceneIndex = 0; + } + + for (offset = 0; offset < 8; offset++) { + gSaveContext.playerName[offset] = fileChooseCtx->fileNames[fileChooseCtx->btnIdx][offset]; + } + + gSaveContext.newf[0] = 'Z'; + gSaveContext.newf[1] = 'E'; + gSaveContext.newf[2] = 'L'; + gSaveContext.newf[3] = 'D'; + gSaveContext.newf[4] = 'A'; + gSaveContext.newf[5] = 'Z'; + + gSaveContext.n64ddFlag = fileChooseCtx->n64ddFlag; + osSyncPrintf("64DDフラグ=%d\n", fileChooseCtx->n64ddFlag); + osSyncPrintf("newf=%x,%x,%x,%x,%x,%x\n", gSaveContext.newf[0], gSaveContext.newf[1], gSaveContext.newf[2], + gSaveContext.newf[3], gSaveContext.newf[4], gSaveContext.newf[5]); + osSyncPrintf("\n$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n"); + + ptr = (u16*)&gSaveContext; + j = 0; + checksum = 0; + + for (offset = 0; offset < CHECKSUM_SIZE; offset++) { + osSyncPrintf("%x ", *ptr); + checksum += *ptr++; + if (++j == 0x20u) { + osSyncPrintf("\n"); + j = 0; + } + } + + gSaveContext.checksum = checksum; + osSyncPrintf("\nチェックサム=%x\n", gSaveContext.checksum); // Checksum = %x + + offset = gSramSlotOffsets[0][gSaveContext.fileNum]; + osSyncPrintf("I=%x no=%d\n", offset, gSaveContext.fileNum); + MemCopy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save)); + + offset = gSramSlotOffsets[1][gSaveContext.fileNum]; + osSyncPrintf("I=%x no=%d\n", offset, gSaveContext.fileNum + 3); + MemCopy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save)); + + SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_WRITE); + + // SAVE end + osSyncPrintf("SAVE終了\n"); + osSyncPrintf("z_common_data.file_no = %d\n", gSaveContext.fileNum); + osSyncPrintf("SAVECT=%x, NAME=%x, LIFE=%x, ITEM=%x, SAVE_64DD=%x\n", DEATHS, NAME, HEALTH_CAP, QUEST, N64DD); + + j = gSramSlotOffsets[0][gSaveContext.fileNum]; + + MemCopy(&fileChooseCtx->deaths[gSaveContext.fileNum], sramCtx->readBuff + j + DEATHS, + sizeof(fileChooseCtx->deaths[0])); + MemCopy(&fileChooseCtx->fileNames[gSaveContext.fileNum], sramCtx->readBuff + j + NAME, + sizeof(fileChooseCtx->fileNames[0])); + MemCopy(&fileChooseCtx->healthCapacities[gSaveContext.fileNum], sramCtx->readBuff + j + HEALTH_CAP, + sizeof(fileChooseCtx->healthCapacities[0])); + MemCopy(&fileChooseCtx->questItems[gSaveContext.fileNum], sramCtx->readBuff + j + QUEST, + sizeof(fileChooseCtx->questItems[0])); + MemCopy(&fileChooseCtx->n64ddFlags[gSaveContext.fileNum], sramCtx->readBuff + j + N64DD, + sizeof(fileChooseCtx->n64ddFlags[0])); + MemCopy(&fileChooseCtx->heartStatus[gSaveContext.fileNum], sramCtx->readBuff + j + DEFENSE, + sizeof(fileChooseCtx->heartStatus[0])); + MemCopy(&fileChooseCtx->nowLife[gSaveContext.fileNum], sramCtx->readBuff + j + HEALTH, + sizeof(fileChooseCtx->nowLife[0])); + + osSyncPrintf("f_64dd[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->n64ddFlags[gSaveContext.fileNum]); + osSyncPrintf("heart_status[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->heartStatus[gSaveContext.fileNum]); + osSyncPrintf("now_life[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->nowLife[gSaveContext.fileNum]); +} + +void Sram_EraseSave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) { + s32 offset; + + Sram_InitNewSave(); + + offset = gSramSlotOffsets[0][fileChooseCtx->selectedFileIdx]; + MemCopy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save)); + SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + offset, &gSaveContext, SLOT_SIZE, OS_WRITE); + + MemCopy(&fileChooseCtx->n64ddFlags[fileChooseCtx->selectedFileIdx], sramCtx->readBuff + offset + N64DD, + sizeof(fileChooseCtx->n64ddFlags[0])); + + offset = gSramSlotOffsets[1][fileChooseCtx->selectedFileIdx]; + MemCopy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save)); + SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + offset, &gSaveContext, SLOT_SIZE, OS_WRITE); + + osSyncPrintf("CLEAR終了\n"); +} + +void Sram_CopySave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) { + s32 offset; + + osSyncPrintf("READ=%d(%x) COPY=%d(%x)\n", fileChooseCtx->selectedFileIdx, + gSramSlotOffsets[0][fileChooseCtx->selectedFileIdx], fileChooseCtx->copyDestFileIdx, + gSramSlotOffsets[0][fileChooseCtx->copyDestFileIdx]); + + offset = gSramSlotOffsets[0][fileChooseCtx->selectedFileIdx]; + MemCopy(&gSaveContext, sramCtx->readBuff + offset, sizeof(Save)); + + offset = gSramSlotOffsets[0][fileChooseCtx->copyDestFileIdx]; + MemCopy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save)); + + offset = gSramSlotOffsets[1][fileChooseCtx->copyDestFileIdx]; + MemCopy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save)); + + SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_WRITE); + + offset = gSramSlotOffsets[0][fileChooseCtx->copyDestFileIdx]; + + MemCopy(&fileChooseCtx->deaths[fileChooseCtx->copyDestFileIdx], sramCtx->readBuff + offset + DEATHS, + sizeof(fileChooseCtx->deaths[0])); + MemCopy(&fileChooseCtx->fileNames[fileChooseCtx->copyDestFileIdx], sramCtx->readBuff + offset + NAME, + sizeof(fileChooseCtx->fileNames[0])); + MemCopy(&fileChooseCtx->healthCapacities[fileChooseCtx->copyDestFileIdx], sramCtx->readBuff + offset + HEALTH_CAP, + sizeof(fileChooseCtx->healthCapacities[0])); + MemCopy(&fileChooseCtx->questItems[fileChooseCtx->copyDestFileIdx], sramCtx->readBuff + offset + QUEST, + sizeof(fileChooseCtx->questItems[0])); + MemCopy(&fileChooseCtx->n64ddFlags[fileChooseCtx->copyDestFileIdx], sramCtx->readBuff + offset + N64DD, + sizeof(fileChooseCtx->n64ddFlags[0])); + MemCopy(&fileChooseCtx->heartStatus[fileChooseCtx->copyDestFileIdx], sramCtx->readBuff + offset + DEFENSE, + sizeof(fileChooseCtx->heartStatus[0])); + MemCopy(&fileChooseCtx->nowLife[fileChooseCtx->copyDestFileIdx], (sramCtx->readBuff + offset) + HEALTH, + sizeof(fileChooseCtx->nowLife[0])); + + osSyncPrintf("f_64dd[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->n64ddFlags[gSaveContext.fileNum]); + osSyncPrintf("heart_status[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->heartStatus[gSaveContext.fileNum]); + osSyncPrintf("COPY終了\n"); // Copy end +} + +void Sram_Write16Bytes(SramContext* sramCtx) { + SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, 0x10, OS_WRITE); +} + +void Sram_InitSram(GameState* gameState, SramContext* sramCtx) { + u16 i; + + osSyncPrintf("sram_initialize( Game *game, Sram *sram )\n"); + SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ); + + for (i = 0; i < ARRAY_COUNTU(sZeldaMagic) - 3; i++) { + if (sZeldaMagic[i + 3] != sramCtx->readBuff[i + 3]) { + // SRAM destruction! ! ! ! ! ! + osSyncPrintf("SRAM破壊!!!!!!\n"); + gSaveContext.language = sramCtx->readBuff[2]; + MemCopy(sramCtx->readBuff, sZeldaMagic, sizeof(sZeldaMagic)); + sramCtx->readBuff[2] = gSaveContext.language; + Sram_Write16Bytes(sramCtx); + } + } + + gSaveContext.audioSetting = sramCtx->readBuff[0] & 3; + gSaveContext.zTargetSetting = sramCtx->readBuff[1] & 1; + gSaveContext.language = sramCtx->readBuff[2]; + + if (gSaveContext.language > 2) { + gSaveContext.language = 0; + sramCtx->readBuff[2] = gSaveContext.language; + Sram_Write16Bytes(sramCtx); + } + + if (CHECK_BTN_ANY(gameState->input[2].cur.button, BTN_DRIGHT)) { + bzero(sramCtx->readBuff, SRAM_SIZE); + for (i = 0; i < CHECKSUM_SIZE; i++) { + sramCtx->readBuff[i] = i; + } + SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_WRITE); + // SRAM destruction! ! ! ! ! ! + osSyncPrintf("SRAM破壊!!!!!!\n"); + } + + // GOOD! GOOD! Size =% d +% d =% d + osSyncPrintf("GOOD!GOOD! サイズ=%d + %d = %d\n", sizeof(SaveInfo), 4, sizeof(SaveInfo) + 4); + osSyncPrintf(VT_FGCOL(BLUE)); + osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting); + osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting); + osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting); + osSyncPrintf(VT_RST); + func_800F6700(gSaveContext.audioSetting); +} + +void Sram_Alloc(GameState* gameState, SramContext* sramCtx) { + sramCtx->readBuff = GameState_Alloc(gameState, SRAM_SIZE, "../z_sram.c", 1294); + + if (!(sramCtx->readBuff != NULL)) { + __assert("sram->read_buff != NULL", "../z_sram.c", 1295); + } +} + +void Sram_Init(GlobalContext* globalCtx, SramContext* sramCtx) { +} diff --git a/src/code/z_ss_sram.c b/src/code/z_ss_sram.c new file mode 100644 index 000000000..6f929678c --- /dev/null +++ b/src/code/z_ss_sram.c @@ -0,0 +1,53 @@ +#include "ultra64.h" +#include "global.h" + +typedef struct { + /* 0x00 */ OSPiHandle piHandle; + /* 0x74 */ OSIoMesg ioMesg; + /* 0x8C */ OSMesgQueue mesgQ; +} SsSramContext; // size = 0xA4 + +SsSramContext sSsSramContext = { 0 }; + +void SsSram_Init(u32 addr, u8 handleType, u8 handleDomain, u8 handleLatency, u8 handlePageSize, u8 handleRelDuration, + u8 handlePulse, u32 handleSpeed) { + u32 intDisabled; + OSPiHandle* handle = &sSsSramContext.piHandle; + + if ((u32)OS_PHYSICAL_TO_K1(addr) != (*handle).baseAddress) { + sSsSramContext.piHandle.type = handleType; + (*handle).baseAddress = OS_PHYSICAL_TO_K1(addr); + sSsSramContext.piHandle.latency = handleLatency; + sSsSramContext.piHandle.pulse = handlePulse; + sSsSramContext.piHandle.pageSize = handlePageSize; + sSsSramContext.piHandle.relDuration = handleRelDuration; + sSsSramContext.piHandle.domain = handleDomain; + sSsSramContext.piHandle.speed = handleSpeed; + bzero(&sSsSramContext.piHandle.transferInfo, sizeof(__OSTranxInfo)); + intDisabled = __osDisableInt(); + sSsSramContext.piHandle.next = __osPiTable; + __osPiTable = &sSsSramContext.piHandle; + __osRestoreInt(intDisabled); + sSsSramContext.ioMesg.hdr.pri = 0; + sSsSramContext.ioMesg.hdr.retQueue = &sSsSramContext.mesgQ; + sSsSramContext.ioMesg.devAddr = addr; + } +} + +void SsSram_Dma(void* dramAddr, size_t size, s32 direction) { + OSMesg mesg; + + osCreateMesgQueue(&sSsSramContext.mesgQ, &mesg, 1); + sSsSramContext.ioMesg.dramAddr = dramAddr; + sSsSramContext.ioMesg.size = size; + osWritebackDCache(dramAddr, size); + osEPiStartDma(&sSsSramContext.piHandle, &sSsSramContext.ioMesg, direction); + osRecvMesg(&sSsSramContext.mesgQ, &mesg, OS_MESG_BLOCK); + osInvalDCache(dramAddr, size); +} + +void SsSram_ReadWrite(u32 addr, void* dramAddr, size_t size, s32 direction) { + osSyncPrintf("ssSRAMReadWrite:%08x %08x %08x %d\n", addr, dramAddr, size, direction); + SsSram_Init(addr, DEVICE_TYPE_SRAM, 1, 5, 0xD, 2, 0xC, 0); + SsSram_Dma(dramAddr, size, direction); +} diff --git a/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c b/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c index a24114dd0..ec4d23211 100644 --- a/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c +++ b/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c @@ -104,7 +104,7 @@ s32 func_80994750(DoorGerudo* this, GlobalContext* globalCtx) { void func_8099485C(DoorGerudo* this, GlobalContext* globalCtx) { if (this->unk_164 != 0) { this->actionFunc = func_8099496C; - gSaveContext.dungeonKeys[gSaveContext.mapIndex] -= 1; + gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] -= 1; Flags_SetSwitch(globalCtx, this->dyna.actor.params & 0x3F); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_CHAIN_KEY_UNLOCK); } else { @@ -113,7 +113,7 @@ void func_8099485C(DoorGerudo* this, GlobalContext* globalCtx) { if (direction != 0) { Player* player = PLAYER; - if (gSaveContext.dungeonKeys[gSaveContext.mapIndex] <= 0) { + if (gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] <= 0) { player->naviMessageId = -0x203; } else if (!Flags_GetCollectible(globalCtx, (this->dyna.actor.params >> 8) & 0x1F)) { player->naviMessageId = -0x225; diff --git a/src/overlays/actors/ovl_En_GirlA/z_en_girla.c b/src/overlays/actors/ovl_En_GirlA/z_en_girla.c index d4af67f4a..d8b52903a 100644 --- a/src/overlays/actors/ovl_En_GirlA/z_en_girla.c +++ b/src/overlays/actors/ovl_En_GirlA/z_en_girla.c @@ -426,7 +426,7 @@ s32 func_80A3AEBC(GlobalContext* globalCtx, EnGirlA* this) { } s32 func_80A3AF30(GlobalContext* globalCtx, EnGirlA* this) { - if ((gBitFlags[2] & gSaveContext.equipment) && !(gBitFlags[3] & gSaveContext.equipment)) { + if ((gBitFlags[2] & gSaveContext.inventory.equipment) && !(gBitFlags[3] & gSaveContext.inventory.equipment)) { return 2; } if (gSaveContext.rupees < this->unk_1C8) { @@ -439,7 +439,7 @@ s32 func_80A3AF30(GlobalContext* globalCtx, EnGirlA* this) { } s32 func_80A3AFC4(GlobalContext* globalCtx, EnGirlA* this) { - if (gBitFlags[5] & gSaveContext.equipment) { + if (gBitFlags[5] & gSaveContext.inventory.equipment) { return 2; } if (gSaveContext.rupees < this->unk_1C8) { @@ -452,7 +452,7 @@ s32 func_80A3AFC4(GlobalContext* globalCtx, EnGirlA* this) { } s32 func_80A3B040(GlobalContext* globalCtx, EnGirlA* this) { - if (gBitFlags[4] & gSaveContext.equipment) { + if (gBitFlags[4] & gSaveContext.inventory.equipment) { return 2; } if (gSaveContext.rupees < this->unk_1C8) { @@ -468,7 +468,7 @@ s32 func_80A3B0BC(GlobalContext* globalCtx, EnGirlA* this) { if (LINK_AGE_IN_YEARS == YEARS_CHILD) { return 2; } - if (gBitFlags[9] & gSaveContext.equipment) { + if (gBitFlags[9] & gSaveContext.inventory.equipment) { return 2; } if (gSaveContext.rupees < this->unk_1C8) { @@ -484,7 +484,7 @@ s32 func_80A3B160(GlobalContext* globalCtx, EnGirlA* this) { if (LINK_AGE_IN_YEARS == YEARS_CHILD) { return 2; } - if (gBitFlags[10] & gSaveContext.equipment) { + if (gBitFlags[10] & gSaveContext.inventory.equipment) { return 2; } if (gSaveContext.rupees < this->unk_1C8) { diff --git a/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c b/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c index aa9ce8a1a..4e8d84a60 100644 --- a/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c +++ b/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c @@ -234,7 +234,7 @@ void EnIshi_DropCollectible(EnIshi* this, GlobalContext* globalCtx) { if (dropParams >= 0xD) { dropParams = 0; } - + Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.posRot.pos, dropParams << 4); } } diff --git a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c index 718959413..2a72df2b1 100644 --- a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c +++ b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c @@ -169,13 +169,13 @@ void func_80A8F660(EnKakasi* this, GlobalContext* globalCtx) { this->unk_196 = 6; if (LINK_IS_CHILD) { this->unk_194 = false; - if (gSaveContext.unk_F3C[4] != 0) { + if (gSaveContext.scarecrowCustomSongSet) { this->actor.textId = 0x407A; this->unk_196 = 5; } } else { this->unk_194 = true; - if (gSaveContext.unk_F3C[4] != 0) { + if (gSaveContext.scarecrowCustomSongSet) { this->actor.textId = 0x4079; this->unk_196 = 5; } @@ -335,7 +335,7 @@ void EnKakasi_Draw(Actor* thisx, GlobalContext* globalCtx) { if (BREG(3) != 0) { osSyncPrintf("\n\n"); // flag! - osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ フラグ! ☆☆☆☆☆ %d\n" VT_RST, gSaveContext.unk_F3C[4]); + osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ フラグ! ☆☆☆☆☆ %d\n" VT_RST, gSaveContext.scarecrowCustomSongSet); } func_80093D18(globalCtx->state.gfxCtx); SkelAnime_DrawSV(globalCtx, this->skelanime.skeleton, this->skelanime.limbDrawTbl, this->skelanime.dListCount, NULL, diff --git a/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c b/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c index b3cb061f5..be25f5f20 100644 --- a/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c +++ b/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c @@ -205,7 +205,8 @@ void EnKakasi2_Update(Actor* thisx, GlobalContext* globalCtx) { } if (BREG(0) != 0) { if (BREG(5) != 0) { - osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ this->actor.player_distance ☆☆☆☆☆ %f\n" VT_RST, this->actor.xzDistFromLink); + osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ this->actor.player_distance ☆☆☆☆☆ %f\n" VT_RST, + this->actor.xzDistFromLink); osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ this->hosei.x ☆☆☆☆☆ %f\n" VT_RST, this->maxSpawnDistance.x); osSyncPrintf("\n\n"); } diff --git a/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c b/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c index b0e0acea6..2ad430e02 100644 --- a/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c +++ b/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c @@ -179,14 +179,14 @@ void func_80A91284(EnKakasi3* this, GlobalContext* globalCtx) { if (LINK_IS_CHILD) { this->unk_194 = false; - if (gSaveContext.unk_12C5 != 0) { + if (gSaveContext.scarecrowSpawnSongSet) { this->actor.textId = 0x40A0; this->dialogState = 5; this->unk_1A8 = 1; } } else { this->unk_194 = true; - if (gSaveContext.unk_12C5 != 0) { + if (gSaveContext.scarecrowSpawnSongSet) { if (this->unk_195) { this->actor.textId = 0x40A2; } else { @@ -238,7 +238,7 @@ void func_80A91348(EnKakasi3* this, GlobalContext* globalCtx) { if (this->actor.xzDistFromLink < 80.0f) { player->stateFlags2 |= 0x800000; } - } else if (gSaveContext.unk_12C5 != 0 && !this->unk_195) { + } else if (gSaveContext.scarecrowSpawnSongSet && !this->unk_195) { if (player->stateFlags2 & 0x1000000) { this->camId = func_800800F8(globalCtx, 0x8D4, -0x63, &this->actor, 0); @@ -341,7 +341,7 @@ void func_80A918E4(EnKakasi3* this, GlobalContext* globalCtx) { } if ((globalCtx->msgCtx.unk_E3EE == 4 || (globalCtx->msgCtx.unk_E3EE >= 5 && globalCtx->msgCtx.unk_E3EE < 11)) && globalCtx->msgCtx.msgMode == 0) { - + func_8010B680(globalCtx, 0x40A6, NULL); this->dialogState = 5; func_800803F0(globalCtx, this->camId); @@ -405,7 +405,7 @@ void EnKakasi3_Update(Actor* thisx, GlobalContext* globalCtx) { if (BREG(2) != 0) { osSyncPrintf("\n\n"); // flag! - osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ フラグ! ☆☆☆☆☆ %d\n" VT_RST, gSaveContext.unk_12C5); + osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ フラグ! ☆☆☆☆☆ %d\n" VT_RST, gSaveContext.scarecrowSpawnSongSet); } this->unk_198++; diff --git a/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c b/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c index 2b9998f89..2423df653 100644 --- a/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c +++ b/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c @@ -83,13 +83,13 @@ u16 func_80AA2AA0(GlobalContext* globalCtx, Actor* thisx) { if (gSaveContext.timer1Value >= 0xD3) { return 0x208E; } - if ((gSaveContext.unk_EC4 == 0) || (gSaveContext.unk_EC4 >= 0xB4)) { - gSaveContext.unk_EC4 = 0xB4; + if ((gSaveContext.horseRaceRecord == 0) || (gSaveContext.horseRaceRecord >= 0xB4)) { + gSaveContext.horseRaceRecord = 0xB4; gSaveContext.timer1Value = *timer1ValuePtr; } if (!(gSaveContext.eventChkInf[1] & 0x4000) && (gSaveContext.timer1Value < 0x32)) { return 0x208F; - } else if (gSaveContext.timer1Value < gSaveContext.unk_EC4) { + } else if (gSaveContext.timer1Value < gSaveContext.horseRaceRecord) { return 0x2012; } else { return 0x2004; @@ -126,7 +126,7 @@ s16 func_80AA2BD4(GlobalContext* globalCtx, Actor* thisx) { if (globalCtx->msgCtx.choiceIndex == 0) { if (gSaveContext.eventChkInf[1] & 0x4000) { func_8010B720(globalCtx, 0x2091); - } else if (gSaveContext.unk_EC4 == 0) { + } else if (gSaveContext.horseRaceRecord == 0) { func_8010B720(globalCtx, 0x2092); } else { func_8010B720(globalCtx, 0x2090); @@ -144,8 +144,8 @@ s16 func_80AA2BD4(GlobalContext* globalCtx, Actor* thisx) { gSaveContext.eventChkInf[1] |= 0x4000; case 0x2004: case 0x2012: - if (gSaveContext.unk_EC4 > gSaveContext.timer1Value) { - gSaveContext.unk_EC4 = gSaveContext.timer1Value; + if (gSaveContext.horseRaceRecord > gSaveContext.timer1Value) { + gSaveContext.horseRaceRecord = gSaveContext.timer1Value; } case 0x208E: gSaveContext.eventInf[0] &= ~0x400; diff --git a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c index e6afa9516..bcecb5aff 100644 --- a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c +++ b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c @@ -117,7 +117,7 @@ void func_80ABEF2C(EnOkarinaTag* this, GlobalContext* globalCtx) { if ((this->switchFlag >= 0) && (Flags_GetSwitch(globalCtx, this->switchFlag))) { this->actor.flags &= ~1; } else { - if ((this->unk_152 != 6) || (gSaveContext.unk_12C5 != 0)) { + if ((this->unk_152 != 6) || (gSaveContext.scarecrowSpawnSongSet)) { if (player->stateFlags2 & 0x1000000) { // "North! ! ! ! !" osSyncPrintf(VT_FGCOL(RED) "☆☆☆☆☆ 北!!!!! ☆☆☆☆☆ %f\n" VT_RST, this->actor.xzDistFromLink); @@ -189,7 +189,7 @@ void func_80ABF28C(EnOkarinaTag* this, GlobalContext* globalCtx) { Player* player = PLAYER; this->unk_15A++; - if ((this->unk_152 != 6) || (gSaveContext.unk_12C5 != 0)) { + if ((this->unk_152 != 6) || (gSaveContext.scarecrowSpawnSongSet)) { if ((this->switchFlag >= 0) && Flags_GetSwitch(globalCtx, this->switchFlag)) { this->actor.flags &= ~1; } else if (((this->unk_150 != 4) || !(gSaveContext.eventChkInf[4] & 0x800)) && diff --git a/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c b/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c index 9792a5c0a..9d3437026 100644 --- a/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c +++ b/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c @@ -229,12 +229,11 @@ void func_80AE5270(EnReeba* this, GlobalContext* globalCtx) { this->actionfunc = func_80AE5688; return; } - + if (this->unk_274 == 0) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIVA_MOVE); this->unk_274 = 10; } - } void func_80AE538C(EnReeba* this, GlobalContext* globalCtx) { diff --git a/src/overlays/actors/ovl_En_Rl/z_en_rl.c b/src/overlays/actors/ovl_En_Rl/z_en_rl.c index 78ea321bb..f72590aab 100644 --- a/src/overlays/actors/ovl_En_Rl/z_en_rl.c +++ b/src/overlays/actors/ovl_En_Rl/z_en_rl.c @@ -396,4 +396,4 @@ const ActorInit En_Rl_InitVars = { (ActorFunc)EnRl_Destroy, (ActorFunc)EnRl_Update, (ActorFunc)EnRl_Draw, -};
\ No newline at end of file +}; diff --git a/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c b/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c index e07be9274..552133f83 100644 --- a/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c +++ b/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c @@ -57,7 +57,7 @@ void EnTakaraMan_Init(Actor* thisx, GlobalContext* globalCtx) { osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ ばぅん! ☆☆☆☆☆ %x\n" VT_RST, globalCtx->actorCtx.flags.chest); // "Bun! %x" (needs a better translation) globalCtx->actorCtx.flags.chest = 0; - gSaveContext.dungeonKeys[gSaveContext.mapIndex] = -1; + gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] = -1; SkelAnime_InitSV(globalCtx, &this->skelAnime, &D_06004FE0, &D_06000498, this->limbDrawTbl, this->transitionDrawTbl, 10); thisx->posRot2.pos = thisx->posRot.pos; diff --git a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c index daa7d7477..ca2271722 100644 --- a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c +++ b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c @@ -268,10 +268,8 @@ void ObjSyokudai_Draw(Actor* thisx, GlobalContext* globalCtx) { gDPSetEnvColor(oGfxCtx->polyXlu.p++, 255, 0, 0, 0); Matrix_Translate(0.0f, 52.0f, 0.0f, MTXMODE_APPLY); - Matrix_RotateY( - (s16)(func_8005A9F4(ACTIVE_CAM) - this->actor.shape.rot.y + 0x8000) * - (M_PI / 0x8000), - MTXMODE_APPLY); + Matrix_RotateY((s16)(func_8005A9F4(ACTIVE_CAM) - this->actor.shape.rot.y + 0x8000) * (M_PI / 0x8000), + MTXMODE_APPLY); Matrix_Scale(flameScale, flameScale, flameScale, MTXMODE_APPLY); gSPMatrix(oGfxCtx->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_obj_syokudai.c", 745), diff --git a/src/overlays/actors/ovl_player_actor/z_player.c b/src/overlays/actors/ovl_player_actor/z_player.c index 03931dd03..c68642e50 100644 --- a/src/overlays/actors/ovl_player_actor/z_player.c +++ b/src/overlays/actors/ovl_player_actor/z_player.c @@ -3056,7 +3056,7 @@ void func_80836BEC(Player* this, GlobalContext* globalCtx) { actorToTarget = &PLAYER->actor; } - holdTarget = (gSaveContext.zTargetingSetting != 0) || (this->actor.type != ACTORTYPE_PLAYER); + holdTarget = (gSaveContext.zTargetSetting != 0) || (this->actor.type != ACTORTYPE_PLAYER); this->stateFlags1 |= 0x8000; if ((actorToTarget != NULL) && !(actorToTarget->flags & 0x8000000)) { @@ -4042,9 +4042,9 @@ s32 func_80839034(GlobalContext* globalCtx, Player* this, CollisionPoly* arg2, u } if (linearVel > R_RUN_SPEED_LIMIT / 100.0f) { - gSaveContext.unk_13BC = R_RUN_SPEED_LIMIT / 100.0f; + gSaveContext.entranceSpeed = R_RUN_SPEED_LIMIT / 100.0f; } else { - gSaveContext.unk_13BC = linearVel; + gSaveContext.entranceSpeed = linearVel; } if (D_808535F4 != 0) { @@ -4273,8 +4273,8 @@ s32 func_80839800(Player* this, GlobalContext* globalCtx) { func_8003C890(&globalCtx->colCtx, &sp58, &sp4C); if (func_80839034(globalCtx, this, sp58, 50)) { - gSaveContext.unk_13BC = 2.0f; - gSaveContext.unk_13C0 = NA_SE_OC_DOOR_OPEN; + gSaveContext.entranceSpeed = 2.0f; + gSaveContext.entranceSound = NA_SE_OC_DOOR_OPEN; } } else { func_8005AD40(Gameplay_GetCamera(globalCtx, 0), doorActor, @@ -5356,18 +5356,18 @@ void func_8083CA20(GlobalContext* globalCtx, Player* this) { void func_8083CA54(GlobalContext* globalCtx, Player* this) { this->linearVelocity = 2.0f; - gSaveContext.unk_13BC = 2.0f; + gSaveContext.entranceSpeed = 2.0f; if (func_8083C910(globalCtx, this, 120.0f)) { this->unk_850 = -15; } } void func_8083CA9C(GlobalContext* globalCtx, Player* this) { - if (gSaveContext.unk_13BC < 0.1f) { - gSaveContext.unk_13BC = 0.1f; + if (gSaveContext.entranceSpeed < 0.1f) { + gSaveContext.entranceSpeed = 0.1f; } - this->linearVelocity = gSaveContext.unk_13BC; + this->linearVelocity = gSaveContext.entranceSpeed; if (func_8083C910(globalCtx, this, 800.0f)) { this->unk_850 = -80 / this->linearVelocity; @@ -8676,7 +8676,7 @@ void func_80845CA4(Player* this, GlobalContext* globalCtx) { sp30 = 20; if (this->stateFlags1 & 1) { - sp34 = gSaveContext.unk_13BC; + sp34 = gSaveContext.entranceSpeed; if (D_808535F4 != 0) { this->unk_450.x = (Math_Sins(D_808535FC) * 400.0f) + this->actor.posRot.pos.x; @@ -8685,7 +8685,7 @@ void func_80845CA4(Player* this, GlobalContext* globalCtx) { } else if (this->unk_850 < 0) { this->unk_850++; - sp34 = gSaveContext.unk_13BC; + sp34 = gSaveContext.entranceSpeed; sp30 = -1; } @@ -9071,7 +9071,7 @@ void Player_Init(Actor* thisx, GlobalContext* globalCtx) { s32 sp4C; s32 initMode; s16 params; - u16 unk_13C0; + u16 entranceSound; globalCtx->unk_11E5C = globalCtx->bombchuBowlingAmmo = 0; @@ -9125,7 +9125,7 @@ void Player_Init(Actor* thisx, GlobalContext* globalCtx) { } if ((sp50 == 0) || (sp50 < -1)) { - if ((scene->titleFile.vromStart != scene->titleFile.vromEnd) && (gSaveContext.unk_13C7 != 0) && + if ((scene->titleFile.vromStart != scene->titleFile.vromEnd) && (gSaveContext.showTitleCard) && (gSaveContext.sceneSetupIndex < 4) && (gEntranceTable[gSaveContext.entranceIndex + gSaveContext.sceneSetupIndex].field & 0x4000) && ((globalCtx->sceneNum != SCENE_DDAN) || (gSaveContext.eventChkInf[11] & 1)) && @@ -9133,7 +9133,7 @@ void Player_Init(Actor* thisx, GlobalContext* globalCtx) { TitleCard_InitPlaceName(globalCtx, &globalCtx->actorCtx.titleCtx, this->giObjectSegment, 0xA0, 0x78, 0x90, 0x18, 0x14); } - gSaveContext.unk_13C7 = 1; + gSaveContext.showTitleCard = true; } if (sp50 == 2) { @@ -9177,10 +9177,10 @@ void Player_Init(Actor* thisx, GlobalContext* globalCtx) { this->stateFlags3 &= ~0x40; } - if (gSaveContext.unk_13C0 != 0) { - unk_13C0 = gSaveContext.unk_13C0; - Audio_PlayActorSound2(&this->actor, unk_13C0); - gSaveContext.unk_13C0 = 0; + if (gSaveContext.entranceSound != 0) { + entranceSound = gSaveContext.entranceSound; + Audio_PlayActorSound2(&this->actor, entranceSound); + gSaveContext.entranceSound = 0; } Map_SavePlayerInitialInfo(globalCtx); @@ -11818,7 +11818,8 @@ s32 func_8084DFF4(GlobalContext* globalCtx, Player* this) { Audio_PlaySoundGeneral(NA_SE_SY_GET_BOXITEM, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); } else { if ((this->getItemId == GI_HEART_CONTAINER_2) || (this->getItemId == GI_HEART_CONTAINER) || - ((this->getItemId == GI_HEART_PIECE) && ((gSaveContext.questItems & 0xF0000000) == 0x40000000))) { + ((this->getItemId == GI_HEART_PIECE) && + ((gSaveContext.inventory.questItems & 0xF0000000) == 0x40000000))) { temp1 = 0x924; } else { temp1 = temp2 = (this->getItemId == GI_HEART_PIECE) ? 0x39 : 0x922; diff --git a/src/overlays/gamestates/ovl_opening/z_opening.c b/src/overlays/gamestates/ovl_opening/z_opening.c index 149b1e2b7..9fe700d05 100644 --- a/src/overlays/gamestates/ovl_opening/z_opening.c +++ b/src/overlays/gamestates/ovl_opening/z_opening.c @@ -10,7 +10,7 @@ void Opening_SetupTitleScreen(OpeningContext* this) { gSaveContext.gameMode = 1; this->state.running = false; gSaveContext.linkAge = 0; - func_800A82C8(); + Sram_InitDebugSave(); gSaveContext.cutsceneIndex = 0xFFF3; gSaveContext.sceneSetupIndex = 7; SET_NEXT_GAMESTATE(&this->state, Gameplay_Init, GlobalContext); diff --git a/src/overlays/gamestates/ovl_select/z_select.c b/src/overlays/gamestates/ovl_select/z_select.c index 309139e03..f858abf0f 100644 --- a/src/overlays/gamestates/ovl_select/z_select.c +++ b/src/overlays/gamestates/ovl_select/z_select.c @@ -19,7 +19,7 @@ void Select_LoadGame(SelectContext* this, s32 entranceIndex) { osSyncPrintf("\n\n\nFILE_NO=%x\n\n\n", gSaveContext.fileNum); osSyncPrintf(VT_RST); if (gSaveContext.fileNum == 0xFF) { - func_800A82C8(); + Sram_InitDebugSave(); gSaveContext.unk_13F6 = gSaveContext.magic; gSaveContext.magic = 0; gSaveContext.unk_13F4 = 0; @@ -37,7 +37,7 @@ void Select_LoadGame(SelectContext* this, s32 entranceIndex) { gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex = -1; gSaveContext.seqIndex = 0xFF; gSaveContext.nightSeqIndex = 0xFF; - gSaveContext.unk_13C7 = 1; + gSaveContext.showTitleCard = true; D_8011FB30 = 0; this->state.running = false; SET_NEXT_GAMESTATE(&this->state, Gameplay_Init, GlobalContext); diff --git a/src/overlays/gamestates/ovl_title/z_title.c b/src/overlays/gamestates/ovl_title/z_title.c index ee1408768..72ce3e69a 100644 --- a/src/overlays/gamestates/ovl_title/z_title.c +++ b/src/overlays/gamestates/ovl_title/z_title.c @@ -155,7 +155,7 @@ void Title_Main(TitleContext* this) { } void Title_Destroy(TitleContext* this) { - func_800A9AD0(this, &this->sram); + Sram_InitSram(this, &this->sramCtx); } void Title_Init(TitleContext* this) { @@ -175,7 +175,7 @@ void Title_Init(TitleContext* this) { this->state.destroy = Title_Destroy; this->exit = false; gSaveContext.fileNum = 0xFF; - func_800A9CD4(&this->state, &this->sram); + Sram_Alloc(&this->state, &this->sramCtx); this->ult = 0; this->unk_1D4 = 0x14; this->coverAlpha = 255; |
