/*
        ANIMATION A PARTIR DE SPRITE - CONTROLE DU MOUVEMENT
        RECUPERER DES SPRITES STOCKES SUR UNE SEULE IMAGE
*/

#include <allegro.h>
#include <stdio.h>
#include <time.h>

#define ECRAN_X	800
#define ECRAN_Y	600
#define MODE    GFX_AUTODETECT_WINDOWED
#define ERREUR(msg) {\
   set_gfx_mode(GFX_TEXT,0,0,0,0);\
   allegro_message("erreur ligne %d, fichier %s: %s\n",__LINE__, __FILE__,msg);\
   allegro_exit();\
   exit(EXIT_FAILURE);\
}
#define NB_IMAGE   32
// généralisation controle du sprite 
typedef struct SPRITE{
    // le deplacement
    int x,y;         // position
    int tx,ty;       // taille
    int px,py;        // pas du deplacement
    int xwait,ywait; // pour retard avancement en x et y
    int xcmpt,ycmpt; // pour compter le retard
    // l'image
    int courant;     // l'image courante
    int nb_image;   // le nombre max des images de l'animation
    int dir;        // sens de l'animation (à reculons ou avancer)
    int tmps;       // pour compter le temps d'affichage de l'image
    int maxtmps;    // temps maxi pour chaque image
    
}t_sprite ;

void avance(t_sprite *s);
void cntl_bords(t_sprite *s);
BITMAP* recup_sprites(  BITMAP*scr, int w, int h, int startx, int starty,
                        int col, int i);
/******************************************************************************
*******************************************************************************/
int main()
{
// Sur une seule image 32 sprites de taille identique et disposés à intervals 
// réguliers sur 8 colones
BITMAP *page,*im[NB_IMAGE],*tmp; 
int i;
t_sprite balle;
t_sprite *s=&balle;

   allegro_init();
   install_keyboard(); 
   srand(time(NULL));
   
   set_color_depth(16);
   if (set_gfx_mode(MODE, ECRAN_X, ECRAN_Y, 0, 0) != 0) 
      ERREUR(allegro_error);
   
   // récup de l'image qui contient tout
   tmp=load_bitmap("all_sprites.bmp",NULL);
   if (!tmp)
      ERREUR("creation image temporaire image");
   
   // découpage dans tableau im[]
   for (i=0;i<NB_IMAGE;i++){
     im[i]=recup_sprites(tmp,64,64,0,0,8,i);
     if (!im[i])
        ERREUR("recup images");
   }
   destroy_bitmap(tmp);   
      
   page=create_bitmap(SCREEN_W,SCREEN_H);
   if (!page)
      ERREUR("creation buffer")  
   
   // initialisation du sprite
   s->x=rand()%(SCREEN_W-im[0]->w);
   s->y=rand()%(SCREEN_H-im[0]->h);
   s->tx=im[0]->w;
   s->ty=im[0]->h;
   s->xwait=rand()%2+1;
   s->ywait=rand()%2+1;
   s->xcmpt=0;
   s->ycmpt=0;
   s->px=rand()%2+4;
   s->py=rand()%2+4;
   s->courant=0;
   s->nb_image=NB_IMAGE-1;
   s->tmps=0;
   s->maxtmps=rand()%3+1;
   s->dir=1;
   
   // boucle
   while (!key[KEY_ESC]){
      
      clear_bitmap(page);
      // mise à jour du sprite
      avance(s);
      // controle bords
      cntl_bords(s);
      
      // infos
      textprintf_ex(page,font,10,10,makecol(0,255,0),-1,
      "x = %3d, y = %3d", s->x,s->y);
      textprintf_ex(page,font,10,20,makecol(0,255,0),-1,
      "retard x = %2d, retard y = %2d",s->xcmpt,s->ycmpt);
      textprintf_ex(page,font,10,30,makecol(0,255,0),-1,
      "pas de deplacement en x = %2d, en y = %2d",s->px,s->py);
      textprintf_ex(page,font,10,30,makecol(0,255,0),-1,"retard image = %2d, "
      "retard max =%2d, direction = %2d",s->tmps,s->maxtmps,s->dir);
      // image
      draw_sprite(page,im[s->courant],s->x,s->y);
      
      //affichage ecran
      blit(page,screen,0,0,0,0,SCREEN_W,SCREEN_H);

   }
   destroy_bitmap(page);
   for (i=0;i<NB_IMAGE;i++)
      destroy_bitmap(im[i]);
      
   return 0;
   
}
END_OF_MAIN();
/******************************************************************************
*******************************************************************************/
BITMAP* recup_sprites(  BITMAP*scr, // bitmap origine
                        int w, int h, // taille element
                        int startx, int starty, // à partir de 
                        int col, int i)// nombre de colones, élément i
{
BITMAP *bmp;
int x,y;
     
   bmp=create_bitmap(w,h);
   if (bmp!=NULL){
      x= startx+(i%col)*w;    
      y= starty+(i/col)*h; 
      blit(scr,bmp,x,y,0,0,w,h);     
   }    
   return bmp;
}
/******************************************************************************
*******************************************************************************/
void avance(t_sprite *s)
{
int res;
   // petit compte pour retard avance en x
   s->xcmpt=(++s->xcmpt)%s->xwait;
   if (!s->xcmpt)
      s->x+=s->px;
   // idem en y
   s->ycmpt=(++s->ycmpt)%s->ywait;
   if (!s->ycmpt)
      s->y+=s->py;
   
   // compte pour affichage image
   s->tmps=(++s->tmps)%s->maxtmps;
   if (!s->tmps){
      s->courant+=s->dir;
      s->courant=(s->courant<0) ? s->nb_image : s->courant;
      s->courant=(s->courant>s->nb_image) ? 0 : s->courant;
   }        
}
/******************************************************************************
*******************************************************************************/
void cntl_bords(t_sprite *s)
{
int res=0;
   // controle mouvement x
   if (res=(s->x<0)){
      s->x=0;
      s->px=rand()%4+1;
      res=1;
   }
   else if (res=(s->x+s->tx>SCREEN_W)){
      s->x=SCREEN_W-s->tx;
      s->px=(rand()%4+1)*-1;
   }      
   
   // controle mouvement y
   if (res=(s->y<0)){
      s->y=0;
      s->py=rand()%4+1;
   }
   else if (res=(s->y+s->ty>SCREEN_H)){
      s->y=SCREEN_H-s->ty;
      s->py=(rand()%4+1)*-1;
   }
   
   if (res){
      // change direction image (reverse)
      s->dir= 2*(rand()%2)-1;
      // le retard mouvement
      s->xwait=rand()%5+1;
      s->ywait=rand()%5+1;
      s->xcmpt=0;
      s->ycmpt=0;
      // le retard image
      s->tmps=0;
      s->maxtmps=rand()%6+1;
   }        
}
/******************************************************************************
RAPPEL LINKAGE lib static :
pour dev :
dans menu : Projet/otpions du projet/paramètres/éditeur de liens , là, 
copier la liste suivante :
  -lalleg_s -lgdi32 -lwinmm -lole32 -ldxguid -ldinput -lddraw -ldsound
et dans la colonne "compilateur" à gauche de l'éditeur de liens copier
  -DALLEGRO_STATICLINK
cliquer "OK"
*******************************************************************************/

