Fading colors: Difference between revisions

From NeoGeo Development Wiki
Jump to navigation Jump to search
mNo edit summary
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
== Palette fades ==
=Palette fade=


==Real-time==
[[Palettes]] can be faded to white or black by respectively incrementing or decrementing each color component of each color individually.
[[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 $1F or 0.
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 actual components to the target ones and incrementing/decrementing them accordingly (see example code).
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).


== Simulated fades ==
==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=


[[File:Sengoku3fade.png|frame|Fix fade to white in [[Sengoku 3]]'s intro]]
[[File:Sengoku3fade.png|frame|Fix fade to white in [[Sengoku 3]]'s intro]]
Line 12: Line 16:
[[File:0003.png|frame|Fix wipe in Metal Slug 3]]
[[File:0003.png|frame|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 pre-dithered tiles.
Since it has the highest priority on the screen, the [[fix layer]] can be used as a mask to fade the underlaying display by using dithered tiles.
This can only be used if the fix doesn't have to show important information.
This can only be done if the fix doesn't have to show important information during fading.
 
This is also used in [[Metal Slug 3]] as transitions between levels sections.
 
This method is quite popular, as fading the full 256 palettes range of the system can be quite CPU intensive, plus vBlank is too short to rewrite all palettes anyway.


== Color handling code ==
[[Metal Slug 3]] clears the HUD then does this for wiping transitions between level sections.


If not using pre-calculated palette tables for fades, each color component of each color needs to be modified.
=Real-time fading code=


<syntaxhighlight>
<syntaxhighlight>
; D0.w: NG palette word -> D2.b, D3.b, D4.b: RGB555 (ignores common bit)
NG2RGB:
NG2RGB:
;D3:NG Palette word -> D2:RGB555 word (ignores common bit)
    clr.l  d2
     ;Red
     ;Red
     move.w  d3,d0               ;DrvbRRRRVVVVBBBB
     move.w  d0,d2               ;CrgbRRRRGGGGBBBB
     andi.w  #$0F00,d0            ;____RRRR________
     lsr.w  #8,d2               ;________CrgbRRRR
    lsl.w  #3,d0               ;_RRRR___________
     andi.b  #$0F,d2             ;____________RRRR
     or.w    d0,d2
     move.w  d0,d1                ;CrgbRRRRGGGGBBBB
     move.w  d3,d0
     lsl.w  #2,d1               ;gbRRRRGGGGBBBBCr
    andi.w  #$4000,d0            ;_r______________
     asl.b  #1,d2                ;___________RRRRr
     lsr.w  #4,d0               ;_____r__________
     or.w    d0,d2                ;_RRRRr__________


     ;Green
     ;Green
     move.w d3,d0               ;DrvbRRRRVVVVBBBB
     move.b d0,d3                ;________GGGGBBBB
     andi.#$00F0,d0            ;________VVVV____
     lsr.#4,d3                ;____________GGGG
     lsl.w  #2,d0               ;______VVVV______
     lsl.w  #1,d1               ;bRRRRGGGGBBBBCrg
     or.w    d0,d2                __RRRRrVVVV______
     asl.b   #1,d3               ;___________GGGGg
    move.w  d3,d0
    andi.w  #$2000,d0            ;__v_____________
    lsr.w   #8,d0                ;__________v_____
    or.w    d0,d2               ;_RRRRrVVVVv_____


     ;Blue
     ;Blue
     move.w d3,d0               ;DrvbRRRRVVVVBBBB
     move.b d0,d4               ;________GGGGBBBB
     andi.w #$000F,d0            ;____________BBBB
     andi.b #$0F,d4              ;____________BBBB
     lsl.b   #1,d0               ;___________BBBB_
     lsl.w   #1,d1               ;RRRRGGGGBBBBCrgb
     or.w    d0,d2                ;_RRRRrVVVVvBBBB_
     asl.b   #1,d4               ;___________BBBBb
    move.w  d3,d0
    andi.w  #$1000,d0            ;___b____________
    rol.w   #4,d0                ;_______________b
    or.w    d0,d2               ;_RRRRrVVVVvBBBBb
     rts
     rts
</syntaxhighlight>
</syntaxhighlight>


<syntaxhighlight>
<syntaxhighlight>
; D2.b, D3.b, D4.b: RGB555 -> D0.w: NG palette word (ignores common bit)
RGB2NG:
RGB2NG:
;D4:RGB555 word -> D2:NG Palette word (ignores common bit)
     moveq.l #0,d0
     clr.l   d2
     lsr.b   #1,d2                ;____________RRRR
    ;Red
     asl.#1,d0               ;_______________r
    move.w  d4,d0                ;_RRRRrVVVVvBBBBb
     lsr.b   #1,d3               ;____________GGGG
    andi.w  #$7800,d0           ;_RRRR___________
     asl.b  #1,d0                ;______________rg
     lsr.w   #3,d0                ;____RRRR________
     lsr.b   #1,d4               ;____________BBBB
    or.w    d0,d2                ;____RRRR________
     asl.b   #1,d0                ;_____________rgb
     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
     lsl.b  #4,d0                ;_________rgb____
    move.w  d4,d0
     or.b    d2,d0               ;_________rgbRRRR
    move.w  d4,d1               ;_RRRRrVVVVvBBBBb
     lsl.w   #4,d0                ;_____rgbRRRR____
     andi.w  #$001E,d0           ;___________BBBB_
     or.b   d3,d0                ;_____rgbRRRRGGGG
     lsr.b   #1,d0                ;____________BBBB
     lsl.w  #4,d0                ;_rgbRRRRGGGG____
     or.w   d0,d2               ;_rv_RRRRVVVVBBBB
     or.b   d4,d0                ;_rgbRRRRGGGGBBBB
     move.w  d4,d0
    andi.w  #$0001,d0            ;_______________b
    ror.w  #4,d0                ;___b____________
     or.w   d0,d2               ;_rvbRRRRVVVVBBBB
     rts
     rts
</syntaxhighlight>
</syntaxhighlight>
Line 100: Line 71:


<syntaxhighlight>
<syntaxhighlight>
;Compares 555 RGB red in D0 with D1
; Compares red in D0 with D2, inc/dec depending on result
    andi.w  #$7C00,d0
     cmp.b   d2,d0
    andi.w  #$7C00,d1
     cmp.w   d1,d0
     blo    .lower
     blo    .lower
     bhi    .higher
     bhi    .higher
     bra    .same
     bra    .same
.lower:
.lower:
     addi.w #$0400,d4
     addq.b #1,d0
     bra    .same
     bra    .same
.higher:
.higher:
     subi.w #$0400,d4
     subq.b #1,d0
.same:
.same:
</syntaxhighlight>
</syntaxhighlight>
Note that with such a constant increment/decrement value, some components will reach their target before others. Doing a correct proportional fade would involve fixed point math, which probably isn't worth the trouble.


[[Category:Code]]
[[Category:Code]]
[[Category:Graphics Code]]
[[Category:Graphics Code]]

Latest revision as of 05:02, 26 September 2023

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

File:Sengoku3fade.png
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 as a mask to fade the underlaying display by using dithered tiles. This can only be done if the fix doesn't have to show important information during fading.

Metal Slug 3 clears the HUD then does this for wiping transitions between level sections.

Real-time fading code

; D0.w: NG palette word -> D2.b, D3.b, D4.b: RGB555 (ignores common bit)
NG2RGB:
    ;Red
    move.w  d0,d2                ;CrgbRRRRGGGGBBBB
    lsr.w   #8,d2                ;________CrgbRRRR
    andi.b  #$0F,d2              ;____________RRRR
    move.w  d0,d1                ;CrgbRRRRGGGGBBBB
    lsl.w   #2,d1                ;gbRRRRGGGGBBBBCr
    asl.b   #1,d2                ;___________RRRRr

    ;Green
    move.b  d0,d3                ;________GGGGBBBB
    lsr.b   #4,d3                ;____________GGGG
    lsl.w   #1,d1                ;bRRRRGGGGBBBBCrg
    asl.b   #1,d3                ;___________GGGGg

    ;Blue
    move.b  d0,d4                ;________GGGGBBBB
    andi.b  #$0F,d4              ;____________BBBB
    lsl.w   #1,d1                ;RRRRGGGGBBBBCrgb
    asl.b   #1,d4                ;___________BBBBb
    rts
; D2.b, D3.b, D4.b: RGB555 -> D0.w: NG palette word (ignores common bit)
RGB2NG:
    moveq.l #0,d0
    lsr.b   #1,d2                ;____________RRRR
    asl.b   #1,d0                ;_______________r
    lsr.b   #1,d3                ;____________GGGG
    asl.b   #1,d0                ;______________rg
    lsr.b   #1,d4                ;____________BBBB
    asl.b   #1,d0                ;_____________rgb

    lsl.b   #4,d0                ;_________rgb____
    or.b    d2,d0                ;_________rgbRRRR
    lsl.w   #4,d0                ;_____rgbRRRR____
    or.b    d3,d0                ;_____rgbRRRRGGGG
    lsl.w   #4,d0                ;_rgbRRRRGGGG____
    or.b    d4,d0                ;_rgbRRRRGGGGBBBB
    rts

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

; Compares red in D0 with D2, inc/dec depending on result
    cmp.b   d2,d0
    blo     .lower
    bhi     .higher
    bra     .same
.lower:
    addq.b  #1,d0
    bra     .same
.higher:
    subq.b  #1,d0
.same:

Note that with such a constant increment/decrement value, some components will reach their target before others. Doing a correct proportional fade would involve fixed point math, which probably isn't worth the trouble.