shithub: zelda3

Download patch

ref: aedf48a7b5fcd87b6ecffe8c28c4716b6b5b7017
parent: ef5451e2df6a862329031b8abbc24eda390e4db8
author: Snesrev <snesrev@protonmail.com>
date: Thu Sep 29 14:00:34 EDT 2022

Add config option to carry more rupees (9999 instead of 999)

 - Also reworked hud code a bit more

--- a/config.c
+++ b/config.c
@@ -313,6 +313,8 @@
       return ParseBoolBit(value, &g_config.features0, kFeatures0_ShowMaxItemsInYellow);
     } else if (StringEqualsNoCase(key, "MoreActiveBombs")) {
       return ParseBoolBit(value, &g_config.features0, kFeatures0_MoreActiveBombs);
+    } else if (StringEqualsNoCase(key, "CarryMoreRupees")) {
+      return ParseBoolBit(value, &g_config.features0, kFeatures0_CarryMoreRupees);
     }
   }
   return false;
--- a/features.h
+++ b/features.h
@@ -34,6 +34,8 @@
 
   // This is set for visual fixes that don't affect game behavior but will affect ram compare.
   kFeatures0_WidescreenVisualFixes = 1024,
+
+  kFeatures0_CarryMoreRupees = 2048,
 };
 
 #define enhanced_features0 (*(uint32*)(g_ram+0x64c))
--- a/hud.c
+++ b/hud.c
@@ -19,8 +19,10 @@
 static void Hud_EquipNextItem(uint8 *item);
 static int Hud_GetItemPosition(int item);
 static void Hud_ReorderItem(int direction);
+static void Hud_Update_Magic();
+static void Hud_Update_Inventory();
+static void Hud_Update_Hearts();
 
-
 const uint8 kMaxBombsForLevel[] = { 10, 15, 20, 25, 30, 35, 40, 50 };
 const uint8 kMaxArrowsForLevel[] = { 30, 35, 40, 45, 50, 55, 60, 70 };
 static const uint8 kMaxHealthForLevel[] = { 9, 9, 9, 9, 9, 9, 9, 9, 17, 17, 17, 17, 17, 17, 17, 25, 25, 25, 25, 25, 25 };
@@ -189,15 +191,8 @@
   {0x2c68, 0x6c68, 0x2c78, 0x6c78},
   {0x2468, 0x6468, 0x2478, 0x6478},
 };
-static const uint16 kHudTilemap[165] = {
-  0x207f, 0x207f, 0x2850, 0xa856, 0x2852, 0x285b, 0x285b, 0x285c, 0x207f, 0x3ca8, 0x207f, 0x207f, 0x2c88, 0x2c89, 0x207f, 0x20a7, 0x20a9, 0x207f, 0x2871, 0x207f, 0x207f, 0x207f, 0x288b, 0x288f, 0x24ab, 0x24ac, 0x688f, 0x688b, 0x207f, 0x207f, 0x207f, 0x207f,
-  0x207f, 0x207f, 0x2854, 0x2871, 0x2858, 0x207f, 0x207f, 0x285d, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f,
-  0x207f, 0x207f, 0x2854, 0x304e, 0x2858, 0x207f, 0x207f, 0x285d, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f,
-  0x207f, 0x207f, 0x2854, 0x305e, 0x2859, 0xa85b, 0xa85b, 0xa85c, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f,
-  0x207f, 0x207f, 0x2854, 0x305e, 0x6854, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f,
-  0x207f, 0x207f, 0xa850, 0x2856, 0xe850,
-};
 
+
 static const ItemBoxGfx * const kHudItemBoxGfxPtrs[] = {
   kHudItemBow,
   kHudItemBoomerang,
@@ -378,7 +373,10 @@
   j = sign8(q - 1) ? 10 : q - 1;
   hud_tile_indices_buffer[0xf2 / 2] = kDungFloorIndicator_Gfx0[j];
   hud_tile_indices_buffer[0x132 / 2] = kDungFloorIndicator_Gfx1[j];
+}
 
+static int MaxRupees() {
+  return enhanced_features0 & kFeatures0_CarryMoreRupees ? 9999 : 999;
 }
 
 void Hud_RefillLogic() {  // 8ddb92
@@ -402,8 +400,9 @@
       if ((int16)--a < 0)
         link_rupees_goal = a = 0;
     } else {
-      if (++a >= 1000)
-        link_rupees_goal = a = 999;
+      int m = MaxRupees();
+      if (++a > m)
+        link_rupees_goal = a = m;
     }
     link_rupees_actual = a;
     if (sound_effect_1 == 0) {
@@ -459,7 +458,8 @@
       animate_heart_refill_countdown = 7;
 
 doing_animation:
-      Hud_Update_IgnoreHealth();
+      Hud_Update_Magic();
+      Hud_Update_Inventory();
       Hud_AnimateHeartRefill();
       flag_update_hud_in_nmi++;
       return;
@@ -467,7 +467,9 @@
     link_health_current = link_health_capacity;
     link_hearts_filler = 0;
   }
-  Hud_Update_IgnoreItemBox();
+  Hud_Update_Hearts();
+  Hud_Update_Magic();
+  Hud_Update_Inventory();
   flag_update_hud_in_nmi++;
 }
 
@@ -663,7 +665,7 @@
 
 void Hud_UpdateHud() {  // 8ddfa9
   overworld_map_state++;
-  Hud_UpdateOnly();
+  Hud_Rebuild();
   Hud_UpdateEquippedItem();
 }
 
@@ -687,7 +689,6 @@
 }
 
 void Hud_UpdateEquippedItem() {  // 8ddfaf
-
   if (hud_cur_item >= kHudItem_Bottle1)
     link_item_bottle_index = hud_cur_item - kHudItem_Bottle1 + 1;
 
@@ -1232,10 +1233,11 @@
   }
 }
 
-void Hud_IntToDecimal(unsigned int number, uint8 *out) {  // 8df0f7
-  out[0] = number / 100 + 0x90;
-  out[1] = (number %= 100) / 10 + 0x90;
-  out[2] = (number % 10) + 0x90;
+static void Hud_IntToDecimal(unsigned int number, uint8 *out) {  // 8df0f7
+  out[0] = number / 1000 + 0x90;
+  out[1] = (number %= 1000) / 100 + 0x90;
+  out[2] = (number %= 100) / 10 + 0x90;
+  out[3] = (number % 10) + 0x90;
 }
 
 bool Hud_RefillHealth() {  // 8df128
@@ -1252,7 +1254,7 @@
   if (--animate_heart_refill_countdown)
     return;
   uint16 n = ((uint16)((link_health_current & ~7) - 1) >> 3) << 1;
-  uint16 *p = hud_tile_indices_buffer + 0x34;
+  uint16 *p = hud_tile_indices_buffer + HUDXY(20, 1);
   if (n >= 20) {
     n -= 20;
     p += 0x20;
@@ -1292,108 +1294,141 @@
   Hud_Rebuild();
 }
 
-void Hud_Rebuild() {  // 8dfa70
-  memcpy(hud_tile_indices_buffer, kHudTilemap, 165 * sizeof(uint16));
-  Hud_UpdateInternal();
-  flag_update_hud_in_nmi++;
-}
-
-void Hud_UpdateOnly() {  // 8dfa85
-  Hud_UpdateInternal();
-  flag_update_hud_in_nmi++;
-}
-
-void Hud_UpdateItemBox() {  // 8dfafd
+static void Hud_UpdateItemBox() {  // 8dfafd
+  // Update r
   if (link_item_bow) {
     if (link_item_bow >= 3) {
-      hud_tile_indices_buffer[15] = 0x2486;
-      hud_tile_indices_buffer[16] = 0x2487;
+      hud_tile_indices_buffer[HUDXY(15, 0)] = 0x2486;
+      hud_tile_indices_buffer[HUDXY(16, 0)] = 0x2487;
       link_item_bow = link_num_arrows ? 4 : 3;
     } else {
       link_item_bow = link_num_arrows ? 2 : 1;
     }
   }
-
   if (hud_cur_item)
-    Hud_DrawItem(&hud_tile_indices_buffer[37], Hud_GetIconForItem(hud_cur_item));
+    Hud_DrawItem(&hud_tile_indices_buffer[HUDXY(5, 1)], Hud_GetIconForItem(hud_cur_item));
 }
 
-void Hud_UpdateInternal() {  // 8dfb91
-  Hud_UpdateItemBox();
-  Hud_Update_IgnoreItemBox();
+static void Hud_UpdateHearts_Inner(uint16 *dst, const uint16 *src, int n) {  // 8dfdab
+  int x = 0;
+  while (n > 0) {
+    if (x >= 10) {
+      dst += 0x20;
+      x = 0;
+    }
+    dst[x] = src[n >= 5 ? 2 : 1];
+    x++;
+    n -= 8;
+  }
 }
 
-void Hud_Update_IgnoreItemBox() {  // 8dfb94
+static void DrawHudComponents(uint16 *dst, const uint16 *src, int w, int h) {
+  do {
+    memcpy(dst, src, w * sizeof(uint16));
+  } while (src += w, dst += 32, --h);
+}
+
+static void Hud_Update_Hearts() {  // 8dfb94
   static const uint16 kHudItemBoxTab1[] = { 0x24A2, 0x24A2, 0x24A2 };
   static const uint16 kHudItemBoxTab2[] = { 0x24A2, 0x24A1, 0x24A0 };
-
-  Hud_UpdateHearts(&hud_tile_indices_buffer[0x34], kHudItemBoxTab1, link_health_capacity);
-  Hud_UpdateHearts(&hud_tile_indices_buffer[0x34], kHudItemBoxTab2, (link_health_current + 3) & ~3);
-
-  Hud_Update_IgnoreHealth();
+  // The life meter
+  Hud_UpdateHearts_Inner(&hud_tile_indices_buffer[HUDXY(20, 1)], kHudItemBoxTab1, link_health_capacity);
+  Hud_UpdateHearts_Inner(&hud_tile_indices_buffer[HUDXY(20, 1)], kHudItemBoxTab2, (link_health_current + 3) & ~3);
 }
 
-void Hud_Update_IgnoreHealth() {  // 8dfc09
+static void Hud_Update_Magic() {  // 8dfc09
+  uint16 *dst = &hud_tile_indices_buffer[HUDXY(2, 0)];
   if (link_magic_consumption >= 1) {
-    hud_tile_indices_buffer[2] = 0x28F7;
-    hud_tile_indices_buffer[3] = 0x2851;
-    hud_tile_indices_buffer[4] = 0x28FA;
+    dst[HUDXY(0, 0)] = 0x28F7;
+    dst[HUDXY(1, 0)] = 0x2851;
+    dst[HUDXY(2, 0)] = 0x28FA;
   }
-
   const uint16 *src = kUpdateMagicPowerTilemap[(link_magic_power + 7) >> 3];
-  hud_tile_indices_buffer[0x23] = src[0];
-  hud_tile_indices_buffer[0x43] = src[1];
-  hud_tile_indices_buffer[0x63] = src[2];
-  hud_tile_indices_buffer[0x83] = src[3];
+  dst[HUDXY(1, 1)] = src[0];
+  dst[HUDXY(1, 2)] = src[1];
+  dst[HUDXY(1, 3)] = src[2];
+  dst[HUDXY(1, 4)] = src[3];
+}
 
-  uint8 d[3];
-
+static void Hud_Update_Inventory() {  // 8dfc09
+  uint8 d[4];
   Hud_IntToDecimal(link_rupees_actual, d);
 
-
   const uint16 base_tiles[2] = {
     0x2400,
     (enhanced_features0 & kFeatures0_ShowMaxItemsInYellow) ? 0x3400 : 0x2400,
   };
 
-  int base_tile = base_tiles[link_rupees_actual == 999];
-  hud_tile_indices_buffer[0x28] = base_tile | d[0];
-  hud_tile_indices_buffer[0x29] = base_tile | d[1];
-  hud_tile_indices_buffer[0x2A] = base_tile | d[2];
+  int inv_offs = (d[0] == 0x90) ? 1 : 0;
 
+  static const uint16 kHudInventoryBg[26] = {
+    0x207f, 0x207f, 0x3ca8, 0x207f, 0x207f, 0x2c88, 0x2c89, 0x207f, 0x20a7, 0x20a9, 0x207f, 0x2871, 0x207f,
+    0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f,
+  };
+
+  uint16 *dst = &hud_tile_indices_buffer[HUDXY(8, 0)];
+  memcpy(dst + HUDXY(0, 0), kHudInventoryBg +  0 + inv_offs, 12 * sizeof(uint16));
+  memcpy(dst + HUDXY(0, 1), kHudInventoryBg + 13 + inv_offs, 12 * sizeof(uint16));
+
+  // Offset everything if we have many coins?
+  int base_tile = base_tiles[link_rupees_actual == MaxRupees()];
+  if (inv_offs == 0) {
+    dst++;
+    dst[HUDXY(-1, 1)] = base_tile | d[0];
+  }
+  dst[HUDXY(0, 1)] = base_tile | d[1];
+  dst[HUDXY(1, 1)] = base_tile | d[2];
+  dst[HUDXY(2, 1)] = base_tile | d[3];
+
   Hud_IntToDecimal(link_item_bombs, d);
   base_tile = base_tiles[link_item_bombs == kMaxBombsForLevel[link_bomb_upgrades]];
+  dst[HUDXY(4, 1)] = base_tile | d[2];
+  dst[HUDXY(5, 1)] = base_tile | d[3];
 
-  hud_tile_indices_buffer[0x2C] = base_tile | d[1];
-  hud_tile_indices_buffer[0x2D] = base_tile | d[2];
-
   Hud_IntToDecimal(link_num_arrows, d);
   base_tile = base_tiles[link_num_arrows == kMaxArrowsForLevel[link_arrow_upgrades]];
-  hud_tile_indices_buffer[0x2F] = base_tile | d[1];
-  hud_tile_indices_buffer[0x30] = base_tile | d[2];
+  dst[HUDXY(7, 1)] = base_tile | d[2];
+  dst[HUDXY(8, 1)] = base_tile | d[3];
 
-  d[2] = 0x7f;
+  // Show keys
+  d[3] = 0x7f;
   if (link_num_keys != 0xff)
     Hud_IntToDecimal(link_num_keys, d);
-  hud_tile_indices_buffer[0x32] = 0x2400 | d[2];
-  if (hud_tile_indices_buffer[0x32] == 0x247f)
-    hud_tile_indices_buffer[0x12] = hud_tile_indices_buffer[0x32];
+  dst[HUDXY(10, 1)] = 0x2400 | d[3];
+  if (dst[HUDXY(10, 1)] == 0x247f)
+    dst[HUDXY(10, 0)] = 0x247f;
 }
 
-void Hud_UpdateHearts(uint16 *dst, const uint16 *src, int n) {  // 8dfdab
-  int x = 0;
+void Hud_Rebuild() {  // 8dfa70
+  // The magic meter and item box
+  static const uint16 kHudTilemapLeftPart[8 * 6] = {
+    0x207f, 0x207f, 0x2850, 0xa856, 0x2852, 0x285b, 0x285b, 0x285c,
+    0x207f, 0x207f, 0x2854, 0x2871, 0x2858, 0x207f, 0x207f, 0x285d,
+    0x207f, 0x207f, 0x2854, 0x304e, 0x2858, 0x207f, 0x207f, 0x285d,
+    0x207f, 0x207f, 0x2854, 0x305e, 0x2859, 0xa85b, 0xa85b, 0xa85c,
+    0x207f, 0x207f, 0x2854, 0x305e, 0x6854, 0x207f, 0x207f, 0x207f,
+    0x207f, 0x207f, 0xa850, 0x2856, 0xe850, 
+  };
+  DrawHudComponents(hud_tile_indices_buffer, kHudTilemapLeftPart, 8, 6);
 
-  while (n > 0) {
-    if (x >= 10) {
-      dst += 0x20;
-      x = 0;
-    }
-    dst[x] = src[n >= 5 ? 2 : 1];
-    x++;
-    n -= 8;
-  }
+  static const uint16 kHudTilemapRightPart[12 * 5] = {
+    0x207f, 0x207f, 0x288b, 0x288f, 0x24ab, 0x24ac, 0x688f, 0x688b, 0x207f, 0x207f, 0x207f, 0x207f,
+    0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f,
+    0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f,
+    0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f,
+    0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f, 0x207f,
+  };
+  DrawHudComponents(&hud_tile_indices_buffer[HUDXY(20, 0)], kHudTilemapRightPart, 12, 5);
+
+
+  Hud_Update_Hearts();
+  Hud_Update_Magic();
+  Hud_Update_Inventory();
+  Hud_UpdateItemBox();
+  flag_update_hud_in_nmi++;
 }
 
+
 const uint16 *Hud_GetItemBoxPtr(int item) {
   return kHudItemBoxGfxPtrs[item]->v;
 }
@@ -1419,6 +1454,7 @@
       sound_effect_2 = 32;
       Hud_UpdateEquippedItem();
       Hud_UpdateItemBox();
+      flag_update_hud_in_nmi++;
     }
   }
 }
--- a/hud.h
+++ b/hud.h
@@ -49,7 +49,6 @@
 void Hud_DrawSelectedYButtonItem();
 void Hud_DrawEquipmentBox();
 void Hud_DrawBottleMenu();
-void Hud_IntToDecimal(unsigned int number, uint8 *out);
 bool Hud_RefillHealth();
 void Hud_AnimateHeartRefill();
 bool Hud_RefillMagicPower();
@@ -56,12 +55,6 @@
 void Hud_RestoreTorchBackground();
 void Hud_RebuildIndoor();
 void Hud_Rebuild();
-void Hud_UpdateOnly();
-void Hud_UpdateItemBox();
-void Hud_UpdateInternal();
-void Hud_Update_IgnoreItemBox();
-void Hud_Update_IgnoreHealth();
-void Hud_UpdateHearts(uint16 *dst, const uint16 *src, int n);
 const uint16 *Hud_GetItemBoxPtr(int item);
 
 void Hud_HandleItemSwitchInputs();
--- a/zelda3.ini
+++ b/zelda3.ini
@@ -70,6 +70,8 @@
 # Allows up to four bombs active at a time instead of two.
 MoreActiveBombs = 0
 
+# Can carry 9999 rupees instead of 999
+CarryMoreRupees = 0
 
 [KeyMap]
 # Change what keyboard keys map to the joypad