Fading colors: Difference between revisions
mNo edit summary |
|||
(4 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
=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 | 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 | 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 | ==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 | 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 | 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= | |||
<syntaxhighlight> | <syntaxhighlight> | ||
; D0.w: NG palette word -> D2.b, D3.b, D4.b: RGB555 (ignores common bit) | |||
NG2RGB: | NG2RGB: | ||
;Red | ;Red | ||
move.w | move.w d0,d2 ;CrgbRRRRGGGGBBBB | ||
lsr.w #8,d2 ;________CrgbRRRR | |||
andi.b #$0F,d2 ;____________RRRR | |||
move.w d0,d1 ;CrgbRRRRGGGGBBBB | |||
move.w | lsl.w #2,d1 ;gbRRRRGGGGBBBBCr | ||
asl.b #1,d2 ;___________RRRRr | |||
;Green | ;Green | ||
move. | move.b d0,d3 ;________GGGGBBBB | ||
lsr.b #4,d3 ;____________GGGG | |||
lsl.w # | lsl.w #1,d1 ;bRRRRGGGGBBBBCrg | ||
asl.b #1,d3 ;___________GGGGg | |||
;Blue | ;Blue | ||
move. | move.b d0,d4 ;________GGGGBBBB | ||
andi. | andi.b #$0F,d4 ;____________BBBB | ||
lsl. | lsl.w #1,d1 ;RRRRGGGGBBBBCrgb | ||
asl.b #1,d4 ;___________BBBBb | |||
rts | rts | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<syntaxhighlight> | <syntaxhighlight> | ||
; D2.b, D3.b, D4.b: RGB555 -> D0.w: NG palette word (ignores common bit) | |||
RGB2NG: | 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. | or.b d4,d0 ;_rgbRRRRGGGGBBBB | ||
lsl.w # | |||
or. | |||
or. | |||
rts | rts | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 98: | Line 71: | ||
<syntaxhighlight> | <syntaxhighlight> | ||
;Compares | ; Compares red in D0 with D2, inc/dec depending on result | ||
cmp.b d2,d0 | |||
cmp. | |||
blo .lower | blo .lower | ||
bhi .higher | bhi .higher | ||
bra .same | bra .same | ||
.lower: | .lower: | ||
addq.b #1,d0 | |||
bra .same | bra .same | ||
.higher: | .higher: | ||
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]] |
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
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.