From 1aa5878ab1b2761878c463f727fc154b79693ea0 Mon Sep 17 00:00:00 2001 From: scawful Date: Mon, 8 Dec 2025 14:04:12 -0500 Subject: [PATCH] Fix: Resolve BG color brightness regression, persist Time System tint, and refactor Minecart data --- Docs/Issues/BGColor_Overlay_RootCause.md | 48 ++++++++++++++++++++++++ Masks/mask_routines.asm | 28 ++++++++++++-- Overworld/ZSCustomOverworld.asm | 10 +++++ Sprites/Objects/minecart.asm | 23 +----------- 4 files changed, 84 insertions(+), 25 deletions(-) create mode 100644 Docs/Issues/BGColor_Overlay_RootCause.md diff --git a/Docs/Issues/BGColor_Overlay_RootCause.md b/Docs/Issues/BGColor_Overlay_RootCause.md new file mode 100644 index 0000000..c994397 --- /dev/null +++ b/Docs/Issues/BGColor_Overlay_RootCause.md @@ -0,0 +1,48 @@ +# BG Color / Overlay Regression — Resolved (March 2026) + +## Resolution Summary +The "Too Bright" and "Flash to Day" bugs have been resolved by fixing the register management in `ZSCustomOverworld.asm`. + +**The Problem:** +When transitioning from an area with an overlay (like Rain/Storms) to an area without one (Overlay ID `$FF`), the code cleared the Subscreen Enable register (`$1D`) but **failed to clear the Color Math Control register (`$9A`)**. +- Rain sets `$9A` to `$72` (Additive Math). +- If `$9A` remains `$72` in a normal area, the SNES PPU continues to perform additive color math using the Fixed Color registers (`$9C`/`$9D`). +- This caused the background to appear significantly brighter (approx +6 per channel), turning the dark night tint into a "bright yellow-ish green". +- This also caused the "Flash to Day" effect during transitions, as the additive brightness kicked in immediately. + +**The Fix:** +Modified `ZSCustomOverworld.asm` in two key locations to ensure `$9A` is always cleared when no overlay is present. + +1. **Walking Transitions (`Overworld_ReloadSubscreenOverlay_Interupt`):** + Added a check for Overlay `$FF` to explicitly clear `$9A`. This prevents the brightness glitch during scrolling. + + ```asm + ; In Overworld_ReloadSubscreenOverlay_Interupt + CPX.b #$FF : BNE .checkScroll + LDA.b #$00 ; Disable Color Math + BRA .loadOverlay + ``` + +2. **Dungeon/Warp/Bird Transitions (`Overworld_LoadBGColorAndSubscreenOverlay`):** + Added `STZ.b $9A` to the block handling the `$FF` case. This prevents the glitch when exiting dungeons or warping. + + ```asm + ; In Overworld_LoadBGColorAndSubscreenOverlay + CMP.w #$00FF : BNE .noCustomFixedColor + SEP #$30 + STZ.b $9A ; FIX: Clear color math + ; ... + ``` + +## Verification +- **Brightness:** The background color in normal areas should now correctly reflect the Time System tint without extra brightness. +- **Transitions:** Walking from a Rain area to a Normal area should no longer result in a brightness jump. +- **Song of Storms:** Summoning and dismissing storms should work correctly, with the overlay and color math engaging and disengaging as expected. + +## Technical Details +- **File:** `Overworld/ZSCustomOverworld.asm` +- **Routines:** `Overworld_LoadBGColorAndSubscreenOverlay`, `Overworld_ReloadSubscreenOverlay_Interupt`. +- **Registers:** `$1D` (Subscreen), `$9A` (CGADDSUB Mirror), `$9C`/`$9D` (COLDATA Mirrors). + +## Outstanding Issues +- None related to BG Color Brightness. \ No newline at end of file diff --git a/Masks/mask_routines.asm b/Masks/mask_routines.asm index b5187f8..16f4eb4 100644 --- a/Masks/mask_routines.asm +++ b/Masks/mask_routines.asm @@ -191,7 +191,7 @@ Palette_ArmorAndGloves: ; ========================================================= ; Overworld Palette Persist -Overworld_CgramAuxToMain: +Oracle_CgramAuxToMain_Impl: { ; Copies the auxiliary CGRAM buffer to the main one ; Causes NMI to reupload the palette. @@ -213,14 +213,36 @@ Overworld_CgramAuxToMain: SEP #$20 + ; Fix BG color: Apply time tinting after aux->main copy + ; Only when outdoors ($1B = 0) + ; NOTE: Overworld_LoadPalettes does NOT load palette 0 (BG color), so aux buffer + ; at offset 0 contains garbage. Must load from Pool_BGColorTable instead. + LDA.b $1B : BNE .skip_bg_fix + + REP #$20 + ; Get area index and load BG color from Pool_BGColorTable ($288000) + LDA.b $8A : AND.w #$00FF : ASL : TAX + LDA.l $288000, X ; Pool_BGColorTable + BEQ .skip_bg_fix_16bit ; Skip if transparent ($0000) + STA.l TimeState.SubColor + JSL ColorSubEffect ; Apply time tinting, result in A + ; Write tinted color to all 4 BG color buffers + STA.l $7EC500 ; PalCgram500_HUD + STA.l $7EC300 ; PalBuf300_HUD + STA.l $7EC540 ; PalCgram540_BG + STA.l $7EC340 ; PalBuf340_BG + .skip_bg_fix_16bit + SEP #$20 + .skip_bg_fix + ; tell NMI to upload new CGRAM data INC $15 RTL } pushpc -org $02C769 ; Overworld_CgramAuxToMain - JSL Overworld_CgramAuxToMain +org $02C769 ; Hook vanilla Overworld_CopyPalettesToCache + JSL Oracle_CgramAuxToMain_Impl RTS pullpc diff --git a/Overworld/ZSCustomOverworld.asm b/Overworld/ZSCustomOverworld.asm index 1012315..540a7d7 100644 --- a/Overworld/ZSCustomOverworld.asm +++ b/Overworld/ZSCustomOverworld.asm @@ -2364,6 +2364,13 @@ Overworld_ReloadSubscreenOverlay_Interupt: CPX.b #$95 : BEQ .loadOverlay ; Sky CPX.b #$9C : BEQ .loadOverlay ; Lava CPX.b #$96 : BEQ .loadOverlay ; Pyramid BG + + ; Check for NO OVERLAY ($FF) + CPX.b #$FF : BNE .checkScroll + LDA.b #$00 ; Disable Color Math + BRA .loadOverlay + + .checkScroll ; TODO: Investigate what these checks are for. LDX.b $11 : CPX.b #$23 : BEQ .loadOverlay CPX.b #$2C : BEQ .loadOverlay @@ -3713,6 +3720,9 @@ Overworld_LoadBGColorAndSubscreenOverlay: SEP #$30 ; Set A, X, and Y in 8bit mode. + ; Clear color math control register to prevent brightness bug + STZ.b $9A + ; Don't set the subscreen during a warp to hide the transparent ; color change. This will get set properly later in the warp ; but not everywhere else. diff --git a/Sprites/Objects/minecart.asm b/Sprites/Objects/minecart.asm index a1274bc..7af9389 100644 --- a/Sprites/Objects/minecart.asm +++ b/Sprites/Objects/minecart.asm @@ -305,28 +305,7 @@ Sprite_Minecart_Prep: PLB RTL - ; This is which room each track should start in if it hasn't already - ; been given a track. - .TrackStartingRooms - dw $0098, $0088, $0087, $0088, $0089, $0089, $0089, $0089 - dw $0089, $0089, $0089, $0089, $0089, $0089, $0089, $0089 - dw $0089, $0089, $0089, $0089, $0089, $0089, $0089, $0089 - dw $0089, $0089, $0089, $0089, $0089, $0089, $0089, $0089 - - ; This is where within the room each track should start in if it hasn't - ; already been given a position. This is necessary to allow for more - ; than one stopping point to be in one room. - .TrackStartingX - dw $1190, $1160, $1300, $1100, $1300, $1300, $1300, $1300 - dw $1300, $1300, $1300, $1300, $1300, $1300, $1300, $1300 - dw $1300, $1300, $1300, $1300, $1300, $1300, $1300, $1300 - dw $1300, $1300, $1300, $1300, $1300, $1300, $1300, $1300 - - .TrackStartingY - dw $1380, $10C9, $1100, $10D0, $1100, $1100, $1100, $1100 - dw $1100, $1100, $1100, $1100, $1100, $1100, $1100, $1100 - dw $1100, $1100, $1100, $1100, $1100, $1100, $1100, $1100 - dw $1100, $1100, $1100, $1100, $1100, $1100, $1100, $1100 + incsrc "data/minecart_tracks.asm" } ; =========================================================