/*
        BOUGER UNE FORME SUR UNE IMAGE EN FOND, EFFETS DE COULEURS
        LA FORME SUR L'IMAGE : DOUBLE BUFFER AVEC RECOPIE DU FOND
*/
#define ALLEGRO_STATICLINK
#include <allegro.h>
#include <time.h>
#include <string.h>
#include <stdio.h>

#define ECRAN_X	800
#define ECRAN_Y	600
#define MODE    GFX_AUTODETECT_WINDOWED
// une macro pour des contrôles d'erreur
#define ERREUR(msg) {\
   set_gfx_mode(GFX_TEXT,0,0,0,0);\
   allegro_message("Error : \n%s\n", msg);\
   allegro_exit();\
   return 1;\
}
enum{triang,cercle,end};
typedef struct FORME{
   int type;    // type rect, triangle ou cercle
   int x,y;		//position
   int tx,ty;	//taille
   int dx,dy;	//deplacement
   int couleur;
}FORME;

void    init_forme           (FORME*f);
int     mouvement_formes     (FORME*f);
void    dessine_forme        (FORME*f, BITMAP* bmp);
void    degrade_pas_variable (PALETTE pal);
/******************************************************************************
*******************************************************************************/
int main()
{
PALETTE p1,p2;					  
BITMAP*page,*fond;
FORME f[2];
int i,cmpt=0;

   allegro_init();
   install_keyboard(); 
   srand(time(NULL));
     
   if (set_gfx_mode(MODE, ECRAN_X, ECRAN_Y, 0, 0) != 0) 
      ERREUR("gfx_mode");
   
   // buffer
   page=create_bitmap(ECRAN_X,ECRAN_Y);
   fond=load_bitmap(".\\kand8b.bmp",p1);
   if (!page || !fond)
      ERREUR("create_bitmap page, fond");
   set_palette(p1);
   
   // initialisation
   init_forme(&f[0]);
   f[0].type=triang;
   init_forme(&f[1]);
   f[1].type=cercle;
   // boucle event
   while (!key[KEY_ESC]){
      
      stretch_blit (fond,page,0,0,fond->w,fond->h,0,0,page->w,page->h);
      for (i=0;i<2;i++){
         // mouvement 
         cmpt+=mouvement_formes(&f[i]);
         if(cmpt>15){
            f[i].dx=rand()%7-3;
            f[i].dy=rand()%7-3;
            f[i].couleur=rand()%130+1;
            cmpt=0;
         }
         // dessin dans buffer page
         dessine_forme(&f[i], page);
      }
      // affichage
      blit(page,screen,0,0,0,0,page->w,page->h);
      
      if (key[KEY_ENTER])
         degrade_pas_variable(p2);
      if (key[KEY_SPACE])
         set_palette(p1);
   }
}
END_OF_MAIN();
/******************************************************************************
initialisation
*******************************************************************************/
void init_forme(FORME*f)
{
   f->x=rand()%ECRAN_X;
   f->y=rand()%ECRAN_Y;
   f->tx=rand()%50+20;
   f->ty=rand()%50+20;
   f->dx=rand()%7-3;
   f->dy=rand()%7-3;
   f->couleur=rand()%130+1;
}
/******************************************************************************
Modifier les coordonnées d'une forme en fonction de ses valeurs de déplacement 
(dx et dy)Contrôler les bords (rebond en cas de collision)
*******************************************************************************/
int mouvement_formes(FORME*f)
{
int res=0;
   f->x += f->dx;
   f->y += f->dy;
   
   if ( f->x < 0){ 
      f->dx = ABS(f->dx);
      res++;
   }
   else if (f->x > ECRAN_X ){
      f->dx = -ABS(f->dx);
      res++;
   }
   if ( f->y < 0){ 
      f->dy = ABS(f->dy);
      res++;
   }
   else if (f->y > ECRAN_Y ){
      f->dy = -ABS(f->dy);
      res++;
   }
   return res;
}
/******************************************************************************
Afficher une forme dans une bitmap en fonction de son type
*******************************************************************************/
void dessine_forme(FORME*f, BITMAP* bmp)
{
   switch(f->type){
      case triang :
		 triangle( bmp,	f->x, f->y, f->x+f->tx, f->y,f->x+f->tx/2 ,f->y-f->ty, 
						f->couleur);
         break;

      case cercle :
		  circlefill( bmp, f->x, f->y, f->ty, f->couleur);	
         break;
	}
}
/******************************************************************************
Fabriquer un dégradé de couleur dans une palette 
*******************************************************************************/
void degrade_pas_variable(PALETTE pal)
{
int i,rouge,pr,vert,pv,bleu,pb;

	pal[0].r=pal[0].g=pal[0].b=0;	
	rouge = rand()%54+5;
	pr = rand()%11-5;
	vert = rand()%54+5;
	pv = rand()%11-5;
	bleu = rand()%54+5;
	pb = rand()%11-5;
	for(i=1;i<256;i++){
		rouge += pr;
		pal[i].r = rouge;
		if( rouge <=ABS(pr) || rouge >= 63-ABS(pr))
			pr*=-1;
		vert += pv;
		if( vert <=ABS(pv) || vert >= 63-ABS(pv))
			pv*=-1;
		pal[i].g = vert;
		bleu +=pb;
		if( bleu <=ABS(pb) || bleu >= 63-ABS(pb))
			pb*=-1;
		pal[i].b = bleu;
	}
	set_palette(pal);
}
/******************************************************************************
*******************************************************************************/

