Fading the screen out and in again can be a nice effect when you want to make the transition from one screen to the next a little bit smoother.

On the SMS the color values of each of the 32 palette entries are stored in a single byte in the format %00bbggrr, where b is blue, g is green and r is red. As you can see, each of the channels can have a value of 0, 1, 2, or 3. Since you don't want to mess with the actual palette, manipulating the data before writing it to CRAM seems like a good idea.

This example expects a copy of the palette in RAM at the label PaletteBuffer for easy access, but that is not really necessary. You can substitute a valid address in ROM where palette data is stored instead.

Note that the code below does not really generate a proper fade. In the first step of the fade-out (and the second of the fade-in), all color values of 2 remain unchanged, only the 3s and the 1s are manipulated. Usually, the fading happens too quickly to notice, though.

Contributed by Kagesan, last edited 2014/06/25 by Kagesan

;=================================================================================
; Quick palette fade
;=================================================================================

.section "Quick fade" free

FadeInScreen:

    halt                   ; wait for Vblank

    xor a
    out ($bf),a            ; palette index (0)
    ld a,$c0
    out ($bf),a            ; palette write identifier

    ld b,32                ; number of palette entries: 32 (full palette)
    ld hl,PaletteBuffer    ; source
 -: ld a,(hl)              ; load raw palette data
    and %00101010          ; modify color values: 3 becomes 2, 1 becomes 0
    srl a                  ; modify color values: 2 becomes 1
    out ($be),a            ; write modified data to CRAM
    inc hl
    djnz -

    ld b,4                 ; delay 4 frames
 -: halt
    djnz -

    ld b,32                ; number of palette entries: 32 (full palette)
    ld hl,PaletteBuffer    ; source
 -: ld a,(hl)              ; load raw palette data
    and %00101010          ; modify color values: 3 becomes 2, 1 becomes 0
    out ($be),a            ; write modified data to CRAM
    inc hl
    djnz -

    ld b,4                 ; delay 4 frames
 -: halt
    djnz -

    ld b,32                ; number of palette entries: 32 (full palette)
    ld hl,PaletteBuffer    ; source
 -: ld a,(hl)              ; load raw palette data
    out ($be),a            ; write unfodified data to CRAM, palette load complete
    inc hl
    djnz -

ret

;---------------------------------------------------------------------------------

FadeOutScreen:

    halt                   ; wait for Vblank

    xor a
    out ($bf),a            ; palette index (0)
    ld a,$c0
    out ($bf),a            ; palette write identifier

    ld b,32                ; number of palette entries: 32 (full palette)
    ld hl,PaletteBuffer    ; source
 -: ld a,(hl)              ; load raw palette data
    and %00101010          ; modify color values: 3 becomes 2, 1 becomes 0
    out ($be),a            ; write modified data to CRAM
    inc hl
    djnz -

    ld b,4                 ; delay 4 frames
 -: halt
    djnz -

    ld b,32                ; number of palette entries: 32 (full palette)
    ld hl,PaletteBuffer    ; source
 -: ld a,(hl)              ; load raw palette data
    and %00101010          ; modify color values: 3 becomes 2, 1 becomes 0
    srl a                  ; modify color values: 2 becomes 1
    out ($be),a            ; write modified data to CRAM
    inc hl
    djnz -

    ld b,4                 ; delay 4 frames
 -: halt
    djnz -

    ld b, 32               ; number of palette entries: 32 (full palette)
    xor a                  ; we want to blacken the palette, so a is set to 0
 -: out ($be), a           ; write zeros to CRAM, palette fade complete
    djnz -

ret

.ends



Return to top
0.17s