ref: e6b5294e8775120fa652e1cb1a636c9a034a5bf7
parent: 634086734f11bb2f220bf1d8353c810fe473c3a9
author: Snesrev <snesrev@protonmail.com>
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))