Fix: Resolve BG color brightness regression, persist Time System tint, and refactor Minecart data
This commit is contained in:
48
Docs/Issues/BGColor_Overlay_RootCause.md
Normal file
48
Docs/Issues/BGColor_Overlay_RootCause.md
Normal file
@@ -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.
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
; =========================================================
|
||||
|
||||
Reference in New Issue
Block a user