#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
/*#include <unistd.h>*/

#include "SDL.h"
#include "SDL_timer.h"

#include "Outils.h"
#include "Effets.h"

/*
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  FONCTION : ZoomOver()                                                    |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  DESCRIPTION : Zoom/deZoom une image source dans une image destination    |
    |                en fonction du facteur de Zoom                             |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  PARAMETRES : StructImage_t *p_pt_Images, StructImage_t *p_pt_Ecran,      |
    |               unsigned short l_c_Pas                                      |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  CODE DE RETOUR : Aucun                                                   |
    |                                                                           |
    +---------------------------------------------------------------------------+
*/

void ZoomOver( StructImage_t *p_pt_Images, StructImage_t *p_pt_Ecran, char p_c_Pas )
{

  long l_l_PositionSourceX = 0, l_l_PositionSourceY = 0;
  long l_l_PositionDestinationX = 0, l_l_PositionDestinationY = 0;
  long l_l_PositionX = 0, l_l_PositionY = 0;
  short l_s_CompteurX = 0, l_s_CompteurY = 0;
  float l_f_RapportLH = 0.0;
  unsigned short l_us_LargeurMax = 0, l_us_HauteurMax = 0;
  unsigned short *l_pus_Source = NULL , *l_pus_Destination = NULL;
  unsigned short l_us_Pas = 0;
  BOOL l_boo_FlagOver = TRUE;

  l_f_RapportLH = p_pt_Ecran->Largeur / ( float )p_pt_Ecran->Hauteur;
  l_us_LargeurMax = p_pt_Ecran->Largeur;
  l_us_HauteurMax = p_pt_Ecran->Hauteur;

  if( p_c_Pas < 0 )
    {
      l_boo_FlagOver = TRUE;
      l_us_Pas = p_pt_Ecran->Hauteur;
    }
  else 
    {
      l_boo_FlagOver = FALSE;
      l_us_Pas = 0;
    }

  while( WaitKey() != TRUE )
    {
      l_pus_Source = ( unsigned short * ) p_pt_Images->DonneesImage->pixels;
      l_pus_Destination = ( unsigned short * ) p_pt_Ecran->DonneesImage->pixels;
      
      if( SDL_MUSTLOCK( p_pt_Ecran->DonneesImage ) )
        { 
          if( SDL_LockSurface( p_pt_Ecran->DonneesImage ) < OK )
            fprintf( stderr, "Impossible de locker l'ecran\n" );
          return ;
        } 
      
      l_l_PositionX = ( short ) ( l_us_LargeurMax - l_us_Pas * l_f_RapportLH ) >> 1;  /* --Centrage X avec correction = Larheur / Hauteur -- */
      l_l_PositionY = ( l_us_LargeurMax -1 ) - l_l_PositionX;                /* -- Point final en X -- */
      
      l_l_PositionSourceY = ( ( l_us_HauteurMax - l_us_Pas ) >>1 ) <<8;      /* -- Centrage Y  -- */
      l_l_PositionDestinationY = ( l_us_Pas <<8 ) / l_us_HauteurMax;           /* -- Coefficient de capture des lignes -- */
      l_l_PositionDestinationX = ( ( l_l_PositionY - l_l_PositionX ) <<8 ) / l_us_LargeurMax;      /* -- Coefficient de capture des colonnes -- */
      
      for( l_s_CompteurY = 0 ; l_s_CompteurY < l_us_HauteurMax ; l_s_CompteurY++ ) /* -- Zoom par rapport a Y -- */
        {
          l_l_PositionSourceX = ( ( l_l_PositionSourceY >>8 ) * l_us_LargeurMax + l_l_PositionX ) <<8;  /* -- Calcul les colonnes -- */
          
          for( l_s_CompteurX = 0 ; l_s_CompteurX < l_us_LargeurMax ; l_s_CompteurX++ )
            {
              //*( l_pus_Destination++ ) = l_pus_Source[ l_l_PositionSourceX >>8 ];
              if( ( ( l_l_PositionSourceX >> 8 ) > 0 ) && ( ( l_l_PositionSourceX >> 8 ) < ( p_pt_Ecran->Largeur * p_pt_Ecran->Hauteur ) ) )
				  if( ( p_pt_Ecran->Largeur * l_s_CompteurY + l_s_CompteurX ) <= p_pt_Ecran->Hauteur * p_pt_Ecran->Largeur * 3 )
					  l_pus_Destination[ p_pt_Ecran->Largeur * l_s_CompteurY + l_s_CompteurX ] = l_pus_Source[ l_l_PositionSourceX >>8 ];

              l_l_PositionSourceX += l_l_PositionDestinationX; /* -- Interpole lineairement les colonnes -- */
            }
              l_l_PositionSourceY += l_l_PositionDestinationY; /* -- Interpole lineairement les lignes -- */
        }
      
      if( SDL_MUSTLOCK( p_pt_Ecran->DonneesImage ) )
        SDL_UnlockSurface( p_pt_Ecran->DonneesImage );  
      SDL_Flip( p_pt_Ecran->DonneesImage );
      
      l_us_Pas += p_c_Pas;
      if( l_boo_FlagOver == TRUE )
        {
          if( l_us_Pas < 1 )
            break;
        }
      else
        {
          if( l_us_Pas > p_pt_Ecran->Hauteur )
            break;
        }            
    }
}

/*
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  FONCTION : FadeOut()                                                     |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  DESCRIPTION : Reduit le Nb de couleur jusqu'au noir total                |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  PARAMETRES : StructImage_t *p_pt_Images, int Pas                         |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  CODE DE RETOUR : Aucun                                                   |
    |                                                                           |
    +---------------------------------------------------------------------------+
*/

void FadeOut( StructImage_t *p_pt_Image, float p_f_Pas )
{
  unsigned short *l_pus_Buffer = NULL;
  unsigned long l_ul_CouleurPixel = 0;
  unsigned char l_uc_Rouge = 0, l_uc_Vert = 0, l_uc_Bleu = 0;
  unsigned long l_ul_Compteur = 0;
  unsigned long l_ul_Rouge = 0, l_ul_Vert = 0, l_ul_Bleu = 0, l_ul_NbTotalPixel = p_pt_Image->Largeur * p_pt_Image->Hauteur;

  
  while( WaitKey() != TRUE )
    {
      l_pus_Buffer = ( unsigned short * ) p_pt_Image->DonneesImage->pixels;
      l_ul_Rouge = l_ul_Vert = l_ul_Bleu = 0;
      
      if( SDL_MUSTLOCK( p_pt_Image->DonneesImage ) )
        { 
          if( SDL_LockSurface( p_pt_Image->DonneesImage ) < OK )
            fprintf( stderr, "Impossible de locker l'ecran\n" );
          return ;
        } 
      
      for( l_ul_Compteur = 0 ; l_ul_Compteur < l_ul_NbTotalPixel ; l_ul_Compteur++ )
        {
          l_ul_CouleurPixel = *l_pus_Buffer;
          SDL_GetRGB( l_ul_CouleurPixel, p_pt_Image->DonneesImage->format, &l_uc_Rouge, &l_uc_Vert, &l_uc_Bleu );
          
          if( l_uc_Rouge > p_f_Pas ) /* -- Le taux de rouge -- */
              l_uc_Rouge /= p_f_Pas;
          else
              if( l_ul_Rouge < l_ul_NbTotalPixel )
	 l_ul_Rouge++;
          
          if( l_uc_Vert > p_f_Pas ) /* -- Le taux de vert -- */
              l_uc_Vert /= p_f_Pas;
          else
              if( l_ul_Vert < l_ul_NbTotalPixel )
	 l_ul_Vert++;
          
          if( l_uc_Bleu > p_f_Pas ) /* -- Le taux de bleu -- */
              l_uc_Bleu /= p_f_Pas;
          else
              if( l_ul_Bleu < l_ul_NbTotalPixel )
	 l_ul_Bleu++;

          l_ul_CouleurPixel = SDL_MapRGB( p_pt_Image->DonneesImage->format, l_uc_Rouge, l_uc_Vert, l_uc_Bleu );
          
          *l_pus_Buffer = l_ul_CouleurPixel;
          l_pus_Buffer++;
          
        } /* -- Fin du for() -- */
      
      if( SDL_MUSTLOCK( p_pt_Image->DonneesImage ) )
        SDL_UnlockSurface( p_pt_Image->DonneesImage );  
      SDL_Flip( p_pt_Image->DonneesImage );
      
      if( ( l_ul_Rouge >= l_ul_NbTotalPixel ) && ( l_ul_Vert >= l_ul_NbTotalPixel ) && ( l_ul_Bleu >= l_ul_NbTotalPixel ) )
        break;
    }
}

/*
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  FONCTION : Ecoule()                                                      |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  DESCRIPTION : Ecoule l'ecran en faisant apparaitre le suivant            |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  PARAMETRES : StructImage_t *p_pt_Ecran1,StructImage_t *p_pt_Ecran2,      |
    |               unsigned char p_uc_Pas                                      |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  CODE DE RETOUR : Aucun                                                   |
    |                                                                           |
    +---------------------------------------------------------------------------+
*/

void Ecoule( StructImage_t *p_pt_Ecran1, StructImage_t *p_pt_Ecran2, unsigned char p_uc_Pas )
{
  SDL_Surface *l_sdl_CopieEcran1 = NULL;
  SDL_Rect l_sdl_CoordSource, l_sdl_CoordDest;
  unsigned char l_uc_LargeurBande = 4;
  unsigned short l_us_NbCollone = p_pt_Ecran1->Largeur / l_uc_LargeurBande;
  unsigned char *l_puc_Pas = NULL, l_uc_FlagOk = 1;
  unsigned short l_us_Compteur = 0, l_us_Compteur2 = 0, *l_pus_CoordY;
  

  l_puc_Pas = ( unsigned char * ) malloc( sizeof( unsigned char ) * l_us_NbCollone);
  if( l_puc_Pas == NULL )
    {
      fprintf( stderr, "Erreur dans l'allocation(1) de la fonction 'Ecoule()'\n" );
      return;
    }
  l_pus_CoordY = ( unsigned short * ) malloc( sizeof( unsigned short ) * l_us_NbCollone );
  if( l_pus_CoordY == NULL )
    {
      fprintf( stderr, "Erreur dans l'allocation(2) de la fonction 'Ecoule()'\n" );
      return;
    }

  for( l_us_Compteur = 0 ; l_us_Compteur < l_us_NbCollone ; l_us_Compteur++ )
    {
      while( ( l_puc_Pas[ l_us_Compteur ] = (unsigned short ) ( 10.0 * rand() / ( RAND_MAX + 1.0 ) ) ) < 1 ); /* -- Random de 1 a 10 -- */ 
      l_pus_CoordY[ l_us_Compteur ] = 0;
    }

  l_sdl_CopieEcran1 = SDL_CreateRGBSurface( SDL_HWSURFACE, p_pt_Ecran1->Largeur, p_pt_Ecran1->Hauteur, p_pt_Ecran1->Bpp, 0, 0, 0, 0 );
  SDL_BlitSurface( p_pt_Ecran1->DonneesImage, &p_pt_Ecran1->Coords, l_sdl_CopieEcran1, &p_pt_Ecran1->Coords );
  l_sdl_CoordSource.x = 0;
  l_sdl_CoordSource.y = 0;
  l_sdl_CoordSource.w = l_uc_LargeurBande;
  l_sdl_CoordSource.h = p_pt_Ecran1->Hauteur;

  l_sdl_CoordDest.x = 0;
  l_sdl_CoordDest.y = 0;
  l_sdl_CoordDest.w = l_uc_LargeurBande;
  l_sdl_CoordDest.h = p_pt_Ecran1->Hauteur;

  while( ( l_uc_FlagOk < l_us_NbCollone ) && ( WaitKey() != TRUE ) )
    {
        /* -- Test s'il faut faire apparaitre l'ecran suivant ou non -- */
      if( p_pt_Ecran2 != NULL )
        SDL_BlitSurface( p_pt_Ecran2->DonneesImage, &p_pt_Ecran1->Coords, p_pt_Ecran1->DonneesImage, &p_pt_Ecran1->Coords );
      else
        SDL_FillRect( p_pt_Ecran1->DonneesImage, &p_pt_Ecran1->Coords, SDL_MapRGB( p_pt_Ecran1->DonneesImage->format, 0, 0, 0 ) );
      
       for( l_us_Compteur2 = 0 ; l_us_Compteur2 < l_us_NbCollone ; l_us_Compteur2++ )
         {
           SDL_BlitSurface( l_sdl_CopieEcran1, &l_sdl_CoordSource, p_pt_Ecran1->DonneesImage, &l_sdl_CoordDest );
           l_pus_CoordY[ l_us_Compteur2 ] += l_puc_Pas[ l_us_Compteur2 ] + p_uc_Pas;
           l_sdl_CoordDest.y = l_pus_CoordY[ l_us_Compteur2 ];
           l_sdl_CoordSource.x += l_uc_LargeurBande;
           l_sdl_CoordDest.x = l_sdl_CoordSource.x; 
         }

      if( l_sdl_CoordDest.y > p_pt_Ecran1->Hauteur )
        l_uc_FlagOk++;
      SDL_Flip( p_pt_Ecran1->DonneesImage );
      l_sdl_CoordSource.x = 0;
      l_sdl_CoordDest.x = l_sdl_CoordSource.x; 

      }

  SDL_FreeSurface( l_sdl_CopieEcran1 );
  if( l_puc_Pas != NULL )
      free( l_puc_Pas );
  if( l_pus_CoordY != NULL )
    free( l_pus_CoordY );
}

/*
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  FONCTION : InitScrollTexteSurRelief()                                    |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  DESCRIPTION : Recupère toutes les ordonnées du relief                    |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  PARAMETRES : StructImage_t *p_pt_Relief                                  |
    |                                                                           |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  CODE DE RETOUR : pointeur sur le tableau des ordonnées                   |
    |                                                                           |
    +---------------------------------------------------------------------------+
*/
unsigned short *InitScrollTexteSurRelief( StructImage_t *p_pt_Relief )
{
  unsigned short *l_pus_Elements = NULL, *l_pus_DonnesRelief = NULL;
  unsigned short l_us_CompteurX = 0, l_us_CompteurY = 0;

  unsigned short l_us_NbElements = p_pt_Relief->Largeur;

  l_pus_Elements = ( unsigned short * ) malloc( sizeof( unsigned short ) * ( l_us_NbElements +1 ) ); /* -- Allocation des N elements -- */
  memset( l_pus_Elements, 0, l_us_NbElements +1 ); /* -- Initialise la memoire -- */

  l_pus_DonnesRelief = ( unsigned short * ) p_pt_Relief->DonneesImage->pixels;

  if( SDL_MUSTLOCK( p_pt_Relief->DonneesImage ) )
    { 
      if( SDL_LockSurface( p_pt_Relief->DonneesImage ) < OK )
        fprintf( stderr, "Impossible de locker l'ecran\n" );
      return NULL;
    } 
  
  for( l_us_CompteurX = 0 ; l_us_CompteurX < l_us_NbElements ; l_us_CompteurX++ )
      for( l_us_CompteurY = 0 ; l_us_CompteurY < p_pt_Relief->Hauteur ; l_us_CompteurY++ )
          if( l_pus_DonnesRelief[ p_pt_Relief->Largeur * l_us_CompteurY + l_us_CompteurX ] != 0 )
            {
              l_pus_Elements[ l_us_CompteurX ] = l_us_CompteurY - 1; /* -- -1 car si pas -1 on tape dans le decore -- */
              break;
            }

  if( SDL_MUSTLOCK( p_pt_Relief->DonneesImage ) )
    SDL_UnlockSurface( p_pt_Relief->DonneesImage );  

  return l_pus_Elements;
}


/*
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  FONCTION : ScrollTexteSurRelief()                                        |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  DESCRIPTION : Fait scroller un sprite sur un relief de droite a gauche   |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  PARAMETRES : StructImage_t *p_pt_Image, StructImage_t *p_pt_Image,       |
    |               StructImage_t *p_pt_Relief, unsigned char p_uc_Pas          |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  CODE DE RETOUR : Aucun                                                   |
    |                                                                           |
    +---------------------------------------------------------------------------+
*/

void ScrollTexteSurRelief( StructImage_t *p_pt_Sprite, StructImage_t *p_pt_Image, StructImage_t *p_pt_Relief, unsigned char p_uc_Pas )
{
  unsigned short *l_pus_DonneesRelief = NULL, l_us_CompteurX = 0, l_us_CompteurSpriteX = 0;
  unsigned short l_us_PosY = 0;
  StructImage_t l_t_ImageTmp;
  SDL_Rect l_sdl_Coords;

  /* -- Init des variables -- */
  l_t_ImageTmp.Coords.x = l_t_ImageTmp.Coords.y = 0;
  l_t_ImageTmp.Largeur = l_t_ImageTmp.Coords.w = p_pt_Image->Largeur;
  l_t_ImageTmp.Hauteur = l_t_ImageTmp.Coords.h = p_pt_Image->Hauteur;
  l_t_ImageTmp.Bpp = p_pt_Image->Bpp;

  p_pt_Sprite->Coords.x = 0;
  p_pt_Sprite->Coords.y = 0;
  p_pt_Sprite->Coords.w = 1;
  p_pt_Sprite->Coords.h = p_pt_Sprite->Hauteur;

  l_t_ImageTmp.DonneesImage = SDL_CreateRGBSurface( SDL_HWSURFACE, p_pt_Image->Largeur, p_pt_Image->Hauteur, p_pt_Image->Bpp, 0, 0, 0, 0 );
  SDL_BlitSurface( p_pt_Image->DonneesImage, &p_pt_Image->Coords, l_t_ImageTmp.DonneesImage, &l_t_ImageTmp.Coords ); /* -- Sauvegarde du fond -- */

  l_pus_DonneesRelief = InitScrollTexteSurRelief( p_pt_Relief );
  l_us_CompteurX = p_pt_Relief->Largeur;

  while( 1 )
    {
      SDL_BlitSurface( l_t_ImageTmp.DonneesImage, &l_t_ImageTmp.Coords, p_pt_Image->DonneesImage, &p_pt_Image->Coords ); /* -- Recopie le fond sauvegarde -- */
      if( l_us_CompteurX < p_uc_Pas )
        {
          l_us_CompteurX = p_pt_Sprite->Largeur;
          while( l_us_CompteurX >= p_uc_Pas )
            { 
              SDL_BlitSurface( l_t_ImageTmp.DonneesImage, &l_t_ImageTmp.Coords, p_pt_Image->DonneesImage, &p_pt_Image->Coords ); /* -- Recopie le fond sauvegarde -- */
              for( l_us_CompteurSpriteX = 0 ; l_us_CompteurSpriteX <= l_us_CompteurX ; l_us_CompteurSpriteX++ )
	 {
	   l_sdl_Coords.x = l_us_CompteurSpriteX - p_uc_Pas;
	   l_sdl_Coords.y =  l_pus_DonneesRelief[ l_us_CompteurSpriteX ] - p_pt_Sprite->Hauteur;
	   l_sdl_Coords.w = 1;
	   l_sdl_Coords.h = p_pt_Sprite->Hauteur;
	   
	   p_pt_Sprite->Coords.x = l_us_CompteurSpriteX + ( p_pt_Sprite->Largeur - l_us_CompteurX );
	   
	   SDL_BlitSurface( p_pt_Sprite->DonneesImage, &p_pt_Sprite->Coords, p_pt_Image->DonneesImage, &l_sdl_Coords );  
	 } /* -- Fin du for -- */
              if( WaitKey() == TRUE )
               break;
              SDL_Flip( p_pt_Image->DonneesImage );
              l_us_CompteurX -= p_uc_Pas;
            } /* -- Fin du while -- */
          return;
        } /* -- Fin du if -- */
      else
        {
          for( l_us_CompteurSpriteX = 0 ; l_us_CompteurSpriteX < p_pt_Sprite->Largeur ; l_us_CompteurSpriteX++ )
            {
              l_us_PosY = l_us_CompteurX + l_us_CompteurSpriteX;
              if( l_us_PosY > p_pt_Image->Largeur )
	 break;
              l_sdl_Coords.x = l_us_CompteurX + l_us_CompteurSpriteX;
              l_sdl_Coords.y =  l_pus_DonneesRelief[ l_us_PosY ] - p_pt_Sprite->Hauteur;
              l_sdl_Coords.w = 1;
              l_sdl_Coords.h = p_pt_Sprite->Hauteur;
              
              p_pt_Sprite->Coords.x = l_us_CompteurSpriteX;
              SDL_BlitSurface( p_pt_Sprite->DonneesImage, &p_pt_Sprite->Coords, p_pt_Image->DonneesImage, &l_sdl_Coords ); 
            } /* -- Fin du for -- */
          if( WaitKey() == TRUE )
            break;
          SDL_Flip( p_pt_Image->DonneesImage );
          l_us_CompteurX -= p_uc_Pas;
        } /* -- Fin du else - */
    } /* -- fin du while infini -- */
  SDL_FreeSurface( l_t_ImageTmp.DonneesImage );
  free( l_pus_DonneesRelief );
}

/*
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  FONCTION : MoveTo()                                                      |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  DESCRIPTION : Deplace un sprite avec clipping                            |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  PARAMETRES : StructImage_t *p_pt_Sprite, StructEcran_t *p_pt_Ecran,      |
    |               short p_s_DebutX, short p_s_DebutY, short p_s_FinX,         |
    |               short p_s_FinY, unsigned char p_uc_Pas                      |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  CODE DE RETOUR : Aucun                                                   |
    |                                                                           |
    +---------------------------------------------------------------------------+
*/

void MoveTo( StructImage_t *p_pt_Sprite, StructImage_t *p_pt_Ecran, short p_s_DebutX, short p_s_DebutY, short p_s_FinX, short p_s_FinY, unsigned char p_uc_Pas )
{
  short l_s_X = 0, l_s_Y = 0;
  int l_i_TmpX = 0, l_i_TmpY = 0;
  int l_i_IncrementX = 0, l_i_IncrementY = 0;
  int l_i_Erreur = 0;
  int l_i_Compteur = 0;
  StructImage_t l_t_ImageTmp;
  SDL_Rect l_sdl_Coords;

  /* -- On initialise nos variables -- */
  l_i_TmpX = abs( p_s_FinX - p_s_DebutX );
  l_i_TmpY = abs( p_s_FinY - p_s_DebutY );

  l_t_ImageTmp.Coords.x = l_t_ImageTmp.Coords.y = 0;
  l_t_ImageTmp.Largeur = l_t_ImageTmp.Coords.w = p_pt_Ecran->Largeur;
  l_t_ImageTmp.Hauteur = l_t_ImageTmp.Coords.h = p_pt_Ecran->Hauteur;
  l_t_ImageTmp.Bpp = p_pt_Ecran->Bpp;

  l_sdl_Coords.x = l_sdl_Coords.y = 0;
  l_sdl_Coords.w = p_pt_Sprite->Largeur;
  l_sdl_Coords.h = p_pt_Sprite->Hauteur;

  l_t_ImageTmp.DonneesImage = SDL_CreateRGBSurface( SDL_HWSURFACE, p_pt_Ecran->Largeur, p_pt_Ecran->Hauteur, p_pt_Ecran->Bpp, 0, 0, 0, 0 );
  SDL_BlitSurface( p_pt_Ecran->DonneesImage, &p_pt_Ecran->Coords, l_t_ImageTmp.DonneesImage, &l_t_ImageTmp.Coords );

  if( p_s_DebutX < p_s_FinX )
    l_i_IncrementX = p_uc_Pas;
  else
    l_i_IncrementX = -p_uc_Pas;
  
  if( p_s_DebutY < p_s_FinY )
    l_i_IncrementY = p_uc_Pas;
  else
    l_i_IncrementY = -p_uc_Pas;
  
  /* -- Effectue le deplacement en fonction de la pente -- */
  l_s_X = p_s_DebutX;
  l_s_Y = p_s_DebutY;
  
  if( l_i_TmpX > l_i_TmpY )
    {
      l_i_Erreur = l_i_TmpX / 2;     /* -- c'est plus esthetique comme ca -- */
      for( l_i_Compteur = 0 ; l_i_Compteur < l_i_TmpX ; l_i_Compteur += p_uc_Pas )
        {
          
          l_s_X += l_i_IncrementX;
          l_i_Erreur += l_i_TmpY;
          if( l_i_Erreur > l_i_TmpX )
            {
              l_i_Erreur -= l_i_TmpX;
              l_s_Y += l_i_IncrementY;
            }
          l_sdl_Coords.x = l_s_X;
          l_sdl_Coords.y = l_s_Y;
          SDL_BlitSurface( l_t_ImageTmp.DonneesImage, &l_t_ImageTmp.Coords , p_pt_Ecran->DonneesImage, &p_pt_Ecran->Coords );
          SDL_BlitSurface( p_pt_Sprite->DonneesImage, &p_pt_Sprite->Coords , p_pt_Ecran->DonneesImage, &l_sdl_Coords );
          SDL_Flip( p_pt_Ecran->DonneesImage );
          if( WaitKey() == TRUE )
            break;
        }
    }
  else
    {
      l_i_Erreur = l_i_TmpY / 2;     /* -- c'est plus esthetique comme ca -- */
      for( l_i_Compteur = 0 ; l_i_Compteur < l_i_TmpY ; l_i_Compteur += p_uc_Pas )
        {
          l_s_Y += l_i_IncrementY;
          l_i_Erreur += l_i_TmpX;
          if( l_i_Erreur > l_i_TmpY )
            {
              l_i_Erreur -= l_i_TmpY;
              l_s_X += l_i_IncrementX;
            }
          l_sdl_Coords.x = l_s_X;
          l_sdl_Coords.y = l_s_Y;
          SDL_BlitSurface( l_t_ImageTmp.DonneesImage, &l_t_ImageTmp.Coords , p_pt_Ecran->DonneesImage, &p_pt_Ecran->Coords );
          SDL_BlitSurface( p_pt_Sprite->DonneesImage, &p_pt_Sprite->Coords , p_pt_Ecran->DonneesImage, &l_sdl_Coords );
          SDL_Flip( p_pt_Ecran->DonneesImage );
          if( WaitKey() == TRUE )
            break;
        }
    }
  SDL_FreeSurface( l_t_ImageTmp.DonneesImage );
}

/*
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  FONCTION : Flash()                                                       |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  DESCRIPTION : Affiche plusieurs flash a une certaine frequence           |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  PARAMETRES : StructImage_t *p_pt_Destination, unsigned char p_uc_NbFlash,|
    |               unsigned char p_uc_Frequence, unsigned char p_uc_Rouge,     |
    |               unsigned char p_uc_Vert, unsigned char p_uc_Bleu            |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  CODE DE RETOUR : Aucun                                                   |
    |                                                                           |
    +---------------------------------------------------------------------------+
*/
void Flash( StructImage_t *p_pt_Destination, unsigned char p_uc_NbFlash, unsigned short p_us_Frequence, unsigned char p_uc_Rouge, unsigned char p_uc_Vert, unsigned char p_uc_Bleu )
{
  StructImage_t l_t_ImageTmp;
  SDL_Surface *l_sdl_ImageFlash = NULL;
  
  l_t_ImageTmp.DonneesImage = SDL_CreateRGBSurface( SDL_HWSURFACE, p_pt_Destination->Largeur, p_pt_Destination->Hauteur, p_pt_Destination->Bpp, 0, 0, 0, 0 );
  l_sdl_ImageFlash = SDL_CreateRGBSurface( SDL_HWSURFACE, p_pt_Destination->Largeur, p_pt_Destination->Hauteur, p_pt_Destination->Bpp, 0, 0, 0, 0 );
  SDL_FillRect( l_sdl_ImageFlash, &p_pt_Destination->Coords, SDL_MapRGB( l_sdl_ImageFlash->format, p_uc_Rouge, p_uc_Vert, p_uc_Bleu ) ); 

  SDL_SetAlpha( l_sdl_ImageFlash, SDL_SRCALPHA, 128 ); /* -- 128 opacite a 50% -- */

  /* -- Init des dimentions de la copie du buffer destination -- */

  SDL_BlitSurface( p_pt_Destination->DonneesImage, &p_pt_Destination->Coords, l_t_ImageTmp.DonneesImage, &p_pt_Destination->Coords );

  while( WaitKey() != TRUE )
    {
      SDL_BlitSurface( l_sdl_ImageFlash, &p_pt_Destination->Coords, p_pt_Destination->DonneesImage, &p_pt_Destination->Coords );
      SDL_Flip( p_pt_Destination->DonneesImage );
      WaitDelayAndWaitKey( p_us_Frequence /2 );

      SDL_BlitSurface( l_t_ImageTmp.DonneesImage, &p_pt_Destination->Coords, p_pt_Destination->DonneesImage, &p_pt_Destination->Coords );
      SDL_Flip( p_pt_Destination->DonneesImage );
      WaitDelayAndWaitKey( p_us_Frequence /2 );

      p_uc_NbFlash--;
      if( p_uc_NbFlash < 1 )
        break;
    }
  SDL_BlitSurface( p_pt_Destination->DonneesImage, &p_pt_Destination->Coords, l_t_ImageTmp.DonneesImage, &l_t_ImageTmp.Coords );

  SDL_Flip( p_pt_Destination->DonneesImage );
  SDL_FreeSurface( l_sdl_ImageFlash );
}

/*
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  FONCTION : Zoom()                                                        |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  DESCRIPTION : Zoom/deZoom une image source dans une image destination    |
    |                en fonction du facteur de Zoom                             |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  PARAMETRES : StructImage_t *p_pt_Image                                   |
    |                                                                           |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  CODE DE RETOUR : Aucun                                                   |
    |                                                                           |
    +---------------------------------------------------------------------------+
*/

int Zoom( StructImage_t *p_pt_Image )
{
  return 1;
}


/*
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  FONCTION : WarpApparence()                                               |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  DESCRIPTION : Apparition/Disparition en 'Warp' d'une image               |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  PARAMETRES : StructImage_t *p_pt_Warp, StructImage_t *p_pt_Ecran,        |
    |               StructImage_t *p_pt_ImgSuivante, unsigned char p_uc_Pas     |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  CODE DE RETOUR : Aucun                                                   |
    |                                                                           |
    +---------------------------------------------------------------------------+
*/

void WarpApparence( StructImage_t *p_pt_Warp, StructImage_t *p_pt_Ecran, StructImage_t *p_pt_ImgSuivante, unsigned char p_uc_Pas )
{
  unsigned long  l_ul_Compteur = 0;
  unsigned short *l_pus_DonneesSource = NULL;
  unsigned short *l_pus_DonneesDestination = NULL;
  unsigned short *l_pus_DonneesImgSuivante = NULL;
  unsigned long l_ul_TauxCouleur = 0;

  while( WaitKey() != TRUE )
    {
      l_pus_DonneesSource = ( unsigned short * ) p_pt_Warp->DonneesImage->pixels; /* -- Pointeur directe sur les donnees -- */
      l_pus_DonneesDestination = ( unsigned short * ) p_pt_Ecran->DonneesImage->pixels; /* -- Pointeur directe sur les donnees -- */
      if( p_pt_ImgSuivante != NULL )
        l_pus_DonneesImgSuivante = ( unsigned short * ) p_pt_ImgSuivante->DonneesImage->pixels; /* -- Pointeur directe sur les donnees -- */        
      
      if( SDL_MUSTLOCK( p_pt_Ecran->DonneesImage ) )
        { 
          if( SDL_LockSurface( p_pt_Ecran->DonneesImage ) < OK )
            fprintf( stderr, "Impossible de locker l'ecran\n" );
          return ;
        } 
      
      /* -- On efface d'abort que les pixels noirs de la source sur la destination -- */
      for( l_ul_Compteur = 0 ; l_ul_Compteur < p_pt_Ecran->Largeur * p_pt_Ecran->Hauteur ; l_ul_Compteur++ ) /* -- Parcourt toute l'image source -- */
        {
          //if( ( ( *l_pus_DonneesSource ) >> 11 <= l_us_TauxCouleur ) && ( ( *l_pus_DonneesSource ) >> 11 >= l_us_TauxCouleur-4 ) ) 
          if( *l_pus_DonneesSource <= l_ul_TauxCouleur )
            {
              if( p_pt_ImgSuivante != NULL )
	 *l_pus_DonneesDestination = *l_pus_DonneesImgSuivante;
              else
	 *l_pus_DonneesDestination = 0; /* -- On commence a effacer ( 0 = encre noir ) -- */
            }
      
          l_pus_DonneesDestination++;
          l_pus_DonneesSource++;
          l_pus_DonneesImgSuivante++;
        } /* -- Fin du for -- */

      if( SDL_MUSTLOCK( p_pt_Ecran->DonneesImage ) )
        SDL_UnlockSurface( p_pt_Ecran->DonneesImage );  
      SDL_Flip( p_pt_Ecran->DonneesImage );
      
      l_ul_TauxCouleur += 100 * p_uc_Pas;
      if ( l_ul_TauxCouleur >= 65535 )
        return;
    } /* -- Fin du while -- */
}

/*
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  FONCTION : MoveToH()                                                     |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  DESCRIPTION : Deplace un sprite avec clipping dans une direction         |
    |                horozontale                                                |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  PARAMETRES : StructImage_t *p_pt_Sprite, StructEcran_t *p_pt_Ecran,      |
    |               short p_s_DebutX, p_s_FinX, short p_s_PositionY,            |
    |               unsigned char p_uc_Pas                                      |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  CODE DE RETOUR : Aucun                                                   |
    |                                                                           |
    +---------------------------------------------------------------------------+
*/

void MoveToH( StructImage_t *p_pt_Sprite, StructImage_t *p_pt_Ecran, short p_s_DebutX, short p_s_FinX, short p_s_PositionY, unsigned char p_uc_Pas )
{
  char l_c_IncrementX = 0;
  StructImage_t l_t_ImageTmp;
  SDL_Rect l_sdl_Coords;

  /* -- On initialise nos variables -- */
  l_t_ImageTmp.Coords.x = l_t_ImageTmp.Coords.y = 0;
  l_t_ImageTmp.Largeur = l_t_ImageTmp.Coords.w = p_pt_Ecran->Largeur;
  l_t_ImageTmp.Hauteur = l_t_ImageTmp.Coords.h = p_pt_Ecran->Hauteur;
  l_t_ImageTmp.Bpp = p_pt_Ecran->Bpp;

  l_sdl_Coords.x = p_s_DebutX;
  l_sdl_Coords.y = p_s_PositionY;
  l_sdl_Coords.w = p_pt_Sprite->Largeur;
  l_sdl_Coords.h = p_pt_Sprite->Hauteur;

  l_t_ImageTmp.DonneesImage = SDL_CreateRGBSurface( SDL_HWSURFACE, p_pt_Ecran->Largeur, p_pt_Ecran->Hauteur, p_pt_Ecran->Bpp, 0, 0, 0, 0 );
  SDL_BlitSurface( p_pt_Ecran->DonneesImage, &p_pt_Ecran->Coords, l_t_ImageTmp.DonneesImage, &l_t_ImageTmp.Coords );

  if( p_s_DebutX < p_s_FinX )
    l_c_IncrementX = p_uc_Pas;
  else
    l_c_IncrementX = -p_uc_Pas;
  
  while( 1 )
    {
      SDL_BlitSurface( l_t_ImageTmp.DonneesImage, &p_pt_Ecran->Coords, p_pt_Ecran->DonneesImage, &p_pt_Ecran->Coords );

      l_sdl_Coords.x += l_c_IncrementX;
      SDL_BlitSurface( p_pt_Sprite->DonneesImage, &p_pt_Sprite->Coords, p_pt_Ecran->DonneesImage, &l_sdl_Coords );
      SDL_Flip( p_pt_Ecran->DonneesImage );
      if( p_s_DebutX < p_s_FinX )
        {
          if( l_sdl_Coords.x > p_s_FinX )
            break;
        }
      else
        {
          if( l_sdl_Coords.x < p_s_FinX )
            break;
        }
	  if( WaitKey() == TRUE )
		break;
    }
  SDL_FreeSurface( l_t_ImageTmp.DonneesImage );
}


/*
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  FONCTION : MoveToV()                                                     |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  DESCRIPTION : Deplace un sprite avec clipping dans une direction         |
    |                Verticale                                                  |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  PARAMETRES : StructImage_t *p_pt_Sprite, StructEcran_t *p_pt_Ecran,      |
    |               short p_s_DebutY, p_s_FinY, short p_s_PositionX,            |
    |               unsigned char p_uc_Pas                                      |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  CODE DE RETOUR : Aucun                                                   |
    |                                                                           |
    +---------------------------------------------------------------------------+
*/
void MoveToV( StructImage_t *p_pt_Sprite, StructImage_t *p_pt_Ecran, short p_s_DebutY, short p_s_FinY, short p_s_PositionX, unsigned char p_uc_Pas )
{
  char l_c_IncrementY = 0;
  StructImage_t l_t_ImageTmp;
  SDL_Rect l_sdl_Coords;
  short l_s_PositionTmpY = p_s_DebutY;

  /* -- On initialise nos variables -- */
  l_t_ImageTmp.Coords.x = l_t_ImageTmp.Coords.y = 0;
  l_t_ImageTmp.Largeur = l_t_ImageTmp.Coords.w = p_pt_Ecran->Largeur;
  l_t_ImageTmp.Hauteur = l_t_ImageTmp.Coords.h = p_pt_Ecran->Hauteur;
  l_t_ImageTmp.Bpp = p_pt_Ecran->Bpp;

  l_sdl_Coords.x = p_s_PositionX;
  l_sdl_Coords.y = l_s_PositionTmpY;
  l_sdl_Coords.w = p_pt_Sprite->Largeur;
  l_sdl_Coords.h = p_pt_Sprite->Hauteur;

  l_t_ImageTmp.DonneesImage = SDL_CreateRGBSurface( SDL_HWSURFACE, p_pt_Ecran->Largeur, p_pt_Ecran->Hauteur, p_pt_Ecran->Bpp, 0, 0, 0, 0 );
  SDL_BlitSurface( p_pt_Ecran->DonneesImage, &p_pt_Ecran->Coords, l_t_ImageTmp.DonneesImage, &l_t_ImageTmp.Coords );

  if( p_s_DebutY < p_s_FinY )
    l_c_IncrementY = p_uc_Pas;
  else
    l_c_IncrementY = -p_uc_Pas;
  
  while( WaitKey() != TRUE )
    {
      SDL_BlitSurface( l_t_ImageTmp.DonneesImage, &p_pt_Ecran->Coords, p_pt_Ecran->DonneesImage, &p_pt_Ecran->Coords );
      SDL_BlitSurface( p_pt_Sprite->DonneesImage, &p_pt_Sprite->Coords, p_pt_Ecran->DonneesImage, &l_sdl_Coords );
      //SDL_Flip( p_pt_Ecran->DonneesImage );
      SDL_UpdateRect( p_pt_Ecran->DonneesImage, p_pt_Ecran->Coords.x, p_pt_Ecran->Coords.y, p_pt_Ecran->Coords.w, p_pt_Ecran->Coords.h );
      l_s_PositionTmpY += l_c_IncrementY;
	  /*if( l_s_PositionTmpY < 0 )
		  l_sdl_Coords.y = 0;*/
	  l_sdl_Coords.y = l_s_PositionTmpY;
	  l_sdl_Coords.h = p_pt_Ecran->Hauteur - l_sdl_Coords.y;
      if( p_s_DebutY < p_s_FinY )
        {
          if( l_sdl_Coords.y >= p_s_FinY )
            break;
        }
      else
        {
          if( l_sdl_Coords.y <= p_s_FinY )
            break;
        }
    }
  SDL_FreeSurface( l_t_ImageTmp.DonneesImage );
}


/*
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  FONCTION : VideoApparence()                                              |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  DESCRIPTION : Transforme une image en effet d'image de télé              |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  PARAMETRES : StructImage_t *p_pt_Ecran                                   |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  CODE DE RETOUR : Aucun                                                   |
    |                                                                           |
    +---------------------------------------------------------------------------+
*/

void VideoApparence( StructImage_t *p_pt_Ecran )
{
  unsigned short l_us_CompteurX = 0, l_us_CompteurY = 0;
  
  
  unsigned short *l_pus_Donnees = NULL;
  SDL_Surface *l_sdl_ImageTV = NULL;
  
  //l_sdl_ImageTV = SDL_CreateRGBSurface( SDL_HWSURFACE, p_pt_Ecran->Largeur, p_pt_Ecran->Hauteur, p_pt_Ecran->Bpp, 0, 0, 0, 0 );
  l_sdl_ImageTV = SDL_CreateRGBSurface( SDL_HWSURFACE, p_pt_Ecran->Largeur, p_pt_Ecran->Hauteur, p_pt_Ecran->DonneesImage->format->BitsPerPixel, 0, 0, 0, 0 );
  
  l_pus_Donnees = ( unsigned short * ) l_sdl_ImageTV->pixels; /* -- Pointeur directe sur les donnees -- */
  
  
  if( SDL_MUSTLOCK( l_sdl_ImageTV ) )
    { 
      if( SDL_LockSurface( l_sdl_ImageTV ) < OK )
        fprintf( stderr, "Impossible de locker l'ecran\n" );
      return ;
    } 
  /* -- Creation des lignes successives de rouge, vert, bleu -- */
  for( l_us_CompteurY = 0 ; l_us_CompteurY < p_pt_Ecran->Hauteur ; l_us_CompteurY+= 3 ) /* -- 3 car une lign de chaque couleur ( rouge, vert, bleu ) -- */
    {
      for( l_us_CompteurX = 0 ; l_us_CompteurX < p_pt_Ecran->Largeur ; l_us_CompteurX++ )
        *( l_pus_Donnees ++ ) = SDL_MapRGB( l_sdl_ImageTV->format, 255, 0, 0 ); /* -- Rouge -- */
      for( l_us_CompteurX = 0 ; l_us_CompteurX < p_pt_Ecran->Largeur ; l_us_CompteurX++ )
        *( l_pus_Donnees ++ ) = SDL_MapRGB( l_sdl_ImageTV->format, 0, 255, 0 ); /* -- Vert -- */
      for( l_us_CompteurX = 0 ; l_us_CompteurX < p_pt_Ecran->Largeur ; l_us_CompteurX++ )
        *( l_pus_Donnees ++ ) = SDL_MapRGB( l_sdl_ImageTV->format, 0, 0, 255 ); /* -- Bleu -- */
    }
  
  if( SDL_MUSTLOCK( l_sdl_ImageTV ) )
    SDL_UnlockSurface( l_sdl_ImageTV );  
  
  SDL_SetAlpha( l_sdl_ImageTV, SDL_SRCALPHA, 40 ); /* -- 128 opacite a 50% -- */
  
  SDL_BlitSurface( l_sdl_ImageTV, &p_pt_Ecran->Coords, p_pt_Ecran->DonneesImage, &p_pt_Ecran->Coords );
  //  SDL_Flip( p_pt_Ecran->DonneesImage );
  SDL_FreeSurface( l_sdl_ImageTV );
}


/*
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  FONCTION : LigneElectrique()                                             |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  DESCRIPTION : Trace une ligne electrique                                 |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  PARAMETRES : StructImage_t *p_pt_Ecran, short p_s_DebutX,                |
    |               short p_s_DebutY, short p_s_FinX, short p_s_FinY            |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  CODE DE RETOUR : Aucun                                                   |
    |                                                                           |
    +---------------------------------------------------------------------------+
*/
void LigneElectrique( StructImage_t *p_pt_Sprite, StructImage_t *p_pt_Ecran, short p_s_DebutX, short p_s_DebutY, short p_s_FinX, short p_s_FinY )
{
  short l_s_X = 0, l_s_Y = 0;
  int l_i_TmpX = 0, l_i_TmpY = 0;
  int l_i_IncrementX = 0, l_i_IncrementY = 0;
  int l_i_Erreur = 0;
  int l_i_Compteur = 0;
  unsigned char p_uc_Pas = 1;
  StructImage_t l_t_ImageTmp;
  SDL_Rect l_sdl_Coords;

  /* -- On initialise nos variables -- */
  l_i_TmpX = abs( p_s_FinX - p_s_DebutX );
  l_i_TmpY = abs( p_s_FinY - p_s_DebutY );

  l_t_ImageTmp.Coords.x = l_t_ImageTmp.Coords.y = 0;
  l_t_ImageTmp.Largeur = l_t_ImageTmp.Coords.w = p_pt_Ecran->Largeur;
  l_t_ImageTmp.Hauteur = l_t_ImageTmp.Coords.h = p_pt_Ecran->Hauteur;
  l_t_ImageTmp.Bpp = p_pt_Ecran->Bpp;

  l_sdl_Coords.x = l_sdl_Coords.y = 0;
  l_sdl_Coords.w = p_pt_Sprite->Largeur;
  l_sdl_Coords.h = p_pt_Sprite->Hauteur;

  l_t_ImageTmp.DonneesImage = SDL_CreateRGBSurface( SDL_HWSURFACE, p_pt_Ecran->Largeur, p_pt_Ecran->Hauteur, p_pt_Ecran->Bpp, 0, 0, 0, 0 );
  SDL_BlitSurface( p_pt_Ecran->DonneesImage, &p_pt_Ecran->Coords, l_t_ImageTmp.DonneesImage, &l_t_ImageTmp.Coords );

  if( p_s_DebutX < p_s_FinX )
    l_i_IncrementX = p_uc_Pas;
  else
    l_i_IncrementX = -p_uc_Pas;
  
  if( p_s_DebutY < p_s_FinY )
    l_i_IncrementY = p_uc_Pas;
  else
    l_i_IncrementY = -p_uc_Pas;
  
  /* -- Effectue le deplacement en fonction de la pente -- */
  l_s_X = p_s_DebutX;
  l_s_Y = p_s_DebutY;
  
  SDL_BlitSurface( l_t_ImageTmp.DonneesImage, &l_t_ImageTmp.Coords , p_pt_Ecran->DonneesImage, &p_pt_Ecran->Coords );
  if( l_i_TmpX > l_i_TmpY )
    {
      l_i_Erreur = l_i_TmpX / 2;     /* -- c'est plus esthetique comme ca -- */
      for( l_i_Compteur = 0 ; l_i_Compteur < l_i_TmpX ; l_i_Compteur += p_uc_Pas )
        {
          
          l_s_X += l_i_IncrementX;
          l_i_Erreur += l_i_TmpY;
          if( l_i_Erreur > l_i_TmpX )
            {
              l_i_Erreur -= l_i_TmpX;
              l_s_Y += l_i_IncrementY;
            }
          l_sdl_Coords.x = l_s_X;
          l_sdl_Coords.y = l_s_Y;
          //SDL_BlitSurface( l_t_ImageTmp.DonneesImage, &l_t_ImageTmp.Coords , p_pt_Ecran->DonneesImage, &p_pt_Ecran->Coords );
          SDL_BlitSurface( p_pt_Sprite->DonneesImage, &p_pt_Sprite->Coords , p_pt_Ecran->DonneesImage, &l_sdl_Coords );
          if( WaitKey() == TRUE )
            break;
        }
    }
  else
    {
      l_i_Erreur = l_i_TmpY / 2;     /* -- c'est plus esthetique comme ca -- */
      for( l_i_Compteur = 0 ; l_i_Compteur < l_i_TmpY ; l_i_Compteur += p_uc_Pas )
        {
          l_s_Y += l_i_IncrementY;
          l_i_Erreur += l_i_TmpX;
          if( l_i_Erreur > l_i_TmpY )
            {
              l_i_Erreur -= l_i_TmpY;
              l_s_X += l_i_IncrementX;
            }
          l_sdl_Coords.x = l_s_X;
          l_sdl_Coords.y = l_s_Y;
          //SDL_BlitSurface( l_t_ImageTmp.DonneesImage, &l_t_ImageTmp.Coords , p_pt_Ecran->DonneesImage, &p_pt_Ecran->Coords );
          SDL_BlitSurface( p_pt_Sprite->DonneesImage, &p_pt_Sprite->Coords , p_pt_Ecran->DonneesImage, &l_sdl_Coords );
          if( WaitKey() == TRUE )
            break;
        }
    }
  //SDL_Flip( p_pt_Ecran->DonneesImage );
  SDL_FreeSurface( l_t_ImageTmp.DonneesImage );
  
}

/*
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  FONCTION : AfficheBulle()                                                |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  DESCRIPTION : Affiche une Bulle sur un fond                              |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  PARAMETRES : unsigned short p_us_PosX, unsigned short p_us_PosY,         |
		|               StructImage_t *p_pt_Bulle, StructImage_t *p_pt_Fond     |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  CODE DE RETOUR : Aucun                                                   |
    |                                                                           |
    +---------------------------------------------------------------------------+
*/

void AfficheBulle( short p_s_PosX, short p_s_PosY, StructImage_t *p_pt_Bulle, StructImage_t *p_pt_Ecran )
{
  unsigned short *l_pus_SourceWater = NULL, *l_pus_Destination = NULL;
  unsigned short l_us_CompteurX = 0, l_us_CompteurY = 0, l_us_CompteurTmp1 = 0;
  unsigned char l_uc_Bleu1 = 0, l_uc_Bleu2 = 0;
  unsigned char l_uc_Rouge2 = 0, l_uc_Rouge1 = 0;
  unsigned char l_uc_Vert2 = 0, l_uc_Vert1 = 0;
  unsigned short l_us_TotalCouleur = 0, l_us_CouleurDest = 0;

  l_pus_SourceWater = ( unsigned short * ) p_pt_Bulle->DonneesImage->pixels;
  l_pus_Destination = ( unsigned short * ) p_pt_Ecran->DonneesImage->pixels;
  
  if( SDL_MUSTLOCK( p_pt_Ecran->DonneesImage ) )
    { 
      if( SDL_LockSurface( p_pt_Ecran->DonneesImage ) < OK )
        fprintf( stderr, "Impossible de locker l'ecran\n" );
      return ;
    } 
  if( SDL_MUSTLOCK( p_pt_Bulle->DonneesImage ) )
    { 
      if( SDL_LockSurface( p_pt_Bulle->DonneesImage ) < OK )
        fprintf( stderr, "Impossible de locker l'ecran\n" );
      return ;
    } 
  
  if( p_s_PosY < 0 )
    {
      l_us_CompteurY = abs( p_s_PosY );
      p_s_PosY = 0;
    }
  else
    l_us_CompteurY = 0;
  
  
  l_us_CompteurTmp1 = 0;
  
  for( ; l_us_CompteurY < p_pt_Bulle->Hauteur ; l_us_CompteurY++ )
    {
      for( l_us_CompteurX = 0 ; l_us_CompteurX < p_pt_Bulle->Largeur ; l_us_CompteurX++ )
        {
          if( l_pus_SourceWater[ p_pt_Bulle->Largeur * l_us_CompteurY + l_us_CompteurX ] != 0 )
            {
			  SDL_GetRGB( l_pus_SourceWater[ p_pt_Bulle->Largeur * (l_us_CompteurY +1 )+ l_us_CompteurX ], p_pt_Bulle->DonneesImage->format, &l_uc_Rouge2, &l_uc_Vert2, &l_uc_Bleu2 );
              SDL_GetRGB( l_pus_SourceWater[ p_pt_Bulle->Largeur * l_us_CompteurY + ( l_us_CompteurX +1 ) ], p_pt_Bulle->DonneesImage->format, &l_uc_Rouge2, &l_uc_Vert2, &l_uc_Bleu1 );
              l_us_TotalCouleur = ( l_uc_Bleu1 + l_uc_Bleu2 ) / 2;
              
			  if( p_pt_Ecran->Largeur * ( p_s_PosY + l_us_CompteurTmp1 + l_us_TotalCouleur ) + ( p_s_PosX + l_us_CompteurX + l_us_TotalCouleur ) < p_pt_Ecran->Largeur * p_pt_Ecran->Hauteur )
			  {
			    l_us_CouleurDest = l_pus_Destination[ p_pt_Ecran->Largeur * ( p_s_PosY + l_us_CompteurTmp1 + l_us_TotalCouleur ) + ( p_s_PosX + l_us_CompteurX + l_us_TotalCouleur ) ];
			    l_pus_Destination[ p_pt_Ecran->Largeur * ( p_s_PosY + l_us_CompteurTmp1 ) + ( p_s_PosX + l_us_CompteurX ) ] = l_us_CouleurDest;
			  }
            }
        }
      l_us_CompteurTmp1++;
    }
  
  if( SDL_MUSTLOCK( p_pt_Ecran->DonneesImage ) )
    SDL_UnlockSurface( p_pt_Ecran->DonneesImage );  
  if( SDL_MUSTLOCK( p_pt_Bulle->DonneesImage ) )
    SDL_UnlockSurface( p_pt_Bulle->DonneesImage );  
}


/*
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  FONCTION : NeigeTV()                                                     |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  DESCRIPTION : Affiche de la neige dans un buffer                         |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  PARAMETRES : SDL_Surface *p_p_Buffer, SDL_Rect p_sdl_Coords              |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  CODE DE RETOUR : Aucun                                                   |
    |                                                                           |
    +---------------------------------------------------------------------------+
*/
void NeigeTV( SDL_Surface *p_p_Buffer, SDL_Rect p_sdl_Coords )
{
  unsigned short *l_p_Buffer = NULL;
  unsigned short l_us_Compteur = 0, l_us_CouleurNeige = 0; /* -- Couleur blanche -- */
  static int l_i_VariableMagique = 0x12345, l_i_VariableTmp;
  
  l_p_Buffer = ( unsigned short * ) p_p_Buffer->pixels;
  
  if( SDL_MUSTLOCK( p_p_Buffer ) )
    { 
      if( SDL_LockSurface( p_p_Buffer ) < OK )
        fprintf( stderr, "Impossible de locker l'ecran\n" );
      return ;
    } 
  for( l_us_Compteur = 0 ; l_us_Compteur < p_sdl_Coords.w * p_sdl_Coords.h ; l_us_Compteur++ )
    {
      l_us_CouleurNeige = l_i_VariableMagique;
      l_us_CouleurNeige >>= 3;
      l_us_CouleurNeige ^= l_i_VariableMagique;
      l_i_VariableTmp = l_us_CouleurNeige & 1;
      l_us_CouleurNeige >>= 1;
      l_i_VariableMagique >>= 1;
      l_i_VariableMagique |= ( l_i_VariableTmp << 30 );
      l_us_CouleurNeige &= 0xFF;
      l_p_Buffer[ l_us_Compteur ] = ( l_us_CouleurNeige << 11 ) | ( l_us_CouleurNeige << 5 ) | l_us_CouleurNeige;
    }
  if( SDL_MUSTLOCK( p_p_Buffer ) )
    SDL_UnlockSurface( p_p_Buffer );  
}

/*
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  FONCTION : Flou()                                                        |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  DESCRIPTION : Smooth un buffer                                           |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  PARAMETRES : StructImage_t *p_pt_Buffer, unsigned short p_us_DebutX,     |
    |               unsigned short p_us_DebutY, unsigned short p_us_Largeur,    |
    |               unsigned short p_us_Hauteur, unsigned char p_uc_PasFlou     |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  CODE DE RETOUR : OK si le flou est fini, NOK sinon                       |
    |                                                                           |
    +---------------------------------------------------------------------------+
*/

int  Flou( StructImage_t *p_pt_Buffer, unsigned short p_us_DebutX, unsigned short p_us_DebutY, unsigned short p_us_Largeur, unsigned short p_us_Hauteur, unsigned char p_uc_PasFlou )
{
  unsigned char l_uc_Rouge = 0, l_uc_Vert = 0, l_uc_Bleu = 0, l_uc_NbPasse = 0;
  unsigned short l_us_SommeRouge = 0, l_us_SommeVert = 0, l_us_SommeBleu = 0;
  unsigned short l_us_CompteurX = 0, l_us_CompteurY = 0;
  unsigned long l_ul_FlagFini = 0;
  unsigned short *l_pus_Buffer = NULL;
  
  l_pus_Buffer = ( unsigned short * ) p_pt_Buffer->DonneesImage->pixels;
  
  if( SDL_MUSTLOCK( p_pt_Buffer->DonneesImage ) )
    { 
      if( SDL_LockSurface( p_pt_Buffer->DonneesImage ) < OK )
        fprintf( stderr, "Impossible de locker l'ecran\n" );
      return NOK;
    } 
  
  for( l_uc_NbPasse = 0 ; l_uc_NbPasse < p_uc_PasFlou ; l_uc_NbPasse++ )
    {
      for( l_us_CompteurY = 0 ; l_us_CompteurY < p_us_Hauteur ; l_us_CompteurY++ )
        for( l_us_CompteurX = 0 ; l_us_CompteurX < p_us_Largeur ; l_us_CompteurX++ )
          {
            if( ( l_us_CompteurX + p_us_DebutX ) == 0 )
              {
	 l_uc_Rouge = 0;
	 l_uc_Vert = 0;
	 l_uc_Bleu = 0;
              }
            else
              SDL_GetRGB( l_pus_Buffer[ p_us_Largeur * ( l_us_CompteurY + p_us_DebutY ) + ( ( l_us_CompteurX + p_us_DebutX ) -1 ) ], p_pt_Buffer->DonneesImage->format, &l_uc_Rouge, &l_uc_Vert, &l_uc_Bleu );
            l_us_SommeRouge += l_uc_Rouge;
            l_us_SommeVert += l_uc_Vert;
            l_us_SommeBleu += l_uc_Bleu;
            
            SDL_GetRGB( l_pus_Buffer[ p_us_Largeur * ( l_us_CompteurY + p_us_DebutY ) + ( l_us_CompteurX + p_us_DebutX ) ], p_pt_Buffer->DonneesImage->format, &l_uc_Rouge, &l_uc_Vert, &l_uc_Bleu );
            l_us_SommeRouge += l_uc_Rouge;
            l_us_SommeVert += l_uc_Vert;
            l_us_SommeBleu += l_uc_Bleu;
            
            if( ( l_us_CompteurX + p_us_DebutX ) == p_us_Largeur -1 )
              {
	 l_uc_Rouge = 0;
	 l_uc_Vert = 0;
	 l_uc_Bleu = 0;
              }
            else
              SDL_GetRGB( l_pus_Buffer[ p_us_Largeur * ( l_us_CompteurY + p_us_DebutY ) + ( ( l_us_CompteurX + p_us_DebutX ) +1 ) ], p_pt_Buffer->DonneesImage->format, &l_uc_Rouge, &l_uc_Vert, &l_uc_Bleu );
            l_us_SommeRouge += l_uc_Rouge;
            l_us_SommeVert += l_uc_Vert;
            l_us_SommeBleu += l_uc_Bleu;
            
            l_uc_Rouge = l_us_SommeRouge /3;
            l_uc_Vert = l_us_SommeVert /3;
            l_uc_Bleu = l_us_SommeBleu /3;
            
            l_pus_Buffer[ p_us_Largeur * ( l_us_CompteurY + p_us_DebutY ) + ( l_us_CompteurX + p_us_DebutX ) ] = SDL_MapRGB( p_pt_Buffer->DonneesImage->format, l_uc_Rouge, l_uc_Vert, l_uc_Bleu );
            
            if( ( l_uc_Rouge == 0 ) && ( l_uc_Vert == 0 ) && ( l_uc_Bleu == 0 ) )
              l_ul_FlagFini++;
            
            l_us_SommeRouge = l_us_SommeVert = l_us_SommeBleu = 0;
            
          }
    }
  
  if( SDL_MUSTLOCK( p_pt_Buffer->DonneesImage ) )
    SDL_UnlockSurface( p_pt_Buffer->DonneesImage );  
  if( l_ul_FlagFini == p_us_Largeur * p_us_Hauteur )
    return OK;
  else
    return NOK;
}

/*
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  FONCTION : PrepareGeneriqueStarWars()                                    |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  DESCRIPTION : Prepare un tableau  pour y stocker les coordonnees X et Y  |
    |                de la pente                                                |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  PARAMETRES :   short *p_ps_Perspective, short p_s_DebutX,                |
    |                 short p_s_DebutY, short p_s_FinX, short p_s_FinY          |
    |                                                                           |
    +---------------------------------------------------------------------------+
    |                                                                           |
    |  CODE DE RETOUR : Aucun                                                   |
    |                                                                           |
    +---------------------------------------------------------------------------+
*/
void PrepareGeneriqueStarWars( short *p_ps_Perspective, short p_s_DebutX, short p_s_DebutY, short p_s_FinX, short p_s_FinY )
{
  unsigned char l_uc_Pas = 1;
  int l_i_IncrementX = 0, l_i_IncrementY = 0, l_i_TmpX = 0, l_i_TmpY = 0, l_i_Compteur = 0, l_i_Erreur = 0;
  short l_s_X = 0, l_s_Y = 0;
  unsigned short l_us_Compteur1 = 0;

  /* -- On initialise nos variables -- */
  l_i_TmpX = abs( p_s_FinX - p_s_DebutX );
  l_i_TmpY = abs( p_s_FinY - p_s_DebutY );

  if( p_s_DebutX < p_s_FinX )
    l_i_IncrementX = l_uc_Pas;
  else
    l_i_IncrementX = -l_uc_Pas;
  
  if( p_s_DebutY < p_s_FinY )
    l_i_IncrementY = l_uc_Pas;
  else
    l_i_IncrementY = -l_uc_Pas;
  
  /* -- Effectue le deplacement en fonction de la pente -- */
  l_s_X = p_s_DebutX;
  l_s_Y = p_s_DebutY;

  if( l_i_TmpX > l_i_TmpY )
    {
      l_i_Erreur = l_i_TmpX / 2;     /* -- c'est plus esthetique comme ca -- */
      for( l_i_Compteur = 0 ; l_i_Compteur < l_i_TmpX ; l_i_Compteur += l_uc_Pas )
        {
          
          l_s_X += l_i_IncrementX;
          l_i_Erreur += l_i_TmpY;
          if( l_i_Erreur > l_i_TmpX )
            {
              l_i_Erreur -= l_i_TmpX;
              l_s_Y += l_i_IncrementY;
            }
          p_ps_Perspective[ l_us_Compteur1++ ]= l_s_X;
          //p_ps_Perspective[ l_us_Compteur1++ ][ l_us_Compteur2 ] = l_s_Y;
        }
    }
  else
    {
      l_i_Erreur = l_i_TmpY / 2;     /* -- c'est plus esthetique comme ca -- */
      for( l_i_Compteur = 0 ; l_i_Compteur < l_i_TmpY ; l_i_Compteur += l_uc_Pas )
        {
          l_s_Y += l_i_IncrementY;
          l_i_Erreur += l_i_TmpX;
          if( l_i_Erreur > l_i_TmpY )
            {
              l_i_Erreur -= l_i_TmpY;
              l_s_X += l_i_IncrementX;
            }
          p_ps_Perspective[ l_us_Compteur1++ ] = l_s_X;
          //p_ps_Perspective[ l_us_Compteur1++ ][ l_us_Compteur2 ] = l_s_Y;
        }
    }
  
}
