I would like to share a C function I have written lately for "fading out" and "fading in" graphics by reducing or increasing the RGB63 values of the respective color palettes step by step.
With the current code you can fade the colors to black but with some adjustments of the "steps" you could also fade them to white or fade them incomplete to have a "dimmed graphic" effect.
Also, you could adjust the fade speed by editing the "steps" value (default is 4). The functions have affect on the first 16 color palettes only (due to RAM limitations) but you could adjust the start
position by editing the "palette_no" variable (for instance a value of 40 would fade all graphics with palette from 40 to 56).
Here is an example how it looks:
And here is the code:
fade_palettes.h
struct palette_t
{
int original_color, new_color;
int index, red, green, blue, index_temp, red_temp, green_temp, blue_temp;
int RGB63_red, RGB63_green, RGB63_blue, RGB63_red_index, RGB63_green_index, RGB63_blue_index;
int RGB63_red_temp, RGB63_green_temp, RGB63_blue_temp, RGB63_red_index_temp, RGB63_green_index_temp, RGB63_blue_index_temp;
};
extern struct palette_t color[256];
void fade_out();
void prepare_fade_in();
void fade_in();
fade_palettes.c
struct palette_t color[256];
// FADE OUT //////////////////////////////////////////////////////////////////
void fade_out()
{
int palette_no = 0; // first palette to start with
int i;
int steps=0;
waitVBlank();
for(i=0; i<256; i++)
{
// save original palettes and calculate hex values for index bits and each color //
color[i].original_color = volMEMWORD(4194304+(i*2)+(palette_no*32)); // 4194304 decimal = 0x400000 hex adress of color 0 of palette 0
color[i].blue=color[i].original_color/16; // quotient
color[i].green=color[i].blue/16; // quotient
color[i].red=color[i].green/16; // quotient
color[i].index=color[i].red/16; // quotient
color[i].index=color[i].red%16; // remainder
color[i].red=color[i].green%16; // remainder
color[i].green=color[i].blue%16; // remainder
color[i].blue=color[i].original_color%16; // remainder
// convert to RGB63 ///////////////////////////////////////////////
if(color[i].index==0) {color[i].RGB63_red_index=1; color[i].RGB63_green_index=1; color[i].RGB63_blue_index=1;}
if(color[i].index==1) {color[i].RGB63_red_index=1; color[i].RGB63_green_index=1; color[i].RGB63_blue_index=3;}
if(color[i].index==2) {color[i].RGB63_red_index=1; color[i].RGB63_green_index=3; color[i].RGB63_blue_index=1;}
if(color[i].index==3) {color[i].RGB63_red_index=1; color[i].RGB63_green_index=3; color[i].RGB63_blue_index=3;}
if(color[i].index==4) {color[i].RGB63_red_index=3; color[i].RGB63_green_index=1; color[i].RGB63_blue_index=1;}
if(color[i].index==5) {color[i].RGB63_red_index=3; color[i].RGB63_green_index=1; color[i].RGB63_blue_index=3;}
if(color[i].index==6) {color[i].RGB63_red_index=3; color[i].RGB63_green_index=3; color[i].RGB63_blue_index=1;}
if(color[i].index==7) {color[i].RGB63_red_index=3; color[i].RGB63_green_index=3; color[i].RGB63_blue_index=3;}
if(color[i].index==8) {color[i].RGB63_red_index=0; color[i].RGB63_green_index=0; color[i].RGB63_blue_index=0;}
if(color[i].index==9) {color[i].RGB63_red_index=0; color[i].RGB63_green_index=0; color[i].RGB63_blue_index=2;}
if(color[i].index==10){color[i].RGB63_red_index=0; color[i].RGB63_green_index=2; color[i].RGB63_blue_index=0;}
if(color[i].index==11){color[i].RGB63_red_index=0; color[i].RGB63_green_index=2; color[i].RGB63_blue_index=2;}
if(color[i].index==12){color[i].RGB63_red_index=2; color[i].RGB63_green_index=0; color[i].RGB63_blue_index=0;}
if(color[i].index==13){color[i].RGB63_red_index=2; color[i].RGB63_green_index=0; color[i].RGB63_blue_index=2;}
if(color[i].index==14){color[i].RGB63_red_index=2; color[i].RGB63_green_index=2; color[i].RGB63_blue_index=0;}
if(color[i].index==15){color[i].RGB63_red_index=2; color[i].RGB63_green_index=2; color[i].RGB63_blue_index=2;}
color[i].RGB63_red = color[i].red * 4 + color[i].RGB63_red_index;
color[i].RGB63_green = color[i].green * 4 + color[i].RGB63_green_index;
color[i].RGB63_blue = color[i].blue * 4 + color[i].RGB63_blue_index;
// copy ASM Hex Color Code values to temporary variables ///////////
color[i].index_temp = color[i].index;
color[i].red_temp = color[i].red;
color[i].green_temp = color[i].green;
color[i].blue_temp = color[i].blue;
}
while(1)
{
waitVBlank();
steps-=4;
for(i=0; i<256; i++)
{
// add steps to RGB63 temporary values /////////////////////////
color[i].RGB63_red_temp = color[i].RGB63_red + steps;
color[i].RGB63_green_temp = color[i].RGB63_green + steps;
color[i].RGB63_blue_temp = color[i].RGB63_blue + steps;
// keep values inside the range of 0 to 63 /////////////////////
if(color[i].RGB63_red_temp>63) color[i].RGB63_red_temp=63;
if(color[i].RGB63_red_temp<0) color[i].RGB63_red_temp=0;
if(color[i].RGB63_green_temp>63) color[i].RGB63_green_temp=63;
if(color[i].RGB63_green_temp<0) color[i].RGB63_green_temp=0;
if(color[i].RGB63_blue_temp>63) color[i].RGB63_blue_temp=63;
if(color[i].RGB63_blue_temp<0) color[i].RGB63_blue_temp=0;
// convert RGB63 back to ASM Hex Color Code ////////////////////
color[i].RGB63_red_index_temp = color[i].RGB63_red_temp%4;
color[i].red_temp = color[i].RGB63_red_temp/4;
color[i].RGB63_green_index_temp = color[i].RGB63_green_temp%4;
color[i].green_temp = color[i].RGB63_green_temp/4;
color[i].RGB63_blue_index_temp = color[i].RGB63_blue_temp%4;
color[i].blue_temp = color[i].RGB63_blue_temp/4;
if(color[i].RGB63_red_index_temp==1 && color[i].RGB63_green_index_temp==1 && color[i].RGB63_blue_index_temp==1) color[i].index_temp=0;
if(color[i].RGB63_red_index_temp==1 && color[i].RGB63_green_index_temp==1 && color[i].RGB63_blue_index_temp==3) color[i].index_temp=1;
if(color[i].RGB63_red_index_temp==1 && color[i].RGB63_green_index_temp==3 && color[i].RGB63_blue_index_temp==1) color[i].index_temp=2;
if(color[i].RGB63_red_index_temp==1 && color[i].RGB63_green_index_temp==3 && color[i].RGB63_blue_index_temp==3) color[i].index_temp=3;
if(color[i].RGB63_red_index_temp==3 && color[i].RGB63_green_index_temp==1 && color[i].RGB63_blue_index_temp==1) color[i].index_temp=4;
if(color[i].RGB63_red_index_temp==3 && color[i].RGB63_green_index_temp==1 && color[i].RGB63_blue_index_temp==3) color[i].index_temp=5;
if(color[i].RGB63_red_index_temp==3 && color[i].RGB63_green_index_temp==3 && color[i].RGB63_blue_index_temp==1) color[i].index_temp=6;
if(color[i].RGB63_red_index_temp==3 && color[i].RGB63_green_index_temp==3 && color[i].RGB63_blue_index_temp==3) color[i].index_temp=7;
if(color[i].RGB63_red_index_temp==0 && color[i].RGB63_green_index_temp==0 && color[i].RGB63_blue_index_temp==0) color[i].index_temp=8;
if(color[i].RGB63_red_index_temp==0 && color[i].RGB63_green_index_temp==0 && color[i].RGB63_blue_index_temp==2) color[i].index_temp=9;
if(color[i].RGB63_red_index_temp==0 && color[i].RGB63_green_index_temp==2 && color[i].RGB63_blue_index_temp==0) color[i].index_temp=10;
if(color[i].RGB63_red_index_temp==0 && color[i].RGB63_green_index_temp==2 && color[i].RGB63_blue_index_temp==2) color[i].index_temp=11;
if(color[i].RGB63_red_index_temp==2 && color[i].RGB63_green_index_temp==0 && color[i].RGB63_blue_index_temp==0) color[i].index_temp=12;
if(color[i].RGB63_red_index_temp==2 && color[i].RGB63_green_index_temp==0 && color[i].RGB63_blue_index_temp==2) color[i].index_temp=13;
if(color[i].RGB63_red_index_temp==2 && color[i].RGB63_green_index_temp==2 && color[i].RGB63_blue_index_temp==0) color[i].index_temp=14;
if(color[i].RGB63_red_index_temp==2 && color[i].RGB63_green_index_temp==2 && color[i].RGB63_blue_index_temp==2) color[i].index_temp=15;
// write new ASM Hex Color Code to color adress ////////////////
color[i].new_color=(color[i].index_temp)*4096+(color[i].red_temp)*256+(color[i].green_temp)*16+(color[i].blue_temp);
volMEMWORD(4194304+(i*2)+(palette_no*32)) = color[i].new_color;
}
if(steps<=-64) break; // exit loop when done
}
}
// FADE IN //////////////////////////////////////////////////////////////////
void prepare_fade_in()
{
int palette_no = 0; // first palette to start with
int i;
int steps=-64;
waitVBlank();
for(i=0; i<256; i++)
{
// save original palettes and calculate hex values for index bits and each color //
color[i].original_color = volMEMWORD(4194304+(i*2)+(palette_no*32)); // 4194304 decimal = 0x400000 hex adress of color 0 of palette 0
color[i].blue=color[i].original_color/16; // quotient
color[i].green=color[i].blue/16; // quotient
color[i].red=color[i].green/16; // quotient
color[i].index=color[i].red/16; // quotient
color[i].index=color[i].red%16; // remainder
color[i].red=color[i].green%16; // remainder
color[i].green=color[i].blue%16; // remainder
color[i].blue=color[i].original_color%16; // remainder
// convert to RGB 63 ////////////////////////////////////////////////////
if(color[i].index==0) {color[i].RGB63_red_index=1; color[i].RGB63_green_index=1; color[i].RGB63_blue_index=1;}
if(color[i].index==1) {color[i].RGB63_red_index=1; color[i].RGB63_green_index=1; color[i].RGB63_blue_index=3;}
if(color[i].index==2) {color[i].RGB63_red_index=1; color[i].RGB63_green_index=3; color[i].RGB63_blue_index=1;}
if(color[i].index==3) {color[i].RGB63_red_index=1; color[i].RGB63_green_index=3; color[i].RGB63_blue_index=3;}
if(color[i].index==4) {color[i].RGB63_red_index=3; color[i].RGB63_green_index=1; color[i].RGB63_blue_index=1;}
if(color[i].index==5) {color[i].RGB63_red_index=3; color[i].RGB63_green_index=1; color[i].RGB63_blue_index=3;}
if(color[i].index==6) {color[i].RGB63_red_index=3; color[i].RGB63_green_index=3; color[i].RGB63_blue_index=1;}
if(color[i].index==7) {color[i].RGB63_red_index=3; color[i].RGB63_green_index=3; color[i].RGB63_blue_index=3;}
if(color[i].index==8) {color[i].RGB63_red_index=0; color[i].RGB63_green_index=0; color[i].RGB63_blue_index=0;}
if(color[i].index==9) {color[i].RGB63_red_index=0; color[i].RGB63_green_index=0; color[i].RGB63_blue_index=2;}
if(color[i].index==10){color[i].RGB63_red_index=0; color[i].RGB63_green_index=2; color[i].RGB63_blue_index=0;}
if(color[i].index==11){color[i].RGB63_red_index=0; color[i].RGB63_green_index=2; color[i].RGB63_blue_index=2;}
if(color[i].index==12){color[i].RGB63_red_index=2; color[i].RGB63_green_index=0; color[i].RGB63_blue_index=0;}
if(color[i].index==13){color[i].RGB63_red_index=2; color[i].RGB63_green_index=0; color[i].RGB63_blue_index=2;}
if(color[i].index==14){color[i].RGB63_red_index=2; color[i].RGB63_green_index=2; color[i].RGB63_blue_index=0;}
if(color[i].index==15){color[i].RGB63_red_index=2; color[i].RGB63_green_index=2; color[i].RGB63_blue_index=2;}
color[i].RGB63_red = color[i].red * 4 + color[i].RGB63_red_index;
color[i].RGB63_green = color[i].green * 4 + color[i].RGB63_green_index;
color[i].RGB63_blue = color[i].blue * 4 + color[i].RGB63_blue_index;
// copy hex values to temporary variables ///////////////////////////////
color[i].index_temp = color[i].index;
color[i].red_temp = color[i].red;
color[i].green_temp = color[i].green;
color[i].blue_temp = color[i].blue;
// set all color palettes to black //////////////////////////////////////
volMEMWORD(4194304+(i*2)+(palette_no*32)) = 0x0000;
}
}
void fade_in()
{
int palette_no;
int i=0;
int steps=-64;
waitVBlank();
palette_no = 0; // first palette to start with
while(1)
{
waitVBlank();
steps+=4;
for(i=0; i<256; i++)
{
// add steps to RGB63 temporary values ////////////////////
color[i].RGB63_red_temp = color[i].RGB63_red + steps;
color[i].RGB63_green_temp = color[i].RGB63_green + steps;
color[i].RGB63_blue_temp = color[i].RGB63_blue + steps;
// keep values inside the range of 0 to 63 ////////////////
if(color[i].RGB63_red_temp>63) color[i].RGB63_red_temp=63;
if(color[i].RGB63_red_temp<0) color[i].RGB63_red_temp=0;
if(color[i].RGB63_green_temp>63) color[i].RGB63_green_temp=63;
if(color[i].RGB63_green_temp<0) color[i].RGB63_green_temp=0;
if(color[i].RGB63_blue_temp>63) color[i].RGB63_blue_temp=63;
if(color[i].RGB63_blue_temp<0) color[i].RGB63_blue_temp=0;
// convert RGB63 back to ASM Hex Color Code ////////////////
color[i].RGB63_red_index_temp = color[i].RGB63_red_temp%4;
color[i].red_temp = color[i].RGB63_red_temp/4;
color[i].RGB63_green_index_temp = color[i].RGB63_green_temp%4;
color[i].green_temp = color[i].RGB63_green_temp/4;
color[i].RGB63_blue_index_temp = color[i].RGB63_blue_temp%4;
color[i].blue_temp = color[i].RGB63_blue_temp/4;
if(color[i].RGB63_red_index_temp==1 && color[i].RGB63_green_index_temp==1 && color[i].RGB63_blue_index_temp==1) color[i].index_temp=0;
if(color[i].RGB63_red_index_temp==1 && color[i].RGB63_green_index_temp==1 && color[i].RGB63_blue_index_temp==3) color[i].index_temp=1;
if(color[i].RGB63_red_index_temp==1 && color[i].RGB63_green_index_temp==3 && color[i].RGB63_blue_index_temp==1) color[i].index_temp=2;
if(color[i].RGB63_red_index_temp==1 && color[i].RGB63_green_index_temp==3 && color[i].RGB63_blue_index_temp==3) color[i].index_temp=3;
if(color[i].RGB63_red_index_temp==3 && color[i].RGB63_green_index_temp==1 && color[i].RGB63_blue_index_temp==1) color[i].index_temp=4;
if(color[i].RGB63_red_index_temp==3 && color[i].RGB63_green_index_temp==1 && color[i].RGB63_blue_index_temp==3) color[i].index_temp=5;
if(color[i].RGB63_red_index_temp==3 && color[i].RGB63_green_index_temp==3 && color[i].RGB63_blue_index_temp==1) color[i].index_temp=6;
if(color[i].RGB63_red_index_temp==3 && color[i].RGB63_green_index_temp==3 && color[i].RGB63_blue_index_temp==3) color[i].index_temp=7;
if(color[i].RGB63_red_index_temp==0 && color[i].RGB63_green_index_temp==0 && color[i].RGB63_blue_index_temp==0) color[i].index_temp=8;
if(color[i].RGB63_red_index_temp==0 && color[i].RGB63_green_index_temp==0 && color[i].RGB63_blue_index_temp==2) color[i].index_temp=9;
if(color[i].RGB63_red_index_temp==0 && color[i].RGB63_green_index_temp==2 && color[i].RGB63_blue_index_temp==0) color[i].index_temp=10;
if(color[i].RGB63_red_index_temp==0 && color[i].RGB63_green_index_temp==2 && color[i].RGB63_blue_index_temp==2) color[i].index_temp=11;
if(color[i].RGB63_red_index_temp==2 && color[i].RGB63_green_index_temp==0 && color[i].RGB63_blue_index_temp==0) color[i].index_temp=12;
if(color[i].RGB63_red_index_temp==2 && color[i].RGB63_green_index_temp==0 && color[i].RGB63_blue_index_temp==2) color[i].index_temp=13;
if(color[i].RGB63_red_index_temp==2 && color[i].RGB63_green_index_temp==2 && color[i].RGB63_blue_index_temp==0) color[i].index_temp=14;
if(color[i].RGB63_red_index_temp==2 && color[i].RGB63_green_index_temp==2 && color[i].RGB63_blue_index_temp==2) color[i].index_temp=15;
// write new ASM Hex Color Code to color adress //////////////
color[i].new_color=(color[i].index_temp)*4096+(color[i].red_temp)*256+(color[i].green_temp)*16+(color[i].blue_temp);
volMEMWORD(4194304+(i*2)+(palette_no*32)) = color[i].new_color;
}
if(steps>=0) break;
}
}
main.c
int main(void)
{
picture demo_pic_1;
aSprite demo_spr_1;
int end_loop_timer=0;
volMEMWORD(0x401ffe)=0x0000; // set BG color to black
LSPCmode=0x900;
initGfx();
clearFixLayer();
clearSprites(1, 381);
palJobPut(2, demo_pic_Palettes.palCount, demo_pic_Palettes.data);
palJobPut(4, demo_spr_Palettes.palCount, demo_spr_Palettes.data);
SCClose();
prepare_fade_in();
pictureInit(&demo_pic_1, &demo_pic, 1, 1, 50, 50, FLIP_NONE);
aSpriteInit(&demo_spr_1, &demo_spr, 2, 2, 50, 50, 0, FLIP_NONE);
SCClose();
fade_in();
do
{
waitVBlank();
end_loop_timer+=1;
aSpriteAnimate(&demo_spr);
SCClose();
if(end_loop_timer==420)
{
fade_out();
clearFixLayer();
clearSprites(1, 381);
}
}while(!(end_loop_timer==420));
}