Skip to content

Instantly share code, notes, and snippets.

@ISSOtm
Created April 24, 2019 20:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ISSOtm/9d0bbad8e4987be15ea9ef26e9afeee4 to your computer and use it in GitHub Desktop.
Save ISSOtm/9d0bbad8e4987be15ea9ef26e9afeee4 to your computer and use it in GitHub Desktop.
Fade-in and fade-out code for Game Boy, for any palette. Run this every frame.
.fadeIn
ld a, [wCurStateFirstFrame]
and a
jr z, .notFirstFrame
; Assume palettes are properly set (ie. we're fading from the proper solid colors)
; Perform first fade immediately
ld a, 1
ld [wFadeFrames], a
; This is the value that will get added to each color
; It'll be decremented just below
ld a, 4
ld [wFadeStep], a
.notFirstFrame
ld hl, wFadeFrames
dec [hl]
ret nz
ld a, [wFadeDelay]
ld [hli], a
; ld hl, wFadeStep
ld a, [hl]
dec a
ld [hli], a
ld e, a
; Unlike for fading in, we can't proceed incrementally
; Getting closer to the desired value and capping isn't symmetrical to the fade-in, which looks better (closer to actual alpha blending a solid color)
; Thus we will add a fixed value to the palette
ld c, LOW(hBGP)
; ld hl, wFadePalettes
.fadePalette
ld a, [hli] ; Target palette, which we'll modify
push hl
ld b, 4
.fadeColor
ld d, a
ld a, [wFadeType]
and a
ld a, d
; Modify current color
jr nz, .fromBlack
and 3
sub e
jr nc, .noCap
xor a
jr .noCap
.fromBlack
and 3
add a, e
cp 4
jr c, .noCap
ld a, 3
.noCap
; Mix back the rest of the palette without an extra reg
xor d ; Reversibly mix the two lower bits of the palette
and 3 ; Trash all others
xor d ; Get upper bits as normal, and cancel lower two bits
; Rotate the colors to get the next one
rlca
rlca
dec b
jr nz, .fadeColor
ld [$ff00+c], a
pop hl
ld a, c
inc c
cp LOW(hOBP1)
jr nz, .fadePalette
; Check if palettes have been faded out fully
ld a, [wFadeStep]
and a
ret nz
ld a, [wFollowingState]
ld [wNextState], a
ret
.fadeOut
ld a, [wCurStateFirstFrame]
and a
jr z, .notFirstFrame
; Save palettes for corresponding fade-in
ld hl, wFadePalettes
lb bc, 3, LOW(hBGP)
.copyPalettes
ld a, [$ff00+c]
inc c
ld [hli], a
dec b
jr nz, .copyPalettes
; Perform first fade immediately
ld a, 1
ld [wFadeFrames], a
.notFirstFrame
ld hl, wFadeFrames
dec [hl]
ret nz
ld a, [wFadeDelay]
ld [hli], a
; When fading out, it's possible to proceed incrementally:
; We need to apply an "alpha" layer, that is, subtract (or add) to every color
; But we can do that incrementally!
ld a, [wFadeType]
and a
jr z, .toWhite
ld a, $FF
.toWhite
ld l, a ; Value of a successfully faded palette
lb bc, 3 + 1, LOW(hBGP) ; Number of palettes successfully faded, pointer to current palette
.fadeOnePalette
ld a, [$ff00+c] ; Current palette
ld h, 4 ; Number of colors that need fading
.fadeOneColor
ld e, a
and $FC
ld d, a ; Other colors in the palette
ld a, [wFadeType]
and a
ld a, e
jr nz, .toBlack
and $03
jr z, .colorDone
dec a
jr .colorDone
.toBlack
and $03
cp 3
jr z, .colorDone
inc a
.colorDone
or d
rlca
rlca
dec h
jr nz, .fadeOneColor
; a = Current palette value
cp l
jr nz, .paletteNotFinished
dec b
.paletteNotFinished
ld [$ff00+c], a
ld a, c
inc c
cp LOW(hOBP1)
jr nz, .fadeOnePalette
dec b
ret nz
ld a, [wFollowingState]
ld [wNextState], a
ret
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment