5903 lines
		
	
	
		
			191 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			5903 lines
		
	
	
		
			191 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include "sdlscreen.h"
 | 
						||
#include "graph.h"
 | 
						||
#include "divers.h"
 | 
						||
#include <math.h>
 | 
						||
#include <malloc.h>
 | 
						||
 | 
						||
#include <string.h>
 | 
						||
#include <stdlib.h>
 | 
						||
#include "moteur.h"
 | 
						||
#include "boutons.h"
 | 
						||
#include "pages.h"
 | 
						||
#include "global.h"
 | 
						||
#include "struct.h"
 | 
						||
#include "erreurs.h"
 | 
						||
 | 
						||
#ifdef __linux__
 | 
						||
    #include <sys/sysinfo.h>
 | 
						||
#elif __WATCOMC__
 | 
						||
    #define _WIN32_WINNT 0x0500
 | 
						||
    #include <windows.h>
 | 
						||
#endif
 | 
						||
 | 
						||
byte Meilleure_couleur(byte R,byte V,byte B)
 | 
						||
{
 | 
						||
  short Coul;
 | 
						||
  int   Delta_R,Delta_V,Delta_B;
 | 
						||
  int   Dist;
 | 
						||
  int   Best_dist=0x7FFFFFFF;
 | 
						||
  byte  Best_color=0;
 | 
						||
 | 
						||
  for (Coul=0; Coul<256; Coul++)
 | 
						||
  {
 | 
						||
    if (!Exclude_color[Coul])
 | 
						||
    {
 | 
						||
      Delta_R=(int)Principal_Palette[Coul].R-R;
 | 
						||
      Delta_V=(int)Principal_Palette[Coul].V-V;
 | 
						||
      Delta_B=(int)Principal_Palette[Coul].B-B;
 | 
						||
 | 
						||
      if (!(Dist=(Delta_R*Delta_R*30)+(Delta_V*Delta_V*59)+(Delta_B*Delta_B*11)))
 | 
						||
        return Coul;
 | 
						||
 | 
						||
      if (Dist<Best_dist)
 | 
						||
      {
 | 
						||
        Best_dist=Dist;
 | 
						||
        Best_color=Coul;
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  return Best_color;
 | 
						||
}
 | 
						||
 | 
						||
void Calculer_les_4_meilleures_couleurs_pour_1_couleur_du_menu
 | 
						||
     (byte Rouge, byte Vert, byte Bleu, struct Composantes * Palette, byte * Table)
 | 
						||
{
 | 
						||
  short Coul;
 | 
						||
  int   Delta_R,Delta_V,Delta_B;
 | 
						||
  int   Dist;
 | 
						||
  int   Best_dist[4]={0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF};
 | 
						||
 | 
						||
 | 
						||
  for (Coul=0; Coul<256; Coul++)
 | 
						||
  {
 | 
						||
    Delta_R=(int)Palette[Coul].R-Rouge;
 | 
						||
    Delta_V=(int)Palette[Coul].V-Vert;
 | 
						||
    Delta_B=(int)Palette[Coul].B-Bleu;
 | 
						||
 | 
						||
    Dist=(Delta_R*Delta_R*30)+(Delta_V*Delta_V*59)+(Delta_B*Delta_B*11);
 | 
						||
 | 
						||
    if (Dist<Best_dist[0])
 | 
						||
    {
 | 
						||
      Best_dist[3]=Best_dist[2];
 | 
						||
      Best_dist[2]=Best_dist[1];
 | 
						||
      Best_dist[1]=Best_dist[0];
 | 
						||
      Best_dist[0]=Dist;
 | 
						||
      Table[3]=Table[2];
 | 
						||
      Table[2]=Table[1];
 | 
						||
      Table[1]=Table[0];
 | 
						||
      Table[0]=Coul;
 | 
						||
    }
 | 
						||
    else
 | 
						||
    {
 | 
						||
      if (Dist<Best_dist[1])
 | 
						||
      {
 | 
						||
        Best_dist[3]=Best_dist[2];
 | 
						||
        Best_dist[2]=Best_dist[1];
 | 
						||
        Best_dist[1]=Dist;
 | 
						||
        Table[3]=Table[2];
 | 
						||
        Table[2]=Table[1];
 | 
						||
        Table[1]=Coul;
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {
 | 
						||
        if (Dist<Best_dist[2])
 | 
						||
        {
 | 
						||
          Best_dist[3]=Best_dist[2];
 | 
						||
          Best_dist[2]=Dist;
 | 
						||
          Table[3]=Table[2];
 | 
						||
          Table[2]=Coul;
 | 
						||
        }
 | 
						||
        else
 | 
						||
        if (Dist<Best_dist[3])
 | 
						||
        {
 | 
						||
          Best_dist[3]=Dist;
 | 
						||
          Table[3]=Coul;
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
byte Old_Noir;
 | 
						||
byte Old_Fonce;
 | 
						||
byte Old_Clair;
 | 
						||
byte Old_Blanc;
 | 
						||
byte Old_Trans;
 | 
						||
 | 
						||
void Remap_pixel(byte * Pix)
 | 
						||
{
 | 
						||
  if (*Pix==Old_Clair)         // On commence par tester le Gris clair
 | 
						||
    *Pix=CM_Clair;             // qui est pas mal utilis<69>.
 | 
						||
  else
 | 
						||
  {
 | 
						||
    if (*Pix==Old_Noir)        // Puis le Noir...
 | 
						||
      *Pix=CM_Noir;
 | 
						||
    else
 | 
						||
    {
 | 
						||
      if (*Pix==Old_Fonce)     // etc...
 | 
						||
        *Pix=CM_Fonce;
 | 
						||
      else
 | 
						||
      {
 | 
						||
        if (*Pix==Old_Blanc)
 | 
						||
          *Pix=CM_Blanc;
 | 
						||
        else
 | 
						||
        {
 | 
						||
          if (*Pix==Old_Trans)
 | 
						||
            *Pix=CM_Trans;
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
void Afficher_palette_du_menu_en_evitant_la_fenetre(byte * Table)
 | 
						||
{
 | 
						||
  // On part du principe qu'il n'y a que le bas d'une fen<65>tre qui puisse
 | 
						||
  // empi<70>ter sur la palette... Et c'est d<>j<EFBFBD> pas mal!
 | 
						||
  byte Couleur,Vraie_couleur;
 | 
						||
  word Debut_X,Debut_Y;
 | 
						||
  word Fin_X,Fin_Y;
 | 
						||
  word Largeur;
 | 
						||
  word Hauteur;
 | 
						||
  word Coin_X=Fenetre_Pos_X+Fenetre_Largeur; // |_ Coin bas-droit
 | 
						||
  word Coin_Y=Fenetre_Pos_Y+Fenetre_Hauteur; // |  de la fen<65>tre +1
 | 
						||
 | 
						||
 | 
						||
  if (Config.Couleurs_separees)
 | 
						||
  {
 | 
						||
    Largeur=(Menu_Taille_couleur-1)*Menu_Facteur_X;
 | 
						||
    Hauteur=Menu_Facteur_Y*3;
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    Largeur=Menu_Taille_couleur*Menu_Facteur_X;
 | 
						||
    Hauteur=Menu_Facteur_Y<<2;
 | 
						||
  }
 | 
						||
 | 
						||
  for (Couleur=0,Vraie_couleur=Couleur_debut_palette;Couleur<64;Couleur++,Vraie_couleur++)
 | 
						||
  {
 | 
						||
    if (Table[Vraie_couleur]!=Vraie_couleur)
 | 
						||
    {
 | 
						||
      Debut_X=(LARGEUR_MENU+1+(Couleur>>3)*Menu_Taille_couleur)*Menu_Facteur_X;
 | 
						||
      Debut_Y=Menu_Ordonnee_avant_fenetre+((2+((Couleur&7)<<2))*Menu_Facteur_Y);
 | 
						||
      Fin_X=Debut_X+Largeur;
 | 
						||
      Fin_Y=Debut_Y+Hauteur;
 | 
						||
 | 
						||
      //   On affiche le bloc en entier si on peut, sinon on le d<>coupe autour
 | 
						||
      // de la fen<65>tre.
 | 
						||
      if ( (Debut_Y>=Coin_Y) || (Fin_X<=Fenetre_Pos_X) || (Debut_X>=Coin_X) )
 | 
						||
        Block(Debut_X,Debut_Y,Largeur,Hauteur,Vraie_couleur);
 | 
						||
      else
 | 
						||
      {
 | 
						||
 | 
						||
        if (Debut_X>=Fenetre_Pos_X)
 | 
						||
        {
 | 
						||
          if ( (Fin_X>Coin_X) || (Fin_Y>Coin_Y) )
 | 
						||
          {
 | 
						||
            if ( (Fin_X>Coin_X) && (Fin_Y>Coin_Y) )
 | 
						||
            {
 | 
						||
              Block(Coin_X,Debut_Y,Fin_X-Coin_X,Coin_Y-Debut_Y,Vraie_couleur);
 | 
						||
              Block(Debut_X,Coin_Y,Largeur,Fin_Y-Coin_Y,Vraie_couleur);
 | 
						||
            }
 | 
						||
            else
 | 
						||
            {
 | 
						||
              if (Fin_Y>Coin_Y)
 | 
						||
                Block(Debut_X,Coin_Y,Largeur,Fin_Y-Coin_Y,Vraie_couleur);
 | 
						||
              else
 | 
						||
                Block(Coin_X,Debut_Y,Fin_X-Coin_X,Hauteur,Vraie_couleur);
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          if (Fin_X<Coin_X)
 | 
						||
          {
 | 
						||
            if (Fin_Y>Coin_Y)
 | 
						||
            {
 | 
						||
              Block(Debut_X,Debut_Y,Fenetre_Pos_X-Debut_X,Coin_Y-Debut_Y,Vraie_couleur);
 | 
						||
              Block(Debut_X,Coin_Y,Largeur,Fin_Y-Coin_Y,Vraie_couleur);
 | 
						||
            }
 | 
						||
            else
 | 
						||
              Block(Debut_X,Debut_Y,Fenetre_Pos_X-Debut_X,Hauteur,Vraie_couleur);
 | 
						||
          }
 | 
						||
          else
 | 
						||
          {
 | 
						||
            if (Fin_Y>Coin_Y)
 | 
						||
            {
 | 
						||
              Block(Debut_X,Debut_Y,Fenetre_Pos_X-Debut_X,Coin_Y-Debut_Y,Vraie_couleur);
 | 
						||
              Block(Coin_X,Debut_Y,Fin_X-Coin_X,Coin_Y-Debut_Y,Vraie_couleur);
 | 
						||
              Block(Debut_X,Coin_Y,Largeur,Fin_Y-Coin_Y,Vraie_couleur);
 | 
						||
            }
 | 
						||
            else
 | 
						||
            {
 | 
						||
              Block(Debut_X,Debut_Y,Fenetre_Pos_X-Debut_X,Hauteur,Vraie_couleur);
 | 
						||
              Block(Coin_X,Debut_Y,Fin_X-Coin_X,Hauteur,Vraie_couleur);
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  SDL_UpdateRect(Ecran_SDL,(LARGEUR_MENU+1)*Menu_Facteur_X,Menu_Ordonnee_avant_fenetre,Largeur,Hauteur);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void Remapper_ecran_apres_changement_couleurs_menu(void)
 | 
						||
{
 | 
						||
  short Indice;
 | 
						||
  byte  Table_de_conversion[256];
 | 
						||
  short Temp/*,Temp2*/;
 | 
						||
 | 
						||
  if ( (CM_Clair!=Old_Clair) || (CM_Fonce!=Old_Fonce) || (CM_Blanc!=Old_Blanc) || (CM_Noir !=Old_Noir )
 | 
						||
    || (CM_Trans!=Old_Trans) )
 | 
						||
  {
 | 
						||
    // Cr<43>ation de la table de conversion
 | 
						||
    for (Indice=0; Indice<256; Indice++)
 | 
						||
      Table_de_conversion[Indice]=Indice;
 | 
						||
 | 
						||
    Table_de_conversion[Old_Noir ]=CM_Noir;
 | 
						||
    Table_de_conversion[Old_Fonce]=CM_Fonce;
 | 
						||
    Table_de_conversion[Old_Clair]=CM_Clair;
 | 
						||
    Table_de_conversion[Old_Blanc]=CM_Blanc;
 | 
						||
 | 
						||
    // Remappage de l'<27>cran
 | 
						||
 | 
						||
    Temp=Fenetre_Hauteur*Menu_Facteur_Y;
 | 
						||
 | 
						||
    Remap_screen(Fenetre_Pos_X, Fenetre_Pos_Y,
 | 
						||
                 Fenetre_Largeur*Menu_Facteur_X,
 | 
						||
                 (Fenetre_Pos_Y+Temp<Menu_Ordonnee_avant_fenetre)?Temp:Menu_Ordonnee_avant_fenetre-Fenetre_Pos_Y,
 | 
						||
                 Table_de_conversion);
 | 
						||
 | 
						||
    if (Menu_visible_avant_fenetre)
 | 
						||
    {
 | 
						||
      Remap_screen(0, Menu_Ordonnee_avant_fenetre,
 | 
						||
                   Largeur_ecran, Hauteur_ecran-Menu_Ordonnee_avant_fenetre,
 | 
						||
                   Table_de_conversion);
 | 
						||
      // On passe la table juste pour ne rafficher que les couleurs modifi<66>es
 | 
						||
      Afficher_palette_du_menu_en_evitant_la_fenetre(Table_de_conversion);
 | 
						||
    }
 | 
						||
    /*
 | 
						||
       Il faudrait peut-<2D>tre remapper les pointill<6C>s d<>limitant l'image.
 | 
						||
       Mais <20>a va <20>tre chiant parce qu'ils peuvent <20>tre affich<63>s en mode Loupe.
 | 
						||
       Mais de toutes fa<66>ons, c'est franchement facultatif...
 | 
						||
    */
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
void Calculer_couleurs_menu_optimales(struct Composantes * Palette)
 | 
						||
{
 | 
						||
  byte Table[4];
 | 
						||
  short I,J,K;
 | 
						||
 | 
						||
 | 
						||
  Old_Noir =CM_Noir;
 | 
						||
  Old_Fonce=CM_Fonce;
 | 
						||
  Old_Clair=CM_Clair;
 | 
						||
  Old_Blanc=CM_Blanc;
 | 
						||
  Old_Trans=CM_Trans;
 | 
						||
 | 
						||
  // Recherche du noir
 | 
						||
  Calculer_les_4_meilleures_couleurs_pour_1_couleur_du_menu
 | 
						||
    (Coul_menu_pref[0].R, Coul_menu_pref[0].V, Coul_menu_pref[0].B,Palette,Table);
 | 
						||
  CM_Noir=Table[0];
 | 
						||
 | 
						||
  // Recherche du blanc
 | 
						||
  Calculer_les_4_meilleures_couleurs_pour_1_couleur_du_menu
 | 
						||
    (Coul_menu_pref[3].R, Coul_menu_pref[3].V, Coul_menu_pref[3].B,Palette,Table);
 | 
						||
  if (CM_Noir!=Table[0])
 | 
						||
    CM_Blanc=Table[0];
 | 
						||
  else
 | 
						||
    CM_Blanc=Table[1];
 | 
						||
 | 
						||
  // Recherche du gris clair
 | 
						||
  Calculer_les_4_meilleures_couleurs_pour_1_couleur_du_menu
 | 
						||
    (Coul_menu_pref[2].R, Coul_menu_pref[2].V, Coul_menu_pref[2].B,Palette,Table);
 | 
						||
  if ( (CM_Noir!=Table[0]) && (CM_Blanc!=Table[0]) )
 | 
						||
    CM_Clair=Table[0];
 | 
						||
  else
 | 
						||
  {
 | 
						||
    if ( (CM_Noir!=Table[1]) && (CM_Blanc!=Table[1]) )
 | 
						||
      CM_Clair=Table[1];
 | 
						||
    else
 | 
						||
      CM_Clair=Table[2];
 | 
						||
  }
 | 
						||
 | 
						||
  // Recherche du gris fonc<6E>
 | 
						||
  Calculer_les_4_meilleures_couleurs_pour_1_couleur_du_menu
 | 
						||
    (Coul_menu_pref[1].R, Coul_menu_pref[1].V, Coul_menu_pref[1].B,Palette,Table);
 | 
						||
  if ( (CM_Noir!=Table[0]) && (CM_Blanc!=Table[0]) && (CM_Clair!=Table[0]) )
 | 
						||
    CM_Fonce=Table[0];
 | 
						||
  else
 | 
						||
  {
 | 
						||
    if ( (CM_Noir!=Table[1]) && (CM_Blanc!=Table[1]) && (CM_Clair!=Table[1]) )
 | 
						||
      CM_Fonce=Table[1];
 | 
						||
    else
 | 
						||
    {
 | 
						||
      if ( (CM_Noir!=Table[2]) && (CM_Blanc!=Table[2]) && (CM_Clair!=Table[2]) )
 | 
						||
        CM_Fonce=Table[2];
 | 
						||
      else
 | 
						||
        CM_Fonce=Table[3];
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  // C'est peu probable mais il est possible que CM_Clair soit plus fonc<6E>e que
 | 
						||
  // CM_Fonce. Dans ce cas, on les inverse.
 | 
						||
  if ( ((Palette[CM_Clair].R*30)+(Palette[CM_Clair].V*59)+(Palette[CM_Clair].B*11)) <
 | 
						||
       ((Palette[CM_Fonce].R*30)+(Palette[CM_Fonce].V*59)+(Palette[CM_Fonce].B*11)) )
 | 
						||
  {
 | 
						||
    I=CM_Clair;
 | 
						||
    CM_Clair=CM_Fonce;
 | 
						||
    CM_Fonce=I;
 | 
						||
  }
 | 
						||
 | 
						||
  // On cherche une couleur de transparence diff<66>rente des 4 autres.
 | 
						||
  for (CM_Trans=0; ((CM_Trans==CM_Noir) || (CM_Trans==CM_Fonce) ||
 | 
						||
                   (CM_Trans==CM_Clair) || (CM_Trans==CM_Blanc)); CM_Trans++);
 | 
						||
 | 
						||
  // Et maintenant, on "remappe" tous les sprites, etc...
 | 
						||
  if ( (CM_Clair!=Old_Clair)
 | 
						||
    || (CM_Fonce!=Old_Fonce)
 | 
						||
    || (CM_Blanc!=Old_Blanc)
 | 
						||
    || (CM_Noir !=Old_Noir )
 | 
						||
    || (CM_Trans!=Old_Trans) )
 | 
						||
  {
 | 
						||
      // Sprites du curseur
 | 
						||
    for (K=0; K<NB_SPRITES_CURSEUR; K++)
 | 
						||
      for (J=0; J<HAUTEUR_SPRITE_CURSEUR; J++)
 | 
						||
        for (I=0; I<LARGEUR_SPRITE_CURSEUR; I++)
 | 
						||
          Remap_pixel(&SPRITE_CURSEUR[K][J][I]);
 | 
						||
      // Le menu
 | 
						||
    for (J=0; J<HAUTEUR_MENU; J++)
 | 
						||
      for (I=0; I<LARGEUR_MENU; I++)
 | 
						||
        Remap_pixel(&BLOCK_MENU[J][I]);
 | 
						||
      // Sprites du menu
 | 
						||
    for (K=0; K<NB_SPRITES_MENU; K++)
 | 
						||
      for (J=0; J<HAUTEUR_SPRITE_MENU; J++)
 | 
						||
        for (I=0; I<LARGEUR_SPRITE_MENU; I++)
 | 
						||
          Remap_pixel(&SPRITE_MENU[K][J][I]);
 | 
						||
      // Sprites d'effets
 | 
						||
    for (K=0; K<NB_SPRITES_EFFETS; K++)
 | 
						||
      for (J=0; J<HAUTEUR_SPRITE_MENU; J++)
 | 
						||
        for (I=0; I<LARGEUR_SPRITE_MENU; I++)
 | 
						||
          Remap_pixel(&SPRITE_EFFET[K][J][I]);
 | 
						||
      // Fonte de l'aide
 | 
						||
    for (K=0; K<315; K++)
 | 
						||
      for (J=0; J<8; J++)
 | 
						||
        for (I=0; I<6; I++)
 | 
						||
          Remap_pixel(&Fonte_help[K][I][J]);
 | 
						||
      // Sprites de lecteurs (drives)
 | 
						||
    for (K=0; K<NB_SPRITES_DRIVES; K++)
 | 
						||
      for (J=0; J<HAUTEUR_SPRITE_DRIVE; J++)
 | 
						||
        for (I=0; I<LARGEUR_SPRITE_DRIVE; I++)
 | 
						||
          Remap_pixel(&SPRITE_DRIVE[K][J][I]);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
// Indique quelle est la m<>moire disponible
 | 
						||
unsigned long Memoire_libre(void)
 | 
						||
{
 | 
						||
  // On appelle la fonction qui optimise la m<>moire libre afin d'en 
 | 
						||
  // regagner un maximum. Sinon, tous les "free" lib<69>rent une m<>moire qui 
 | 
						||
  // n'est pas prise en compte par la fonction, et on se retrouve avec un 
 | 
						||
  // manque alarmant de m<>moire.
 | 
						||
  /*
 | 
						||
  A revoir, mais est-ce vraiment utile?
 | 
						||
  _heapmin();
 | 
						||
  */
 | 
						||
    #ifdef __linux__
 | 
						||
        struct sysinfo info;
 | 
						||
        sysinfo(&info);
 | 
						||
        return info.freeram*info.mem_unit;
 | 
						||
    #elif __WATCOMC__
 | 
						||
         MEMORYSTATUSEX mstt;
 | 
						||
         mstt.dwLength = sizeof(MEMORYSTATUSEX);
 | 
						||
         GlobalMemoryStatusEx(&mstt);
 | 
						||
         return mstt.ullAvailPhys;
 | 
						||
    #endif
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Transformer une liste de shade en deux tables de conversion
 | 
						||
void Liste2tables(word * Liste,short Pas,byte Mode,byte * Table_inc,byte * Table_dec)
 | 
						||
{
 | 
						||
  int Indice;
 | 
						||
  int Premier;
 | 
						||
  int Dernier;
 | 
						||
  int Couleur;
 | 
						||
  int Temp;
 | 
						||
 | 
						||
 | 
						||
  // On initialise les deux tables de conversion en Identit<69>
 | 
						||
  for (Indice=0;Indice<256;Indice++)
 | 
						||
  {
 | 
						||
    Table_inc[Indice]=Indice;
 | 
						||
    Table_dec[Indice]=Indice;
 | 
						||
  }
 | 
						||
 | 
						||
  // On s'appr<70>te <20> examiner l'ensemble de la liste
 | 
						||
  for (Indice=0;Indice<512;Indice++)
 | 
						||
  {
 | 
						||
    // On recherche la premi<6D>re case de la liste non vide (et non inhib<69>e)
 | 
						||
    while ((Indice<512) && (Liste[Indice]>255))
 | 
						||
      Indice++;
 | 
						||
 | 
						||
    // On note la position de la premi<6D>re case de la s<>quence
 | 
						||
    Premier=Indice;
 | 
						||
 | 
						||
    // On recherche la position de la derni<6E>re case de la s<>quence
 | 
						||
    for (Dernier=Premier;Liste[Dernier+1]<256;Dernier++);
 | 
						||
 | 
						||
    // Pour toutes les cases non vides (et non inhib<69>es) qui suivent
 | 
						||
    switch (Mode)
 | 
						||
    {
 | 
						||
      case MODE_SHADE_NORMAL :
 | 
						||
        for (;(Indice<512) && (Liste[Indice]<256);Indice++)
 | 
						||
        { // On met <20> jour les tables de conversion
 | 
						||
          Couleur=Liste[Indice];
 | 
						||
          Table_inc[Couleur]=Liste[(Indice+Pas<=Dernier)?Indice+Pas:Dernier];
 | 
						||
          Table_dec[Couleur]=Liste[(Indice-Pas>=Premier)?Indice-Pas:Premier];
 | 
						||
        }
 | 
						||
        break;
 | 
						||
      case MODE_SHADE_BOUCLE :
 | 
						||
        Temp=1+Dernier-Premier;
 | 
						||
        for (;(Indice<512) && (Liste[Indice]<256);Indice++)
 | 
						||
        { // On met <20> jour les tables de conversion
 | 
						||
          Couleur=Liste[Indice];
 | 
						||
          Table_inc[Couleur]=Liste[Premier+((Pas+Indice-Premier)%Temp)];
 | 
						||
          Table_dec[Couleur]=Liste[Premier+(((Temp-Pas)+Indice-Premier)%Temp)];
 | 
						||
        }
 | 
						||
        break;
 | 
						||
      default : // MODE_SHADE_NOSAT
 | 
						||
        for (;(Indice<512) && (Liste[Indice]<256);Indice++)
 | 
						||
        { // On met <20> jour les tables de conversion
 | 
						||
          Couleur=Liste[Indice];
 | 
						||
          if (Indice+Pas<=Dernier)
 | 
						||
            Table_inc[Couleur]=Liste[Indice+Pas];
 | 
						||
          if (Indice-Pas>=Premier)
 | 
						||
            Table_dec[Couleur]=Liste[Indice-Pas];
 | 
						||
        }
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Transformer un nombre (entier naturel) en cha<68>ne
 | 
						||
void Num2str(dword Nombre,char * Chaine,byte Taille)
 | 
						||
{
 | 
						||
  int Indice;
 | 
						||
 | 
						||
  for (Indice=Taille-1;Indice>=0;Indice--)
 | 
						||
  {
 | 
						||
    Chaine[Indice]=(Nombre%10)+'0';
 | 
						||
    Nombre/=10;
 | 
						||
    if (Nombre==0)
 | 
						||
      for (Indice--;Indice>=0;Indice--)
 | 
						||
        Chaine[Indice]=' ';
 | 
						||
  }
 | 
						||
  Chaine[Taille]='\0';
 | 
						||
}
 | 
						||
 | 
						||
// Transformer une cha<68>ne en un entier naturel (renvoie -1 si ch. invalide)
 | 
						||
int Str2num(char * Chaine)
 | 
						||
{
 | 
						||
  int Valeur=0;
 | 
						||
 | 
						||
  for (;*Chaine;Chaine++)
 | 
						||
  {
 | 
						||
    if ( (*Chaine>='0') && (*Chaine<='9') )
 | 
						||
      Valeur=(Valeur*10)+(*Chaine-'0');
 | 
						||
    else
 | 
						||
      return -1;
 | 
						||
  }
 | 
						||
  return Valeur;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Arrondir un nombre r<>el <20> la valeur enti<74>re la plus proche
 | 
						||
short Round(float Valeur)
 | 
						||
{
 | 
						||
  short Temp=Valeur;
 | 
						||
 | 
						||
  if (Valeur>=0)
 | 
						||
    { if ((Valeur-Temp)>= 0.5) Temp++; }
 | 
						||
  else
 | 
						||
    { if ((Valeur-Temp)<=-0.5) Temp--; }
 | 
						||
 | 
						||
  return Temp;
 | 
						||
}
 | 
						||
 | 
						||
// Arrondir le r<>sultat d'une division <20> la valeur enti<74>re sup<75>rieure
 | 
						||
short Round_div_max(short Numerateur,short Diviseur)
 | 
						||
{
 | 
						||
  if (!(Numerateur % Diviseur))
 | 
						||
    return (Numerateur/Diviseur);
 | 
						||
  else
 | 
						||
    return (Numerateur/Diviseur)+1;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
int Min(int A,int B)
 | 
						||
{
 | 
						||
  return (A<B)?A:B;
 | 
						||
}
 | 
						||
 | 
						||
int Max(int A,int B)
 | 
						||
{
 | 
						||
  return (A>B)?A:B;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
void Transformer_point(short X, short Y, float cosA, float sinA,
 | 
						||
                       short * Xr, short * Yr)
 | 
						||
{
 | 
						||
  *Xr=Round(((float)X*cosA)+((float)Y*sinA));
 | 
						||
  *Yr=Round(((float)Y*cosA)-((float)X*sinA));
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
// -- Recadrer la partie non-zoom<6F>e de l'image par rapport <20> la partie zoom<6F>e
 | 
						||
//    lorsqu'on scrolle en mode Loupe --
 | 
						||
void Recadrer_ecran_par_rapport_au_zoom(void)
 | 
						||
{
 | 
						||
  // Centrage en X
 | 
						||
  if (Principal_Largeur_image>Principal_Split)
 | 
						||
  {
 | 
						||
    Principal_Decalage_X=Loupe_Decalage_X+(Loupe_Largeur>>1)
 | 
						||
                         -(Principal_Split>>1);
 | 
						||
    if (Principal_Decalage_X<0)
 | 
						||
      Principal_Decalage_X=0;
 | 
						||
    else
 | 
						||
    if (Principal_Largeur_image<Principal_Decalage_X+Principal_Split)
 | 
						||
      Principal_Decalage_X=Principal_Largeur_image-Principal_Split;
 | 
						||
  }
 | 
						||
  else
 | 
						||
    Principal_Decalage_X=0;
 | 
						||
 | 
						||
  // Centrage en Y
 | 
						||
  if (Principal_Hauteur_image>Menu_Ordonnee)
 | 
						||
  {
 | 
						||
    Principal_Decalage_Y=Loupe_Decalage_Y+(Loupe_Hauteur>>1)
 | 
						||
                         -(Menu_Ordonnee>>1);
 | 
						||
    if (Principal_Decalage_Y<0)
 | 
						||
      Principal_Decalage_Y=0;
 | 
						||
    else
 | 
						||
    if (Principal_Hauteur_image<Principal_Decalage_Y+Menu_Ordonnee)
 | 
						||
      Principal_Decalage_Y=Principal_Hauteur_image-Menu_Ordonnee;
 | 
						||
  }
 | 
						||
  else
 | 
						||
    Principal_Decalage_Y=0;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// - Calcul des donn<6E>es du split en fonction de la proportion de chaque zone -
 | 
						||
void Calculer_split(void)
 | 
						||
{
 | 
						||
  //short Temp;
 | 
						||
  short X_theorique=Round(Principal_Proportion_split*Largeur_ecran);
 | 
						||
 | 
						||
  Principal_X_Zoom=Largeur_ecran-(((Largeur_ecran+(Loupe_Facteur>>1)-X_theorique)/Loupe_Facteur)*Loupe_Facteur);
 | 
						||
  Principal_Split=Principal_X_Zoom-(Menu_Facteur_X*LARGEUR_BARRE_SPLIT);
 | 
						||
 | 
						||
  // Correction en cas de d<>bordement sur la gauche
 | 
						||
  while (Principal_Split*(Loupe_Facteur+1)<Largeur_ecran-(Menu_Facteur_X*LARGEUR_BARRE_SPLIT))
 | 
						||
  {
 | 
						||
    Principal_Split+=Loupe_Facteur;
 | 
						||
    Principal_X_Zoom+=Loupe_Facteur;
 | 
						||
  }
 | 
						||
  // Correction en cas de d<>bordement sur la droite
 | 
						||
  X_theorique=Largeur_ecran-((NB_PIXELS_ZOOMES_MIN-1)*Loupe_Facteur);
 | 
						||
  while (Principal_X_Zoom>=X_theorique)
 | 
						||
  {
 | 
						||
    Principal_Split-=Loupe_Facteur;
 | 
						||
    Principal_X_Zoom-=Loupe_Facteur;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
// -------------------- Calcul des information de la loupe -------------------
 | 
						||
void Calculer_donnees_loupe(void)
 | 
						||
/*
 | 
						||
  Apr<70>s modification des donn<6E>es de la loupe, il faut recalculer les limites.
 | 
						||
*/
 | 
						||
{
 | 
						||
  Calculer_split();
 | 
						||
 | 
						||
  Loupe_Largeur=(Largeur_ecran-Principal_X_Zoom)/Loupe_Facteur;
 | 
						||
 | 
						||
  Loupe_Hauteur=Menu_Ordonnee/Loupe_Facteur;
 | 
						||
  if (Menu_Ordonnee%Loupe_Facteur)
 | 
						||
    Loupe_Hauteur++;
 | 
						||
 | 
						||
  if (Loupe_Mode && Loupe_Decalage_X)
 | 
						||
  {
 | 
						||
    if (Principal_Largeur_image<Loupe_Decalage_X+Loupe_Largeur)
 | 
						||
      Loupe_Decalage_X=Principal_Largeur_image-Loupe_Largeur;
 | 
						||
    if (Loupe_Decalage_X<0) Loupe_Decalage_X=0;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// -------- Calcul des bornes de la partie d'image visible <20> l'<27>cran ---------
 | 
						||
void Calculer_limites(void)
 | 
						||
/*
 | 
						||
  Avant l'appel <20> cette fonction, les donn<6E>es de la loupe doivent <20>tre <20> jour.
 | 
						||
*/
 | 
						||
{
 | 
						||
  if (Loupe_Mode)
 | 
						||
  {
 | 
						||
    // -- Calcul des limites de la partie non zoom<6F>e de l'image --
 | 
						||
    Limite_Haut  =Principal_Decalage_Y;
 | 
						||
    Limite_Gauche=Principal_Decalage_X;
 | 
						||
    Limite_visible_Bas   =Limite_Haut+Menu_Ordonnee-1;
 | 
						||
    Limite_visible_Droite=Limite_Gauche+Principal_Split-1;
 | 
						||
 | 
						||
    if (Limite_visible_Bas>=Principal_Hauteur_image)
 | 
						||
      Limite_Bas=Principal_Hauteur_image-1;
 | 
						||
    else
 | 
						||
      Limite_Bas=Limite_visible_Bas;
 | 
						||
 | 
						||
    if (Limite_visible_Droite>=Principal_Largeur_image)
 | 
						||
      Limite_Droite=Principal_Largeur_image-1;
 | 
						||
    else
 | 
						||
      Limite_Droite=Limite_visible_Droite;
 | 
						||
 | 
						||
    // -- Calcul des limites de la partie zoom<6F>e de l'image --
 | 
						||
    Limite_Haut_Zoom  =Loupe_Decalage_Y;
 | 
						||
    Limite_Gauche_Zoom=Loupe_Decalage_X;
 | 
						||
    Limite_visible_Bas_Zoom   =Limite_Haut_Zoom+Loupe_Hauteur-1;
 | 
						||
    Limite_visible_Droite_Zoom=Limite_Gauche_Zoom+Loupe_Largeur-1;
 | 
						||
 | 
						||
    if (Limite_visible_Bas_Zoom>=Principal_Hauteur_image)
 | 
						||
      Limite_Bas_Zoom=Principal_Hauteur_image-1;
 | 
						||
    else
 | 
						||
      Limite_Bas_Zoom=Limite_visible_Bas_Zoom;
 | 
						||
 | 
						||
    if (Limite_visible_Droite_Zoom>=Principal_Largeur_image)
 | 
						||
      Limite_Droite_Zoom=Principal_Largeur_image-1;
 | 
						||
    else
 | 
						||
      Limite_Droite_Zoom=Limite_visible_Droite_Zoom;
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    // -- Calcul des limites de la partie visible de l'image --
 | 
						||
    Limite_Haut  =Principal_Decalage_Y;
 | 
						||
    Limite_Gauche=Principal_Decalage_X;
 | 
						||
    Limite_visible_Bas   =Limite_Haut+(Menu_visible?Menu_Ordonnee:Hauteur_ecran)-1; // A REVOIR POUR SIMPLIFICATION
 | 
						||
    Limite_visible_Droite=Limite_Gauche+Largeur_ecran-1;
 | 
						||
 | 
						||
    if (Limite_visible_Bas>=Principal_Hauteur_image)
 | 
						||
      Limite_Bas=Principal_Hauteur_image-1;
 | 
						||
    else
 | 
						||
      Limite_Bas=Limite_visible_Bas;
 | 
						||
 | 
						||
    if (Limite_visible_Droite>=Principal_Largeur_image)
 | 
						||
      Limite_Droite=Principal_Largeur_image-1;
 | 
						||
    else
 | 
						||
      Limite_Droite=Limite_visible_Droite;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// -- Calculer les coordonn<6E>es du pinceau en fonction du snap et de la loupe -
 | 
						||
void Calculer_coordonnees_pinceau(void)
 | 
						||
{
 | 
						||
  if ((Loupe_Mode) && (Mouse_X>=Principal_X_Zoom))
 | 
						||
  {
 | 
						||
    Pinceau_X=((Mouse_X-Principal_X_Zoom)/Loupe_Facteur)+Loupe_Decalage_X;
 | 
						||
    Pinceau_Y=(Mouse_Y/Loupe_Facteur)+Loupe_Decalage_Y;
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    Pinceau_X=Mouse_X+Principal_Decalage_X;
 | 
						||
    Pinceau_Y=Mouse_Y+Principal_Decalage_Y;
 | 
						||
  }
 | 
						||
 | 
						||
  if (Snap_Mode)
 | 
						||
  {
 | 
						||
    Pinceau_X=(((Pinceau_X+(Snap_Largeur>>1)-Snap_Decalage_X)/Snap_Largeur)*Snap_Largeur)+Snap_Decalage_X;
 | 
						||
    Pinceau_Y=(((Pinceau_Y+(Snap_Hauteur>>1)-Snap_Decalage_Y)/Snap_Hauteur)*Snap_Hauteur)+Snap_Decalage_Y;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// ------------ Changer le facteur de zoom et tout mettre <20> jour -------------
 | 
						||
void Changer_facteur_loupe(byte Indice_facteur)
 | 
						||
{
 | 
						||
  short Centre_X;
 | 
						||
  short Centre_Y;
 | 
						||
 | 
						||
  Centre_X=Loupe_Decalage_X+(Loupe_Largeur>>1);
 | 
						||
  Centre_Y=Loupe_Decalage_Y+(Loupe_Hauteur>>1);
 | 
						||
 | 
						||
  Loupe_Facteur=FACTEUR_ZOOM[Indice_facteur];
 | 
						||
  Table_mul_facteur_zoom=TABLE_ZOOM[Indice_facteur];
 | 
						||
  Calculer_donnees_loupe();
 | 
						||
 | 
						||
  if (Loupe_Mode)
 | 
						||
  {
 | 
						||
    // Recalculer le d<>calage de la loupe
 | 
						||
    // Centrage "brut" de l<>cran par rapport <20> la loupe
 | 
						||
    Loupe_Decalage_X=Centre_X-(Loupe_Largeur>>1);
 | 
						||
    Loupe_Decalage_Y=Centre_Y-(Loupe_Hauteur>>1);
 | 
						||
    // Correction en cas de d<>bordement de l'image
 | 
						||
    if (Loupe_Decalage_X+Loupe_Largeur>Principal_Largeur_image)
 | 
						||
      Loupe_Decalage_X=Principal_Largeur_image-Loupe_Largeur;
 | 
						||
    if (Loupe_Decalage_Y+Loupe_Hauteur>Principal_Hauteur_image)
 | 
						||
      Loupe_Decalage_Y=Principal_Hauteur_image-Loupe_Hauteur;
 | 
						||
    if (Loupe_Decalage_X<0)
 | 
						||
      Loupe_Decalage_X=0;
 | 
						||
    if (Loupe_Decalage_Y<0)
 | 
						||
      Loupe_Decalage_Y=0;
 | 
						||
 | 
						||
    Recadrer_ecran_par_rapport_au_zoom();
 | 
						||
 | 
						||
    Pixel_Preview=Pixel_Preview_Loupe;
 | 
						||
  }
 | 
						||
  else
 | 
						||
    Pixel_Preview=Pixel_Preview_Normal;
 | 
						||
 | 
						||
  Calculer_limites();
 | 
						||
  Calculer_coordonnees_pinceau();
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// -- Affichage de la limite de l'image -------------------------------------
 | 
						||
void Afficher_limites_de_l_image(void)
 | 
						||
{
 | 
						||
  short Debut;
 | 
						||
  short Pos;
 | 
						||
  short Fin;
 | 
						||
  byte Droite_visible;
 | 
						||
  byte Bas_visible;
 | 
						||
  short Ancienne_Limite_Zoom;
 | 
						||
 | 
						||
  Droite_visible=Principal_Largeur_image<((Loupe_Mode)?Principal_Split:Largeur_ecran);
 | 
						||
  Bas_visible   =Principal_Hauteur_image<Menu_Ordonnee;
 | 
						||
 | 
						||
 | 
						||
  // On v<>rifie que la limite <20> droite est visible:
 | 
						||
  if (Droite_visible)
 | 
						||
  {
 | 
						||
    Debut=Limite_Haut;
 | 
						||
    Fin=(Limite_Bas<Principal_Hauteur_image)?
 | 
						||
        Limite_Bas:Principal_Hauteur_image;
 | 
						||
 | 
						||
    if (Bas_visible)
 | 
						||
      Fin++;
 | 
						||
 | 
						||
    // Juste le temps d'afficher les limites, on <20>tend les limites de la loupe
 | 
						||
    // aux limites visibles, car sinon Pixel_Preview ne voudra pas afficher.
 | 
						||
    Ancienne_Limite_Zoom=Limite_Droite_Zoom;
 | 
						||
    Limite_Droite_Zoom=Limite_visible_Droite_Zoom;
 | 
						||
 | 
						||
    for (Pos=Debut;Pos<=Fin;Pos++)
 | 
						||
      Pixel_Preview(Principal_Largeur_image,Pos,((Pos+Principal_Hauteur_image)&1)?CM_Blanc:CM_Noir);
 | 
						||
 | 
						||
    // On restaure la bonne valeur des limites
 | 
						||
    Limite_Droite_Zoom=Ancienne_Limite_Zoom;
 | 
						||
  }
 | 
						||
 | 
						||
  // On v<>rifie que la limite en bas est visible:
 | 
						||
  if (Bas_visible)
 | 
						||
  {
 | 
						||
    Debut=Limite_Gauche;
 | 
						||
    Fin=(Limite_Droite<Principal_Largeur_image)?
 | 
						||
        Limite_Droite:Principal_Largeur_image;
 | 
						||
 | 
						||
    // On <20>tend <20>galement les limites en bas (comme pour la limite droit)
 | 
						||
    Ancienne_Limite_Zoom=Limite_Bas_Zoom;
 | 
						||
    Limite_Bas_Zoom=Limite_visible_Bas_Zoom;
 | 
						||
 | 
						||
    for (Pos=Debut;Pos<=Fin;Pos++)
 | 
						||
      Pixel_Preview(Pos,Principal_Hauteur_image,((Pos+Principal_Hauteur_image)&1)?CM_Blanc:CM_Noir);
 | 
						||
 | 
						||
    // On restaure la bonne valeur des limites
 | 
						||
    Limite_Bas_Zoom=Ancienne_Limite_Zoom;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
// Fonction retournant le libell<6C> d'une mode (ex: " 320x200")
 | 
						||
char * Libelle_mode(int Mode)
 | 
						||
{
 | 
						||
  static char Chaine[9];
 | 
						||
 | 
						||
  Num2str(Mode_video[Mode].Largeur,Chaine,4);
 | 
						||
  Chaine[4]='x';
 | 
						||
  Num2str(Mode_video[Mode].Hauteur,Chaine+5,3);
 | 
						||
  return Chaine;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
//--------------------- Initialisation d'un mode vid<69>o -----------------------
 | 
						||
 | 
						||
void * Mode_X_Ptr; // Pointeur sur la table <20> utiliser pour le changement de
 | 
						||
                   // mode vid<69>o X
 | 
						||
 | 
						||
void Initialiser_mode_video(int Numero)
 | 
						||
{
 | 
						||
  int Sensibilite_X;
 | 
						||
  int Sensibilite_Y;
 | 
						||
 | 
						||
  if (Resolution_actuelle != Numero)
 | 
						||
  {
 | 
						||
    Largeur_ecran = Mode_video[Numero].Largeur;
 | 
						||
    Hauteur_ecran = Mode_video[Numero].Hauteur;
 | 
						||
 | 
						||
    switch (Config.Ratio)
 | 
						||
    {
 | 
						||
      case 1: // adapter tout
 | 
						||
        Menu_Facteur_X=Mode_video[Numero].Facteur_X;
 | 
						||
        Menu_Facteur_Y=Mode_video[Numero].Facteur_Y;
 | 
						||
        break;
 | 
						||
      case 2: // adapter l<>g<EFBFBD>rement
 | 
						||
        Menu_Facteur_X=Mode_video[Numero].Facteur_X-1;
 | 
						||
        if (Menu_Facteur_X<1) Menu_Facteur_X=1;
 | 
						||
        Menu_Facteur_Y=Mode_video[Numero].Facteur_Y-1;
 | 
						||
        if (Menu_Facteur_Y<1) Menu_Facteur_Y=1;
 | 
						||
        if ( (Mode_video[Numero].Facteur_X<Mode_video[Numero].Facteur_Y)
 | 
						||
          && (Menu_Facteur_X==Menu_Facteur_Y) )
 | 
						||
          Menu_Facteur_Y++;
 | 
						||
        else
 | 
						||
        if ( (Mode_video[Numero].Facteur_X>Mode_video[Numero].Facteur_Y)
 | 
						||
          && (Menu_Facteur_X==Menu_Facteur_Y) )
 | 
						||
          Menu_Facteur_X++;
 | 
						||
        break;
 | 
						||
      default: // ne pas adapter
 | 
						||
        Menu_Facteur_X=1;
 | 
						||
        Menu_Facteur_Y=1;
 | 
						||
    }
 | 
						||
 | 
						||
    if (Buffer_de_ligne_horizontale)
 | 
						||
      free(Buffer_de_ligne_horizontale);
 | 
						||
 | 
						||
    Buffer_de_ligne_horizontale=(byte *)malloc((Largeur_ecran>Principal_Largeur_image)?Largeur_ecran:Principal_Largeur_image);
 | 
						||
 | 
						||
    switch (Mode_video[Numero].Mode)
 | 
						||
    {
 | 
						||
        case MODE_SDL:
 | 
						||
            Pixel = Pixel_SDL;
 | 
						||
            Lit_pixel= Lit_Pixel_SDL;
 | 
						||
            Clear_screen = Effacer_Tout_l_Ecran_SDL;
 | 
						||
            Display_screen = Afficher_partie_de_l_ecran_SDL;
 | 
						||
            Block = Block_SDL;
 | 
						||
            Block_Fast = Block_SDL_Fast;
 | 
						||
            Pixel_Preview_Normal = Pixel_Preview_Normal_SDL;
 | 
						||
            Pixel_Preview_Loupe = Pixel_Preview_Loupe_SDL;
 | 
						||
            Ligne_horizontale_XOR = Ligne_horizontale_XOR_SDL;
 | 
						||
            Ligne_verticale_XOR = Ligne_verticale_XOR_SDL;
 | 
						||
            Display_brush_Color = Display_brush_Color_SDL;
 | 
						||
            Display_brush_Mono = Display_brush_Mono_SDL;
 | 
						||
            Clear_brush = Clear_brush_SDL;
 | 
						||
            Remap_screen = Remap_screen_SDL;
 | 
						||
            Afficher_ligne = Afficher_une_ligne_ecran_SDL;
 | 
						||
            Lire_ligne = Lire_une_ligne_ecran_SDL;
 | 
						||
            Display_zoomed_screen = Afficher_partie_de_l_ecran_zoomee_SDL;
 | 
						||
            Display_brush_Color_zoom = Display_brush_Color_zoom_SDL;
 | 
						||
            Display_brush_Mono_zoom = Display_brush_Mono_zoom_SDL;
 | 
						||
            Clear_brush_zoom = Clear_brush_zoom_SDL;
 | 
						||
            Set_Mode_SDL();
 | 
						||
        break;
 | 
						||
    }
 | 
						||
    
 | 
						||
    Set_palette(Principal_Palette);
 | 
						||
 | 
						||
    Resolution_actuelle = Numero;
 | 
						||
 | 
						||
    Menu_Taille_couleur = ((Largeur_ecran/Menu_Facteur_X)-(LARGEUR_MENU+2)) >> 3;
 | 
						||
    Menu_Ordonnee = Hauteur_ecran;
 | 
						||
    if (Menu_visible)
 | 
						||
      Menu_Ordonnee -= HAUTEUR_MENU * Menu_Facteur_Y;
 | 
						||
    Menu_Ordonnee_Texte = Hauteur_ecran-(Menu_Facteur_Y<<3);
 | 
						||
    Bouton[BOUTON_CHOIX_COL].Largeur=(Menu_Taille_couleur<<3)-1;
 | 
						||
 | 
						||
    Clip_mouse();
 | 
						||
    Mouse_X = Largeur_ecran >> 1;
 | 
						||
    Mouse_Y = Hauteur_ecran >> 1;
 | 
						||
    Set_mouse_position();
 | 
						||
 | 
						||
    Sensibilite_X = Config.Indice_Sensibilite_souris_X / Mode_video[Numero].Facteur_X;
 | 
						||
    Sensibilite_Y = Config.Indice_Sensibilite_souris_Y / Mode_video[Numero].Facteur_Y;
 | 
						||
    Sensibilite_X>>=Mouse_Facteur_de_correction_X;
 | 
						||
    Sensibilite_Y>>=Mouse_Facteur_de_correction_Y;
 | 
						||
    Sensibilite_souris(Sensibilite_X?Sensibilite_X:1,Sensibilite_Y?Sensibilite_Y:1);
 | 
						||
 | 
						||
    Brouillon_Decalage_X=0; // |  Il faut penser <20> <20>viter les incoh<6F>rences
 | 
						||
    Brouillon_Decalage_Y=0; // |- de d<>calage du brouillon par rapport <20>
 | 
						||
    Brouillon_Loupe_Mode=0; // |  la r<>solution.
 | 
						||
  }
 | 
						||
 | 
						||
  Pixel_Preview=Pixel_Preview_Normal;
 | 
						||
 | 
						||
  Principal_Decalage_X=0; // Il faut quand m<>me modifier ces valeurs <20> chaque
 | 
						||
  Principal_Decalage_Y=0; // fois car on n'est pas <20> l'abri d'une modification
 | 
						||
                          // des dimensions de l'image.
 | 
						||
  Calculer_donnees_loupe();
 | 
						||
  Calculer_limites();
 | 
						||
  Calculer_coordonnees_pinceau();
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// -- Interface avec l'image, affect<63>e par le facteur de grossissement -------
 | 
						||
 | 
						||
  // fonction d'affichage "Pixel" utilis<69>e pour les op<6F>rations d<>finitivement
 | 
						||
  // Ne doit <20> aucune condition <20>tre appel<65>e en dehors de la partie visible
 | 
						||
  // de l'image dans l'<27>cran (<28>a pourrait <20>tre grave)
 | 
						||
void Afficher_pixel(word X,word Y,byte Couleur)
 | 
						||
  // X & Y    sont la position d'un point dans l'IMAGE
 | 
						||
  // Couleur  est la couleur du point
 | 
						||
  // Le Stencil est g<>r<EFBFBD>.
 | 
						||
  // Les effets sont g<>r<EFBFBD>s par appel <20> Fonction_effet().
 | 
						||
  // La Loupe est g<>r<EFBFBD>e par appel <20> Pixel_Preview().
 | 
						||
{
 | 
						||
  if ( ( (!Trame_Mode)   || (Effet_Trame(X,Y)) )
 | 
						||
    && (!((Stencil_Mode) && (Stencil[Lit_pixel_dans_ecran_courant(X,Y)])))
 | 
						||
    && (!((Mask_Mode)    && (Mask[Lit_pixel_dans_ecran_brouillon(X,Y)]))) )
 | 
						||
  {
 | 
						||
    Couleur=Fonction_effet(X,Y,Couleur);
 | 
						||
    Pixel_dans_ecran_courant(X,Y,Couleur);
 | 
						||
    Pixel_Preview(X,Y,Couleur);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// -- Interface avec le menu et les fen<65>tres ---------------------------------
 | 
						||
 | 
						||
  // Affichage d'un pixel dans le menu (le menu do<64>t <20>tre visible)
 | 
						||
 | 
						||
void Pixel_dans_barre_d_outil(word X,word Y,byte Couleur)
 | 
						||
{
 | 
						||
  Block_Fast(X*Menu_Facteur_X,(Y*Menu_Facteur_Y)+Menu_Ordonnee,Menu_Facteur_X,Menu_Facteur_Y,Couleur);
 | 
						||
}
 | 
						||
 | 
						||
  // Affichage d'un pixel dans la fen<65>tre (la fen<65>tre do<64>t <20>tre visible)
 | 
						||
 | 
						||
void Pixel_dans_fenetre(word X,word Y,byte Couleur)
 | 
						||
{
 | 
						||
    Block_Fast((X*Menu_Facteur_X)+Fenetre_Pos_X,(Y*Menu_Facteur_Y)+Fenetre_Pos_Y,Menu_Facteur_X,Menu_Facteur_Y,Couleur);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// -- Affichages de diff<66>rents c<>dres dans une fen<65>tre -----------------------
 | 
						||
 | 
						||
  // -- Cadre g<>n<EFBFBD>ral avec couleurs param<61>trables --
 | 
						||
 | 
						||
void Fenetre_Afficher_cadre_general(word Pos_X,word Pos_Y,word Largeur,word Hauteur,
 | 
						||
                                    byte Couleur_HG,byte Couleur_BD,byte Couleur_S,byte Couleur_CHG,byte Couleur_CBD)
 | 
						||
// Param<61>tres de couleurs:
 | 
						||
// Couleur_HG =Bords Haut et Gauche
 | 
						||
// Couleur_BD =Bords Bas et Droite
 | 
						||
// Couleur_S  =Coins Haut-Droite et Bas-Gauche
 | 
						||
// Couleur_CHG=Coin Haut-Gauche
 | 
						||
// Couleur_CBD=Coin Bas-Droite
 | 
						||
{
 | 
						||
  // Bord haut (sans les extr<74>mit<69>s)
 | 
						||
  Block(Fenetre_Pos_X+((Pos_X+1)*Menu_Facteur_X),
 | 
						||
        Fenetre_Pos_Y+(Pos_Y*Menu_Facteur_Y),
 | 
						||
        (Largeur-2)*Menu_Facteur_X,Menu_Facteur_Y,Couleur_HG);
 | 
						||
 | 
						||
  // Bord bas (sans les extr<74>mit<69>s)
 | 
						||
  Block(Fenetre_Pos_X+((Pos_X+1)*Menu_Facteur_X),
 | 
						||
        Fenetre_Pos_Y+((Pos_Y+Hauteur-1)*Menu_Facteur_Y),
 | 
						||
        (Largeur-2)*Menu_Facteur_X,Menu_Facteur_Y,Couleur_BD);
 | 
						||
 | 
						||
  // Bord gauche (sans les extr<74>mit<69>s)
 | 
						||
  Block(Fenetre_Pos_X+(Pos_X*Menu_Facteur_X),
 | 
						||
        Fenetre_Pos_Y+((Pos_Y+1)*Menu_Facteur_Y),
 | 
						||
        Menu_Facteur_X,(Hauteur-2)*Menu_Facteur_Y,Couleur_HG);
 | 
						||
 | 
						||
  // Bord droite (sans les extr<74>mit<69>s)
 | 
						||
  Block(Fenetre_Pos_X+((Pos_X+Largeur-1)*Menu_Facteur_X),
 | 
						||
        Fenetre_Pos_Y+((Pos_Y+1)*Menu_Facteur_Y),
 | 
						||
        Menu_Facteur_X,(Hauteur-2)*Menu_Facteur_Y,Couleur_BD);
 | 
						||
 | 
						||
  // Coin haut gauche
 | 
						||
  Pixel_dans_fenetre(Pos_X,Pos_Y,Couleur_CHG);
 | 
						||
  // Coin haut droite
 | 
						||
  Pixel_dans_fenetre(Pos_X+Largeur-1,Pos_Y,Couleur_S);
 | 
						||
  // Coin bas droite
 | 
						||
  Pixel_dans_fenetre(Pos_X+Largeur-1,Pos_Y+Hauteur-1,Couleur_CBD);
 | 
						||
  // Coin bas gauche
 | 
						||
  Pixel_dans_fenetre(Pos_X,Pos_Y+Hauteur-1,Couleur_S);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Cadre dont tout le contour est d'une seule couleur --
 | 
						||
 | 
						||
void Fenetre_Afficher_cadre_mono(word Pos_X,word Pos_Y,word Largeur,word Hauteur,byte Couleur)
 | 
						||
{
 | 
						||
  Fenetre_Afficher_cadre_general(Pos_X,Pos_Y,Largeur,Hauteur,Couleur,Couleur,Couleur,Couleur,Couleur);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Cadre creux: fonc<6E> en haut-gauche et clair en bas-droite --
 | 
						||
 | 
						||
void Fenetre_Afficher_cadre_creux(word Pos_X,word Pos_Y,word Largeur,word Hauteur)
 | 
						||
{
 | 
						||
  Fenetre_Afficher_cadre_general(Pos_X,Pos_Y,Largeur,Hauteur,CM_Fonce,CM_Blanc,CM_Clair,CM_Fonce,CM_Blanc);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Cadre bomb<6D>: clair en haut-gauche et fonc<6E> en bas-droite --
 | 
						||
 | 
						||
void Fenetre_Afficher_cadre_bombe(word Pos_X,word Pos_Y,word Largeur,word Hauteur)
 | 
						||
{
 | 
						||
  Fenetre_Afficher_cadre_general(Pos_X,Pos_Y,Largeur,Hauteur,CM_Blanc,CM_Fonce,CM_Clair,CM_Blanc,CM_Fonce);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Cadre de s<>paration: un cadre bomb<6D> dans un cadre creux (3D!!!) --
 | 
						||
 | 
						||
void Fenetre_Afficher_cadre(word Pos_X,word Pos_Y,word Largeur,word Hauteur)
 | 
						||
{
 | 
						||
  Fenetre_Afficher_cadre_creux(Pos_X,Pos_Y,Largeur,Hauteur);
 | 
						||
  Fenetre_Afficher_cadre_bombe(Pos_X+1,Pos_Y+1,Largeur-2,Hauteur-2);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
//-- Affichages relatifs <20> la palette dans le menu ---------------------------
 | 
						||
 | 
						||
  // -- Affichage des couleurs courante (fore/back) de pinceau dans le menu --
 | 
						||
 | 
						||
void Afficher_foreback(void)
 | 
						||
{
 | 
						||
  if (Menu_visible)
 | 
						||
  {
 | 
						||
    Block((LARGEUR_MENU-17)*Menu_Facteur_X,Menu_Ordonnee+Menu_Facteur_Y,Menu_Facteur_X<<4,Menu_Facteur_Y*7,Back_color);
 | 
						||
    Block((LARGEUR_MENU-13)*Menu_Facteur_X,Menu_Ordonnee+(Menu_Facteur_Y<<1),Menu_Facteur_X<<3,Menu_Facteur_Y*5,Fore_color);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
  // -- Tracer un cadre de couleur autour de la Fore_color dans le menu --
 | 
						||
 | 
						||
void Encadrer_couleur_menu(byte Couleur)
 | 
						||
{
 | 
						||
  word Debut_X,Debut_Y,Fin_X,Fin_Y;
 | 
						||
  word Indice;
 | 
						||
 | 
						||
  if ((Fore_color>=Couleur_debut_palette) && (Fore_color<Couleur_debut_palette+64) && (Menu_visible))
 | 
						||
  {
 | 
						||
    if (Config.Couleurs_separees)
 | 
						||
    {
 | 
						||
      Debut_X=(LARGEUR_MENU+((Fore_color-Couleur_debut_palette)>>3)*Menu_Taille_couleur)*Menu_Facteur_X;
 | 
						||
      Debut_Y=Menu_Ordonnee+((1+(((Fore_color-Couleur_debut_palette)&7)<<2))*Menu_Facteur_Y);
 | 
						||
 | 
						||
      Block(Debut_X,Debut_Y,(Menu_Taille_couleur+1)*Menu_Facteur_X,Menu_Facteur_Y,Couleur);
 | 
						||
      Block(Debut_X,Debut_Y+(Menu_Facteur_Y<<2),(Menu_Taille_couleur+1)*Menu_Facteur_X,Menu_Facteur_Y,Couleur);
 | 
						||
 | 
						||
      Block(Debut_X,Debut_Y+Menu_Facteur_Y,Menu_Facteur_X,Menu_Facteur_Y*3,Couleur);
 | 
						||
      Block(Debut_X+(Menu_Taille_couleur*Menu_Facteur_X),Debut_Y+Menu_Facteur_Y,Menu_Facteur_X,Menu_Facteur_Y*3,Couleur);
 | 
						||
    }
 | 
						||
    else
 | 
						||
    {
 | 
						||
      if (Couleur==CM_Noir)
 | 
						||
      {
 | 
						||
        Debut_X=(LARGEUR_MENU+1+((Fore_color-Couleur_debut_palette)>>3)*Menu_Taille_couleur)*Menu_Facteur_X;
 | 
						||
        Debut_Y=Menu_Ordonnee+((2+(((Fore_color-Couleur_debut_palette)&7)<<2))*Menu_Facteur_Y);
 | 
						||
 | 
						||
        Block(Debut_X,Debut_Y,Menu_Taille_couleur*Menu_Facteur_X,
 | 
						||
              Menu_Facteur_Y<<2,Fore_color);
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {
 | 
						||
        Debut_X=LARGEUR_MENU+1+((Fore_color-Couleur_debut_palette)>>3)*Menu_Taille_couleur;
 | 
						||
        Debut_Y=2+(((Fore_color-Couleur_debut_palette)&7)<<2);
 | 
						||
 | 
						||
        Fin_X=Debut_X+Menu_Taille_couleur-1;
 | 
						||
        Fin_Y=Debut_Y+3;
 | 
						||
 | 
						||
        for (Indice=Debut_X; Indice<=Fin_X; Indice++)
 | 
						||
          Block(Indice*Menu_Facteur_X,Menu_Ordonnee+(Debut_Y*Menu_Facteur_Y),
 | 
						||
                Menu_Facteur_X,Menu_Facteur_Y,
 | 
						||
                ((Indice+Debut_Y)&1)?CM_Blanc:CM_Noir);
 | 
						||
 | 
						||
        for (Indice=Debut_Y+1; Indice<Fin_Y; Indice++)
 | 
						||
          Block(Debut_X*Menu_Facteur_X,Menu_Ordonnee+(Indice*Menu_Facteur_Y),
 | 
						||
                Menu_Facteur_X,Menu_Facteur_Y,
 | 
						||
                ((Indice+Debut_X)&1)?CM_Blanc:CM_Noir);
 | 
						||
 | 
						||
        for (Indice=Debut_Y+1; Indice<Fin_Y; Indice++)
 | 
						||
          Block(Fin_X*Menu_Facteur_X,Menu_Ordonnee+(Indice*Menu_Facteur_Y),
 | 
						||
                Menu_Facteur_X,Menu_Facteur_Y,
 | 
						||
                ((Indice+Fin_X)&1)?CM_Blanc:CM_Noir);
 | 
						||
 | 
						||
        for (Indice=Debut_X; Indice<=Fin_X; Indice++)
 | 
						||
          Block(Indice*Menu_Facteur_X,Menu_Ordonnee+(Fin_Y*Menu_Facteur_Y),
 | 
						||
                Menu_Facteur_X,Menu_Facteur_Y,
 | 
						||
                ((Indice+Fin_Y)&1)?CM_Blanc:CM_Noir);
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
  // -- Afficher la palette dans le menu --
 | 
						||
 | 
						||
void Afficher_palette_du_menu(void)
 | 
						||
{
 | 
						||
  byte Couleur;
 | 
						||
 | 
						||
  if (Menu_visible)
 | 
						||
  {
 | 
						||
    Block(LARGEUR_MENU*Menu_Facteur_X,Menu_Ordonnee,Largeur_ecran-(LARGEUR_MENU*Menu_Facteur_X),(HAUTEUR_MENU-9)*Menu_Facteur_Y,CM_Noir);
 | 
						||
 | 
						||
    if (Config.Couleurs_separees)
 | 
						||
      for (Couleur=0;Couleur<64;Couleur++)
 | 
						||
        Block((LARGEUR_MENU+1+(Couleur>>3)*Menu_Taille_couleur)*Menu_Facteur_X,
 | 
						||
              Menu_Ordonnee+((2+((Couleur&7)<<2))*Menu_Facteur_Y),
 | 
						||
              (Menu_Taille_couleur-1)*Menu_Facteur_X,
 | 
						||
              Menu_Facteur_Y*3,
 | 
						||
              Couleur_debut_palette+Couleur);
 | 
						||
    else
 | 
						||
      for (Couleur=0;Couleur<64;Couleur++)
 | 
						||
        Block((LARGEUR_MENU+1+(Couleur>>3)*Menu_Taille_couleur)*Menu_Facteur_X,
 | 
						||
              Menu_Ordonnee+((2+((Couleur&7)<<2))*Menu_Facteur_Y),
 | 
						||
              Menu_Taille_couleur*Menu_Facteur_X,
 | 
						||
              Menu_Facteur_Y<<2,
 | 
						||
              Couleur_debut_palette+Couleur);
 | 
						||
 | 
						||
    Encadrer_couleur_menu(CM_Blanc);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
  // -- Recalculer l'origine de la palette dans le menu pour rendre la
 | 
						||
  //    Fore_color visible --
 | 
						||
 | 
						||
void Recadrer_palette(void)
 | 
						||
{
 | 
						||
  byte Ancienne_couleur=Couleur_debut_palette;
 | 
						||
 | 
						||
  if (Fore_color<Couleur_debut_palette)
 | 
						||
  {
 | 
						||
    while (Fore_color<Couleur_debut_palette)
 | 
						||
      Couleur_debut_palette-=8;
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    while (Fore_color>=Couleur_debut_palette+64)
 | 
						||
      Couleur_debut_palette+=8;
 | 
						||
  }
 | 
						||
  if (Ancienne_couleur!=Couleur_debut_palette)
 | 
						||
    Afficher_palette_du_menu();
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
  // -- Afficher la barre de s<>paration entre les parties zoom<6F>es ou non en
 | 
						||
  //    mode Loupe --
 | 
						||
 | 
						||
void Afficher_barre_de_split(void)
 | 
						||
{
 | 
						||
  // Partie grise du milieu
 | 
						||
  Block(Principal_Split+(Menu_Facteur_X<<1),Menu_Facteur_Y,
 | 
						||
        (LARGEUR_BARRE_SPLIT-4)*Menu_Facteur_X,
 | 
						||
        Menu_Ordonnee-(Menu_Facteur_Y<<1),CM_Clair);
 | 
						||
 | 
						||
  // Barre noire de gauche
 | 
						||
  Block(Principal_Split,0,Menu_Facteur_X,Menu_Ordonnee,CM_Noir);
 | 
						||
 | 
						||
  // Barre noire de droite
 | 
						||
  Block(Principal_X_Zoom-Menu_Facteur_X,0,Menu_Facteur_X,Menu_Ordonnee,CM_Noir);
 | 
						||
 | 
						||
  // Bord haut (blanc)
 | 
						||
  Block(Principal_Split+Menu_Facteur_X,0,
 | 
						||
        (LARGEUR_BARRE_SPLIT-3)*Menu_Facteur_X,Menu_Facteur_Y,CM_Blanc);
 | 
						||
 | 
						||
  // Bord gauche (blanc)
 | 
						||
  Block(Principal_Split+Menu_Facteur_X,Menu_Facteur_Y,
 | 
						||
        Menu_Facteur_X,(Menu_Ordonnee-(Menu_Facteur_Y<<1)),CM_Blanc);
 | 
						||
 | 
						||
  // Bord droite (gris fonc<6E>)
 | 
						||
  Block(Principal_X_Zoom-(Menu_Facteur_X<<1),Menu_Facteur_Y,
 | 
						||
        Menu_Facteur_X,(Menu_Ordonnee-(Menu_Facteur_Y<<1)),CM_Fonce);
 | 
						||
 | 
						||
  // Bord bas (gris fonc<6E>)
 | 
						||
  Block(Principal_Split+(Menu_Facteur_X<<1),Menu_Ordonnee-Menu_Facteur_Y,
 | 
						||
        (LARGEUR_BARRE_SPLIT-3)*Menu_Facteur_X,Menu_Facteur_Y,CM_Fonce);
 | 
						||
 | 
						||
  // Coin bas gauche
 | 
						||
  Block(Principal_Split+Menu_Facteur_X,Menu_Ordonnee-Menu_Facteur_Y,
 | 
						||
        Menu_Facteur_X,Menu_Facteur_Y,CM_Clair);
 | 
						||
  // Coin haut droite
 | 
						||
  Block(Principal_X_Zoom-(Menu_Facteur_X<<1),0,
 | 
						||
        Menu_Facteur_X,Menu_Facteur_Y,CM_Clair);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Afficher tout le menu --
 | 
						||
 | 
						||
void Afficher_menu(void)
 | 
						||
{
 | 
						||
  word Pos_X;
 | 
						||
  word Pos_Y;
 | 
						||
  char Chaine[4];
 | 
						||
 | 
						||
 | 
						||
  if (Menu_visible)
 | 
						||
  {
 | 
						||
    // Affichage du sprite du menu
 | 
						||
    for (Pos_Y=0;Pos_Y<HAUTEUR_MENU;Pos_Y++)
 | 
						||
      for (Pos_X=0;Pos_X<LARGEUR_MENU;Pos_X++)
 | 
						||
        Pixel_dans_menu(Pos_X,Pos_Y,BLOCK_MENU[Pos_Y][Pos_X]);
 | 
						||
    // Affichage de la bande grise sous la palette
 | 
						||
    Block(LARGEUR_MENU*Menu_Facteur_X,Menu_Ordonnee_Texte-Menu_Facteur_Y,Largeur_ecran-(LARGEUR_MENU*Menu_Facteur_X),9*Menu_Facteur_Y,CM_Clair);
 | 
						||
 | 
						||
    // Affichage de la palette
 | 
						||
    Afficher_palette_du_menu();
 | 
						||
 | 
						||
    // Affichage des couleurs de travail
 | 
						||
    Afficher_foreback();
 | 
						||
 | 
						||
    if (!Une_fenetre_est_ouverte)
 | 
						||
    {
 | 
						||
      if ((Mouse_Y<Menu_Ordonnee) &&
 | 
						||
          ( (!Loupe_Mode) || (Mouse_X<Principal_Split) || (Mouse_X>=Principal_X_Zoom) ))
 | 
						||
      {
 | 
						||
        if ( (Operation_en_cours!=OPERATION_PIPETTE)
 | 
						||
          && (Operation_en_cours!=OPERATION_REMPLACER) )
 | 
						||
          Print_dans_menu("X:       Y:             ",0);
 | 
						||
        else
 | 
						||
        {
 | 
						||
          Print_dans_menu("X:       Y:       (    )",0);
 | 
						||
          Num2str(Pipette_Couleur,Chaine,3);
 | 
						||
          Print_dans_menu(Chaine,20);
 | 
						||
          Print_general(170*Menu_Facteur_X,Menu_Ordonnee_Texte," ",0,Pipette_Couleur);
 | 
						||
        }
 | 
						||
        Print_coordonnees();
 | 
						||
      }
 | 
						||
      Print_nom_fichier();
 | 
						||
    }
 | 
						||
    SDL_UpdateRect(Ecran_SDL,0,Menu_Ordonnee,LARGEUR_MENU*Menu_Facteur_X,HAUTEUR_MENU*Menu_Facteur_Y);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// -- Affichage de texte -----------------------------------------------------
 | 
						||
 | 
						||
  // -- Afficher une cha<68>ne n'importe o<> <20> l'<27>cran --
 | 
						||
 | 
						||
void Print_general(short X,short Y,char * Chaine,byte Couleur_texte,byte Couleur_fond)
 | 
						||
{
 | 
						||
  word  Indice;
 | 
						||
  short Pos_X;
 | 
						||
  short Pos_Y;
 | 
						||
  char  Caractere;
 | 
						||
  short Reel_X;
 | 
						||
  short Reel_Y;
 | 
						||
  short Largeur;
 | 
						||
  short Repeat_Menu_Facteur_X;
 | 
						||
  short Repeat_Menu_Facteur_Y;
 | 
						||
 | 
						||
  Reel_Y=Y;
 | 
						||
  Largeur=strlen(Chaine)*Menu_Facteur_X*8;
 | 
						||
  for (Pos_Y=0;Pos_Y<8;Pos_Y++)
 | 
						||
  {
 | 
						||
    Reel_X=0; // Position dans le buffer
 | 
						||
    for (Indice=0;Chaine[Indice]!='\0';Indice++)
 | 
						||
    {
 | 
						||
      Caractere=Chaine[Indice];
 | 
						||
      for (Pos_X=0;Pos_X<8;Pos_X++)
 | 
						||
        for (Repeat_Menu_Facteur_X=0;Repeat_Menu_Facteur_X<Menu_Facteur_X;Repeat_Menu_Facteur_X++)
 | 
						||
          Buffer_de_ligne_horizontale[Reel_X++]=(*(Fonte+(Caractere<<6)+(Pos_X<<3)+Pos_Y)?Couleur_texte:Couleur_fond);
 | 
						||
    }
 | 
						||
    for (Repeat_Menu_Facteur_Y=0;Repeat_Menu_Facteur_Y<Menu_Facteur_Y;Repeat_Menu_Facteur_Y++)
 | 
						||
      Afficher_ligne(X,Reel_Y++,Largeur,Buffer_de_ligne_horizontale);
 | 
						||
  }
 | 
						||
  SDL_UpdateRect(Ecran_SDL,X,Y,Largeur,8*Menu_Facteur_Y);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Afficher un caract<63>re dans une fen<65>tre --
 | 
						||
 | 
						||
void Print_char_dans_fenetre(short Pos_X,short Pos_Y,char Caractere,byte Couleur_texte,byte Couleur_fond)
 | 
						||
{
 | 
						||
  short X,Y;
 | 
						||
 | 
						||
  Pos_X=(Pos_X*Menu_Facteur_X)+Fenetre_Pos_X;
 | 
						||
  Pos_Y=(Pos_Y*Menu_Facteur_Y)+Fenetre_Pos_Y;
 | 
						||
 | 
						||
  for (X=0;X<8;X++)
 | 
						||
    for (Y=0;Y<8;Y++)
 | 
						||
      Block(Pos_X+(X*Menu_Facteur_X), Pos_Y+(Y*Menu_Facteur_Y),
 | 
						||
            Menu_Facteur_X, Menu_Facteur_Y,
 | 
						||
            (*(Fonte+(Caractere<<6)+(X<<3)+Y)?Couleur_texte:Couleur_fond));
 | 
						||
}
 | 
						||
 | 
						||
  // -- Afficher un caract<63>re sans fond dans une fen<65>tre --
 | 
						||
 | 
						||
void Print_char_transparent_dans_fenetre(short Pos_X,short Pos_Y,char Caractere,byte Couleur)
 | 
						||
{
 | 
						||
  short X,Y;
 | 
						||
 | 
						||
  Pos_X=(Pos_X*Menu_Facteur_X)+Fenetre_Pos_X;
 | 
						||
  Pos_Y=(Pos_Y*Menu_Facteur_Y)+Fenetre_Pos_Y;
 | 
						||
 | 
						||
  for (X=0;X<8;X++)
 | 
						||
    for (Y=0;Y<8;Y++)
 | 
						||
    {
 | 
						||
      if (*(Fonte+(Caractere<<6)+(X<<3)+Y))
 | 
						||
        Block(Pos_X+(X*Menu_Facteur_X), Pos_Y+(Y*Menu_Facteur_Y),
 | 
						||
              Menu_Facteur_X, Menu_Facteur_Y, Couleur);
 | 
						||
    }
 | 
						||
}
 | 
						||
 | 
						||
  // -- Afficher une cha<68>ne dans une fen<65>tre --
 | 
						||
 | 
						||
void Print_dans_fenetre(short X,short Y,char * Chaine,byte Couleur_texte,byte Couleur_fond)
 | 
						||
{
 | 
						||
  Print_general((X*Menu_Facteur_X)+Fenetre_Pos_X,
 | 
						||
                (Y*Menu_Facteur_Y)+Fenetre_Pos_Y,
 | 
						||
                Chaine,Couleur_texte,Couleur_fond);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Afficher une cha<68>ne dans le menu --
 | 
						||
 | 
						||
void Print_dans_menu(char * Chaine, short Position)
 | 
						||
{
 | 
						||
  Print_general((18+(Position<<3))*Menu_Facteur_X,Menu_Ordonnee_Texte,Chaine,CM_Noir,CM_Clair);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Afficher les coordonn<6E>es du pinceau dans le menu --
 | 
						||
 | 
						||
void Print_coordonnees(void)
 | 
						||
{
 | 
						||
  char Tempo[5];
 | 
						||
 | 
						||
  if (Menu_visible)
 | 
						||
  {
 | 
						||
    if ( (Operation_en_cours==OPERATION_PIPETTE)
 | 
						||
      || (Operation_en_cours==OPERATION_REMPLACER) )
 | 
						||
    {
 | 
						||
      if ( (Pinceau_X>=0) && (Pinceau_Y>=0)
 | 
						||
        && (Pinceau_X<Principal_Largeur_image)
 | 
						||
        && (Pinceau_Y<Principal_Hauteur_image) )
 | 
						||
        Pipette_Couleur=Lit_pixel_dans_ecran_courant(Pinceau_X,Pinceau_Y);
 | 
						||
      else
 | 
						||
        Pipette_Couleur=0;
 | 
						||
      Pipette_X=Pinceau_X;
 | 
						||
      Pipette_Y=Pinceau_Y;
 | 
						||
 | 
						||
      Num2str(Pipette_Couleur,Tempo,3);
 | 
						||
      Print_dans_menu(Tempo,20);
 | 
						||
      Print_general(170*Menu_Facteur_X,Menu_Ordonnee_Texte," ",0,Pipette_Couleur);
 | 
						||
    }
 | 
						||
 | 
						||
    Num2str((dword)Pinceau_X,Tempo,4);
 | 
						||
    Print_dans_menu(Tempo,2);
 | 
						||
    Num2str((dword)Pinceau_Y,Tempo,4);
 | 
						||
    Print_dans_menu(Tempo,11);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
  // -- Afficher le nom du fichier dans le menu --
 | 
						||
 | 
						||
void Print_nom_fichier(void)
 | 
						||
{
 | 
						||
  short Debut_X;
 | 
						||
 | 
						||
  if (Menu_visible)
 | 
						||
  {
 | 
						||
    Block((LARGEUR_MENU+2+((Menu_Taille_couleur-12)<<3))*Menu_Facteur_X,
 | 
						||
          Menu_Ordonnee_Texte,Menu_Facteur_X*96,Menu_Facteur_Y<<3,CM_Clair);
 | 
						||
 | 
						||
    Debut_X=LARGEUR_MENU+2+((Menu_Taille_couleur-strlen(Principal_Nom_fichier))<<3);
 | 
						||
 | 
						||
    Print_general(Debut_X*Menu_Facteur_X,Menu_Ordonnee_Texte,Principal_Nom_fichier,CM_Noir,CM_Clair);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// -- Calcul des diff<66>rents effets -------------------------------------------
 | 
						||
 | 
						||
  // -- Aucun effet en cours --
 | 
						||
 | 
						||
byte Aucun_effet(word X,word Y,byte Couleur)
 | 
						||
{
 | 
						||
  return Couleur;
 | 
						||
}
 | 
						||
 | 
						||
  // -- Effet de Shading --
 | 
						||
 | 
						||
byte Effet_Shade(word X,word Y,byte Couleur)
 | 
						||
{
 | 
						||
  return Shade_Table[Lit_pixel_dans_ecran_feedback(X,Y)];
 | 
						||
}
 | 
						||
 | 
						||
byte Effet_Quick_shade(word X,word Y,byte Couleur)
 | 
						||
{
 | 
						||
  int C=Couleur=Lit_pixel_dans_ecran_feedback(X,Y);
 | 
						||
  int Sens=(Fore_color<=Back_color);
 | 
						||
  byte Debut,Fin;
 | 
						||
  int Largeur;
 | 
						||
 | 
						||
  if (Sens)
 | 
						||
  {
 | 
						||
    Debut=Fore_color;
 | 
						||
    Fin  =Back_color;
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    Debut=Back_color;
 | 
						||
    Fin  =Fore_color;
 | 
						||
  }
 | 
						||
 | 
						||
  if ((C>=Debut) && (C<=Fin) && (Debut!=Fin))
 | 
						||
  {
 | 
						||
    Largeur=1+Fin-Debut;
 | 
						||
 | 
						||
    if ( ((Mouse_K==A_GAUCHE) && Sens) || ((Mouse_K==A_DROITE) && (!Sens)) )
 | 
						||
      C-=Quick_shade_Step%Largeur;
 | 
						||
    else
 | 
						||
      C+=Quick_shade_Step%Largeur;
 | 
						||
 | 
						||
    if (C<Debut)
 | 
						||
      switch (Quick_shade_Loop)
 | 
						||
      {
 | 
						||
        case MODE_SHADE_NORMAL : return Debut;
 | 
						||
        case MODE_SHADE_BOUCLE : return (Largeur+C);
 | 
						||
        default : return Couleur;
 | 
						||
      }
 | 
						||
 | 
						||
    if (C>Fin)
 | 
						||
      switch (Quick_shade_Loop)
 | 
						||
      {
 | 
						||
        case MODE_SHADE_NORMAL : return Fin;
 | 
						||
        case MODE_SHADE_BOUCLE : return (C-Largeur);
 | 
						||
        default : return Couleur;
 | 
						||
      }
 | 
						||
  }
 | 
						||
 | 
						||
  return C;
 | 
						||
}
 | 
						||
 | 
						||
  // -- Effet de Tiling --
 | 
						||
 | 
						||
byte Effet_Tiling(word X,word Y,byte Couleur)
 | 
						||
{
 | 
						||
  return Lit_pixel_dans_brosse((X+Brosse_Largeur-Tiling_Decalage_X)%Brosse_Largeur,
 | 
						||
                               (Y+Brosse_Hauteur-Tiling_Decalage_Y)%Brosse_Hauteur);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Effet de Smooth --
 | 
						||
 | 
						||
byte Effet_Smooth(word X,word Y,byte Couleur)
 | 
						||
{
 | 
						||
  int R,V,B;
 | 
						||
  byte C;
 | 
						||
  int Poids,Poids_total;
 | 
						||
  byte X2=((X+1)<Principal_Largeur_image);
 | 
						||
  byte Y2=((Y+1)<Principal_Hauteur_image);
 | 
						||
 | 
						||
  // On commence par le pixel central
 | 
						||
  C=Lit_pixel_dans_ecran_feedback(X,Y);
 | 
						||
  Poids_total=Smooth_Matrice[1][1];
 | 
						||
  R=Poids_total*Principal_Palette[C].R;
 | 
						||
  V=Poids_total*Principal_Palette[C].V;
 | 
						||
  B=Poids_total*Principal_Palette[C].B;
 | 
						||
 | 
						||
  if (X)
 | 
						||
  {
 | 
						||
    C=Lit_pixel_dans_ecran_feedback(X-1,Y);
 | 
						||
    Poids_total+=(Poids=Smooth_Matrice[0][1]);
 | 
						||
    R+=Poids*Principal_Palette[C].R;
 | 
						||
    V+=Poids*Principal_Palette[C].V;
 | 
						||
    B+=Poids*Principal_Palette[C].B;
 | 
						||
 | 
						||
    if (Y)
 | 
						||
    {
 | 
						||
      C=Lit_pixel_dans_ecran_feedback(X-1,Y-1);
 | 
						||
      Poids_total+=(Poids=Smooth_Matrice[0][0]);
 | 
						||
      R+=Poids*Principal_Palette[C].R;
 | 
						||
      V+=Poids*Principal_Palette[C].V;
 | 
						||
      B+=Poids*Principal_Palette[C].B;
 | 
						||
 | 
						||
      if (Y2)
 | 
						||
      {
 | 
						||
        C=Lit_pixel_dans_ecran_feedback(X-1,Y+1);
 | 
						||
        Poids_total+=(Poids=Smooth_Matrice[0][2]);
 | 
						||
        R+=Poids*Principal_Palette[C].R;
 | 
						||
        V+=Poids*Principal_Palette[C].V;
 | 
						||
        B+=Poids*Principal_Palette[C].B;
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  if (X2)
 | 
						||
  {
 | 
						||
    C=Lit_pixel_dans_ecran_feedback(X+1,Y);
 | 
						||
    Poids_total+=(Poids=Smooth_Matrice[2][1]);
 | 
						||
    R+=Poids*Principal_Palette[C].R;
 | 
						||
    V+=Poids*Principal_Palette[C].V;
 | 
						||
    B+=Poids*Principal_Palette[C].B;
 | 
						||
 | 
						||
    if (Y)
 | 
						||
    {
 | 
						||
      C=Lit_pixel_dans_ecran_feedback(X+1,Y-1);
 | 
						||
      Poids_total+=(Poids=Smooth_Matrice[2][0]);
 | 
						||
      R+=Poids*Principal_Palette[C].R;
 | 
						||
      V+=Poids*Principal_Palette[C].V;
 | 
						||
      B+=Poids*Principal_Palette[C].B;
 | 
						||
 | 
						||
      if (Y2)
 | 
						||
      {
 | 
						||
        C=Lit_pixel_dans_ecran_feedback(X+1,Y+1);
 | 
						||
        Poids_total+=(Poids=Smooth_Matrice[2][2]);
 | 
						||
        R+=Poids*Principal_Palette[C].R;
 | 
						||
        V+=Poids*Principal_Palette[C].V;
 | 
						||
        B+=Poids*Principal_Palette[C].B;
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  if (Y)
 | 
						||
  {
 | 
						||
    C=Lit_pixel_dans_ecran_feedback(X,Y-1);
 | 
						||
    Poids_total+=(Poids=Smooth_Matrice[1][0]);
 | 
						||
    R+=Poids*Principal_Palette[C].R;
 | 
						||
    V+=Poids*Principal_Palette[C].V;
 | 
						||
    B+=Poids*Principal_Palette[C].B;
 | 
						||
  }
 | 
						||
 | 
						||
  if (Y2)
 | 
						||
  {
 | 
						||
    C=Lit_pixel_dans_ecran_feedback(X,Y+1);
 | 
						||
    Poids_total+=(Poids=Smooth_Matrice[1][2]);
 | 
						||
    R+=Poids*Principal_Palette[C].R;
 | 
						||
    V+=Poids*Principal_Palette[C].V;
 | 
						||
    B+=Poids*Principal_Palette[C].B;
 | 
						||
  }
 | 
						||
 | 
						||
  return (Poids_total)? // On regarde s'il faut <20>viter le 0/0.
 | 
						||
    Meilleure_couleur(Round_div(R,Poids_total),
 | 
						||
                      Round_div(V,Poids_total),
 | 
						||
                      Round_div(B,Poids_total)):
 | 
						||
    Lit_pixel_dans_ecran_courant(X,Y); // C'est bien l'<27>cran courant et pas
 | 
						||
                                       // l'<27>cran feedback car il s'agit de ne
 | 
						||
}                                      // pas modifier l'<27>cran courant.
 | 
						||
 | 
						||
 | 
						||
 | 
						||
// -- Fonctions de manipulation du pinceau -----------------------------------
 | 
						||
 | 
						||
  // -- Calcul de redimensionnement du pinceau pour <20>viter les d<>bordements
 | 
						||
  //    de l'<27>cran et de l'image --
 | 
						||
 | 
						||
void Calculer_dimensions_clipees(short * X,short * Y,short * Largeur,short * Hauteur)
 | 
						||
{
 | 
						||
  if ((*X)<Limite_Gauche)
 | 
						||
  {
 | 
						||
    (*Largeur)-=(Limite_Gauche-(*X));
 | 
						||
    (*X)=Limite_Gauche;
 | 
						||
  }
 | 
						||
 | 
						||
  if (((*X)+(*Largeur))>(Limite_Droite+1))
 | 
						||
  {
 | 
						||
    (*Largeur)=(Limite_Droite-(*X))+1;
 | 
						||
  }
 | 
						||
 | 
						||
  if ((*Y)<Limite_Haut)
 | 
						||
  {
 | 
						||
    (*Hauteur)-=(Limite_Haut-(*Y));
 | 
						||
    (*Y)=Limite_Haut;
 | 
						||
  }
 | 
						||
 | 
						||
  if (((*Y)+(*Hauteur))>(Limite_Bas+1))
 | 
						||
  {
 | 
						||
    (*Hauteur)=(Limite_Bas-(*Y))+1;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
  // -- Calcul de redimensionnement du pinceau pour <20>viter les d<>bordements
 | 
						||
  //    de l'<27>cran zoom<6F> et de l'image --
 | 
						||
 | 
						||
void Calculer_dimensions_clipees_zoom(short * X,short * Y,short * Largeur,short * Hauteur)
 | 
						||
{
 | 
						||
  if ((*X)<Limite_Gauche_Zoom)
 | 
						||
  {
 | 
						||
    (*Largeur)-=(Limite_Gauche_Zoom-(*X));
 | 
						||
    (*X)=Limite_Gauche_Zoom;
 | 
						||
  }
 | 
						||
 | 
						||
  if (((*X)+(*Largeur))>(Limite_Droite_Zoom+1))
 | 
						||
  {
 | 
						||
    (*Largeur)=(Limite_Droite_Zoom-(*X))+1;
 | 
						||
  }
 | 
						||
 | 
						||
  if ((*Y)<Limite_Haut_Zoom)
 | 
						||
  {
 | 
						||
    (*Hauteur)-=(Limite_Haut_Zoom-(*Y));
 | 
						||
    (*Y)=Limite_Haut_Zoom;
 | 
						||
  }
 | 
						||
 | 
						||
  if (((*Y)+(*Hauteur))>(Limite_Bas_Zoom+1))
 | 
						||
  {
 | 
						||
    (*Hauteur)=(Limite_Bas_Zoom-(*Y))+1;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
  // -- Afficher le pinceau (de fa<66>on d<>finitive ou non) --
 | 
						||
 | 
						||
void Afficher_pinceau(short X,short Y,byte Couleur,byte Preview)
 | 
						||
  // X,Y: position du centre du pinceau
 | 
						||
  // Couleur: couleur <20> appliquer au pinceau
 | 
						||
  // Preview: "Il ne faut l'afficher qu'<27> l'<27>cran"
 | 
						||
{
 | 
						||
  short Debut_X; // Position X (dans l'image) <20> partir de laquelle on 
 | 
						||
        // affiche la brosse/pinceau
 | 
						||
  short Debut_Y; // Position Y (dans l'image) <20> partir de laquelle on 
 | 
						||
        // affiche la brosse/pinceau
 | 
						||
  short Largeur; // Largeur dans l'<27>cran selon laquelle on affiche la 
 | 
						||
        // brosse/pinceau
 | 
						||
  short Hauteur; // Hauteur dans l'<27>cran selon laquelle on affiche la 
 | 
						||
        // brosse/pinceau
 | 
						||
  short Debut_Compteur_X; // Position X (dans la brosse/pinceau) <20> partir 
 | 
						||
        // de laquelle on affiche la brosse/pinceau
 | 
						||
  short Debut_Compteur_Y; // Position Y (dans la brosse/pinceau) <20> partir 
 | 
						||
        // de laquelle on affiche la brosse/pinceau
 | 
						||
  short Pos_X; // Position X (dans l'image) en cours d'affichage
 | 
						||
  short Pos_Y; // Position Y (dans l'image) en cours d'affichage
 | 
						||
  short Compteur_X; // Position X (dans la brosse/pinceau) en cours 
 | 
						||
        // d'affichage
 | 
						||
  short Compteur_Y; // Position Y (dans la brosse/pinceau) en cours 
 | 
						||
        // d'affichage
 | 
						||
  short Fin_Compteur_X; // Position X ou s'arr<72>te l'affichade de la 
 | 
						||
        // brosse/pinceau
 | 
						||
  short Fin_Compteur_Y; // Position Y ou s'arr<72>te l'affichade de la 
 | 
						||
        // brosse/pinceau
 | 
						||
  byte  Couleur_temporaire; // Couleur de la brosse en cours d'affichage
 | 
						||
  int Position;
 | 
						||
  byte * Temp;
 | 
						||
 | 
						||
  #define UpdateZoom(X,Y,w,h) if((Y)>= Limite_Haut_Zoom && (Y) <= Limite_visible_Bas_Zoom && (X)>= Limite_Gauche_Zoom && (X) <= Limite_visible_Droite_Zoom) SDL_UpdateRect(Ecran_SDL,Table_mul_facteur_zoom[(X)-Loupe_Decalage_X]+Principal_X_Zoom,((Y)-Loupe_Decalage_Y)*Loupe_Facteur,(w)*Loupe_Facteur,(h)*Loupe_Facteur)
 | 
						||
  if (!(Preview && Mouse_K)) // Si bouton enfonc<6E> & preview > pas de dessin
 | 
						||
  switch (Pinceau_Forme)
 | 
						||
  {
 | 
						||
    case FORME_PINCEAU_POINT : // !!! TOUJOURS EN PREVIEW !!!
 | 
						||
      if ( (Pinceau_X>=Limite_Gauche)
 | 
						||
        && (Pinceau_X<=Limite_Droite)
 | 
						||
        && (Pinceau_Y>=Limite_Haut)
 | 
						||
        && (Pinceau_Y<=Limite_Bas) )
 | 
						||
        {
 | 
						||
                Pixel_Preview(Pinceau_X,Pinceau_Y,Couleur);
 | 
						||
                SDL_UpdateRect(Ecran_SDL, 
 | 
						||
                        Max(Pinceau_X - Principal_Decalage_X,0), 
 | 
						||
                        Max(Pinceau_Y - Principal_Decalage_Y,0), 1,1 );
 | 
						||
                // Attention au zoom !
 | 
						||
                if(Loupe_Mode) UpdateZoom(X,Y,1,1);
 | 
						||
        }
 | 
						||
      break;
 | 
						||
 | 
						||
    case FORME_PINCEAU_BROSSE_COULEUR : // Brosse en couleur
 | 
						||
 | 
						||
      Debut_X=X-Brosse_Decalage_X;
 | 
						||
      Debut_Y=Y-Brosse_Decalage_Y;
 | 
						||
      Largeur=Brosse_Largeur;
 | 
						||
      Hauteur=Brosse_Hauteur;
 | 
						||
      Calculer_dimensions_clipees(&Debut_X,&Debut_Y,&Largeur,&Hauteur);
 | 
						||
      Debut_Compteur_X=Debut_X-(X-Brosse_Decalage_X);
 | 
						||
      Debut_Compteur_Y=Debut_Y-(Y-Brosse_Decalage_Y);
 | 
						||
      Fin_Compteur_X=Debut_Compteur_X+Largeur;
 | 
						||
      Fin_Compteur_Y=Debut_Compteur_Y+Hauteur;
 | 
						||
 | 
						||
      if (Preview)
 | 
						||
      {
 | 
						||
        if ( (Largeur>0) && (Hauteur>0) )
 | 
						||
          Display_brush_Color(
 | 
						||
                Debut_X-Principal_Decalage_X,
 | 
						||
                Debut_Y-Principal_Decalage_Y,
 | 
						||
                Debut_Compteur_X,
 | 
						||
                Debut_Compteur_Y,
 | 
						||
                Largeur,
 | 
						||
                Hauteur,
 | 
						||
                Back_color,
 | 
						||
                Brosse_Largeur
 | 
						||
          );
 | 
						||
 | 
						||
        if (Loupe_Mode)
 | 
						||
        {
 | 
						||
          Calculer_dimensions_clipees_zoom(&Debut_X,&Debut_Y,&Largeur,
 | 
						||
                &Hauteur
 | 
						||
          );
 | 
						||
 | 
						||
          Debut_Compteur_X=Debut_X-(X-Brosse_Decalage_X);
 | 
						||
          Debut_Compteur_Y=Debut_Y-(Y-Brosse_Decalage_Y);
 | 
						||
 | 
						||
          if ( (Largeur>0) && (Hauteur>0) )
 | 
						||
          {
 | 
						||
            // Corrections dues au Zoom:
 | 
						||
            Debut_X=(Debut_X-Loupe_Decalage_X)*Loupe_Facteur;
 | 
						||
            Debut_Y=(Debut_Y-Loupe_Decalage_Y)*Loupe_Facteur;
 | 
						||
            Hauteur=Debut_Y+(Hauteur*Loupe_Facteur);
 | 
						||
            if (Hauteur>Menu_Ordonnee)
 | 
						||
              Hauteur=Menu_Ordonnee;
 | 
						||
 | 
						||
            Display_brush_Color_zoom(Principal_X_Zoom+Debut_X,Debut_Y,
 | 
						||
                                     Debut_Compteur_X,Debut_Compteur_Y,
 | 
						||
                                     Largeur,Hauteur,Back_color,
 | 
						||
                                     Brosse_Largeur,
 | 
						||
                                     Buffer_de_ligne_horizontale);
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {
 | 
						||
        if ((Smear_Mode) && (Shade_Table==Shade_Table_gauche))
 | 
						||
        {
 | 
						||
          if (Smear_Debut)
 | 
						||
          {
 | 
						||
            if ((Largeur>0) && (Hauteur>0))
 | 
						||
            {
 | 
						||
              Copier_une_partie_d_image_dans_une_autre(
 | 
						||
                Principal_Ecran, Debut_X, Debut_Y, Largeur, Hauteur,
 | 
						||
                Principal_Largeur_image, Smear_Brosse,
 | 
						||
                Debut_Compteur_X, Debut_Compteur_Y,
 | 
						||
                Smear_Brosse_Largeur
 | 
						||
              );
 | 
						||
              // UPDATERECT
 | 
						||
            }
 | 
						||
            Smear_Debut=0;
 | 
						||
          }
 | 
						||
          else
 | 
						||
          {
 | 
						||
            for (Pos_Y = Debut_Y, Compteur_Y = Debut_Compteur_Y;
 | 
						||
                Compteur_Y < Fin_Compteur_Y;
 | 
						||
                Pos_Y++, Compteur_Y++
 | 
						||
            )
 | 
						||
              for (Pos_X = Debut_X, Compteur_X = Debut_Compteur_X;
 | 
						||
                Compteur_X < Fin_Compteur_X;
 | 
						||
                Pos_X++, Compteur_X++
 | 
						||
              )
 | 
						||
              {
 | 
						||
                Couleur_temporaire = Lit_pixel_dans_ecran_courant(
 | 
						||
                        Pos_X,Pos_Y
 | 
						||
                );
 | 
						||
                Position = (Compteur_Y * Smear_Brosse_Largeur)+ Compteur_X;
 | 
						||
                if ( (Lit_pixel_dans_brosse(Compteur_X,Compteur_Y) != Back_color)
 | 
						||
                  && (Compteur_Y<Smear_Max_Y) && (Compteur_X<Smear_Max_X)
 | 
						||
                  && (Compteur_Y>=Smear_Min_Y) && (Compteur_X>=Smear_Min_X) )
 | 
						||
                        Afficher_pixel(Pos_X,Pos_Y,Smear_Brosse[Position]);
 | 
						||
                Smear_Brosse[Position]=Couleur_temporaire;
 | 
						||
              }
 | 
						||
 | 
						||
              SDL_UpdateRect(Ecran_SDL,Max(Debut_X,0),Max(Debut_Y,0), 
 | 
						||
                Fin_Compteur_X,Fin_Compteur_Y );
 | 
						||
          }
 | 
						||
 | 
						||
          Smear_Min_X=Debut_Compteur_X;
 | 
						||
          Smear_Min_Y=Debut_Compteur_Y;
 | 
						||
          Smear_Max_X=Fin_Compteur_X;
 | 
						||
          Smear_Max_Y=Fin_Compteur_Y;
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          if (Shade_Table==Shade_Table_gauche)
 | 
						||
            for (Pos_Y=Debut_Y,Compteur_Y=Debut_Compteur_Y;Compteur_Y<Fin_Compteur_Y;Pos_Y++,Compteur_Y++)
 | 
						||
              for (Pos_X=Debut_X,Compteur_X=Debut_Compteur_X;Compteur_X<Fin_Compteur_X;Pos_X++,Compteur_X++)
 | 
						||
              {
 | 
						||
                Couleur_temporaire=Lit_pixel_dans_brosse(Compteur_X,Compteur_Y);
 | 
						||
                if (Couleur_temporaire!=Back_color)
 | 
						||
                  Afficher_pixel(Pos_X,Pos_Y,Couleur_temporaire);
 | 
						||
              }
 | 
						||
          else
 | 
						||
            for (Pos_Y=Debut_Y,Compteur_Y=Debut_Compteur_Y;Compteur_Y<Fin_Compteur_Y;Pos_Y++,Compteur_Y++)
 | 
						||
              for (Pos_X=Debut_X,Compteur_X=Debut_Compteur_X;Compteur_X<Fin_Compteur_X;Pos_X++,Compteur_X++)
 | 
						||
              {
 | 
						||
                if (Lit_pixel_dans_brosse(Compteur_X,Compteur_Y)!=Back_color)
 | 
						||
                  Afficher_pixel(Pos_X,Pos_Y,Couleur);
 | 
						||
              }
 | 
						||
        }
 | 
						||
        SDL_UpdateRect(Ecran_SDL, Max(Debut_X,0), Max(Debut_Y,0), Fin_Compteur_X, Fin_Compteur_Y);
 | 
						||
 | 
						||
      }
 | 
						||
      break;
 | 
						||
    case FORME_PINCEAU_BROSSE_MONOCHROME : // Brosse monochrome
 | 
						||
      Debut_X=X-Brosse_Decalage_X;
 | 
						||
      Debut_Y=Y-Brosse_Decalage_Y;
 | 
						||
      Largeur=Brosse_Largeur;
 | 
						||
      Hauteur=Brosse_Hauteur;
 | 
						||
      Calculer_dimensions_clipees(&Debut_X,&Debut_Y,&Largeur,&Hauteur);
 | 
						||
      Debut_Compteur_X=Debut_X-(X-Brosse_Decalage_X);
 | 
						||
      Debut_Compteur_Y=Debut_Y-(Y-Brosse_Decalage_Y);
 | 
						||
      Fin_Compteur_X=Debut_Compteur_X+Largeur;
 | 
						||
      Fin_Compteur_Y=Debut_Compteur_Y+Hauteur;
 | 
						||
      if (Preview)
 | 
						||
      {
 | 
						||
        if ( (Largeur>0) && (Hauteur>0) )
 | 
						||
          Display_brush_Mono(Debut_X-Principal_Decalage_X,
 | 
						||
                             Debut_Y-Principal_Decalage_Y,
 | 
						||
                             Debut_Compteur_X,Debut_Compteur_Y,
 | 
						||
                             Largeur,Hauteur,
 | 
						||
                             Back_color,Fore_color,
 | 
						||
                             Brosse_Largeur);
 | 
						||
 | 
						||
        if (Loupe_Mode)
 | 
						||
        {
 | 
						||
          Calculer_dimensions_clipees_zoom(&Debut_X,&Debut_Y,&Largeur,&Hauteur);
 | 
						||
          Debut_Compteur_X=Debut_X-(X-Brosse_Decalage_X);
 | 
						||
          Debut_Compteur_Y=Debut_Y-(Y-Brosse_Decalage_Y);
 | 
						||
 | 
						||
          if ( (Largeur>0) && (Hauteur>0) )
 | 
						||
          {
 | 
						||
            // Corrections dues au Zoom:
 | 
						||
            Debut_X=(Debut_X-Loupe_Decalage_X)*Loupe_Facteur;
 | 
						||
            Debut_Y=(Debut_Y-Loupe_Decalage_Y)*Loupe_Facteur;
 | 
						||
            Hauteur=Debut_Y+(Hauteur*Loupe_Facteur);
 | 
						||
            if (Hauteur>Menu_Ordonnee)
 | 
						||
              Hauteur=Menu_Ordonnee;
 | 
						||
 | 
						||
            Display_brush_Mono_zoom(Principal_X_Zoom+Debut_X,Debut_Y,
 | 
						||
                                    Debut_Compteur_X,Debut_Compteur_Y,
 | 
						||
                                    Largeur,Hauteur,
 | 
						||
                                    Back_color,Fore_color,
 | 
						||
                                    Brosse_Largeur,
 | 
						||
                                    Buffer_de_ligne_horizontale);
 | 
						||
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {
 | 
						||
        if ((Smear_Mode) && (Shade_Table==Shade_Table_gauche))
 | 
						||
        {
 | 
						||
          if (Smear_Debut)
 | 
						||
          {
 | 
						||
            if ((Largeur>0) && (Hauteur>0))
 | 
						||
              Copier_une_partie_d_image_dans_une_autre(Principal_Ecran,
 | 
						||
                                                       Debut_X,Debut_Y,
 | 
						||
                                                       Largeur,Hauteur,
 | 
						||
                                                       Principal_Largeur_image,
 | 
						||
                                                       Smear_Brosse,
 | 
						||
                                                       Debut_Compteur_X,
 | 
						||
                                                       Debut_Compteur_Y,
 | 
						||
                                                       Smear_Brosse_Largeur);
 | 
						||
                                                       //UPDATERECT
 | 
						||
            Smear_Debut=0;
 | 
						||
          }
 | 
						||
          else
 | 
						||
          {
 | 
						||
            for (Pos_Y=Debut_Y,Compteur_Y=Debut_Compteur_Y;Compteur_Y<Fin_Compteur_Y;Pos_Y++,Compteur_Y++)
 | 
						||
              for (Pos_X=Debut_X,Compteur_X=Debut_Compteur_X;Compteur_X<Fin_Compteur_X;Pos_X++,Compteur_X++)
 | 
						||
              {
 | 
						||
                Couleur_temporaire=Lit_pixel_dans_ecran_courant(Pos_X,Pos_Y);
 | 
						||
                Position=(Compteur_Y*Smear_Brosse_Largeur)+Compteur_X;
 | 
						||
                if ( (Lit_pixel_dans_brosse(Compteur_X,Compteur_Y)!=Back_color)
 | 
						||
                  && (Compteur_Y<Smear_Max_Y) && (Compteur_X<Smear_Max_X)
 | 
						||
                  && (Compteur_Y>=Smear_Min_Y) && (Compteur_X>=Smear_Min_X) )
 | 
						||
                  Afficher_pixel(Pos_X,Pos_Y,Smear_Brosse[Position]);
 | 
						||
                Smear_Brosse[Position]=Couleur_temporaire;
 | 
						||
              }
 | 
						||
 | 
						||
              SDL_UpdateRect(Ecran_SDL,Max(Debut_X,0),Max(Debut_Y,0),
 | 
						||
                Fin_Compteur_X,Fin_Compteur_Y
 | 
						||
              );
 | 
						||
 | 
						||
          }
 | 
						||
 | 
						||
          Smear_Min_X=Debut_Compteur_X;
 | 
						||
          Smear_Min_Y=Debut_Compteur_Y;
 | 
						||
          Smear_Max_X=Fin_Compteur_X;
 | 
						||
          Smear_Max_Y=Fin_Compteur_Y;
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          for (Pos_Y=Debut_Y,Compteur_Y=Debut_Compteur_Y;Compteur_Y<Fin_Compteur_Y;Pos_Y++,Compteur_Y++)
 | 
						||
            for (Pos_X=Debut_X,Compteur_X=Debut_Compteur_X;Compteur_X<Fin_Compteur_X;Pos_X++,Compteur_X++)
 | 
						||
            {
 | 
						||
              if (Lit_pixel_dans_brosse(Compteur_X,Compteur_Y)!=Back_color)
 | 
						||
                Afficher_pixel(Pos_X,Pos_Y,Couleur);
 | 
						||
            }
 | 
						||
//ok
 | 
						||
          SDL_UpdateRect(Ecran_SDL,
 | 
						||
                Max(Debut_X-Principal_Decalage_X,0),
 | 
						||
                Max(Debut_Y-Principal_Decalage_Y,0),
 | 
						||
                Fin_Compteur_X-Debut_Compteur_X,Fin_Compteur_Y-Debut_Compteur_Y
 | 
						||
          );
 | 
						||
          DEBUG("X",Debut_X-Principal_Decalage_X);
 | 
						||
          DEBUG("Y",Debut_Y-Principal_Decalage_Y);
 | 
						||
          DEBUG("W",Fin_Compteur_X-Debut_Compteur_X);
 | 
						||
          DEBUG("H",Fin_Compteur_Y-Debut_Compteur_Y);
 | 
						||
          if(Loupe_Mode) UpdateZoom(Debut_X,Debut_Y,Fin_Compteur_X-Debut_Compteur_X,Fin_Compteur_Y-Debut_Compteur_Y);
 | 
						||
        }
 | 
						||
      }
 | 
						||
      break;
 | 
						||
    default : // Pinceau
 | 
						||
      Debut_X=X-Pinceau_Decalage_X;
 | 
						||
      Debut_Y=Y-Pinceau_Decalage_Y;
 | 
						||
      Largeur=Pinceau_Largeur;
 | 
						||
      Hauteur=Pinceau_Hauteur;
 | 
						||
      Calculer_dimensions_clipees(&Debut_X,&Debut_Y,&Largeur,&Hauteur);
 | 
						||
      Debut_Compteur_X=Debut_X-(X-Pinceau_Decalage_X);
 | 
						||
      Debut_Compteur_Y=Debut_Y-(Y-Pinceau_Decalage_Y);
 | 
						||
      Fin_Compteur_X=Debut_Compteur_X+Largeur;
 | 
						||
      Fin_Compteur_Y=Debut_Compteur_Y+Hauteur;
 | 
						||
      if (Preview)
 | 
						||
      {
 | 
						||
        Temp=Brosse;
 | 
						||
        Brosse=Pinceau_Sprite;
 | 
						||
 | 
						||
        if ( (Largeur>0) && (Hauteur>0) )
 | 
						||
          Display_brush_Mono(Debut_X-Principal_Decalage_X,
 | 
						||
                             Debut_Y-Principal_Decalage_Y,
 | 
						||
                             Debut_Compteur_X,Debut_Compteur_Y,
 | 
						||
                             Largeur,Hauteur,
 | 
						||
                             0,Fore_color,
 | 
						||
                             TAILLE_MAXI_PINCEAU);
 | 
						||
 | 
						||
        if (Loupe_Mode)
 | 
						||
        {
 | 
						||
          Calculer_dimensions_clipees_zoom(&Debut_X,&Debut_Y,&Largeur,&Hauteur);
 | 
						||
          Debut_Compteur_X=Debut_X-(X-Pinceau_Decalage_X);
 | 
						||
          Debut_Compteur_Y=Debut_Y-(Y-Pinceau_Decalage_Y);
 | 
						||
 | 
						||
          if ( (Largeur>0) && (Hauteur>0) )
 | 
						||
          {
 | 
						||
            // Corrections dues au Zoom:
 | 
						||
            Debut_X=(Debut_X-Loupe_Decalage_X)*Loupe_Facteur;
 | 
						||
            Debut_Y=(Debut_Y-Loupe_Decalage_Y)*Loupe_Facteur;
 | 
						||
            Hauteur=Debut_Y+(Hauteur*Loupe_Facteur);
 | 
						||
            if (Hauteur>Menu_Ordonnee)
 | 
						||
              Hauteur=Menu_Ordonnee;
 | 
						||
 | 
						||
            Display_brush_Mono_zoom(Principal_X_Zoom+Debut_X,Debut_Y,
 | 
						||
                                    Debut_Compteur_X,Debut_Compteur_Y,
 | 
						||
                                    Largeur,Hauteur,
 | 
						||
                                    0,Fore_color,
 | 
						||
                                    TAILLE_MAXI_PINCEAU,
 | 
						||
                                    Buffer_de_ligne_horizontale);
 | 
						||
 | 
						||
          }
 | 
						||
        }
 | 
						||
 | 
						||
        Brosse=Temp;
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {
 | 
						||
        if ((Smear_Mode) && (Shade_Table==Shade_Table_gauche))
 | 
						||
        {
 | 
						||
          if (Smear_Debut)
 | 
						||
          {
 | 
						||
            if ((Largeur>0) && (Hauteur>0))
 | 
						||
              Copier_une_partie_d_image_dans_une_autre(Principal_Ecran,
 | 
						||
                                                       Debut_X,Debut_Y,
 | 
						||
                                                       Largeur,Hauteur,
 | 
						||
                                                       Principal_Largeur_image,
 | 
						||
                                                       Smear_Brosse,
 | 
						||
                                                       Debut_Compteur_X,
 | 
						||
                                                       Debut_Compteur_Y,
 | 
						||
                                                       Smear_Brosse_Largeur);
 | 
						||
            // UPDATERECT
 | 
						||
            Smear_Debut=0;
 | 
						||
          }
 | 
						||
          else
 | 
						||
          {
 | 
						||
            for (Pos_Y=Debut_Y,Compteur_Y=Debut_Compteur_Y;Compteur_Y<Fin_Compteur_Y;Pos_Y++,Compteur_Y++)
 | 
						||
              for (Pos_X=Debut_X,Compteur_X=Debut_Compteur_X;Compteur_X<Fin_Compteur_X;Pos_X++,Compteur_X++)
 | 
						||
              {
 | 
						||
                Couleur_temporaire=Lit_pixel_dans_ecran_courant(Pos_X,Pos_Y);
 | 
						||
                Position=(Compteur_Y*Smear_Brosse_Largeur)+Compteur_X;
 | 
						||
                if ( (Pinceau_Sprite[(TAILLE_MAXI_PINCEAU*Compteur_Y)+Compteur_X])
 | 
						||
                  && (Compteur_Y<Smear_Max_Y) && (Compteur_X<Smear_Max_X)
 | 
						||
                  && (Compteur_Y>=Smear_Min_Y) && (Compteur_X>=Smear_Min_X) )
 | 
						||
                  Afficher_pixel(Pos_X,Pos_Y,Smear_Brosse[Position]);
 | 
						||
                Smear_Brosse[Position]=Couleur_temporaire;
 | 
						||
              }
 | 
						||
          }
 | 
						||
 | 
						||
          SDL_UpdateRect(Ecran_SDL,Debut_X,Debut_Y,
 | 
						||
                Fin_Compteur_X,Fin_Compteur_Y
 | 
						||
          );
 | 
						||
 | 
						||
          Smear_Min_X=Debut_Compteur_X;
 | 
						||
          Smear_Min_Y=Debut_Compteur_Y;
 | 
						||
          Smear_Max_X=Fin_Compteur_X;
 | 
						||
          Smear_Max_Y=Fin_Compteur_Y;
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          for (Pos_Y=Debut_Y,Compteur_Y=Debut_Compteur_Y;Compteur_Y<Fin_Compteur_Y;Pos_Y++,Compteur_Y++)
 | 
						||
            for (Pos_X=Debut_X,Compteur_X=Debut_Compteur_X;Compteur_X<Fin_Compteur_X;Pos_X++,Compteur_X++)
 | 
						||
            {
 | 
						||
              if (Pinceau_Sprite[(TAILLE_MAXI_PINCEAU*Compteur_Y)+Compteur_X])
 | 
						||
                Afficher_pixel(Pos_X,Pos_Y,Couleur);
 | 
						||
            }
 | 
						||
// Ceci est test<73> et fonctionne :)
 | 
						||
          if(Fin_Compteur_X-Debut_Compteur_X > 0 
 | 
						||
                && Fin_Compteur_Y - Debut_Compteur_Y > 0)
 | 
						||
          {
 | 
						||
                SDL_UpdateRect(Ecran_SDL,
 | 
						||
                        Max(Debut_X-Principal_Decalage_X,1),
 | 
						||
                        Max(Debut_Y-Principal_Decalage_Y,1),
 | 
						||
                        Fin_Compteur_X-Debut_Compteur_X,
 | 
						||
                        Fin_Compteur_Y-Debut_Compteur_Y
 | 
						||
                );
 | 
						||
 | 
						||
                if(Loupe_Mode) 
 | 
						||
                        UpdateZoom(Debut_X,Debut_Y,
 | 
						||
                                Fin_Compteur_X-Debut_Compteur_X,
 | 
						||
                                Fin_Compteur_Y-Debut_Compteur_Y);
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// -- Effacer le pinceau -- //
 | 
						||
//
 | 
						||
void Effacer_pinceau(short X,short Y)
 | 
						||
  // X,Y: position du centre du pinceau
 | 
						||
{
 | 
						||
  short Debut_X; // Position X (dans l'image) <20> partir de laquelle on 
 | 
						||
        // affiche la brosse/pinceau
 | 
						||
  short Debut_Y; // Position Y (dans l'image) <20> partir de laquelle on 
 | 
						||
        // affiche la brosse/pinceau
 | 
						||
  short Largeur; // Largeur dans l'<27>cran selon laquelle on affiche la 
 | 
						||
        // brosse/pinceau
 | 
						||
  short Hauteur; // Hauteur dans l'<27>cran selon laquelle on affiche la 
 | 
						||
        // brosse/pinceau
 | 
						||
  short Debut_Compteur_X; // Position X (dans la brosse/pinceau) <20> partir 
 | 
						||
        // de laquelle on affiche la brosse/pinceau
 | 
						||
  short Debut_Compteur_Y; // Position Y (dans la brosse/pinceau) <20> partir 
 | 
						||
        // de laquelle on affiche la brosse/pinceau
 | 
						||
  //short Pos_X; // Position X (dans l'image) en cours d'affichage
 | 
						||
  //short Pos_Y; // Position Y (dans l'image) en cours d'affichage
 | 
						||
  //short Compteur_X; // Position X (dans la brosse/pinceau) en cours 
 | 
						||
        //d'affichage
 | 
						||
  //short Compteur_Y; // Position Y (dans la brosse/pinceau) en cours d'affichage
 | 
						||
  short Fin_Compteur_X; // Position X ou s'arr<72>te l'affichade de la brosse/pinceau
 | 
						||
  short Fin_Compteur_Y; // Position Y ou s'arr<72>te l'affichade de la brosse/pinceau
 | 
						||
  byte * Temp;
 | 
						||
 | 
						||
  if (!Mouse_K)
 | 
						||
  switch (Pinceau_Forme)
 | 
						||
  {
 | 
						||
    case FORME_PINCEAU_POINT :
 | 
						||
      if ( (Pinceau_X>=Limite_Gauche)
 | 
						||
        && (Pinceau_X<=Limite_Droite)
 | 
						||
        && (Pinceau_Y>=Limite_Haut)
 | 
						||
        && (Pinceau_Y<=Limite_Bas) )
 | 
						||
      {
 | 
						||
        Pixel_Preview(Pinceau_X,Pinceau_Y,Lit_pixel_dans_ecran_courant(Pinceau_X,Pinceau_Y));
 | 
						||
        SDL_UpdateRect(Ecran_SDL,Max(Pinceau_X-Principal_Decalage_X,0),Max(Pinceau_Y-Principal_Decalage_Y,0),1,1);
 | 
						||
        if(Loupe_Mode) UpdateZoom(Pinceau_X,Pinceau_Y,1,1);
 | 
						||
      }
 | 
						||
      break;
 | 
						||
    case FORME_PINCEAU_BROSSE_COULEUR :    // Brosse en couleur
 | 
						||
    case FORME_PINCEAU_BROSSE_MONOCHROME : // Brosse monochrome
 | 
						||
      Debut_X=X-Brosse_Decalage_X;
 | 
						||
      Debut_Y=Y-Brosse_Decalage_Y;
 | 
						||
      Largeur=Brosse_Largeur;
 | 
						||
      Hauteur=Brosse_Hauteur;
 | 
						||
      Calculer_dimensions_clipees(&Debut_X,&Debut_Y,&Largeur,&Hauteur);
 | 
						||
      Debut_Compteur_X=Debut_X-(X-Brosse_Decalage_X);
 | 
						||
      Debut_Compteur_Y=Debut_Y-(Y-Brosse_Decalage_Y);
 | 
						||
      Fin_Compteur_X=Debut_Compteur_X+Largeur;
 | 
						||
      Fin_Compteur_Y=Debut_Compteur_Y+Hauteur;
 | 
						||
 | 
						||
      if ( (Largeur>0) && (Hauteur>0) )
 | 
						||
        Clear_brush(Debut_X-Principal_Decalage_X,
 | 
						||
                    Debut_Y-Principal_Decalage_Y,
 | 
						||
                    Debut_Compteur_X,Debut_Compteur_Y,
 | 
						||
                    Largeur,Hauteur,Back_color,
 | 
						||
                    Principal_Largeur_image);
 | 
						||
 | 
						||
      if (Loupe_Mode)
 | 
						||
      {
 | 
						||
        Calculer_dimensions_clipees_zoom(&Debut_X,&Debut_Y,&Largeur,&Hauteur);
 | 
						||
        Debut_Compteur_X=Debut_X;
 | 
						||
        Debut_Compteur_Y=Debut_Y;
 | 
						||
 | 
						||
        if ( (Largeur>0) && (Hauteur>0) )
 | 
						||
        {
 | 
						||
          // Corrections dues au Zoom:
 | 
						||
          Debut_X=(Debut_X-Loupe_Decalage_X)*Loupe_Facteur;
 | 
						||
          Debut_Y=(Debut_Y-Loupe_Decalage_Y)*Loupe_Facteur;
 | 
						||
          Hauteur=Debut_Y+(Hauteur*Loupe_Facteur);
 | 
						||
          if (Hauteur>Menu_Ordonnee)
 | 
						||
            Hauteur=Menu_Ordonnee;
 | 
						||
 | 
						||
          Clear_brush_zoom(Principal_X_Zoom+Debut_X,Debut_Y,
 | 
						||
                           Debut_Compteur_X,Debut_Compteur_Y,
 | 
						||
                           Largeur,Hauteur,Back_color,
 | 
						||
                           Principal_Largeur_image,
 | 
						||
                           Buffer_de_ligne_horizontale);
 | 
						||
        }
 | 
						||
      }
 | 
						||
      break;
 | 
						||
    default: // Pinceau
 | 
						||
      Debut_X=X-Pinceau_Decalage_X;
 | 
						||
      Debut_Y=Y-Pinceau_Decalage_Y;
 | 
						||
      Largeur=Pinceau_Largeur;
 | 
						||
      Hauteur=Pinceau_Hauteur;
 | 
						||
      Calculer_dimensions_clipees(&Debut_X,&Debut_Y,&Largeur,&Hauteur);
 | 
						||
      Debut_Compteur_X=Debut_X-(X-Pinceau_Decalage_X);
 | 
						||
      Debut_Compteur_Y=Debut_Y-(Y-Pinceau_Decalage_Y);
 | 
						||
      Fin_Compteur_X=Debut_Compteur_X+Largeur;
 | 
						||
      Fin_Compteur_Y=Debut_Compteur_Y+Hauteur;
 | 
						||
 | 
						||
      Temp=Brosse;
 | 
						||
      Brosse=Pinceau_Sprite;
 | 
						||
 | 
						||
      if ( (Largeur>0) && (Hauteur>0) )
 | 
						||
      {
 | 
						||
        Clear_brush(Debut_X-Principal_Decalage_X,
 | 
						||
                    Debut_Y-Principal_Decalage_Y,
 | 
						||
                    Debut_Compteur_X,Debut_Compteur_Y,
 | 
						||
                    Largeur,Hauteur,0,
 | 
						||
                    Principal_Largeur_image);
 | 
						||
      }
 | 
						||
 | 
						||
      if (Loupe_Mode)
 | 
						||
      {
 | 
						||
        Calculer_dimensions_clipees_zoom(&Debut_X,&Debut_Y,&Largeur,&Hauteur);
 | 
						||
        Debut_Compteur_X=Debut_X;
 | 
						||
        Debut_Compteur_Y=Debut_Y;
 | 
						||
 | 
						||
        if ( (Largeur>0) && (Hauteur>0) )
 | 
						||
        {
 | 
						||
          // Corrections dues au Zoom:
 | 
						||
          Debut_X=(Debut_X-Loupe_Decalage_X)*Loupe_Facteur;
 | 
						||
          Debut_Y=(Debut_Y-Loupe_Decalage_Y)*Loupe_Facteur;
 | 
						||
          Hauteur=Debut_Y+(Hauteur*Loupe_Facteur);
 | 
						||
          if (Hauteur>Menu_Ordonnee)
 | 
						||
            Hauteur=Menu_Ordonnee;
 | 
						||
 | 
						||
          Clear_brush_zoom(Principal_X_Zoom+Debut_X,Debut_Y,
 | 
						||
                           Debut_Compteur_X,Debut_Compteur_Y,
 | 
						||
                           Largeur,Hauteur,0,
 | 
						||
                           Principal_Largeur_image,
 | 
						||
                           Buffer_de_ligne_horizontale);
 | 
						||
        }
 | 
						||
      }
 | 
						||
 | 
						||
      Brosse=Temp;
 | 
						||
      break;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// -- Fonctions de manipulation du curseur -----------------------------------
 | 
						||
 | 
						||
 | 
						||
  // -- Afficher une barre horizontale XOR zoom<6F>e
 | 
						||
 | 
						||
void Ligne_horizontale_XOR_Zoom(short Pos_X, short Pos_Y, short Largeur)
 | 
						||
{
 | 
						||
  short Pos_X_reelle=Principal_X_Zoom+(Pos_X-Loupe_Decalage_X)*Loupe_Facteur;
 | 
						||
  short Pos_Y_reelle=(Pos_Y-Loupe_Decalage_Y)*Loupe_Facteur;
 | 
						||
  short Largeur_reelle=Largeur*Loupe_Facteur;
 | 
						||
  short Pos_Y_Fin=(Pos_Y_reelle+Loupe_Facteur<Menu_Ordonnee)?Pos_Y_reelle+Loupe_Facteur:Menu_Ordonnee;
 | 
						||
  short Indice;
 | 
						||
 | 
						||
  for (Indice=Pos_Y_reelle; Indice<Pos_Y_Fin; Indice++)
 | 
						||
    Ligne_horizontale_XOR(Pos_X_reelle,Indice,Largeur_reelle);
 | 
						||
 | 
						||
  SDL_UpdateRect(Ecran_SDL,Pos_X_reelle,Pos_Y_reelle,Largeur_reelle,Pos_Y_Fin-Pos_Y_reelle);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
  // -- Afficher une barre verticale XOR zoom<6F>e
 | 
						||
 | 
						||
void Ligne_verticale_XOR_Zoom(short Pos_X, short Pos_Y, short Hauteur)
 | 
						||
{
 | 
						||
  short Pos_X_reelle=Principal_X_Zoom+(Pos_X-Loupe_Decalage_X)*Loupe_Facteur;
 | 
						||
  short Pos_Y_reelle=(Pos_Y-Loupe_Decalage_Y)*Loupe_Facteur;
 | 
						||
  short Pos_Y_Fin=(Pos_Y_reelle+(Hauteur*Loupe_Facteur<Menu_Ordonnee))?Pos_Y_reelle+(Hauteur*Loupe_Facteur):Menu_Ordonnee;
 | 
						||
  short Indice;
 | 
						||
 | 
						||
  for (Indice=Pos_Y_reelle; Indice<Pos_Y_Fin; Indice++)
 | 
						||
    Ligne_horizontale_XOR(Pos_X_reelle,Indice,Loupe_Facteur);
 | 
						||
 | 
						||
  SDL_UpdateRect(Ecran_SDL,Pos_X_reelle,Pos_Y_reelle,Loupe_Facteur,Pos_Y_Fin-Pos_Y_reelle);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
  // -- Afficher le curseur --
 | 
						||
 | 
						||
void Afficher_curseur(void)
 | 
						||
{
 | 
						||
  byte  Forme;
 | 
						||
  short Debut_X;
 | 
						||
  short Debut_Y;
 | 
						||
  short Fin_X;
 | 
						||
  short Fin_Y;
 | 
						||
  short Pos_X;
 | 
						||
  short Pos_Y;
 | 
						||
  short Compteur_X;
 | 
						||
  short Compteur_Y;
 | 
						||
  //short Fin_Compteur_X; // Position X ou s'arr<72>te l'affichage de la brosse/pinceau
 | 
						||
  //short Fin_Compteur_Y; // Position Y ou s'arr<72>te l'affichage de la brosse/pinceau
 | 
						||
  int   Temp;
 | 
						||
  byte  Couleur;
 | 
						||
  float cosA,sinA;
 | 
						||
  short X1,Y1,X2,Y2,X3,Y3,X4,Y4;
 | 
						||
 | 
						||
  if ( ( (Mouse_Y<Menu_Ordonnee)
 | 
						||
      && ( (!Loupe_Mode) || (Mouse_X<Principal_Split) || (Mouse_X>=Principal_X_Zoom) ) )
 | 
						||
    || (Une_fenetre_est_ouverte) || (Forme_curseur==FORME_CURSEUR_SABLIER) )
 | 
						||
    Forme=Forme_curseur;
 | 
						||
  else
 | 
						||
    Forme=FORME_CURSEUR_FLECHE;
 | 
						||
 | 
						||
  switch(Forme)
 | 
						||
  {
 | 
						||
    case FORME_CURSEUR_CIBLE :
 | 
						||
      if (!Cacher_pinceau)
 | 
						||
        Afficher_pinceau(Pinceau_X,Pinceau_Y,Fore_color,1);
 | 
						||
      if (!Cacher_curseur)
 | 
						||
      {
 | 
						||
        if (Config.Curseur==1)
 | 
						||
        {
 | 
						||
          Debut_Y=(Mouse_Y<6)?6-Mouse_Y:0;
 | 
						||
          if (Debut_Y<4)
 | 
						||
            Ligne_verticale_XOR  (Mouse_X,Mouse_Y+Debut_Y-6,4-Debut_Y);
 | 
						||
 | 
						||
          Debut_X=(Mouse_X<6)?(short)6-Mouse_X:0;
 | 
						||
          if (Debut_X<4)
 | 
						||
            Ligne_horizontale_XOR(Mouse_X+Debut_X-6,Mouse_Y,4-Debut_X);
 | 
						||
 | 
						||
          Fin_X=(Mouse_X+7>Largeur_ecran)?Mouse_X+7-Largeur_ecran:0;
 | 
						||
          if (Fin_X<4)
 | 
						||
            Ligne_horizontale_XOR(Mouse_X+3,Mouse_Y,4-Fin_X);
 | 
						||
 | 
						||
          Fin_Y=(Mouse_Y+7>Menu_Ordonnee/*Hauteur_ecran*/)?Mouse_Y+7-Menu_Ordonnee/*Hauteur_ecran*/:0;
 | 
						||
          if (Fin_Y<4)
 | 
						||
            Ligne_verticale_XOR  (Mouse_X,Mouse_Y+3,4-Fin_Y);
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          Temp=(Config.Curseur)?FORME_CURSEUR_CIBLE_FINE:FORME_CURSEUR_CIBLE;
 | 
						||
          Debut_X=Mouse_X-Curseur_Decalage_X[Temp];
 | 
						||
          Debut_Y=Mouse_Y-Curseur_Decalage_Y[Temp];
 | 
						||
 | 
						||
          for (Pos_X=Debut_X,Compteur_X=0;Compteur_X<15;Pos_X++,Compteur_X++)
 | 
						||
            for (Pos_Y=Debut_Y,Compteur_Y=0;Compteur_Y<15;Pos_Y++,Compteur_Y++)
 | 
						||
            {
 | 
						||
              Couleur=SPRITE_CURSEUR[Temp][Compteur_Y][Compteur_X];
 | 
						||
              if ( (Pos_X>=0) && (Pos_X<Largeur_ecran)
 | 
						||
                && (Pos_Y>=0) && (Pos_Y<Hauteur_ecran) )
 | 
						||
              {
 | 
						||
                FOND_CURSEUR[Compteur_Y][Compteur_X]=Lit_pixel(Pos_X,Pos_Y);
 | 
						||
                if (Couleur!=CM_Trans)
 | 
						||
                  Pixel(Pos_X,Pos_Y,Couleur);
 | 
						||
              }
 | 
						||
            }
 | 
						||
 | 
						||
          SDL_UpdateRect(Ecran_SDL,Max(Debut_X,0),Max(Debut_Y,0),16,16);
 | 
						||
        }
 | 
						||
      }
 | 
						||
      break;
 | 
						||
    case FORME_CURSEUR_CIBLE_PIPETTE:
 | 
						||
      if (!Cacher_pinceau)
 | 
						||
        Afficher_pinceau(Pinceau_X,Pinceau_Y,Fore_color,1);
 | 
						||
      if (!Cacher_curseur)
 | 
						||
      {
 | 
						||
        if (Config.Curseur==1)
 | 
						||
        {
 | 
						||
          // Barres formant la croix principale
 | 
						||
 | 
						||
          Debut_Y=(Mouse_Y<5)?5-Mouse_Y:0;
 | 
						||
          if (Debut_Y<3)
 | 
						||
            Ligne_verticale_XOR  (Mouse_X,Mouse_Y+Debut_Y-5,3-Debut_Y);
 | 
						||
 | 
						||
          Debut_X=(Mouse_X<5)?(short)5-Mouse_X:0;
 | 
						||
          if (Debut_X<3)
 | 
						||
            Ligne_horizontale_XOR(Mouse_X+Debut_X-5,Mouse_Y,3-Debut_X);
 | 
						||
 | 
						||
          Fin_X=(Mouse_X+6>Largeur_ecran)?Mouse_X+6-Largeur_ecran:0;
 | 
						||
          if (Fin_X<3)
 | 
						||
            Ligne_horizontale_XOR(Mouse_X+3,Mouse_Y,3-Fin_X);
 | 
						||
 | 
						||
          Fin_Y=(Mouse_Y+6>Menu_Ordonnee/*Hauteur_ecran*/)?Mouse_Y+6-Menu_Ordonnee/*Hauteur_ecran*/:0;
 | 
						||
          if (Fin_Y<3)
 | 
						||
            Ligne_verticale_XOR  (Mouse_X,Mouse_Y+3,3-Fin_Y);
 | 
						||
 | 
						||
          // Petites barres aux extr<74>mit<69>s
 | 
						||
 | 
						||
          Debut_X=(!Mouse_X);
 | 
						||
          Debut_Y=(!Mouse_Y);
 | 
						||
          Fin_X=(Mouse_X>=Largeur_ecran-1);
 | 
						||
          Fin_Y=(Mouse_Y>=Menu_Ordonnee-1);
 | 
						||
 | 
						||
          if (Mouse_Y>5)
 | 
						||
            Ligne_horizontale_XOR(Debut_X+Mouse_X-1,Mouse_Y-6,3-(Debut_X+Fin_X));
 | 
						||
 | 
						||
          if (Mouse_X>5)
 | 
						||
            Ligne_verticale_XOR  (Mouse_X-6,Debut_Y+Mouse_Y-1,3-(Debut_Y+Fin_Y));
 | 
						||
 | 
						||
          if (Mouse_X<Largeur_ecran-6)
 | 
						||
            Ligne_verticale_XOR  (Mouse_X+6,Debut_Y+Mouse_Y-1,3-(Debut_Y+Fin_Y));
 | 
						||
 | 
						||
          if (Mouse_Y<Menu_Ordonnee-6)
 | 
						||
            Ligne_horizontale_XOR(Debut_X+Mouse_X-1,Mouse_Y+6,3-(Debut_X+Fin_X));
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          Temp=(Config.Curseur)?FORME_CURSEUR_CIBLE_PIPETTE_FINE:FORME_CURSEUR_CIBLE_PIPETTE;
 | 
						||
          Debut_X=Mouse_X-Curseur_Decalage_X[Temp];
 | 
						||
          Debut_Y=Mouse_Y-Curseur_Decalage_Y[Temp];
 | 
						||
 | 
						||
          for (Pos_X=Debut_X,Compteur_X=0;Compteur_X<15;Pos_X++,Compteur_X++)
 | 
						||
            for (Pos_Y=Debut_Y,Compteur_Y=0;Compteur_Y<15;Pos_Y++,Compteur_Y++)
 | 
						||
            {
 | 
						||
              Couleur=SPRITE_CURSEUR[Temp][Compteur_Y][Compteur_X];
 | 
						||
              if ( (Pos_X>=0) && (Pos_X<Largeur_ecran)
 | 
						||
                && (Pos_Y>=0) && (Pos_Y<Hauteur_ecran) )
 | 
						||
              {
 | 
						||
                FOND_CURSEUR[Compteur_Y][Compteur_X]=Lit_pixel(Pos_X,Pos_Y);
 | 
						||
                if (Couleur!=CM_Trans)
 | 
						||
                  Pixel(Pos_X,Pos_Y,Couleur);
 | 
						||
              }
 | 
						||
            }
 | 
						||
          SDL_UpdateRect(Ecran_SDL,Debut_X,Debut_Y,16,16);
 | 
						||
        }
 | 
						||
      }
 | 
						||
      break;
 | 
						||
    case FORME_CURSEUR_MULTIDIRECTIONNEL :
 | 
						||
    case FORME_CURSEUR_HORIZONTAL :
 | 
						||
      if (Cacher_curseur)
 | 
						||
        break;
 | 
						||
    case FORME_CURSEUR_FLECHE :
 | 
						||
    case FORME_CURSEUR_SABLIER :
 | 
						||
      Debut_X=Mouse_X-Curseur_Decalage_X[Forme];
 | 
						||
      Debut_Y=Mouse_Y-Curseur_Decalage_Y[Forme];
 | 
						||
      for (Pos_X=Debut_X,Compteur_X=0;Compteur_X<15;Pos_X++,Compteur_X++)
 | 
						||
        for (Pos_Y=Debut_Y,Compteur_Y=0;Compteur_Y<15;Pos_Y++,Compteur_Y++)
 | 
						||
        {
 | 
						||
          Couleur=SPRITE_CURSEUR[Forme][Compteur_Y][Compteur_X];
 | 
						||
          if ( (Pos_X<Largeur_ecran) && (Pos_Y<Hauteur_ecran)
 | 
						||
            && (Pos_X>=0)            && (Pos_Y>=0) )
 | 
						||
          {
 | 
						||
            // On sauvegarde dans FOND_CURSEUR pour restaurer plus tard
 | 
						||
            FOND_CURSEUR[Compteur_Y][Compteur_X]=Lit_pixel(Pos_X,Pos_Y);
 | 
						||
            if (Couleur!=CM_Trans)
 | 
						||
              Pixel(Pos_X,Pos_Y,Couleur);
 | 
						||
          }
 | 
						||
        }
 | 
						||
      SDL_UpdateRect(Ecran_SDL,Max(Debut_X,0),Max(Debut_Y,0),16,16);
 | 
						||
      break;
 | 
						||
    case FORME_CURSEUR_CIBLE_XOR :
 | 
						||
      Pos_X=Pinceau_X-Principal_Decalage_X;
 | 
						||
      Pos_Y=Pinceau_Y-Principal_Decalage_Y;
 | 
						||
 | 
						||
      Compteur_X=(Loupe_Mode)?Principal_Split:Largeur_ecran; // Largeur de la barre XOR
 | 
						||
      if ((Pos_Y<Menu_Ordonnee) && (Pinceau_Y>=Limite_Haut))
 | 
						||
      {
 | 
						||
        Ligne_horizontale_XOR(0,Pinceau_Y-Principal_Decalage_Y,Compteur_X);
 | 
						||
        SDL_UpdateRect(Ecran_SDL,0,Pinceau_Y-Principal_Decalage_Y,Compteur_X,1);
 | 
						||
      }
 | 
						||
 | 
						||
      if ((Pos_X<Compteur_X) && (Pinceau_X>=Limite_Gauche))
 | 
						||
      {
 | 
						||
        Ligne_verticale_XOR(Pinceau_X-Principal_Decalage_X,0,Menu_Ordonnee);
 | 
						||
        SDL_UpdateRect(Ecran_SDL,Pinceau_X-Principal_Decalage_X,0,1,Menu_Ordonnee);
 | 
						||
      }
 | 
						||
 | 
						||
      if (Loupe_Mode)
 | 
						||
      {
 | 
						||
        // UPDATERECT
 | 
						||
        if ((Pinceau_Y>=Limite_Haut_Zoom) && (Pinceau_Y<=Limite_visible_Bas_Zoom))
 | 
						||
          Ligne_horizontale_XOR_Zoom(Limite_Gauche_Zoom,Pinceau_Y,Loupe_Largeur);
 | 
						||
        if ((Pinceau_X>=Limite_Gauche_Zoom) && (Pinceau_X<=Limite_visible_Droite_Zoom))
 | 
						||
          Ligne_verticale_XOR_Zoom(Pinceau_X,Limite_Haut_Zoom,Loupe_Hauteur);
 | 
						||
      }
 | 
						||
      break;
 | 
						||
    case FORME_CURSEUR_RECTANGLE_XOR :
 | 
						||
      // !!! Cette forme ne peut pas <20>tre utilis<69>e en mode Loupe !!!
 | 
						||
 | 
						||
      // Petite croix au centre
 | 
						||
      Debut_X=(Mouse_X-3);
 | 
						||
      Debut_Y=(Mouse_Y-3);
 | 
						||
      Fin_X  =(Mouse_X+4);
 | 
						||
      Fin_Y  =(Mouse_Y+4);
 | 
						||
      if (Debut_X<0)
 | 
						||
        Debut_X=0;
 | 
						||
      if (Debut_Y<0)
 | 
						||
        Debut_Y=0;
 | 
						||
      if (Fin_X>Largeur_ecran)
 | 
						||
        Fin_X=Largeur_ecran;
 | 
						||
      if (Fin_Y>Menu_Ordonnee)
 | 
						||
        Fin_Y=Menu_Ordonnee;
 | 
						||
 | 
						||
      Ligne_horizontale_XOR(Debut_X,Mouse_Y,Fin_X-Debut_X);
 | 
						||
      Ligne_verticale_XOR  (Mouse_X,Debut_Y,Fin_Y-Debut_Y);
 | 
						||
 | 
						||
      // Grand rectangle autour
 | 
						||
      Debut_X=Mouse_X-(Loupe_Largeur>>1);
 | 
						||
      Debut_Y=Mouse_Y-(Loupe_Hauteur>>1);
 | 
						||
      if (Debut_X+Loupe_Largeur>=Limite_Droite-Principal_Decalage_X)
 | 
						||
        Debut_X=Limite_Droite-Loupe_Largeur-Principal_Decalage_X+1;
 | 
						||
      if (Debut_Y+Loupe_Hauteur>=Limite_Bas-Principal_Decalage_Y)
 | 
						||
        Debut_Y=Limite_Bas-Loupe_Hauteur-Principal_Decalage_Y+1;
 | 
						||
      if (Debut_X<0)
 | 
						||
        Debut_X=0;
 | 
						||
      if (Debut_Y<0)
 | 
						||
        Debut_Y=0;
 | 
						||
      Fin_X=Debut_X+Loupe_Largeur-1;
 | 
						||
      Fin_Y=Debut_Y+Loupe_Hauteur-1;
 | 
						||
 | 
						||
      Ligne_horizontale_XOR(Debut_X,Debut_Y,Loupe_Largeur);
 | 
						||
      Ligne_verticale_XOR(Debut_X,Debut_Y+1,Loupe_Hauteur-2);
 | 
						||
      Ligne_verticale_XOR(  Fin_X,Debut_Y+1,Loupe_Hauteur-2);
 | 
						||
      Ligne_horizontale_XOR(Debut_X,  Fin_Y,Loupe_Largeur);
 | 
						||
 | 
						||
      SDL_UpdateRect(Ecran_SDL,Debut_X,Debut_Y,Fin_X+1-Debut_X,Fin_Y+1-Debut_Y);
 | 
						||
 | 
						||
      break;
 | 
						||
    default: //case FORME_CURSEUR_ROTATE_XOR :
 | 
						||
      Debut_X=1-(Brosse_Largeur>>1);
 | 
						||
      Debut_Y=1-(Brosse_Hauteur>>1);
 | 
						||
      Fin_X=Debut_X+Brosse_Largeur-1;
 | 
						||
      Fin_Y=Debut_Y+Brosse_Hauteur-1;
 | 
						||
 | 
						||
      if (Brosse_Centre_rotation_defini)
 | 
						||
      {
 | 
						||
        if ( (Brosse_Centre_rotation_X==Pinceau_X)
 | 
						||
          && (Brosse_Centre_rotation_Y==Pinceau_Y) )
 | 
						||
        {
 | 
						||
          cosA=1.0;
 | 
						||
          sinA=0.0;
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          Pos_X=Pinceau_X-Brosse_Centre_rotation_X;
 | 
						||
          Pos_Y=Pinceau_Y-Brosse_Centre_rotation_Y;
 | 
						||
          cosA=(float)Pos_X/sqrt((Pos_X*Pos_X)+(Pos_Y*Pos_Y));
 | 
						||
          sinA=sin(acos(cosA));
 | 
						||
          if (Pos_Y>0) sinA=-sinA;
 | 
						||
        }
 | 
						||
 | 
						||
        Transformer_point(Debut_X,Debut_Y, cosA,sinA, &X1,&Y1);
 | 
						||
        Transformer_point(Fin_X  ,Debut_Y, cosA,sinA, &X2,&Y2);
 | 
						||
        Transformer_point(Debut_X,Fin_Y  , cosA,sinA, &X3,&Y3);
 | 
						||
        Transformer_point(Fin_X  ,Fin_Y  , cosA,sinA, &X4,&Y4);
 | 
						||
 | 
						||
        X1+=Brosse_Centre_rotation_X;
 | 
						||
        Y1+=Brosse_Centre_rotation_Y;
 | 
						||
        X2+=Brosse_Centre_rotation_X;
 | 
						||
        Y2+=Brosse_Centre_rotation_Y;
 | 
						||
        X3+=Brosse_Centre_rotation_X;
 | 
						||
        Y3+=Brosse_Centre_rotation_Y;
 | 
						||
        X4+=Brosse_Centre_rotation_X;
 | 
						||
        Y4+=Brosse_Centre_rotation_Y;
 | 
						||
        Pixel_figure_Preview_xor(Brosse_Centre_rotation_X,Brosse_Centre_rotation_Y,0);
 | 
						||
        Tracer_ligne_Preview_xor(Brosse_Centre_rotation_X,Brosse_Centre_rotation_Y,Pinceau_X,Pinceau_Y,0);
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {
 | 
						||
        X1=X3=1-Brosse_Largeur;
 | 
						||
        Y1=Y2=Debut_Y;
 | 
						||
        X2=X4=Pinceau_X;
 | 
						||
        Y3=Y4=Fin_Y;
 | 
						||
 | 
						||
        X1+=Pinceau_X;
 | 
						||
        Y1+=Pinceau_Y;
 | 
						||
        Y2+=Pinceau_Y;
 | 
						||
        X3+=Pinceau_X;
 | 
						||
        Y3+=Pinceau_Y;
 | 
						||
        Y4+=Pinceau_Y;
 | 
						||
        Pixel_figure_Preview_xor(Pinceau_X-Fin_X,Pinceau_Y,0);
 | 
						||
        Tracer_ligne_Preview_xor(Pinceau_X-Fin_X,Pinceau_Y,Pinceau_X,Pinceau_Y,0);
 | 
						||
      }
 | 
						||
 | 
						||
      Tracer_ligne_Preview_xor(X1,Y1,X2,Y2,0);
 | 
						||
      Tracer_ligne_Preview_xor(X2,Y2,X4,Y4,0);
 | 
						||
      Tracer_ligne_Preview_xor(X4,Y4,X3,Y3,0);
 | 
						||
      Tracer_ligne_Preview_xor(X3,Y3,X1,Y1,0);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
  // -- Effacer le curseur --
 | 
						||
 | 
						||
void Effacer_curseur(void)
 | 
						||
{
 | 
						||
  byte  Forme;
 | 
						||
  int Debut_X; // int car sont parfois n<>gatifs ! (quand on dessine sur un bord)
 | 
						||
  int Debut_Y;
 | 
						||
  short Fin_X;
 | 
						||
  short Fin_Y;
 | 
						||
  int Pos_X;
 | 
						||
  int Pos_Y;
 | 
						||
  short Compteur_X;
 | 
						||
  short Compteur_Y;
 | 
						||
  //short Fin_Compteur_X; // Position X ou s'arr<72>te l'affichage de la brosse/pinceau
 | 
						||
  //short Fin_Compteur_Y; // Position Y ou s'arr<72>te l'affichage de la brosse/pinceau
 | 
						||
  int   Temp;
 | 
						||
  //byte  Couleur;
 | 
						||
  float cosA,sinA;
 | 
						||
  short X1,Y1,X2,Y2,X3,Y3,X4,Y4;
 | 
						||
 | 
						||
  if ( ( (Mouse_Y<Menu_Ordonnee)
 | 
						||
      && ( (!Loupe_Mode) || (Mouse_X<Principal_Split) 
 | 
						||
                         || (Mouse_X>=Principal_X_Zoom) ) )
 | 
						||
    || (Une_fenetre_est_ouverte) || (Forme_curseur==FORME_CURSEUR_SABLIER) )
 | 
						||
    Forme=Forme_curseur;
 | 
						||
  else
 | 
						||
    Forme=FORME_CURSEUR_FLECHE;
 | 
						||
 | 
						||
  switch(Forme)
 | 
						||
  {
 | 
						||
    case FORME_CURSEUR_CIBLE :
 | 
						||
      if (!Cacher_curseur)
 | 
						||
      {
 | 
						||
        if (Config.Curseur==1)
 | 
						||
        {
 | 
						||
          Debut_Y=(Mouse_Y<6)?6-Mouse_Y:0;
 | 
						||
          if (Debut_Y<4)
 | 
						||
            Ligne_verticale_XOR  (Mouse_X,Mouse_Y+Debut_Y-6,4-Debut_Y);
 | 
						||
 | 
						||
          Debut_X=(Mouse_X<6)?(short)6-Mouse_X:0;
 | 
						||
          if (Debut_X<4)
 | 
						||
            Ligne_horizontale_XOR(Mouse_X+Debut_X-6,Mouse_Y,4-Debut_X);
 | 
						||
 | 
						||
          Fin_X=(Mouse_X+7>Largeur_ecran)?Mouse_X+7-Largeur_ecran:0;
 | 
						||
          if (Fin_X<4)
 | 
						||
            Ligne_horizontale_XOR(Mouse_X+3,Mouse_Y,4-Fin_X);
 | 
						||
 | 
						||
          Fin_Y=(Mouse_Y+7>Hauteur_ecran)?Mouse_Y+7-Hauteur_ecran:0;
 | 
						||
          if (Fin_Y<4)
 | 
						||
            Ligne_verticale_XOR  (Mouse_X,Mouse_Y+3,4-Fin_Y);
 | 
						||
 | 
						||
          SDL_UpdateRect(Ecran_SDL,Debut_X,Debut_Y,Fin_X-Debut_X,Fin_Y-Debut_Y);
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          Temp=(Config.Curseur)?FORME_CURSEUR_CIBLE_FINE:FORME_CURSEUR_CIBLE;
 | 
						||
          Debut_X=Mouse_X-Curseur_Decalage_X[Temp];
 | 
						||
          Debut_Y=Mouse_Y-Curseur_Decalage_Y[Temp];
 | 
						||
 | 
						||
          for (Pos_Y=Debut_Y,Compteur_Y=0;Compteur_Y<15;Pos_Y++,Compteur_Y++)
 | 
						||
            for (Pos_X=Debut_X,Compteur_X=0;Compteur_X<15;Pos_X++,Compteur_X++)
 | 
						||
              if ( (Pos_X>=0) && (Pos_X<Largeur_ecran) && (Pos_Y>=0) && (Pos_Y<Hauteur_ecran) )
 | 
						||
                Pixel(Pos_X,Pos_Y,FOND_CURSEUR[Compteur_Y][Compteur_X]);
 | 
						||
 | 
						||
          SDL_UpdateRect(Ecran_SDL,Max(Debut_X,0),Max(Debut_Y,0),16,16);
 | 
						||
        }
 | 
						||
      }
 | 
						||
      if (!Cacher_pinceau)
 | 
						||
      {
 | 
						||
        Effacer_pinceau(Pinceau_X,Pinceau_Y);
 | 
						||
      }
 | 
						||
      break;
 | 
						||
    case FORME_CURSEUR_CIBLE_PIPETTE:
 | 
						||
      if (!Cacher_curseur)
 | 
						||
      {
 | 
						||
        if (Config.Curseur==1)
 | 
						||
        {
 | 
						||
          // Barres formant la croix principale
 | 
						||
 | 
						||
          Debut_Y=(Mouse_Y<5)?5-Mouse_Y:0;
 | 
						||
          if (Debut_Y<3)
 | 
						||
            Ligne_verticale_XOR  (Mouse_X,Mouse_Y+Debut_Y-5,3-Debut_Y);
 | 
						||
 | 
						||
          Debut_X=(Mouse_X<5)?(short)5-Mouse_X:0;
 | 
						||
          if (Debut_X<3)
 | 
						||
            Ligne_horizontale_XOR(Mouse_X+Debut_X-5,Mouse_Y,3-Debut_X);
 | 
						||
 | 
						||
          Fin_X=(Mouse_X+6>Largeur_ecran)?Mouse_X+6-Largeur_ecran:0;
 | 
						||
          if (Fin_X<3)
 | 
						||
            Ligne_horizontale_XOR(Mouse_X+3,Mouse_Y,3-Fin_X);
 | 
						||
 | 
						||
          Fin_Y=(Mouse_Y+6>Hauteur_ecran)?Mouse_Y+6-Hauteur_ecran:0;
 | 
						||
          if (Fin_Y<3)
 | 
						||
            Ligne_verticale_XOR  (Mouse_X,Mouse_Y+3,3-Fin_Y);
 | 
						||
 | 
						||
          Debut_X=(!Mouse_X);
 | 
						||
          Debut_Y=(!Mouse_Y);
 | 
						||
          Fin_X=(Mouse_X>=Largeur_ecran-1);
 | 
						||
          Fin_Y=(Mouse_Y>=Menu_Ordonnee-1);
 | 
						||
 | 
						||
          if (Mouse_Y>5)
 | 
						||
            Ligne_horizontale_XOR(Debut_X+Mouse_X-1,Mouse_Y-6,3-(Debut_X+Fin_X));
 | 
						||
 | 
						||
          if (Mouse_X>5)
 | 
						||
            Ligne_verticale_XOR  (Mouse_X-6,Debut_Y+Mouse_Y-1,3-(Debut_Y+Fin_Y));
 | 
						||
 | 
						||
          if (Mouse_X<Largeur_ecran-6)
 | 
						||
            Ligne_verticale_XOR  (Mouse_X+6,Debut_Y+Mouse_Y-1,3-(Debut_Y+Fin_Y));
 | 
						||
 | 
						||
          if (Mouse_Y<Menu_Ordonnee-6)
 | 
						||
            Ligne_horizontale_XOR(Debut_X+Mouse_X-1,Mouse_Y+6,3-(Debut_X+Fin_X));
 | 
						||
 | 
						||
          SDL_UpdateRect(Ecran_SDL,Debut_X,Debut_Y,Fin_X-Debut_X,Fin_Y-Debut_Y);
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          Temp=(Config.Curseur)?FORME_CURSEUR_CIBLE_PIPETTE_FINE:FORME_CURSEUR_CIBLE_PIPETTE;
 | 
						||
          Debut_X=Mouse_X-Curseur_Decalage_X[Temp];
 | 
						||
          Debut_Y=Mouse_Y-Curseur_Decalage_Y[Temp];
 | 
						||
 | 
						||
          for (Pos_X=Debut_X,Compteur_X=0;Compteur_X<15;Pos_X++,Compteur_X++)
 | 
						||
            for (Pos_Y=Debut_Y,Compteur_Y=0;Compteur_Y<15;Pos_Y++,Compteur_Y++)
 | 
						||
              if ( (Pos_X>=0) && (Pos_X<Largeur_ecran) && (Pos_Y>=0) && (Pos_Y<Hauteur_ecran) )
 | 
						||
                Pixel(Pos_X,Pos_Y,FOND_CURSEUR[Compteur_Y][Compteur_X]);
 | 
						||
 | 
						||
          SDL_UpdateRect(Ecran_SDL,Max(Debut_X,0),Max(Debut_Y,0),16,16);
 | 
						||
        }
 | 
						||
      }
 | 
						||
      if (!Cacher_pinceau)
 | 
						||
        Effacer_pinceau(Pinceau_X,Pinceau_Y);
 | 
						||
      break;
 | 
						||
    case FORME_CURSEUR_MULTIDIRECTIONNEL :
 | 
						||
    case FORME_CURSEUR_HORIZONTAL :
 | 
						||
      if (Cacher_curseur)
 | 
						||
        break;
 | 
						||
    case FORME_CURSEUR_FLECHE :
 | 
						||
    case FORME_CURSEUR_SABLIER :
 | 
						||
      Debut_X=Mouse_X-Curseur_Decalage_X[Forme];
 | 
						||
      Debut_Y=Mouse_Y-Curseur_Decalage_Y[Forme];
 | 
						||
 | 
						||
      for (Pos_X=Debut_X,Compteur_X=0;Compteur_X<15;Pos_X++,Compteur_X++)
 | 
						||
        for (Pos_Y=Debut_Y,Compteur_Y=0;Compteur_Y<15;Pos_Y++,Compteur_Y++)
 | 
						||
          if ( (Pos_X<Largeur_ecran) && (Pos_Y<Hauteur_ecran)
 | 
						||
            && (Pos_X>=0)            && (Pos_Y>=0) )
 | 
						||
            Pixel(Pos_X,Pos_Y,FOND_CURSEUR[Compteur_Y][Compteur_X]);
 | 
						||
      SDL_UpdateRect(Ecran_SDL,Max(Debut_X,0),Max(Debut_Y,0),16,16);
 | 
						||
      break;
 | 
						||
 | 
						||
    case FORME_CURSEUR_CIBLE_XOR :
 | 
						||
      Pos_X=Pinceau_X-Principal_Decalage_X;
 | 
						||
      Pos_Y=Pinceau_Y-Principal_Decalage_Y;
 | 
						||
 | 
						||
      Compteur_X=(Loupe_Mode)?Principal_Split:Largeur_ecran; // Largeur de la barre XOR
 | 
						||
      if ((Pos_Y<Menu_Ordonnee) && (Pinceau_Y>=Limite_Haut))
 | 
						||
      {
 | 
						||
        Ligne_horizontale_XOR(0,Pinceau_Y-Principal_Decalage_Y,Compteur_X);
 | 
						||
        SDL_UpdateRect(Ecran_SDL,0,Pinceau_Y-Principal_Decalage_Y,Compteur_X,1);
 | 
						||
      }
 | 
						||
 | 
						||
      if ((Pos_X<Compteur_X) && (Pinceau_X>=Limite_Gauche))
 | 
						||
      {
 | 
						||
        Ligne_verticale_XOR(Pinceau_X-Principal_Decalage_X,0,Menu_Ordonnee);
 | 
						||
        SDL_UpdateRect(Ecran_SDL,Pinceau_X-Principal_Decalage_X,0,1,Menu_Ordonnee);
 | 
						||
      }
 | 
						||
 | 
						||
      if (Loupe_Mode)
 | 
						||
      {
 | 
						||
        // UPDATERECT
 | 
						||
        if ((Pinceau_Y>=Limite_Haut_Zoom) && (Pinceau_Y<=Limite_visible_Bas_Zoom))
 | 
						||
          Ligne_horizontale_XOR_Zoom(Limite_Gauche_Zoom,Pinceau_Y,Loupe_Largeur);
 | 
						||
        if ((Pinceau_X>=Limite_Gauche_Zoom) && (Pinceau_X<=Limite_visible_Droite_Zoom))
 | 
						||
          Ligne_verticale_XOR_Zoom(Pinceau_X,Limite_Haut_Zoom,Loupe_Hauteur);
 | 
						||
      }
 | 
						||
 | 
						||
 | 
						||
      break;
 | 
						||
    case FORME_CURSEUR_RECTANGLE_XOR :
 | 
						||
      // !!! Cette forme ne peut pas <20>tre utilis<69>e en mode Loupe !!!
 | 
						||
 | 
						||
      // Petite croix au centre
 | 
						||
      Debut_X=(Mouse_X-3);
 | 
						||
      Debut_Y=(Mouse_Y-3);
 | 
						||
      Fin_X  =(Mouse_X+4);
 | 
						||
      Fin_Y  =(Mouse_Y+4);
 | 
						||
      if (Debut_X<0)
 | 
						||
        Debut_X=0;
 | 
						||
      if (Debut_Y<0)
 | 
						||
        Debut_Y=0;
 | 
						||
      if (Fin_X>Largeur_ecran)
 | 
						||
        Fin_X=Largeur_ecran;
 | 
						||
      if (Fin_Y>Menu_Ordonnee)
 | 
						||
        Fin_Y=Menu_Ordonnee;
 | 
						||
 | 
						||
      Ligne_horizontale_XOR(Debut_X,Mouse_Y,Fin_X-Debut_X);
 | 
						||
      Ligne_verticale_XOR  (Mouse_X,Debut_Y,Fin_Y-Debut_Y);
 | 
						||
 | 
						||
      // Grand rectangle autour
 | 
						||
 | 
						||
      Debut_X=Mouse_X-(Loupe_Largeur>>1);
 | 
						||
      Debut_Y=Mouse_Y-(Loupe_Hauteur>>1);
 | 
						||
      if (Debut_X+Loupe_Largeur>=Limite_Droite-Principal_Decalage_X)
 | 
						||
        Debut_X=Limite_Droite-Loupe_Largeur-Principal_Decalage_X+1;
 | 
						||
      if (Debut_Y+Loupe_Hauteur>=Limite_Bas-Principal_Decalage_Y)
 | 
						||
        Debut_Y=Limite_Bas-Loupe_Hauteur-Principal_Decalage_Y+1;
 | 
						||
      if (Debut_X<0)
 | 
						||
        Debut_X=0;
 | 
						||
      if (Debut_Y<0)
 | 
						||
        Debut_Y=0;
 | 
						||
      Fin_X=Debut_X+Loupe_Largeur-1;
 | 
						||
      Fin_Y=Debut_Y+Loupe_Hauteur-1;
 | 
						||
 | 
						||
      Ligne_horizontale_XOR(Debut_X,Debut_Y,Loupe_Largeur);
 | 
						||
      Ligne_verticale_XOR(Debut_X,Debut_Y+1,Loupe_Hauteur-2);
 | 
						||
      Ligne_verticale_XOR(  Fin_X,Debut_Y+1,Loupe_Hauteur-2);
 | 
						||
      Ligne_horizontale_XOR(Debut_X,  Fin_Y,Loupe_Largeur);
 | 
						||
 | 
						||
      SDL_UpdateRect(Ecran_SDL,Debut_X,Debut_Y,Fin_X+1-Debut_X,Fin_Y+1-Debut_Y);
 | 
						||
 | 
						||
      break;
 | 
						||
    default: //case FORME_CURSEUR_ROTATE_XOR :
 | 
						||
      Debut_X=1-(Brosse_Largeur>>1);
 | 
						||
      Debut_Y=1-(Brosse_Hauteur>>1);
 | 
						||
      Fin_X=Debut_X+Brosse_Largeur-1;
 | 
						||
      Fin_Y=Debut_Y+Brosse_Hauteur-1;
 | 
						||
 | 
						||
      if (Brosse_Centre_rotation_defini)
 | 
						||
      {
 | 
						||
        if ( (Brosse_Centre_rotation_X==Pinceau_X)
 | 
						||
          && (Brosse_Centre_rotation_Y==Pinceau_Y) )
 | 
						||
        {
 | 
						||
          cosA=1.0;
 | 
						||
          sinA=0.0;
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          Pos_X=Pinceau_X-Brosse_Centre_rotation_X;
 | 
						||
          Pos_Y=Pinceau_Y-Brosse_Centre_rotation_Y;
 | 
						||
          cosA=(float)Pos_X/sqrt((Pos_X*Pos_X)+(Pos_Y*Pos_Y));
 | 
						||
          sinA=sin(acos(cosA));
 | 
						||
          if (Pos_Y>0) sinA=-sinA;
 | 
						||
        }
 | 
						||
 | 
						||
        Transformer_point(Debut_X,Debut_Y, cosA,sinA, &X1,&Y1);
 | 
						||
        Transformer_point(Fin_X  ,Debut_Y, cosA,sinA, &X2,&Y2);
 | 
						||
        Transformer_point(Debut_X,Fin_Y  , cosA,sinA, &X3,&Y3);
 | 
						||
        Transformer_point(Fin_X  ,Fin_Y  , cosA,sinA, &X4,&Y4);
 | 
						||
 | 
						||
        X1+=Brosse_Centre_rotation_X;
 | 
						||
        Y1+=Brosse_Centre_rotation_Y;
 | 
						||
        X2+=Brosse_Centre_rotation_X;
 | 
						||
        Y2+=Brosse_Centre_rotation_Y;
 | 
						||
        X3+=Brosse_Centre_rotation_X;
 | 
						||
        Y3+=Brosse_Centre_rotation_Y;
 | 
						||
        X4+=Brosse_Centre_rotation_X;
 | 
						||
        Y4+=Brosse_Centre_rotation_Y;
 | 
						||
        Pixel_figure_Preview_xor(Brosse_Centre_rotation_X,Brosse_Centre_rotation_Y,0);
 | 
						||
        Tracer_ligne_Preview_xor(Brosse_Centre_rotation_X,Brosse_Centre_rotation_Y,Pinceau_X,Pinceau_Y,0);
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {
 | 
						||
        X1=X3=1-Brosse_Largeur;
 | 
						||
        Y1=Y2=Debut_Y;
 | 
						||
        X2=X4=Pinceau_X;
 | 
						||
        Y3=Y4=Fin_Y;
 | 
						||
 | 
						||
        X1+=Pinceau_X;
 | 
						||
        Y1+=Pinceau_Y;
 | 
						||
        Y2+=Pinceau_Y;
 | 
						||
        X3+=Pinceau_X;
 | 
						||
        Y3+=Pinceau_Y;
 | 
						||
        Y4+=Pinceau_Y;
 | 
						||
        Pixel_figure_Preview_xor(Pinceau_X-Fin_X,Pinceau_Y,0);
 | 
						||
        Tracer_ligne_Preview_xor(Pinceau_X-Fin_X,Pinceau_Y,Pinceau_X,Pinceau_Y,0);
 | 
						||
      }
 | 
						||
 | 
						||
      Tracer_ligne_Preview_xor(X1,Y1,X2,Y2,0);
 | 
						||
      Tracer_ligne_Preview_xor(X2,Y2,X4,Y4,0);
 | 
						||
      Tracer_ligne_Preview_xor(X4,Y4,X3,Y3,0);
 | 
						||
      Tracer_ligne_Preview_xor(X3,Y3,X1,Y1,0);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
//---- Fen<65>tre demandant de confirmer une action et renvoyant la r<>ponse -----
 | 
						||
byte Demande_de_confirmation(char * Message)
 | 
						||
{
 | 
						||
  short Bouton_clicke;
 | 
						||
  word  Largeur_de_la_fenetre;
 | 
						||
 | 
						||
  Largeur_de_la_fenetre=(strlen(Message)<<3)+20;
 | 
						||
 | 
						||
  if (Largeur_de_la_fenetre<120)
 | 
						||
    Largeur_de_la_fenetre=120;
 | 
						||
 | 
						||
  Ouvrir_fenetre(Largeur_de_la_fenetre,60,"Confirmation");
 | 
						||
 | 
						||
  Print_dans_fenetre((Largeur_de_la_fenetre>>1)-(strlen(Message)<<2),20,Message,CM_Noir,CM_Clair);
 | 
						||
 | 
						||
  Fenetre_Definir_bouton_normal((Largeur_de_la_fenetre/3)-20     ,37,40,14,"Yes",1,1,0x0015); // 1
 | 
						||
  Fenetre_Definir_bouton_normal(((Largeur_de_la_fenetre<<1)/3)-20,37,40,14,"No" ,1,1,0x0031); // 2
 | 
						||
 | 
						||
  Afficher_curseur();
 | 
						||
 | 
						||
  do
 | 
						||
  {
 | 
						||
    Bouton_clicke=Fenetre_Bouton_clicke();
 | 
						||
    if (Touche==0x001C) Bouton_clicke=1;
 | 
						||
    if (Touche==0x0001) Bouton_clicke=2;
 | 
						||
  }
 | 
						||
  while (Bouton_clicke<=0);
 | 
						||
 | 
						||
  Fermer_fenetre();
 | 
						||
  Afficher_curseur();
 | 
						||
 | 
						||
  return (Bouton_clicke==1)? 1 : 0;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
//---- Fen<65>tre avertissant de quelque chose et attendant un click sur OK -----
 | 
						||
void Warning_message(char * Message)
 | 
						||
{
 | 
						||
  short Bouton_clicke;
 | 
						||
  word  Largeur_de_la_fenetre;
 | 
						||
 | 
						||
  Largeur_de_la_fenetre=(strlen(Message)<<3)+20;
 | 
						||
  if (Largeur_de_la_fenetre<120)
 | 
						||
    Largeur_de_la_fenetre=120;
 | 
						||
 | 
						||
  Ouvrir_fenetre(Largeur_de_la_fenetre,60,"Warning!");
 | 
						||
 | 
						||
  Print_dans_fenetre((Largeur_de_la_fenetre>>1)-(strlen(Message)<<2),20,Message,CM_Noir,CM_Clair);
 | 
						||
  Fenetre_Definir_bouton_normal((Largeur_de_la_fenetre>>1)-20     ,37,40,14,"OK",1,1,0x001C); // 1
 | 
						||
  Afficher_curseur();
 | 
						||
 | 
						||
  do
 | 
						||
    Bouton_clicke=Fenetre_Bouton_clicke();
 | 
						||
  while ((Bouton_clicke<=0) && (Touche!=0x0001) && (Touche!=0x0018));
 | 
						||
 | 
						||
  Fermer_fenetre();
 | 
						||
  Afficher_curseur();
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
// -- Fonction diverses d'affichage ------------------------------------------
 | 
						||
 | 
						||
  // -- Reafficher toute l'image (en prenant en compte le facteur de zoom) --
 | 
						||
 | 
						||
void Afficher_ecran(void)
 | 
						||
{
 | 
						||
  word Largeur;
 | 
						||
  word Hauteur;
 | 
						||
 | 
						||
  // ---/\/\/\  Partie non zoom<6F>e: /\/\/\---
 | 
						||
  if (Loupe_Mode)
 | 
						||
  {
 | 
						||
    if (Principal_Largeur_image<Principal_Split)
 | 
						||
      Largeur=Principal_Largeur_image;
 | 
						||
    else
 | 
						||
      Largeur=Principal_Split;
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    if (Principal_Largeur_image<Largeur_ecran)
 | 
						||
      Largeur=Principal_Largeur_image;
 | 
						||
    else
 | 
						||
      Largeur=Largeur_ecran;
 | 
						||
  }
 | 
						||
  if (Principal_Hauteur_image<Menu_Ordonnee)
 | 
						||
    Hauteur=Principal_Hauteur_image;
 | 
						||
  else
 | 
						||
    Hauteur=Menu_Ordonnee;
 | 
						||
  Display_screen(Largeur,Hauteur,Principal_Largeur_image);
 | 
						||
 | 
						||
  // Effacement de la partie non-image dans la partie non zoom<6F>e:
 | 
						||
  if (Loupe_Mode)
 | 
						||
  {
 | 
						||
    if (Principal_Largeur_image<Principal_Split)
 | 
						||
      Block(Principal_Largeur_image,0,(Principal_Split-Principal_Largeur_image),Menu_Ordonnee,0);
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    if (Principal_Largeur_image<Largeur_ecran)
 | 
						||
      Block(Principal_Largeur_image,0,(Largeur_ecran-Principal_Largeur_image),Menu_Ordonnee,0);
 | 
						||
  }
 | 
						||
  if (Principal_Hauteur_image<Menu_Ordonnee)
 | 
						||
    Block(0,Principal_Hauteur_image,Largeur,(Menu_Ordonnee-Hauteur),0);
 | 
						||
 | 
						||
  // ---/\/\/\  Partie zoom<6F>e: /\/\/\---
 | 
						||
  if (Loupe_Mode)
 | 
						||
  {
 | 
						||
    // Affichage de la barre de split
 | 
						||
    Afficher_barre_de_split();
 | 
						||
 | 
						||
    // Calcul de la largeur visible
 | 
						||
    if (Principal_Largeur_image<Loupe_Largeur)
 | 
						||
      Largeur=Principal_Largeur_image;
 | 
						||
    else
 | 
						||
      Largeur=Loupe_Largeur;
 | 
						||
 | 
						||
    // Calcul du nombre de lignes visibles de l'image zoom<6F>e
 | 
						||
    if (Principal_Hauteur_image<Loupe_Hauteur)
 | 
						||
      Hauteur=Principal_Hauteur_image*Loupe_Facteur;
 | 
						||
    else
 | 
						||
      Hauteur=Menu_Ordonnee;
 | 
						||
 | 
						||
    Display_zoomed_screen(Largeur,Hauteur,Principal_Largeur_image,Buffer_de_ligne_horizontale);
 | 
						||
 | 
						||
    // Effacement de la partie non-image dans la partie zoom<6F>e:
 | 
						||
    if (Principal_Largeur_image<Loupe_Largeur)
 | 
						||
      Block(Principal_X_Zoom+(Principal_Largeur_image*Loupe_Facteur),0,
 | 
						||
            (Loupe_Largeur-Principal_Largeur_image)*Loupe_Facteur,
 | 
						||
            Menu_Ordonnee,0);
 | 
						||
    if (Principal_Hauteur_image<Loupe_Hauteur)
 | 
						||
      Block(Principal_X_Zoom,Hauteur,Largeur*Loupe_Facteur,(Menu_Ordonnee-Hauteur),0);
 | 
						||
  }
 | 
						||
 | 
						||
  // ---/\/\/\ Affichage des limites /\/\/\---
 | 
						||
  if (Config.Afficher_limites_image)
 | 
						||
    Afficher_limites_de_l_image();
 | 
						||
}
 | 
						||
 | 
						||
  // -- Redessiner le sprite d'un bouton dans le menu --
 | 
						||
 | 
						||
void Afficher_sprite_dans_menu(int Numero_bouton,int Numero_sprite)
 | 
						||
{
 | 
						||
  word Pos_X;
 | 
						||
  word Pos_Y;
 | 
						||
  word Pos_menu_X;
 | 
						||
  word Pos_menu_Y;
 | 
						||
  byte Couleur;
 | 
						||
 | 
						||
  for (Pos_Y=0,Pos_menu_Y=Bouton[Numero_bouton].Decalage_Y+1;Pos_Y<HAUTEUR_SPRITE_MENU;Pos_Y++,Pos_menu_Y++)
 | 
						||
    for (Pos_X=0,Pos_menu_X=Bouton[Numero_bouton].Decalage_X+1;Pos_X<LARGEUR_SPRITE_MENU;Pos_X++,Pos_menu_X++)
 | 
						||
    {
 | 
						||
      Couleur=SPRITE_MENU[Numero_sprite][Pos_Y][Pos_X];
 | 
						||
      Pixel_dans_menu(Pos_menu_X,Pos_menu_Y,Couleur);
 | 
						||
      BLOCK_MENU[Pos_menu_Y][Pos_menu_X]=Couleur;
 | 
						||
    }
 | 
						||
  SDL_UpdateRect(Ecran_SDL,0,Menu_Ordonnee*Menu_Facteur_Y,Pos_X*Menu_Facteur_X,Pos_Y*Menu_Facteur_Y);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Redessiner la forme du pinceau dans le menu --
 | 
						||
 | 
						||
void Afficher_pinceau_dans_menu(void)
 | 
						||
{
 | 
						||
  short Pos_X,Pos_Y;
 | 
						||
  short Debut_X;
 | 
						||
  short Pos_menu_X,Pos_menu_Y;
 | 
						||
  short Debut_menu_X;
 | 
						||
  byte Couleur;
 | 
						||
 | 
						||
  switch (Pinceau_Forme)
 | 
						||
  {
 | 
						||
    case FORME_PINCEAU_BROSSE_COULEUR    : // Brosse en couleur
 | 
						||
    case FORME_PINCEAU_BROSSE_MONOCHROME : // Brosse monochrome
 | 
						||
      for (Pos_menu_Y=2,Pos_Y=0;Pos_Y<HAUTEUR_SPRITE_MENU;Pos_menu_Y++,Pos_Y++)
 | 
						||
        for (Pos_menu_X=1,Pos_X=0;Pos_X<LARGEUR_SPRITE_MENU;Pos_menu_X++,Pos_X++)
 | 
						||
        {
 | 
						||
          Couleur=SPRITE_MENU[3][Pos_Y][Pos_X];
 | 
						||
          Pixel_dans_menu(Pos_menu_X,Pos_menu_Y,Couleur);
 | 
						||
          BLOCK_MENU[Pos_menu_Y][Pos_menu_X]=Couleur;
 | 
						||
        }
 | 
						||
      break;
 | 
						||
    default : // Pinceau
 | 
						||
      // On efface le pinceau pr<70>c<EFBFBD>dent
 | 
						||
      for (Pos_menu_Y=2,Pos_Y=0;Pos_Y<HAUTEUR_SPRITE_MENU;Pos_menu_Y++,Pos_Y++)
 | 
						||
        for (Pos_menu_X=1,Pos_X=0;Pos_X<LARGEUR_SPRITE_MENU;Pos_menu_X++,Pos_X++)
 | 
						||
        {
 | 
						||
          Pixel_dans_menu(Pos_menu_X,Pos_menu_Y,CM_Clair);
 | 
						||
          BLOCK_MENU[Pos_menu_Y][Pos_menu_X]=CM_Clair;
 | 
						||
        }
 | 
						||
      // On affiche le nouveau
 | 
						||
      Debut_menu_X=8-Pinceau_Decalage_X;
 | 
						||
      if (Debut_menu_X<1)
 | 
						||
      {
 | 
						||
        Debut_X=Pinceau_Decalage_X-7;
 | 
						||
        Debut_menu_X=1;
 | 
						||
      }
 | 
						||
      else
 | 
						||
        Debut_X=0;
 | 
						||
 | 
						||
      Pos_menu_Y=9-Pinceau_Decalage_Y;
 | 
						||
      if (Pos_menu_Y<2)
 | 
						||
      {
 | 
						||
        Pos_Y=Pinceau_Decalage_Y-7;
 | 
						||
        Pos_menu_Y=2;
 | 
						||
      }
 | 
						||
      else
 | 
						||
        Pos_Y=0;
 | 
						||
 | 
						||
      for (;((Pos_Y<Pinceau_Hauteur) && (Pos_menu_Y<16));Pos_menu_Y++,Pos_Y++)
 | 
						||
        for (Pos_menu_X=Debut_menu_X,Pos_X=Debut_X;((Pos_X<Pinceau_Largeur) && (Pos_menu_X<15));Pos_menu_X++,Pos_X++)
 | 
						||
        {
 | 
						||
          Couleur=(Pinceau_Sprite[(Pos_Y*TAILLE_MAXI_PINCEAU)+Pos_X])?CM_Noir:CM_Clair;
 | 
						||
          Pixel_dans_menu(Pos_menu_X,Pos_menu_Y,Couleur);
 | 
						||
          BLOCK_MENU[Pos_menu_Y][Pos_menu_X]=Couleur;
 | 
						||
        }
 | 
						||
  }
 | 
						||
  SDL_UpdateRect(Ecran_SDL,0,0,LARGEUR_SPRITE_MENU*Menu_Facteur_X,HAUTEUR_SPRITE_MENU*Menu_Facteur_Y);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Dessiner un pinceau pr<70>d<EFBFBD>fini dans la fen<65>tre --
 | 
						||
 | 
						||
void Afficher_pinceau_dans_fenetre(word X,word Y,int Numero)
 | 
						||
  // Pinceau = 0..NB_SPRITES_PINCEAU-1 : Pinceau pr<70>d<EFBFBD>fini
 | 
						||
{
 | 
						||
  word Pos_X;
 | 
						||
  word Pos_Y;
 | 
						||
  word Pos_fenetre_X;
 | 
						||
  word Pos_fenetre_Y;
 | 
						||
 | 
						||
  word Orig_X = X + 8 - Pinceau_predefini_Decalage_X[Numero];
 | 
						||
  word Orig_Y = Y + 8 - Pinceau_predefini_Decalage_Y[Numero];
 | 
						||
 | 
						||
  for (Pos_fenetre_Y=Orig_Y,Pos_Y=0; Pos_Y<Pinceau_predefini_Hauteur[Numero]; Pos_fenetre_Y++,Pos_Y++)
 | 
						||
    for (Pos_fenetre_X=Orig_X,Pos_X=0; Pos_X<Pinceau_predefini_Largeur[Numero]; Pos_fenetre_X++,Pos_X++)
 | 
						||
      Pixel_dans_fenetre(Pos_fenetre_X,Pos_fenetre_Y,(SPRITE_PINCEAU[Numero][Pos_Y][Pos_X])?CM_Noir:CM_Clair);
 | 
						||
 | 
						||
#define ToWinX(x) (((x)*Menu_Facteur_X)+Fenetre_Pos_X)
 | 
						||
#define ToWinY(y) (((y)*Menu_Facteur_Y)+Fenetre_Pos_Y)
 | 
						||
#define ToWinL(l) ((l)*Menu_Facteur_X)
 | 
						||
#define ToWinH(h) ((h)*Menu_Facteur_X)
 | 
						||
 | 
						||
  SDL_UpdateRect(Ecran_SDL, ToWinX(Orig_X), ToWinY(Orig_Y),
 | 
						||
        ToWinL(Pinceau_predefini_Largeur[Numero]), 
 | 
						||
        ToWinH(Pinceau_predefini_Hauteur[Numero])
 | 
						||
  );
 | 
						||
}
 | 
						||
 | 
						||
  // -- Dessiner des zigouigouis --
 | 
						||
 | 
						||
void Dessiner_zigouigoui(word X,word Y, byte Couleur, short Sens)
 | 
						||
{
 | 
						||
  word i;
 | 
						||
 | 
						||
  for (i=0; i<11; i++) Pixel_dans_fenetre(X,Y+i,Couleur);
 | 
						||
  X+=Sens;
 | 
						||
  for (i=1; i<10; i++) Pixel_dans_fenetre(X,Y+i,Couleur);
 | 
						||
  X+=Sens+Sens;
 | 
						||
  for (i=3; i<8; i++) Pixel_dans_fenetre(X,Y+i,Couleur);
 | 
						||
  X+=Sens+Sens;
 | 
						||
  Pixel_dans_fenetre(X,Y+5,Couleur);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Dessiner un bloc de couleurs d<>grad<61> verticalement
 | 
						||
 | 
						||
void Bloc_degrade_dans_fenetre(word Pos_X,word Pos_Y,word Debut_block,word Fin_block)
 | 
						||
{
 | 
						||
  word Total_lignes  =Menu_Facteur_Y<<6; // <=> <20> 64 lignes fct(Menu_Facteur)
 | 
						||
  word Nb_couleurs   =(Debut_block<=Fin_block)?Fin_block-Debut_block+1:Debut_block-Fin_block+1;
 | 
						||
  word Ligne_en_cours=(Debut_block<=Fin_block)?0:Total_lignes-1;
 | 
						||
 | 
						||
  word Debut_X       =Fenetre_Pos_X+(Menu_Facteur_X*Pos_X);
 | 
						||
  word Largeur_ligne =Menu_Facteur_X<<4; // <=> <20> 16 pixels fct(Menu_Facteur)
 | 
						||
 | 
						||
  word Debut_Y       =Fenetre_Pos_Y+(Menu_Facteur_Y*Pos_Y);
 | 
						||
  word Fin_Y         =Debut_Y+Total_lignes;
 | 
						||
  word Indice;
 | 
						||
 | 
						||
  if (Debut_block>Fin_block)
 | 
						||
  {
 | 
						||
    Indice=Debut_block;
 | 
						||
    Debut_block=Fin_block;
 | 
						||
    Fin_block=Indice;
 | 
						||
  }
 | 
						||
 | 
						||
  for (Indice=Debut_Y;Indice<Fin_Y;Indice++,Ligne_en_cours++)
 | 
						||
    Block(Debut_X,Indice,Largeur_ligne,1,Debut_block+(Nb_couleurs*Ligne_en_cours)/Total_lignes);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  // -- Redimentionner l'image (nettoie l'<27>cran virtuel) --
 | 
						||
 | 
						||
void Redimentionner_image(word Largeur_choisie,word Hauteur_choisie)
 | 
						||
{
 | 
						||
  word Ancienne_largeur=Principal_Largeur_image;
 | 
						||
  word Ancienne_hauteur=Principal_Hauteur_image;
 | 
						||
 | 
						||
  // <20><><EFBFBD>Ŀ
 | 
						||
  // <20>C<EFBFBD> <20>  A+B+C = Ancienne image
 | 
						||
  // <20>ĴA<C4B4>
 | 
						||
  // <20>B<EFBFBD> <20>    C   = Nouvelle image
 | 
						||
  // <20><><EFBFBD><EFBFBD><EFBFBD>
 | 
						||
 | 
						||
  if (Backup_avec_nouvelles_dimensions(1,Largeur_choisie,Hauteur_choisie))
 | 
						||
  {
 | 
						||
    // La nouvelle page a pu <20>tre allou<6F>e, elle est pour l'instant pleine de
 | 
						||
    // 0s. Elle fait Principal_Largeur_image de large.
 | 
						||
 | 
						||
    // On copie donc maintenant la partie C dans la nouvelle image.
 | 
						||
    Copier_une_partie_d_image_dans_une_autre(
 | 
						||
      Ecran_backup,0,0,Min(Ancienne_largeur,Principal_Largeur_image),
 | 
						||
      Min(Ancienne_hauteur,Principal_Hauteur_image),Ancienne_largeur,
 | 
						||
      Principal_Ecran,0,0,Principal_Largeur_image);
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    // Afficher un message d'erreur
 | 
						||
    Afficher_curseur();
 | 
						||
    Message_Memoire_insuffisante();
 | 
						||
    Effacer_curseur();
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
  // -- Dessiner un petit sprite repr<70>sentant le type d'un drive --
 | 
						||
 | 
						||
void Fenetre_Afficher_sprite_drive(word Pos_X,word Pos_Y,byte Type)
 | 
						||
{
 | 
						||
  word i,j;
 | 
						||
 | 
						||
  for (j=0; j<HAUTEUR_SPRITE_DRIVE; j++)
 | 
						||
    for (i=0; i<LARGEUR_SPRITE_DRIVE; i++)
 | 
						||
      Pixel_dans_fenetre(Pos_X+i,Pos_Y+j,SPRITE_DRIVE[Type][j][i]);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void Capturer_brosse(short Debut_X,short Debut_Y,short Fin_X,short Fin_Y,short Effacement)
 | 
						||
{
 | 
						||
  short Temporaire;
 | 
						||
  short Pos_X;
 | 
						||
  short Pos_Y;
 | 
						||
  word  Nouvelle_Brosse_Largeur;
 | 
						||
  word  Nouvelle_Brosse_Hauteur;
 | 
						||
 | 
						||
 | 
						||
  // On commence par "redresser" les bornes:
 | 
						||
  if (Debut_X>Fin_X)
 | 
						||
  {
 | 
						||
    Temporaire=Debut_X;
 | 
						||
    Debut_X   =Fin_X;
 | 
						||
    Fin_X     =Temporaire;
 | 
						||
  }
 | 
						||
  if (Debut_Y>Fin_Y)
 | 
						||
  {
 | 
						||
    Temporaire=Debut_Y;
 | 
						||
    Debut_Y   =Fin_Y;
 | 
						||
    Fin_Y     =Temporaire;
 | 
						||
  }
 | 
						||
 | 
						||
  // On ne capture la nouvelle brosse que si elle est au moins partiellement
 | 
						||
  // dans l'image:
 | 
						||
 | 
						||
  if ((Debut_X<Principal_Largeur_image) && (Debut_Y<Principal_Hauteur_image))
 | 
						||
  {
 | 
						||
    // On met les d<>calages du tiling <20> 0 pour eviter toute incoh<6F>rence.
 | 
						||
    // Si par hasard on voulait les mettre <20>
 | 
						||
    //    min(Tiling_Decalage_?,Brosse_?a??eur-1)
 | 
						||
    // il faudrait penser <20> les initialiser <20> 0 dans "MAIN.C".
 | 
						||
    Tiling_Decalage_X=0;
 | 
						||
    Tiling_Decalage_Y=0;
 | 
						||
 | 
						||
    // Ensuite, on calcule les dimensions de la brosse:
 | 
						||
    Nouvelle_Brosse_Largeur=(Fin_X-Debut_X)+1;
 | 
						||
    Nouvelle_Brosse_Hauteur=(Fin_Y-Debut_Y)+1;
 | 
						||
 | 
						||
    if (Debut_X+Nouvelle_Brosse_Largeur>Principal_Largeur_image)
 | 
						||
      Nouvelle_Brosse_Largeur=Principal_Largeur_image-Debut_X;
 | 
						||
    if (Debut_Y+Nouvelle_Brosse_Hauteur>Principal_Hauteur_image)
 | 
						||
      Nouvelle_Brosse_Hauteur=Principal_Hauteur_image-Debut_Y;
 | 
						||
 | 
						||
    if ( (((long)Brosse_Hauteur)*Brosse_Largeur) !=
 | 
						||
         (((long)Nouvelle_Brosse_Hauteur)*Nouvelle_Brosse_Largeur) )
 | 
						||
    {
 | 
						||
      free(Brosse);
 | 
						||
      Brosse=(byte *)malloc(((long)Nouvelle_Brosse_Hauteur)*Nouvelle_Brosse_Largeur);
 | 
						||
      if (!Brosse)
 | 
						||
      {
 | 
						||
        Erreur(0);
 | 
						||
 | 
						||
        Brosse=(byte *)malloc(1*1);
 | 
						||
        Nouvelle_Brosse_Hauteur=Nouvelle_Brosse_Largeur=1;
 | 
						||
        *Brosse=Fore_color;
 | 
						||
      }
 | 
						||
    }
 | 
						||
    Brosse_Largeur=Nouvelle_Brosse_Largeur;
 | 
						||
    Brosse_Hauteur=Nouvelle_Brosse_Hauteur;
 | 
						||
 | 
						||
    free(Smear_Brosse);
 | 
						||
    Smear_Brosse_Largeur=(Brosse_Largeur>TAILLE_MAXI_PINCEAU)?Brosse_Largeur:TAILLE_MAXI_PINCEAU;
 | 
						||
    Smear_Brosse_Hauteur=(Brosse_Hauteur>TAILLE_MAXI_PINCEAU)?Brosse_Hauteur:TAILLE_MAXI_PINCEAU;
 | 
						||
    Smear_Brosse=(byte *)malloc(((long)Smear_Brosse_Hauteur)*Smear_Brosse_Largeur);
 | 
						||
 | 
						||
    if (!Smear_Brosse) // On ne peut m<>me pas allouer la brosse du smear!
 | 
						||
    {
 | 
						||
      Erreur(0);
 | 
						||
 | 
						||
      free(Brosse);
 | 
						||
      Brosse=(byte *)malloc(1*1);
 | 
						||
      Brosse_Hauteur=1;
 | 
						||
      Brosse_Largeur=1;
 | 
						||
 | 
						||
      Smear_Brosse=(byte *)malloc(TAILLE_MAXI_PINCEAU*TAILLE_MAXI_PINCEAU);
 | 
						||
      Smear_Brosse_Hauteur=TAILLE_MAXI_PINCEAU;
 | 
						||
      Smear_Brosse_Largeur=TAILLE_MAXI_PINCEAU;
 | 
						||
    }
 | 
						||
 | 
						||
    Copier_image_dans_brosse(Debut_X,Debut_Y,Brosse_Largeur,Brosse_Hauteur,Principal_Largeur_image);
 | 
						||
 | 
						||
    // On regarde s'il faut effacer quelque chose:
 | 
						||
    if (Effacement)
 | 
						||
    {
 | 
						||
      for (Pos_Y=Debut_Y;Pos_Y<Debut_Y+Brosse_Hauteur;Pos_Y++)
 | 
						||
        for (Pos_X=Debut_X;Pos_X<Debut_X+Brosse_Largeur;Pos_X++)
 | 
						||
        {
 | 
						||
          Pixel_dans_ecran_courant(Pos_X,Pos_Y,Back_color);
 | 
						||
          Pixel_Preview           (Pos_X,Pos_Y,Back_color);
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
    // On centre la prise sur la brosse
 | 
						||
    Brosse_Decalage_X=(Brosse_Largeur>>1);
 | 
						||
    Brosse_Decalage_Y=(Brosse_Hauteur>>1);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void Rotate_90_deg()
 | 
						||
{
 | 
						||
  short Temporaire;
 | 
						||
  byte * Nouvelle_Brosse;
 | 
						||
 | 
						||
  Nouvelle_Brosse=(byte *)malloc(((long)Brosse_Hauteur)*Brosse_Largeur);
 | 
						||
  if (Nouvelle_Brosse)
 | 
						||
  {
 | 
						||
    Rotate_90_deg_LOWLEVEL(Brosse,Nouvelle_Brosse);
 | 
						||
    free(Brosse);
 | 
						||
    Brosse=Nouvelle_Brosse;
 | 
						||
 | 
						||
    Temporaire=Brosse_Largeur;
 | 
						||
    Brosse_Largeur=Brosse_Hauteur;
 | 
						||
    Brosse_Hauteur=Temporaire;
 | 
						||
 | 
						||
    Temporaire=Smear_Brosse_Largeur;
 | 
						||
    Smear_Brosse_Largeur=Smear_Brosse_Hauteur;
 | 
						||
    Smear_Brosse_Hauteur=Temporaire;
 | 
						||
 | 
						||
    // On centre la prise sur la brosse
 | 
						||
    Brosse_Decalage_X=(Brosse_Largeur>>1);
 | 
						||
    Brosse_Decalage_Y=(Brosse_Hauteur>>1);
 | 
						||
  }
 | 
						||
  else
 | 
						||
    Erreur(0);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void Remap_brosse(void)
 | 
						||
{
 | 
						||
  short Pos_X; // Variable de balayage de la brosse
 | 
						||
  short Pos_Y; // Variable de balayage de la brosse
 | 
						||
  byte  Utilisee[256]; // Tableau de bool<6F>ens "La couleur est utilis<69>e"
 | 
						||
  int   Couleur;
 | 
						||
 | 
						||
 | 
						||
  // On commence par initialiser le tableau de bool<6F>ens <20> faux
 | 
						||
  for (Couleur=0;Couleur<=255;Couleur++)
 | 
						||
    Utilisee[Couleur]=0;
 | 
						||
 | 
						||
  // On calcule la table d'utilisation des couleurs
 | 
						||
  for (Pos_Y=0;Pos_Y<Brosse_Hauteur;Pos_Y++)
 | 
						||
    for (Pos_X=0;Pos_X<Brosse_Largeur;Pos_X++)
 | 
						||
      Utilisee[Lit_pixel_dans_brosse(Pos_X,Pos_Y)]=1;
 | 
						||
 | 
						||
  //  On n'est pas cens<6E> remapper la couleur de transparence, sinon la brosse
 | 
						||
  // changera de forme, donc on dit pour l'instant qu'elle n'est pas utilis<69>e
 | 
						||
  // ainsi on ne s'emb<6D>tera pas <20> la recalculer
 | 
						||
  Utilisee[Back_color]=0;
 | 
						||
 | 
						||
  //   On va maintenant se servir de la table "Utilisee" comme table de
 | 
						||
  // conversion: pour chaque indice, la table donne une couleur de
 | 
						||
  // remplacement.
 | 
						||
  // Note : Seules les couleurs utilis<69>es on besoin d'<27>tres recalcul<75>es: les
 | 
						||
  //       autres ne seront jamais consult<6C>es dans la nouvelle table de
 | 
						||
  //       conversion puisque elles n'existent pas dans la brosse, donc elles
 | 
						||
  //       ne seront pas utilis<69>es par Remap_brush_LOWLEVEL.
 | 
						||
  for (Couleur=0;Couleur<=255;Couleur++)
 | 
						||
    if (Utilisee[Couleur])
 | 
						||
      Utilisee[Couleur]=Meilleure_couleur(Brouillon_Palette[Couleur].R,Brouillon_Palette[Couleur].V,Brouillon_Palette[Couleur].B);
 | 
						||
      //Utilisee[Couleur]=Meilleure_couleur_sans_exclusion(Brouillon_Palette[Couleur].R,Brouillon_Palette[Couleur].V,Brouillon_Palette[Couleur].B);
 | 
						||
 | 
						||
  //   Il reste une couleur non calcul<75>e dans la table qu'il faut mettre <20>
 | 
						||
  // jour: c'est la couleur de fond. On l'avait inhib<69>e pour <20>viter son
 | 
						||
  // calcul inutile, mais comme il est possible qu'elle soit quand m<>me dans
 | 
						||
  // la brosse, on va mettre dans la table une relation d'<27>quivalence entre
 | 
						||
  // les deux palettes: comme on ne veut pas que la couleur soit remplac<61>e,
 | 
						||
  // on va dire qu'on veut qu'elle soit remplac<61>e par la couleur en question.
 | 
						||
  Utilisee[Back_color]=Back_color;
 | 
						||
 | 
						||
  //   Maintenant qu'on a une super table de conversion qui n'a que le nom
 | 
						||
  // qui craint un peu, on peut faire l'<27>change dans la brosse de toutes les
 | 
						||
  // teintes.
 | 
						||
  Remap_general_LOWLEVEL(Utilisee,Brosse,Brosse_Largeur,Brosse_Hauteur,Brosse_Largeur);
 | 
						||
  //Remap_brush_LOWLEVEL(Utilisee);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
void Remap_picture(void)
 | 
						||
{
 | 
						||
  short Pos_X; // Variable de balayage de la brosse
 | 
						||
  short Pos_Y; // Variable de balayage de la brosse
 | 
						||
  byte  Utilisee[256]; // Tableau de bool<6F>ens "La couleur est utilis<69>e"
 | 
						||
  int   Couleur;
 | 
						||
 | 
						||
  // On commence par initialiser le tableau de bool<6F>ens <20> faux
 | 
						||
  for (Couleur=0;Couleur<=255;Couleur++)
 | 
						||
    Utilisee[Couleur]=0;
 | 
						||
 | 
						||
  // On calcule la table d'utilisation des couleurs
 | 
						||
  for (Pos_Y=0;Pos_Y<Brouillon_Hauteur_image;Pos_Y++)
 | 
						||
    for (Pos_X=0;Pos_X<Brouillon_Largeur_image;Pos_X++)
 | 
						||
      Utilisee[Lit_pixel_dans_ecran_brouillon(Pos_X,Pos_Y)]=1;
 | 
						||
 | 
						||
  //   On va maintenant se servir de la table "Utilisee" comme table de
 | 
						||
  // conversion: pour chaque indice, la table donne une couleur de
 | 
						||
  // remplacement.
 | 
						||
  // Note : Seules les couleurs utilis<69>es on besoin d'<27>tres recalcul<75>es: les
 | 
						||
  //       autres ne seront jamais consult<6C>es dans la nouvelle table de
 | 
						||
  //       conversion puisque elles n'existent pas dans l'image, donc elles
 | 
						||
  //       ne seront pas utilis<69>es par Remap_general_LOWLEVEL.
 | 
						||
  for (Couleur=0;Couleur<=255;Couleur++)
 | 
						||
    if (Utilisee[Couleur])
 | 
						||
      Utilisee[Couleur]=Meilleure_couleur(Brouillon_Palette[Couleur].R,Brouillon_Palette[Couleur].V,Brouillon_Palette[Couleur].B);
 | 
						||
      //Utilisee[Couleur]=Meilleure_couleur_sans_exclusion(Brouillon_Palette[Couleur].R,Brouillon_Palette[Couleur].V,Brouillon_Palette[Couleur].B);
 | 
						||
 | 
						||
  //   Maintenant qu'on a une super table de conversion qui n'a que le nom
 | 
						||
  // qui craint un peu, on peut faire l'<27>change dans la brosse de toutes les
 | 
						||
  // teintes.
 | 
						||
  Remap_general_LOWLEVEL(Utilisee,Brouillon_Ecran,Brouillon_Largeur_image,Brouillon_Hauteur_image,Brouillon_Largeur_image);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
void Get_colors_from_brush(void)
 | 
						||
{
 | 
						||
  short Pos_X; // Variable de balayage de la brosse
 | 
						||
  short Pos_Y; // Variable de balayage de la brosse
 | 
						||
  byte  Utilisee[256]; // Tableau de bool<6F>ens "La couleur est utilis<69>e"
 | 
						||
  int   Couleur;
 | 
						||
 | 
						||
  if (Demande_de_confirmation("Modify current palette ?"))
 | 
						||
  {
 | 
						||
    Backup();
 | 
						||
 | 
						||
    // On commence par initialiser le tableau de bool<6F>en <20> faux
 | 
						||
    for (Couleur=0;Couleur<=255;Couleur++)
 | 
						||
      Utilisee[Couleur]=0;
 | 
						||
 | 
						||
    // On calcule la table d'utilisation des couleurs
 | 
						||
    for (Pos_Y=0;Pos_Y<Brosse_Hauteur;Pos_Y++)
 | 
						||
      for (Pos_X=0;Pos_X<Brosse_Largeur;Pos_X++)
 | 
						||
        Utilisee[Lit_pixel_dans_brosse(Pos_X,Pos_Y)]=1;
 | 
						||
 | 
						||
    // On recopie dans la palette principale les teintes des couleurs utilis<69>es
 | 
						||
    // dans la palette du brouillon
 | 
						||
    for (Couleur=0;Couleur<=255;Couleur++)
 | 
						||
      if (Utilisee[Couleur])
 | 
						||
      {
 | 
						||
        Principal_Palette[Couleur].R=Brouillon_Palette[Couleur].R;
 | 
						||
        Principal_Palette[Couleur].V=Brouillon_Palette[Couleur].V;
 | 
						||
        Principal_Palette[Couleur].B=Brouillon_Palette[Couleur].B;
 | 
						||
      }
 | 
						||
 | 
						||
    Set_palette(Principal_Palette);
 | 
						||
    Calculer_couleurs_menu_optimales(Principal_Palette);
 | 
						||
    Effacer_curseur();
 | 
						||
    Afficher_ecran();
 | 
						||
    Afficher_menu();
 | 
						||
    Afficher_curseur();
 | 
						||
 | 
						||
    Principal_Image_modifiee=1;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
void Outline_brush(void)
 | 
						||
{
 | 
						||
  long /*Pos,*/Pos_X,Pos_Y;
 | 
						||
  byte Etat;
 | 
						||
  byte * Nouvelle_brosse;
 | 
						||
  byte * Temporaire;
 | 
						||
  word Largeur;
 | 
						||
  word Hauteur;
 | 
						||
 | 
						||
 | 
						||
  Largeur=Brosse_Largeur+2;
 | 
						||
  Hauteur=Brosse_Hauteur+2;
 | 
						||
  Nouvelle_brosse=(byte *)malloc(((long)Largeur)*Hauteur);
 | 
						||
 | 
						||
  if (Nouvelle_brosse)
 | 
						||
  {
 | 
						||
    // On remplit la bordure ajout<75>e par la Backcolor
 | 
						||
    memset(Nouvelle_brosse,Back_color,((long)Largeur)*Hauteur);
 | 
						||
 | 
						||
    // On copie la brosse courante dans la nouvelle
 | 
						||
    Copier_une_partie_d_image_dans_une_autre(Brosse, // Source
 | 
						||
                                             0, 0,
 | 
						||
                                             Brosse_Largeur,
 | 
						||
                                             Brosse_Hauteur,
 | 
						||
                                             Brosse_Largeur,
 | 
						||
                                             Nouvelle_brosse, // Destination
 | 
						||
                                             1, 1,
 | 
						||
                                             Largeur);
 | 
						||
 | 
						||
    // On intervertit la nouvelle et l'ancienne brosse:
 | 
						||
    Temporaire=Brosse;
 | 
						||
    Brosse=Nouvelle_brosse;
 | 
						||
    Brosse_Largeur+=2;
 | 
						||
    Brosse_Hauteur+=2;
 | 
						||
    Largeur-=2;
 | 
						||
    Hauteur-=2;
 | 
						||
 | 
						||
    // Si on "outline" avec une couleur diff<66>rente de la Back_color on y va!
 | 
						||
    if (Fore_color!=Back_color)
 | 
						||
    {
 | 
						||
      // 1er balayage (horizontal)
 | 
						||
      for (Pos_Y=1; Pos_Y<Brosse_Hauteur-1; Pos_Y++)
 | 
						||
      {
 | 
						||
        Etat=0;
 | 
						||
        for (Pos_X=1; Pos_X<Brosse_Largeur-1; Pos_X++)
 | 
						||
        {
 | 
						||
          if (Temporaire[((Pos_Y-1)*Largeur)+Pos_X-1]==Back_color)
 | 
						||
          {
 | 
						||
            if (Etat)
 | 
						||
            {
 | 
						||
              Pixel_dans_brosse(Pos_X,Pos_Y,Fore_color);
 | 
						||
              Etat=0;
 | 
						||
            }
 | 
						||
          }
 | 
						||
          else
 | 
						||
          {
 | 
						||
            if (!Etat)
 | 
						||
            {
 | 
						||
              Pixel_dans_brosse(Pos_X-1,Pos_Y,Fore_color);
 | 
						||
              Etat=1;
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
        // Cas du dernier pixel <20> droite de la ligne
 | 
						||
        if (Etat)
 | 
						||
          Pixel_dans_brosse(Pos_X,Pos_Y,Fore_color);
 | 
						||
      }
 | 
						||
 | 
						||
      // 2<>me balayage (vertical)
 | 
						||
      for (Pos_X=1; Pos_X<Brosse_Largeur-1; Pos_X++)
 | 
						||
      {
 | 
						||
        Etat=0;
 | 
						||
        for (Pos_Y=1; Pos_Y<Brosse_Hauteur-1; Pos_Y++)
 | 
						||
        {
 | 
						||
          if (Temporaire[((Pos_Y-1)*Largeur)+Pos_X-1]==Back_color)
 | 
						||
          {
 | 
						||
            if (Etat)
 | 
						||
            {
 | 
						||
              Pixel_dans_brosse(Pos_X,Pos_Y,Fore_color);
 | 
						||
              Etat=0;
 | 
						||
            }
 | 
						||
          }
 | 
						||
          else
 | 
						||
          {
 | 
						||
            if (!Etat)
 | 
						||
            {
 | 
						||
              Pixel_dans_brosse(Pos_X,Pos_Y-1,Fore_color);
 | 
						||
              Etat=1;
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
        // Cas du dernier pixel en bas de la colonne
 | 
						||
        if (Etat)
 | 
						||
          Pixel_dans_brosse(Pos_X,Pos_Y,Fore_color);
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    // On recentre la prise sur la brosse
 | 
						||
    Brosse_Decalage_X=(Brosse_Largeur>>1);
 | 
						||
    Brosse_Decalage_Y=(Brosse_Hauteur>>1);
 | 
						||
 | 
						||
    free(Temporaire); // Lib<69>ration de l'ancienne brosse
 | 
						||
 | 
						||
    // R<>allocation d'un buffer de Smear
 | 
						||
    free(Smear_Brosse);
 | 
						||
    Smear_Brosse_Largeur=(Brosse_Largeur>TAILLE_MAXI_PINCEAU)?Brosse_Largeur:TAILLE_MAXI_PINCEAU;
 | 
						||
    Smear_Brosse_Hauteur=(Brosse_Hauteur>TAILLE_MAXI_PINCEAU)?Brosse_Hauteur:TAILLE_MAXI_PINCEAU;
 | 
						||
    Smear_Brosse=(byte *)malloc(((long)Smear_Brosse_Largeur)*Smear_Brosse_Hauteur);
 | 
						||
  }
 | 
						||
  else
 | 
						||
    Erreur(0); // Pas assez de m<>moire!
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void Nibble_brush(void)
 | 
						||
{
 | 
						||
  long /*Pos,*/Pos_X,Pos_Y;
 | 
						||
  byte Etat;
 | 
						||
  byte * Nouvelle_brosse;
 | 
						||
  byte * Temporaire;
 | 
						||
  word Largeur;
 | 
						||
  word Hauteur;
 | 
						||
 | 
						||
  if ( (Brosse_Largeur>2) && (Brosse_Hauteur>2) )
 | 
						||
  {
 | 
						||
    Largeur=Brosse_Largeur-2;
 | 
						||
    Hauteur=Brosse_Hauteur-2;
 | 
						||
    Nouvelle_brosse=(byte *)malloc(((long)Largeur)*Hauteur);
 | 
						||
 | 
						||
    if (Nouvelle_brosse)
 | 
						||
    {
 | 
						||
      // On copie la brosse courante dans la nouvelle
 | 
						||
      Copier_une_partie_d_image_dans_une_autre(Brosse, // Source
 | 
						||
                                               1,
 | 
						||
                                               1,
 | 
						||
                                               Largeur,
 | 
						||
                                               Hauteur,
 | 
						||
                                               Brosse_Largeur,
 | 
						||
                                               Nouvelle_brosse, // Destination
 | 
						||
                                               0,
 | 
						||
                                               0,
 | 
						||
                                               Largeur);
 | 
						||
 | 
						||
      // On intervertit la nouvelle et l'ancienne brosse:
 | 
						||
      Temporaire=Brosse;
 | 
						||
      Brosse=Nouvelle_brosse;
 | 
						||
      Brosse_Largeur-=2;
 | 
						||
      Brosse_Hauteur-=2;
 | 
						||
      Largeur+=2;
 | 
						||
      Hauteur+=2;
 | 
						||
 | 
						||
      // 1er balayage (horizontal)
 | 
						||
      for (Pos_Y=0; Pos_Y<Brosse_Hauteur; Pos_Y++)
 | 
						||
      {
 | 
						||
        Etat=(Temporaire[(Pos_Y+1)*Largeur]!=Back_color);
 | 
						||
        for (Pos_X=0; Pos_X<Brosse_Largeur; Pos_X++)
 | 
						||
        {
 | 
						||
          if (Temporaire[((Pos_Y+1)*Largeur)+Pos_X+1]==Back_color)
 | 
						||
          {
 | 
						||
            if (Etat)
 | 
						||
            {
 | 
						||
              if (Pos_X>0)
 | 
						||
                Pixel_dans_brosse(Pos_X-1,Pos_Y,Back_color);
 | 
						||
              Etat=0;
 | 
						||
            }
 | 
						||
          }
 | 
						||
          else
 | 
						||
          {
 | 
						||
            if (!Etat)
 | 
						||
            {
 | 
						||
              Pixel_dans_brosse(Pos_X,Pos_Y,Back_color);
 | 
						||
              Etat=1;
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
        // Cas du dernier pixel <20> droite de la ligne
 | 
						||
        if (Temporaire[((Pos_Y+1)*Largeur)+Pos_X+1]==Back_color)
 | 
						||
          Pixel_dans_brosse(Pos_X-1,Pos_Y,Back_color);
 | 
						||
      }
 | 
						||
 | 
						||
      // 2<>me balayage (vertical)
 | 
						||
      for (Pos_X=0; Pos_X<Brosse_Largeur; Pos_X++)
 | 
						||
      {
 | 
						||
        Etat=(Temporaire[Largeur+Pos_X+1]!=Back_color);;
 | 
						||
        for (Pos_Y=0; Pos_Y<Brosse_Hauteur; Pos_Y++)
 | 
						||
        {
 | 
						||
          if (Temporaire[((Pos_Y+1)*Largeur)+Pos_X+1]==Back_color)
 | 
						||
          {
 | 
						||
            if (Etat)
 | 
						||
            {
 | 
						||
              if (Pos_Y>0)
 | 
						||
                Pixel_dans_brosse(Pos_X,Pos_Y-1,Back_color);
 | 
						||
              Etat=0;
 | 
						||
            }
 | 
						||
          }
 | 
						||
          else
 | 
						||
          {
 | 
						||
            if (!Etat)
 | 
						||
            {
 | 
						||
              Pixel_dans_brosse(Pos_X,Pos_Y,Back_color);
 | 
						||
              Etat=1;
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
        // Cas du dernier pixel en bas de la colonne
 | 
						||
        if (Temporaire[((Pos_Y+1)*Largeur)+Pos_X+1]==Back_color)
 | 
						||
          Pixel_dans_brosse(Pos_X,Pos_Y-1,Back_color);
 | 
						||
      }
 | 
						||
 | 
						||
      // On recentre la prise sur la brosse
 | 
						||
      Brosse_Decalage_X=(Brosse_Largeur>>1);
 | 
						||
      Brosse_Decalage_Y=(Brosse_Hauteur>>1);
 | 
						||
 | 
						||
      free(Temporaire); // Lib<69>ration de l'ancienne brosse
 | 
						||
 | 
						||
      // R<>allocation d'un buffer de Smear
 | 
						||
      free(Smear_Brosse);
 | 
						||
      Smear_Brosse_Largeur=(Brosse_Largeur>TAILLE_MAXI_PINCEAU)?Brosse_Largeur:TAILLE_MAXI_PINCEAU;
 | 
						||
      Smear_Brosse_Hauteur=(Brosse_Hauteur>TAILLE_MAXI_PINCEAU)?Brosse_Hauteur:TAILLE_MAXI_PINCEAU;
 | 
						||
      Smear_Brosse=(byte *)malloc(((long)Smear_Brosse_Largeur)*Smear_Brosse_Hauteur);
 | 
						||
    }
 | 
						||
    else
 | 
						||
      Erreur(0);  // Pas assez de m<>moire!
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
//////////////////////////////////////////////////////////////////////////////
 | 
						||
////////////////////////////// GESTION DU FILLER /////////////////////////////
 | 
						||
//////////////////////////////////////////////////////////////////////////////
 | 
						||
 | 
						||
 | 
						||
void Fill(short * Limite_atteinte_Haut  , short * Limite_atteinte_Bas,
 | 
						||
          short * Limite_atteinte_Gauche, short * Limite_atteinte_Droite)
 | 
						||
//
 | 
						||
//   Cette fonction fait un remplissage classique d'une zone d<>limit<69>e de
 | 
						||
// l'image. Les limites employ<6F>es sont Limite_Haut, Limite_Bas, Limite_Gauche
 | 
						||
// et Limite_Droite. Le point de d<>part du remplissage est Pinceau_X,Pinceau_Y
 | 
						||
// et s'effectue en th<74>orie sur la couleur 1 et emploie la couleur 2 pour le
 | 
						||
// remplissage. Ces restrictions sont d<>es <20> l'utilisation qu'on en fait dans
 | 
						||
// la fonction principale "Remplir", qui se charge de faire une gestion de
 | 
						||
// tous les effets.
 | 
						||
//   Cette fonction ne doit pas <20>tre directement appel<65>e.
 | 
						||
//
 | 
						||
{
 | 
						||
  short Pos_X;   // Abscisse de balayage du segment, utilis<69>e lors de l'"affichage"
 | 
						||
  short Ligne;   // Ordonn<6E>e de la ligne en cours de traitement
 | 
						||
  short Debut_X; // Abscisse de d<>part du segment trait<69>
 | 
						||
  short Fin_X;   // Abscisse de fin du segment trait<69>
 | 
						||
  int   Modifs_effectuees;    // Bool<6F>en "On a fait une modif dans le dernier passage"
 | 
						||
  int   Propagation_possible; // Bool<6F>en "On peut propager la couleur dans le segment"
 | 
						||
  short Limite_courante_Bas;  // Intervalle vertical restreint
 | 
						||
  short Limite_courante_Haut;
 | 
						||
  int   Ligne_modifiee;       // Bool<6F>en "On a fait une modif dans la ligne"
 | 
						||
 | 
						||
  Modifs_effectuees=1;
 | 
						||
  Limite_courante_Haut=Pinceau_Y;
 | 
						||
  Limite_courante_Bas =Min(Pinceau_Y+1,Limite_Bas);
 | 
						||
  *Limite_atteinte_Gauche=Pinceau_X;
 | 
						||
  *Limite_atteinte_Droite=Pinceau_X+1;
 | 
						||
  Pixel_dans_ecran_courant(Pinceau_X,Pinceau_Y,2);
 | 
						||
 | 
						||
  while (Modifs_effectuees)
 | 
						||
  {
 | 
						||
    Modifs_effectuees=0;
 | 
						||
 | 
						||
    for (Ligne=Limite_courante_Haut;Ligne<=Limite_courante_Bas;Ligne++)
 | 
						||
    {
 | 
						||
      Ligne_modifiee=0;
 | 
						||
      // On va traiter le cas de la ligne n<> Ligne.
 | 
						||
 | 
						||
      // On commence le traitement <20> la gauche de l'<27>cran
 | 
						||
      Debut_X=Limite_Gauche;
 | 
						||
 | 
						||
      // Pour chaque segment de couleur 1 que peut contenir la ligne
 | 
						||
      while (Debut_X<=Limite_Droite)
 | 
						||
      {
 | 
						||
        // On cherche son d<>but
 | 
						||
        while((Debut_X<=Limite_Droite) && 
 | 
						||
                (Lit_pixel_dans_ecran_courant(Debut_X,Ligne)!=1))
 | 
						||
             Debut_X++;
 | 
						||
 | 
						||
        if (Debut_X<=Limite_Droite)
 | 
						||
        {
 | 
						||
          // Un segment de couleur 1 existe et commence <20> la position Debut_X.
 | 
						||
          // On va donc en chercher la fin.
 | 
						||
          for (Fin_X=Debut_X+1;(Fin_X<=Limite_Droite) &&
 | 
						||
               (Lit_pixel_dans_ecran_courant(Fin_X,Ligne)==1);Fin_X++);
 | 
						||
 | 
						||
          //   On sait qu'il existe un segment de couleur 1 qui commence en
 | 
						||
          // Debut_X et qui se termine en Fin_X-1.
 | 
						||
 | 
						||
          //   On va maintenant regarder si une couleur sur la p<>riph<70>rie
 | 
						||
          // permet de colorier ce segment avec la couleur 2.
 | 
						||
 | 
						||
          Propagation_possible=(
 | 
						||
            // Test de la pr<70>sence d'un point <20> gauche du segment
 | 
						||
            ((Debut_X>Limite_Gauche) &&
 | 
						||
             (Lit_pixel_dans_ecran_courant(Debut_X-1,Ligne)==2)) ||
 | 
						||
            // Test de la pr<70>sence d'un point <20> droite du segment
 | 
						||
            ((Fin_X-1<Limite_Droite) &&
 | 
						||
             (Lit_pixel_dans_ecran_courant(Fin_X    ,Ligne)==2))
 | 
						||
                               );
 | 
						||
 | 
						||
          // Test de la pr<70>sence d'un point en haut du segment
 | 
						||
          if (!Propagation_possible && (Ligne>Limite_Haut))
 | 
						||
            for (Pos_X=Debut_X;Pos_X<Fin_X;Pos_X++)
 | 
						||
              if (Lit_pixel_dans_ecran_courant(Pos_X,Ligne-1)==2)
 | 
						||
              {
 | 
						||
                Propagation_possible=1;
 | 
						||
                break;
 | 
						||
              }
 | 
						||
 | 
						||
          if (Propagation_possible)
 | 
						||
          {
 | 
						||
            if (Debut_X<*Limite_atteinte_Gauche)
 | 
						||
              *Limite_atteinte_Gauche=Debut_X;
 | 
						||
            if (Fin_X>*Limite_atteinte_Droite)
 | 
						||
              *Limite_atteinte_Droite=Fin_X;
 | 
						||
            // On remplit le segment de Debut_X <20> Fin_X-1.
 | 
						||
            for (Pos_X=Debut_X;Pos_X<Fin_X;Pos_X++)
 | 
						||
              Pixel_dans_ecran_courant(Pos_X,Ligne,2);
 | 
						||
            // On vient d'effectuer des modifications.
 | 
						||
            Modifs_effectuees=1;
 | 
						||
            Ligne_modifiee=1;
 | 
						||
          }
 | 
						||
 | 
						||
          Debut_X=Fin_X+1;
 | 
						||
        }
 | 
						||
      }
 | 
						||
 | 
						||
      // Si on est en bas, et qu'on peut se propager vers le bas...
 | 
						||
      if ( (Ligne==Limite_courante_Bas) &&
 | 
						||
           (Ligne_modifiee) &&
 | 
						||
           (Limite_courante_Bas<Limite_Bas) )
 | 
						||
        Limite_courante_Bas++; // On descend cette limite vers le bas
 | 
						||
    }
 | 
						||
 | 
						||
    // Pour le prochain balayage vers le haut, on va se permettre d'aller
 | 
						||
    // voir une ligne plus haut.
 | 
						||
    // Si on ne le fait pas, et que la premi<6D>re ligne (Limite_courante_Haut)
 | 
						||
    // n'<27>tait pas modifi<66>e, alors cette limite ne serait pas remont<6E>e, donc
 | 
						||
    // le filler ne progresserait pas vers le haut.
 | 
						||
    if (Limite_courante_Haut>Limite_Haut)
 | 
						||
      Limite_courante_Haut--;
 | 
						||
 | 
						||
    for (Ligne=Limite_courante_Bas;Ligne>=Limite_courante_Haut;Ligne--)
 | 
						||
    {
 | 
						||
      Ligne_modifiee=0;
 | 
						||
      // On va traiter le cas de la ligne n<> Ligne.
 | 
						||
 | 
						||
      // On commence le traitement <20> la gauche de l'<27>cran
 | 
						||
      Debut_X=Limite_Gauche;
 | 
						||
 | 
						||
      // Pour chaque segment de couleur 1 que peut contenir la ligne
 | 
						||
      while (Debut_X<=Limite_Droite)
 | 
						||
      {
 | 
						||
        // On cherche son d<>but
 | 
						||
        for (;(Debut_X<=Limite_Droite) &&
 | 
						||
             (Lit_pixel_dans_ecran_courant(Debut_X,Ligne)!=1);Debut_X++);
 | 
						||
 | 
						||
        if (Debut_X<=Limite_Droite)
 | 
						||
        {
 | 
						||
          // Un segment de couleur 1 existe et commence <20> la position Debut_X.
 | 
						||
          // On va donc en chercher la fin.
 | 
						||
          for (Fin_X=Debut_X+1;(Fin_X<=Limite_Droite) &&
 | 
						||
               (Lit_pixel_dans_ecran_courant(Fin_X,Ligne)==1);Fin_X++);
 | 
						||
 | 
						||
          //   On sait qu'il existe un segment de couleur 1 qui commence en
 | 
						||
          // Debut_X et qui se termine en Fin_X-1.
 | 
						||
 | 
						||
          //   On va maintenant regarder si une couleur sur la p<>riph<70>rie
 | 
						||
          // permet de colorier ce segment avec la couleur 2.
 | 
						||
 | 
						||
          Propagation_possible=(
 | 
						||
            // Test de la pr<70>sence d'un point <20> gauche du segment
 | 
						||
            ((Debut_X>Limite_Gauche) &&
 | 
						||
             (Lit_pixel_dans_ecran_courant(Debut_X-1,Ligne)==2)) ||
 | 
						||
            // Test de la pr<70>sence d'un point <20> droite du segment
 | 
						||
            ((Fin_X-1<Limite_Droite) &&
 | 
						||
             (Lit_pixel_dans_ecran_courant(Fin_X    ,Ligne)==2))
 | 
						||
                               );
 | 
						||
 | 
						||
          // Test de la pr<70>sence d'un point en bas du segment
 | 
						||
          if (!Propagation_possible && (Ligne<Limite_Bas))
 | 
						||
            for (Pos_X=Debut_X;Pos_X<Fin_X;Pos_X++)
 | 
						||
              if (Lit_pixel_dans_ecran_courant(Pos_X,Ligne+1)==2)
 | 
						||
              {
 | 
						||
                Propagation_possible=1;
 | 
						||
                break;
 | 
						||
              }
 | 
						||
 | 
						||
          if (Propagation_possible)
 | 
						||
          {
 | 
						||
            if (Debut_X<*Limite_atteinte_Gauche)
 | 
						||
              *Limite_atteinte_Gauche=Debut_X;
 | 
						||
            if (Fin_X>*Limite_atteinte_Droite)
 | 
						||
              *Limite_atteinte_Droite=Fin_X;
 | 
						||
            // On remplit le segment de Debut_X <20> Fin_X-1.
 | 
						||
            for (Pos_X=Debut_X;Pos_X<Fin_X;Pos_X++)
 | 
						||
              Pixel_dans_ecran_courant(Pos_X,Ligne,2);
 | 
						||
            // On vient d'effectuer des modifications.
 | 
						||
            Modifs_effectuees=1;
 | 
						||
            Ligne_modifiee=1;
 | 
						||
          }
 | 
						||
 | 
						||
          Debut_X=Fin_X+1;
 | 
						||
        }
 | 
						||
      }
 | 
						||
 | 
						||
      // Si on est en haut, et qu'on peut se propager vers le haut...
 | 
						||
      if ( (Ligne==Limite_courante_Haut) &&
 | 
						||
           (Ligne_modifiee) &&
 | 
						||
           (Limite_courante_Haut>Limite_Haut) )
 | 
						||
        Limite_courante_Haut--; // On monte cette limite vers le haut
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  *Limite_atteinte_Haut=Limite_courante_Haut;
 | 
						||
  *Limite_atteinte_Bas =Limite_courante_Bas;
 | 
						||
  (*Limite_atteinte_Droite)--;
 | 
						||
} // Fin de la routine de remplissage "Fill"
 | 
						||
 | 
						||
 | 
						||
void Remplir(byte Couleur_de_remplissage)
 | 
						||
//
 | 
						||
//  Cette fonction fait un remplissage qui g<>re tous les effets. Elle fait
 | 
						||
// appel <20> "Fill()".
 | 
						||
//
 | 
						||
{
 | 
						||
  byte   Forme_curseur_avant_remplissage;
 | 
						||
  byte * FX_Feedback_Ecran_avant_remplissage;
 | 
						||
  short  Pos_X,Pos_Y;
 | 
						||
  short  Limite_atteinte_Haut  ,Limite_atteinte_Bas;
 | 
						||
  short  Limite_atteinte_Gauche,Limite_atteinte_Droite;
 | 
						||
  byte   Table_de_remplacement[256];
 | 
						||
 | 
						||
 | 
						||
  // Avant toute chose, on v<>rifie que l'on n'est pas en train de remplir
 | 
						||
  // en dehors de l'image:
 | 
						||
 | 
						||
  if ( (Pinceau_X>=Limite_Gauche) &&
 | 
						||
       (Pinceau_X<=Limite_Droite) &&
 | 
						||
       (Pinceau_Y>=Limite_Haut)   &&
 | 
						||
       (Pinceau_Y<=Limite_Bas) )
 | 
						||
  {
 | 
						||
    // On suppose que le curseur est d<>j<EFBFBD> cach<63>.
 | 
						||
    // Effacer_curseur();
 | 
						||
 | 
						||
    //   On va faire patienter l'utilisateur en lui affichant un joli petit
 | 
						||
    // sablier:
 | 
						||
    Forme_curseur_avant_remplissage=Forme_curseur;
 | 
						||
    Forme_curseur=FORME_CURSEUR_SABLIER;
 | 
						||
    Afficher_curseur();
 | 
						||
 | 
						||
    // On commence par effectuer un backup de l'image.
 | 
						||
    Backup();
 | 
						||
 | 
						||
    // On fait attention au Feedback qui DOIT se faire avec le backup.
 | 
						||
    FX_Feedback_Ecran_avant_remplissage=FX_Feedback_Ecran;
 | 
						||
    FX_Feedback_Ecran=Ecran_backup;
 | 
						||
 | 
						||
    // On va maintenant "<22>purer" la zone visible de l'image:
 | 
						||
    memset(Table_de_remplacement,0,256);
 | 
						||
    DEBUG("Num couleur",Lit_pixel_dans_ecran_courant(Pinceau_X,Pinceau_Y));
 | 
						||
    Table_de_remplacement[Lit_pixel_dans_ecran_courant(Pinceau_X,Pinceau_Y)]=1;
 | 
						||
    Remplacer_toutes_les_couleurs_dans_limites(Table_de_remplacement);
 | 
						||
 | 
						||
    // On fait maintenant un remplissage classique de la couleur 1 avec la 2
 | 
						||
    Fill(&Limite_atteinte_Haut  ,&Limite_atteinte_Bas,
 | 
						||
         &Limite_atteinte_Gauche,&Limite_atteinte_Droite);
 | 
						||
 | 
						||
    //  On s'appr<70>te <20> faire des op<6F>rations qui n<>cessitent un affichage. Il
 | 
						||
    // faut donc retirer de l'<27>cran le curseur:
 | 
						||
    Effacer_curseur();
 | 
						||
    Forme_curseur=Forme_curseur_avant_remplissage;
 | 
						||
 | 
						||
    //  Il va maintenant falloir qu'on "turn" ce gros caca "into" un truc qui
 | 
						||
    // ressemble un peu plus <20> ce <20> quoi l'utilisateur peut s'attendre.
 | 
						||
    if (Limite_atteinte_Haut>Limite_Haut)
 | 
						||
      Copier_une_partie_d_image_dans_une_autre(Ecran_backup,
 | 
						||
                                               Limite_Gauche,Limite_Haut,
 | 
						||
                                               (Limite_Droite-Limite_Gauche)+1,
 | 
						||
                                               Limite_atteinte_Haut-Limite_Haut,
 | 
						||
                                               Principal_Largeur_image,Principal_Ecran,
 | 
						||
                                               Limite_Gauche,Limite_Haut,Principal_Largeur_image);
 | 
						||
    if (Limite_atteinte_Bas<Limite_Bas)
 | 
						||
      Copier_une_partie_d_image_dans_une_autre(Ecran_backup,
 | 
						||
                                               Limite_Gauche,Limite_atteinte_Bas+1,
 | 
						||
                                               (Limite_Droite-Limite_Gauche)+1,
 | 
						||
                                               Limite_Bas-Limite_atteinte_Bas,
 | 
						||
                                               Principal_Largeur_image,Principal_Ecran,
 | 
						||
                                               Limite_Gauche,Limite_atteinte_Bas+1,Principal_Largeur_image);
 | 
						||
    if (Limite_atteinte_Gauche>Limite_Gauche)
 | 
						||
      Copier_une_partie_d_image_dans_une_autre(Ecran_backup,
 | 
						||
                                               Limite_Gauche,Limite_atteinte_Haut,
 | 
						||
                                               Limite_atteinte_Gauche-Limite_Gauche,
 | 
						||
                                               (Limite_atteinte_Bas-Limite_atteinte_Haut)+1,
 | 
						||
                                               Principal_Largeur_image,Principal_Ecran,
 | 
						||
                                               Limite_Gauche,Limite_atteinte_Haut,Principal_Largeur_image);
 | 
						||
    if (Limite_atteinte_Droite<Limite_Droite)
 | 
						||
      Copier_une_partie_d_image_dans_une_autre(Ecran_backup,
 | 
						||
                                               Limite_atteinte_Droite+1,Limite_atteinte_Haut,
 | 
						||
                                               Limite_Droite-Limite_atteinte_Droite,
 | 
						||
                                               (Limite_atteinte_Bas-Limite_atteinte_Haut)+1,
 | 
						||
                                               Principal_Largeur_image,Principal_Ecran,
 | 
						||
                                               Limite_atteinte_Droite+1,Limite_atteinte_Haut,Principal_Largeur_image);
 | 
						||
 | 
						||
    DEBUG("Haut",Limite_atteinte_Haut);
 | 
						||
    DEBUG("Bas",Limite_atteinte_Bas);
 | 
						||
 | 
						||
    DEBUG("Gauche",Limite_atteinte_Gauche);
 | 
						||
    DEBUG("Droite",Limite_atteinte_Droite);
 | 
						||
 | 
						||
    for (Pos_Y=Limite_atteinte_Haut;Pos_Y<=Limite_atteinte_Bas;Pos_Y++)
 | 
						||
      for (Pos_X=Limite_atteinte_Gauche;Pos_X<=Limite_atteinte_Droite;Pos_X++)
 | 
						||
        if (Lit_pixel_dans_ecran_courant(Pos_X,Pos_Y)==2)
 | 
						||
        {
 | 
						||
          //   Si le pixel en cours de traitement a <20>t<EFBFBD> touch<63> par le Fill()
 | 
						||
          // on se doit d'afficher le pixel modifi<66> par la couleur de
 | 
						||
          // remplissage:
 | 
						||
 | 
						||
          //  Ceci se fait en commen<65>ant par restaurer la couleur qu'il y avait
 | 
						||
          // pr<70>c<EFBFBD>demment (c'est important pour que les effets ne s'emm<6D>lent
 | 
						||
          // pas le pinceaux)
 | 
						||
          Pixel_dans_ecran_courant(Pos_X,Pos_Y,Lit_pixel_dans_ecran_backup(Pos_X,Pos_Y));
 | 
						||
 | 
						||
          //  Enfin, on peut afficher le pixel, en le soumettant aux effets en
 | 
						||
          // cours:
 | 
						||
          Afficher_pixel(Pos_X,Pos_Y,Couleur_de_remplissage);
 | 
						||
        }
 | 
						||
        else
 | 
						||
          Pixel_dans_ecran_courant(Pos_X,Pos_Y,Lit_pixel_dans_ecran_backup(Pos_X,Pos_Y));
 | 
						||
 | 
						||
    FX_Feedback_Ecran=FX_Feedback_Ecran_avant_remplissage;
 | 
						||
 | 
						||
    //   A la fin, on n'a pas besoin de r<>afficher le curseur puisque c'est
 | 
						||
    // l'appelant qui s'en charge, et on n'a pas besoin de rafficher l'image
 | 
						||
    // puisque les seuls points qui ont chang<6E> dans l'image ont <20>t<EFBFBD> raffich<63>s
 | 
						||
    // par l'utilisation de "Afficher_pixel()", et que les autres... eh bein
 | 
						||
    // on n'y a jamais touch<63> <20> l'<27>cran les autres: ils sont donc corrects.
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
//////////////////////////////////////////////////////////////////////////////
 | 
						||
////////////////// TRAC<41>S DE FIGURES G<>OM<4F>TRIQUES STANDARDS //////////////////
 | 
						||
////////////////////////// avec gestion de previews //////////////////////////
 | 
						||
//////////////////////////////////////////////////////////////////////////////
 | 
						||
 | 
						||
  // D<>finition d'une fonction g<>n<EFBFBD>rique de tra<72>age de figures:
 | 
						||
  fonction_afficheur Pixel_figure;
 | 
						||
 | 
						||
  // Affichage d'un point de fa<66>on d<>finitive (utilisation du pinceau)
 | 
						||
  void inline Pixel_figure_Definitif(word Pos_X,word Pos_Y,byte Couleur)
 | 
						||
  {
 | 
						||
    Afficher_pinceau(Pos_X,Pos_Y,Couleur,0);
 | 
						||
  }
 | 
						||
 | 
						||
  // Affichage d'un point pour une preview
 | 
						||
  void Pixel_figure_Preview(word Pos_X,word Pos_Y,byte Couleur)
 | 
						||
  {
 | 
						||
    if ( (Pos_X>=Limite_Gauche) &&
 | 
						||
         (Pos_X<=Limite_Droite) &&
 | 
						||
         (Pos_Y>=Limite_Haut)   &&
 | 
						||
         (Pos_Y<=Limite_Bas) )
 | 
						||
      Pixel_Preview(Pos_X,Pos_Y,Couleur);
 | 
						||
  }
 | 
						||
 | 
						||
  // Affichage d'un point pour une preview en xor
 | 
						||
  void Pixel_figure_Preview_xor(word Pos_X,word Pos_Y,byte Couleur)
 | 
						||
  {
 | 
						||
    if ( (Pos_X>=Limite_Gauche) &&
 | 
						||
         (Pos_X<=Limite_Droite) &&
 | 
						||
         (Pos_Y>=Limite_Haut)   &&
 | 
						||
         (Pos_Y<=Limite_Bas) )
 | 
						||
      Pixel_Preview(Pos_X,Pos_Y,~Lit_pixel(Pos_X-Principal_Decalage_X,
 | 
						||
                                           Pos_Y-Principal_Decalage_Y));
 | 
						||
  }
 | 
						||
 | 
						||
  // Effacement d'un point de preview
 | 
						||
  void Pixel_figure_Effacer_preview(word Pos_X,word Pos_Y,byte Couleur)
 | 
						||
  {
 | 
						||
    if ( (Pos_X>=Limite_Gauche) &&
 | 
						||
         (Pos_X<=Limite_Droite) &&
 | 
						||
         (Pos_Y>=Limite_Haut)   &&
 | 
						||
         (Pos_Y<=Limite_Bas) )
 | 
						||
      Pixel_Preview(Pos_X,Pos_Y,Lit_pixel_dans_ecran_courant(Pos_X,Pos_Y));
 | 
						||
  }
 | 
						||
 | 
						||
  // Affichage d'un point dans la brosse
 | 
						||
  void Pixel_figure_Dans_brosse(word Pos_X,word Pos_Y,byte Couleur)
 | 
						||
  {
 | 
						||
    Pos_X-=Brosse_Decalage_X;
 | 
						||
    Pos_Y-=Brosse_Decalage_Y;
 | 
						||
    if ( (Pos_X<Brosse_Largeur) && // Les pos sont des word donc jamais < 0 ...
 | 
						||
         (Pos_Y<Brosse_Hauteur) )
 | 
						||
      Pixel_dans_brosse(Pos_X,Pos_Y,Couleur);
 | 
						||
  }
 | 
						||
 | 
						||
 | 
						||
  // -- Tracer g<>n<EFBFBD>ral d'un cercle vide -------------------------------------
 | 
						||
 | 
						||
void Tracer_cercle_vide_General(short Centre_X,short Centre_Y,short Rayon,byte Couleur)
 | 
						||
{
 | 
						||
  short Debut_X;
 | 
						||
  short Debut_Y;
 | 
						||
  short Pos_X;
 | 
						||
  short Pos_Y;
 | 
						||
 | 
						||
  // Ensuite, on va parcourire le quart haut gauche du cercle
 | 
						||
  Debut_X=Centre_X-Rayon;
 | 
						||
  Debut_Y=Centre_Y-Rayon;
 | 
						||
 | 
						||
  // Affichage des extremit<69>es du cercle sur chaque quart du cercle:
 | 
						||
  for (Pos_Y=Debut_Y,Cercle_Curseur_Y=-Rayon;Pos_Y<Centre_Y;Pos_Y++,Cercle_Curseur_Y++)
 | 
						||
    for (Pos_X=Debut_X,Cercle_Curseur_X=-Rayon;Pos_X<Centre_X;Pos_X++,Cercle_Curseur_X++)
 | 
						||
      if (Pixel_dans_cercle())
 | 
						||
      {
 | 
						||
        // On vient de tomber sur le premier point sur la ligne horizontale
 | 
						||
        // qui fait partie du cercle.
 | 
						||
        // Donc on peut l'afficher (lui et ses copains sym<79>triques)
 | 
						||
 | 
						||
         // Quart Haut-gauche
 | 
						||
        Pixel_figure(Pos_X,Pos_Y,Couleur);
 | 
						||
         // Quart Haut-droite
 | 
						||
        Pixel_figure((Centre_X<<1)-Pos_X,Pos_Y,Couleur);
 | 
						||
         // Quart Bas-droite
 | 
						||
        Pixel_figure((Centre_X<<1)-Pos_X,(Centre_Y<<1)-Pos_Y,Couleur);
 | 
						||
         // Quart Bas-gauche
 | 
						||
        Pixel_figure(Pos_X,(Centre_Y<<1)-Pos_Y,Couleur);
 | 
						||
 | 
						||
        // On peut ensuite afficher tous les points qui le suivent dont le
 | 
						||
        // pixel voisin du haut n'appartient pas au cercle:
 | 
						||
        for (Cercle_Curseur_Y--,Pos_X++,Cercle_Curseur_X++;Pos_X<Centre_X;Pos_X++,Cercle_Curseur_X++)
 | 
						||
          if (!Pixel_dans_cercle())
 | 
						||
          {
 | 
						||
             // Quart Haut-gauche
 | 
						||
            Pixel_figure(Pos_X,Pos_Y,Couleur);
 | 
						||
             // Quart Haut-droite
 | 
						||
            Pixel_figure((Centre_X<<1)-Pos_X,Pos_Y,Couleur);
 | 
						||
             // Quart Bas-gauche
 | 
						||
            Pixel_figure(Pos_X,(Centre_Y<<1)-Pos_Y,Couleur);
 | 
						||
             // Quart Bas-droite
 | 
						||
            Pixel_figure((Centre_X<<1)-Pos_X,(Centre_Y<<1)-Pos_Y,Couleur);
 | 
						||
          }
 | 
						||
          else
 | 
						||
            break;
 | 
						||
 | 
						||
        Cercle_Curseur_Y++;
 | 
						||
        break;
 | 
						||
      }
 | 
						||
 | 
						||
  // On affiche <20> la fin les points cardinaux:
 | 
						||
  Pixel_figure(Centre_X,Centre_Y-Rayon,Couleur); // Haut
 | 
						||
  Pixel_figure(Centre_X-Rayon,Centre_Y,Couleur); // Gauche
 | 
						||
  Pixel_figure(Centre_X+Rayon,Centre_Y,Couleur); // Droite
 | 
						||
  Pixel_figure(Centre_X,Centre_Y+Rayon,Couleur); // Bas
 | 
						||
 | 
						||
  SDL_UpdateRect(Ecran_SDL,Max(Centre_X-Rayon-Principal_Decalage_X,0),
 | 
						||
        Max(Centre_Y-Rayon-Principal_Decalage_Y,0),2*Rayon+1,2*Rayon+1);
 | 
						||
  if(Loupe_Mode) UpdateZoom(Centre_X-Rayon,Centre_Y-Rayon,2*Rayon+1,2*Rayon+1);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Trac<61> d<>finitif d'un cercle vide --
 | 
						||
 | 
						||
void Tracer_cercle_vide_Definitif(short Centre_X,short Centre_Y,short Rayon,byte Couleur)
 | 
						||
{
 | 
						||
  Pixel_figure=Pixel_figure_Definitif;
 | 
						||
  Tracer_cercle_vide_General(Centre_X,Centre_Y,Rayon,Couleur);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Tracer la preview d'un cercle vide --
 | 
						||
 | 
						||
void Tracer_cercle_vide_Preview(short Centre_X,short Centre_Y,short Rayon,byte Couleur)
 | 
						||
{
 | 
						||
  Pixel_figure=Pixel_figure_Preview;
 | 
						||
  Tracer_cercle_vide_General(Centre_X,Centre_Y,Rayon,Couleur);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Effacer la preview d'un cercle vide --
 | 
						||
 | 
						||
void Effacer_cercle_vide_Preview(short Centre_X,short Centre_Y,short Rayon)
 | 
						||
{
 | 
						||
  Pixel_figure=Pixel_figure_Effacer_preview;
 | 
						||
  Tracer_cercle_vide_General(Centre_X,Centre_Y,Rayon,0);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Tracer un cercle plein --
 | 
						||
 | 
						||
void Tracer_cercle_plein(short Centre_X,short Centre_Y,short Rayon,byte Couleur)
 | 
						||
{
 | 
						||
  short Debut_X;
 | 
						||
  short Debut_Y;
 | 
						||
  short Pos_X;
 | 
						||
  short Pos_Y;
 | 
						||
  short Fin_X;
 | 
						||
  short Fin_Y;
 | 
						||
 | 
						||
  Debut_X=Centre_X-Rayon;
 | 
						||
  Debut_Y=Centre_Y-Rayon;
 | 
						||
  Fin_X=Centre_X+Rayon;
 | 
						||
  Fin_Y=Centre_Y+Rayon;
 | 
						||
 | 
						||
  // Correction des bornes d'apr<70>s les limites
 | 
						||
  if (Debut_Y<Limite_Haut)
 | 
						||
    Debut_Y=Limite_Haut;
 | 
						||
  if (Fin_Y>Limite_Bas)
 | 
						||
    Fin_Y=Limite_Bas;
 | 
						||
  if (Debut_X<Limite_Gauche)
 | 
						||
    Debut_X=Limite_Gauche;
 | 
						||
  if (Fin_X>Limite_Droite)
 | 
						||
    Fin_X=Limite_Droite;
 | 
						||
 | 
						||
  // Affichage du cercle
 | 
						||
  for (Pos_Y=Debut_Y,Cercle_Curseur_Y=(long)Debut_Y-Centre_Y;Pos_Y<=Fin_Y;Pos_Y++,Cercle_Curseur_Y++)
 | 
						||
    for (Pos_X=Debut_X,Cercle_Curseur_X=(long)Debut_X-Centre_X;Pos_X<=Fin_X;Pos_X++,Cercle_Curseur_X++)
 | 
						||
      if (Pixel_dans_cercle())
 | 
						||
        Afficher_pixel(Pos_X,Pos_Y,Couleur);
 | 
						||
 | 
						||
  SDL_UpdateRect(Ecran_SDL,Max(Debut_X+Principal_Decalage_X,0),
 | 
						||
        Max(Debut_Y+Principal_Decalage_Y,0),Fin_X+1-Debut_X,Fin_Y+1-Debut_Y);
 | 
						||
  if(Loupe_Mode) UpdateZoom(Debut_X,Debut_Y,Fin_X+1-Debut_X,Fin_Y+1-Debut_Y);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
  // -- Tracer g<>n<EFBFBD>ral d'une ellipse vide -----------------------------------
 | 
						||
 | 
						||
void Tracer_ellipse_vide_General(short Centre_X,short Centre_Y,short Rayon_horizontal,short Rayon_vertical,byte Couleur)
 | 
						||
{
 | 
						||
  short Debut_X;
 | 
						||
  short Debut_Y;
 | 
						||
  short Pos_X;
 | 
						||
  short Pos_Y;
 | 
						||
 | 
						||
  Debut_X=Centre_X-Rayon_horizontal;
 | 
						||
  Debut_Y=Centre_Y-Rayon_vertical;
 | 
						||
 | 
						||
  // Calcul des limites de l'ellipse
 | 
						||
  Ellipse_Calculer_limites(Rayon_horizontal+1,Rayon_vertical+1);
 | 
						||
 | 
						||
  // Affichage des extremit<69>es de l'ellipse sur chaque quart de l'ellipse:
 | 
						||
  for (Pos_Y=Debut_Y,Ellipse_Curseur_Y=-Rayon_vertical;Pos_Y<Centre_Y;Pos_Y++,Ellipse_Curseur_Y++)
 | 
						||
    for (Pos_X=Debut_X,Ellipse_Curseur_X=-Rayon_horizontal;Pos_X<Centre_X;Pos_X++,Ellipse_Curseur_X++)
 | 
						||
      if (Pixel_dans_ellipse())
 | 
						||
      {
 | 
						||
        // On vient de tomber sur le premier point qui sur la ligne
 | 
						||
        // horizontale fait partie de l'ellipse.
 | 
						||
 | 
						||
        // Donc on peut l'afficher (lui et ses copains sym<79>triques)
 | 
						||
 | 
						||
         // Quart Haut-gauche
 | 
						||
        Pixel_figure(Pos_X,Pos_Y,Couleur);
 | 
						||
         // Quart Haut-droite
 | 
						||
        Pixel_figure((Centre_X<<1)-Pos_X,Pos_Y,Couleur);
 | 
						||
         // Quart Bas-gauche
 | 
						||
        Pixel_figure(Pos_X,(Centre_Y<<1)-Pos_Y,Couleur);
 | 
						||
         // Quart Bas-droite
 | 
						||
        Pixel_figure((Centre_X<<1)-Pos_X,(Centre_Y<<1)-Pos_Y,Couleur);
 | 
						||
 | 
						||
        // On peut ensuite afficher tous les points qui le suivent dont le
 | 
						||
        // pixel voisin du haut n'appartient pas <20> l'ellipse:
 | 
						||
        for (Ellipse_Curseur_Y--,Pos_X++,Ellipse_Curseur_X++;Pos_X<Centre_X;Pos_X++,Ellipse_Curseur_X++)
 | 
						||
          if (!Pixel_dans_ellipse())
 | 
						||
          {
 | 
						||
             // Quart Haut-gauche
 | 
						||
            Pixel_figure(Pos_X,Pos_Y,Couleur);
 | 
						||
             // Quart Haut-droite
 | 
						||
            Pixel_figure((Centre_X<<1)-Pos_X,Pos_Y,Couleur);
 | 
						||
             // Quart Bas-gauche
 | 
						||
            Pixel_figure(Pos_X,(Centre_Y<<1)-Pos_Y,Couleur);
 | 
						||
             // Quart Bas-droite
 | 
						||
            Pixel_figure((Centre_X<<1)-Pos_X,(Centre_Y<<1)-Pos_Y,Couleur);
 | 
						||
          }
 | 
						||
          else
 | 
						||
            break;
 | 
						||
 | 
						||
        Ellipse_Curseur_Y++;
 | 
						||
        break;
 | 
						||
      }
 | 
						||
 | 
						||
  // On affiche <20> la fin les points cardinaux:
 | 
						||
 | 
						||
  // Points verticaux:
 | 
						||
  Pos_X=Centre_X;
 | 
						||
  Ellipse_Curseur_X=-1;
 | 
						||
  for (Pos_Y=Centre_Y+1-Rayon_vertical,Ellipse_Curseur_Y=-Rayon_vertical+1;Pos_Y<Centre_Y+Rayon_vertical;Pos_Y++,Ellipse_Curseur_Y++)
 | 
						||
    if (!Pixel_dans_ellipse())
 | 
						||
      Pixel_figure(Pos_X,Pos_Y,Couleur);
 | 
						||
 | 
						||
  // Points horizontaux:
 | 
						||
  Pos_Y=Centre_Y;
 | 
						||
  Ellipse_Curseur_Y=-1;
 | 
						||
  for (Pos_X=Centre_X+1-Rayon_horizontal,Ellipse_Curseur_X=-Rayon_horizontal+1;Pos_X<Centre_X+Rayon_horizontal;Pos_X++,Ellipse_Curseur_X++)
 | 
						||
    if (!Pixel_dans_ellipse())
 | 
						||
      Pixel_figure(Pos_X,Pos_Y,Couleur);
 | 
						||
 | 
						||
  Pixel_figure(Centre_X,Centre_Y-Rayon_vertical,Couleur);   // Haut
 | 
						||
  Pixel_figure(Centre_X-Rayon_horizontal,Centre_Y,Couleur); // Gauche
 | 
						||
  Pixel_figure(Centre_X+Rayon_horizontal,Centre_Y,Couleur); // Droite
 | 
						||
  Pixel_figure(Centre_X,Centre_Y+Rayon_vertical,Couleur);   // Bas
 | 
						||
}
 | 
						||
 | 
						||
  // -- Trac<61> d<>finitif d'une ellipse vide --
 | 
						||
 | 
						||
void Tracer_ellipse_vide_Definitif(short Centre_X,short Centre_Y,short Rayon_horizontal,short Rayon_vertical,byte Couleur)
 | 
						||
{
 | 
						||
  Pixel_figure=Pixel_figure_Definitif;
 | 
						||
  Tracer_ellipse_vide_General(Centre_X,Centre_Y,Rayon_horizontal,Rayon_vertical,Couleur);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Tracer la preview d'une ellipse vide --
 | 
						||
 | 
						||
void Tracer_ellipse_vide_Preview(short Centre_X,short Centre_Y,short Rayon_horizontal,short Rayon_vertical,byte Couleur)
 | 
						||
{
 | 
						||
  Pixel_figure=Pixel_figure_Preview;
 | 
						||
  Tracer_ellipse_vide_General(Centre_X,Centre_Y,Rayon_horizontal,Rayon_vertical,Couleur);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Effacer la preview d'une ellipse vide --
 | 
						||
 | 
						||
void Effacer_ellipse_vide_Preview(short Centre_X,short Centre_Y,short Rayon_horizontal,short Rayon_vertical)
 | 
						||
{
 | 
						||
  Pixel_figure=Pixel_figure_Effacer_preview;
 | 
						||
  Tracer_ellipse_vide_General(Centre_X,Centre_Y,Rayon_horizontal,Rayon_vertical,0);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Tracer une ellipse pleine --
 | 
						||
 | 
						||
void Tracer_ellipse_pleine(short Centre_X,short Centre_Y,short Rayon_horizontal,short Rayon_vertical,byte Couleur)
 | 
						||
{
 | 
						||
  short Debut_X;
 | 
						||
  short Debut_Y;
 | 
						||
  short Pos_X;
 | 
						||
  short Pos_Y;
 | 
						||
  short Fin_X;
 | 
						||
  short Fin_Y;
 | 
						||
 | 
						||
  Debut_X=Centre_X-Rayon_horizontal;
 | 
						||
  Debut_Y=Centre_Y-Rayon_vertical;
 | 
						||
  Fin_X=Centre_X+Rayon_horizontal;
 | 
						||
  Fin_Y=Centre_Y+Rayon_vertical;
 | 
						||
 | 
						||
  // Calcul des limites de l'ellipse
 | 
						||
  Ellipse_Calculer_limites(Rayon_horizontal+1,Rayon_vertical+1);
 | 
						||
 | 
						||
  // Correction des bornes d'apr<70>s les limites
 | 
						||
  if (Debut_Y<Limite_Haut)
 | 
						||
    Debut_Y=Limite_Haut;
 | 
						||
  if (Fin_Y>Limite_Bas)
 | 
						||
    Fin_Y=Limite_Bas;
 | 
						||
  if (Debut_X<Limite_Gauche)
 | 
						||
    Debut_X=Limite_Gauche;
 | 
						||
  if (Fin_X>Limite_Droite)
 | 
						||
    Fin_X=Limite_Droite;
 | 
						||
 | 
						||
  // Affichage de l'ellipse
 | 
						||
  for (Pos_Y=Debut_Y,Ellipse_Curseur_Y=Debut_Y-Centre_Y;Pos_Y<=Fin_Y;Pos_Y++,Ellipse_Curseur_Y++)
 | 
						||
    for (Pos_X=Debut_X,Ellipse_Curseur_X=Debut_X-Centre_X;Pos_X<=Fin_X;Pos_X++,Ellipse_Curseur_X++)
 | 
						||
      if (Pixel_dans_ellipse())
 | 
						||
        Afficher_pixel(Pos_X,Pos_Y,Couleur);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
  // -- Tracer g<>n<EFBFBD>ral d'une ligne ------------------------------------------
 | 
						||
 | 
						||
void Tracer_ligne_General(short Debut_X,short Debut_Y,short Fin_X,short Fin_Y, byte Couleur)
 | 
						||
{
 | 
						||
  short Pos_X,Pos_Y;
 | 
						||
  short Incr_X,Incr_Y;
 | 
						||
  short i,Cumul;
 | 
						||
  short Delta_X,Delta_Y;
 | 
						||
 | 
						||
 | 
						||
  Pos_X=Debut_X;
 | 
						||
  Pos_Y=Debut_Y;
 | 
						||
 | 
						||
  if (Debut_X<Fin_X)
 | 
						||
  {
 | 
						||
    Incr_X=+1;
 | 
						||
    Delta_X=Fin_X-Debut_X;
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    Incr_X=-1;
 | 
						||
    Delta_X=Debut_X-Fin_X;
 | 
						||
  }
 | 
						||
 | 
						||
  if (Debut_Y<Fin_Y)
 | 
						||
  {
 | 
						||
    Incr_Y=+1;
 | 
						||
    Delta_Y=Fin_Y-Debut_Y;
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    Incr_Y=-1;
 | 
						||
    Delta_Y=Debut_Y-Fin_Y;
 | 
						||
  }
 | 
						||
 | 
						||
  if (Delta_Y>Delta_X)
 | 
						||
  {
 | 
						||
    Cumul=Delta_Y>>1;
 | 
						||
    for (i=1; i<Delta_Y; i++)
 | 
						||
    {
 | 
						||
      Pos_Y+=Incr_Y;
 | 
						||
      Cumul+=Delta_X;
 | 
						||
      if (Cumul>=Delta_Y)
 | 
						||
      {
 | 
						||
        Cumul-=Delta_Y;
 | 
						||
        Pos_X+=Incr_X;
 | 
						||
      }
 | 
						||
      Pixel_figure(Pos_X,Pos_Y,Couleur);
 | 
						||
    }
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    Cumul=Delta_X>>1;
 | 
						||
    for (i=1; i<Delta_X; i++)
 | 
						||
    {
 | 
						||
      Pos_X+=Incr_X;
 | 
						||
      Cumul+=Delta_Y;
 | 
						||
      if (Cumul>=Delta_X)
 | 
						||
      {
 | 
						||
        Cumul-=Delta_X;
 | 
						||
        Pos_Y+=Incr_Y;
 | 
						||
      }
 | 
						||
      Pixel_figure(Pos_X,Pos_Y,Couleur);
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  if ( (Debut_X!=Fin_X) || (Debut_Y!=Fin_Y) )
 | 
						||
    Pixel_figure(Fin_X,Fin_Y,Couleur);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Tracer d<>finitif d'une ligne --
 | 
						||
 | 
						||
void Tracer_ligne_Definitif(short Debut_X,short Debut_Y,short Fin_X,short Fin_Y, byte Couleur)
 | 
						||
{
 | 
						||
  Pixel_figure=Pixel_figure_Definitif;
 | 
						||
  Tracer_ligne_General(Debut_X,Debut_Y,Fin_X,Fin_Y,Couleur);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Tracer la preview d'une ligne --
 | 
						||
 | 
						||
void Tracer_ligne_Preview(short Debut_X,short Debut_Y,short Fin_X,short Fin_Y,byte Couleur)
 | 
						||
{
 | 
						||
  Pixel_figure=Pixel_figure_Preview;
 | 
						||
  Tracer_ligne_General(Debut_X,Debut_Y,Fin_X,Fin_Y,Couleur);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Tracer la preview d'une ligne en xor --
 | 
						||
 | 
						||
void Tracer_ligne_Preview_xor(short Debut_X,short Debut_Y,short Fin_X,short Fin_Y,byte Couleur)
 | 
						||
{
 | 
						||
  Pixel_figure=Pixel_figure_Preview_xor;
 | 
						||
  Tracer_ligne_General(Debut_X,Debut_Y,Fin_X,Fin_Y,Couleur);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Effacer la preview d'une ligne --
 | 
						||
 | 
						||
void Effacer_ligne_Preview(short Debut_X,short Debut_Y,short Fin_X,short Fin_Y)
 | 
						||
{
 | 
						||
  Pixel_figure=Pixel_figure_Effacer_preview;
 | 
						||
  Tracer_ligne_General(Debut_X,Debut_Y,Fin_X,Fin_Y,0);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
  // -- Tracer un rectangle vide --
 | 
						||
 | 
						||
void Tracer_rectangle_vide(short Debut_X,short Debut_Y,short Fin_X,short Fin_Y,byte Couleur)
 | 
						||
{
 | 
						||
  short Tempo;
 | 
						||
  short Pos_X;
 | 
						||
  short Pos_Y;
 | 
						||
 | 
						||
 | 
						||
  // On v<>rifie que les bornes soient dans le bon sens:
 | 
						||
  if (Debut_X>Fin_X)
 | 
						||
  {
 | 
						||
    Tempo=Debut_X;
 | 
						||
    Debut_X=Fin_X;
 | 
						||
    Fin_X=Tempo;
 | 
						||
  }
 | 
						||
  if (Debut_Y>Fin_Y)
 | 
						||
  {
 | 
						||
    Tempo=Debut_Y;
 | 
						||
    Debut_Y=Fin_Y;
 | 
						||
    Fin_Y=Tempo;
 | 
						||
  }
 | 
						||
 | 
						||
  // On trace le rectangle:
 | 
						||
 | 
						||
  for (Pos_X=Debut_X;Pos_X<=Fin_X;Pos_X++)
 | 
						||
    Afficher_pinceau(Pos_X,Debut_Y,Couleur,0);
 | 
						||
 | 
						||
  for (Pos_Y=Debut_Y+1;Pos_Y<Fin_Y;Pos_Y++)
 | 
						||
  {
 | 
						||
    Afficher_pinceau(Debut_X,Pos_Y,Couleur,0);
 | 
						||
    Afficher_pinceau(  Fin_X,Pos_Y,Couleur,0);
 | 
						||
  }
 | 
						||
 | 
						||
  for (Pos_X=Debut_X;Pos_X<=Fin_X;Pos_X++)
 | 
						||
    Afficher_pinceau(Pos_X,  Fin_Y,Couleur,0);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Tracer un rectangle plein --
 | 
						||
 | 
						||
void Tracer_rectangle_plein(short Debut_X,short Debut_Y,short Fin_X,short Fin_Y,byte Couleur)
 | 
						||
{
 | 
						||
  short Tempo;
 | 
						||
  short Pos_X;
 | 
						||
  short Pos_Y;
 | 
						||
 | 
						||
 | 
						||
  // On v<>rifie que les bornes sont dans le bon sens:
 | 
						||
  if (Debut_X>Fin_X)
 | 
						||
  {
 | 
						||
    Tempo=Debut_X;
 | 
						||
    Debut_X=Fin_X;
 | 
						||
    Fin_X=Tempo;
 | 
						||
  }
 | 
						||
  if (Debut_Y>Fin_Y)
 | 
						||
  {
 | 
						||
    Tempo=Debut_Y;
 | 
						||
    Debut_Y=Fin_Y;
 | 
						||
    Fin_Y=Tempo;
 | 
						||
  }
 | 
						||
 | 
						||
  // Correction en cas de d<>passement des limites de l'image
 | 
						||
  if (Fin_X>Limite_Droite)
 | 
						||
    Fin_X=Limite_Droite;
 | 
						||
  if (Fin_Y>Limite_Bas)
 | 
						||
    Fin_Y=Limite_Bas;
 | 
						||
 | 
						||
  // On trace le rectangle:
 | 
						||
  for (Pos_Y=Debut_Y;Pos_Y<=Fin_Y;Pos_Y++)
 | 
						||
    for (Pos_X=Debut_X;Pos_X<=Fin_X;Pos_X++)
 | 
						||
      // Afficher_pixel traite chaque pixel avec tous les effets ! (smear, ...)
 | 
						||
      // Donc on ne peut pas otimiser en tra<72>ant ligne par ligne avec memset :(
 | 
						||
      Afficher_pixel(Pos_X,Pos_Y,Couleur);
 | 
						||
  SDL_UpdateRect(Ecran_SDL,
 | 
						||
        Debut_X-Principal_Decalage_X,
 | 
						||
        Debut_Y-Principal_Decalage_Y,
 | 
						||
        Fin_X-Debut_X,
 | 
						||
        Fin_Y-Debut_Y);
 | 
						||
  if(Loupe_Mode) UpdateZoom(Debut_X,Debut_Y,Fin_X-Debut_X,Fin_Y-Debut_Y);
 | 
						||
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  // -- Tracer une courbe de B<>zier --
 | 
						||
 | 
						||
void Tracer_courbe_General(short X1, short Y1,
 | 
						||
                           short X2, short Y2,
 | 
						||
                           short X3, short Y3,
 | 
						||
                           short X4, short Y4,
 | 
						||
                           byte Couleur)
 | 
						||
{
 | 
						||
  float Delta,T,T2,T3;
 | 
						||
  short X,Y,Old_X,Old_Y;
 | 
						||
  word  i;
 | 
						||
  int   CX[4];
 | 
						||
  int   CY[4];
 | 
						||
 | 
						||
  // Calcul des vecteurs de coefficients
 | 
						||
  CX[0]= -   X1 + 3*X2 - 3*X3 + X4;
 | 
						||
  CX[1]= + 3*X1 - 6*X2 + 3*X3;
 | 
						||
  CX[2]= - 3*X1 + 3*X2;
 | 
						||
  CX[3]= +   X1;
 | 
						||
  CY[0]= -   Y1 + 3*Y2 - 3*Y3 + Y4;
 | 
						||
  CY[1]= + 3*Y1 - 6*Y2 + 3*Y3;
 | 
						||
  CY[2]= - 3*Y1 + 3*Y2;
 | 
						||
  CY[3]= +   Y1;
 | 
						||
 | 
						||
  // Tra<72>age de la courbe
 | 
						||
  Old_X=X1;
 | 
						||
  Old_Y=Y1;
 | 
						||
  Pixel_figure(Old_X,Old_Y,Couleur);
 | 
						||
  Delta=0.05; // 1.0/20
 | 
						||
  T=0;
 | 
						||
  for (i=1; i<=20; i++)
 | 
						||
  {
 | 
						||
    T=T+Delta; T2=T*T; T3=T2*T;
 | 
						||
    X=Round(T3*CX[0] + T2*CX[1] + T*CX[2] + CX[3]);
 | 
						||
    Y=Round(T3*CY[0] + T2*CY[1] + T*CY[2] + CY[3]);
 | 
						||
    Tracer_ligne_General(Old_X,Old_Y,X,Y,Couleur);
 | 
						||
    Old_X=X;
 | 
						||
    Old_Y=Y;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
  // -- Tracer une courbe de B<>zier d<>finitivement --
 | 
						||
 | 
						||
void Tracer_courbe_Definitif(short X1, short Y1,
 | 
						||
                             short X2, short Y2,
 | 
						||
                             short X3, short Y3,
 | 
						||
                             short X4, short Y4,
 | 
						||
                             byte Couleur)
 | 
						||
{
 | 
						||
  Pixel_figure=Pixel_figure_Definitif;
 | 
						||
  Tracer_courbe_General(X1,Y1,X2,Y2,X3,Y3,X4,Y4,Couleur);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Tracer la preview d'une courbe de B<>zier --
 | 
						||
 | 
						||
void Tracer_courbe_Preview(short X1, short Y1,
 | 
						||
                           short X2, short Y2,
 | 
						||
                           short X3, short Y3,
 | 
						||
                           short X4, short Y4,
 | 
						||
                           byte Couleur)
 | 
						||
{
 | 
						||
  Pixel_figure=Pixel_figure_Preview;
 | 
						||
  Tracer_courbe_General(X1,Y1,X2,Y2,X3,Y3,X4,Y4,Couleur);
 | 
						||
}
 | 
						||
 | 
						||
  // -- Effacer la preview d'une courbe de B<>zier --
 | 
						||
 | 
						||
void Effacer_courbe_Preview(short X1, short Y1,
 | 
						||
                            short X2, short Y2,
 | 
						||
                            short X3, short Y3,
 | 
						||
                            short X4, short Y4,
 | 
						||
                            byte Couleur)
 | 
						||
{
 | 
						||
  Pixel_figure=Pixel_figure_Effacer_preview;
 | 
						||
  Tracer_courbe_General(X1,Y1,X2,Y2,X3,Y3,X4,Y4,Couleur);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  // -- Spray : un petit coup de Pschiitt! --
 | 
						||
 | 
						||
void Aerographe(short Bouton_clicke)
 | 
						||
{
 | 
						||
  short Pos_X,Pos_Y;
 | 
						||
  short Rayon=Spray_Size>>1;
 | 
						||
  long  Rayon_au_carre=(long)Rayon*Rayon;
 | 
						||
  short Indice,Count;
 | 
						||
  byte  Indice_couleur;
 | 
						||
  byte  Sens;
 | 
						||
 | 
						||
 | 
						||
  Effacer_curseur();
 | 
						||
 | 
						||
  if (Spray_Mode)
 | 
						||
  {
 | 
						||
    for (Count=1; Count<=Spray_Mono_flow; Count++)
 | 
						||
    {
 | 
						||
      Pos_X=(rand()%Spray_Size)-Rayon;
 | 
						||
      Pos_Y=(rand()%Spray_Size)-Rayon;
 | 
						||
      if ( (Pos_X*Pos_X)+(Pos_Y*Pos_Y) <= Rayon_au_carre )
 | 
						||
      {
 | 
						||
        Pos_X+=Pinceau_X;
 | 
						||
        Pos_Y+=Pinceau_Y;
 | 
						||
        if (Bouton_clicke==1)
 | 
						||
          Afficher_pinceau(Pos_X,Pos_Y,Fore_color,0);
 | 
						||
        else
 | 
						||
          Afficher_pinceau(Pos_X,Pos_Y,Back_color,0);
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    //   On essaye de se balader dans la table des flux de fa<66>on <20> ce que ce
 | 
						||
    // ne soit pas toujours la derni<6E>re couleur qui soit affich<63>e en dernier
 | 
						||
    // Pour <20>a, on part d'une couleur au pif dans une direction al<61>atoire.
 | 
						||
    Sens=rand()&1;
 | 
						||
    for (Indice=0,Indice_couleur=rand()/*%256*/; Indice<256; Indice++)
 | 
						||
    {
 | 
						||
      for (Count=1; Count<=Spray_Multi_flow[Indice_couleur]; Count++)
 | 
						||
      {
 | 
						||
        Pos_X=(rand()%Spray_Size)-Rayon;
 | 
						||
        Pos_Y=(rand()%Spray_Size)-Rayon;
 | 
						||
        if ( (Pos_X*Pos_X)+(Pos_Y*Pos_Y) <= Rayon_au_carre )
 | 
						||
        {
 | 
						||
          Pos_X+=Pinceau_X;
 | 
						||
          Pos_Y+=Pinceau_Y;
 | 
						||
          if (Bouton_clicke==A_GAUCHE)
 | 
						||
            Afficher_pinceau(Pos_X,Pos_Y,Indice_couleur,0);
 | 
						||
          else
 | 
						||
            Afficher_pinceau(Pos_X,Pos_Y,Back_color,0);
 | 
						||
        }
 | 
						||
      }
 | 
						||
      if (Sens)
 | 
						||
        Indice_couleur++;
 | 
						||
      else
 | 
						||
        Indice_couleur--;
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  Afficher_curseur();
 | 
						||
 | 
						||
  for (Count=1; Count<=Spray_Delay; Count++)
 | 
						||
    Wait_VBL();
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  //////////////////////////////////////////////////////////////////////////
 | 
						||
  ////////////////////////// GESTION DES DEGRADES //////////////////////////
 | 
						||
  //////////////////////////////////////////////////////////////////////////
 | 
						||
 | 
						||
 | 
						||
  // -- Gestion d'un d<>grad<61> de base (le plus moche) --
 | 
						||
 | 
						||
void Degrade_de_base(long Indice,short Pos_X,short Pos_Y)
 | 
						||
{
 | 
						||
  long Position;
 | 
						||
 | 
						||
  // On fait un premier calcul partiel
 | 
						||
  Position=(Indice*Degrade_Intervalle_bornes);
 | 
						||
 | 
						||
  // On g<>re un d<>placement au hasard
 | 
						||
  Position+=(Degrade_Intervalle_total*(rand()%Degrade_Melange_aleatoire)) >>6;
 | 
						||
  Position-=(Degrade_Intervalle_total*Degrade_Melange_aleatoire) >>7;
 | 
						||
 | 
						||
  Position/=Degrade_Intervalle_total;
 | 
						||
 | 
						||
  //   On va v<>rifier que nos petites idioties n'ont pas <20>ject<63> la valeur hors
 | 
						||
  // des valeurs autoris<69>es par le d<>grad<61> d<>fini par l'utilisateur.
 | 
						||
 | 
						||
  if (Position<0)
 | 
						||
    Position=0;
 | 
						||
  else if (Position>=Degrade_Intervalle_bornes)
 | 
						||
    Position=Degrade_Intervalle_bornes-1;
 | 
						||
 | 
						||
  // On ram<61>ne ensuite la position dans le d<>grad<61> vers un num<75>ro de couleur
 | 
						||
  if (Degrade_Inverse)
 | 
						||
    Traiter_pixel_de_degrade(Pos_X,Pos_Y,Degrade_Borne_Superieure-Position);
 | 
						||
  else
 | 
						||
    Traiter_pixel_de_degrade(Pos_X,Pos_Y,Degrade_Borne_Inferieure+Position);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
  // -- Gestion d'un d<>grad<61> par trames simples --
 | 
						||
 | 
						||
void Degrade_de_trames_simples(long Indice,short Pos_X,short Pos_Y)
 | 
						||
{
 | 
						||
  long Position_dans_degrade;
 | 
						||
  long Position_dans_segment;
 | 
						||
 | 
						||
  //
 | 
						||
  //   But de l'op<6F>ration: en plus de calculer la position de base (d<>sign<67>e
 | 
						||
  // dans cette proc<6F>dure par "Position_dans_degrade", on calcule la position
 | 
						||
  // de l'indice dans le sch<63>ma suivant:
 | 
						||
  //
 | 
						||
  //         <20> Les indices qui tra<72>nent de ce c<>t<EFBFBD> du segment se voient subir
 | 
						||
  //         <20> une incr<63>mentation conditionnelle <20> leur position dans l'<27>cran.
 | 
						||
  //         v
 | 
						||
  //  <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20>
 | 
						||
  //   ^
 | 
						||
  //   <20><> Les indices qui tra<72>nent de ce c<>t<EFBFBD> du segment se voient subir une
 | 
						||
  //      d<>cr<63>mentation conditionnelle <20> leur position dans l'<27>cran.
 | 
						||
 | 
						||
  // On fait d'abord un premier calcul partiel
 | 
						||
  Position_dans_degrade=(Indice*Degrade_Intervalle_bornes);
 | 
						||
 | 
						||
  // On g<>re un d<>placement au hasard...
 | 
						||
  Position_dans_degrade+=(Degrade_Intervalle_total*(rand()%Degrade_Melange_aleatoire)) >>6;
 | 
						||
  Position_dans_degrade-=(Degrade_Intervalle_total*Degrade_Melange_aleatoire) >>7;
 | 
						||
 | 
						||
  if (Position_dans_degrade<0)
 | 
						||
    Position_dans_degrade=0;
 | 
						||
 | 
						||
  // ... qui nous permet de calculer la position dans le segment
 | 
						||
  Position_dans_segment=((Position_dans_degrade<<2)/Degrade_Intervalle_total)&3;
 | 
						||
 | 
						||
  // On peut ensuite terminer le calcul de l'indice dans le d<>grad<61>
 | 
						||
  Position_dans_degrade/=Degrade_Intervalle_total;
 | 
						||
 | 
						||
  // On va pouvoir discuter de la valeur de Position_dans_degrade en fonction
 | 
						||
  // de la position dans l'<27>cran et de la Position_dans_segment.
 | 
						||
 | 
						||
  switch (Position_dans_segment)
 | 
						||
  {
 | 
						||
    case 0 : // On est sur la gauche du segment
 | 
						||
      if (((Pos_X+Pos_Y)&1)==0)
 | 
						||
        Position_dans_degrade--;
 | 
						||
      break;
 | 
						||
 | 
						||
      // On n'a pas <20> traiter les cas 1 et 2 car ils repr<70>sentent des valeurs
 | 
						||
      // suffisament au centre du segment pour ne pas avoir <20> subir la trame
 | 
						||
 | 
						||
    case 3 : // On est sur la droite du segment
 | 
						||
      if (((Pos_X+Pos_Y)&1)!=0) // Note: on doit faire le test inverse au cas gauche pour synchroniser les 2 c<>t<EFBFBD>s de la trame.
 | 
						||
        Position_dans_degrade++;
 | 
						||
  }
 | 
						||
 | 
						||
  //   On va v<>rifier que nos petites idioties n'ont pas <20>ject<63> la valeur hors
 | 
						||
  // des valeurs autoris<69>es par le d<>grad<61> d<>fini par l'utilisateur.
 | 
						||
 | 
						||
  if (Position_dans_degrade<0)
 | 
						||
    Position_dans_degrade=0;
 | 
						||
  else if (Position_dans_degrade>=Degrade_Intervalle_bornes)
 | 
						||
    Position_dans_degrade=Degrade_Intervalle_bornes-1;
 | 
						||
 | 
						||
  // On ram<61>ne ensuite la position dans le d<>grad<61> vers un num<75>ro de couleur
 | 
						||
  if (Degrade_Inverse)
 | 
						||
    Position_dans_degrade=Degrade_Borne_Superieure-Position_dans_degrade;
 | 
						||
  else
 | 
						||
    Position_dans_degrade=Degrade_Borne_Inferieure+Position_dans_degrade;
 | 
						||
 | 
						||
  Traiter_pixel_de_degrade(Pos_X,Pos_Y,Position_dans_degrade);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
  // -- Gestion d'un d<>grad<61> par trames <20>tendues --
 | 
						||
 | 
						||
void Degrade_de_trames_etendues(long Indice,short Pos_X,short Pos_Y)
 | 
						||
{
 | 
						||
  long Position_dans_degrade;
 | 
						||
  long Position_dans_segment;
 | 
						||
 | 
						||
  //
 | 
						||
  //   But de l'op<6F>ration: en plus de calculer la position de base (d<>sign<67>e
 | 
						||
  // dans cette proc<6F>dure par "Position_dans_degrade", on calcule la position
 | 
						||
  // de l'indice dans le sch<63>ma suivant:
 | 
						||
  //
 | 
						||
  //         <20> Les indices qui tra<72>nent de ce c<>t<EFBFBD> du segment se voient subir
 | 
						||
  //         <20> une incr<63>mentation conditionnelle <20> leur position dans l'<27>cran.
 | 
						||
  //         v
 | 
						||
  //  <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20>
 | 
						||
  //   ^
 | 
						||
  //   <20><> Les indices qui tra<72>nent de ce c<>t<EFBFBD> du segment se voient subir une
 | 
						||
  //      d<>cr<63>mentation conditionnelle <20> leur position dans l'<27>cran.
 | 
						||
 | 
						||
  // On fait d'abord un premier calcul partiel
 | 
						||
  Position_dans_degrade=(Indice*Degrade_Intervalle_bornes);
 | 
						||
 | 
						||
  // On g<>re un d<>placement au hasard
 | 
						||
  Position_dans_degrade+=(Degrade_Intervalle_total*(rand()%Degrade_Melange_aleatoire)) >>6;
 | 
						||
  Position_dans_degrade-=(Degrade_Intervalle_total*Degrade_Melange_aleatoire) >>7;
 | 
						||
 | 
						||
  if (Position_dans_degrade<0)
 | 
						||
    Position_dans_degrade=0;
 | 
						||
 | 
						||
  // Qui nous permet de calculer la position dans le segment
 | 
						||
  Position_dans_segment=((Position_dans_degrade<<3)/Degrade_Intervalle_total)&7;
 | 
						||
 | 
						||
  // On peut ensuite terminer le calcul de l'indice dans le d<>grad<61>
 | 
						||
  Position_dans_degrade/=Degrade_Intervalle_total;
 | 
						||
 | 
						||
  // On va pouvoir discuter de la valeur de Position_dans_degrade en fonction
 | 
						||
  // de la position dans l'<27>cran et de la Position_dans_segment.
 | 
						||
 | 
						||
  switch (Position_dans_segment)
 | 
						||
  {
 | 
						||
    case 0 : // On est sur l'extr<74>me gauche du segment
 | 
						||
      if (((Pos_X+Pos_Y)&1)==0)
 | 
						||
        Position_dans_degrade--;
 | 
						||
      break;
 | 
						||
 | 
						||
    case 1 : // On est sur la gauche du segment
 | 
						||
    case 2 : // On est sur la gauche du segment
 | 
						||
      if (((Pos_X & 1)==0) && ((Pos_Y & 1)==0))
 | 
						||
        Position_dans_degrade--;
 | 
						||
      break;
 | 
						||
 | 
						||
      // On n'a pas <20> traiter les cas 3 et 4 car ils repr<70>sentent des valeurs
 | 
						||
      // suffisament au centre du segment pour ne pas avoir <20> subir la trame
 | 
						||
 | 
						||
    case 5 : // On est sur la droite du segment
 | 
						||
    case 6 : // On est sur la droite du segment
 | 
						||
      if (((Pos_X & 1)==0) && ((Pos_Y & 1)!=0))
 | 
						||
        Position_dans_degrade++;
 | 
						||
      break;
 | 
						||
 | 
						||
    case 7 : // On est sur l'extreme droite du segment
 | 
						||
      if (((Pos_X+Pos_Y)&1)!=0) // Note: on doit faire le test inverse au cas gauche pour synchroniser les 2 c<>t<EFBFBD>s de la trame.
 | 
						||
        Position_dans_degrade++;
 | 
						||
  }
 | 
						||
 | 
						||
  //   On va v<>rifier que nos petites idioties n'ont pas <20>ject<63> la valeur hors
 | 
						||
  // des valeurs autoris<69>es par le d<>grad<61> d<>fini par l'utilisateur.
 | 
						||
 | 
						||
  if (Position_dans_degrade<0)
 | 
						||
    Position_dans_degrade=0;
 | 
						||
  else if (Position_dans_degrade>=Degrade_Intervalle_bornes)
 | 
						||
    Position_dans_degrade=Degrade_Intervalle_bornes-1;
 | 
						||
 | 
						||
  // On ram<61>ne ensuite la position dans le d<>grad<61> vers un num<75>ro de couleur
 | 
						||
  if (Degrade_Inverse)
 | 
						||
    Position_dans_degrade=Degrade_Borne_Superieure-Position_dans_degrade;
 | 
						||
  else
 | 
						||
    Position_dans_degrade=Degrade_Borne_Inferieure+Position_dans_degrade;
 | 
						||
 | 
						||
  Traiter_pixel_de_degrade(Pos_X,Pos_Y,Position_dans_degrade);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  // -- Tracer un cercle degrad<61> (une sph<70>re) --
 | 
						||
 | 
						||
void Tracer_cercle_degrade(short Centre_X,short Centre_Y,short Rayon,short Eclairage_X,short Eclairage_Y)
 | 
						||
{
 | 
						||
  long Debut_X;
 | 
						||
  long Debut_Y;
 | 
						||
  long Pos_X;
 | 
						||
  long Pos_Y;
 | 
						||
  long Fin_X;
 | 
						||
  long Fin_Y;
 | 
						||
  long Distance_X; // Distance (au carr<72>) sur les X du point en cours au centre d'<27>clairage
 | 
						||
  long Distance_Y; // Distance (au carr<72>) sur les Y du point en cours au centre d'<27>clairage
 | 
						||
 | 
						||
  Debut_X=Centre_X-Rayon;
 | 
						||
  Debut_Y=Centre_Y-Rayon;
 | 
						||
  Fin_X=Centre_X+Rayon;
 | 
						||
  Fin_Y=Centre_Y+Rayon;
 | 
						||
 | 
						||
  // Correction des bornes d'apr<70>s les limites
 | 
						||
  if (Debut_Y<Limite_Haut)
 | 
						||
    Debut_Y=Limite_Haut;
 | 
						||
  if (Fin_Y>Limite_Bas)
 | 
						||
    Fin_Y=Limite_Bas;
 | 
						||
  if (Debut_X<Limite_Gauche)
 | 
						||
    Debut_X=Limite_Gauche;
 | 
						||
  if (Fin_X>Limite_Droite)
 | 
						||
    Fin_X=Limite_Droite;
 | 
						||
 | 
						||
  Degrade_Intervalle_total=Cercle_Limite+
 | 
						||
                           ((Centre_X-Eclairage_X)*(Centre_X-Eclairage_X))+
 | 
						||
                           ((Centre_Y-Eclairage_Y)*(Centre_Y-Eclairage_Y))+
 | 
						||
                           (2L*Rayon*sqrt(
 | 
						||
                           ((Centre_X-Eclairage_X)*(Centre_X-Eclairage_X))+
 | 
						||
                           ((Centre_Y-Eclairage_Y)*(Centre_Y-Eclairage_Y))));
 | 
						||
 | 
						||
  if (Degrade_Intervalle_total==0)
 | 
						||
    Degrade_Intervalle_total=1;
 | 
						||
 | 
						||
  // Affichage du cercle
 | 
						||
  for (Pos_Y=Debut_Y,Cercle_Curseur_Y=(long)Debut_Y-Centre_Y;Pos_Y<=Fin_Y;Pos_Y++,Cercle_Curseur_Y++)
 | 
						||
  {
 | 
						||
    Distance_Y =(Pos_Y-Eclairage_Y);
 | 
						||
    Distance_Y*=Distance_Y;
 | 
						||
    for (Pos_X=Debut_X,Cercle_Curseur_X=(long)Debut_X-Centre_X;Pos_X<=Fin_X;Pos_X++,Cercle_Curseur_X++)
 | 
						||
      if (Pixel_dans_cercle())
 | 
						||
      {
 | 
						||
        Distance_X =(Pos_X-Eclairage_X);
 | 
						||
        Distance_X*=Distance_X;
 | 
						||
        Traiter_degrade(Distance_X+Distance_Y,Pos_X,Pos_Y);
 | 
						||
      }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
  // -- Tracer une ellipse degrad<61>e --
 | 
						||
 | 
						||
void Tracer_ellipse_degradee(short Centre_X,short Centre_Y,short Rayon_horizontal,short Rayon_vertical,short Eclairage_X,short Eclairage_Y)
 | 
						||
{
 | 
						||
  long Debut_X;
 | 
						||
  long Debut_Y;
 | 
						||
  long Pos_X;
 | 
						||
  long Pos_Y;
 | 
						||
  long Fin_X;
 | 
						||
  long Fin_Y;
 | 
						||
  long Distance_X; // Distance (au carr<72>) sur les X du point en cours au centre d'<27>clairage
 | 
						||
  long Distance_Y; // Distance (au carr<72>) sur les Y du point en cours au centre d'<27>clairage
 | 
						||
 | 
						||
 | 
						||
  Debut_X=Centre_X-Rayon_horizontal;
 | 
						||
  Debut_Y=Centre_Y-Rayon_vertical;
 | 
						||
  Fin_X=Centre_X+Rayon_horizontal;
 | 
						||
  Fin_Y=Centre_Y+Rayon_vertical;
 | 
						||
 | 
						||
  // Calcul des limites de l'ellipse
 | 
						||
  Ellipse_Calculer_limites(Rayon_horizontal+1,Rayon_vertical+1);
 | 
						||
 | 
						||
  // On calcule la distance maximale:
 | 
						||
  Degrade_Intervalle_total=(Rayon_horizontal*Rayon_horizontal)+
 | 
						||
                           (Rayon_vertical*Rayon_vertical)+
 | 
						||
                           ((Centre_X-Eclairage_X)*(Centre_X-Eclairage_X))+
 | 
						||
                           ((Centre_Y-Eclairage_Y)*(Centre_Y-Eclairage_Y))+
 | 
						||
                           (2L
 | 
						||
                           *sqrt(
 | 
						||
                           (Rayon_horizontal*Rayon_horizontal)+
 | 
						||
                           (Rayon_vertical  *Rayon_vertical  ))
 | 
						||
                           *sqrt(
 | 
						||
                           ((Centre_X-Eclairage_X)*(Centre_X-Eclairage_X))+
 | 
						||
                           ((Centre_Y-Eclairage_Y)*(Centre_Y-Eclairage_Y))));
 | 
						||
 | 
						||
  if (Degrade_Intervalle_total==0)
 | 
						||
    Degrade_Intervalle_total=1;
 | 
						||
 | 
						||
  // Correction des bornes d'apr<70>s les limites
 | 
						||
  if (Debut_Y<Limite_Haut)
 | 
						||
    Debut_Y=Limite_Haut;
 | 
						||
  if (Fin_Y>Limite_Bas)
 | 
						||
    Fin_Y=Limite_Bas;
 | 
						||
  if (Debut_X<Limite_Gauche)
 | 
						||
    Debut_X=Limite_Gauche;
 | 
						||
  if (Fin_X>Limite_Droite)
 | 
						||
    Fin_X=Limite_Droite;
 | 
						||
 | 
						||
  // Affichage de l'ellipse
 | 
						||
  for (Pos_Y=Debut_Y,Ellipse_Curseur_Y=Debut_Y-Centre_Y;Pos_Y<=Fin_Y;Pos_Y++,Ellipse_Curseur_Y++)
 | 
						||
  {
 | 
						||
    Distance_Y =(Pos_Y-Eclairage_Y);
 | 
						||
    Distance_Y*=Distance_Y;
 | 
						||
    for (Pos_X=Debut_X,Ellipse_Curseur_X=Debut_X-Centre_X;Pos_X<=Fin_X;Pos_X++,Ellipse_Curseur_X++)
 | 
						||
      if (Pixel_dans_ellipse())
 | 
						||
      {
 | 
						||
        Distance_X =(Pos_X-Eclairage_X);
 | 
						||
        Distance_X*=Distance_X;
 | 
						||
        Traiter_degrade(Distance_X+Distance_Y,Pos_X,Pos_Y);
 | 
						||
      }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  // -- Tracer un polyg<79>ne plein --
 | 
						||
 | 
						||
typedef struct POLYGON_EDGE      /* an active edge */
 | 
						||
{
 | 
						||
  short top;                     /* top y position */
 | 
						||
  short bottom;                  /* bottom y position */
 | 
						||
  float x, dx;                   /* floating point x position and gradient */
 | 
						||
  float w;                       /* width of line segment */
 | 
						||
  struct POLYGON_EDGE *prev;     /* doubly linked list */
 | 
						||
  struct POLYGON_EDGE *next;
 | 
						||
} POLYGON_EDGE;
 | 
						||
 | 
						||
 | 
						||
 | 
						||
/* fill_edge_structure:
 | 
						||
 *  Polygon helper function: initialises an edge structure for the 2d
 | 
						||
 *  rasteriser.
 | 
						||
 */
 | 
						||
void fill_edge_structure(POLYGON_EDGE *edge, short *i1, short *i2)
 | 
						||
{
 | 
						||
  short *it;
 | 
						||
 | 
						||
  if (i2[1] < i1[1])
 | 
						||
  {
 | 
						||
    it = i1;
 | 
						||
    i1 = i2;
 | 
						||
    i2 = it;
 | 
						||
  }
 | 
						||
 | 
						||
  edge->top = i1[1];
 | 
						||
  edge->bottom = i2[1] - 1;
 | 
						||
  edge->dx = ((float) i2[0] - (float) i1[0]) / ((float) i2[1] - (float) i1[1]);
 | 
						||
  edge->x = i1[0] + 0.4999999;
 | 
						||
  edge->prev = NULL;
 | 
						||
  edge->next = NULL;
 | 
						||
 | 
						||
  if (edge->dx+1 < 0.0)
 | 
						||
    edge->x += edge->dx+1;
 | 
						||
 | 
						||
  if (edge->dx >= 0.0)
 | 
						||
    edge->w = edge->dx;
 | 
						||
  else
 | 
						||
    edge->w = -(edge->dx);
 | 
						||
 | 
						||
  if (edge->w-1.0<0.0)
 | 
						||
    edge->w = 0.0;
 | 
						||
  else
 | 
						||
    edge->w = edge->w-1;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
/* add_edge:
 | 
						||
 *  Adds an edge structure to a linked list, returning the new head pointer.
 | 
						||
 */
 | 
						||
POLYGON_EDGE * add_edge(POLYGON_EDGE *list, POLYGON_EDGE *edge, int sort_by_x)
 | 
						||
{
 | 
						||
  POLYGON_EDGE *pos = list;
 | 
						||
  POLYGON_EDGE *prev = NULL;
 | 
						||
 | 
						||
  if (sort_by_x)
 | 
						||
  {
 | 
						||
    while ( (pos) && ((pos->x+((pos->w+pos->dx)/2)) < (edge->x+((edge->w+edge->dx)/2))) )
 | 
						||
    {
 | 
						||
      prev = pos;
 | 
						||
      pos = pos->next;
 | 
						||
    }
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    while ((pos) && (pos->top < edge->top))
 | 
						||
    {
 | 
						||
      prev = pos;
 | 
						||
      pos = pos->next;
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  edge->next = pos;
 | 
						||
  edge->prev = prev;
 | 
						||
 | 
						||
  if (pos)
 | 
						||
    pos->prev = edge;
 | 
						||
 | 
						||
  if (prev)
 | 
						||
  {
 | 
						||
    prev->next = edge;
 | 
						||
    return list;
 | 
						||
  }
 | 
						||
  else
 | 
						||
    return edge;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
/* remove_edge:
 | 
						||
 *  Removes an edge structure from a list, returning the new head pointer.
 | 
						||
 */
 | 
						||
POLYGON_EDGE * remove_edge(POLYGON_EDGE *list, POLYGON_EDGE *edge)
 | 
						||
{
 | 
						||
  if (edge->next)
 | 
						||
    edge->next->prev = edge->prev;
 | 
						||
 | 
						||
  if (edge->prev)
 | 
						||
  {
 | 
						||
    edge->prev->next = edge->next;
 | 
						||
    return list;
 | 
						||
  }
 | 
						||
  else
 | 
						||
    return edge->next;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
/* polygon:
 | 
						||
 *  Draws a filled polygon with an arbitrary number of corners. Pass the
 | 
						||
 *  number of vertices, then an array containing a series of x, y points
 | 
						||
 *  (a total of vertices*2 values).
 | 
						||
 */
 | 
						||
void Polyfill_General(int Vertices, short * Points, int Color)
 | 
						||
{
 | 
						||
  short c;
 | 
						||
  short top = 0x7FFF;
 | 
						||
  short bottom = 0;
 | 
						||
  short *i1, *i2;
 | 
						||
  short Pos_X,Fin_X;
 | 
						||
  POLYGON_EDGE *edge, *next_edge, *initial_edge;
 | 
						||
  POLYGON_EDGE *active_edges = NULL;
 | 
						||
  POLYGON_EDGE *inactive_edges = NULL;
 | 
						||
 | 
						||
 | 
						||
  /* allocate some space and fill the edge table */
 | 
						||
  initial_edge=edge=(POLYGON_EDGE *) malloc(sizeof(POLYGON_EDGE) * Vertices);
 | 
						||
 | 
						||
  i1 = Points;
 | 
						||
  i2 = Points + ((Vertices-1)<<1);
 | 
						||
 | 
						||
  for (c=0; c<Vertices; c++)
 | 
						||
  {
 | 
						||
    if (i1[1] != i2[1])
 | 
						||
    {
 | 
						||
      fill_edge_structure(edge, i1, i2);
 | 
						||
 | 
						||
      if (edge->bottom >= edge->top)
 | 
						||
      {
 | 
						||
        if (edge->top < top)
 | 
						||
          top = edge->top;
 | 
						||
 | 
						||
        if (edge->bottom > bottom)
 | 
						||
          bottom = edge->bottom;
 | 
						||
 | 
						||
        inactive_edges = add_edge(inactive_edges, edge, 0);
 | 
						||
        edge++;
 | 
						||
      }
 | 
						||
    }
 | 
						||
    i2 = i1;
 | 
						||
    i1 += 2;
 | 
						||
  }
 | 
						||
 | 
						||
  /* for each scanline in the polygon... */
 | 
						||
  for (c=top; c<=bottom; c++)
 | 
						||
  {
 | 
						||
    /* check for newly active edges */
 | 
						||
    edge = inactive_edges;
 | 
						||
    while ((edge) && (edge->top == c))
 | 
						||
    {
 | 
						||
      next_edge = edge->next;
 | 
						||
      inactive_edges = remove_edge(inactive_edges, edge);
 | 
						||
      active_edges = add_edge(active_edges, edge, 1);
 | 
						||
      edge = next_edge;
 | 
						||
    }
 | 
						||
 | 
						||
    /* draw horizontal line segments */
 | 
						||
    if ((c>=Limite_Haut) && (c<=Limite_Bas))
 | 
						||
    {
 | 
						||
      edge = active_edges;
 | 
						||
      while ((edge) && (edge->next))
 | 
						||
      {
 | 
						||
        Pos_X=/*Round*/(edge->x);
 | 
						||
        Fin_X=/*Round*/(edge->next->x+edge->next->w);
 | 
						||
        if (Pos_X<Limite_Gauche)
 | 
						||
          Pos_X=Limite_Gauche;
 | 
						||
        if (Fin_X>Limite_Droite)
 | 
						||
          Fin_X=Limite_Droite;
 | 
						||
        for (; Pos_X<=Fin_X; Pos_X++)
 | 
						||
          Pixel_figure(Pos_X,c,Color);
 | 
						||
        edge = edge->next->next;
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    /* update edges, sorting and removing dead ones */
 | 
						||
    edge = active_edges;
 | 
						||
    while (edge)
 | 
						||
    {
 | 
						||
      next_edge = edge->next;
 | 
						||
      if (c >= edge->bottom)
 | 
						||
        active_edges = remove_edge(active_edges, edge);
 | 
						||
      else
 | 
						||
      {
 | 
						||
        edge->x += edge->dx;
 | 
						||
        while ((edge->prev) && ( (edge->x+(edge->w/2)) < (edge->prev->x+(edge->prev->w/2))) )
 | 
						||
        {
 | 
						||
          if (edge->next)
 | 
						||
            edge->next->prev = edge->prev;
 | 
						||
          edge->prev->next = edge->next;
 | 
						||
          edge->next = edge->prev;
 | 
						||
          edge->prev = edge->prev->prev;
 | 
						||
          edge->next->prev = edge;
 | 
						||
          if (edge->prev)
 | 
						||
            edge->prev->next = edge;
 | 
						||
          else
 | 
						||
            active_edges = edge;
 | 
						||
        }
 | 
						||
      }
 | 
						||
      edge = next_edge;
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  free(initial_edge);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void Polyfill(int Vertices, short * Points, int Color)
 | 
						||
{
 | 
						||
  Pixel_figure=Afficher_pixel;
 | 
						||
  Polyfill_General(Vertices,Points,Color);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
void Capturer_brosse_au_lasso(int Vertices, short * Points,short Effacement)
 | 
						||
{
 | 
						||
  short Debut_X=Limite_Droite+1;
 | 
						||
  short Debut_Y=Limite_Bas+1;
 | 
						||
  short Fin_X=Limite_Gauche-1;
 | 
						||
  short Fin_Y=Limite_Haut-1;
 | 
						||
  short Temporaire;
 | 
						||
  short Pos_X;
 | 
						||
  short Pos_Y;
 | 
						||
  word  Nouvelle_Brosse_Largeur;
 | 
						||
  word  Nouvelle_Brosse_Hauteur;
 | 
						||
 | 
						||
 | 
						||
  // On recherche les bornes de la brosse:
 | 
						||
  for (Temporaire=0; Temporaire<Vertices; Temporaire++)
 | 
						||
  {
 | 
						||
    Pos_X=Points[Temporaire<<1];
 | 
						||
    Pos_Y=Points[(Temporaire<<1)+1];
 | 
						||
    if (Pos_X<Debut_X)
 | 
						||
      Debut_X=Pos_X;
 | 
						||
    if (Pos_X>Fin_X)
 | 
						||
      Fin_X=Pos_X;
 | 
						||
    if (Pos_Y<Debut_Y)
 | 
						||
      Debut_Y=Pos_Y;
 | 
						||
    if (Pos_Y>Fin_Y)
 | 
						||
      Fin_Y=Pos_Y;
 | 
						||
  }
 | 
						||
 | 
						||
  // On clippe ces bornes <20> l'<27>cran:
 | 
						||
  if (Debut_X<Limite_Gauche)
 | 
						||
    Debut_X=Limite_Gauche;
 | 
						||
  if (Fin_X>Limite_Droite)
 | 
						||
    Fin_X=Limite_Droite;
 | 
						||
  if (Debut_Y<Limite_Haut)
 | 
						||
    Debut_Y=Limite_Haut;
 | 
						||
  if (Fin_Y>Limite_Bas)
 | 
						||
    Fin_Y=Limite_Bas;
 | 
						||
 | 
						||
  // On ne capture la nouvelle brosse que si elle est au moins partiellement
 | 
						||
  // dans l'image:
 | 
						||
 | 
						||
  if ((Debut_X<Principal_Largeur_image) && (Debut_Y<Principal_Hauteur_image))
 | 
						||
  {
 | 
						||
    // On met les d<>calages du tiling <20> 0 pour eviter toute incoh<6F>rence.
 | 
						||
    // Si par hasard on voulait les mettre <20>
 | 
						||
    //    min(Tiling_Decalage_?,Brosse_?a??eur-1)
 | 
						||
    // il faudrait penser <20> les initialiser <20> 0 dans "MAIN.C".
 | 
						||
    Tiling_Decalage_X=0;
 | 
						||
    Tiling_Decalage_Y=0;
 | 
						||
 | 
						||
    // Ensuite, on calcule les dimensions de la brosse:
 | 
						||
    Nouvelle_Brosse_Largeur=(Fin_X-Debut_X)+1;
 | 
						||
    Nouvelle_Brosse_Hauteur=(Fin_Y-Debut_Y)+1;
 | 
						||
 | 
						||
    if ( (((long)Brosse_Hauteur)*Brosse_Largeur) !=
 | 
						||
         (((long)Nouvelle_Brosse_Hauteur)*Nouvelle_Brosse_Largeur) )
 | 
						||
    {
 | 
						||
      free(Brosse);
 | 
						||
      Brosse=(byte *)malloc(((long)Nouvelle_Brosse_Hauteur)*Nouvelle_Brosse_Largeur);
 | 
						||
      if (!Brosse)
 | 
						||
      {
 | 
						||
        Erreur(0);
 | 
						||
 | 
						||
        Brosse=(byte *)malloc(1*1);
 | 
						||
        Nouvelle_Brosse_Hauteur=Nouvelle_Brosse_Largeur=1;
 | 
						||
        *Brosse=Fore_color;
 | 
						||
      }
 | 
						||
    }
 | 
						||
    Brosse_Largeur=Nouvelle_Brosse_Largeur;
 | 
						||
    Brosse_Hauteur=Nouvelle_Brosse_Hauteur;
 | 
						||
 | 
						||
    free(Smear_Brosse);
 | 
						||
    Smear_Brosse_Largeur=(Brosse_Largeur>TAILLE_MAXI_PINCEAU)?Brosse_Largeur:TAILLE_MAXI_PINCEAU;
 | 
						||
    Smear_Brosse_Hauteur=(Brosse_Hauteur>TAILLE_MAXI_PINCEAU)?Brosse_Hauteur:TAILLE_MAXI_PINCEAU;
 | 
						||
    Smear_Brosse=(byte *)malloc(((long)Smear_Brosse_Hauteur)*Smear_Brosse_Largeur);
 | 
						||
 | 
						||
    if (!Smear_Brosse) // On ne peut m<>me pas allouer la brosse du smear!
 | 
						||
    {
 | 
						||
      Erreur(0);
 | 
						||
 | 
						||
      free(Brosse);
 | 
						||
      Brosse=(byte *)malloc(1*1);
 | 
						||
      Brosse_Hauteur=1;
 | 
						||
      Brosse_Largeur=1;
 | 
						||
 | 
						||
      Smear_Brosse=(byte *)malloc(TAILLE_MAXI_PINCEAU*TAILLE_MAXI_PINCEAU);
 | 
						||
      Smear_Brosse_Hauteur=TAILLE_MAXI_PINCEAU;
 | 
						||
      Smear_Brosse_Largeur=TAILLE_MAXI_PINCEAU;
 | 
						||
    }
 | 
						||
 | 
						||
    Brosse_Decalage_X=Debut_X;
 | 
						||
    Brosse_Decalage_Y=Debut_Y;
 | 
						||
    Pixel_figure=Pixel_figure_Dans_brosse;
 | 
						||
 | 
						||
    memset(Brosse,Back_color,(long)Brosse_Largeur*Brosse_Hauteur);
 | 
						||
    Polyfill_General(Vertices,Points,~Back_color);
 | 
						||
 | 
						||
    // On retrace les bordures du lasso:
 | 
						||
    for (Temporaire=1; Temporaire<Vertices; Temporaire++)
 | 
						||
    {
 | 
						||
      Tracer_ligne_General(Points[(Temporaire-1)<<1],Points[((Temporaire-1)<<1)+1],
 | 
						||
                           Points[Temporaire<<1],Points[(Temporaire<<1)+1],
 | 
						||
                           ~Back_color);
 | 
						||
    }
 | 
						||
    Tracer_ligne_General(Points[(Vertices-1)<<1],Points[((Vertices-1)<<1)+1],
 | 
						||
                         Points[0],Points[1],
 | 
						||
                         ~Back_color);
 | 
						||
 | 
						||
    // On scanne la brosse pour remplacer tous les pixels affect<63>s par le
 | 
						||
    // polyfill par ceux de l'image:
 | 
						||
    for (Pos_Y=Debut_Y;Pos_Y<=Fin_Y;Pos_Y++)
 | 
						||
      for (Pos_X=Debut_X;Pos_X<=Fin_X;Pos_X++)
 | 
						||
        if (Lit_pixel_dans_brosse(Pos_X-Debut_X,Pos_Y-Debut_Y)!=Back_color)
 | 
						||
        {
 | 
						||
          Pixel_dans_brosse(Pos_X-Debut_X,Pos_Y-Debut_Y,Lit_pixel_dans_ecran_courant(Pos_X,Pos_Y));
 | 
						||
          // On regarde s'il faut effacer quelque chose:
 | 
						||
          if (Effacement)
 | 
						||
            Pixel_dans_ecran_courant(Pos_X,Pos_Y,Back_color);
 | 
						||
        }
 | 
						||
 | 
						||
    // On centre la prise sur la brosse
 | 
						||
    Brosse_Decalage_X=(Brosse_Largeur>>1);
 | 
						||
    Brosse_Decalage_Y=(Brosse_Hauteur>>1);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
//------------ Remplacement de la couleur point<6E>e par une autre --------------
 | 
						||
 | 
						||
void Remplacer(byte Nouvelle_couleur)
 | 
						||
{
 | 
						||
  byte Ancienne_couleur;
 | 
						||
 | 
						||
  if ((Pinceau_X<Principal_Largeur_image)
 | 
						||
   && (Pinceau_Y<Principal_Hauteur_image))
 | 
						||
  {
 | 
						||
    Ancienne_couleur=Lit_pixel_dans_ecran_courant(Pinceau_X,Pinceau_Y);
 | 
						||
    if ( (Ancienne_couleur!=Nouvelle_couleur)
 | 
						||
      && ((!Stencil_Mode) || (!Stencil[Ancienne_couleur])) )
 | 
						||
    {
 | 
						||
      Remplacer_une_couleur(Ancienne_couleur,Nouvelle_couleur);
 | 
						||
      Afficher_ecran();
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
//------------------------- Etirement de la brosse ---------------------------
 | 
						||
 | 
						||
void Etirer_brosse(short X1, short Y1, short X2, short Y2)
 | 
						||
{
 | 
						||
  int    Offset,Ligne,Colonne;
 | 
						||
  byte * New_Brosse;
 | 
						||
 | 
						||
  int    New_Brosse_Largeur;  // Largeur de la nouvelle brosse
 | 
						||
  int    New_Brosse_Hauteur;  // Hauteur de la nouvelle brosse
 | 
						||
 | 
						||
  int    Pos_X_dans_brosse;   // Position courante dans l'ancienne brosse
 | 
						||
  int    Pos_Y_dans_brosse;
 | 
						||
  int    Delta_X_dans_brosse; // "Vecteur incr<63>mental" du point pr<70>c<EFBFBD>dent
 | 
						||
  int    Delta_Y_dans_brosse;
 | 
						||
  int    Pos_X_initial;       // Position X de d<>but de parcours de ligne
 | 
						||
  int    Dx,Dy;
 | 
						||
 | 
						||
  Dx=(X1<X2)?1:-1;
 | 
						||
  Dy=(Y1<Y2)?1:-1;
 | 
						||
 | 
						||
  // Calcul des nouvelles dimensions de la brosse:
 | 
						||
  if ((New_Brosse_Largeur=X1-X2)<0)
 | 
						||
    New_Brosse_Largeur=-New_Brosse_Largeur;
 | 
						||
  New_Brosse_Largeur++;
 | 
						||
 | 
						||
  if ((New_Brosse_Hauteur=Y1-Y2)<0)
 | 
						||
    New_Brosse_Hauteur=-New_Brosse_Hauteur;
 | 
						||
  New_Brosse_Hauteur++;
 | 
						||
 | 
						||
  // Calcul des anciennes dimensions de la brosse:
 | 
						||
 | 
						||
  // Calcul du "vecteur incr<63>mental":
 | 
						||
  Delta_X_dans_brosse=(Brosse_Largeur<<16)/(X2-X1+Dx);
 | 
						||
  Delta_Y_dans_brosse=(Brosse_Hauteur<<16)/(Y2-Y1+Dy);
 | 
						||
 | 
						||
  // Calcul de la valeur initiale de Pos_X pour chaque ligne:
 | 
						||
  if (Dx>=0)
 | 
						||
    Pos_X_initial = 0;                // Pas d'inversion en X de la brosse
 | 
						||
  else
 | 
						||
    Pos_X_initial = (Brosse_Largeur<<16)-1; // Inversion en X de la brosse
 | 
						||
 | 
						||
  free(Smear_Brosse); // On lib<69>re un peu de m<>moire
 | 
						||
 | 
						||
  if ((New_Brosse=((byte *)malloc(New_Brosse_Largeur*New_Brosse_Hauteur))))
 | 
						||
  {
 | 
						||
    Offset=0;
 | 
						||
 | 
						||
    // Calcul de la valeur initiale de Pos_Y:
 | 
						||
    if (Dy>=0)
 | 
						||
      Pos_Y_dans_brosse=0;                // Pas d'inversion en Y de la brosse
 | 
						||
    else
 | 
						||
      Pos_Y_dans_brosse=(Brosse_Hauteur<<16)-1; // Inversion en Y de la brosse
 | 
						||
 | 
						||
    // Pour chaque ligne
 | 
						||
    for (Ligne=0;Ligne<New_Brosse_Hauteur;Ligne++)
 | 
						||
    {
 | 
						||
      // On repart du d<>but de la ligne:
 | 
						||
      Pos_X_dans_brosse=Pos_X_initial;
 | 
						||
 | 
						||
      // Pour chaque colonne:
 | 
						||
      for (Colonne=0;Colonne<New_Brosse_Largeur;Colonne++)
 | 
						||
      {
 | 
						||
        // On copie le pixel:
 | 
						||
        New_Brosse[Offset]=Lit_pixel_dans_brosse(Pos_X_dans_brosse>>16,Pos_Y_dans_brosse>>16);
 | 
						||
        // On passe <20> la colonne de brosse suivante:
 | 
						||
        Pos_X_dans_brosse+=Delta_X_dans_brosse;
 | 
						||
        // On passe au pixel suivant de la nouvelle brosse:
 | 
						||
        Offset++;
 | 
						||
      }
 | 
						||
 | 
						||
      // On passe <20> la ligne de brosse suivante:
 | 
						||
      Pos_Y_dans_brosse+=Delta_Y_dans_brosse;
 | 
						||
    }
 | 
						||
 | 
						||
    free(Brosse);
 | 
						||
    Brosse=New_Brosse;
 | 
						||
 | 
						||
    Brosse_Largeur=New_Brosse_Largeur;
 | 
						||
    Brosse_Hauteur=New_Brosse_Hauteur;
 | 
						||
 | 
						||
    Smear_Brosse_Largeur=(Brosse_Largeur>TAILLE_MAXI_PINCEAU)?Brosse_Largeur:TAILLE_MAXI_PINCEAU;
 | 
						||
    Smear_Brosse_Hauteur=(Brosse_Hauteur>TAILLE_MAXI_PINCEAU)?Brosse_Hauteur:TAILLE_MAXI_PINCEAU;
 | 
						||
    Smear_Brosse=(byte *)malloc(((long)Smear_Brosse_Hauteur)*Smear_Brosse_Largeur);
 | 
						||
 | 
						||
    if (!Smear_Brosse) // On ne peut m<>me pas allouer la brosse du smear!
 | 
						||
    {
 | 
						||
      Erreur(0);
 | 
						||
 | 
						||
      free(Brosse);
 | 
						||
      Brosse=(byte *)malloc(1*1);
 | 
						||
      Brosse_Hauteur=1;
 | 
						||
      Brosse_Largeur=1;
 | 
						||
 | 
						||
      Smear_Brosse=(byte *)malloc(TAILLE_MAXI_PINCEAU*TAILLE_MAXI_PINCEAU);
 | 
						||
      Smear_Brosse_Hauteur=TAILLE_MAXI_PINCEAU;
 | 
						||
      Smear_Brosse_Largeur=TAILLE_MAXI_PINCEAU;
 | 
						||
    }
 | 
						||
 | 
						||
    Brosse_Decalage_X=(Brosse_Largeur>>1);
 | 
						||
    Brosse_Decalage_Y=(Brosse_Hauteur>>1);
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    // Ici la lib<69>ration de m<>moire n'a pas suffit donc on remet dans l'<27>tat
 | 
						||
    // o<> c'etait avant. On a juste <20> r<>allouer la Smear_Brosse car il y a
 | 
						||
    // normalement la place pour elle puisque rien d'autre n'a pu <20>tre allou<6F>
 | 
						||
    // entre temps.
 | 
						||
    Smear_Brosse=(byte *)malloc(((long)Smear_Brosse_Hauteur)*Smear_Brosse_Largeur);
 | 
						||
    Erreur(0);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
void Etirer_brosse_preview(short X1, short Y1, short X2, short Y2)
 | 
						||
{
 | 
						||
  int    Pos_X_src,Pos_Y_src;
 | 
						||
  int    Pos_X_src_Initiale,Pos_Y_src_Initiale;
 | 
						||
  int    Delta_X,Delta_Y;
 | 
						||
  int    Pos_X_dest,Pos_Y_dest;
 | 
						||
  int    Pos_X_dest_Initiale,Pos_Y_dest_Initiale;
 | 
						||
  int    Pos_X_dest_Finale,Pos_Y_dest_Finale;
 | 
						||
  int    Largeur_dest,Hauteur_dest;
 | 
						||
  byte   Couleur;
 | 
						||
 | 
						||
 | 
						||
  // 1er calcul des positions destination extremes:
 | 
						||
  Pos_X_dest_Initiale=Min(X1,X2);
 | 
						||
  Pos_Y_dest_Initiale=Min(Y1,Y2);
 | 
						||
  Pos_X_dest_Finale  =Max(X1,X2);
 | 
						||
  Pos_Y_dest_Finale  =Max(Y1,Y2);
 | 
						||
 | 
						||
  // Calcul des dimensions de la destination:
 | 
						||
  Largeur_dest=Pos_X_dest_Finale-Pos_X_dest_Initiale+1;
 | 
						||
  Hauteur_dest=Pos_Y_dest_Finale-Pos_Y_dest_Initiale+1;
 | 
						||
 | 
						||
  // Calcul des vecteurs d'incr<63>mentation :
 | 
						||
  Delta_X=(Brosse_Largeur<<16)/Largeur_dest;
 | 
						||
  Delta_Y=(Brosse_Hauteur<<16)/Hauteur_dest;
 | 
						||
 | 
						||
  // 1er calcul de la position X initiale dans la source:
 | 
						||
  Pos_X_src_Initiale=(Brosse_Largeur<<16)*
 | 
						||
                     (Max(Pos_X_dest_Initiale,Limite_Gauche)-
 | 
						||
                      Pos_X_dest_Initiale)/Largeur_dest;
 | 
						||
  // Calcul du clip de la destination:
 | 
						||
  Pos_X_dest_Initiale=Max(Pos_X_dest_Initiale,Limite_Gauche);
 | 
						||
  Pos_X_dest_Finale  =Min(Pos_X_dest_Finale  ,Limite_visible_Droite);
 | 
						||
  // On discute selon l'inversion en X
 | 
						||
  if (X1>X2)
 | 
						||
  {
 | 
						||
    // Inversion -> Inversion du signe de Delta_X
 | 
						||
    Delta_X=-Delta_X;
 | 
						||
    Pos_X_src_Initiale=(Brosse_Largeur<<16)-1-Pos_X_src_Initiale;
 | 
						||
  }
 | 
						||
 | 
						||
  // 1er calcul de la position Y initiale dans la source:
 | 
						||
  Pos_Y_src_Initiale=(Brosse_Hauteur<<16)*
 | 
						||
                     (Max(Pos_Y_dest_Initiale,Limite_Haut)-
 | 
						||
                      Pos_Y_dest_Initiale)/Hauteur_dest;
 | 
						||
  // Calcul du clip de la destination:
 | 
						||
  Pos_Y_dest_Initiale=Max(Pos_Y_dest_Initiale,Limite_Haut);
 | 
						||
  Pos_Y_dest_Finale  =Min(Pos_Y_dest_Finale  ,Limite_visible_Bas);
 | 
						||
  // On discute selon l'inversion en Y
 | 
						||
  if (Y1>Y2)
 | 
						||
  {
 | 
						||
    // Inversion -> Inversion du signe de Delta_Y
 | 
						||
    Delta_Y=-Delta_Y;
 | 
						||
    Pos_Y_src_Initiale=(Brosse_Hauteur<<16)-1-Pos_Y_src_Initiale;
 | 
						||
  }
 | 
						||
 | 
						||
  // Pour chaque ligne :
 | 
						||
  Pos_Y_src=Pos_Y_src_Initiale;
 | 
						||
  for (Pos_Y_dest=Pos_Y_dest_Initiale;Pos_Y_dest<=Pos_Y_dest_Finale;Pos_Y_dest++)
 | 
						||
  {
 | 
						||
    // Pour chaque colonne:
 | 
						||
    Pos_X_src=Pos_X_src_Initiale;
 | 
						||
    for (Pos_X_dest=Pos_X_dest_Initiale;Pos_X_dest<=Pos_X_dest_Finale;Pos_X_dest++)
 | 
						||
    {
 | 
						||
      Couleur=Lit_pixel_dans_brosse(Pos_X_src>>16,Pos_Y_src>>16);
 | 
						||
      if (Couleur!=Back_color)
 | 
						||
        Pixel_Preview(Pos_X_dest,Pos_Y_dest,Couleur);
 | 
						||
 | 
						||
      Pos_X_src+=Delta_X;
 | 
						||
    }
 | 
						||
 | 
						||
    Pos_Y_src+=Delta_Y;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
//------------------------- Rotation de la brosse ---------------------------
 | 
						||
 | 
						||
#define INDEFINI (-1.0e20F)
 | 
						||
float * ScanY_Xt[2];
 | 
						||
float * ScanY_Yt[2];
 | 
						||
float * ScanY_X[2];
 | 
						||
 | 
						||
 | 
						||
void Interpoler_texture(int Debut_X,int Debut_Y,int Xt1,int Yt1,
 | 
						||
                        int Fin_X  ,int Fin_Y  ,int Xt2,int Yt2,int Hauteur)
 | 
						||
{
 | 
						||
  int Pos_X,Pos_Y;
 | 
						||
  int Incr_X,Incr_Y;
 | 
						||
  int i,Cumul;
 | 
						||
  int Delta_X,Delta_Y;
 | 
						||
  int Delta_Xt=Xt2-Xt1;
 | 
						||
  int Delta_Yt=Yt2-Yt1;
 | 
						||
  int Delta_X2=Fin_X-Debut_X;
 | 
						||
  int Delta_Y2=Fin_Y-Debut_Y;
 | 
						||
  float Xt,Yt;
 | 
						||
 | 
						||
 | 
						||
  Pos_X=Debut_X;
 | 
						||
  Pos_Y=Debut_Y;
 | 
						||
 | 
						||
  if (Debut_X<Fin_X)
 | 
						||
  {
 | 
						||
    Incr_X=+1;
 | 
						||
    Delta_X=Delta_X2;
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    Incr_X=-1;
 | 
						||
    Delta_X=-Delta_X2;
 | 
						||
  }
 | 
						||
 | 
						||
  if (Debut_Y<Fin_Y)
 | 
						||
  {
 | 
						||
    Incr_Y=+1;
 | 
						||
    Delta_Y=Delta_Y2;
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    Incr_Y=-1;
 | 
						||
    Delta_Y=-Delta_Y2;
 | 
						||
  }
 | 
						||
 | 
						||
  if (Delta_X>Delta_Y)
 | 
						||
  {
 | 
						||
    Cumul=Delta_X>>1;
 | 
						||
    for (i=0; i<=Delta_X; i++)
 | 
						||
    {
 | 
						||
      if (Cumul>=Delta_X)
 | 
						||
      {
 | 
						||
        Cumul-=Delta_X;
 | 
						||
        Pos_Y+=Incr_Y;
 | 
						||
      }
 | 
						||
 | 
						||
      if ((Pos_Y>=0) && (Pos_Y<Hauteur))
 | 
						||
      {
 | 
						||
        Xt=(((float)((Pos_X-Debut_X)*Delta_Xt))/(float)Delta_X2) + (float)Xt1;
 | 
						||
        Yt=(((float)((Pos_X-Debut_X)*Delta_Yt))/(float)Delta_X2) + (float)Yt1;
 | 
						||
        if (ScanY_X[0][Pos_Y]==INDEFINI) // Gauche non d<>fini
 | 
						||
        {
 | 
						||
          ScanY_X[0][Pos_Y]=Pos_X;
 | 
						||
          ScanY_Xt[0][Pos_Y]=Xt;
 | 
						||
          ScanY_Yt[0][Pos_Y]=Yt;
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          if (Pos_X>=ScanY_X[0][Pos_Y])
 | 
						||
          {
 | 
						||
            if ((ScanY_X[1][Pos_Y]==INDEFINI) // Droit non d<>fini
 | 
						||
             || (Pos_X>ScanY_X[1][Pos_Y]))
 | 
						||
            {
 | 
						||
              ScanY_X[1][Pos_Y]=Pos_X;
 | 
						||
              ScanY_Xt[1][Pos_Y]=Xt;
 | 
						||
              ScanY_Yt[1][Pos_Y]=Yt;
 | 
						||
            }
 | 
						||
          }
 | 
						||
          else
 | 
						||
          {
 | 
						||
            if (ScanY_X[1][Pos_Y]==INDEFINI) // Droit non d<>fini
 | 
						||
            {
 | 
						||
              ScanY_X[1][Pos_Y]=ScanY_X[0][Pos_Y];
 | 
						||
              ScanY_Xt[1][Pos_Y]=ScanY_Xt[0][Pos_Y];
 | 
						||
              ScanY_Yt[1][Pos_Y]=ScanY_Yt[0][Pos_Y];
 | 
						||
              ScanY_X[0][Pos_Y]=Pos_X;
 | 
						||
              ScanY_Xt[0][Pos_Y]=Xt;
 | 
						||
              ScanY_Yt[0][Pos_Y]=Yt;
 | 
						||
            }
 | 
						||
            else
 | 
						||
            {
 | 
						||
              ScanY_X[0][Pos_Y]=Pos_X;
 | 
						||
              ScanY_Xt[0][Pos_Y]=Xt;
 | 
						||
              ScanY_Yt[0][Pos_Y]=Yt;
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
      Pos_X+=Incr_X;
 | 
						||
      Cumul+=Delta_Y;
 | 
						||
    }
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    Cumul=Delta_Y>>1;
 | 
						||
    for (i=0; i<=Delta_Y; i++)
 | 
						||
    {
 | 
						||
      if (Cumul>=Delta_Y)
 | 
						||
      {
 | 
						||
        Cumul-=Delta_Y;
 | 
						||
        Pos_X+=Incr_X;
 | 
						||
      }
 | 
						||
 | 
						||
      if ((Pos_Y>=0) && (Pos_Y<Hauteur))
 | 
						||
      {
 | 
						||
        Xt=(((float)((Pos_Y-Debut_Y)*Delta_Xt))/(float)Delta_Y2) + (float)Xt1;
 | 
						||
        Yt=(((float)((Pos_Y-Debut_Y)*Delta_Yt))/(float)Delta_Y2) + (float)Yt1;
 | 
						||
        if (ScanY_X[0][Pos_Y]==INDEFINI) // Gauche non d<>fini
 | 
						||
        {
 | 
						||
          ScanY_X[0][Pos_Y]=Pos_X;
 | 
						||
          ScanY_Xt[0][Pos_Y]=Xt;
 | 
						||
          ScanY_Yt[0][Pos_Y]=Yt;
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          if (Pos_X>=ScanY_X[0][Pos_Y])
 | 
						||
          {
 | 
						||
            if ((ScanY_X[1][Pos_Y]==INDEFINI) // Droit non d<>fini
 | 
						||
             || (Pos_X>ScanY_X[1][Pos_Y]))
 | 
						||
            {
 | 
						||
              ScanY_X[1][Pos_Y]=Pos_X;
 | 
						||
              ScanY_Xt[1][Pos_Y]=Xt;
 | 
						||
              ScanY_Yt[1][Pos_Y]=Yt;
 | 
						||
            }
 | 
						||
          }
 | 
						||
          else
 | 
						||
          {
 | 
						||
            if (ScanY_X[1][Pos_Y]==INDEFINI) // Droit non d<>fini
 | 
						||
            {
 | 
						||
              ScanY_X[1][Pos_Y]=ScanY_X[0][Pos_Y];
 | 
						||
              ScanY_Xt[1][Pos_Y]=ScanY_Xt[0][Pos_Y];
 | 
						||
              ScanY_Yt[1][Pos_Y]=ScanY_Yt[0][Pos_Y];
 | 
						||
              ScanY_X[0][Pos_Y]=Pos_X;
 | 
						||
              ScanY_Xt[0][Pos_Y]=Xt;
 | 
						||
              ScanY_Yt[0][Pos_Y]=Yt;
 | 
						||
            }
 | 
						||
            else
 | 
						||
            {
 | 
						||
              ScanY_X[0][Pos_Y]=Pos_X;
 | 
						||
              ScanY_Xt[0][Pos_Y]=Xt;
 | 
						||
              ScanY_Yt[0][Pos_Y]=Yt;
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
      Pos_Y+=Incr_Y;
 | 
						||
      Cumul+=Delta_X;
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
void Calculer_quad_texture(int X1,int Y1,int Xt1,int Yt1,
 | 
						||
                           int X2,int Y2,int Xt2,int Yt2,
 | 
						||
                           int X3,int Y3,int Xt3,int Yt3,
 | 
						||
                           int X4,int Y4,int Xt4,int Yt4,
 | 
						||
                           byte * Buffer, int Largeur, int Hauteur)
 | 
						||
{
 | 
						||
  int Xmin,/*Xmax,*/Ymin/*,Ymax*/;
 | 
						||
  int X,Y,Xt,Yt;
 | 
						||
  int Debut_X,Fin_X,Largeur_ligne;
 | 
						||
  float Temp;
 | 
						||
  //byte Couleur;
 | 
						||
 | 
						||
  Xmin=Min(Min(X1,X2),Min(X3,X4));
 | 
						||
  Ymin=Min(Min(Y1,Y2),Min(Y3,Y4));
 | 
						||
 | 
						||
  ScanY_Xt[0]=(float *)malloc(Hauteur*sizeof(float));
 | 
						||
  ScanY_Xt[1]=(float *)malloc(Hauteur*sizeof(float));
 | 
						||
  ScanY_Yt[0]=(float *)malloc(Hauteur*sizeof(float));
 | 
						||
  ScanY_Yt[1]=(float *)malloc(Hauteur*sizeof(float));
 | 
						||
  ScanY_X[0] =(float *)malloc(Hauteur*sizeof(float));
 | 
						||
  ScanY_X[1] =(float *)malloc(Hauteur*sizeof(float));
 | 
						||
 | 
						||
  // Remplir avec des valeurs <20>gales <20> INDEFINI.
 | 
						||
  for (Y=0; Y<Hauteur; Y++)
 | 
						||
  {
 | 
						||
    ScanY_X[0][Y]=INDEFINI;
 | 
						||
    ScanY_X[1][Y]=INDEFINI;
 | 
						||
  }
 | 
						||
 | 
						||
  Interpoler_texture(X1-Xmin,Y1-Ymin,Xt1,Yt1,X3-Xmin,Y3-Ymin,Xt3,Yt3,Hauteur);
 | 
						||
  Interpoler_texture(X3-Xmin,Y3-Ymin,Xt3,Yt3,X4-Xmin,Y4-Ymin,Xt4,Yt4,Hauteur);
 | 
						||
  Interpoler_texture(X4-Xmin,Y4-Ymin,Xt4,Yt4,X2-Xmin,Y2-Ymin,Xt2,Yt2,Hauteur);
 | 
						||
  Interpoler_texture(X2-Xmin,Y2-Ymin,Xt2,Yt2,X1-Xmin,Y1-Ymin,Xt1,Yt1,Hauteur);
 | 
						||
 | 
						||
  for (Y=0; Y<Hauteur; Y++)
 | 
						||
  {
 | 
						||
    Debut_X=Round(ScanY_X[0][Y]);
 | 
						||
    Fin_X  =Round(ScanY_X[1][Y]);
 | 
						||
 | 
						||
    Largeur_ligne=1+Fin_X-Debut_X;
 | 
						||
 | 
						||
    for (X=0; X<Debut_X; X++)
 | 
						||
      Buffer[X+(Y*Largeur)]=Back_color;
 | 
						||
    for (; X<=Fin_X; X++)
 | 
						||
    {
 | 
						||
      Temp=(float)(0.5+(float)X-ScanY_X[0][Y])/(float)Largeur_ligne;
 | 
						||
      Xt=Round((float)(ScanY_Xt[0][Y])+(Temp*(ScanY_Xt[1][Y]-ScanY_Xt[0][Y])));
 | 
						||
      Yt=Round((float)(ScanY_Yt[0][Y])+(Temp*(ScanY_Yt[1][Y]-ScanY_Yt[0][Y])));
 | 
						||
 | 
						||
      Buffer[X+(Y*Largeur)]=Lit_pixel_dans_brosse(Xt,Yt);
 | 
						||
    }
 | 
						||
    for (; X<Largeur; X++)
 | 
						||
      Buffer[X+(Y*Largeur)]=Back_color;
 | 
						||
  }
 | 
						||
 | 
						||
  free(ScanY_Xt[0]);
 | 
						||
  free(ScanY_Xt[1]);
 | 
						||
  free(ScanY_Yt[0]);
 | 
						||
  free(ScanY_Yt[1]);
 | 
						||
  free(ScanY_X[0]);
 | 
						||
  free(ScanY_X[1]);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
void Tourner_brosse(float Angle)
 | 
						||
{
 | 
						||
  byte * New_Brosse;
 | 
						||
  int    New_Brosse_Largeur;  // Largeur de la nouvelle brosse
 | 
						||
  int    New_Brosse_Hauteur;  // Hauteur de la nouvelle brosse
 | 
						||
 | 
						||
  short X1,Y1,X2,Y2,X3,Y3,X4,Y4;
 | 
						||
  int Debut_X,Fin_X,Debut_Y,Fin_Y;
 | 
						||
  int Xmin,Xmax,Ymin,Ymax;
 | 
						||
  float cosA=cos(Angle);
 | 
						||
  float sinA=sin(Angle);
 | 
						||
 | 
						||
  // Calcul des coordonn<6E>es des 4 coins:
 | 
						||
  // 1 2
 | 
						||
  // 3 4
 | 
						||
 | 
						||
  Debut_X=1-(Brosse_Largeur>>1);
 | 
						||
  Debut_Y=1-(Brosse_Hauteur>>1);
 | 
						||
  Fin_X=Debut_X+Brosse_Largeur-1;
 | 
						||
  Fin_Y=Debut_Y+Brosse_Hauteur-1;
 | 
						||
 | 
						||
  Transformer_point(Debut_X,Debut_Y, cosA,sinA, &X1,&Y1);
 | 
						||
  Transformer_point(Fin_X  ,Debut_Y, cosA,sinA, &X2,&Y2);
 | 
						||
  Transformer_point(Debut_X,Fin_Y  , cosA,sinA, &X3,&Y3);
 | 
						||
  Transformer_point(Fin_X  ,Fin_Y  , cosA,sinA, &X4,&Y4);
 | 
						||
 | 
						||
  // Calcul des nouvelles dimensions de la brosse:
 | 
						||
  Xmin=Min(Min((int)X1,(int)X2),Min((int)X3,(int)X4));
 | 
						||
  Xmax=Max(Max((int)X1,(int)X2),Max((int)X3,(int)X4));
 | 
						||
  Ymin=Min(Min((int)Y1,(int)Y2),Min((int)Y3,(int)Y4));
 | 
						||
  Ymax=Max(Max((int)Y1,(int)Y2),Max((int)Y3,(int)Y4));
 | 
						||
 | 
						||
  New_Brosse_Largeur=Xmax+1-Xmin;
 | 
						||
  New_Brosse_Hauteur=Ymax+1-Ymin;
 | 
						||
 | 
						||
  free(Smear_Brosse); // On lib<69>re un peu de m<>moire
 | 
						||
 | 
						||
  if ((New_Brosse=((byte *)malloc(New_Brosse_Largeur*New_Brosse_Hauteur))))
 | 
						||
  {
 | 
						||
    // Et maintenant on calcule la nouvelle brosse tourn<72>e.
 | 
						||
    Calculer_quad_texture(X1,Y1,               0,               0,
 | 
						||
                          X2,Y2,Brosse_Largeur-1,               0,
 | 
						||
                          X3,Y3,               0,Brosse_Hauteur-1,
 | 
						||
                          X4,Y4,Brosse_Largeur-1,Brosse_Hauteur-1,
 | 
						||
                          New_Brosse,New_Brosse_Largeur,New_Brosse_Hauteur);
 | 
						||
 | 
						||
    free(Brosse);
 | 
						||
    Brosse=New_Brosse;
 | 
						||
 | 
						||
    Brosse_Largeur=New_Brosse_Largeur;
 | 
						||
    Brosse_Hauteur=New_Brosse_Hauteur;
 | 
						||
 | 
						||
    Smear_Brosse_Largeur=(Brosse_Largeur>TAILLE_MAXI_PINCEAU)?Brosse_Largeur:TAILLE_MAXI_PINCEAU;
 | 
						||
    Smear_Brosse_Hauteur=(Brosse_Hauteur>TAILLE_MAXI_PINCEAU)?Brosse_Hauteur:TAILLE_MAXI_PINCEAU;
 | 
						||
    Smear_Brosse=(byte *)malloc(((long)Smear_Brosse_Hauteur)*Smear_Brosse_Largeur);
 | 
						||
 | 
						||
    if (!Smear_Brosse) // On ne peut m<>me pas allouer la brosse du smear!
 | 
						||
    {
 | 
						||
      Erreur(0);
 | 
						||
 | 
						||
      free(Brosse);
 | 
						||
      Brosse=(byte *)malloc(1*1);
 | 
						||
      Brosse_Hauteur=1;
 | 
						||
      Brosse_Largeur=1;
 | 
						||
 | 
						||
      Smear_Brosse=(byte *)malloc(TAILLE_MAXI_PINCEAU*TAILLE_MAXI_PINCEAU);
 | 
						||
      Smear_Brosse_Hauteur=TAILLE_MAXI_PINCEAU;
 | 
						||
      Smear_Brosse_Largeur=TAILLE_MAXI_PINCEAU;
 | 
						||
    }
 | 
						||
 | 
						||
    Brosse_Decalage_X=(Brosse_Largeur>>1);
 | 
						||
    Brosse_Decalage_Y=(Brosse_Hauteur>>1);
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    // Ici la lib<69>ration de m<>moire n'a pas suffit donc on remet dans l'<27>tat
 | 
						||
    // o<> c'etait avant. On a juste <20> r<>allouer la Smear_Brosse car il y a
 | 
						||
    // normalement la place pour elle puisque rien d'autre n'a pu <20>tre allou<6F>
 | 
						||
    // entre temps.
 | 
						||
    Smear_Brosse=(byte *)malloc(((long)Smear_Brosse_Hauteur)*Smear_Brosse_Largeur);
 | 
						||
    Erreur(0);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
void Dessiner_quad_texture_preview(int X1,int Y1,int Xt1,int Yt1,
 | 
						||
                                   int X2,int Y2,int Xt2,int Yt2,
 | 
						||
                                   int X3,int Y3,int Xt3,int Yt3,
 | 
						||
                                   int X4,int Y4,int Xt4,int Yt4)
 | 
						||
{
 | 
						||
  int Xmin,Xmax,Ymin,Ymax;
 | 
						||
  int X,Y,Xt,Yt;
 | 
						||
  int Y_,Ymin_;
 | 
						||
  int Debut_X,Fin_X,Largeur,Hauteur;
 | 
						||
  float Temp;
 | 
						||
  byte Couleur;
 | 
						||
 | 
						||
  Xmin=Min(Min(X1,X2),Min(X3,X4));
 | 
						||
  Xmax=Max(Max(X1,X2),Max(X3,X4));
 | 
						||
  Ymin=Min(Min(Y1,Y2),Min(Y3,Y4));
 | 
						||
  Ymax=Max(Max(Y1,Y2),Max(Y3,Y4));
 | 
						||
  Hauteur=1+Ymax-Ymin;
 | 
						||
 | 
						||
  ScanY_Xt[0]=(float *)malloc(Hauteur*sizeof(float));
 | 
						||
  ScanY_Xt[1]=(float *)malloc(Hauteur*sizeof(float));
 | 
						||
  ScanY_Yt[0]=(float *)malloc(Hauteur*sizeof(float));
 | 
						||
  ScanY_Yt[1]=(float *)malloc(Hauteur*sizeof(float));
 | 
						||
  ScanY_X[0] =(float *)malloc(Hauteur*sizeof(float));
 | 
						||
  ScanY_X[1] =(float *)malloc(Hauteur*sizeof(float));
 | 
						||
 | 
						||
  // Remplir avec des valeurs <20>gales <20> INDEFINI.
 | 
						||
  for (Y=0; Y<Hauteur; Y++)
 | 
						||
  {
 | 
						||
    ScanY_X[0][Y]=INDEFINI;
 | 
						||
    ScanY_X[1][Y]=INDEFINI;
 | 
						||
  }
 | 
						||
 | 
						||
  Interpoler_texture(X1,Y1-Ymin,Xt1,Yt1,X3,Y3-Ymin,Xt3,Yt3,Hauteur);
 | 
						||
  Interpoler_texture(X3,Y3-Ymin,Xt3,Yt3,X4,Y4-Ymin,Xt4,Yt4,Hauteur);
 | 
						||
  Interpoler_texture(X4,Y4-Ymin,Xt4,Yt4,X2,Y2-Ymin,Xt2,Yt2,Hauteur);
 | 
						||
  Interpoler_texture(X2,Y2-Ymin,Xt2,Yt2,X1,Y1-Ymin,Xt1,Yt1,Hauteur);
 | 
						||
 | 
						||
  Ymin_=Ymin;
 | 
						||
  if (Ymin<Limite_Haut) Ymin=Limite_Haut;
 | 
						||
  if (Ymax>Limite_Bas)  Ymax=Limite_Bas;
 | 
						||
 | 
						||
  for (Y_=Ymin; Y_<=Ymax; Y_++)
 | 
						||
  {
 | 
						||
    Y=Y_-Ymin_;
 | 
						||
    Debut_X=Round(ScanY_X[0][Y]);
 | 
						||
    Fin_X  =Round(ScanY_X[1][Y]);
 | 
						||
 | 
						||
    Largeur=1+Fin_X-Debut_X;
 | 
						||
 | 
						||
    if (Debut_X<Limite_Gauche) Debut_X=Limite_Gauche;
 | 
						||
    if (  Fin_X>Limite_Droite)   Fin_X=Limite_Droite;
 | 
						||
 | 
						||
    for (X=Debut_X; X<=Fin_X; X++)
 | 
						||
    {
 | 
						||
      Temp=(float)(0.5+(float)X-ScanY_X[0][Y])/(float)Largeur;
 | 
						||
      Xt=Round((float)(ScanY_Xt[0][Y])+(Temp*(ScanY_Xt[1][Y]-ScanY_Xt[0][Y])));
 | 
						||
      Yt=Round((float)(ScanY_Yt[0][Y])+(Temp*(ScanY_Yt[1][Y]-ScanY_Yt[0][Y])));
 | 
						||
 | 
						||
      Couleur=Lit_pixel_dans_brosse(Xt,Yt);
 | 
						||
      if (Couleur!=Back_color)
 | 
						||
        Pixel_Preview(X,Y_,Couleur);
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  free(ScanY_Xt[0]);
 | 
						||
  free(ScanY_Xt[1]);
 | 
						||
  free(ScanY_Yt[0]);
 | 
						||
  free(ScanY_Yt[1]);
 | 
						||
  free(ScanY_X[0]);
 | 
						||
  free(ScanY_X[1]);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void Tourner_brosse_preview(float Angle)
 | 
						||
{
 | 
						||
  short X1,Y1,X2,Y2,X3,Y3,X4,Y4;
 | 
						||
  int Debut_X,Fin_X,Debut_Y,Fin_Y;
 | 
						||
  float cosA=cos(Angle);
 | 
						||
  float sinA=sin(Angle);
 | 
						||
 | 
						||
  // Calcul des coordonn<6E>es des 4 coins:
 | 
						||
  // 1 2
 | 
						||
  // 3 4
 | 
						||
 | 
						||
  Debut_X=1-(Brosse_Largeur>>1);
 | 
						||
  Debut_Y=1-(Brosse_Hauteur>>1);
 | 
						||
  Fin_X=Debut_X+Brosse_Largeur-1;
 | 
						||
  Fin_Y=Debut_Y+Brosse_Hauteur-1;
 | 
						||
 | 
						||
  Transformer_point(Debut_X,Debut_Y, cosA,sinA, &X1,&Y1);
 | 
						||
  Transformer_point(Fin_X  ,Debut_Y, cosA,sinA, &X2,&Y2);
 | 
						||
  Transformer_point(Debut_X,Fin_Y  , cosA,sinA, &X3,&Y3);
 | 
						||
  Transformer_point(Fin_X  ,Fin_Y  , cosA,sinA, &X4,&Y4);
 | 
						||
 | 
						||
  X1+=Brosse_Centre_rotation_X;
 | 
						||
  Y1+=Brosse_Centre_rotation_Y;
 | 
						||
  X2+=Brosse_Centre_rotation_X;
 | 
						||
  Y2+=Brosse_Centre_rotation_Y;
 | 
						||
  X3+=Brosse_Centre_rotation_X;
 | 
						||
  Y3+=Brosse_Centre_rotation_Y;
 | 
						||
  X4+=Brosse_Centre_rotation_X;
 | 
						||
  Y4+=Brosse_Centre_rotation_Y;
 | 
						||
 | 
						||
  // Et maintenant on dessine la brosse tourn<72>e.
 | 
						||
  Dessiner_quad_texture_preview(X1,Y1,               0,               0,
 | 
						||
                                X2,Y2,Brosse_Largeur-1,               0,
 | 
						||
                                X3,Y3,               0,Brosse_Hauteur-1,
 | 
						||
                                X4,Y4,Brosse_Largeur-1,Brosse_Hauteur-1);
 | 
						||
}
 |