diff --git a/aide.c b/aide.c index d1fdff39..4cc90f72 100644 --- a/aide.c +++ b/aide.c @@ -8,7 +8,11 @@ #include -#include +#ifdef __linux__ + #include +#elif __WATCOMC__ + #include +#endif // -- Menu d'aide ----------------------------------------------------------- @@ -199,13 +203,20 @@ void Bouton_Stats(void) short Bouton_clicke; char Buffer[37]; dword Utilisation_couleur[256]; - unsigned long long Taille; - struct statfs Informations_Disque; + unsigned long long freeRam; + + #ifdef __linux__ + struct statfs Informations_Disque; + unsigned long long Taille = 0; + #elif __WATCOMC__ + unsigned __int64 Taille; + ULARGE_INTEGER tailleU; + #endif Ouvrir_fenetre(310,174,"Statistics"); - // dessiner de la fenˆtre o— va s'afficher le texte + // Dessin de la fenetre ou va s'afficher le texte Fenetre_Afficher_cadre_creux(8,17,294,132); Block(Fenetre_Pos_X+(Menu_Facteur_X*9), Fenetre_Pos_Y+(Menu_Facteur_Y*18), @@ -219,33 +230,42 @@ void Bouton_Stats(void) Print_dans_fenetre(82,19,Buffer,STATS_COULEUR_DONNEES,CM_Noir); // Affichage de la mémoire restante - Print_dans_fenetre(10,35,"Free memory:",STATS_COULEUR_TITRES,CM_Noir); - unsigned long long freeRam = Memoire_libre(); + Print_dans_fenetre(10,35,"Free memory: ",STATS_COULEUR_TITRES,CM_Noir); + + freeRam = Memoire_libre(); + if(freeRam > (100ULL*1024*1024*1024)) - sprintf(Buffer,"%d Gigabytes",(unsigned int)(freeRam/(1024*1024*1024))); + sprintf(Buffer,"%d Gigabytes",(unsigned int)(freeRam/(1024*1024*1024))); else if(freeRam > (100*1024*1024)) - sprintf(Buffer,"%d Megabytes",(unsigned int)(freeRam/(1024*1024))); + sprintf(Buffer,"%d Megabytes",(unsigned int)(freeRam/(1024*1024))); else if(freeRam > 100*1024) - sprintf(Buffer,"%d Kilobytes",(unsigned int)(freeRam/1024)); + sprintf(Buffer,"%d Kilobytes",(unsigned int)(freeRam/1024)); else - sprintf(Buffer,"%d bytes",(unsigned int)freeRam); + sprintf(Buffer,"%d bytes",(unsigned int)freeRam); Print_dans_fenetre(114,35,Buffer,STATS_COULEUR_DONNEES,CM_Noir); // Affichage de l'espace disque libre sprintf(Buffer,"Free space on %c:",Principal_Repertoire_courant[0]); Print_dans_fenetre(10,51,Buffer,STATS_COULEUR_TITRES,CM_Noir); - statfs(Principal_Repertoire_courant,&Informations_Disque); - Taille=Informations_Disque.f_bfree * Informations_Disque.f_bsize; + + #ifdef __linux__ + statfs(Principal_Repertoire_courant,&Informations_Disque); + Taille=Informations_Disque.f_bfree * Informations_Disque.f_bsize; + #elif __WATCOMC__ + GetDiskFreeSpaceEx(Principal_Repertoire_courant,&tailleU,NULL,NULL); + Taille = tailleU.QuadPart; + #endif + if (Taille>=0) { if(Taille > (100ULL*1024*1024*1024)) - sprintf(Buffer,"%d Gigabytes",(unsigned int)(Taille/(1024*1024*1024))); + sprintf(Buffer,"%d Gigabytes",(unsigned int)(Taille/(1024*1024*1024))); else if(Taille > (100*1024*1024)) - sprintf(Buffer,"%d Megabytes",(unsigned int)(Taille/(1024*1024))); + sprintf(Buffer,"%d Megabytes",(unsigned int)(Taille/(1024*1024))); else if(Taille > (100*1024)) - sprintf(Buffer,"%d Kilobytes",(unsigned int)(Taille/1024)); + sprintf(Buffer,"%d Kilobytes",(unsigned int)(Taille/1024)); else - sprintf(Buffer,"%d bytes",(unsigned int)Taille); + sprintf(Buffer,"%d bytes",(unsigned int)Taille); Print_dans_fenetre(146,51,Buffer,STATS_COULEUR_DONNEES,CM_Noir); } else diff --git a/boutons.c b/boutons.c index f89138a1..d406d973 100644 --- a/boutons.c +++ b/boutons.c @@ -21,6 +21,12 @@ #include "pages.h" #include "erreurs.h" +#ifdef __WATCOMC__ + #include + #define chdir(x) SetCurrentDirectory(x) + #define rmdir(x) DeleteFile(x) +#endif + //-- MODELE DE BOUTON DE MENU ------------------------------------------------ /* void Bouton_***(void) @@ -122,7 +128,7 @@ void Bouton_Message_initial(void) Print_dans_fenetre( 7,128,"file before using this program",CM_Fonce,CM_Clair); Print_dans_fenetre( 7,136,"for the first time.",CM_Fonce,CM_Clair); - if ((*ALPHA_BETA)=='Ó') + if ((*ALPHA_BETA)=='á') { Print_char_transparent_dans_fenetre(43,119,'M',CM_Noir); Print_char_transparent_dans_fenetre(53,121,'U',CM_Noir); @@ -1190,7 +1196,7 @@ void Cocher_bouton_mode(short Pos_X, short Pos_Y, byte Etat) } Block(Fenetre_Pos_X+Menu_Facteur_X*Pos_X,Fenetre_Pos_Y+Menu_Facteur_Y*Pos_Y, Menu_Facteur_X*9,Menu_Facteur_Y*3,Couleur); - + SDL_UpdateRect(Ecran_SDL,Fenetre_Pos_X+Menu_Facteur_X*Pos_X,Fenetre_Pos_Y+Menu_Facteur_Y*Pos_Y, Menu_Facteur_X*9,Menu_Facteur_Y*3); } @@ -1685,7 +1691,7 @@ void Degrade_Dessiner_bouton_de_technique(short Pos_X,short Pos_Y,int Technique) } SDL_UpdateRect(Ecran_SDL,Fenetre_Pos_X+((Pos_X+2)*Menu_Facteur_X),Fenetre_Pos_Y+((Pos_Y+2)*Menu_Facteur_Y), - Menu_Facteur_X*10,Menu_Facteur_Y*10); + Menu_Facteur_X*10,Menu_Facteur_Y*10); } void Degrade_Charger_infos_du_tableau(int Indice) @@ -2105,12 +2111,12 @@ void Print_repertoire_courant(void) // le reste de la chaine (Ouaaaaaah!!! Vachement fort le mec!!) for (Indice++;Indice>Mouse_Facteur_de_correction_X; - INPUT_Nouveau_Mouse_Y = event.motion.y>>Mouse_Facteur_de_correction_Y; - break; - case SDL_MOUSEBUTTONDOWN: - //Clic sur un des boutons de la souris - INPUT_Nouveau_Mouse_K=event.button.button; - break; - case SDL_MOUSEBUTTONUP: - //Bouton souris relaché - INPUT_Nouveau_Mouse_K=0; - break; - case SDL_KEYDOWN: - //Appui sur une touche du clavier + switch( event.type) + { + case SDL_MOUSEMOTION: + //Mouvement de la souris + INPUT_Nouveau_Mouse_X = event.motion.x>>Mouse_Facteur_de_correction_X; + INPUT_Nouveau_Mouse_Y = event.motion.y>>Mouse_Facteur_de_correction_Y; + break; + case SDL_MOUSEBUTTONDOWN: + //Clic sur un des boutons de la souris + INPUT_Nouveau_Mouse_K=event.button.button; + break; + case SDL_MOUSEBUTTONUP: + //Bouton souris relaché + INPUT_Nouveau_Mouse_K=0; + break; + case SDL_KEYDOWN: + { + byte ok = 0; + //Appui sur une touche du clavier - //On met le scancode dans Touche" - Touche = event.key.keysym.scancode; + //On met le scancode dans Touche" + Touche = event.key.keysym.scancode; - //...et le code ASCII dans Touche_ASCII - Touche_ASCII=event.key.keysym.sym; + //...et le code ASCII dans Touche_ASCII + Touche_ASCII=event.key.keysym.sym; - //On ajoute aussi l'état des modifiers - #define ekkm event.key.keysym.mod - if (ekkm & (KMOD_LSHIFT | KMOD_RSHIFT)) - { - Touche |= 0x0100; - } - if (ekkm & (KMOD_LCTRL | KMOD_RCTRL)) - { - Touche |= 0x0200; - } - if (ekkm & (KMOD_LALT | KMOD_RALT)) - { - Touche |= 0x0400; - } - #undef ekkm + //On ajoute aussi l'état des modifiers + #define ekkm event.key.keysym.mod + if (ekkm & (KMOD_LSHIFT | KMOD_RSHIFT)) + { + Touche |= 0x0100; + } + if (ekkm & (KMOD_LCTRL | KMOD_RCTRL)) + { + Touche |= 0x0200; + } + if (ekkm & (KMOD_LALT | KMOD_RALT)) + { + Touche |= 0x0400; + } + #undef ekkm + + //TODO revoir les scancodes qui sont dans le tableau + //Config_Touche, ça correspond à rien ! + + //Cas particulier: déplacement du curseur avec haut bas gauche droite + //On doit interpréter ça comme un mvt de la souris + + if(Touche == Config_Touche[0]) + { + //[Touche] = Emulation de MOUSE UP + //si on est déjà en haut on peut plus bouger + if(INPUT_Nouveau_Mouse_Y!=0) + { + INPUT_Nouveau_Mouse_Y--; + ok=1; + } + } + else if(Touche == Config_Touche[1]) + { + //[Touche] = Emulation de MOUSE DOWN + if(INPUT_Nouveau_Mouse_Y=Principal_Split) - { - bl++; - INPUT_Nouveau_Mouse_X=Principal_Split-1; - } - } - else - { - if(INPUT_Nouveau_Mouse_X=Principal_Split) + { + bl++; + INPUT_Nouveau_Mouse_X=Principal_Split-1; + } + } + else + { + if(INPUT_Nouveau_Mouse_XChrono_cmp) Etat_chrono=1; + if((SDL_GetTicks()/55)-Chrono_delay>Chrono_cmp) Etat_chrono=1; } void Flip_Y_LOWLEVEL(void) { - UNIMPLEMENTED + UNIMPLEMENTED } void Flip_X_LOWLEVEL(void) { - UNIMPLEMENTED + UNIMPLEMENTED } void Rotate_180_deg_LOWLEVEL(void) { - UNIMPLEMENTED + UNIMPLEMENTED } void Tempo_jauge(byte Vitesse) //Boucle d'attente pour faire bouger les scrollbars à une vitesse correcte { - while (Vitesse!=0) - { - Wait_VBL(); - Vitesse--; - } + while (Vitesse!=0) + { + Wait_VBL(); + Vitesse--; + } } byte Meilleure_couleur_sans_exclusion(byte Rouge,byte Vert,byte Bleu) { - UNIMPLEMENTED - return 0; + UNIMPLEMENTED + return 0; } void Set_color(byte Couleur, byte Rouge, byte Vert, byte Bleu) { - UNIMPLEMENTED + UNIMPLEMENTED } void Scroll_picture(short Decalage_X,short Decalage_Y) { - UNIMPLEMENTED + UNIMPLEMENTED } byte Get_key(void) { - SDL_Event event; + SDL_Event event; - SDL_EnableUNICODE(SDL_ENABLE); // On a besoin du caractère + SDL_EnableUNICODE(SDL_ENABLE); // On a besoin du caractère - while(1) - { - SDL_PollEvent(&event); - if(event.type == SDL_KEYDOWN) - { - // On retourne en mode standard pour la gestion normale - SDL_EnableUNICODE(SDL_DISABLE); - return (byte)(event.key.keysym.unicode); - } - } + while(1) + { + SDL_PollEvent(&event); + if(event.type == SDL_KEYDOWN) + { + // On retourne en mode standard pour la gestion normale + SDL_EnableUNICODE(SDL_DISABLE); + return (byte)(event.key.keysym.unicode); + } + } } void Zoomer_une_ligne(byte* Ligne_originale, byte* Ligne_zoomee, - word Facteur, word Largeur + word Facteur, word Largeur ) { - byte couleur; - word larg; + byte couleur; + word larg; - // Pour chaque pixel - for(larg=0;larg #include -#include #include #include #include #include #include - -#include "linux.h" +#ifdef __linux__ + #include "linux.h" + #include + #define isDir(Enreg) ((Enreg)->d_type == DT_DIR) + #define isHidden(Enreg) ((Enreg)->d_name[0]=='.') + #define isFile(Enreg) (Enreg->d_type==DT_REG) +#elif __WATCOMC__ + #include + #define isDir(Enreg) ((Enreg)->d_attr & _A_SUBDIR) + #define isHidden(Enreg) ((Enreg)->d_attr & _A_HIDDEN) + #define isFile(Enreg) ((Enreg)->d_attr & _A_SUBDIR == 0) +#endif #define COULEUR_FICHIER_NORMAL CM_Clair // Couleur du texte pour une ligne de fichier non sélectionné #define COULEUR_REPERTOIRE_NORMAL CM_Fonce // Couleur du texte pour une ligne de répertoire non sélectionné @@ -133,19 +142,23 @@ char * Nom_formate(char * Nom) } -// -- Rajouter … la liste des ‚l‚ments de la liste un ‚l‚ment --------------- +// -- Rajouter a la liste des elements de la liste un element --------------- void Ajouter_element_a_la_liste(struct dirent* Enreg) -// Cette proc‚dure ajoute … la liste chain‚e un fichier pass‚ en argument. +// Cette procedure ajoute a la liste chainee un fichier pass‚ en argument. { // Pointeur temporaire d'insertion struct Element_de_liste_de_fileselect * Element_temporaire; - // On alloue de la place pour un nouvel ‚l‚ment + // On alloue de la place pour un nouvel element Element_temporaire=(struct Element_de_liste_de_fileselect *)malloc(sizeof(struct Element_de_liste_de_fileselect)); - // On met … jour le nouvel emplacement: + // On met a jour le nouvel emplacement: strcpy(Element_temporaire->Nom,Nom_formate(Enreg->d_name)); - Element_temporaire->Type =(Enreg->d_type == DT_DIR); + #ifdef __linux__ + Element_temporaire->Type = (Enreg->d_type == DT_DIR); + #elif __WATCOMC__ + Element_temporaire->Type = (Enreg->d_attr & _A_SUBDIR); + #endif Element_temporaire->Suivant =Liste_du_fileselect; Element_temporaire->Precedent=NULL; @@ -187,22 +200,22 @@ void Lire_liste_des_fichiers(byte Format_demande) // Si l'élément n'est pas le répertoire courant if ( (Enreg->d_name[0]!='.') && (Enreg->d_name[1] != 0)) { - // et que l'élément trouvé est un répertoire - if( (Enreg->d_type == DT_DIR) && - // et qu'il n'est pas caché - (Enreg->d_name[0]!='.' || Config.Lire_les_repertoires_caches)) - { - // On rajoute le répertore à la liste - Ajouter_element_a_la_liste(Enreg); - Liste_Nb_repertoires++; - } - else if ((Enreg->d_type==DT_REG) //Il s'agit d'un fichier - && (Enreg->d_name[0]!='.' || Config.Lire_les_fichiers_caches)) //Il n'est pas caché - { - // On rajoute le fichier à la liste - Ajouter_element_a_la_liste(Enreg); - Liste_Nb_fichiers++; - } + // et que l'élément trouvé est un répertoire + if( isDir(Enreg) && + // et qu'il n'est pas caché + ((!isHidden(Enreg)) || Config.Lire_les_repertoires_caches)) + { + // On rajoute le répertore à la liste + Ajouter_element_a_la_liste(Enreg); + Liste_Nb_repertoires++; + } + else if (isFile(Enreg) //Il s'agit d'un fichier + && ((!isHidden(Enreg)) || Config.Lire_les_fichiers_caches)) //Il n'est pas caché + { + // On rajoute le fichier à la liste + Ajouter_element_a_la_liste(Enreg); + Liste_Nb_fichiers++; + } } // On cherche l'élément suivant diff --git a/global.h b/global.h index f98e8e8e..53cf2c77 100644 --- a/global.h +++ b/global.h @@ -159,7 +159,7 @@ GLOBAL fonction_lecteur Lit_pixel; // Teste la couleur d'un pixel dans l' GLOBAL fonction_effaceur Clear_screen; // Efface rapidement tout l'écran (en faisant attention de ne pas effacer le menu) GLOBAL fonction_display Display_screen; // Affiche rapidement tout l'écran (en faisant attention de ne pas effacer le menu) GLOBAL fonction_block Block; // Affiche rapidement un bloc à l'écran -GLOBAL fonction_block Block_Fast; // Affiche rapidement un bloc à l'écran sans rafraichir +GLOBAL fonction_block Block_Fast; // Affiche rapidement un bloc à l'écran sans rafraichir GLOBAL fonction_afficheur Pixel_Preview_Normal; // Affiche un point de l'image à l'Úcran en mode normal (pas en mode loupe) GLOBAL fonction_afficheur Pixel_Preview_Loupe; // Affiche un point de l'image à l'Úcran en mode loupe GLOBAL fonction_afficheur Pixel_Preview; // Affiche un point de l'image à l'Úcran en fonction de l'Útat du mode loupe @@ -212,6 +212,10 @@ GLOBAL short Principal_Decalage_Y; // D GLOBAL short Ancien_Principal_Decalage_X; GLOBAL short Ancien_Principal_Decalage_Y; +#ifdef __WATCOMC__ + GLOBAL char Principal_Drive_fichier[2]; +#endif + GLOBAL char Principal_Repertoire_fichier[256]; // |_ Nom complet = GLOBAL char Principal_Nom_fichier[13]; // | Repertoire_fichier+"\"+Nom_fichier GLOBAL byte Principal_Format_fichier; // Format auquel il faut lire et Úcrire le fichier diff --git a/graph.c b/graph.c index d4ad2450..f6c8aa7f 100644 --- a/graph.c +++ b/graph.c @@ -1,5895 +1,5905 @@ -#include "sdlscreen.h" -#include "graph.h" -#include "divers.h" -#include -#include - -#include -#include -#include -#include "moteur.h" -#include "boutons.h" -#include "pages.h" -#include "global.h" -#include "struct.h" -#include "erreurs.h" - -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>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ê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_XCoin_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é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'écran - - Temp=Fenetre_Hauteur*Menu_Facteur_Y; - - Remap_screen(Fenetre_Pos_X, Fenetre_Pos_Y, - Fenetre_Largeur*Menu_Facteur_X, - (Fenetre_Pos_Y+Temp255)) - Indice++; - - // On note la position de la première case de la séquence - Premier=Indice; - - // On recherche la position de la dernière case de la séquence - for (Dernier=Premier;Liste[Dernier+1]<256;Dernier++); - - // Pour toutes les cases non vides (et non inhibées) qui suivent - switch (Mode) - { - case MODE_SHADE_NORMAL : - for (;(Indice<512) && (Liste[Indice]<256);Indice++) - { // On met à 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 à 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 à 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Œ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Œ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 à la valeur entiè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 à la valeur entière supé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 (AB)?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ée de l'image par rapport à la partie zoomé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_imageMenu_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>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)=X_theorique) - { - Principal_Split-=Loupe_Facteur; - Principal_X_Zoom-=Loupe_Facteur; - } -} - - - -// -------------------- Calcul des information de la loupe ------------------- -void Calculer_donnees_loupe(void) -/* - Après modification des donné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=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é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é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 à 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 à 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_imageMode_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 à éviter les incohérences - Brouillon_Decalage_Y=0; // |- de décalage du brouillon par rapport à - Brouillon_Loupe_Mode=0; // | la résolution. - } - - Pixel_Preview=Pixel_Preview_Normal; - - Principal_Decalage_X=0; // Il faut quand même modifier ces valeurs à chaque - Principal_Decalage_Y=0; // fois car on n'est pas à l'abri d'une modification - // des dimensions de l'image. - Calculer_donnees_loupe(); - Calculer_limites(); - Calculer_coordonnees_pinceau(); -} - - -// -- Interface avec l'image, affectée par le facteur de grossissement ------- - - // fonction d'affichage "Pixel" utilisée pour les opérations définitivement - // Ne doit à aucune condition être appelée en dehors de la partie visible - // de l'image dans l'écran (ça pourrait ê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é. - // Les effets sont gérés par appel à Fonction_effet(). - // La Loupe est gérée par appel à 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êtres --------------------------------- - - // Affichage d'un pixel dans le menu (le menu doŒt ê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être (la fenêtre doŒt ê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érents cƒdres dans une fenêtre ----------------------- - - // -- Cadre général avec couleurs paramè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è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émité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émité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émité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émité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é 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é: clair en haut-gauche et foncé 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é 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 à 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>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>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+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é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é) - 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é) - 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=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Œne n'importe o— à l'é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=0) && (Pinceau_Y>=0) - && (Pinceau_X=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 (CFin) - 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)(Limite_Droite+1)) - { - (*Largeur)=(Limite_Droite-(*X))+1; - } - - if ((*Y)(Limite_Bas+1)) - { - (*Hauteur)=(Limite_Bas-(*Y))+1; - } -} - - // -- Calcul de redimensionnement du pinceau pour éviter les débordements - // de l'écran zoomé et de l'image -- - -void Calculer_dimensions_clipees_zoom(short * X,short * Y,short * Largeur,short * Hauteur) -{ - if ((*X)(Limite_Droite_Zoom+1)) - { - (*Largeur)=(Limite_Droite_Zoom-(*X))+1; - } - - if ((*Y)(Limite_Bas_Zoom+1)) - { - (*Hauteur)=(Limite_Bas_Zoom-(*Y))+1; - } -} - - - // -- Afficher le pinceau (de faç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 à appliquer au pinceau - // Preview: "Il ne faut l'afficher qu'à l'écran" -{ - short Debut_X; // Position X (dans l'image) à partir de laquelle on - // affiche la brosse/pinceau - short Debut_Y; // Position Y (dans l'image) à partir de laquelle on - // affiche la brosse/pinceau - short Largeur; // Largeur dans l'écran selon laquelle on affiche la - // brosse/pinceau - short Hauteur; // Hauteur dans l'écran selon laquelle on affiche la - // brosse/pinceau - short Debut_Compteur_X; // Position X (dans la brosse/pinceau) à partir - // de laquelle on affiche la brosse/pinceau - short Debut_Compteur_Y; // Position Y (dans la brosse/pinceau) à 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ête l'affichade de la - // brosse/pinceau - short Fin_Compteur_Y; // Position Y ou s'arrê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é & 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_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_Y0) && (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=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_Y0) && (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=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 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) à partir de laquelle on - // affiche la brosse/pinceau - short Debut_Y; // Position Y (dans l'image) à partir de laquelle on - // affiche la brosse/pinceau - short Largeur; // Largeur dans l'écran selon laquelle on affiche la - // brosse/pinceau - short Hauteur; // Hauteur dans l'écran selon laquelle on affiche la - // brosse/pinceau - short Debut_Compteur_X; // Position X (dans la brosse/pinceau) à partir - // de laquelle on affiche la brosse/pinceau - short Debut_Compteur_Y; // Position Y (dans la brosse/pinceau) à 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ête l'affichade de la brosse/pinceau - short Fin_Compteur_Y; // Position Y ou s'arrê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é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=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=0) && (Pos_YLargeur_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émité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=0) && (Pos_X=0) && (Pos_Y=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=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=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 être utilisé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ête l'affichage de la brosse/pinceau - //short Fin_Compteur_Y; // Position Y ou s'arrê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=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=0) && (Pos_YLargeur_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=0) && (Pos_X=0) && (Pos_Y=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=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=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 être utilisé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ê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ê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ée: /\/\/\--- - if (Loupe_Mode) - { - if (Principal_Largeur_image à 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; // <=> à 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;IndiceFin_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_XPrincipal_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>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éens "La couleur est utilisée" - int Couleur; - - - // On commence par initialiser le tableau de booléens à faux - for (Couleur=0;Couleur<=255;Couleur++) - Utilisee[Couleur]=0; - - // On calcule la table d'utilisation des couleurs - for (Pos_Y=0;Pos_Y>1); - Brosse_Decalage_Y=(Brosse_Hauteur>>1); - - free(Temporaire); // Libé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_Y0) - 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 à 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_X0) - 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é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! - } -} - - -#include "pages.c" - - -////////////////////////////////////////////////////////////////////////////// -////////////////////////////// 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ée de -// l'image. Les limites employé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éorie sur la couleur 1 et emploie la couleur 2 pour le -// remplissage. Ces restrictions sont d–es à 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 être directement appelée. -// -{ - short Pos_X; // Abscisse de balayage du segment, utilisée lors de l'"affichage" - short Ligne; // Ordonnée de la ligne en cours de traitement - short Debut_X; // Abscisse de départ du segment traité - short Fin_X; // Abscisse de fin du segment traité - int Modifs_effectuees; // Booléen "On a fait une modif dans le dernier passage" - int Propagation_possible; // Booléen "On peut propager la couleur dans le segment" - short Limite_courante_Bas; // Intervalle vertical restreint - short Limite_courante_Haut; - int Ligne_modifiee; // Boolé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 à la gauche de l'é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 à 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érie - // permet de colorier ce segment avec la couleur 2. - - Propagation_possible=( - // Test de la présence d'un point à gauche du segment - ((Debut_X>Limite_Gauche) && - (Lit_pixel_dans_ecran_courant(Debut_X-1,Ligne)==2)) || - // Test de la présence d'un point à droite du segment - ((Fin_X-1Limite_Haut)) - for (Pos_X=Debut_X;Pos_X*Limite_atteinte_Droite) - *Limite_atteinte_Droite=Fin_X; - // On remplit le segment de Debut_X à Fin_X-1. - for (Pos_X=Debut_X;Pos_XLimite_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 à la gauche de l'é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 à 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érie - // permet de colorier ce segment avec la couleur 2. - - Propagation_possible=( - // Test de la présence d'un point à gauche du segment - ((Debut_X>Limite_Gauche) && - (Lit_pixel_dans_ecran_courant(Debut_X-1,Ligne)==2)) || - // Test de la présence d'un point à droite du segment - ((Fin_X-1*Limite_atteinte_Droite) - *Limite_atteinte_Droite=Fin_X; - // On remplit le segment de Debut_X à Fin_X-1. - for (Pos_X=Debut_X;Pos_XLimite_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 à "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à caché. - // 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 "é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ête à faire des opérations qui nécessitent un affichage. Il - // faut donc retirer de l'é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 à ce à 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_BasLimite_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_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>=0) && - (Pos_X=0) && - (Pos_YLimite_Bas) - Fin_Y=Limite_Bas; - if (Debut_XLimite_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é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ées de l'ellipse sur chaque quart de l'ellipse: - for (Pos_Y=Debut_Y,Ellipse_Curseur_Y=-Rayon_vertical;Pos_YLimite_Bas) - Fin_Y=Limite_Bas; - if (Debut_XLimite_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é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_XDelta_X) - { - Cumul=Delta_Y>>1; - for (i=1; i=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) - { - 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_YFin_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ç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ç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çon à ce que ce - // ne soit pas toujours la dernière couleur qui soit affichée en dernier - // Pour ça, on part d'une couleur au pif dans une direction alé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é 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 éjecté la valeur hors - // des valeurs autorisées par le dégradé défini par l'utilisateur. - - if (Position<0) - Position=0; - else if (Position>=Degrade_Intervalle_bornes) - Position=Degrade_Intervalle_bornes-1; - - // On ramène ensuite la position dans le dégradé vers un numé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é 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ération: en plus de calculer la position de base (désignée - // dans cette procédure par "Position_dans_degrade", on calcule la position - // de l'indice dans le schéma suivant: - // - // Ú Les indices qui traŒnent de ce c“té du segment se voient subir - // ³ une incrémentation conditionnelle à leur position dans l'écran. - // v - // ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄúúú ú ú - // ^ - // ÀÄ Les indices qui traŒnent de ce c“té du segment se voient subir une - // décrémentation conditionnelle à leur position dans l'é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é - Position_dans_degrade/=Degrade_Intervalle_total; - - // On va pouvoir discuter de la valeur de Position_dans_degrade en fonction - // de la position dans l'é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 à traiter les cas 1 et 2 car ils représentent des valeurs - // suffisament au centre du segment pour ne pas avoir à 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és de la trame. - Position_dans_degrade++; - } - - // On va vérifier que nos petites idioties n'ont pas éjecté la valeur hors - // des valeurs autorisées par le dégradé 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ène ensuite la position dans le dégradé vers un numé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é par trames é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ération: en plus de calculer la position de base (désignée - // dans cette procédure par "Position_dans_degrade", on calcule la position - // de l'indice dans le schéma suivant: - // - // Ú Les indices qui traŒnent de ce c“té du segment se voient subir - // ³ une incrémentation conditionnelle à leur position dans l'écran. - // v - // ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄúúú ú ú - // ^ - // ÀÄ Les indices qui traŒnent de ce c“té du segment se voient subir une - // décrémentation conditionnelle à leur position dans l'é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é - Position_dans_degrade/=Degrade_Intervalle_total; - - // On va pouvoir discuter de la valeur de Position_dans_degrade en fonction - // de la position dans l'écran et de la Position_dans_segment. - - switch (Position_dans_segment) - { - case 0 : // On est sur l'extrê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 à traiter les cas 3 et 4 car ils représentent des valeurs - // suffisament au centre du segment pour ne pas avoir à 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és de la trame. - Position_dans_degrade++; - } - - // On va vérifier que nos petites idioties n'ont pas éjecté la valeur hors - // des valeurs autorisées par le dégradé 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ène ensuite la position dans le dégradé vers un numé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é (une sphè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é) sur les X du point en cours au centre d'éclairage - long Distance_Y; // Distance (au carré) sur les Y du point en cours au centre d'é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ès les limites - if (Debut_YLimite_Bas) - Fin_Y=Limite_Bas; - if (Debut_XLimite_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é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é) sur les X du point en cours au centre d'éclairage - long Distance_Y; // Distance (au carré) sur les Y du point en cours au centre d'é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ès les limites - if (Debut_YLimite_Bas) - Fin_Y=Limite_Bas; - if (Debut_XLimite_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“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; cbottom >= 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_XLimite_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; TemporaireFin_X) - Fin_X=Pos_X; - if (Pos_YFin_Y) - Fin_Y=Pos_Y; - } - - // On clippe ces bornes à l'écran: - if (Debut_XLimite_Droite) - Fin_X=Limite_Droite; - if (Debut_YLimite_Bas) - Fin_Y=Limite_Bas; - - // On ne capture la nouvelle brosse que si elle est au moins partiellement - // dans l'image: - - if ((Debut_XTAILLE_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>1); - Brosse_Decalage_Y=(Brosse_Hauteur>>1); - } -} - - - -//------------ Remplacement de la couleur pointée par une autre -------------- - -void Remplacer(byte Nouvelle_couleur) -{ - byte Ancienne_couleur; - - if ((Pinceau_X=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è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>16,Pos_Y_dans_brosse>>16); - // On passe à 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 à 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ération de mémoire n'a pas suffit donc on remet dans l'état - // o— c'etait avant. On a juste à réallouer la Smear_Brosse car il y a - // normalement la place pour elle puisque rien d'autre n'a pu être alloué - // 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é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_XDelta_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=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=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 égales à INDEFINI. - for (Y=0; Y>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è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é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ération de mémoire n'a pas suffit donc on remet dans l'état - // o— c'etait avant. On a juste à réallouer la Smear_Brosse car il y a - // normalement la place pour elle puisque rien d'autre n'a pu être alloué - // 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 égales à INDEFINI. - for (Y=0; YLimite_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_XLimite_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é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é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); -} +#include "sdlscreen.h" +#include "graph.h" +#include "divers.h" +#include +#include + +#include +#include +#include "moteur.h" +#include "boutons.h" +#include "pages.h" +#include "global.h" +#include "struct.h" +#include "erreurs.h" + +#ifdef __linux__ + #include +#elif __WATCOMC__ + #define _WIN32_WINNT 0x0500 + #include +#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>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ê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_XCoin_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é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'écran + + Temp=Fenetre_Hauteur*Menu_Facteur_Y; + + Remap_screen(Fenetre_Pos_X, Fenetre_Pos_Y, + Fenetre_Largeur*Menu_Facteur_X, + (Fenetre_Pos_Y+Temp255)) + Indice++; + + // On note la position de la première case de la séquence + Premier=Indice; + + // On recherche la position de la dernière case de la séquence + for (Dernier=Premier;Liste[Dernier+1]<256;Dernier++); + + // Pour toutes les cases non vides (et non inhibées) qui suivent + switch (Mode) + { + case MODE_SHADE_NORMAL : + for (;(Indice<512) && (Liste[Indice]<256);Indice++) + { // On met à 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 à 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 à 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Œ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Œ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 à la valeur entiè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 à la valeur entière supé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 (AB)?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ée de l'image par rapport à la partie zoomé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_imageMenu_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>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)=X_theorique) + { + Principal_Split-=Loupe_Facteur; + Principal_X_Zoom-=Loupe_Facteur; + } +} + + + +// -------------------- Calcul des information de la loupe ------------------- +void Calculer_donnees_loupe(void) +/* + Après modification des donné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=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é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é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 à 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 à 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_imageMode_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 à éviter les incohérences + Brouillon_Decalage_Y=0; // |- de décalage du brouillon par rapport à + Brouillon_Loupe_Mode=0; // | la résolution. + } + + Pixel_Preview=Pixel_Preview_Normal; + + Principal_Decalage_X=0; // Il faut quand même modifier ces valeurs à chaque + Principal_Decalage_Y=0; // fois car on n'est pas à l'abri d'une modification + // des dimensions de l'image. + Calculer_donnees_loupe(); + Calculer_limites(); + Calculer_coordonnees_pinceau(); +} + + +// -- Interface avec l'image, affectée par le facteur de grossissement ------- + + // fonction d'affichage "Pixel" utilisée pour les opérations définitivement + // Ne doit à aucune condition être appelée en dehors de la partie visible + // de l'image dans l'écran (ça pourrait ê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é. + // Les effets sont gérés par appel à Fonction_effet(). + // La Loupe est gérée par appel à 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êtres --------------------------------- + + // Affichage d'un pixel dans le menu (le menu doŒt ê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être (la fenêtre doŒt ê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érents cƒdres dans une fenêtre ----------------------- + + // -- Cadre général avec couleurs paramè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è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émité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émité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émité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émité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é 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é: clair en haut-gauche et foncé 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é 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 à 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>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>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+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é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é) + 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é) + 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=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Œne n'importe o— à l'é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=0) && (Pinceau_Y>=0) + && (Pinceau_X=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 (CFin) + 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)(Limite_Droite+1)) + { + (*Largeur)=(Limite_Droite-(*X))+1; + } + + if ((*Y)(Limite_Bas+1)) + { + (*Hauteur)=(Limite_Bas-(*Y))+1; + } +} + + // -- Calcul de redimensionnement du pinceau pour éviter les débordements + // de l'écran zoomé et de l'image -- + +void Calculer_dimensions_clipees_zoom(short * X,short * Y,short * Largeur,short * Hauteur) +{ + if ((*X)(Limite_Droite_Zoom+1)) + { + (*Largeur)=(Limite_Droite_Zoom-(*X))+1; + } + + if ((*Y)(Limite_Bas_Zoom+1)) + { + (*Hauteur)=(Limite_Bas_Zoom-(*Y))+1; + } +} + + + // -- Afficher le pinceau (de faç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 à appliquer au pinceau + // Preview: "Il ne faut l'afficher qu'à l'écran" +{ + short Debut_X; // Position X (dans l'image) à partir de laquelle on + // affiche la brosse/pinceau + short Debut_Y; // Position Y (dans l'image) à partir de laquelle on + // affiche la brosse/pinceau + short Largeur; // Largeur dans l'écran selon laquelle on affiche la + // brosse/pinceau + short Hauteur; // Hauteur dans l'écran selon laquelle on affiche la + // brosse/pinceau + short Debut_Compteur_X; // Position X (dans la brosse/pinceau) à partir + // de laquelle on affiche la brosse/pinceau + short Debut_Compteur_Y; // Position Y (dans la brosse/pinceau) à 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ête l'affichade de la + // brosse/pinceau + short Fin_Compteur_Y; // Position Y ou s'arrê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é & 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_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_Y0) && (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=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_Y0) && (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=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 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) à partir de laquelle on + // affiche la brosse/pinceau + short Debut_Y; // Position Y (dans l'image) à partir de laquelle on + // affiche la brosse/pinceau + short Largeur; // Largeur dans l'écran selon laquelle on affiche la + // brosse/pinceau + short Hauteur; // Hauteur dans l'écran selon laquelle on affiche la + // brosse/pinceau + short Debut_Compteur_X; // Position X (dans la brosse/pinceau) à partir + // de laquelle on affiche la brosse/pinceau + short Debut_Compteur_Y; // Position Y (dans la brosse/pinceau) à 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ête l'affichade de la brosse/pinceau + short Fin_Compteur_Y; // Position Y ou s'arrê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é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=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=0) && (Pos_YLargeur_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émité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=0) && (Pos_X=0) && (Pos_Y=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=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=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 être utilisé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ête l'affichage de la brosse/pinceau + //short Fin_Compteur_Y; // Position Y ou s'arrê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=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=0) && (Pos_YLargeur_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=0) && (Pos_X=0) && (Pos_Y=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=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=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 être utilisé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ê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ê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ée: /\/\/\--- + if (Loupe_Mode) + { + if (Principal_Largeur_image à 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; // <=> à 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;IndiceFin_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_XPrincipal_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>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éens "La couleur est utilisée" + int Couleur; + + + // On commence par initialiser le tableau de booléens à faux + for (Couleur=0;Couleur<=255;Couleur++) + Utilisee[Couleur]=0; + + // On calcule la table d'utilisation des couleurs + for (Pos_Y=0;Pos_Y>1); + Brosse_Decalage_Y=(Brosse_Hauteur>>1); + + free(Temporaire); // Libé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_Y0) + 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 à 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_X0) + 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é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! + } +} + + +#include "pages.c" + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////// 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ée de +// l'image. Les limites employé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éorie sur la couleur 1 et emploie la couleur 2 pour le +// remplissage. Ces restrictions sont d–es à 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 être directement appelée. +// +{ + short Pos_X; // Abscisse de balayage du segment, utilisée lors de l'"affichage" + short Ligne; // Ordonnée de la ligne en cours de traitement + short Debut_X; // Abscisse de départ du segment traité + short Fin_X; // Abscisse de fin du segment traité + int Modifs_effectuees; // Booléen "On a fait une modif dans le dernier passage" + int Propagation_possible; // Booléen "On peut propager la couleur dans le segment" + short Limite_courante_Bas; // Intervalle vertical restreint + short Limite_courante_Haut; + int Ligne_modifiee; // Boolé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 à la gauche de l'é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 à 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érie + // permet de colorier ce segment avec la couleur 2. + + Propagation_possible=( + // Test de la présence d'un point à gauche du segment + ((Debut_X>Limite_Gauche) && + (Lit_pixel_dans_ecran_courant(Debut_X-1,Ligne)==2)) || + // Test de la présence d'un point à droite du segment + ((Fin_X-1Limite_Haut)) + for (Pos_X=Debut_X;Pos_X*Limite_atteinte_Droite) + *Limite_atteinte_Droite=Fin_X; + // On remplit le segment de Debut_X à Fin_X-1. + for (Pos_X=Debut_X;Pos_XLimite_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 à la gauche de l'é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 à 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érie + // permet de colorier ce segment avec la couleur 2. + + Propagation_possible=( + // Test de la présence d'un point à gauche du segment + ((Debut_X>Limite_Gauche) && + (Lit_pixel_dans_ecran_courant(Debut_X-1,Ligne)==2)) || + // Test de la présence d'un point à droite du segment + ((Fin_X-1*Limite_atteinte_Droite) + *Limite_atteinte_Droite=Fin_X; + // On remplit le segment de Debut_X à Fin_X-1. + for (Pos_X=Debut_X;Pos_XLimite_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 à "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à caché. + // 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 "é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ête à faire des opérations qui nécessitent un affichage. Il + // faut donc retirer de l'é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 à ce à 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_BasLimite_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_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_XLimite_Bas) + Fin_Y=Limite_Bas; + if (Debut_XLimite_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é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ées de l'ellipse sur chaque quart de l'ellipse: + for (Pos_Y=Debut_Y,Ellipse_Curseur_Y=-Rayon_vertical;Pos_YLimite_Bas) + Fin_Y=Limite_Bas; + if (Debut_XLimite_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é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_XDelta_X) + { + Cumul=Delta_Y>>1; + for (i=1; i=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) + { + 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_YFin_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ç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ç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çon à ce que ce + // ne soit pas toujours la dernière couleur qui soit affichée en dernier + // Pour ça, on part d'une couleur au pif dans une direction alé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é 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 éjecté la valeur hors + // des valeurs autorisées par le dégradé défini par l'utilisateur. + + if (Position<0) + Position=0; + else if (Position>=Degrade_Intervalle_bornes) + Position=Degrade_Intervalle_bornes-1; + + // On ramène ensuite la position dans le dégradé vers un numé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é 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ération: en plus de calculer la position de base (désignée + // dans cette procédure par "Position_dans_degrade", on calcule la position + // de l'indice dans le schéma suivant: + // + // Ú Les indices qui traŒnent de ce c“té du segment se voient subir + // ³ une incrémentation conditionnelle à leur position dans l'écran. + // v + // ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄúúú ú ú + // ^ + // ÀÄ Les indices qui traŒnent de ce c“té du segment se voient subir une + // décrémentation conditionnelle à leur position dans l'é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é + Position_dans_degrade/=Degrade_Intervalle_total; + + // On va pouvoir discuter de la valeur de Position_dans_degrade en fonction + // de la position dans l'é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 à traiter les cas 1 et 2 car ils représentent des valeurs + // suffisament au centre du segment pour ne pas avoir à 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és de la trame. + Position_dans_degrade++; + } + + // On va vérifier que nos petites idioties n'ont pas éjecté la valeur hors + // des valeurs autorisées par le dégradé 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ène ensuite la position dans le dégradé vers un numé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é par trames é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ération: en plus de calculer la position de base (désignée + // dans cette procédure par "Position_dans_degrade", on calcule la position + // de l'indice dans le schéma suivant: + // + // Ú Les indices qui traŒnent de ce c“té du segment se voient subir + // ³ une incrémentation conditionnelle à leur position dans l'écran. + // v + // ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄúúú ú ú + // ^ + // ÀÄ Les indices qui traŒnent de ce c“té du segment se voient subir une + // décrémentation conditionnelle à leur position dans l'é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é + Position_dans_degrade/=Degrade_Intervalle_total; + + // On va pouvoir discuter de la valeur de Position_dans_degrade en fonction + // de la position dans l'écran et de la Position_dans_segment. + + switch (Position_dans_segment) + { + case 0 : // On est sur l'extrê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 à traiter les cas 3 et 4 car ils représentent des valeurs + // suffisament au centre du segment pour ne pas avoir à 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és de la trame. + Position_dans_degrade++; + } + + // On va vérifier que nos petites idioties n'ont pas éjecté la valeur hors + // des valeurs autorisées par le dégradé 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ène ensuite la position dans le dégradé vers un numé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é (une sphè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é) sur les X du point en cours au centre d'éclairage + long Distance_Y; // Distance (au carré) sur les Y du point en cours au centre d'é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ès les limites + if (Debut_YLimite_Bas) + Fin_Y=Limite_Bas; + if (Debut_XLimite_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é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é) sur les X du point en cours au centre d'éclairage + long Distance_Y; // Distance (au carré) sur les Y du point en cours au centre d'é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ès les limites + if (Debut_YLimite_Bas) + Fin_Y=Limite_Bas; + if (Debut_XLimite_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“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; cbottom >= 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_XLimite_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; TemporaireFin_X) + Fin_X=Pos_X; + if (Pos_YFin_Y) + Fin_Y=Pos_Y; + } + + // On clippe ces bornes à l'écran: + if (Debut_XLimite_Droite) + Fin_X=Limite_Droite; + if (Debut_YLimite_Bas) + Fin_Y=Limite_Bas; + + // On ne capture la nouvelle brosse que si elle est au moins partiellement + // dans l'image: + + if ((Debut_XTAILLE_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>1); + Brosse_Decalage_Y=(Brosse_Hauteur>>1); + } +} + + + +//------------ Remplacement de la couleur pointée par une autre -------------- + +void Remplacer(byte Nouvelle_couleur) +{ + byte Ancienne_couleur; + + if ((Pinceau_X=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è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>16,Pos_Y_dans_brosse>>16); + // On passe à 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 à 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ération de mémoire n'a pas suffit donc on remet dans l'état + // o— c'etait avant. On a juste à réallouer la Smear_Brosse car il y a + // normalement la place pour elle puisque rien d'autre n'a pu être alloué + // 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é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_XDelta_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=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=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 égales à INDEFINI. + for (Y=0; Y>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è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é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ération de mémoire n'a pas suffit donc on remet dans l'état + // o— c'etait avant. On a juste à réallouer la Smear_Brosse car il y a + // normalement la place pour elle puisque rien d'autre n'a pu être alloué + // 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 égales à INDEFINI. + for (Y=0; YLimite_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_XLimite_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é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é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); +} diff --git a/init.c b/init.c index 3374f099..33ddbfe7 100644 --- a/init.c +++ b/init.c @@ -1,2240 +1,2267 @@ -#define TAILLE_FICHIER_DATA 84369 // Taille du fichier GFX2.DAT - -#include -#include "const.h" -#include "struct.h" -#include "global.h" -#include "modesvdo.h" -#include "graph.h" -#include "boutons.h" -#include "palette.h" -#include "aide.h" -#include "operatio.h" -#include - -#include -#include -#include -#include -#include -#include -#include "divers.h" - -#include "errno.h" -#include -#include - -// On déclare méchamment le prototype de Erreur pour éviter de faire un -// fichier "main.h": -void Erreur(int Code); - -// Chercher le répertoire contenant GFX2.EXE -void Chercher_repertoire_du_programme(char * Chaine) -{ - /*int Position; - - strcpy(Repertoire_du_programme,Chaine); - for (Position=strlen(Repertoire_du_programme);Repertoire_du_programme[Position]!='/';Position--); //sous linux c'est un /, sous windows c'est \\ - Repertoire_du_programme[Position+1]='\0';*/ - puts("Chercher_repertoire_du_programme: implémentation incomplète"); - Repertoire_du_programme[0]=0; //On va travailler dans le dossier courant ... -} - - -word Drive_Touche[26]= -{ - 0x041E, - 0x0430, - 0x042E, - 0x0420, - 0x0412, - 0x0421, - 0x0422, - 0x0423, - 0x0417, - 0x0424, - 0x0425, - 0x0426, - 0x0432, - 0x0431, - 0x0418, - 0x0419, - 0x0410, - 0x0413, - 0x041F, - 0x0414, - 0x0416, - 0x042F, - 0x0411, - 0x042D, - 0x0415, - 0x042C -}; - -// Ajouter un lecteur à la liste de lecteurs -void Ajouter_lecteur(byte Numero, byte Type) -{ - Drive[Nb_drives].Lettre=Numero+65; - Drive[Nb_drives].Type =Type; - Drive[Nb_drives].Touche=Drive_Touche[Numero]; - - Nb_drives++; -} - - -// Rechercher la liste et le type des lecteurs de la machine -void Rechercher_drives(void) -{ -/* - byte Lecteur; - byte Nb_lecteurs_disquettes; - byte Lecteur_de_disquettes; - byte Type_de_lecteur=42; - //char Bidon[256]; - - Nb_drives=0; - Nb_lecteurs_disquettes=(Type_de_lecteur_de_disquette(0)>0)+(Type_de_lecteur_de_disquette(1)>0); - - // Test du type des lecteurs A: et B: - if (Nb_lecteurs_disquettes==2) - for (Lecteur=0; Lecteur<=1; Lecteur++) - { - switch (Type_de_lecteur_de_disquette(Lecteur)) - { - case 1 : - case 2 : - Ajouter_lecteur(Lecteur,DRIVE_FLOPPY_5_25); - break; - default: - Ajouter_lecteur(Lecteur,DRIVE_FLOPPY_3_5); - } - } - else // On n'a pas 2 lecteurs donc on regarde si "logiquement" c'est A: ou B: - if (Nb_lecteurs_disquettes==1) - { - if (Disk_map(2)==Disk_map(1)) - { - // Il n'y a pas de lecteur émulé par un SUBST - Lecteur_de_disquettes=Disk_map(1)-1; - for (Lecteur=0; Lecteur<=1; Lecteur++) - { - switch (Type_de_lecteur_de_disquette(Lecteur)) - { - case 0 : - break; - case 1 : - case 2 : - Ajouter_lecteur(Lecteur_de_disquettes,DRIVE_FLOPPY_5_25); - break; - default: - Ajouter_lecteur(Lecteur_de_disquettes,DRIVE_FLOPPY_3_5); - } - } - } - else - { - // Il y a un lecteur émulé par un SUBST - Lecteur_de_disquettes=Disk_map(1)-1; - - // On cherche d'abord sur quel lecteur le lecteur physique est dispo - for (Lecteur=0; Lecteur<=1; Lecteur++) - { - switch (Type_de_lecteur_de_disquette(Lecteur)) - { - case 0 : - break; - case 1 : - case 2 : - Type_de_lecteur=DRIVE_FLOPPY_5_25; - break; - default: - Type_de_lecteur=DRIVE_FLOPPY_3_5; - } - } - - // On déclare les trucs maintenant - if (Lecteur_de_disquettes==0) - { - // Situation : On a un lecteur A: qui est réel et un lecteur B: émulé - Ajouter_lecteur(0,Type_de_lecteur); - Ajouter_lecteur(1,DRIVE_NETWORK); - } - else - { - // Situation : On a un lecteur A: qui est réel et un lecteur B: émulé - Ajouter_lecteur(0,DRIVE_NETWORK); - Ajouter_lecteur(1,Type_de_lecteur); - } - } - } - else - // Il n'y a pas de lecteur de D7 physique, mais on vérifie s'il n'y en a - // pas qui seraient émulés par SUBST - for (Lecteur=0; Lecteur<=1; Lecteur++) - { - switch (Freespace(Lecteur+1)) - { - case -1: - break; - default: - Ajouter_lecteur(Lecteur,DRIVE_NETWORK); - } - } - - // Test de la présence d'autres lecteurs (HDD, CD, Réseau) - // On les met tous en réseau avant de tester leur vrai type. - for (Lecteur=2; Lecteur<=25; Lecteur++) - { - if (Disque_dur_present(Lecteur-2)) - Ajouter_lecteur(Lecteur,DRIVE_HDD); - else - if (Lecteur_CDROM_present(Lecteur)) - Ajouter_lecteur(Lecteur,DRIVE_CDROM); - else - if (Freespace(Lecteur+1)!=-1) - Ajouter_lecteur(Lecteur,DRIVE_NETWORK); - } -*/ -//Sous linux, il n'y a pas de lecteurs, on va juste mettre un disque dur qui pointera vers la racine -Ajouter_lecteur(0,DRIVE_HDD); //Le lecteur numéro 0 est un disque dur. -} - - -// Fonction de décryptage - - #define DECRYPT_TAILLE_CLE 14 - byte Decrypt_compteur=0; - char Decrypt_cle[DECRYPT_TAILLE_CLE]="Sunset Design"; - - byte Decrypt(byte Octet) - { - byte Temp; - - Temp=Octet ^ Decrypt_cle[Decrypt_compteur]; - if ((++Decrypt_compteur)>=(DECRYPT_TAILLE_CLE-1)) - Decrypt_compteur=0; - return Temp; - } - -// Décryptage d'une donnée - -void Decrypte(byte * Donnee,int Taille) -{ - int Indice; - - for (Indice=0;Indice>Pos_X)) ? 1 : 0); - - // Lecture de la fonte alternative - if (read(Handle,Fonte_temporaire,2048)!=2048) - Erreur(ERREUR_DAT_CORROMPU); - Decrypte(Fonte_temporaire,2048); - for (Indice=0;Indice<256;Indice++) - for (Pos_X=0;Pos_X<8;Pos_X++) - for (Pos_Y=0;Pos_Y<8;Pos_Y++) - Fonte_fun[(Indice<<6)+(Pos_X<<3)+Pos_Y]=( ((*(Fonte_temporaire+(Indice*8)+Pos_Y))&(0x80>>Pos_X)) ? 1 : 0); - - free(Fonte_temporaire); - - Fonte=Fonte_systeme; - - // Lecture de la fonte 6x8: (spéciale aide) - if (read(Handle,Fonte_help,(315*6*8))!=(315*6*8)) - Erreur(ERREUR_DAT_CORROMPU); - Decrypte((byte*)Fonte_help,(315*6*8)); - - // Lecture des différentes sections de l'aide: - - // Pour chaque section "Indice" de l'aide: - for (Indice=0;Indice>1); - Pinceau_predefini_Decalage_Y[Indice]=(Pinceau_predefini_Hauteur[Indice]>>1); - } - - Curseur_Decalage_X[FORME_CURSEUR_FLECHE]=0; - Curseur_Decalage_Y[FORME_CURSEUR_FLECHE]=0; - - Curseur_Decalage_X[FORME_CURSEUR_CIBLE]=7; - Curseur_Decalage_Y[FORME_CURSEUR_CIBLE]=7; - - Curseur_Decalage_X[FORME_CURSEUR_CIBLE_PIPETTE]=7; - Curseur_Decalage_Y[FORME_CURSEUR_CIBLE_PIPETTE]=7; - - Curseur_Decalage_X[FORME_CURSEUR_SABLIER]=7; - Curseur_Decalage_Y[FORME_CURSEUR_SABLIER]=7; - - Curseur_Decalage_X[FORME_CURSEUR_MULTIDIRECTIONNEL]=7; - Curseur_Decalage_Y[FORME_CURSEUR_MULTIDIRECTIONNEL]=7; - - Curseur_Decalage_X[FORME_CURSEUR_HORIZONTAL]=7; - Curseur_Decalage_Y[FORME_CURSEUR_HORIZONTAL]=3; - - Curseur_Decalage_X[FORME_CURSEUR_CIBLE_FINE]=7; - Curseur_Decalage_Y[FORME_CURSEUR_CIBLE_FINE]=7; - - Curseur_Decalage_X[FORME_CURSEUR_CIBLE_PIPETTE_FINE]=7; - Curseur_Decalage_Y[FORME_CURSEUR_CIBLE_PIPETTE_FINE]=7; -} - - -// Initialisation des boutons: - - // Action factice: - -void Rien_du_tout(void) -{} - - // Initialiseur d'un bouton: - -void Initialiser_bouton(byte Numero, - word Decalage_X , word Decalage_Y, - word Largeur , word Hauteur, - byte Forme, - fonction_action Gauche , fonction_action Droite, - fonction_action Desenclencher, - byte Famille) -{ - Bouton[Numero].Decalage_X =Decalage_X; - Bouton[Numero].Decalage_Y =Decalage_Y; - Bouton[Numero].Largeur =Largeur-1; - Bouton[Numero].Hauteur =Hauteur-1; - Bouton[Numero].Enfonce =0; - Bouton[Numero].Forme =Forme; - Bouton[Numero].Gauche =Gauche; - Bouton[Numero].Droite =Droite; - Bouton[Numero].Desenclencher =Desenclencher; - Bouton[Numero].Famille =Famille; -} - - - // Initiliseur de tous les boutons: - -void Initialisation_des_boutons(void) -{ - byte Indice_bouton; - - for (Indice_bouton=0;Indice_bouton>8) - { - case 0 : - Config_Touche[Ordonnancement[Indice2]&0xFF]=CFG_Infos_touche.Touche; - break; - case 1 : - Bouton[Ordonnancement[Indice2]&0xFF].Raccourci_gauche = CFG_Infos_touche.Touche; - break; - case 2 : - Bouton[Ordonnancement[Indice2]&0xFF].Raccourci_droite = CFG_Infos_touche.Touche; - break; - } - } - else - goto Erreur_lecture_config; - } - } - } - else - { - if (lseek(Handle,Chunk.Taille,SEEK_CUR)==-1) - goto Erreur_lecture_config; - } - break; - case CHUNK_MODES_VIDEO: // Modes vidéo - if ((Chunk.Taille/5/*sizeof(CFG_Mode_video)*/)!=NB_MODES_VIDEO) - goto Erreur_lecture_config; - for (Indice=1; Indice<=NB_MODES_VIDEO; Indice++) - { - read(Handle,&(CFG_Mode_video.Etat),1); - read(Handle,&(CFG_Mode_video.Largeur),2); - if (read(Handle,&(CFG_Mode_video.Hauteur),2)!=2) - goto Erreur_lecture_config; - else - { - for (Indice2=0; - ( (Indice2>6)) ) ); - Indice2++); - if (Indice2>8) - { - case 0 : CFG_Infos_touche.Touche=Config_Touche[Ordonnancement[Indice]&0xFF]; break; - case 1 : CFG_Infos_touche.Touche=Bouton[Ordonnancement[Indice]&0xFF].Raccourci_gauche; break; - case 2 : CFG_Infos_touche.Touche=Bouton[Ordonnancement[Indice]&0xFF].Raccourci_droite; break; - } - CFG_Infos_touche.Touche2=0x00FF; - #if __BYTE_ORDER == __BIG_ENDIAN - CFG_Infos_touche.Touche=bswap_16(CFG_Infos_touche.Touche); - CFG_Infos_touche.Touche2=bswap_16(CFG_Infos_touche.Touche2); - CFG_Infos_touche.Numero=bswap_16(CFG_Infos_touche.Numero); - #endif - if (write(Handle,&CFG_Infos_touche,sizeof(CFG_Infos_touche))!=sizeof(CFG_Infos_touche)) - goto Erreur_sauvegarde_config; - } - - // Sauvegarde de l'état de chaque mode vidéo - Chunk.Numero=CHUNK_MODES_VIDEO; - Chunk.Taille=NB_MODES_VIDEO*5 /*sizeof(CFG_Mode_video)*/; - #if __BYTE_ORDER == __BIG_ENDIAN - //On remet les octets dans l'ordre "normal" - Chunk.Taille=bswap_16(Chunk.Taille); - #endif - if (write(Handle,&(Chunk.Numero),sizeof(byte))!=sizeof(byte)||write(Handle,&(Chunk.Taille),sizeof(word))!=sizeof(word)) - goto Erreur_sauvegarde_config; - for (Indice=0; Indice +#include "const.h" +#include "struct.h" +#include "global.h" +#include "modesvdo.h" +#include "graph.h" +#include "boutons.h" +#include "palette.h" +#include "aide.h" +#include "operatio.h" +#include + +#include +#include +#include +#include +#include +#include +#include "divers.h" + +#include "errno.h" + +#ifdef __linux__ + #include + #include +#endif + +// On déclare méchamment le prototype de Erreur pour éviter de faire un +// fichier "main.h": +void Erreur(int Code); + +// Chercher le répertoire contenant GFX2.EXE +void Chercher_repertoire_du_programme(char * Chaine) +{ + /*int Position; + + strcpy(Repertoire_du_programme,Chaine); + for (Position=strlen(Repertoire_du_programme);Repertoire_du_programme[Position]!='/';Position--); //sous linux c'est un /, sous windows c'est \\ + Repertoire_du_programme[Position+1]='\0';*/ + puts("Chercher_repertoire_du_programme: implémentation incomplète"); + Repertoire_du_programme[0]=0; //On va travailler dans le dossier courant ... +} + + +word Drive_Touche[26]= +{ + 0x041E, + 0x0430, + 0x042E, + 0x0420, + 0x0412, + 0x0421, + 0x0422, + 0x0423, + 0x0417, + 0x0424, + 0x0425, + 0x0426, + 0x0432, + 0x0431, + 0x0418, + 0x0419, + 0x0410, + 0x0413, + 0x041F, + 0x0414, + 0x0416, + 0x042F, + 0x0411, + 0x042D, + 0x0415, + 0x042C +}; + +// Ajouter un lecteur à la liste de lecteurs +void Ajouter_lecteur(byte Numero, byte Type) +{ + Drive[Nb_drives].Lettre=Numero+65; + Drive[Nb_drives].Type =Type; + Drive[Nb_drives].Touche=Drive_Touche[Numero]; + + Nb_drives++; +} + + +// Rechercher la liste et le type des lecteurs de la machine +void Rechercher_drives(void) +{ +/* + byte Lecteur; + byte Nb_lecteurs_disquettes; + byte Lecteur_de_disquettes; + byte Type_de_lecteur=42; + //char Bidon[256]; + + Nb_drives=0; + Nb_lecteurs_disquettes=(Type_de_lecteur_de_disquette(0)>0)+(Type_de_lecteur_de_disquette(1)>0); + + // Test du type des lecteurs A: et B: + if (Nb_lecteurs_disquettes==2) + for (Lecteur=0; Lecteur<=1; Lecteur++) + { + switch (Type_de_lecteur_de_disquette(Lecteur)) + { + case 1 : + case 2 : + Ajouter_lecteur(Lecteur,DRIVE_FLOPPY_5_25); + break; + default: + Ajouter_lecteur(Lecteur,DRIVE_FLOPPY_3_5); + } + } + else // On n'a pas 2 lecteurs donc on regarde si "logiquement" c'est A: ou B: + if (Nb_lecteurs_disquettes==1) + { + if (Disk_map(2)==Disk_map(1)) + { + // Il n'y a pas de lecteur émulé par un SUBST + Lecteur_de_disquettes=Disk_map(1)-1; + for (Lecteur=0; Lecteur<=1; Lecteur++) + { + switch (Type_de_lecteur_de_disquette(Lecteur)) + { + case 0 : + break; + case 1 : + case 2 : + Ajouter_lecteur(Lecteur_de_disquettes,DRIVE_FLOPPY_5_25); + break; + default: + Ajouter_lecteur(Lecteur_de_disquettes,DRIVE_FLOPPY_3_5); + } + } + } + else + { + // Il y a un lecteur émulé par un SUBST + Lecteur_de_disquettes=Disk_map(1)-1; + + // On cherche d'abord sur quel lecteur le lecteur physique est dispo + for (Lecteur=0; Lecteur<=1; Lecteur++) + { + switch (Type_de_lecteur_de_disquette(Lecteur)) + { + case 0 : + break; + case 1 : + case 2 : + Type_de_lecteur=DRIVE_FLOPPY_5_25; + break; + default: + Type_de_lecteur=DRIVE_FLOPPY_3_5; + } + } + + // On déclare les trucs maintenant + if (Lecteur_de_disquettes==0) + { + // Situation : On a un lecteur A: qui est réel et un lecteur B: émulé + Ajouter_lecteur(0,Type_de_lecteur); + Ajouter_lecteur(1,DRIVE_NETWORK); + } + else + { + // Situation : On a un lecteur A: qui est réel et un lecteur B: émulé + Ajouter_lecteur(0,DRIVE_NETWORK); + Ajouter_lecteur(1,Type_de_lecteur); + } + } + } + else + // Il n'y a pas de lecteur de D7 physique, mais on vérifie s'il n'y en a + // pas qui seraient émulés par SUBST + for (Lecteur=0; Lecteur<=1; Lecteur++) + { + switch (Freespace(Lecteur+1)) + { + case -1: + break; + default: + Ajouter_lecteur(Lecteur,DRIVE_NETWORK); + } + } + + // Test de la présence d'autres lecteurs (HDD, CD, Réseau) + // On les met tous en réseau avant de tester leur vrai type. + for (Lecteur=2; Lecteur<=25; Lecteur++) + { + if (Disque_dur_present(Lecteur-2)) + Ajouter_lecteur(Lecteur,DRIVE_HDD); + else + if (Lecteur_CDROM_present(Lecteur)) + Ajouter_lecteur(Lecteur,DRIVE_CDROM); + else + if (Freespace(Lecteur+1)!=-1) + Ajouter_lecteur(Lecteur,DRIVE_NETWORK); + } +*/ +//Sous linux, il n'y a pas de lecteurs, on va juste mettre un disque dur qui pointera vers la racine +Ajouter_lecteur(0,DRIVE_HDD); //Le lecteur numéro 0 est un disque dur. +} + + +// Fonction de décryptage + + #define DECRYPT_TAILLE_CLE 14 + byte Decrypt_compteur=0; + char Decrypt_cle[DECRYPT_TAILLE_CLE]="Sunset Design"; + + byte Decrypt(byte Octet) + { + byte Temp; + + Temp=Octet ^ Decrypt_cle[Decrypt_compteur]; + if ((++Decrypt_compteur)>=(DECRYPT_TAILLE_CLE-1)) + Decrypt_compteur=0; + return Temp; + } + +// Décryptage d'une donnée + +void Decrypte(byte * Donnee,int Taille) +{ + int Indice; + + for (Indice=0;Indice>Pos_X)) ? 1 : 0); + + // Lecture de la fonte alternative + if (read(Handle,Fonte_temporaire,2048)!=2048) + Erreur(ERREUR_DAT_CORROMPU); + Decrypte(Fonte_temporaire,2048); + for (Indice=0;Indice<256;Indice++) + for (Pos_X=0;Pos_X<8;Pos_X++) + for (Pos_Y=0;Pos_Y<8;Pos_Y++) + Fonte_fun[(Indice<<6)+(Pos_X<<3)+Pos_Y]=( ((*(Fonte_temporaire+(Indice*8)+Pos_Y))&(0x80>>Pos_X)) ? 1 : 0); + + free(Fonte_temporaire); + + Fonte=Fonte_systeme; + + // Lecture de la fonte 6x8: (spéciale aide) + if (read(Handle,Fonte_help,(315*6*8))!=(315*6*8)) + Erreur(ERREUR_DAT_CORROMPU); + Decrypte((byte*)Fonte_help,(315*6*8)); + + // Lecture des différentes sections de l'aide: + + // Pour chaque section "Indice" de l'aide: + for (Indice=0;Indice>1); + Pinceau_predefini_Decalage_Y[Indice]=(Pinceau_predefini_Hauteur[Indice]>>1); + } + + Curseur_Decalage_X[FORME_CURSEUR_FLECHE]=0; + Curseur_Decalage_Y[FORME_CURSEUR_FLECHE]=0; + + Curseur_Decalage_X[FORME_CURSEUR_CIBLE]=7; + Curseur_Decalage_Y[FORME_CURSEUR_CIBLE]=7; + + Curseur_Decalage_X[FORME_CURSEUR_CIBLE_PIPETTE]=7; + Curseur_Decalage_Y[FORME_CURSEUR_CIBLE_PIPETTE]=7; + + Curseur_Decalage_X[FORME_CURSEUR_SABLIER]=7; + Curseur_Decalage_Y[FORME_CURSEUR_SABLIER]=7; + + Curseur_Decalage_X[FORME_CURSEUR_MULTIDIRECTIONNEL]=7; + Curseur_Decalage_Y[FORME_CURSEUR_MULTIDIRECTIONNEL]=7; + + Curseur_Decalage_X[FORME_CURSEUR_HORIZONTAL]=7; + Curseur_Decalage_Y[FORME_CURSEUR_HORIZONTAL]=3; + + Curseur_Decalage_X[FORME_CURSEUR_CIBLE_FINE]=7; + Curseur_Decalage_Y[FORME_CURSEUR_CIBLE_FINE]=7; + + Curseur_Decalage_X[FORME_CURSEUR_CIBLE_PIPETTE_FINE]=7; + Curseur_Decalage_Y[FORME_CURSEUR_CIBLE_PIPETTE_FINE]=7; +} + + +// Initialisation des boutons: + + // Action factice: + +void Rien_du_tout(void) +{} + + // Initialiseur d'un bouton: + +void Initialiser_bouton(byte Numero, + word Decalage_X , word Decalage_Y, + word Largeur , word Hauteur, + byte Forme, + fonction_action Gauche , fonction_action Droite, + fonction_action Desenclencher, + byte Famille) +{ + Bouton[Numero].Decalage_X =Decalage_X; + Bouton[Numero].Decalage_Y =Decalage_Y; + Bouton[Numero].Largeur =Largeur-1; + Bouton[Numero].Hauteur =Hauteur-1; + Bouton[Numero].Enfonce =0; + Bouton[Numero].Forme =Forme; + Bouton[Numero].Gauche =Gauche; + Bouton[Numero].Droite =Droite; + Bouton[Numero].Desenclencher =Desenclencher; + Bouton[Numero].Famille =Famille; +} + + + // Initiliseur de tous les boutons: + +void Initialisation_des_boutons(void) +{ + byte Indice_bouton; + + for (Indice_bouton=0;Indice_bouton>8) + { + case 0 : + Config_Touche[Ordonnancement[Indice2]&0xFF]=CFG_Infos_touche.Touche; + break; + case 1 : + Bouton[Ordonnancement[Indice2]&0xFF].Raccourci_gauche = CFG_Infos_touche.Touche; + break; + case 2 : + Bouton[Ordonnancement[Indice2]&0xFF].Raccourci_droite = CFG_Infos_touche.Touche; + break; + } + } + else + goto Erreur_lecture_config; + } + } + } + else + { + if (lseek(Handle,Chunk.Taille,SEEK_CUR)==-1) + goto Erreur_lecture_config; + } + break; + case CHUNK_MODES_VIDEO: // Modes vidéo + if ((Chunk.Taille/5/*sizeof(CFG_Mode_video)*/)!=NB_MODES_VIDEO) + goto Erreur_lecture_config; + for (Indice=1; Indice<=NB_MODES_VIDEO; Indice++) + { + read(Handle,&(CFG_Mode_video.Etat),1); + read(Handle,&(CFG_Mode_video.Largeur),2); + if (read(Handle,&(CFG_Mode_video.Hauteur),2)!=2) + goto Erreur_lecture_config; + else + { + for (Indice2=0; + ( (Indice2>6)) ) ); + Indice2++); + if (Indice2>8) + { + case 0 : CFG_Infos_touche.Touche=Config_Touche[Ordonnancement[Indice]&0xFF]; break; + case 1 : CFG_Infos_touche.Touche=Bouton[Ordonnancement[Indice]&0xFF].Raccourci_gauche; break; + case 2 : CFG_Infos_touche.Touche=Bouton[Ordonnancement[Indice]&0xFF].Raccourci_droite; break; + } + CFG_Infos_touche.Touche2=0x00FF; + #ifndef __WATCOMC__ + #if __BYTE_ORDER == __BIG_ENDIAN + CFG_Infos_touche.Touche=bswap_16(CFG_Infos_touche.Touche); + CFG_Infos_touche.Touche2=bswap_16(CFG_Infos_touche.Touche2); + CFG_Infos_touche.Numero=bswap_16(CFG_Infos_touche.Numero); + #endif + #endif + if (write(Handle,&CFG_Infos_touche,sizeof(CFG_Infos_touche))!=sizeof(CFG_Infos_touche)) + goto Erreur_sauvegarde_config; + } + + // Sauvegarde de l'état de chaque mode vidéo + Chunk.Numero=CHUNK_MODES_VIDEO; + Chunk.Taille=NB_MODES_VIDEO*5 /*sizeof(CFG_Mode_video)*/; + #ifndef __WATCOMC__ + #if __BYTE_ORDER == __BIG_ENDIAN + //On remet les octets dans l'ordre "normal" + Chunk.Taille=bswap_16(Chunk.Taille); + #endif + #endif + if (write(Handle,&(Chunk.Numero),sizeof(byte))!=sizeof(byte)||write(Handle,&(Chunk.Taille),sizeof(word))!=sizeof(word)) + goto Erreur_sauvegarde_config; + for (Indice=0; Indice #include "boutons.h" -#include "linux.h" +#ifdef __linux__ + #include "linux.h" +#endif // On déclare méchamment le prototype de Erreur pour éviter de faire un // fichier "main.h": @@ -323,7 +325,7 @@ void Nom_fichier_complet(char * Nom_du_fichier, byte Sauve_Colorix) //On va ajouter un / à la fin du chemin s'il n'y est pas encore //Attention sous windows il faut un \... if (Nom_du_fichier[strlen(Nom_du_fichier)-1]!='/') - strcat(Nom_du_fichier,"/"); + strcat(Nom_du_fichier,"/"); // Si on est en train de sauvegarder une image Colorix, on calcule son ext. if (Sauve_Colorix) @@ -695,9 +697,9 @@ void Save_PAL(void) close(Fichier); remove(Nom_du_fichier); // On se fout du résultat de l'opération car si ‡a - // renvoie 0 c'est que le fichier avait été partiel- - // -lement écrit, sinon pas du tout. Or dans tous les - // cas ‡a revient au mˆme pour nous: Sauvegarde ratée! + // renvoie 0 c'est que le fichier avait été partiel- + // -lement écrit, sinon pas du tout. Or dans tous les + // cas ‡a revient au mˆme pour nous: Sauvegarde ratée! } } @@ -901,15 +903,15 @@ void Test_PKM(void) { char Ident[3]; // ChaŒne "PKM" } byte Methode; // Méthode de compression: - // 0 = compression en ligne (c)KM - // autres = inconnues pour le moment + // 0 = compression en ligne (c)KM + // autres = inconnues pour le moment byte Recon1; // Octet de reconnaissance sur 1 octet } byte Recon2; // Octet de reconnaissance sur 2 octets } word Largeur; // Largeur de l'image word Hauteur; // Hauteur de l'image T_Palette Palette; // Palette RVB 256*3 word Jump; // Taille du saut entre le header et l'image: - // On va s'en servir pour rajouter un commentaire + // On va s'en servir pour rajouter un commentaire } Head; @@ -1160,8 +1162,8 @@ void Load_PKM(void) for (Indice=1;Indice<=255;Indice++) if (Find_recon[Indice]2) && (Compteur_de_repetitions<256) ) - { // RECON1/couleur/nombre - Ecrire_octet(Fichier,Head.Recon1); - Ecrire_octet(Fichier,Derniere_couleur); - Ecrire_octet(Fichier,Compteur_de_repetitions&0xFF); - } + if ( (Compteur_de_repetitions>2) && (Compteur_de_repetitions<256) ) + { // RECON1/couleur/nombre + Ecrire_octet(Fichier,Head.Recon1); + Ecrire_octet(Fichier,Derniere_couleur); + Ecrire_octet(Fichier,Compteur_de_repetitions&0xFF); + } else - if (Compteur_de_repetitions>=256) - { // RECON2/couleur/hi(nombre)/lo(nombre) - Ecrire_octet(Fichier,Head.Recon2); - Ecrire_octet(Fichier,Derniere_couleur); - Ecrire_octet(Fichier,Compteur_de_repetitions>>8); - Ecrire_octet(Fichier,Compteur_de_repetitions&0xFF); - } + if (Compteur_de_repetitions>=256) + { // RECON2/couleur/hi(nombre)/lo(nombre) + Ecrire_octet(Fichier,Head.Recon2); + Ecrire_octet(Fichier,Derniere_couleur); + Ecrire_octet(Fichier,Compteur_de_repetitions>>8); + Ecrire_octet(Fichier,Compteur_de_repetitions&0xFF); + } } else { - if (Compteur_de_repetitions<256) + if (Compteur_de_repetitions<256) { - Ecrire_octet(Fichier,Head.Recon1); - Ecrire_octet(Fichier,Derniere_couleur); - Ecrire_octet(Fichier,Compteur_de_repetitions&0xFF); - } - else - { - Ecrire_octet(Fichier,Head.Recon2); - Ecrire_octet(Fichier,Derniere_couleur); - Ecrire_octet(Fichier,Compteur_de_repetitions>>8); - Ecrire_octet(Fichier,Compteur_de_repetitions&0xFF); - } + Ecrire_octet(Fichier,Head.Recon1); + Ecrire_octet(Fichier,Derniere_couleur); + Ecrire_octet(Fichier,Compteur_de_repetitions&0xFF); + } + else + { + Ecrire_octet(Fichier,Head.Recon2); + Ecrire_octet(Fichier,Derniere_couleur); + Ecrire_octet(Fichier,Compteur_de_repetitions>>8); + Ecrire_octet(Fichier,Compteur_de_repetitions&0xFF); + } } } @@ -1887,7 +1889,7 @@ void Load_LBM(void) if (LBM_Mode_repetition) { Ecrire_octet(LBM_Fichier,257-LBM_Taille_de_file); - Ecrire_octet(LBM_Fichier,LBM_File_de_couleurs[0]); + Ecrire_octet(LBM_Fichier,LBM_File_de_couleurs[0]); } else { @@ -1927,7 +1929,7 @@ void Load_LBM(void) // On conserve le mode... { LBM_File_de_couleurs[LBM_Taille_de_file]=Couleur; - LBM_Taille_de_file++; + LBM_Taille_de_file++; if (LBM_Taille_de_file==128) Transferer_couleurs(); } diff --git a/main.c b/main.c index 4847bd54..a6fe216b 100644 --- a/main.c +++ b/main.c @@ -1,627 +1,647 @@ -#define VARIABLES_GLOBALES - -#include "const.h" -#include "struct.h" -#include "global.h" -#include "graph.h" -#include "divers.h" -#include "init.h" -#include "boutons.h" -#include "moteur.h" -#include -#include - -#include -#include -#include -#include -#include -#include "linux.h" //Fichier avec diverses fonctions qui existaient sous dos mais pas sous linux... -#include "pages.h" -#include "files.h" -#include "loadsave.h" -#include "sdlscreen.h" -#include "erreurs.h" - -byte Ancien_nb_lignes; // Ancien nombre de lignes de l'écran - - -//--- Affichage de la syntaxe, et de la liste des modes vidéos disponibles --- -void Afficher_syntaxe(void) -{ - printf("Syntax: GFX2 [] [