summaryrefslogblamecommitdiff
path: root/background.h
blob: d422d163f92cb730148ebdf4aa9172790eb0c65f (plain) (tree)
1
2
3
4

                                    
                         
               











                                              
                         


























                                                                      

                                                         















                                                                              





                                          
                                                            

                                      
                                                               







                                              



                                
               




                                
       
                   
         

                                                                      



                                                                    
         
                     
         





                                                
                                                  
                                                     
                         
         






                                   
         






                                           
                 










                                                                                      
                 
         
      
                                              

                         
                                              




                                                                          
           
 






                                       
        
                         

                                                  











                                                                                  
         










                                                 
         
                          
         








                                                    

         

                   
                                                                       
                                          









                                                          




































                                                                                        
                           




                                                  
                                                 








                                                              


                     














                                                            

                                                                
                                                                     

                                                                
                                                                     

                                                                
                                                                     

                                                                


































































































































                                                                                                           
            

                                            
      


                                                                         

















                                                                                        

         
          
               
 














                                
                     










                                                                           



                                                                   
         
                                                  
         
                                                                                                                        








                                                                       
                                               


                                                          
                                                            










                                                                                  



                                              
      







                                                                
                                                                        


                                   
                                                                                                                                            

                                                           
                                                                                        





















                                                                                       
              

                                    


                                                        


                                  

                                                         
 
//Chrisoft Bullet Lab Remix HGE
//Background drawing Implementations
//Copyright Chrisoft 2014
#include <list>
const char* BACKGROUND_H_FN="background.h";

double deltaBG;
//********************************************
//Full-screen Leaves Background
//********************************************
class BG_Leaves
{
private:
	DWORD alpha,alim;
	bool onfadein,onfadeout;
	int fadebreak;
	hgeSprite* BGSpr;
	HTEXTURE LeafTex;
	void DoFadeIn()
	{
		if (LOWFPS)fadebreak+=17;else ++fadebreak;
		if (fadebreak>17)fadebreak=0;else return;
		if (LOWFPS)if(alpha+0x20<=alim)alpha+=0x20;else{}
		else if (alpha+0x2<=alim)alpha+=2;
		if (alpha>=alim)onfadein=false;
	}
	void DoFadeOut()
	{
		if (LOWFPS)fadebreak+=17;else ++fadebreak;
		if (fadebreak>30)fadebreak=0;else return;
		if (LOWFPS)
			if (alpha<0x20)alpha=0;else alpha-=0x20;
		else
			if (alpha<0x2)alpha=0;else alpha-=0x2;
		if (!alpha)onfadeout=0;
	}
public:
	bool IsActive()
	{
		return alpha?true:false;
	}
	void Init(DWORD limalpha)
	{
		LeafTex=hge->Texture_Load("./Resources/b_leaves.png");
		BGSpr=new hgeSprite(LeafTex,0,0,200,150);
		BGSpr->SetColor(0x00CCCCCC);
		onfadein=onfadeout=false;alpha=0x00;alim=limalpha;fadebreak=0;

	}
	void SetFadeIn()
	{
		alpha=0x01;
		onfadein=true;
	}
	void SetFadeOut()
	{
		alpha=alim;
		onfadeout=true;
	}
	void Update()
	{
		double tx,ty,dt;
		if (onfadein)DoFadeIn();
		if (onfadeout)DoFadeOut();
		dt=hge->Timer_GetDelta();
		deltaBG+=dt;
		tx=200*cosf(deltaBG/10);
		ty=150*sinf(deltaBG/10);
		BGSpr->SetColor(ARGB(alpha,0xCC,0xCC,0xCC));
		for (int i=-1;i<5;++i)
		for (int j=-1;j<5;++j)
			BGSpr->Render(i*199.0f+tx,j*149.0f+ty);
	}
};
BG_Leaves Leaves;
//********************************************
//Animated Leaves Background
//********************************************
HTEXTURE TLeaf;
HTEXTURE TSflake;
bool LE_Active;
double lescale;
HTEXTURE letex;TextureRect letr;
DWORD lecolor;
class Leaf_Node
{
private:
	hgeSprite* Leaf;
	double Rotation,DRotate;
	double x,y,dx,dy;
public:
	void init()
	{
		Leaf=new hgeSprite(letex,letr.x,letr.y,letr.w,letr.h);
		Leaf->SetColor(lecolor);
		x=rand()%908-108;y=-108;
		dx=rand()%200/100.0f-1.0f;dx*=0.075;
		dy=rand()%200/100.0f+0.5f;dy*=0.075;
		Rotation=0;DRotate=rand()%100/10000.0f;DRotate*=0.1;
	}
	bool Update()
	{
		int times=1;if (LOWFPS)times=17;
		for (int i=1;i<=times;++i)
		{
			Rotation+=DRotate;
			x+=dx;y+=dy;
		}
		if (x>908||x<-108||y>708)return 1;
		Leaf->RenderEx(x,y,Rotation,lescale);
		return 0;
	}
};
class Leaf_Anim
{
public:
	std::list<Leaf_Node> llist;
	double brk;
	void Init()
	{
		llist.clear();
		brk=rand()%1000/1250.0f;
	}
	void Update()
	{
		brk-=hge->Timer_GetDelta();
		if(brk<0)
		{
			brk=rand()%1000/1250.0f;
			Leaf_Node a;a.init();
			llist.push_back(a);
		}
		for(std::list<Leaf_Node>::iterator i=llist.begin();i!=llist.end();++i)
		{
			if(i->Update())
			{
				std::list<Leaf_Node>::iterator r=i;++r;
				llist.erase(i);i=--r;
			}
		}
	}
}Leaf;
//********************************************
//3D-sky Background
//Based on a hge tutorial
//********************************************
static const DWORD skyTopColors[3] = {0xFF15092A, 0xFF6C6480, 0xFF89B9D0};
static const DWORD skyBtmColors[3] = {0xFF303E57, 0xFFAC7963, 0xFFCAD7DB};
static const DWORD seaTopColors[3] = {0xFF3D546B, 0xFF927E76, 0xFF86A2AD};
static const DWORD seaBtmColors[3] = {0xFF1E394C, 0xFF2F4E64, 0xFF2F4E64};
static const int skyseq[9]={0, 0, 1, 2, 2, 2, 1, 0, 0};
class TDSky
{
#define ScreenWidth 800
#define ScreenHeight 600
#define Stars 100
#define SeaDisize 16
#define SkyHeight (ScreenHeight*0.6f)
#define StarsHeight (SkyHeight*0.9f)
#define OrbitRadius (ScreenWidth*0.43f)
private:
	HTEXTURE skyitem;
	hgeQuad skygrad;
	hgeSprite *sun,*moon,*glow,*seaglow,*star;
	hgeDistortionMesh *sea,*skylyr;
	float timet,speed,skya,skylima,seq_residue;
	int seq_id;
	float starX[Stars],starY[Stars],starS[Stars],starA[Stars],seaP[SeaDisize];
	hgeColor colWhite,colSkyTop,colSkyBtm,colSeaTop,colSeaBtm;
	hgeColor colSun,colSunGlow;
	hgeColor colMoon,colMoonGlow,colSeaGlow;
	float sunX,sunY,sunS,sunGlowS;
	float moonX,moonY,moonS,moonGlowS;
	float seaGlowX,seaGlowSX,seaGlowSY;
	bool skyOnFadeIn,skyOnFadeOut;
	float GetTime()
	{
		struct tm *t=0;
		time_t tt=time(NULL);
		t=localtime(&tt);
		float tmp=0;
		if(t)
		{
			tmp=t->tm_sec;
			tmp=t->tm_min+tmp/60.0f;
			tmp=t->tm_hour+tmp/60.0f;
		}
		return tmp;
	}
	void SkyDoFadeIn()
	{
		float dlt=1.0f/hge->Timer_GetFPS();
		if (skya+dlt<skylima)skya+=dlt;
		else skya=skylima,skyOnFadeIn=false;
	}
	void SkyDoFadeOut()
	{
		float dlt=1.0f/hge->Timer_GetFPS();
		if (skya-dlt>0)skya-=dlt;
		else skya=0.0f,skyOnFadeOut=false;
	}
public:
	bool Init()
	{
		skyitem=hge->Texture_Load("./Resources/e_skyitem.png");
		if(!skyitem) return false;
		skygrad.tex=0;skygrad.blend=BLEND_DEFAULT;
		for(int i=0;i<4;++i)skygrad.v[i].z=0.5;
		skygrad.v[0].tx=0;skygrad.v[0].ty=0;
		skygrad.v[1].tx=1;skygrad.v[1].ty=0;
		skygrad.v[2].tx=1;skygrad.v[2].ty=1;
		skygrad.v[3].tx=0;skygrad.v[3].ty=1;
		skygrad.v[0].x=0;skygrad.v[0].y=0;
		skygrad.v[1].x=800;skygrad.v[1].y=0;
		skygrad.v[2].x=800;skygrad.v[2].y=600;
		skygrad.v[3].x=0;skygrad.v[3].y=600;
		sea=new hgeDistortionMesh(SeaDisize, SeaDisize);
		sea->SetTextureRect(0, 0, ScreenWidth, ScreenHeight-SkyHeight);
		sun=new hgeSprite(skyitem,81,0,114,114);
		sun->SetHotSpot(57,57);
		moon=new hgeSprite(skyitem,0,0,81,81);
		moon->SetHotSpot(40,40);
		star=new hgeSprite(skyitem,195,0,9,9);
		star->SetHotSpot(5,5);
		glow=new hgeSprite(skyitem,204,0,128,128);
		glow->SetHotSpot(64,64);
		glow->SetBlendMode(BLEND_COLORADD | BLEND_ALPHABLEND | BLEND_NOZWRITE);
		seaglow=new hgeSprite(skyitem,204,96,128,32);
		seaglow->SetHotSpot(64,0);
		seaglow->SetBlendMode(BLEND_COLORADD | BLEND_ALPHAADD | BLEND_NOZWRITE);
		skylyr=new hgeDistortionMesh(16, 16);
		skylyr->SetTexture(skyitem);
		skylyr->SetTextureRect(0,128,512,512);
		skylyr->SetBlendMode(BLEND_ALPHAADD);
		colWhite.SetHWColor(0xFFFFFFFF);
		timet=GetTime();
		speed=skya=0.0f;
		for(int i=0;i<Stars;++i)
		{
			starX[i]=rand()%ScreenWidth;
			starY[i]=rand()%((int)StarsHeight);
			starS[i]=(rand()%60+10.0f)/100.0f;
		}
		for(int i=0;i<SeaDisize;++i)
		{
			seaP[i]=i+(rand()%300-150.0f)/10.0f;
		}
		return true;
	}
	void Deinit()
	{
		delete seaglow;delete glow;
		delete star;delete moon;
		delete sun;
		delete sea;delete skylyr;
		hge->Texture_Free(skyitem);
	}
	void SetSpeed(float _speed){speed=_speed;}
	void SetSkyA(float _skya){skya=_skya;}
	void SetTime(float _timet){timet=_timet;}
	void SkySetFadeIn(float _starta=0.0f,float _lima=1.0f)
	{
		skya=_starta;skylima=_lima;
		skyOnFadeIn=true;skyOnFadeOut=false;
	}
	void SkySetFadeOut(float _starta=0.0f)
	{
		if (_starta>1E-4)skya=_starta;
		skyOnFadeIn=false;skyOnFadeOut=true;
	}
	void Update()
	{
		int i, j, k;
		float zenith,a,dy,fTime;
		float posX,s1,s2;
		const float cellw=ScreenWidth/(SeaDisize-1);
		hgeColor col1,col2;
		DWORD dwCol1,dwCol2;
		if(speed==0.0f) timet=GetTime();
		else
		{
			timet+=hge->Timer_GetDelta()*speed;
			if(timet>=24.0f) timet-=24.0f;
		}
		seq_id=(int)(timet/3);
		seq_residue=timet/3-seq_id;
		zenith=-(timet/12.0f*pi-pi/2.0f);
		col1.SetHWColor(skyTopColors[skyseq[seq_id]]);
		col2.SetHWColor(skyTopColors[skyseq[seq_id+1]]);
		colSkyTop=col2*seq_residue + col1*(1.0f-seq_residue);
		col1.SetHWColor(skyBtmColors[skyseq[seq_id]]);
		col2.SetHWColor(skyBtmColors[skyseq[seq_id+1]]);
		colSkyBtm=col2*seq_residue + col1*(1.0f-seq_residue);
		col1.SetHWColor(seaTopColors[skyseq[seq_id]]);
		col2.SetHWColor(seaTopColors[skyseq[seq_id+1]]);
		colSeaTop=col2*seq_residue + col1*(1.0f-seq_residue);
		col1.SetHWColor(seaBtmColors[skyseq[seq_id]]);
		col2.SetHWColor(seaBtmColors[skyseq[seq_id+1]]);
		colSeaBtm=col2*seq_residue + col1*(1.0f-seq_residue);
		if(seq_id>=6 || seq_id<2)
			for(int i=0; i<Stars; ++i)
			{
				a=1.0f-starY[i]/StarsHeight;
				//a*=hge->Random_Float(0.6f, 1.0f);
				a*=(rand()%40+60.0f)/100.0f;
				if(seq_id>=6) a*=sinf((timet-18.0f)/12.0f*pi);
				else a*=sinf((1.0f-timet/6.0f)*pi/2);
				starA[i]=a;
			}
			if(seq_id==2) a=sinf(seq_residue*pi/2);
		else if(seq_id==5) a=cosf(seq_residue*pi/2);
		else if(seq_id>2 && seq_id<5) a=1.0f;
		else a=0.0f;
		colSun.SetHWColor(0xFFEAE1BE);
		colSun=colSun*(1-a)+colWhite*a;
		a=(cosf(timet/6.0f*pi)+1.0f)/2.0f;
		if(seq_id>=2 && seq_id<=6)
		{
			colSunGlow=colWhite*a;
			colSunGlow.a=1.0f;
		}
		else colSunGlow.SetHWColor(0xFF000000);
		sunX=ScreenWidth*0.5f+cosf(zenith)*OrbitRadius;
		sunY=SkyHeight*1.2f+sinf(zenith)*OrbitRadius;
		sunS=1.0f-0.3f*sinf((timet-6.0f)/12.0f*pi);
		sunGlowS=3.0f*(1.0f-a)+3.0f;
		if(seq_id>=6) a=sinf((timet-18.0f)/12.0f*pi);
		else a=sinf((1.0f-timet/6.0f)*pi/2);
		colMoon.SetHWColor(0x20FFFFFF);
		colMoon=colMoon*(1-a)+colWhite*a;
		colMoonGlow=colWhite;
		colMoonGlow.a=0.5f*a;
		moonX=ScreenWidth*0.5f+cosf(zenith-pi)*OrbitRadius;
		moonY=SkyHeight*1.2f+sinf(zenith-pi)*OrbitRadius;
		moonS=1.0f-0.3f*sinf((timet+6.0f)/12.0f*pi);
		moonGlowS=a*0.4f+0.5f;
		if(timet>19.0f || timet<4.5f)
		{
			a=0.2f;
			if(timet>19.0f && timet<20.0f) a*=(timet-19.0f);
			else if(timet>3.5f && timet<4.5f) a*=1.0f-(timet-3.5f);
			colSeaGlow=colMoonGlow;
			colSeaGlow.a=a;
			seaGlowX=moonX;
			seaGlowSX=moonGlowS*3.0f;
			seaGlowSY=moonGlowS*2.0f;
		}
		else if(timet>6.5f && timet<19.0f)
		{
			a=0.3f;
			if(timet<7.5f) a*=(timet-6.5f);
			else if(timet>18.0f) a*=1.0f-(timet-18.0f);
			colSeaGlow=colSunGlow;
			colSeaGlow.a=a;
			seaGlowX=sunX;
			seaGlowSX=sunGlowS;
			seaGlowSY=sunGlowS*0.6f;
		}
		else colSeaGlow.a=0.0f;
		for(i=1; i<SeaDisize-1; ++i)
		{
			a=float(i)/(SeaDisize-1);
			col1=colSeaTop*(1-a)+colSeaBtm*a;
			dwCol1=col1.GetHWColor();
			fTime=2.0f*hge->Timer_GetTime();
			a*=20;
			for(j=0; j<SeaDisize; ++j)
			{
				sea->SetColor(j, i, dwCol1);
				dy=a*sinf(seaP[i]+(float(j)/(SeaDisize-1)-0.5f)*pi*16.0f-fTime);
				sea->SetDisplacement(j, i, 0.0f, dy, HGEDISP_NODE);
			}
		}
		float t=0.1*hge->Timer_GetTime();
		skylyr->SetTextureRect(128+sin(t)*128.0f,256+cos(t)*128.0f,256,128);
		if (skyOnFadeIn)SkyDoFadeIn();
		if (skyOnFadeOut)SkyDoFadeOut();
		for (int i=-8;i<8;++i)
		for (int j=-8;j<8;++j)
		{
			skylyr->SetColor(j+8,i+8,ARGB((int)(skya*((i+9)*16-16)),0xFF,0xFF,0xFF));
			skylyr->SetDisplacement(j+8,i+8,j*(16.0f*((i+9)/16.0f)+64.0f),i*24,HGEDISP_CENTER);
		}
		dwCol1=colSeaTop.GetHWColor();
		dwCol2=colSeaBtm.GetHWColor();
		for(j=0; j<SeaDisize; ++j)
		{
			sea->SetColor(j, 0, dwCol1);
			sea->SetColor(j, SeaDisize-1, dwCol2);
		}
		if(timet>19.0f || timet<5.0f)
		{
			a=0.12f;
			if(timet>19.0f && timet<20.0f) a*=(timet-19.0f);
			else if(timet>4.0f && timet<5.0f) a*=1.0f-(timet-4.0f);
			posX=moonX;
		}
		else if(timet>7.0f && timet<17.0f)
		{
			a=0.14f;
			if(timet<8.0f) a*=(timet-7.0f);
			else if(timet>16.0f) a*=1.0f-(timet-16.0f);
			posX=sunX;
		}
		else a=0.0f;
		if(a!=0.0f)
		{
			k=(int)floorf(posX/cellw);
			s1=(1.0f-(posX-k*cellw)/cellw);
			s2=(1.0f-((k+1)*cellw-posX)/cellw);
			if(s1>0.7f) s1=0.7f;
			if(s2>0.7f) s2=0.7f;
			s1*=a;s2*=a;
			for(i=0; i<SeaDisize; i+=2)
			{
				a=sinf(float(i)/(SeaDisize-1)*pi/2);
				col1.SetHWColor(sea->GetColor(k,i));
				col1+=colSun*s1*(1-a);
				col1.Clamp();
				sea->SetColor(k, i, col1.GetHWColor());
				col1.SetHWColor(sea->GetColor(k+1,i));
				col1+=colSun*s2*(1-a);
				col1.Clamp();
				sea->SetColor(k+1, i, col1.GetHWColor());
			}
		}
	}
	void Render()
	{
#ifdef WIN32
		skygrad.tex=0;
		skygrad.blend=BLEND_DEFAULT;
#endif
		skygrad.v[0].col=skygrad.v[1].col=colSkyTop.GetHWColor();
		skygrad.v[2].col=skygrad.v[3].col=colSkyBtm.GetHWColor();
		hge->Gfx_RenderQuad(&skygrad);
		if(seq_id>=6 || seq_id<2)
			for(int i=0; i<Stars; ++i)
			{
				star->SetColor((DWORD(starA[i]*255.0f)<<24) | 0xFFFFFF);
				star->RenderEx(starX[i], starY[i], 0.0f, starS[i]);
			}
		glow->SetColor(colSunGlow.GetHWColor());
		glow->RenderEx(sunX, sunY, 0.0f, sunGlowS);
		sun->SetColor(colSun.GetHWColor());
		sun->RenderEx(sunX, sunY, 0.0f, sunS);
		glow->SetColor(colMoonGlow.GetHWColor());
		glow->RenderEx(moonX, moonY, 0.0f, moonGlowS);
		moon->SetColor(colMoon.GetHWColor());
		moon->RenderEx(moonX, moonY, 0.0f, moonS);
		sea->Render(0, SkyHeight);
		seaglow->SetColor(colSeaGlow.GetHWColor());
		seaglow->RenderEx(seaGlowX, SkyHeight, 0.0f, seaGlowSX, seaGlowSY);
		skylyr->Render(ScreenWidth/8*3,ScreenHeight/3*2);
	}
};
TDSky sky;
bool skyactive;

class PicBack
{
public:
	enum arMode
	{
		Centered,
		Tiled,
		Stretched
	};
private:
	hgeQuad quad;
	arMode Mode;
	DWORD alpha,alim;
	bool onfadein,onfadeout;
	int fadebreak;
	double scale;
	void DoFadeIn()
	{
		if (LOWFPS)fadebreak+=17;else ++fadebreak;
		if (fadebreak>17)fadebreak=0;else return;
		if (LOWFPS)if(alpha+0x20<=alim)alpha+=0x20;else alpha=alim;
		else if (alpha+0x2<=alim)alpha+=2;else alpha=alim;
		if (alpha>=alim)onfadein=false;
	}
	void DoFadeOut()
	{
		if (LOWFPS)fadebreak+=17;else ++fadebreak;
		if (fadebreak>17)fadebreak=0;else return;
		if (LOWFPS)if (alpha<0x20)alpha=0;else alpha-=0x20;
		else if (alpha<0x2)alpha=0;else alpha-=0x2;
		if (!alpha)onfadeout=false;
	}
	void RenderCenterAt(vector2d a,double scl)
	{
		vector2d s=vector2d(hge->Texture_GetWidth(quad.tex,true)*scl,hge->Texture_GetHeight(quad.tex,true)*scl);
		for(int i=0;i<4;++i)quad.v[i].col=SETA(0xFFFFFF,alpha);
		quad.v[0].x=a.x-s.x/2.0f;quad.v[0].y=a.y-s.y/2.0f;
		quad.v[1].x=a.x+s.x/2.0f;quad.v[1].y=a.y-s.y/2.0f;
		quad.v[2].x=a.x+s.x/2.0f;quad.v[2].y=a.y+s.y/2.0f;
		quad.v[3].x=a.x-s.x/2.0f;quad.v[3].y=a.y+s.y/2.0f;
		hge->Gfx_RenderQuad(&quad);
	}
public:
	bool active(){return alpha;}
	void SetScale(double _scl){scale=_scl;}
	void Init(const char *tx,arMode _Mode,DWORD _alim)
	{
		quad.tex=hge->Texture_Load(tx);alim=_alim;
		Mode=_Mode;scale=1;quad.blend=BLEND_DEFAULT;
#ifdef WIN32
		vector2d srl=vector2d(hge->Texture_GetWidth(quad.tex,true),
			                  hge->Texture_GetHeight(quad.tex,true));
		vector2d srm=vector2d(hge->Texture_GetWidth(quad.tex,false),
			                  hge->Texture_GetHeight(quad.tex,false));
		srm.x=srl.x/srm.x;srm.y=srl.y/srm.y;
		quad.v[0].tx=0;quad.v[0].ty=0;
		quad.v[1].tx=srm.x;quad.v[1].ty=0;
		quad.v[2].tx=srm.x;quad.v[2].ty=srm.y;
		quad.v[3].tx=0;quad.v[3].ty=srm.y;
#else
		quad.v[0].tx=0,quad.v[0].ty=0;
		quad.v[1].tx=1,quad.v[1].ty=0;
		quad.v[2].tx=1,quad.v[2].ty=1;
		quad.v[3].tx=0,quad.v[3].ty=1;
#endif
		onfadein=onfadeout=false;alpha=0;
	}
	void Update()
	{
		if(onfadein)DoFadeIn();if(onfadeout)DoFadeOut();
		switch(Mode)
		{
			case Centered:
				RenderCenterAt(vector2d(400,300),scale);
			break;
			case Tiled:
			{
				vector2d s=vector2d(hge->Texture_GetWidth(quad.tex,true)*scale,hge->Texture_GetHeight(quad.tex,true)*scale);
				for(int i=0;i*s.x<=800;++i)
				for(int j=0;j*s.y<=600;++j)
				RenderCenterAt(vector2d(s.x/2+i*s.x,s.y/2+j*s.y),scale);
			}
			break;
			case Stretched:
				for(int i=0;i<4;++i)quad.v[i].col=SETA(0xFFFFFF,alpha);
				quad.v[0].x=0,quad.v[0].y=0;
				quad.v[1].x=800,quad.v[1].y=0;
				quad.v[2].x=800,quad.v[2].y=600;
				quad.v[3].x=0,quad.v[3].y=600;
				hge->Gfx_RenderQuad(&quad);
			break;
		}
	}
	void SetFadeIn()
	{
		alpha=0x01;
		onfadein=true;
	}
	void SetFadeOut()
	{
		alpha=alim;
		onfadeout=true;
	}
}binter,bdiff;
DWORD ColorTransfer(DWORD a,DWORD t)
{
	int r=GETR(a),g=GETG(a),b=GETB(a),sa=GETA(a);
	int tr=GETR(t),tg=GETG(t),tb=GETB(t),ta=GETA(t);
	if (sa<ta)++sa;if (sa>ta)--sa;
	if (r<tr)++r;if (r>tr)--r;
	if (g<tg)++g;if (g>tg)--g;
	if (b<tb)++b;if (b>tb)--b;
	a=SETR(a,r);a=SETG(a,g);a=SETB(a,b);a=SETA(a,sa);
	return a;
}