// Chrisoft Bullet Lab Remix HGE -*- C++ -*- // Background drawing Implementations // Copyright Chrisoft 2014 #include 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 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::iterator i=llist.begin();i!=llist.end();++i) { if(i->Update()) { std::list::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+dltTimer_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;iTexture_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; iRandom_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; iTimer_GetTime(); a*=20; for(j=0; jSetColor(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; jSetColor(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; iGetColor(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; iSetColor((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 (sata)--sa; if (rtr)--r; if (gtg)--g; if (btb)--b; a=SETR(a,r);a=SETG(a,g);a=SETB(a,b);a=SETA(a,sa); return a; }