Fading colors

From NeoGeo Development Wiki
Revision as of 00:30, 3 March 2021 by Furrtek (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Palette fade

Real-time

Palettes can be faded to white or black by respectively incrementing or decrementing each color component of each color individually. Of course, care has to be taken so that each value stops at 31 or 0.

Fading to a specific color can also be done this way, by comparing each color components with the target ones and incrementing/decrementing them accordingly (see example code).

Pre-computed

Real time fading is very flexible but also very CPU intensive. Another way to fade palettes is to pre-compute all the steps and store them into ROM for simple lookup. This method requires very little CPU but uses more ROM space.

Simulated fade

Fix fade to white in Sengoku 3's intro
Fix wipe in Metal Slug 3

Since it has the highest priority on the screen, the fix layer can be used to fade the underlaying display by using dithered tiles as a mask. This can only be used if the fix doesn't have to show important information during fading.

This is also used in Metal Slug 3 for wiping transitions between levels sections.

Real-time fading code

NG2RGB:
;D3:NG Palette word -> D2:RGB555 word (ignores common bit)
    clr.l   d2
    ;Red
    move.w  d3,d0                ;DrvbRRRRVVVVBBBB
    andi.w  #$0F00,d0            ;____RRRR________
    lsl.w   #3,d0                ;_RRRR___________
    or.w    d0,d2
    move.w  d3,d0
    andi.w  #$4000,d0            ;_r______________
    lsr.w   #4,d0                ;_____r__________
    or.w    d0,d2                ;_RRRRr__________

    ;Green
    move.w  d3,d0                ;DrvbRRRRVVVVBBBB
    andi.w  #$00F0,d0            ;________VVVV____
    lsl.w   #2,d0                ;______VVVV______
    or.w    d0,d2                __RRRRrVVVV______
    move.w  d3,d0
    andi.w  #$2000,d0            ;__v_____________
    lsr.w   #8,d0                ;__________v_____
    or.w    d0,d2                ;_RRRRrVVVVv_____

    ;Blue
    move.w  d3,d0                ;DrvbRRRRVVVVBBBB
    andi.w  #$000F,d0            ;____________BBBB
    lsl.b   #1,d0                ;___________BBBB_
    or.w    d0,d2                ;_RRRRrVVVVvBBBB_
    move.w  d3,d0
    andi.w  #$1000,d0            ;___b____________
    rol.w   #4,d0                ;_______________b
    or.w    d0,d2                ;_RRRRrVVVVvBBBBb
    rts
RGB2NG:
;D4:RGB555 word -> D2:NG Palette word (ignores common bit)
    clr.l   d2
    ;Red
    move.w  d4,d0                ;_RRRRrVVVVvBBBBb
    andi.w  #$7800,d0            ;_RRRR___________
    lsr.w   #3,d0                ;____RRRR________
    or.w    d0,d2                ;____RRRR________
    move.w  d4,d0
    andi.w  #$0400,d0            ;_____r__________
    lsl.w   #4,d0                ;_r______________
    or.w    d0,d2                ;_r__RRRR________

    ;Green
    move.w  d4,d0
    move.w  d4,d1                ;_RRRRrVVVVvBBBBb
    andi.w  #$03C0,d0            ;______VVVV______
    lsr.w   #2,d0                ;________VVVV____
    or.w    d0,d2                ;_r__RRRRVVVV____
    move.w  d4,d0
    andi.w  #$0020,d0            ;__________v_____
    lsl.w   #8,d0                ;__v_____________
    or.w    d0,d2                ;_rv_RRRRVVVV____

    ;Blue
    move.w  d4,d0
    move.w  d4,d1                ;_RRRRrVVVVvBBBBb
    andi.w  #$001E,d0            ;___________BBBB_
    lsr.b   #1,d0                ;____________BBBB
    or.w    d0,d2                ;_rv_RRRRVVVVBBBB
    move.w  d4,d0
    andi.w  #$0001,d0            ;_______________b
    ror.w   #4,d0                ;___b____________
    or.w    d0,d2                ;_rvbRRRRVVVVBBBB
    rts

RGB components can then be compared with a target palette in RAM and adjusted until they match, for example:

;Compares 555 RGB red in D0 with D1
    andi.w  #$7C00,d0
    andi.w  #$7C00,d1
    cmp.w   d1,d0
    blo     .lower
    bhi     .higher
    bra     .same
.lower:
    addi.w  #$0400,d4
    bra     .same
.higher:
    subi.w  #$0400,d4
.same: