gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Can use help with fading routine

#83504 - Roembout - Tue May 16, 2006 6:23 pm

Hi there,

I'm trying out some stuff to fade in/out the palette of a tiled background. I found this routine on this forum:

Code:
int readX, step;
float red, green, blue;
u16 sourceColor, targetColor;
targetColor = WHITE;
int fadeSteps = 30;

for( step = 0; step <= fadeSteps; step++ )
{
  swiWaitForVBlank( );

  for( readX = 0; readX < 256; readX++ )
  {
    sourceColor = BG_PALETTE_SUB[readX];

    red =   ( ( REDVALUE  ( sourceColor ) * ( fadeSteps - step ) ) + ( REDVALUE  ( targetColor ) * step ) ) / fadeSteps;
    green = ( ( GREENVALUE( sourceColor ) * ( fadeSteps - step ) ) + ( GREENVALUE( targetColor ) * step ) ) / fadeSteps;
    blue =  ( ( BLUEVALUE ( sourceColor ) * ( fadeSteps - step ) ) + ( BLUEVALUE ( targetColor ) * step ) ) / fadeSteps;

    BG_PALETTE_SUB[readX] = RGB( (int)red , (int)green , (int)blue );
  }
}


It works fine for fading out to white, but I can't get it to work for fading in from white.

Anybody knows how I can get it to work?

Thx, in advance.[/code]


Last edited by Roembout on Tue May 16, 2006 6:33 pm; edited 2 times in total

#83507 - ProblemBaby - Tue May 16, 2006 6:28 pm

you have to set targetcolor for each palette entry.

to make the routine faster and probably the actual fade a bit smoothier change fadeSteps to 32

#83512 - Roembout - Tue May 16, 2006 6:38 pm

ProblemBaby wrote:
you have to set targetcolor for each palette entry.

to make the routine faster and probably the actual fade a bit smoothier change fadeSteps to 32


Got my fade-in routine now like this:

Code:
dmaCopy( menu_img_bin, (u16*)CHAR_BASE_BLOCK_SUB(0), menu_img_bin_size );
dmaCopy( menu_map_bin, (u16*)SCREEN_BASE_BLOCK_SUB(4), menu_map_bin_size );

fadeSteps = 32;
sourceColor = WHITE;

for( step = 0; step <= fadeSteps; step++ )
{
  swiWaitForVBlank( );

  for( readX = 0; readX < 256; readX++ )
  {
    targetColor = menu_pal_bin[readX];
 
    red =   ( ( REDVALUE  ( sourceColor ) * ( fadeSteps - step ) ) + ( REDVALUE  ( targetColor ) * step ) ) / fadeSteps;
    green = ( ( GREENVALUE( sourceColor ) * ( fadeSteps - step ) ) + ( GREENVALUE( targetColor ) * step ) ) / fadeSteps;
    blue =  ( ( BLUEVALUE ( sourceColor ) * ( fadeSteps - step ) ) + ( BLUEVALUE ( targetColor ) * step ) ) / fadeSteps;

    BG_PALETTE_SUB[readX] = RGB( (int)red , (int)green , (int)blue );
  }
}


but still getting a weird result; is starts ok but it fades towards red now in stead of white, like my palette is screwup or something which it aint'.

Changes the fadesteps to 32, it's a bit smoother yes.

#83518 - waruwaru - Tue May 16, 2006 7:20 pm

Roembout wrote:
but still getting a weird result; is starts ok but it fades towards red now in stead of white, like my palette is screwup or something which it aint'.


How about:
Code:

red   = REDVALUE( sourceColor ) - ( ( REDVALUE( sourceColor ) - REDVALUE( targetColor ) ) * 1.0 * step / fadesteps );
green = GREENVALUE( sourceColor ) - ( ( GREENVALUE( sourceColor ) - GREENVALUE( targetColor ) ) * 1.0 * step / fadesteps );
blue  = BLUEVALUE( sourceColor ) - ( ( BLUEVALUE( sourceColor ) - BLUEVALUE( targetColor ) ) * 1.0 * step / fadesteps );

_________________
DSLua - a scripting language for your DS!

#83519 - Mighty Max - Tue May 16, 2006 7:21 pm

Code:

red =   ( ( REDVALUE  ( sourceColor ) * ( fadeSteps - step ) ) + ( REDVALUE  ( targetColor ) * step ) ) / fadeSteps;


- keep in mind that even tho red is float, the conversation to float is only done _after_ the calculation was done. Your float definition therefor does not increase the accuracy, you could have just left it an int if you don't do the calcs in float (explicit cast)

-you are in each step using the values from the last step. as this influenzes the amount of change in each step, this change might be greater then the actual linear factor included in (fadeSteps - step) / fadeSteps. Your value could in the worst case increase instead of decrease to the target. You can change that by basing your interpolation on the start & endpoint instead of current & endpoint.
_________________
GBAMP Multiboot

#83520 - ProblemBaby - Tue May 16, 2006 7:38 pm

Yaeh, something like this would be better, I think

Code:

u32 fadeSteps = 32;
u32 sourceColor = 0x7FFF;
u32 red, green, blue;
s32 dr, dg, db;

dr = ((REDVALUE(targetColor) - REDVALUE(sourceColor)) << 8) / fadeSteps
dg = etc
db = etc

red = REDVALUE(sourceColor) + ((dr * step) >> 8);
green = etc
blue = etc

#83522 - Roembout - Tue May 16, 2006 7:47 pm

Thx for the replies. I'm gonna try out your suggentions.

#83610 - Roembout - Wed May 17, 2006 10:22 am

This is stuff is tough getting it to work correctly. I came across defines as BLEND_ALPHA and BLEND_FADE_WHITE in video.h. Can I get the same result with this and if I can how do I have to implement it?

#83635 - wintermute - Wed May 17, 2006 3:13 pm

The blend registers won't give you such fine control over the fade - there are only 16 steps.


There is code in libgba which does what you're trying to do which should work on DS with minor modifications.

http://devkitpro.cvs.sourceforge.net/devkitpro/libgba/src/fade.c?revision=1.4&view=markup
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog