shithub: zelda3

Download patch

ref: e6b5294e8775120fa652e1cb1a636c9a034a5bf7
parent: 634086734f11bb2f220bf1d8353c810fe473c3a9
author: Snesrev <[email protected]>
date: Wed Sep 28 12:10:55 EDT 2022

Workaround graphics glitch when Link is blinking

 - The game sets the hi x bit to 1 hide link every other frame
   But this won't work with widescreen.
 - Changed so it sets y to 240 instead.

--- a/config.c
+++ b/config.c
@@ -266,6 +266,8 @@
           g_config.extended_aspect_ratio = 0;
         else if (strcmp(s, "unchanged_sprites") == 0)
           g_config.extended_aspect_ratio_nospr = true;
+        else if (strcmp(s, "no_visual_fixes") == 0)
+          g_config.extended_aspect_ratio_novis = true;
         else
           return false;
       }
--- a/config.h
+++ b/config.h
@@ -45,7 +45,7 @@
   uint16 audio_samples;
   bool autosave;
   uint8 extended_aspect_ratio;
-  bool extend_y, extended_aspect_ratio_nospr;
+  bool extend_y, extended_aspect_ratio_nospr, extended_aspect_ratio_novis;
   bool no_sprite_limits;
   bool display_perf_title;
   bool enable_msu;
--- a/main.c
+++ b/main.c
@@ -189,6 +189,7 @@
   {
     uint32 f = 0;
     f |= (g_zenv.ppu->extraLeftRight && !g_config.extended_aspect_ratio_nospr) ? kFeatures0_ExtendScreen64 : 0;
+    f |= (g_zenv.ppu->extraLeftRight && !g_config.extended_aspect_ratio_novis) ? kFeatures0_WidescreenVisualFixes : 0;
     f |= g_config.item_switch_lr * kFeatures0_SwitchLR;
     f |= g_config.turn_while_dashing * kFeatures0_TurnWhileDashing;
     f |= g_config.mirror_to_darkworld * kFeatures0_MirrorToDarkworld;
--- a/player_oam.c
+++ b/player_oam.c
@@ -1103,13 +1103,22 @@
       submodule_index == 0 && countdown_for_blink && --countdown_for_blink >= 4 && (countdown_for_blink & 1) == 0 ||
       link_visibility_status == 12 ||
       link_cape_mode != 0)) {
-    uint8 *p = &bytewise_extended_oam[sort_sprites_offset_into_oam_buffer >> 2];
-    WORD(p[0]) = 0x101;
-    WORD(p[2]) = 0x101;
-    WORD(p[4]) = 0x101;
-    WORD(p[6]) = 0x101;
-    WORD(p[8]) = 0x101;
-    WORD(p[10]) = 0x101;
+    // This appears to hide link by setting the extended bits of the oam to hide them from the screen.
+    // It doesn't really play well with the widescreen modes, so change how it's done.
+    if (enhanced_features0 & kFeatures0_WidescreenVisualFixes) {
+      OamEnt *oam = &oam_buf[sort_sprites_offset_into_oam_buffer >> 2];
+      oam[0].y = oam[1].y = oam[2].y = oam[3].y = 0xf0;
+      oam[4].y = oam[5].y = oam[6].y = oam[7].y = 0xf0;
+      oam[8].y = oam[9].y = oam[10].y = oam[11].y = 0xf0;
+    } else {
+      uint8 *p = &bytewise_extended_oam[sort_sprites_offset_into_oam_buffer >> 2];
+      WORD(p[0]) = 0x101;
+      WORD(p[2]) = 0x101;
+      WORD(p[4]) = 0x101;
+      WORD(p[6]) = 0x101;
+      WORD(p[8]) = 0x101;
+      WORD(p[10]) = 0x101;
+    }
     if (link_visibility_status != 12 && !skip_erase) {
       int oam_pos = ((scratch_0_var ? kShadow_oam_indexes_1 : kShadow_oam_indexes_0)[r4loc] + sort_sprites_offset_into_oam_buffer)>>2;
       WORD(bytewise_extended_oam[oam_pos]) = 0;
--- a/zelda3.ini
+++ b/zelda3.ini
@@ -6,8 +6,10 @@
 
 # Extended aspect ratio, either 16:9, 16:10, or 18:9. 4:3 means normal aspect ratio.
 # Add ", unchanged_sprites" to avoid changing sprite spawn/die behavior. Without this
-# replays will be incompatible. Add "extend_y, " right before the aspect radio specifier
-# to display 240 lines instead of 224.
+# replays will be incompatible.
+# Add ", no_visual_fixes" to avoid fixing some graphics glitches (for example with Cape).
+# It won't affect replays/game behavior but the memory compare will not work.
+# Add "extend_y, " right before the aspect radio specifier to display 240 lines instead of 224.
 ExtendedAspectRatio = 4:3
 
 [Graphics]
--- a/zelda_rtl.h
+++ b/zelda_rtl.h
@@ -124,6 +124,9 @@
   kFeatures0_SkipIntroOnKeypress = 128,
   kFeatures0_ShowMaxItemsInYellow = 256,
   kFeatures0_MoreActiveBombs = 512,
+
+  // This is set for visual fixes that don't affect game behavior but will affect ram compare.
+  kFeatures0_WidescreenVisualFixes = 1024,
 };
 
 #define enhanced_features0 (*(uint32*)(g_ram+0x64c))