shithub: zelda3

Download patch

ref: 9f2de022ddb043baa482b773ce022f55fe9ef9ba
parent: 608af92760c022f28ca4fcbe6f9e2d50bb847909
author: Snesrev <[email protected]>
date: Thu Sep 29 19:00:09 EDT 2022

Fix some Zelda bugs
 - Kiki messes up Superbomb
 - Cane of somaria block on the door button crash
 - Boss prize didn't spawn if out of ancillas

Also renamed some vars

--- a/ancilla.c
+++ b/ancilla.c
@@ -3502,7 +3502,7 @@
     if (ancilla_timer[k] != 17)
       goto endif_1;
     word_7E02CD = 0xDF3;
-    savegame_tagalong = 0xe;
+    follower_indicator = 0xe;
     goto endif_6;
   }
 
@@ -4829,7 +4829,7 @@
         link_disable_sprite_damage = 0;
         byte_7E03FD = 0;
         countdown_for_blink = 144;
-        if (!((savegame_tagalong == 12 || savegame_tagalong == 13) && super_bomb_going_off)) {
+        if (!((follower_indicator == 12 || follower_indicator == 13) && follower_dropped)) {
           Follower_Initialize();
         }
       }
@@ -4854,8 +4854,8 @@
       if (a == 0x2a || a == 0x1f || a == 0x30 || a == 0x31 || a == 0x41)
         ancilla_type[i] = 0;
     }
-    if (savegame_tagalong == 9) {
-      savegame_tagalong = 0;
+    if (follower_indicator == 9) {
+      follower_indicator = 0;
       tagalong_var5 = 0;
     }
   }
@@ -5563,7 +5563,7 @@
   }
   if (ancilla_item_to_link[k] == 3 && ancilla_arr3[k] == 1) {
     Bomb_CheckForDestructibles(Ancilla_GetX(k), Ancilla_GetY(k), 0); // r14?
-    savegame_tagalong = 0;
+    follower_indicator = 0;
   }
 }
 
@@ -6197,7 +6197,7 @@
   } while (--k, --j != j_end);
 }
 
-void AncillaAdd_FallingPrize(uint8 a, uint8 item_idx, uint8 yv) {  // 898bc1
+int AncillaAdd_FallingPrize(uint8 a, uint8 item_idx, uint8 yv) {  // 898bc1
   static const int8 kFallingItem_Type[7] = {0x10, 0x37, 0x39, 0x38, 0x26, 0xf, 0x20};
   static const int8 kFallingItem_G[7] = {0x40, 0, 0, 0, 0, -1, 0};
   static const int16 kFallingItem_X[7] = {0x78, 0x78, 0x78, 0x78, 0x78, 0x80, 0x78};
@@ -6206,7 +6206,7 @@
   link_receiveitem_index = item_idx;
   int k = Ancilla_AddAncilla(a, yv);
   if (k < 0)
-    return;
+    return k;
   uint8 item_type = kFallingItem_Type[item_idx];
   ancilla_item_to_link[k] = item_type;
   if (item_type == 0x10 || item_type == 0xf)
@@ -6237,6 +6237,7 @@
     y = kFallingItem_Y[item_idx] + BG2VOFS_copy2;
   }
   Ancilla_SetXY(k, x, y);
+  return k;
 }
 
 void AncillaAdd_ChargedSpinAttackSparkle() {  // 898cb1
@@ -6478,7 +6479,7 @@
   int k = Ancilla_AddAncilla(ain, yin);
   if (k < 0)
     return;
-  if (savegame_tagalong == 8)
+  if (follower_indicator == 8)
     sound_effect_1 = Link_CalculateSfxPan() | 0x14;
   else
     sound_effect_1 = Link_CalculateSfxPan() | 0x15;
--- a/ancilla.h
+++ b/ancilla.h
@@ -216,7 +216,7 @@
 uint8 AncillaAdd_Boomerang(uint8 a, uint8 y);
 void AncillaAdd_TossedPondItem(uint8 a, uint8 xin, uint8 yin);
 void AddHappinessPondRupees(uint8 arg);
-void AncillaAdd_FallingPrize(uint8 a, uint8 item_idx, uint8 yv);
+int AncillaAdd_FallingPrize(uint8 a, uint8 item_idx, uint8 yv);
 void AncillaAdd_ChargedSpinAttackSparkle();
 void AncillaAdd_ExplodingWeatherVane(uint8 a, uint8 y);
 void AncillaAdd_CutsceneDuck(uint8 a, uint8 y);
--- a/dungeon.c
+++ b/dungeon.c
@@ -4579,7 +4579,8 @@
   int t = savegame_is_darkworld ? link_has_crystals : link_which_pendants;
   if (!(t & kDungeonCrystalPendantBit[BYTE(cur_palace_index_x2) >> 1])) {
     byte_7E04C2 = 128;
-    Ancilla_SpawnFallingPrize(kBossFinishedFallingItem[BYTE(cur_palace_index_x2) >> 1]);
+    if (Ancilla_SpawnFallingPrize(kBossFinishedFallingItem[BYTE(cur_palace_index_x2) >> 1]) < 0)
+      return; // Zelda bugfix. Price won't spawn if we're out of ancillas
   }
   dung_hdr_tag[k] = 0;
 }
@@ -6454,8 +6455,8 @@
   Dungeon_ResetTorchBackgroundAndPlayer();
   Link_CheckBunnyStatus();
   ResetThenCacheRoomEntryProperties();
-  if (savegame_tagalong == 13) {
-    savegame_tagalong = 0;
+  if (follower_indicator == 13) {
+    follower_indicator = 0;
     super_bomb_indicator_unk2 = 0;
     Hud_RemoveSuperBombIndicator();
   }
@@ -6500,6 +6501,12 @@
 void Module07_Dungeon() {  // 8287a2
   Dungeon_HandleLayerEffect();
   kDungeonSubmodules[submodule_index]();
+
+  // When having the somaria on door button and exiting in skull woods, 
+  // don't overwrite submodule_index
+  if (enhanced_features0 & kFeatures0_MiscBugFixes && main_module_index != 7)
+    goto skip;
+
   dung_misc_objs_index = 0;
   Dungeon_PushBlock_Handler();
   if (submodule_index) goto skip;
@@ -7299,8 +7306,8 @@
 }
 
 void Dungeon_SyncBackgroundsFromSpiralStairs() {  // 8290c7
-  if (savegame_tagalong == 6 && BYTE(dungeon_room_index) == 100)
-    savegame_tagalong = 0;
+  if (follower_indicator == 6 && BYTE(dungeon_room_index) == 100)
+    follower_indicator = 0;
   uint8 bak = link_is_on_lower_level;
   link_y_coord += which_staircase_index & 4 ? 48 : -48;
   link_is_on_lower_level = kTeleportPitLevel2[cur_staircase_plane];
@@ -8317,7 +8324,7 @@
   }
   bg1_y_offset = bg1_x_offset = 0;
   WORD(death_var5) = 0;
-  if (WORD(savegame_tagalong) == 4 || WORD(death_var4)) {
+  if (WORD(follower_indicator) == 4 || WORD(death_var4)) {
     int i = which_starting_point;
     WORD(which_entrance) = kStartingPoint_entrance[i];
     dungeon_room_index = dungeon_room_index2 = kStartingPoint_rooms[i];
@@ -8607,7 +8614,7 @@
     return;
 
   RepositionLinkAfterSpiralStairs();
-  if (savegame_tagalong)
+  if (follower_indicator)
     Follower_Initialize();
 
   tiledetect_which_y_pos[1] = link_x_coord + ((which_staircase_index & 4) ? -8 : 12);
@@ -8777,12 +8784,12 @@
   item_receipt_method = 0;
   if (BYTE(cur_palace_index_x2) == 24) {
     sprite_oam_flags[j] = 9;
-    savegame_tagalong = 1;
+    follower_indicator = 1;
   } else {
-    savegame_tagalong = 6;
+    follower_indicator = 6;
   }
   LoadFollowerGraphics();
-  savegame_tagalong = 0;
+  follower_indicator = 0;
   dung_floor_x_offs = BG2HOFS_copy2 - link_x_coord + 0x79;
   dung_floor_y_offs = 0x30 - (uint8)BG1VOFS_copy2;
   dung_hdr_collision_2_mirror = 1;
--- a/features.h
+++ b/features.h
@@ -36,6 +36,8 @@
   kFeatures0_WidescreenVisualFixes = 1024,
 
   kFeatures0_CarryMoreRupees = 2048,
+
+  kFeatures0_MiscBugFixes = 4096,
 };
 
 #define enhanced_features0 (*(uint32*)(g_ram+0x64c))
--- a/load_gfx.c
+++ b/load_gfx.c
@@ -541,17 +541,17 @@
 
 void LoadFollowerGraphics() {  // 80d423
   uint8 yv = 0x64;
-  if (savegame_tagalong != 1) {
+  if (follower_indicator != 1) {
     yv = 0x66;
-    if (savegame_tagalong >= 9) {
+    if (follower_indicator >= 9) {
       yv = 0x59;
-      if (savegame_tagalong >= 12)
+      if (follower_indicator >= 12)
         yv = 0x58;
     }
   }
   Decomp_spr(&g_ram[0x14600], yv);
   Decomp_spr(&g_ram[0x14000], 0x65);
-  Do3To4Low16Bit(&g_ram[0x9000] + 0x2940, &g_ram[0x14000 + kTagalongWhich[savegame_tagalong]], 0x20);
+  Do3To4Low16Bit(&g_ram[0x9000] + 0x2940, &g_ram[0x14000 + kTagalongWhich[follower_indicator]], 0x20);
 }
 
 void WriteTo4BPPBuffer_at_7F4000(uint8 a) {  // 80d4db
--- a/messaging.c
+++ b/messaging.c
@@ -901,8 +901,8 @@
     player_is_indoors = 0;
 
   ResetSomeThingsAfterDeath((uint8)dungeon_room_index);
-  if (savegame_tagalong == 6 || savegame_tagalong == 9 || savegame_tagalong == 10 || savegame_tagalong == 13)
-    savegame_tagalong = 0;
+  if (follower_indicator == 6 || follower_indicator == 9 || follower_indicator == 10 || follower_indicator == 13)
+    follower_indicator = 0;
 
   death_var4 = link_health_current = kHealthAfterDeath[link_health_capacity >> 3];
   uint8 i = BYTE(cur_palace_index_x2);
@@ -916,7 +916,7 @@
     if (!player_is_indoors)
       goto outdoors;
 
-    if (savegame_tagalong != 1 && BYTE(cur_palace_index_x2) != 255) {
+    if (follower_indicator != 1 && BYTE(cur_palace_index_x2) != 255) {
       death_var4 = 0;
     } else {
       buffer_for_playing_songs = 0;
--- a/overworld.c
+++ b/overworld.c
@@ -268,7 +268,7 @@
 }
 
 bool CanEnterWithTagalong(int e) {
-  uint8 t = savegame_tagalong;
+  uint8 t = follower_indicator;
   return t == 0 || t == 5 || t == 14 || t == 1 || (t == 7 || t == 8) && e >= 59;
 }
 
@@ -478,8 +478,8 @@
   if (!(overworld_screen_index & 0x40))
     Sprite_InitializeMirrorPortal();
   sound_effect_ambient = sram_progress_indicator < 2 ? 1 : 5;
-  if (savegame_tagalong == 6)
-    savegame_tagalong = 0;
+  if (follower_indicator == 6)
+    follower_indicator = 0;
 
   is_standing_in_doorway = 0;
   button_mask_b_y = 0;
@@ -3270,7 +3270,7 @@
   if (lx < 0)
     return;
 
-  if (!super_bomb_going_off && (link_pose_for_item == 1 || !CanEnterWithTagalong(kOverworld_Entrance_Id[lx] - 1))) {
+  if (!follower_dropped && (link_pose_for_item == 1 || !CanEnterWithTagalong(kOverworld_Entrance_Id[lx] - 1))) {
     if (!big_key_door_message_triggered) {
       big_key_door_message_triggered = 1;
       dialogue_message_index = 5;
@@ -3474,7 +3474,7 @@
   int pos = ((y - overworld_offset_base_y & overworld_offset_mask_y) << 3) +
     ((x >> 3) - overworld_offset_base_x & overworld_offset_mask_x);
 
-  if (savegame_tagalong == 13)
+  if (follower_indicator == 13)
     goto label_a;
 
   a = dung_bg2[pos >> 1];
@@ -3582,7 +3582,7 @@
 
   BYTE(dung_secrets_unk1) = 0xff;
   if (data != 0x84 && !(save_ow_event_info[overworld_screen_index] & 2)) {
-    if (overworld_screen_index == 0x5b && savegame_tagalong != 13)
+    if (overworld_screen_index == 0x5b && follower_indicator != 13)
       goto fail;
     sound_effect_2 = 0x1b;
   }
--- a/player.c
+++ b/player.c
@@ -1165,8 +1165,8 @@
     Ancilla_Sfx2_Near(35);
   if (sign8(--link_countdown_for_dash)) {
     link_countdown_for_dash = 0;
-    if (savegame_tagalong == kTagalongArr1[savegame_tagalong])
-      savegame_tagalong = kTagalongArr2[savegame_tagalong];
+    if (follower_indicator == kTagalongArr1[follower_indicator])
+      follower_indicator = kTagalongArr2[follower_indicator];
   } else {
     index_of_dashing_sfx = 0;
     if (!(joypad1L_last & 0x80)) {
@@ -1478,7 +1478,7 @@
     return;
   uint8 x = ++link_this_controls_sprite_oam;
   byte_7E005C = 9;
-  if (savegame_tagalong != 13 && x == 1)
+  if (follower_indicator != 13 && x == 1)
     tagalong_var5 = x;
 
   if (x == 6) {
@@ -1558,13 +1558,13 @@
   subsubmodule_index = 0;
   submodule_index = 0;
   link_disable_sprite_damage = 0;
-  if (savegame_tagalong != 0 && savegame_tagalong != 3) {
+  if (follower_indicator != 0 && follower_indicator != 3) {
     tagalong_var5 = 0;
-    if (savegame_tagalong == 13) {
-      savegame_tagalong = 0;
+    if (follower_indicator == 13) {
+      follower_indicator = 0;
       super_bomb_indicator_unk2 = 0;
       super_bomb_indicator_unk1 = 0;
-      super_bomb_going_off = 0;
+      follower_dropped = 0;
     } else {
       Follower_Initialize();
     }
@@ -2389,7 +2389,7 @@
 }
 
 void LinkItem_Bombs() {  // 87a138
-  if (is_standing_in_doorway || savegame_tagalong == 13 || !CheckYButtonPress())
+  if (is_standing_in_doorway || follower_indicator == 13 || !CheckYButtonPress())
     return;
   button_mask_b_y &= ~0x40;
   AncillaAdd_Bomb(7, enhanced_features0 & kFeatures0_MoreActiveBombs ? 3 : 1);
@@ -2606,7 +2606,7 @@
   button_mask_b_y &= ~0x40;
 
   if (is_standing_in_doorway || flag_block_link_menu || dung_savegame_state_bits & 0x8000 || !((uint8)(link_sword_type + 1) & ~1) ||
-      super_bomb_going_off && savegame_tagalong == 13) {
+      follower_dropped && follower_indicator == 13) {
     Ancilla_Sfx2_Near(60);
     return;
   }
@@ -2654,7 +2654,7 @@
   button_mask_b_y &= ~0x40;
 
   if (is_standing_in_doorway || flag_block_link_menu || dung_savegame_state_bits & 0x8000 || !((uint8)(link_sword_type + 1) & ~1) ||
-      super_bomb_going_off && savegame_tagalong == 13) {
+      follower_dropped && follower_indicator == 13) {
     Ancilla_Sfx2_Near(60);
     return;
   }
@@ -2702,7 +2702,7 @@
   button_mask_b_y &= ~0x40;
 
   if (is_standing_in_doorway || flag_block_link_menu || dung_savegame_state_bits & 0x8000 || !((uint8)(link_sword_type + 1) & ~1) ||
-      super_bomb_going_off && savegame_tagalong == 13) {
+      follower_dropped && follower_indicator == 13) {
     Ancilla_Sfx2_Near(60);
     return;
   }
@@ -2862,7 +2862,7 @@
     if (!CheckYButtonPress())
       return;
 
-    if (savegame_tagalong == 10) {
+    if (follower_indicator == 10) {
       dialogue_message_index = 289;
       Main_ShowTextMessage();
       return;
@@ -2976,19 +2976,19 @@
 void HandleFollowersAfterMirroring() {  // 87aaa2
   TileDetect_MainHandler(0);
   link_animation_steps = 0;
-  if (savegame_tagalong == 12 || savegame_tagalong == 13) {
-    if (savegame_tagalong == 13) {
+  if (follower_indicator == 12 || follower_indicator == 13) {
+    if (follower_indicator == 13) {
       super_bomb_indicator_unk2 = 0xfe;
       super_bomb_indicator_unk1 = 0;
     }
-    if (super_bomb_going_off) {
-      super_bomb_going_off = 0;
-      savegame_tagalong = 0;
+    if (follower_dropped) {
+      follower_dropped = 0;
+      follower_indicator = 0;
     }
-  } else if (savegame_tagalong == 9 || savegame_tagalong == 10) {
-    savegame_tagalong = 0;
-  } else if (savegame_tagalong == 7 || savegame_tagalong == 8) {
-    savegame_tagalong ^= (7 ^ 8);
+  } else if (follower_indicator == 9 || follower_indicator == 10) {
+    follower_indicator = 0;
+  } else if (follower_indicator == 7 || follower_indicator == 8) {
+    follower_indicator ^= (7 ^ 8);
     LoadFollowerGraphics();
     AncillaAdd_DwarfPoof(0x40, 4);
   }
@@ -3534,7 +3534,7 @@
   bitmask_of_dragstate = 0;
   link_moving_against_diag_tile = 0;
 
-  if (savegame_tagalong == kTagalongArr1[savegame_tagalong]) {
+  if (follower_indicator == kTagalongArr1[follower_indicator]) {
     printf("Warning: Write to CART!\n");
     link_speed_setting = 0;
     timer_tagalong_reacquire = 64;
--- a/sprite.c
+++ b/sprite.c
@@ -877,8 +877,8 @@
   }
 }
 
-void Ancilla_SpawnFallingPrize(uint8 item) {  // 85a51d
-  AncillaAdd_FallingPrize(0x29, item, 4);
+int Ancilla_SpawnFallingPrize(uint8 item) {  // 85a51d
+  return AncillaAdd_FallingPrize(0x29, item, 4);
 }
 
 bool Sprite_CheckDamageToAndFromLink(int k) {  // 85ab93
@@ -3798,7 +3798,7 @@
   byte_7E0FC6 = 0;
   sprite_limit_instance = 0;
   sort_sprites_setting = 0;
-  if (savegame_tagalong != 13)
+  if (follower_indicator != 13)
     super_bomb_indicator_unk2 = 0xfe;
   memset(sprite_where_in_room, 0, 0x1000);
   memset(overworld_sprite_was_loaded, 0, 0x200);
--- a/sprite.h
+++ b/sprite.h
@@ -112,7 +112,7 @@
 void SpriteModule_Burn(int k);
 void Sprite_HitTimer31(int k);
 void SpriteStunned_MainEx(int k, bool second_entry);
-void Ancilla_SpawnFallingPrize(uint8 item);
+int Ancilla_SpawnFallingPrize(uint8 item);
 bool Sprite_CheckDamageToAndFromLink(int k);
 uint8 Sprite_CheckTileCollision(int k);
 bool Sprite_TrackBodyToHead(int k);
--- a/sprite_main.c
+++ b/sprite_main.c
@@ -1391,7 +1391,7 @@
   Sprite_NullifyHookshotDrag();
   Sprite_RepelDash();
 
-  if (savegame_tagalong != 1 || !link_item_torch || link_is_running || sprite_G[k] == 0x90 || sign8(link_actual_vel_x - 24))
+  if (follower_indicator != 1 || !link_item_torch || link_is_running || sprite_G[k] == 0x90 || sign8(link_actual_vel_x - 24))
     return;
 
   which_starting_point = 4;
@@ -1558,12 +1558,16 @@
   Sprite_PrepOamCoord(k, &info);
   if (Sprite_ReturnIfInactive(k))
     return;
-  if (link_is_bunny_mirror | link_disable_sprite_damage | countdown_for_blink || savegame_tagalong == 10)
+  if (link_is_bunny_mirror | link_disable_sprite_damage | countdown_for_blink || follower_indicator == 10)
     return;
   if (save_ow_event_info[BYTE(overworld_screen_index)] & 0x20)
     return;
   if (Sprite_CheckDamageToLink_same_layer(k)) {
-    savegame_tagalong = 10;
+    // Kiki Big Bomb Fix
+    if (enhanced_features0 & kFeatures0_MiscBugFixes)
+      follower_dropped = 0;  // defuse bomb
+
+    follower_indicator = 10;
     tagalong_var5 = 0;
     LoadFollowerGraphics();
     Follower_Initialize();
@@ -5923,7 +5927,7 @@
     }
     break;
   case 4:  // Uncle_ApplyTelepathyFollower
-    savegame_tagalong = 5;
+    follower_indicator = 5;
     word_7E02CD = 0xdf3;
     sram_progress_flags |= 0x10;
     sprite_state[k] = 0;
@@ -5938,7 +5942,7 @@
     if (Sprite_CheckDamageToLink_same_layer(k))
       Link_CancelDash();
     if (Sprite_ShowMessageOnContact(k, 0xe) & 0x100) {
-      savegame_tagalong = 0;
+      follower_indicator = 0;
       sprite_ai_state[k]++;
     }
     break;
@@ -6463,7 +6467,7 @@
   Sprite_SetX(k, link_x_coord);
   Sprite_SetY(k, link_y_coord);
   sprite_subtype2[k] = 1;
-  savegame_tagalong = 0;
+  follower_indicator = 0;
   sprite_ignore_projectile[k]++;
   sprite_flags4[k] = 3;
 }
@@ -6522,7 +6526,7 @@
     flag_is_link_immobilized = 0;
     which_starting_point = 2;
     SavePalaceDeaths();
-    savegame_tagalong = 1;
+    follower_indicator = 1;
     Dungeon_FlagRoomData_Quadrants();
     Sprite_BecomeFollower(k);
     sprite_state[k] = 0;
@@ -7611,13 +7615,13 @@
 void SpritePrep_BlindMaiden(int k) {  // 86899c
   if (!(save_dung_info[0xac] & 0x800)) {
     sprite_ignore_projectile[k]++;
-    if (savegame_tagalong != 6) {
-      savegame_tagalong = 6;
-      super_bomb_going_off = 0;
+    if (follower_indicator != 6) {
+      follower_indicator = 6;
+      follower_dropped = 0;
       tagalong_var5 = 0;
       LoadFollowerGraphics();
       Follower_Initialize();
-      savegame_tagalong = 0;
+      follower_indicator = 0;
       return;
     }
   }
@@ -7666,7 +7670,7 @@
 }
 
 void SpritePrep_PurpleChest(int k) {  // 868a59
-  if (savegame_tagalong != 12 && !(sram_progress_indicator_3 & 16) && sram_progress_indicator_3 & 32)
+  if (follower_indicator != 12 && !(sram_progress_indicator_3 & 16) && sram_progress_indicator_3 & 32)
     sprite_ignore_projectile[k]++;
   else
     sprite_state[k] = 0;
@@ -7675,7 +7679,7 @@
 void SpritePrep_Smithy(int k) {  // 868a79
   sprite_ignore_projectile[k]++;
   if (savegame_is_darkworld & 64) {
-    if (sram_progress_indicator_3 & 32 || savegame_tagalong != 0)
+    if (sram_progress_indicator_3 & 32 || follower_indicator != 0)
       sprite_state[k] = 0;
     else
       sprite_subtype2[k] = 2;
@@ -7960,11 +7964,11 @@
 
 void SpritePrep_Locksmith(int k) {  // 868d59
   sprite_ignore_projectile[k]++;
-  if (savegame_tagalong == 9) {
+  if (follower_indicator == 9) {
     sprite_state[k] = 0;
     return;
   }
-  if (savegame_tagalong == 12) {
+  if (follower_indicator == 12) {
     sprite_ai_state[k] = 2;
   }
   if (sram_progress_indicator_3 & 0x10)
@@ -10275,7 +10279,7 @@
     if (Sprite_ShowSolicitedMessage(k, 0xe1) & 0x100)
       sprite_ai_state[k] = 1;
   } else {
-    savegame_tagalong = 7;
+    follower_indicator = 7;
     LoadFollowerGraphics();
     Sprite_BecomeFollower(k);  // zelda bug: doesn't save X
     sprite_state[k] = 0;
@@ -10340,7 +10344,7 @@
   switch(sprite_ai_state[k]) {
   case 0:  // ConversationStart
     sprite_C[k] = 0;
-    if (savegame_tagalong != 8) {
+    if (follower_indicator != 8) {
       if (Smithy_ListenForHammer(k)) {
         Sprite_ShowMessageUnconditional(0xe4);
         sprite_delay_aux1[k] = 96;
@@ -10435,7 +10439,7 @@
       sprite_ignore_projectile[j] = 3;
     }
     sprite_ai_state[k] = 11;
-    savegame_tagalong = 0;
+    follower_indicator = 0;
     sprite_graphics[k] = 4;
     break;
   }
@@ -10856,13 +10860,13 @@
     sprite_y_vel[k] = 1;
     if (!Sprite_CheckTileCollision(k)) {
       sprite_ai_state[k]++;
-      if (savegame_tagalong != 0)
+      if (follower_indicator != 0)
         sprite_ai_state[k] = 5;
     }
     sprite_x_lo[k] = bak;
     break;
   case 1:  // transition to tagalong
-    savegame_tagalong = 9;
+    follower_indicator = 9;
     tagalong_var5 = 0;
     LoadFollowerGraphics();
     Follower_Initialize();
@@ -10872,7 +10876,7 @@
   case 2:  // offer chest
     if (Sprite_CheckIfLinkIsBusy())
       return;
-    if (super_bomb_going_off) {
+    if (follower_dropped) {
       j = Sprite_ShowSolicitedMessage(k, 0x109);
     } else {
       j = Sprite_ShowMessageOnContact(k, 0x109);
@@ -10882,7 +10886,7 @@
     break;
   case 3:  // react to secret keeping
     if (!choice_in_multiselect_box) {
-      if (super_bomb_going_off) {
+      if (follower_dropped) {
         Sprite_ShowMessageUnconditional(0x10c);
         sprite_ai_state[k] = 2;
       } else {
@@ -10890,7 +10894,7 @@
         Link_ReceiveItem(0x16, 0);
         sram_progress_indicator_3 |= 0x10;
         sprite_ai_state[k] = 4;
-        savegame_tagalong = 0;
+        follower_indicator = 0;
       }
     } else {
       Sprite_ShowMessageUnconditional(0x10a);
@@ -11117,7 +11121,7 @@
       j = 0;
     } else {
       sprite_D[k] = sprite_head_dir[k] = Sprite_DirectionToFaceLink(k, NULL) ^ 3;
-      if (savegame_tagalong == 1) {
+      if (follower_indicator == 1) {
         sram_progress_flags |= 0x4;
         save_ow_event_info[0x1b] |= 0x20;
         sprite_delay_main[k] = 170;
@@ -11153,12 +11157,12 @@
     sprite_subtype2[k] = 2;
     return;
   }
-  if (savegame_tagalong == 0) {
+  if (follower_indicator == 0) {
     if (link_item_mirror == 2)
       sprite_state[k] = 0;
-    savegame_tagalong = 4;
+    follower_indicator = 4;
     LoadFollowerGraphics();
-    savegame_tagalong = 0;
+    follower_indicator = 0;
   } else {
     sprite_state[k] = 0;
     LoadFollowerGraphics();
@@ -11370,10 +11374,10 @@
   }
   sprite_ignore_projectile[k]++;
   sprite_D[k] = sprite_head_dir[k] = Sprite_DirectionToFaceLink(k, NULL) ^ 3;
-  uint8 bak0 = savegame_tagalong;
-  savegame_tagalong = 1;
+  uint8 bak0 = follower_indicator;
+  follower_indicator = 1;
   LoadFollowerGraphics();
-  savegame_tagalong = bak0;
+  follower_indicator = bak0;
 
   if (BYTE(dungeon_room_index) == 0x12) {
     sprite_subtype2[k] = 2;
@@ -11386,7 +11390,7 @@
     }
   } else {
     sprite_subtype2[k] = 0;
-    if (savegame_tagalong == 1 || (sram_progress_flags & 4))
+    if (follower_indicator == 1 || (sram_progress_flags & 4))
       sprite_state[k] = 0;
   }
 }
@@ -15593,7 +15597,7 @@
 }
 
 void SpritePrep_Blind_PrepareBattle(int k) {  // 9da081
-  if (savegame_tagalong != 6 && dung_savegame_state_bits & 0x2000) {
+  if (follower_indicator != 6 && dung_savegame_state_bits & 0x2000) {
     sprite_delay_aux2[k] = 96;
     sprite_C[k] = 1;
     sprite_D[k] = 2;
@@ -19425,7 +19429,7 @@
   switch(sprite_ai_state[k]) {
   case 0:  // intro
     if ((uint8)(sprite_y_lo[k] + 7) < BYTE(link_y_coord) && Sprite_DirectionToFaceLink(k, NULL) == 2) {
-      if (savegame_tagalong == 0) {
+      if (follower_indicator == 0) {
         if (Sprite_ShowSolicitedMessage(k, 0x187) & 0x100)
           sprite_ai_state[k]++;
       } else {
@@ -24498,11 +24502,11 @@
   if (Sprite_ReturnIfInactive(k))
     return;
   if (!sprite_ai_state[k]) {
-    if (Sprite_ShowMessageOnContact(k, 0x116) & 0x100 && savegame_tagalong == 0)
+    if (Sprite_ShowMessageOnContact(k, 0x116) & 0x100 && follower_indicator == 0)
       sprite_ai_state[k] = 1;
   } else {
     sprite_state[k] = 0;
-    savegame_tagalong = 12;
+    follower_indicator = 12;
     LoadFollowerGraphics();
     Sprite_BecomeFollower(k);
   }
@@ -24576,7 +24580,7 @@
       Sprite_ShowMessageUnconditional(0x17c);
       ShopItem_PlayBeep(k);
     } else {
-      savegame_tagalong = 13;
+      follower_indicator = 13;
       LoadFollowerGraphics();
       Sprite_BecomeFollower(k);
       sprite_state[k] = 0;
@@ -24691,7 +24695,7 @@
     } else {
       Sprite_ShowMessageUnconditional(0x120);
       tagalong_event_flags &= ~3;
-      savegame_tagalong = 0;
+      follower_indicator = 0;
       sprite_ai_state[k]++;
       flag_is_link_immobilized++;
     }
@@ -24905,7 +24909,7 @@
       sprite_ai_state[k] = 1;
   } else {
     sprite_state[k] = 0;
-    savegame_tagalong = 6;
+    follower_indicator = 6;
     LoadFollowerGraphics();
     Sprite_BecomeFollower(k);
   }
@@ -24921,7 +24925,7 @@
   sprite_ignore_projectile[j] = 1;
   sprite_subtype2[j] = 1;
   OldMan_EnableCutscene();
-  savegame_tagalong = 0;
+  follower_indicator = 0;
   link_speed_setting = 0;
 }
 
@@ -24949,7 +24953,7 @@
       }
       break;
     case 1: // switch to tagalong
-      savegame_tagalong = 4;
+      follower_indicator = 4;
       Sprite_BecomeFollower(k);
       which_starting_point = 5;
       sprite_state[k] = 0;
--- a/tagalong.c
+++ b/tagalong.c
@@ -225,18 +225,18 @@
   tagalong_var4 = 0;
   link_speed_setting = 0;
   tagalong_var5 = 0;
-  super_bomb_going_off = 0;
+  follower_dropped = 0;
   Follower_MoveTowardsLink();
 }
 
 void Follower_Main() {  // 899fc4
-  if (!savegame_tagalong)
+  if (!follower_indicator)
     return;
-  if (savegame_tagalong == 0xe) {
+  if (follower_indicator == 0xe) {
     Follower_HandleTrigger();
     return;
   }
-  int j = FindInByteArray(kTagalong_Tab0, savegame_tagalong, 3);
+  int j = FindInByteArray(kTagalong_Tab0, follower_indicator, 3);
   if (j >= 0 && submodule_index == 0 && !(j == 2 && overworld_screen_index & 0x40) && sign16(--word_7E02CD)) {
     if (!Follower_ValidateMessageFreedom()) {
       word_7E02CD = 0;
@@ -253,16 +253,16 @@
 void Follower_NoTimedMessage() {  // 89a02b
   int k;
 
-  if (super_bomb_going_off) {
+  if (follower_dropped) {
     Follower_NotFollowing();
     return;
   }
 
-  if (savegame_tagalong == 12) {
+  if (follower_indicator == 12) {
     if (link_auxiliary_state != 0)
       goto label_a;
 
-  } else if (savegame_tagalong == 13) {
+  } else if (follower_indicator == 13) {
     if (link_auxiliary_state == 2 || player_near_pit_state == 2)
       goto label_c;
   } else {
@@ -275,7 +275,7 @@
 
 label_c:
 
-  if (savegame_tagalong == 13 && !player_is_indoors) {
+  if (follower_indicator == 13 && !player_is_indoors) {
     if (link_player_handler_state == kPlayerState_Ether ||
         link_player_handler_state == kPlayerState_Bombos ||
         link_player_handler_state == kPlayerState_Quake)
@@ -284,7 +284,7 @@
     super_bomb_indicator_unk1 = 0xbb;
   }
 
-  super_bomb_going_off = 128;
+  follower_dropped = 128;
   timer_tagalong_reacquire = 64;
 
   k = tagalong_var2;
@@ -327,7 +327,7 @@
     tagalong_layerbits[k] = layerbits;
   }
 
-  switch (savegame_tagalong) {
+  switch (follower_indicator) {
   case 2: case 4:
     Follower_OldMan();
     return;
@@ -352,18 +352,18 @@
 
   Follower_HandleTrigger();
 
-  if (savegame_tagalong == 10 && link_auxiliary_state && countdown_for_blink) {
+  if (follower_indicator == 10 && link_auxiliary_state && countdown_for_blink) {
     int k = tagalong_var2 + 1 == 20 ? 0 : tagalong_var2 + 1;
     Kiki_SpawnHandler_B(k);
-    savegame_tagalong = 0;
+    follower_indicator = 0;
     return;
   }
 
-  if (savegame_tagalong == 6 && dungeon_room_index == 0xac && (save_dung_info[101] & 0x100) && Follower_CheckBlindTrigger()) {
+  if (follower_indicator == 6 && dungeon_room_index == 0xac && (save_dung_info[101] & 0x100) && Follower_CheckBlindTrigger()) {
     int k = tagalong_var2;
     uint16 x = tagalong_x_lo[k] | tagalong_x_hi[k] << 8;
     uint16 y = tagalong_y_lo[k] | tagalong_y_hi[k] << 8;
-    savegame_tagalong = 0;
+    follower_indicator = 0;
     Blind_SpawnFromMaiden(x, y);
     BYTE(dung_flag_trapdoors_down)++;
     BYTE(dung_cur_door_pos) = 0;
@@ -418,16 +418,16 @@
   if (!link_is_running && !Follower_CheckProximityToLink()) {
     Follower_Initialize();
     saved_tagalong_indoors = player_is_indoors;
-    if (savegame_tagalong == 13) {
+    if (follower_indicator == 13) {
       super_bomb_indicator_unk2 = 254;
       super_bomb_indicator_unk1 = 0;
     }
-    super_bomb_going_off = 0;
+    follower_dropped = 0;
     Tagalong_Draw();
   } else {
-    if (savegame_tagalong == 13 && !player_is_indoors && !super_bomb_indicator_unk2) {
+    if (follower_indicator == 13 && !player_is_indoors && !super_bomb_indicator_unk2) {
       AncillaAdd_SuperBombExplosion(0x3a, 0);
-      super_bomb_going_off = 0;
+      follower_dropped = 0;
     }
     Follower_DoLayers();
   }
@@ -446,9 +446,9 @@
 
   Follower_HandleTrigger();
 
-  if (savegame_tagalong == 0) {
+  if (follower_indicator == 0) {
     return;
-  } else if (savegame_tagalong == 4) {
+  } else if (follower_indicator == 4) {
     if ((int8)tagalong_z[tagalong_var2] > 0 && tagalong_var1 != tagalong_var2) {
       tagalong_var2 = (tagalong_var2 + 1 >= 20) ? 0 : tagalong_var2 + 1;
       Tagalong_Draw();
@@ -464,7 +464,7 @@
 
     if (link_auxiliary_state & 2) {
 transform:
-      savegame_tagalong = kTagalong_Tab4[savegame_tagalong];
+      follower_indicator = kTagalong_Tab4[follower_indicator];
       timer_tagalong_reacquire = 64;
       int k = tagalong_var2;
       saved_tagalong_y = tagalong_y_lo[k] | tagalong_y_hi[k] << 8;
@@ -499,7 +499,7 @@
     link_speed_setting = 0;
     if (link_player_handler_state != kPlayerState_Hookshot && !Follower_CheckProximityToLink()) {
       Follower_Initialize();
-      savegame_tagalong = kTagalong_Tab5[savegame_tagalong];
+      follower_indicator = kTagalong_Tab5[follower_indicator];
       return;
     }
   }
@@ -508,7 +508,7 @@
 
 void Follower_DoLayers() {  // 89a450
   oam_priority_value = kTagalongFlags[saved_tagalong_floor] << 8;
-  uint8 a = (savegame_tagalong == 12 || savegame_tagalong == 13) ? 2 : 1;
+  uint8 a = (follower_indicator == 12 || follower_indicator == 13) ? 2 : 1;
   Follower_AnimateMovement_preserved(a, saved_tagalong_x, saved_tagalong_y);
 }
 
@@ -544,7 +544,7 @@
   }
   int st = (tagalong_var2 + 1 >= 20) ? 0 : tagalong_var2 + 1;
   do {
-    if (tmi->tagalong == savegame_tagalong && Follower_CheckForTrigger(tmi)) {
+    if (tmi->tagalong == follower_indicator && Follower_CheckForTrigger(tmi)) {
       if (tmi->bit & tagalong_event_flags)
         return;
       tagalong_event_flags |= tmi->bit;
@@ -559,7 +559,7 @@
       if (tmi->msg == 0x9d) {
         OldMan_RevertToSprite(st);
       } else if (tmi->msg == 0x28) {
-        savegame_tagalong = 0;
+        follower_indicator = 0;
       }
       Main_ShowTextMessage();
       return;
@@ -588,7 +588,7 @@
   uint8 yt = 0, av = 0;
   uint8 sc = 0;
 
-  if ((ain >> 2 & 8) && (savegame_tagalong == 6 || savegame_tagalong == 1)) {
+  if ((ain >> 2 & 8) && (follower_indicator == 6 || follower_indicator == 1)) {
     yt = 8;
     if (swimcoll_var7[0] | swimcoll_var7[1])
       av = (frame_counter >> 1) & 4;
@@ -596,9 +596,9 @@
       av = (frame_counter >> 2) & 4;
   } else if (submodule_index == 8 || submodule_index == 14 || submodule_index == 16) {
     av = link_is_running ? (frame_counter & 4) : ((frame_counter >> 1) & 4);
-  } else if (savegame_tagalong == 11) {
+  } else if (follower_indicator == 11) {
     av = (frame_counter >> 1) & 4;
-  } else if ((savegame_tagalong == 12 || savegame_tagalong == 13) && super_bomb_going_off || flag_is_link_immobilized ||
+  } else if ((follower_indicator == 12 || follower_indicator == 13) && follower_dropped || flag_is_link_immobilized ||
              submodule_index == 10 || main_module_index == 9 && submodule_index == 0x23 ||
              main_module_index == 14 && (submodule_index == 1 || submodule_index == 2) ||
              (link_y_vel | link_x_vel) == 0) {
@@ -620,7 +620,7 @@
   uint16 scrollx = xin - BG2HOFS_copy2;
 
   const uint8 *sk = kTagalongDraw_SprInfo0;
-  if (savegame_tagalong == 1 || savegame_tagalong == 6 || !(ain & 0x20)) {
+  if (follower_indicator == 1 || follower_indicator == 6 || !(ain & 0x20)) {
     if (!(ain & 0xc0))
       goto skip_first_sprites;
     if ((ain & 0x80) || (sk += 12, sc == 0))
@@ -651,17 +651,17 @@
   }
   uint8 pal;
 skip_first_sprites:
-  pal = kTagalongDraw_Pals[savegame_tagalong];
+  pal = kTagalongDraw_Pals[follower_indicator];
   if (pal == 7 && overworld_palette_swap_flag)
     pal = 0;
 
-  if (savegame_tagalong == 13 && super_bomb_indicator_unk2 == 1)
+  if (follower_indicator == 13 && super_bomb_indicator_unk2 == 1)
     pal = (frame_counter & 7);
 
-  const TagalongSprXY *sprd = kTagalongDraw_SprXY + frame + (kTagalongDraw_Offs[savegame_tagalong] >> 3);
+  const TagalongSprXY *sprd = kTagalongDraw_SprXY + frame + (kTagalongDraw_Offs[follower_indicator] >> 3);
   const TagalongDmaFlags *sprf = kTagalongDmaAndFlags + frame;
 
-  if (savegame_tagalong != 12 && savegame_tagalong != 13) {
+  if (follower_indicator != 12 && follower_indicator != 13) {
     uint16 y = scrolly + sprd->y1, x = scrollx + sprd->x1, ext = 0;
     oam->x = x;
     oam->y = (uint16)(x + 0x80) < 0x180 && (ext = x >> 8 & 1, (uint16)(y + 0x10) < 0x100) ? y : 0xf0;
@@ -693,8 +693,8 @@
 }
 
 void Follower_Disable() {  // 89acf3
-  if (savegame_tagalong == 9 || savegame_tagalong == 10)
-    savegame_tagalong = 0;
+  if (follower_indicator == 9 || follower_indicator == 10)
+    follower_indicator = 0;
 }
 
 void Blind_SpawnFromMaiden(uint16 x, uint16 y) {  // 9da03c
@@ -715,7 +715,7 @@
 void Kiki_RevertToSprite(int k) {  // 9ee66b
   int j = Kiki_SpawnHandlerMonke(k);
   sprite_subtype2[j] = 1;
-  savegame_tagalong = 0;
+  follower_indicator = 0;
 }
 
 int Kiki_SpawnHandlerMonke(int k) {  // 9ee67a
@@ -746,6 +746,6 @@
   sprite_z[j] = 1;
   sprite_z_vel[j] = 16;
   sprite_subtype2[j] = 3;
-  savegame_tagalong = 0;
+  follower_indicator = 0;
 }
 
--- a/variables.h
+++ b/variables.h
@@ -1114,12 +1114,12 @@
 #define which_starting_point (*(uint8*)(g_ram+0xF3C8))
 #define sram_progress_indicator_3 (*(uint8*)(g_ram+0xF3C9))
 #define savegame_is_darkworld (*(uint8*)(g_ram+0xF3CA))
-#define savegame_tagalong (*(uint8*)(g_ram+0xF3CC))
+#define follower_indicator (*(uint8*)(g_ram+0xF3CC))
 #define saved_tagalong_y (*(uint16*)(g_ram+0xF3CD))
 #define saved_tagalong_x (*(uint16*)(g_ram+0xF3CF))
 #define saved_tagalong_indoors (*(uint8*)(g_ram+0xF3D1))
 #define saved_tagalong_floor (*(uint8*)(g_ram+0xF3D2))
-#define super_bomb_going_off (*(uint8*)(g_ram+0xF3D3))
+#define follower_dropped (*(uint8*)(g_ram+0xF3D3))
 #define deaths_per_palace ((uint16*)(g_ram+0xF3E7))
 #define death_save_counter (*(uint16*)(g_ram+0xF403))
 #define death_var2 (*(uint16*)(g_ram+0xF405))
--- a/zelda3.ini
+++ b/zelda3.ini
@@ -73,6 +73,9 @@
 # Can carry 9999 rupees instead of 999
 CarryMoreRupees = 0
 
+# Enable various zelda bug fixes
+MiscBugFixes = 1
+
 [KeyMap]
 # Change what keyboard keys map to the joypad
 # Order: Up, Down, Left, Right, Select, Start, A, B, X, Y, L, R
--- a/zelda_cpu_infra.c
+++ b/zelda_cpu_infra.c
@@ -322,7 +322,7 @@
     cpu_reset(g_snes->cpu);
 }
 
-static void EmuRunFrameWithCompare(uint16 input_state, int run_what) {
+void EmuRunFrameWithCompare(uint16 input_state, int run_what) {
   MakeSnapshot(&g_snapshot_before);
   MakeMySnapshot(&g_snapshot_mine);
   MakeSnapshot(&g_snapshot_theirs);