aboutsummaryrefslogblamecommitdiff
path: root/background.h
blob: 62c8424de5d1509813fe4e66e6434a626b52681b (plain) (tree)





























































































































































                                                                                

                         
                                              
           
 






                                       
        


















                                                                                  
         










                                                 
         
                          
         








                                                    

         

                   
                                                                       





















































                                                                                        


                     



















































































































































































                                                                                                           

         
          
               


                                    


                                                        


                                  

                                                         
 
//Chrisoft Bullet Lab Remix HGE
//Background drawing Implementations
//"Copyleft" Chrisoft 2013
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[6][6];
	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");
		for (int i=0;i<6;++i)
		for (int j=0;j<6;++j)
		{
			BGSpr[i][j]=new hgeSprite(LeafTex,0,0,200,150);
			BGSpr[i][j]->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;
		DWORD tcol;
		if (onfadein)DoFadeIn();
		if (onfadeout)DoFadeOut();
		dt=hge->Timer_GetDelta();
		deltaBG+=dt;
		tx=200*cosf(deltaBG/10);
		ty=150*sinf(deltaBG/10);
		for (int i=-1;i<5;++i)
		for (int j=-1;j<5;++j)
			BGSpr[i+1][j+1]->SetColor(ARGB(alpha,0xCC,0xCC,0xCC)),
			BGSpr[i+1][j+1]->Render(i*199.0f+tx,j*149.0f+ty);
	}
};
BG_Leaves Leaves;
//********************************************
//Animated Leaves Background
//********************************************
HTEXTURE TLeaf;
HTEXTURE TSflake;
class Leaf_Anim;
Leaf_Anim *Head,*Tail;
bool LE_Active;
double lescale;
HTEXTURE letex;TextureRect letr;
DWORD lecolor;
class Leaf_Anim
{
private:
	hgeSprite* Leaf;
	double Rotation,DRotate;
	double x,y,dx,dy;
	int lim;
	~Leaf_Anim(){}
public:
	Leaf_Anim *Last,*Next;
	void init(int _lim)
	{
		//Leaf=new hgeSprite(letex,0,0,108,108);
		Leaf=new hgeSprite(letex,letr.x,letr.y,letr.w,letr.h);
		Leaf->SetColor(lecolor);
		x=rand()%908-108;
		y=-108;
		lim=_lim;
		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;
		Next=NULL;
	}
	void Delete()
	{
		if (this==Head)Head=this->Next;
		if (this==Tail)Tail=this->Last;
		if (this->Next)
		this->Next->Last=this->Last;
		if (this->Last)
		this->Last->Next=this->Next;
		delete this->Leaf;
		delete this;//Not sure this will work?..--Answer: This worked...
	}
	void Update()
	{
		if (!this||!Leaf)return;
		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 Delete();
		if (!Leaf)return;
		Leaf->RenderEx(x,y,Rotation,lescale);
	}
	void Process()
	{
		int times=1;
		if(LOWFPS) times=17;
		for (int i=1;i<=times;++i)
		if (rand()%1000>lim&&LE_Active)
		{
			Tail->Next=new Leaf_Anim();
			Tail->Next->init(990);
			Tail->Next->Last=Tail;
			Tail=Tail->Next;
		}
		Leaf_Anim *cur=Head;
		while (cur)cur->Update(),cur=cur->Next;
	}
};
//********************************************
//3D-sky Background
//Based on a hge tutorial
//********************************************
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:
	const DWORD skyTopColors[3] = {0xFF15092A, 0xFF6C6480, 0xFF89B9D0};
	const DWORD skyBtmColors[3] = {0xFF303E57, 0xFFAC7963, 0xFFCAD7DB};
	const DWORD seaTopColors[3] = {0xFF3D546B, 0xFF927E76, 0xFF86A2AD};
	const DWORD seaBtmColors[3] = {0xFF1E394C, 0xFF2F4E64, 0xFF2F4E64};
	const int seq[9]={0, 0, 1, 2, 2, 2, 1, 0, 0};
	HTEXTURE skyitem;
	hgeSprite *sky,*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;
		sky=new hgeSprite(0, 0, 0, ScreenWidth, ScreenHeight);
		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 sky;
		delete sea;delete skylyr;
		hge->Texture_Free(skyitem);
	}
	void SetSpeed(float _speed){speed=_speed;}
	void SetSkyA(float _skya){skya=_skya;}
	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[seq[seq_id]]);
		col2.SetHWColor(skyTopColors[seq[seq_id+1]]);
		colSkyTop=col2*seq_residue + col1*(1.0f-seq_residue);
		col1.SetHWColor(skyBtmColors[seq[seq_id]]);
		col2.SetHWColor(skyBtmColors[seq[seq_id+1]]);
		colSkyBtm=col2*seq_residue + col1*(1.0f-seq_residue);
		col1.SetHWColor(seaTopColors[seq[seq_id]]);
		col2.SetHWColor(seaTopColors[seq[seq_id+1]]);
		colSeaTop=col2*seq_residue + col1*(1.0f-seq_residue);
		col1.SetHWColor(seaBtmColors[seq[seq_id]]);
		col2.SetHWColor(seaBtmColors[seq[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()
	{
		sky->SetColor(colSkyTop.GetHWColor(), 0);
		sky->SetColor(colSkyTop.GetHWColor(), 1);
		sky->SetColor(colSkyBtm.GetHWColor(), 2);
		sky->SetColor(colSkyBtm.GetHWColor(), 3);
		sky->Render(0, 0);
		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;

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;
}