diff --git a/aide.h b/aide.h new file mode 100644 index 00000000..a0eaa137 --- /dev/null +++ b/aide.h @@ -0,0 +1,2 @@ +void Bouton_Aide(void); +void Bouton_Stats(void); diff --git a/boutons.c b/boutons.c new file mode 100644 index 00000000..28f21d4c --- /dev/null +++ b/boutons.c @@ -0,0 +1,5487 @@ +#include "const.h" +#include "struct.h" +#include "global.h" +#include "divers.h" +#include "graph.h" +#include "moteur.h" +#include "readline.h" +#include "files.h" +#include "loadsave.h" +#include "init.h" +#include +#include + +#include +#include +#include +#include +#include +#include "boutons.h" +#include "operatio.h" + +// On d‚clare m‚chamment le prototype de Erreur pour ‚viter de faire un +// fichier "main.h": +void Erreur(int Code); + +//-- MODELE DE BOUTON DE MENU ------------------------------------------------ +/* +void Bouton_***(void) +{ + short Bouton_clicke; + + Ouvrir_fenetre(310,190,"***"); + + Fenetre_Definir_bouton_normal(103,137,80,14,"OK",0,1,0x001C); // 1 + Fenetre_Definir_bouton_scroller(18,44,88,16,4,0); // 2 + + Afficher_curseur(); + + do + { + Bouton_clicke=Fenetre_Bouton_clicke(); + } + while (Bouton_clicke!=1); + + Fermer_fenetre(); + Desenclencher_bouton(BOUTON_***); + Afficher_curseur(); +} +*/ + + +void Message_Non_disponible(void) +{ + short Bouton_clicke; + + Ouvrir_fenetre(160,76,"Not available yet!"); + + Print_dans_fenetre(8,20,"This function will",CM_Noir,CM_Clair); + Print_dans_fenetre(12,28,"be implemented in",CM_Noir,CM_Clair); + Print_dans_fenetre(16,36,"a later version.",CM_Noir,CM_Clair); + Fenetre_Definir_bouton_normal(60,53,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(); + + // Puisque cette fonction peut ˆtre appel‚e par plusieurs boutons et qu'on + // ne sait pas lequel c'est, on les d‚senclenche tous. De toutes fa‡ons, ‡a + // ne sert … rien d'essayer d'optimiser ‡a puisque l'utilisateur ne devrait + // pas souvent l'appeler, et en plus y'en a pas beaucoup … d‚senclencher. ;) + Desenclencher_bouton(BOUTON_GRADRECT); + Desenclencher_bouton(BOUTON_TEXTE); + + Afficher_curseur(); +} + + +void Message_Memoire_insuffisante(void) +{ + short Bouton_clicke; + + Ouvrir_fenetre(216,76,"Not enough memory!"); + + Print_dans_fenetre(8,20,"Please consult the manual",CM_Noir,CM_Clair); + Print_dans_fenetre(24,28,"to know how to obtain",CM_Noir,CM_Clair); + Print_dans_fenetre(36,36,"more memory space.",CM_Noir,CM_Clair); + Fenetre_Definir_bouton_normal(60,53,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(); +} + + +void Bouton_Message_initial(void) +{ + short Bouton_clicke; + char Chaine[21]; + int Pos_X,Offs_Y,X,Y; + + sprintf(Chaine,"GrafX 2.00 %s%s",ALPHA_BETA,POURCENTAGE_VERSION); + Ouvrir_fenetre(260,172,Chaine); + + Fenetre_Afficher_cadre_creux(10,20,239,62); + Block(Fenetre_Pos_X+(Menu_Facteur_X*11), + Fenetre_Pos_Y+(Menu_Facteur_Y*21), + Menu_Facteur_X*237,Menu_Facteur_Y*60,CM_Noir); + for (Y=23,Offs_Y=0; Y<79; Offs_Y+=231,Y++) + for (X=14,Pos_X=0; Pos_X<231; Pos_X++,X++) + Pixel_dans_fenetre(X,Y,Logo_GrafX2[Offs_Y+Pos_X]); + + Print_dans_fenetre(27, 88,"Copyright (c) 1996-1999 by",CM_Fonce,CM_Clair); + Print_dans_fenetre(79, 96,"Sunset Design",CM_Noir,CM_Clair); + Print_dans_fenetre(55,104,"All rights reserved",CM_Fonce,CM_Clair); + + Print_dans_fenetre( 7,120,"You should read the README!.1ST",CM_Fonce,CM_Clair); + 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)=='à') + { + Print_char_transparent_dans_fenetre(43,119,'M',CM_Noir); + Print_char_transparent_dans_fenetre(53,121,'U',CM_Noir); + Print_char_transparent_dans_fenetre(63,119,'S',CM_Noir); + Print_char_transparent_dans_fenetre(74,120,'T',CM_Noir); + } + + Fenetre_Definir_bouton_normal(90,151,80,14,"OK",0,1,0x001C); // 1 + + Afficher_curseur(); + + do + { + Bouton_clicke=Fenetre_Bouton_clicke(); + } + while ((Bouton_clicke!=1) && (Touche!=0x0001) && (Touche!=0x0018)); + + Fermer_fenetre(); + Afficher_curseur(); +} + + + +void Changer_la_forme_du_pinceau(byte Forme) +{ + Pinceau_Forme=Forme; + Afficher_pinceau_dans_menu(); + + switch (Operation_en_cours) + { + case OPERATION_FILL : + Pinceau_Forme_avant_fill=Forme; + Pinceau_Forme=FORME_PINCEAU_POINT; + break; + case OPERATION_PIPETTE : + Pinceau_Forme_avant_pipette=Forme; + Pinceau_Forme=FORME_PINCEAU_POINT; + break; + // Note: Il existe un Pinceau_Forme_avant_lasso, mais comme le lasso aura + // ‚t‚ automatiquement d‚sactiv‚ avant d'arriver ici, y'a pas de problŠme. + } +} + + +//-------------------------------- UNDO/REDO --------------------------------- +void Bouton_Undo(void) +{ + Effacer_curseur(); + Undo(); + + Set_palette(Principal_Palette); + Calculer_couleurs_menu_optimales(Principal_Palette); + + Afficher_ecran(); + Desenclencher_bouton(BOUTON_UNDO); + Tracer_cadre_de_bouton_du_menu(BOUTON_LOUPE,Loupe_Mode); + Afficher_menu(); + Afficher_curseur(); +} + +void Bouton_Redo(void) +{ + Effacer_curseur(); + Redo(); + + Set_palette(Principal_Palette); + Calculer_couleurs_menu_optimales(Principal_Palette); + + Afficher_ecran(); + Desenclencher_bouton(BOUTON_UNDO); + Tracer_cadre_de_bouton_du_menu(BOUTON_LOUPE,Loupe_Mode); + Afficher_menu(); + Afficher_curseur(); +} + + +//---------------------------- SCROLL PALETTE LEFT --------------------------- +void Bouton_Pal_left(void) +{ + Effacer_curseur(); + if (Couleur_debut_palette) + { + Couleur_debut_palette-=8; + Afficher_palette_du_menu(); + } + Desenclencher_bouton(BOUTON_PAL_LEFT); + Afficher_curseur(); +} + +void Bouton_Pal_left_fast(void) +{ + Effacer_curseur(); + if (Couleur_debut_palette) + { + Couleur_debut_palette=(Couleur_debut_palette>=64)? Couleur_debut_palette-64 : 0; + Afficher_palette_du_menu(); + } + Desenclencher_bouton(BOUTON_PAL_LEFT); + Afficher_curseur(); +} + + +//--------------------------- SCROLL PALETTE RIGHT --------------------------- +void Bouton_Pal_right(void) +{ + Effacer_curseur(); + if (Couleur_debut_palette<=184) + { + Couleur_debut_palette+=8; + Afficher_palette_du_menu(); + } + Desenclencher_bouton(BOUTON_PAL_RIGHT); + Afficher_curseur(); +} + +void Bouton_Pal_right_fast(void) +{ + Effacer_curseur(); + if (Couleur_debut_palette<=184) + { + Couleur_debut_palette=(Couleur_debut_palette<=120)? Couleur_debut_palette+64 : 192; + Afficher_palette_du_menu(); + } + Desenclencher_bouton(BOUTON_PAL_RIGHT); + Afficher_curseur(); +} + +//-------------------- Choix de la forecolor dans le menu -------------------- +void Bouton_Choix_forecolor(void) +{ + word Pos_X, Pos_Y; + + Pos_X=(Mouse_X/Menu_Facteur_X)-(LARGEUR_MENU+1); + Pos_Y=((Mouse_Y-Menu_Ordonnee)/Menu_Facteur_Y)-2; + + if ((!Config.Couleurs_separees) + || ((Pos_X%Menu_Taille_couleur!=Menu_Taille_couleur-1) && ((Pos_Y&3)!=3))) + { + Effacer_curseur(); + Encadrer_couleur_menu(CM_Noir); + Fore_color=Couleur_debut_palette+((Pos_X/Menu_Taille_couleur)<<3)+(Pos_Y>>2); + Encadrer_couleur_menu(CM_Blanc); + Afficher_foreback(); + Afficher_curseur(); + } +} + +//-------------------- Choix de la backcolor dans le menu -------------------- +void Bouton_Choix_backcolor(void) +{ + word Pos_X, Pos_Y; + + Pos_X=(Mouse_X/Menu_Facteur_X)-(LARGEUR_MENU+1); + Pos_Y=((Mouse_Y-Menu_Ordonnee)/Menu_Facteur_Y)-2; + + if ((!Config.Couleurs_separees) + || ((Pos_X%Menu_Taille_couleur!=Menu_Taille_couleur-1) && ((Pos_Y&3)!=3))) + { + Effacer_curseur(); + Back_color=Couleur_debut_palette+((Pos_X/Menu_Taille_couleur)<<3)+(Pos_Y>>2); + Afficher_foreback(); + Afficher_curseur(); + } +} + + +//---------------------- Cacher ou r‚afficher le menu ------------------------ +void Pixel_dans_barre_d_outil_cachee(word X,word Y,byte Couleur) +{ + // C'est fait exprŠs que ce soit vide... + // C'est parce que y'a rien du tout … afficher vu que la barre d'outil est + // cach‚e... C'est simple non? +} + + +void Bouton_Cacher_menu(void) +{ + Effacer_curseur(); + if (Menu_visible) + { + Menu_visible=0; + Pixel_dans_menu=Pixel_dans_barre_d_outil_cachee; + Menu_Ordonnee=Hauteur_ecran; + + if (Loupe_Mode) + { + Calculer_donnees_loupe(); + if (Loupe_Decalage_Y+Loupe_Hauteur>Principal_Hauteur_image) + { + if (Loupe_Hauteur>Principal_Hauteur_image) + Loupe_Decalage_Y=0; + else + Loupe_Decalage_Y=Principal_Hauteur_image-Loupe_Hauteur; + } + } + + // On repositionne le d‚calage de l'image pour qu'il n'y ait pas d'in- + // -coh‚rences lorsqu'on sortira du mode Loupe. + if (Principal_Decalage_Y+Hauteur_ecran>Principal_Hauteur_image) + { + if (Hauteur_ecran>Principal_Hauteur_image) + Principal_Decalage_Y=0; + else + Principal_Decalage_Y=Principal_Hauteur_image-Hauteur_ecran; + } + // On fait pareil pour le brouillon + if (Brouillon_Decalage_Y+Hauteur_ecran>Brouillon_Hauteur_image) + { + if (Hauteur_ecran>Brouillon_Hauteur_image) + Brouillon_Decalage_Y=0; + else + Brouillon_Decalage_Y=Brouillon_Hauteur_image-Hauteur_ecran; + } + + Calculer_donnees_loupe(); + if (Loupe_Mode) + Recadrer_ecran_par_rapport_au_zoom(); + Calculer_limites(); + Calculer_coordonnees_pinceau(); + Afficher_ecran(); + } + else + { + Menu_visible=1; + Pixel_dans_menu=Pixel_dans_barre_d_outil; + Menu_Ordonnee=Hauteur_ecran-(HAUTEUR_MENU*Menu_Facteur_Y); + + Calculer_donnees_loupe(); + if (Loupe_Mode) + Recadrer_ecran_par_rapport_au_zoom(); + Calculer_limites(); + Calculer_coordonnees_pinceau(); + Afficher_menu(); + if (Loupe_Mode) + Afficher_ecran(); + } + Desenclencher_bouton(BOUTON_CACHER); + Afficher_curseur(); +} + + +//--------------------------- Quitter le programme --------------------------- +byte Bouton_Quitter_Routine_locale(void) +{ + short Bouton_clicke; + byte Enregistrer; + char Nom_du_fichier[256]; + byte Ancienne_forme_curseur; + + if (!Principal_Image_modifiee) + return 1; + + // On commence par afficher la fenˆtre de QUIT + Ouvrir_fenetre(160,84,"Quit ?"); + Fenetre_Definir_bouton_normal(20,20,120,14,"Stay",0,1,0x0001); // 1 + Fenetre_Definir_bouton_normal(20,40,120,14,"Save & quit",1,1,0x001F); // 2 + Fenetre_Definir_bouton_normal(20,60,120,14,"Discard (Quit)",1,1,0x0020);// 3 + Afficher_curseur(); + + do + { + Bouton_clicke=Fenetre_Bouton_clicke(); + } + while (Bouton_clicke<=0); + Attendre_fin_de_click(); + + Fermer_fenetre(); + Afficher_curseur(); + + switch(Bouton_clicke) + { + case 1 : return 0; // Rester + case 2 : // Sauver et enregistrer + Nom_fichier_complet(Nom_du_fichier,0); + if ( (!Fichier_existe(Nom_du_fichier)) || Demande_de_confirmation("Erase old file ?") ) + { + Effacer_curseur(); + Ancienne_forme_curseur=Forme_curseur; + Forme_curseur=FORME_CURSEUR_SABLIER; + Afficher_curseur(); + + Sauver_image(1); + + Effacer_curseur(); + Forme_curseur=Ancienne_forme_curseur; + Afficher_curseur(); + + if (!Erreur_fichier) + // L'ayant sauv‚e avec succŠs, + return 1; // On peut quitter + else + // Il y a eu une erreur lors de la sauvegarde, + return 0; // On ne peut donc pas quitter + } + else + // L'utilisateur ne veut pas ‚craser l'ancien fichier, + return 0; // On doit donc rester + case 3 : return 1; // Quitter + } + return 0; +} + + +void Bouton_Quit(void) +{ + short Bouton_clicke; + + if (Bouton_Quitter_Routine_locale()) + { + if (Brouillon_Image_modifiee) + { + Bouton_Page(); // On passe sur le brouillon + // Si l'utilisateur pr‚sente les derniers symptomes de l'abandon + if (Bouton_Quitter_Routine_locale()) + Sortir_du_programme=1; + } + else + Sortir_du_programme=1; + } + + if ( (Menu_visible) && (Mouse_Y+8>Menu_Ordonnee) ) + Effacer_curseur(); + + Desenclencher_bouton(BOUTON_QUIT); + + if ( (Menu_visible) && (Mouse_Y+8>Menu_Ordonnee) ) + Afficher_curseur(); +} + + +//---------------------------- Effacer l'‚cran ------------------------------- +void Bouton_Clear(void) +{ + Effacer_curseur(); + Backup(); + if (Stencil_Mode && Config.Clear_with_stencil) + Effacer_image_courante_Stencil(0,Stencil); + else + Effacer_image_courante(0); + Afficher_ecran(); + Desenclencher_bouton(BOUTON_CLEAR); + Afficher_curseur(); +} + +void Bouton_Clear_colore(void) +{ + Effacer_curseur(); + Backup(); + if (Stencil_Mode && Config.Clear_with_stencil) + Effacer_image_courante_Stencil(Back_color,Stencil); + else + Effacer_image_courante(Back_color); + Afficher_ecran(); + Desenclencher_bouton(BOUTON_CLEAR); + Afficher_curseur(); +} + + +//---------- Menu dans lequel on tagge des couleurs (genre Stencil) ---------- +void Menu_Tag_couleurs(char * En_tete, byte * Table, byte * Mode, byte Cancel) +{ + short Bouton_clicke; + byte Backup_table[256]; + word Indice; + word Ancien_Mouse_X; + word Ancien_Mouse_Y; + byte Ancien_Mouse_K; + byte Couleur_taggee; + byte Couleur; + byte Click; + + + Ouvrir_fenetre(176,150,En_tete); + + Fenetre_Definir_bouton_palette(6,38); // 1 + Fenetre_Definir_bouton_normal( 7, 19,78,14,"Clear" ,1,1,0x002E); // 2 + Fenetre_Definir_bouton_normal(91, 19,78,14,"Invert",1,1,0x0017); // 3 + if (Cancel) + { + Fenetre_Definir_bouton_normal(91,129,78,14,"OK" ,0,1,0x001C); // 4 + Fenetre_Definir_bouton_normal( 7,129,78,14,"Cancel",0,1,0x0001); // 5 + // On enregistre la table dans un backup au cas o— on ferait Cancel + memcpy(Backup_table,Table,256); + } + else + Fenetre_Definir_bouton_normal(49,129,78,14,"OK" ,0,1,0x001C); // 4 + + // On affiche l'‚tat actuel de la table + for (Indice=0; Indice<=255; Indice++) + Stencil_Tagger_couleur(Indice, (Table[Indice])?CM_Noir:CM_Clair); + + Afficher_curseur(); + + do + { + Ancien_Mouse_X=Mouse_X; + Ancien_Mouse_Y=Mouse_Y; + Ancien_Mouse_K=Mouse_K; + + Bouton_clicke=Fenetre_Bouton_clicke(); + + switch (Bouton_clicke) + { + case 0 : + break; + case -1 : + case 1 : // Palette + if ( (Mouse_X!=Ancien_Mouse_X) || (Mouse_Y!=Ancien_Mouse_Y) || (Mouse_K!=Ancien_Mouse_K) ) + { + Effacer_curseur(); + Couleur_taggee=Lit_pixel(Mouse_X,Mouse_Y); + Table[Couleur_taggee]=(Mouse_K==A_GAUCHE); + Stencil_Tagger_couleur(Couleur_taggee,(Mouse_K==A_GAUCHE)?CM_Noir:CM_Clair); + Afficher_curseur(); + } + break; + case 2 : // Clear + memset(Table,0,256); + Effacer_curseur(); + for (Indice=0; Indice<=255; Indice++) + Stencil_Tagger_couleur(Indice,CM_Clair); + Afficher_curseur(); + break; + case 3 : // Invert + Effacer_curseur(); + for (Indice=0; Indice<=255; Indice++) + Stencil_Tagger_couleur(Indice,(Table[Indice]^=1)?CM_Noir:CM_Clair); + Afficher_curseur(); + } + + if (!Mouse_K) + switch (Touche) + { + case 0x0029 : // R‚cup‚ration d'une couleur derriŠre le menu + case 0x0033 : + Recuperer_couleur_derriere_fenetre(&Couleur,&Click); + if (Click) + { + Effacer_curseur(); + Couleur_taggee=Couleur; + Table[Couleur_taggee]=(Click==A_GAUCHE); + Stencil_Tagger_couleur(Couleur_taggee,(Click==A_GAUCHE)?CM_Noir:CM_Clair); + Afficher_curseur(); + } + } + } + while (Bouton_clicke<4); + + Fermer_fenetre(); + + if (Bouton_clicke==5) // Cancel + memcpy(Table,Backup_table,256); + else // OK + *Mode=1; + + Afficher_curseur(); +} + + +//--------------------------------- Stencil ---------------------------------- +void Bouton_Stencil_Mode(void) +{ + Stencil_Mode=!Stencil_Mode; +} + + +void Stencil_Tagger_couleur(byte Couleur, byte Couleur_de_taggage) +{ + Block(Fenetre_Pos_X+(Menu_Facteur_X*(Fenetre_Liste_boutons_palette->Pos_X+4+(Couleur >> 4)*10)), + Fenetre_Pos_Y+(Menu_Facteur_Y*(Fenetre_Liste_boutons_palette->Pos_Y+3+(Couleur & 15)* 5)), + Menu_Facteur_X<<1,Menu_Facteur_Y*5,Couleur_de_taggage); +} + + +void Bouton_Menu_Stencil(void) +{ + Menu_Tag_couleurs("Stencil",Stencil,&Stencil_Mode,1); +} + + +//--------------------------------- Masque ----------------------------------- +void Bouton_Mask_Mode(void) +{ + Mask_Mode=!Mask_Mode; +} + + +void Bouton_Mask_Menu(void) +{ + Menu_Tag_couleurs("Mask",Mask,&Mask_Mode,1); +} + + +//------------------------------- ParamŠtres --------------------------------- + +void Settings_Afficher_config(struct S_Config * Conf) +#define YES "YES" +#define NO " NO" +{ + struct Fenetre_Bouton_scroller * Jauge=Fenetre_Liste_boutons_scroller; + char Chaine[4]; + + Effacer_curseur(); + + // Jauge = Jauge de sensibilit‚ Y + Jauge->Position=Conf->Indice_Sensibilite_souris_Y-1; + Fenetre_Dessiner_jauge(Jauge); + + Jauge=Jauge->Next; + // Jauge = Jauge de sensibilit‚ X + Jauge->Position=Conf->Indice_Sensibilite_souris_X-1; + Fenetre_Dessiner_jauge(Jauge); + + Print_dans_fenetre(273, 31,(Conf->Lire_les_fichiers_caches)?YES:NO,CM_Noir,CM_Clair); + Print_dans_fenetre(273, 46,(Conf->Lire_les_repertoires_caches)?YES:NO,CM_Noir,CM_Clair); + Print_dans_fenetre(273, 61,(Conf->Lire_les_repertoires_systemes)?YES:NO,CM_Noir,CM_Clair); + + Print_dans_fenetre(223, 84,(Conf->Safety_colors)?YES:NO,CM_Noir,CM_Clair); + Print_dans_fenetre(223, 99,(Conf->Adjust_brush_pick)?YES:NO,CM_Noir,CM_Clair); + Print_dans_fenetre(223,114,(Conf->Couleurs_separees)?YES:NO,CM_Noir,CM_Clair); + Print_dans_fenetre(223,129,(Conf->Auto_set_res)?YES:NO,CM_Noir,CM_Clair); + Print_dans_fenetre(183,144,(Conf->Coords_rel)?"Relative":"Absolute",CM_Noir,CM_Clair); + + Print_dans_fenetre( 91, 84,(Conf->Afficher_limites_image)?YES:NO,CM_Noir,CM_Clair); + Print_dans_fenetre( 91, 99,(Conf->Clear_palette)?YES:NO,CM_Noir,CM_Clair); + Print_dans_fenetre( 91,114,(Conf->Maximize_preview)?YES:NO,CM_Noir,CM_Clair); + Print_dans_fenetre( 91,129,(Conf->Backup)?YES:NO,CM_Noir,CM_Clair); + switch (Conf->Curseur) + { + case 0 : Print_dans_fenetre(67,144," Solid",CM_Noir,CM_Clair); break; + case 1 : Print_dans_fenetre(67,144,"Transp",CM_Noir,CM_Clair); break; + default: Print_dans_fenetre(67,144," Thin",CM_Noir,CM_Clair); + } + + if (Conf->Fonte) + { // Fun + Print_dans_fenetre( 8,31," ",CM_Noir,CM_Clair); + Print_dans_fenetre( 78,31," ",CM_Noir,CM_Clair); + Print_dans_fenetre( 82,31,"\020",CM_Noir,CM_Clair); + Print_dans_fenetre(152,31,"\021",CM_Noir,CM_Clair); + } + else + { // Classic + Print_dans_fenetre( 82,31," ",CM_Noir,CM_Clair); + Print_dans_fenetre(152,31," ",CM_Noir,CM_Clair); + Print_dans_fenetre( 8,31,"\020",CM_Noir,CM_Clair); + Print_dans_fenetre( 78,31,"\021",CM_Noir,CM_Clair); + } + + Print_dans_fenetre(155,166,(Conf->Auto_save)?YES:NO,CM_Noir,CM_Clair); + + Num2str(Conf->Nb_pages_Undo,Chaine,2); + Fenetre_Contenu_bouton_saisie(Fenetre_Liste_boutons_special,Chaine); + + Afficher_curseur(); +} + +void Settings_Sauver_config(struct S_Config * Conf) +{ + if (Sauver_CFG()) + Erreur(0); + else + if (Sauver_INI(Conf)) + Erreur(0); +} + +void Settings_Charger_config(struct S_Config * Conf) +{ + if (Charger_CFG(0)) + Erreur(0); + else + if (Charger_INI(Conf)) + Erreur(0); +} + +void Bouton_Settings(void) +{ + int Sensibilite_X; + int Sensibilite_Y; + short Bouton_clicke; + struct S_Config Config_choisie; + char Chaine[3]; + byte On_a_recharge_la_config=0; + + Config_choisie=Config; + + Ouvrir_fenetre(307,182,"Settings"); + + // On commence par dessiner tous les cƒdres + Fenetre_Afficher_cadre( 5, 16,157,30); + Fenetre_Afficher_cadre( 5, 47,157,17); + Fenetre_Afficher_cadre(163, 16,139,60); + Fenetre_Afficher_cadre(253, 77, 49,82); + Fenetre_Afficher_cadre( 5, 77,247,82); // |_ Misc. + Fenetre_Afficher_cadre( 5, 65,157,14); // | + // On d‚coupe le cƒdre bizarre des "Miscellaneous" + Pixel_dans_fenetre(6,77,CM_Blanc); + Pixel_dans_fenetre(5,78,CM_Fonce); + Block(Fenetre_Pos_X+(7*Menu_Facteur_X),Fenetre_Pos_Y+(77*Menu_Facteur_Y), + Menu_Facteur_X*154,Menu_Facteur_Y<<1,CM_Clair); + Pixel_dans_fenetre(161,77,CM_Clair); + Pixel_dans_fenetre(160,77,CM_Fonce); + + // On affiche maintenant tout le blabla + Print_dans_fenetre( 69, 19,"Font" ,CM_Fonce,CM_Clair); + Print_dans_fenetre(169, 19,"Show in filelist",CM_Fonce,CM_Clair); + Print_dans_fenetre( 9, 52,"Nb of UNDO pages",CM_Fonce,CM_Clair); + Print_dans_fenetre( 32, 70,"Miscellaneous" ,CM_Fonce,CM_Clair); + Print_dans_fenetre(258, 80,"Mouse" ,CM_Fonce,CM_Clair); + Print_dans_fenetre(258, 88,"Sens." ,CM_Fonce,CM_Clair); + Print_dans_fenetre(256,123,"X" ,CM_Fonce,CM_Clair); + Print_dans_fenetre(292,123,"Y" ,CM_Fonce,CM_Clair); + + // Boutons de fontes + Fenetre_Definir_bouton_normal(17,28,59,14,"Classic",0,1,0xFFFF); // 1 + Fenetre_Definir_bouton_normal(91,28,59,14,"Fun" ,0,1,0xFFFF); // 2 + + // Bouton Show/Hide dans le fileselect + Fenetre_Definir_bouton_normal(167, 28,131,14,"Hidden files: ",0,1,0xFFFF); // 3 + Fenetre_Definir_bouton_normal(167, 43,131,14,"Hidden dir. : ",0,1,0xFFFF); // 4 + Fenetre_Definir_bouton_normal(167, 58,131,14,"System dir. : ",0,1,0xFFFF); // 5 + + // Bouton Show/Hide Picture limits + Fenetre_Definir_bouton_normal( 9, 81,107,14,"Limits : ",0,1,0xFFFF); // 6 + // Bouton Show/Hide Picture limits + Fenetre_Definir_bouton_normal( 9, 96,107,14,"Clear pal: ",0,1,0xFFFF); // 7 + // Bouton Show/Hide Picture limits + Fenetre_Definir_bouton_normal( 9,111,107,14,"Max prev.: ",0,1,0xFFFF); // 8 + // Bouton Effectuer des backups … chaque sauvegarde + Fenetre_Definir_bouton_normal( 9,126,107,14,"Backup : ",0,1,0xFFFF); // 9 + // Bouton Choix du curseur + Fenetre_Definir_bouton_normal( 9,141,107,14,"Cursor: ",0,1,0xFFFF); // 10 + + // Bouton Safety colors + Fenetre_Definir_bouton_normal(117, 81,131,14,"Safe. colors: ",0,1,0xFFFF); // 11 + // Bouton Adjust Brush Pick + Fenetre_Definir_bouton_normal(117, 96,131,14,"AdjBrushPick: ",0,1,0xFFFF); // 12 + // Bouton Separate colors + Fenetre_Definir_bouton_normal(117,111,131,14,"Separate col: ",0,1,0xFFFF); // 13 + // Bouton Passer dans la r‚solution appropri‚e aprŠs un chargement + Fenetre_Definir_bouton_normal(117,126,131,14,"Auto-set res: ",0,1,0xFFFF); // 14 + // Bouton Adapter la palette aprŠs un chargement (<=> Shift+BkSpc) + Fenetre_Definir_bouton_normal(117,141,131,14,"Coords: ",0,1,0xFFFF); // 15 + + // Bouton Reload + Fenetre_Definir_bouton_normal( 6,163, 51,14,"Reload" ,0,1,0xFFFF); // 16 + // Bouton Auto-save + Fenetre_Definir_bouton_normal( 73,163,107,14,"Auto-save: ",0,1,0xFFFF); // 17 + // Bouton Save + Fenetre_Definir_bouton_normal(183,163, 51,14,"Save" ,0,1,0xFFFF); // 18 + // Bouton Close + Fenetre_Definir_bouton_normal(250,163, 51,14,"Close" ,0,1,0x0001); // 19 + + // Jauges de sensibilit‚ de la souris (X puis Y) + Fenetre_Definir_bouton_scroller(265,99,56,255,1,0); // 20 + Fenetre_Definir_bouton_scroller(279,99,56,255,1,0); // 21 + + // Zone de saisie du nb de pages de Undo + Fenetre_Definir_bouton_saisie(140,50,2); // 22 + + Afficher_curseur(); + + Settings_Afficher_config(&Config_choisie); + + + do + { + Bouton_clicke=Fenetre_Bouton_clicke(); + + switch(Bouton_clicke) + { + case 1 : // Classic + Config_choisie.Fonte=0; + break; + case 2 : // Fun + Config_choisie.Fonte=1; + break; + case 3 : // Hidden files + Config_choisie.Lire_les_fichiers_caches=(Config_choisie.Lire_les_fichiers_caches)?0:-1; + break; + case 4 : // Hidden dir. + Config_choisie.Lire_les_repertoires_caches=(Config_choisie.Lire_les_repertoires_caches)?0:-1; + break; + case 5 : // System dir. + Config_choisie.Lire_les_repertoires_systemes=(Config_choisie.Lire_les_repertoires_systemes)?0:-1; + break; + case 6 : // Draw limits + Config_choisie.Afficher_limites_image=!Config_choisie.Afficher_limites_image; + break; + case 7 : // Clear palette + Config_choisie.Clear_palette=!Config_choisie.Clear_palette; + break; + case 8 : // Maximize preview + Config_choisie.Maximize_preview=!Config_choisie.Maximize_preview; + break; + case 9 : // Backup + Config_choisie.Backup=!Config_choisie.Backup; + break; + case 10 : // Curseur + Config_choisie.Curseur=(Config_choisie.Curseur+1)%3; + break; + case 11 : // Safety colors + Config_choisie.Safety_colors=!Config_choisie.Safety_colors; + break; + case 12 : // Adjust brush pick + Config_choisie.Adjust_brush_pick=!Config_choisie.Adjust_brush_pick; + break; + case 13 : // Separate colors + Config_choisie.Couleurs_separees=!Config_choisie.Couleurs_separees; + break; + case 14 : // Auto-set resolution + Config_choisie.Auto_set_res=!Config_choisie.Auto_set_res; + break; + case 15 : // Coordonn‚es + Config_choisie.Coords_rel=!Config_choisie.Coords_rel; + break; + case 16 : // Reload + Settings_Charger_config(&Config_choisie); + On_a_recharge_la_config=1; + break; + case 17 : // Auto-save + Config_choisie.Auto_save=!Config_choisie.Auto_save; + break; + case 18 : // Save + Settings_Sauver_config(&Config_choisie); + break; + case 20 : // X Sensib. + Config_choisie.Indice_Sensibilite_souris_X=Fenetre_Attribut2+1; + break; + case 21 : // Y Sensib. + Config_choisie.Indice_Sensibilite_souris_Y=Fenetre_Attribut2+1; + break; + case 22 : // Nb pages Undo + Effacer_curseur(); + Num2str(Config_choisie.Nb_pages_Undo,Chaine,2); + Readline(142,52,Chaine,2,1); + Config_choisie.Nb_pages_Undo=atoi(Chaine); + // On corrige la valeur + if (Config_choisie.Nb_pages_Undo>NB_PAGES_UNDO_MAX) + { + Config_choisie.Nb_pages_Undo=NB_PAGES_UNDO_MAX; + Num2str(Config_choisie.Nb_pages_Undo,Chaine,2); + Fenetre_Contenu_bouton_saisie(Fenetre_Liste_boutons_special,Chaine); + } + else if (!Config_choisie.Nb_pages_Undo) + { + Config_choisie.Nb_pages_Undo=1; + Num2str(Config_choisie.Nb_pages_Undo,Chaine,2); + Fenetre_Contenu_bouton_saisie(Fenetre_Liste_boutons_special,Chaine); + } + Afficher_curseur(); + } + + if ((Bouton_clicke>=3) && (Bouton_clicke<=5)) + { + Principal_File_list_Position=0; + Principal_File_list_Decalage=0; + Brouillon_File_list_Position=0; + Brouillon_File_list_Decalage=0; + } + + if ((Bouton_clicke>=1) && (Bouton_clicke<=17)) + Settings_Afficher_config(&Config_choisie); + } + while ( (Bouton_clicke!=19) && (Touche!=0x001C) ); + + Config=Config_choisie; + + // Prise en compte de la nouvelle config + // Gestion de la sensibilit‚ + Sensibilite_X=(Config.Indice_Sensibilite_souris_X/Menu_Facteur_X); + Sensibilite_Y=(Config.Indice_Sensibilite_souris_Y/Menu_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); + // Gestion des fontes + if (Config.Fonte) + Fonte=Fonte_fun; + else + Fonte=Fonte_systeme; + + if (On_a_recharge_la_config) + Calculer_couleurs_menu_optimales(Principal_Palette); + + Fermer_fenetre(); + Desenclencher_bouton(BOUTON_PARAMETRES); + // Raffichage du menu pour que les inscriptions qui y figurent soient retrac‚es avec la nouvelle fonte + Afficher_menu(); + Afficher_curseur(); + + // On v‚rifie qu'on peut bien allouer le nombre de pages Undo. + Nouveau_nombre_de_backups(Config.Nb_pages_Undo); +} + + +//---------------------------- Changement de page ---------------------------- +void Bouton_Page(void) +{ + byte Octet_temporaire; + word Mot_temporaire; + short Short_temporaire; + float Float_temporaire; + char Zone_temporaire[256]; + + Effacer_curseur(); + + // On d‚grossit le travail avec les infos des listes de pages + Interchanger_image_principale_et_brouillon(); + + // On fait le reste du travail "… la main": + Short_temporaire=Brouillon_Decalage_X; + Brouillon_Decalage_X=Principal_Decalage_X; + Principal_Decalage_X=Short_temporaire; + + Short_temporaire=Brouillon_Decalage_Y; + Brouillon_Decalage_Y=Principal_Decalage_Y; + Principal_Decalage_Y=Short_temporaire; + + Short_temporaire=Ancien_Brouillon_Decalage_X; + Ancien_Brouillon_Decalage_X=Ancien_Principal_Decalage_X; + Ancien_Principal_Decalage_X=Short_temporaire; + + Short_temporaire=Ancien_Brouillon_Decalage_Y; + Ancien_Brouillon_Decalage_Y=Ancien_Principal_Decalage_Y; + Ancien_Principal_Decalage_Y=Short_temporaire; + + Short_temporaire=Brouillon_Split; + Brouillon_Split=Principal_Split; + Principal_Split=Short_temporaire; + + Short_temporaire=Brouillon_X_Zoom; + Brouillon_X_Zoom=Principal_X_Zoom; + Principal_X_Zoom=Short_temporaire; + + Float_temporaire=Brouillon_Proportion_split; + Brouillon_Proportion_split=Principal_Proportion_split; + Principal_Proportion_split=Float_temporaire; + + Octet_temporaire=Brouillon_Loupe_Mode; + Brouillon_Loupe_Mode=Loupe_Mode; + Loupe_Mode=Octet_temporaire; + + Pixel_Preview=(Loupe_Mode)?Pixel_Preview_Loupe:Pixel_Preview_Normal; + + Mot_temporaire=Brouillon_Loupe_Facteur; + Brouillon_Loupe_Facteur=Loupe_Facteur; + Loupe_Facteur=Mot_temporaire; + + Mot_temporaire=Brouillon_Loupe_Hauteur; + Brouillon_Loupe_Hauteur=Loupe_Hauteur; + Loupe_Hauteur=Mot_temporaire; + + Mot_temporaire=Brouillon_Loupe_Largeur; + Brouillon_Loupe_Largeur=Loupe_Largeur; + Loupe_Largeur=Mot_temporaire; + + Short_temporaire=Brouillon_Loupe_Decalage_X; + Brouillon_Loupe_Decalage_X=Loupe_Decalage_X; + Loupe_Decalage_X=Short_temporaire; + + Short_temporaire=Brouillon_Loupe_Decalage_Y; + Brouillon_Loupe_Decalage_Y=Loupe_Decalage_Y; + Loupe_Decalage_Y=Short_temporaire; + + // Swap du bool‚en "Image modifi‚e" + Octet_temporaire =Brouillon_Image_modifiee; + Brouillon_Image_modifiee=Principal_Image_modifiee; + Principal_Image_modifiee=Octet_temporaire; + + // Swap des infos sur les fileselects + strcpy(Zone_temporaire ,Brouillon_Repertoire_courant); + strcpy(Brouillon_Repertoire_courant,Principal_Repertoire_courant); + strcpy(Principal_Repertoire_courant,Zone_temporaire ); + + Octet_temporaire=Brouillon_Format; + Brouillon_Format=Principal_Format; + Principal_Format=Octet_temporaire; + + Mot_temporaire =Brouillon_File_list_Position; + Brouillon_File_list_Position=Principal_File_list_Position; + Principal_File_list_Position=Mot_temporaire; + + Mot_temporaire =Brouillon_File_list_Decalage; + Brouillon_File_list_Decalage=Principal_File_list_Decalage; + Principal_File_list_Decalage=Mot_temporaire; + + // A la fin, on affiche l'‚cran + for (Octet_temporaire=0; FACTEUR_ZOOM[Octet_temporaire]!=Loupe_Facteur; Octet_temporaire++); + Changer_facteur_loupe(Octet_temporaire); + + Set_palette(Principal_Palette); + Calculer_couleurs_menu_optimales(Principal_Palette); + Afficher_ecran(); + Desenclencher_bouton(BOUTON_PAGE); + Tracer_cadre_de_bouton_du_menu(BOUTON_LOUPE,Loupe_Mode); + Afficher_menu(); + + Afficher_curseur(); +} + + +// -- Copie de page --------------------------------------------------------- + +void Copier_image_seule(void) +{ + if (Backuper_et_redimensionner_brouillon(Principal_Largeur_image,Principal_Hauteur_image)) + { + // copie de l'image + memcpy(Brouillon_Ecran,Principal_Ecran,Principal_Largeur_image*Principal_Hauteur_image); + + // Copie des dimensions de l'image + /* + C'est inutile, le "Backuper et redimensionner brouillon" a d‚j… modifi‚ + ces valeurs pour qu'elles soient correctes. + */ + Brouillon_Largeur_image=Principal_Largeur_image; + Brouillon_Hauteur_image=Principal_Hauteur_image; + + // Copie des d‚calages de la fenˆtre principale (non zoom‚e) de l'image + Brouillon_Decalage_X=Principal_Decalage_X; + Brouillon_Decalage_Y=Principal_Decalage_Y; + + // Copie du bool‚en "Mode loupe" de l'image + Brouillon_Loupe_Mode=Loupe_Mode; + + // Copie du facteur de zoom du brouillon + Brouillon_Loupe_Facteur=Loupe_Facteur; + + // Copie des dimensions de la fenˆtre de zoom + Brouillon_Loupe_Largeur=Loupe_Largeur; + Brouillon_Loupe_Hauteur=Loupe_Hauteur; + + // Copie des d‚calages de la fenˆtre de zoom + Brouillon_Loupe_Decalage_X=Loupe_Decalage_X; + Brouillon_Loupe_Decalage_Y=Loupe_Decalage_Y; + + // Copie des donn‚es du split du zoom + Brouillon_Split=Principal_Split; + Brouillon_X_Zoom=Principal_X_Zoom; + Brouillon_Proportion_split=Principal_Proportion_split; + } + else + Message_Memoire_insuffisante(); +} + + +void Copier_certaines_couleurs(void) +{ + short Indice; + + Menu_Tag_couleurs("Tag colors to copy",Masque_copie_couleurs,NULL,0); + + if ( (!Brouillon_Image_modifiee) + || (Demande_de_confirmation("Spare page was modified. Proceed?")) ) + for (Indice=0; Indice<256; Indice++) + { + if (Masque_copie_couleurs[Indice]) + memcpy(Brouillon_Palette+Indice,Principal_Palette+Indice, + sizeof(struct Composantes)); + } +} + + +void Bouton_Copy_page(void) +{ + short Bouton_clicke; + + + Ouvrir_fenetre(168,137,"Copy to spare page"); + + Fenetre_Definir_bouton_normal(10, 20,148,14,"Pixels + palette" , 0,1,0x001C); // 1 + Fenetre_Definir_bouton_normal(10, 37,148,14,"Pixels only" , 3,1,0x002D); // 2 + Fenetre_Definir_bouton_normal(10, 54,148,14,"Palette only" , 1,1,0x0019); // 3 + Fenetre_Definir_bouton_normal(10, 71,148,14,"Some colors only" , 6,1,0x002E); // 4 + Fenetre_Definir_bouton_normal(10, 88,148,14,"Palette and remap",13,1,0x0013); // 5 + Fenetre_Definir_bouton_normal(44,114, 80,14,"Cancel" , 0,1,0x0001); // 6 + + Afficher_curseur(); + + do + { + Bouton_clicke=Fenetre_Bouton_clicke(); + } + while (Bouton_clicke<=0); + + Fermer_fenetre(); + Afficher_curseur(); + + if (Bouton_clicke!=6) + { + if (Bouton_clicke==4) + Copier_certaines_couleurs(); + else + { + if ( (!Brouillon_Image_modifiee) + || (Demande_de_confirmation("Spare page was modified. Proceed?")) ) + { + if (Bouton_clicke<=2) + Copier_image_seule(); + + if (Bouton_clicke==5) + Remap_picture(); + + if (Bouton_clicke!=2) // copie de la palette + memcpy(Brouillon_Palette,Principal_Palette,sizeof(T_Palette)); + + Brouillon_Image_modifiee=1; + } + } + } + + Effacer_curseur(); + Desenclencher_bouton(BOUTON_PAGE); + Afficher_curseur(); +} + + +// -- Suppression d'une page ------------------------------------------------- +void Bouton_Kill(void) +{ + if ( (Principal_Backups->Nb_pages_allouees==1) + || (!Demande_de_confirmation("Delete the current page?")) ) + { + if (Principal_Backups->Nb_pages_allouees==1) + Warning_message("You can't delete the last page."); + Effacer_curseur(); + Desenclencher_bouton(BOUTON_KILL); + Afficher_curseur(); + } + else + { + Effacer_curseur(); + Detruire_la_page_courante(); + + Set_palette(Principal_Palette); + Calculer_couleurs_menu_optimales(Principal_Palette); + + Afficher_ecran(); + Desenclencher_bouton(BOUTON_KILL); + Tracer_cadre_de_bouton_du_menu(BOUTON_LOUPE,Loupe_Mode); + Afficher_menu(); + Afficher_curseur(); + } +} + + +//------------------------- Dimensions Image/Ecran --------------------------- + +void Cocher_bouton_mode(short Pos_X, short Pos_Y, byte Etat) +{ + byte Couleur; + + if (Etat>=128) + Etat-=128; + switch (Etat) + { + case 0 : Couleur=CM_Blanc; break; + case 1 : Couleur=CM_Clair; break; + case 2 : Couleur=CM_Fonce; break; + default: Couleur=CM_Noir; + } + 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); +} + + +void Afficher_liste_modes(short Debut_liste, short Position_curseur) +{ + short Indice,Mode_courant; + short Pos_Y; + byte Couleur_texte,Couleur_fond; + char Chaine[29]; + + for (Mode_courant=Debut_liste,Indice=0; Indice<12; Indice++,Mode_courant++) + { + Pos_Y=70+(Indice<<3); + Cocher_bouton_mode(19,Pos_Y+2,Mode_video[Mode_courant].Etat); + + if (Position_curseur!=Indice) + { + Couleur_fond =CM_Noir; + if (Mode_video[Mode_courant].Etat<128) + Couleur_texte=CM_Clair; + else + Couleur_texte=CM_Fonce; + } + else + { + Couleur_fond =CM_Fonce; + if (Mode_video[Mode_courant].Etat<128) + Couleur_texte=CM_Blanc; + else + Couleur_texte=CM_Clair; + } + Num2str(Mode_video[Mode_courant].Largeur,Chaine,4); + Num2str(Mode_video[Mode_courant].Hauteur,Chaine+4,4); + switch (Mode_video[Mode_courant].Mode) + { + case MODE_SDL : + memcpy(Chaine+8," SDL ",10); + break; + + } + if (Mode_video[Mode_courant].Refresh>0) + { + Num2str(Mode_video[Mode_courant].Refresh,Chaine+18,2); + Chaine[20]=' '; + } + else + { + if (Mode_video[Mode_courant].Refresh==-1) + memcpy(Chaine+18," ",3); + else + { + Num2str(-Mode_video[Mode_courant].Refresh,Chaine+18,2); + Chaine[20]='i'; + } + } + memcpy(Chaine+21," ",2); + memcpy(Chaine+23,Mode_video[Mode_courant].Ratio,4); + Chaine[27]=' '; + Chaine[28]=0; + + Print_dans_fenetre(39,Pos_Y,Chaine,Couleur_texte,Couleur_fond); + } +} + + +void Scroller_la_liste_des_modes(short Debut_liste, short Position_curseur, int * Mode_choisi) +{ + Effacer_curseur(); + *Mode_choisi=Debut_liste+Position_curseur; + if (Fenetre_Liste_boutons_scroller->Position!=Debut_liste) + { + Fenetre_Liste_boutons_scroller->Position=Debut_liste; + Fenetre_Dessiner_jauge(Fenetre_Liste_boutons_scroller); + } + Afficher_liste_modes(Debut_liste,Position_curseur); + Afficher_curseur(); +} + + +void Bouton_Resol(void) +{ + short Bouton_clicke; + int Mode_choisi; + word Largeur_choisie; + word Hauteur_choisie; + short Debut_liste; + short Position_curseur; + short Temp; + byte Temp2; + char Chaine[5]; + struct Fenetre_Bouton_special * Bouton_saisie_Width, * Bouton_saisie_Height; + + Ouvrir_fenetre(299,190,"Picture & screen sizes"); + + Fenetre_Afficher_cadre ( 8,17,195, 33); + Fenetre_Afficher_cadre ( 8,56,283,126); + Fenetre_Afficher_cadre_creux(37,68,228,100); + Block(Fenetre_Pos_X+Menu_Facteur_X*38,Fenetre_Pos_Y+Menu_Facteur_Y*69, + Menu_Facteur_X*226,Menu_Facteur_Y*98,CM_Noir); + + Print_dans_fenetre( 12, 21,"Picture size:" ,CM_Fonce,CM_Clair); + Print_dans_fenetre( 12, 37,"Width:" ,CM_Fonce,CM_Clair); + Print_dans_fenetre(108, 37,"Height:" ,CM_Fonce,CM_Clair); + Print_dans_fenetre( 16, 60,"OK" ,CM_Fonce,CM_Clair); + Print_dans_fenetre( 55, 60,"X Y" ,CM_Fonce,CM_Clair); + Print_dans_fenetre(131, 60,"Mode" ,CM_Fonce,CM_Clair); + Print_dans_fenetre(183, 60,"Hz" ,CM_Fonce,CM_Clair); + Print_dans_fenetre(219, 60,"Ratio" ,CM_Fonce,CM_Clair); + Print_dans_fenetre( 30,170,"\03" ,CM_Fonce,CM_Clair); + Print_dans_fenetre( 62,170,"OK" ,CM_Fonce,CM_Clair); + Print_dans_fenetre(102,170,"Imperfect" ,CM_Fonce,CM_Clair); + Print_dans_fenetre(196,170,"Unsupported" ,CM_Fonce,CM_Clair); + + Fenetre_Definir_bouton_normal(223, 18,67,14,"OK" ,0,1,0x001C); // 1 + Fenetre_Definir_bouton_normal(223, 35,67,14,"Cancel" ,0,1,0x0001); // 2 + + Fenetre_Definir_bouton_saisie( 60, 35,4); // 3 + Bouton_saisie_Width=Fenetre_Liste_boutons_special; + Fenetre_Definir_bouton_saisie(164, 35,4); // 4 + Bouton_saisie_Height=Fenetre_Liste_boutons_special; + + Fenetre_Definir_bouton_special(38,70,225,96); // 5 + + Mode_choisi=Resolution_actuelle; + + if (Mode_choisi>=6) + { + if (Mode_choisi>3; + if ((Mouse_K==2) || (Temp!=Position_curseur)) + { + Effacer_curseur(); + if (Temp!=Position_curseur) + { + Position_curseur=Temp; + Afficher_liste_modes(Debut_liste,Position_curseur); + } + Mode_choisi=Debut_liste+Position_curseur; + // Si l'utilisateur s'est servi du bouton droit de la souris: + if (Mouse_K==2) + { + // On affecte ‚galement les dimensions de l'image: + Largeur_choisie=Mode_video[Mode_choisi].Largeur; + Num2str(Largeur_choisie,Chaine,4); + Fenetre_Contenu_bouton_saisie(Bouton_saisie_Width,Chaine); + + Hauteur_choisie=Mode_video[Mode_choisi].Hauteur; + Num2str(Hauteur_choisie,Chaine,4); + Fenetre_Contenu_bouton_saisie(Bouton_saisie_Height,Chaine); + } + Afficher_curseur(); + } + Attendre_fin_de_click(); + break; + + case 6: // Scroller + Debut_liste=Fenetre_Attribut2; + Mode_choisi=Debut_liste+Position_curseur; + Afficher_liste_modes(Debut_liste,Position_curseur); + break; + + default: // Boutons de tag des ‚tats des modes + Temp=Debut_liste+Bouton_clicke-7; + if (Temp) // On n'a pas le droit de cocher le mode 0 (320x200) + { + Temp2=(Mode_video[Temp].Etat & 0x80)?128:0; + + if (Fenetre_Attribut1==A_GAUCHE) + Mode_video[Temp].Etat=Temp2+(((Mode_video[Temp].Etat&0x7F)+1)&3); + else + Mode_video[Temp].Etat=Temp2+(((Mode_video[Temp].Etat&0x7F)+3)&3); + + Effacer_curseur(); + Cocher_bouton_mode(19,16+(Bouton_clicke<<3),Mode_video[Temp].Etat); + Afficher_curseur(); + } + } + + // Gestion des touches de d‚placement dans la liste + switch (Touche) + { + case 0x0048 : // Haut + if (Position_curseur>0) + Position_curseur--; + else + if (Debut_liste>0) + Debut_liste--; + Scroller_la_liste_des_modes(Debut_liste,Position_curseur,&Mode_choisi); + break; + case 0x0050 : // Bas + if (Position_curseur<11) + Position_curseur++; + else + if (Debut_liste0) + Position_curseur=0; + else + { + if (Debut_liste>11) + Debut_liste-=11; + else + Debut_liste=0; + } + Scroller_la_liste_des_modes(Debut_liste,Position_curseur,&Mode_choisi); + break; + case 0x0051 : // PageDown + if (Position_curseur<11) + Position_curseur=11; + else + { + if (Debut_listeOPERATION_DESSIN_POINT) + Mode_de_dessin_en_cours=OPERATION_DESSIN_CONTINU; + + Effacer_curseur(); + Afficher_sprite_dans_menu(BOUTON_DESSIN,Mode_de_dessin_en_cours); + Demarrer_pile_operation(Mode_de_dessin_en_cours); + Afficher_curseur(); +} + + +// -- Gestion des boutons de rectangle vide et plein ------------------------ + +void Bouton_Rectangle_vide(void) +{ + Effacer_curseur(); + Demarrer_pile_operation(OPERATION_RECTANGLE_VIDE); + Afficher_curseur(); +} + + +void Bouton_Rectangle_plein(void) +{ + Effacer_curseur(); + Demarrer_pile_operation(OPERATION_RECTANGLE_PLEIN); + Afficher_curseur(); +} + + +// -- Gestion des boutons de cercle (ellipse) vide et plein(e) -------------- + +void Bouton_Cercle_vide(void) +{ + Effacer_curseur(); + Demarrer_pile_operation(OPERATION_CERCLE_VIDE); + Afficher_curseur(); +} + + +void Bouton_Ellipse_vide(void) +{ + Effacer_curseur(); + Demarrer_pile_operation(OPERATION_ELLIPSE_VIDE); + Afficher_curseur(); +} + + +void Bouton_Cercle_plein(void) +{ + Effacer_curseur(); + Demarrer_pile_operation(OPERATION_CERCLE_PLEIN); + Afficher_curseur(); +} + + +void Bouton_Ellipse_pleine(void) +{ + Effacer_curseur(); + Demarrer_pile_operation(OPERATION_ELLIPSE_PLEINE); + Afficher_curseur(); +} + + +// -- Gestion du menu des d‚grad‚s ------------------------------------------ +void Degrade_Dessiner_bouton_de_technique(short Pos_X,short Pos_Y,int Technique) +{ + short Ligne; + + // On commence par afficher les 2 c“t‚s qui constituent le d‚grad‚ de base: + // C“t‚ gauche (noir) + Block(Fenetre_Pos_X+((Pos_X+2)*Menu_Facteur_X), + Fenetre_Pos_Y+((Pos_Y+2)*Menu_Facteur_Y), + Menu_Facteur_X*6, + Menu_Facteur_Y*10,CM_Noir); + // C“t‚ droit (blanc) + Block(Fenetre_Pos_X+((Pos_X+8)*Menu_Facteur_X), + Fenetre_Pos_Y+((Pos_Y+2)*Menu_Facteur_Y), + Menu_Facteur_X*5, + Menu_Facteur_Y*10,CM_Blanc); + + switch(Technique) + { + case 1 : // D‚grad‚ de trames simples + // Au centre, on place 10 lignes tram‚es simplement + for (Ligne=2;Ligne<2+10;Ligne++) + if (Ligne&1) + { + // Lignes impaires + Pixel_dans_fenetre(Pos_X+ 5,Pos_Y+Ligne,CM_Blanc); + Pixel_dans_fenetre(Pos_X+ 7,Pos_Y+Ligne,CM_Blanc); + Pixel_dans_fenetre(Pos_X+ 8,Pos_Y+Ligne,CM_Noir); + } + else + { + // Lignes paires + Pixel_dans_fenetre(Pos_X+ 6,Pos_Y+Ligne,CM_Blanc); + Pixel_dans_fenetre(Pos_X+ 9,Pos_Y+Ligne,CM_Noir); + } + break; + case 2 : // D‚grad‚ de trames ‚tendues + // Au centre, on place 10 lignes tram‚es de fa‡on compliqu‚e + for (Ligne=2;Ligne<2+10;Ligne++) + if (Ligne&1) + { + // Lignes impaires + Pixel_dans_fenetre(Pos_X+ 7,Pos_Y+Ligne,CM_Blanc); + Pixel_dans_fenetre(Pos_X+ 8,Pos_Y+Ligne,CM_Noir); + Pixel_dans_fenetre(Pos_X+10,Pos_Y+Ligne,CM_Noir); + } + else + { + // Lignes paires + Pixel_dans_fenetre(Pos_X+ 4,Pos_Y+Ligne,CM_Blanc); + Pixel_dans_fenetre(Pos_X+ 6,Pos_Y+Ligne,CM_Blanc); + } + } +} + +void Degrade_Charger_infos_du_tableau(int Indice) +{ + Degrade_Borne_Inferieure =Degrade_Tableau[Indice].Debut; + Degrade_Borne_Superieure =Degrade_Tableau[Indice].Fin; + Degrade_Inverse =Degrade_Tableau[Indice].Inverse; + Degrade_Melange_aleatoire=Degrade_Tableau[Indice].Melange+1; + + Degrade_Intervalle_bornes=(Degrade_Borne_Inferieure indice du d‚grad‚ dans le tableau + Fenetre_Definir_bouton_scroller(218,22,75,16,1,Degrade_Courant); // 2 + // D‚finition du scrolleur de m‚lange du d‚grad‚ + Fenetre_Definir_bouton_scroller(31,22,84,256,1,Degrade_Tableau[Degrade_Courant].Melange); // 3 + Scroller_de_melange=Fenetre_Liste_boutons_scroller; + // D‚finition du bouton de sens + Fenetre_Definir_bouton_normal(8,22,15,14, + (Degrade_Tableau[Degrade_Courant].Inverse)?"\033":"\032",0,1,0x000F); // 4 + // D‚finition du bouton de technique + Fenetre_Definir_bouton_normal(8,92,15,14,"",0,1,0x010F); // 5 + Degrade_Dessiner_bouton_de_technique(8,92,Degrade_Tableau[Degrade_Courant].Technique); + + Fenetre_Definir_bouton_normal(178,112,51,14,"OK",0,1,0x001C); // 6 + Fenetre_Definir_bouton_normal(123,112,51,14,"Cancel",0,1,0x0001); // 7 + + Print_dans_fenetre(5,60,"MIX",CM_Fonce,CM_Clair); + + // On tagge les couleurs qui vont avec + Tagger_intervalle_palette(Degrade_Tableau[Degrade_Courant].Debut,Degrade_Tableau[Degrade_Courant].Fin); + + Num2str(Degrade_Courant+1,Chaine,2); + Print_dans_fenetre(215,100,Chaine,CM_Noir,CM_Clair); + + // On affiche le cadre autour de la pr‚view + Fenetre_Afficher_cadre_creux(7,111,110,16); + // On affiche la preview + Degrade_Dessiner_preview(8,112,108,14,Degrade_Courant); + + Premiere_couleur=Derniere_couleur=(Degrade_Tableau[Degrade_Courant].Inverse)?Degrade_Tableau[Degrade_Courant].Fin:Degrade_Tableau[Degrade_Courant].Debut; + + Afficher_curseur(); + + do + { + Ancien_Mouse_X=Mouse_X; + Ancien_Mouse_Y=Mouse_Y; + Ancien_Mouse_K=Mouse_K; + + Bouton_clicke=Fenetre_Bouton_clicke(); + + switch(Bouton_clicke) + { + case -1 : + case 1 : // Palette + if ( (Mouse_X!=Ancien_Mouse_X) || (Mouse_Y!=Ancien_Mouse_Y) || (Mouse_K!=Ancien_Mouse_K) ) + { + Effacer_curseur(); + Couleur_temporaire=Lit_pixel(Mouse_X,Mouse_Y); + + if (!Ancien_Mouse_K) + { + // On vient de clicker + + // On met … jour l'intervalle du d‚grad‚ + Premiere_couleur=Derniere_couleur=Degrade_Tableau[Degrade_Courant].Debut=Degrade_Tableau[Degrade_Courant].Fin=Couleur_temporaire; + // On tagge le bloc + Tagger_intervalle_palette(Degrade_Tableau[Degrade_Courant].Debut,Degrade_Tableau[Degrade_Courant].Fin); + // Trac‚ de la preview: + Degrade_Dessiner_preview(8,112,108,14,Degrade_Courant); + } + else + { + // On maintient le click, on va donc tester si le curseur bouge + if (Couleur_temporaire!=Derniere_couleur) + { + // On commence par ordonner la 1Šre et derniŠre couleur du bloc + if (Premiere_couleurCouleur_temporaire) + { + Degrade_Tableau[Degrade_Courant].Debut=Couleur_temporaire; + Degrade_Tableau[Degrade_Courant].Fin =Premiere_couleur; + } + else + Degrade_Tableau[Degrade_Courant].Debut=Degrade_Tableau[Degrade_Courant].Fin=Premiere_couleur; + // On tagge le bloc + Tagger_intervalle_palette(Degrade_Tableau[Degrade_Courant].Debut,Degrade_Tableau[Degrade_Courant].Fin); + // Trac‚ de la preview: + Degrade_Dessiner_preview(8,112,108,14,Degrade_Courant); + Derniere_couleur=Couleur_temporaire; + } + } + Afficher_curseur(); + } + break; + case 2 : // Nouvel indice de d‚grad‚ + Effacer_curseur(); + // Nouvel indice dans Fenetre_Attribut2 + Degrade_Courant=Fenetre_Attribut2; + + // On affiche la valeur sous la jauge + Num2str(Degrade_Courant+1,Chaine,2); + Print_dans_fenetre(215,100,Chaine,CM_Noir,CM_Clair); + + // On tagge les couleurs qui vont avec + Tagger_intervalle_palette(Degrade_Tableau[Degrade_Courant].Debut,Degrade_Tableau[Degrade_Courant].Fin); + + // On affiche le sens qui va avec + Print_dans_fenetre(12,25,(Degrade_Tableau[Degrade_Courant].Inverse)?"\033":"\032",CM_Noir,CM_Clair); + + // On raffiche le m‚lange (jauge) qui va avec + Scroller_de_melange->Position=Degrade_Tableau[Degrade_Courant].Melange; + Fenetre_Dessiner_jauge(Scroller_de_melange); + + // On raffiche la technique qui va avec + Degrade_Dessiner_bouton_de_technique(8,92,Degrade_Tableau[Degrade_Courant].Technique); + + // On affiche la nouvelle preview + Degrade_Dessiner_preview(8,112,108,14,Degrade_Courant); + + Afficher_curseur(); + break; + case 3 : // Nouveau m‚lange de d‚grad‚ + Effacer_curseur(); + // Nouvel m‚lange dans Fenetre_Attribut2 + Degrade_Tableau[Degrade_Courant].Melange=Fenetre_Attribut2; + // On affiche la nouvelle preview + Degrade_Dessiner_preview(8,112,108,14,Degrade_Courant); + Afficher_curseur(); + break; + case 4 : // Changement de sens + Effacer_curseur(); + // On inverse le sens (par un XOR de 1) + Degrade_Tableau[Degrade_Courant].Inverse^=1; + Print_dans_fenetre(12,25,(Degrade_Tableau[Degrade_Courant].Inverse)?"\033":"\032",CM_Noir,CM_Clair); + // On affiche la nouvelle preview + Degrade_Dessiner_preview(8,112,108,14,Degrade_Courant); + Afficher_curseur(); + break; + case 5 : // Changement de technique + Effacer_curseur(); + // On change la technique par (+1)%3 + Degrade_Tableau[Degrade_Courant].Technique=(Degrade_Tableau[Degrade_Courant].Technique+1)%3; + Degrade_Dessiner_bouton_de_technique(8,92,Degrade_Tableau[Degrade_Courant].Technique); + // On affiche la nouvelle preview + Degrade_Dessiner_preview(8,112,108,14,Degrade_Courant); + Afficher_curseur(); + } + + if (!Mouse_K) + switch (Touche) + { + case 0x0029 : // R‚cup‚ration d'une couleur derriŠre le menu + case 0x0033 : + Recuperer_couleur_derriere_fenetre(&Couleur,&Click); + if (Click) + { + Effacer_curseur(); + Couleur_temporaire=Couleur; + + // On met … jour l'intervalle du d‚grad‚ + Premiere_couleur=Derniere_couleur=Degrade_Tableau[Degrade_Courant].Debut=Degrade_Tableau[Degrade_Courant].Fin=Couleur_temporaire; + // On tagge le bloc + Tagger_intervalle_palette(Degrade_Tableau[Degrade_Courant].Debut,Degrade_Tableau[Degrade_Courant].Fin); + // Trac‚ de la preview: + Degrade_Dessiner_preview(8,112,108,14,Degrade_Courant); + + Afficher_curseur(); + } + } + } + while (Bouton_clicke<6); + + Fermer_fenetre(); + Desenclencher_bouton(BOUTON_GRADMENU); + Afficher_curseur(); + + Traiter_pixel_de_degrade=Afficher_pixel; + if (Bouton_clicke==7) // Cancel + { + Degrade_Courant=Ancien_Degrade_Courant; + memcpy(Degrade_Tableau,Backup_Degrade_Tableau,sizeof(struct T_Degrade_Tableau)*16); + Degrade_Charger_infos_du_tableau(Degrade_Courant); + } +} + + +// -- Gestion des boutons de cercle (ellipse) d‚grad‚(e) -------------------- + +void Bouton_Cercle_degrade(void) +{ + Effacer_curseur(); + Demarrer_pile_operation(OPERATION_CERCLE_DEGRADE); + Afficher_curseur(); +} + + +void Bouton_Ellipse_degrade(void) +{ + Effacer_curseur(); + Demarrer_pile_operation(OPERATION_ELLIPSE_DEGRADEE); + Afficher_curseur(); +} + + +// -- Gestion du bouton de remplissage --------------------------------------- + +void Bouton_Fill(void) +{ + if (Operation_en_cours!=OPERATION_FILL) + { + Effacer_curseur(); + if (Operation_en_cours!=OPERATION_REMPLACER) + { + Pinceau_Forme_avant_fill=Pinceau_Forme; + Pinceau_Forme=FORME_PINCEAU_POINT; + } + else + if ( (Mouse_Y=Principal_X_Zoom) ) ) + Print_dans_menu("X: Y: ",0); + Demarrer_pile_operation(OPERATION_FILL); + Afficher_curseur(); + } +} + + +void Bouton_Remplacer(void) +{ + if (Operation_en_cours!=OPERATION_REMPLACER) + { + Effacer_curseur(); + if (Operation_en_cours!=OPERATION_FILL) + { + Pinceau_Forme_avant_fill=Pinceau_Forme; + Pinceau_Forme=FORME_PINCEAU_POINT; + } + if ( (Mouse_Y=Principal_X_Zoom) ) ) + Print_dans_menu("X: Y: ( )",0); + Demarrer_pile_operation(OPERATION_REMPLACER); + Afficher_curseur(); + } +} + + +void Bouton_desenclencher_Fill(void) +{ + Pinceau_Forme=Pinceau_Forme_avant_fill; + + if (Operation_en_cours==OPERATION_REMPLACER) + if ( (Mouse_Y=Principal_X_Zoom) ) ) + Print_dans_menu("X: Y: ",0); +} + + +//---------------------------- Menu des pinceaux ----------------------------- + +void Bouton_Menu_pinceaux(void) +{ + short Bouton_clicke; + short Pos_X,Pos_Y; + byte Indice; + + Ouvrir_fenetre(310,155,"Paintbrush menu"); + + Fenetre_Afficher_cadre(8,21,294,107); + + Fenetre_Definir_bouton_normal(122,133,67,14,"Cancel",0,1,0x0001); // 1 + + for (Indice=0; IndiceTAILLE_MAXI_PATH) + { // Doh! il va falloir tronquer le r‚pertoire (bouh !) + + // On commence par copier bˆtement les 3 premiers caractŠres (e.g. "C:\") + for (Indice=0;Indice<3;Indice++) + Nom_temporaire[Indice]=Principal_Repertoire_courant[Indice]; + + // On y rajoute 3 petits points: + strcpy(Nom_temporaire+3,"..."); + + // Ensuite, on cherche un endroit … partir duquel on pourrait loger tout + // le reste de la chaine (Ouaaaaaah!!! Vachement fort le mec!!) + for (Indice++;IndiceNb_elements=Liste_Nb_elements; + Enreg->Position=Position; + Calculer_hauteur_curseur_jauge(Enreg); + Fenetre_Dessiner_jauge(Enreg); + // On efface les anciens noms de fichier: + Block(Fenetre_Pos_X+(Menu_Facteur_X<<3),Fenetre_Pos_Y+(Menu_Facteur_Y*89),Menu_Facteur_X*98,Menu_Facteur_Y*82,CM_Noir); + // On affiche les nouveaux: + Afficher_la_liste_des_fichiers(Position,Decalage); + + // On r‚cupŠre le nom du schmilblick … "acc‚der" + Determiner_element_de_la_liste(Position,Decalage,Principal_Nom_fichier); + // On affiche le nouveau nom de fichier + Print_Nom_fichier_dans_selecteur(); + // On affiche le nom du r‚pertoire courant + Print_repertoire_courant(); +} + + +void Relire_liste_fichiers(byte Filtre, short Position, short Decalage, + struct Fenetre_Bouton_scroller * Enreg) +{ + Lire_liste_des_fichiers(Filtre); + Trier_la_liste_des_fichiers(); + Preparer_et_afficher_liste_fichiers(Position,Decalage,Enreg); +} + + // -- Gestion du chrono -- + byte Etat_chrono; // Etat du chrono: 0=Attente d'un XŠme de seconde + // 1=Il faut afficher la preview + // 2=Plus de chrono … gerer pour l'instant + long Chrono_delay; // Nombre de 18.2Šme de secondes demand‚s + long Chrono_cmp; // Heure de d‚part du chrono + byte Nouvelle_preview; // Bool‚en "Il faut relancer le chrono de preview" + // Les fonctions de manipulation du chrono se trouvent dans DIVERS.ASM + + +void On_vient_de_scroller_dans_le_fileselect(struct Fenetre_Bouton_scroller * Scroller_de_fichiers) +{ + char Ancien_nom_de_fichier[13]; + + strcpy(Ancien_nom_de_fichier,Principal_Nom_fichier); + + // On regarde si la liste a boug‚ + if (Scroller_de_fichiers->Position!=Principal_File_list_Position) + { + // Si c'est le cas, il faut mettre … jour la jauge + Scroller_de_fichiers->Position=Principal_File_list_Position; + Fenetre_Dessiner_jauge(Scroller_de_fichiers); + } + // On r‚cup‚re le nom du schmilblick … "acc‚der" + Determiner_element_de_la_liste(Principal_File_list_Position,Principal_File_list_Decalage,Principal_Nom_fichier); + if (strcmp(Ancien_nom_de_fichier,Principal_Nom_fichier)) + Nouvelle_preview=1; + + // On affiche le nouveau nom de fichier + Print_Nom_fichier_dans_selecteur(); + Afficher_curseur(); +} + + +short Position_fichier_dans_liste(char * Nom) +{ + struct Element_de_liste_de_fileselect * Element_courant; + short Indice; + + for (Indice=0, Element_courant=Liste_du_fileselect; + ((Element_courant!=NULL) && (strcmp(Element_courant->Nom,Nom))); + Indice++,Element_courant=Element_courant->Suivant); + + return (Element_courant!=NULL)?Indice:0; +} + + +void Placer_barre_de_selection_sur(char * Nom) +{ + short Indice; + + Indice=Position_fichier_dans_liste(Nom); + + if ((Liste_Nb_elements<=10) || (Indice<5)) + { + Principal_File_list_Position=0; + Principal_File_list_Decalage=Indice; + } + else + { + if (Indice>=Liste_Nb_elements-5) + { + Principal_File_list_Position=Liste_Nb_elements-10; + Principal_File_list_Decalage=Indice-Principal_File_list_Position; + } + else + { + Principal_File_list_Position=Indice-4; + Principal_File_list_Decalage=4; + } + } +} + + +char FFF_Meilleur_nom[13]; +char * Nom_correspondant_le_mieux_a(char * Nom) +{ + char Nom_courant[13]; + char * Pointeur1; + char * Pointeur2; + char * Pointeur_Meilleur_nom; + struct Element_de_liste_de_fileselect * Element_courant; + byte Lettres_identiques=0; + byte Compteur; + + strcpy(FFF_Meilleur_nom,Principal_Nom_fichier); + Pointeur_Meilleur_nom=NULL; + + for (Element_courant=Liste_du_fileselect; Element_courant!=NULL; Element_courant=Element_courant->Suivant) + { + if ( (!Config.Find_file_fast) + || (Config.Find_file_fast==(Element_courant->Type+1)) ) + { + // On copie le nom de la liste en cours de traitement dans Nom_courant + // tout en le remettant sous forme normale. + for (Pointeur1=Element_courant->Nom,Pointeur2=Nom_courant;*Pointeur1;Pointeur1++) + if (*Pointeur1!=' ') + *(Pointeur2++)=*Pointeur1; + *Pointeur2=0; + // On compare et si c'est mieux, on stocke dans Meilleur_nom + for (Compteur=0; Nom_courant[Compteur]==Nom[Compteur]; Compteur++); + if (Compteur>Lettres_identiques) + { + Lettres_identiques=Compteur; + strcpy(FFF_Meilleur_nom,Nom_courant); + Pointeur_Meilleur_nom=Element_courant->Nom; + } + } + } + + return Pointeur_Meilleur_nom; +} + + +byte Bouton_Load_ou_Save(byte Load, byte Image) + // Load=1 => On affiche le menu du bouton LOAD + // Load=0 => On affiche le menu du bouton SAVE +{ + short Bouton_clicke; + struct Fenetre_Bouton_scroller * Scroller_de_fichiers; + short Temp; + unsigned Bidon; // Sert … appeler _dos_setdrive + word Drives_Debut_Y; + byte Charger_ou_sauver_l_image=0; + char Nom_drive[3]=" "; + byte On_a_clicke_sur_OK=0;// Indique si on a click‚ sur Load ou Save ou sur + //un bouton enclenchant Load ou Save juste aprŠs. + struct Composantes * Palette_initiale; // | Donn‚es concernant l'image qui + byte Image_modifiee_initiale; // | sont m‚moris‚es pour pouvoir + short Largeur_image_initiale; // |- ˆtre restaur‚es en sortant, + short Hauteur_image_initiale; // | parce que la preview elle les + byte Back_color_initiale; // | fout en l'air (c'te conne). + char Nom_fichier_initial[13]; // Sert … laisser le nom courant du fichier en cas de sauvegarde + char Repertoire_precedent[13]; // R‚pertoire d'o— l'on vient aprŠs un CHDIR + char Commentaire_initial[TAILLE_COMMENTAIRE+1]; + char Fichier_recherche[13]=""; + char * Fichier_le_plus_ressemblant; + + Palette_initiale=(struct Composantes *)malloc(sizeof(T_Palette)); + memcpy(Palette_initiale,Principal_Palette,sizeof(T_Palette)); + + Back_color_initiale=Back_color; + Image_modifiee_initiale=Principal_Image_modifiee; + Largeur_image_initiale=Principal_Largeur_image; + Hauteur_image_initiale=Principal_Hauteur_image; + strcpy(Nom_fichier_initial,Principal_Nom_fichier); + strcpy(Commentaire_initial,Principal_Commentaire); + if (Load) + { + if (Image) + Ouvrir_fenetre(310,190,"Load picture"); + else + Ouvrir_fenetre(310,190,"Load brush"); + Fenetre_Definir_bouton_normal(125,157,51,14,"Load",0,1,0x001C); // 1 + } + else + { + if (Image) + Ouvrir_fenetre(310,190,"Save picture"); + else + Ouvrir_fenetre(310,190,"Save brush"); + Fenetre_Definir_bouton_normal(125,157,51,14,"Save",0,1,0x001C); // 1 + if (Principal_Format==0) // Correction du *.* + { + Principal_Format=Principal_Format_fichier; + Principal_File_list_Position=0; + Principal_File_list_Decalage=0; + } + + if (Principal_Format>NB_FORMATS_SAVE) // Correction d'un format insauvable + { + Principal_Format=FORMAT_PAR_DEFAUT; + Principal_File_list_Position=0; + Principal_File_list_Decalage=0; + } + // Affichage du commentaire + if (Format_Commentaire[Principal_Format-1]) + Print_dans_fenetre(46,176,Principal_Commentaire,CM_Noir,CM_Clair); + } + + Fenetre_Definir_bouton_normal(125,139,51,14,"Cancel",0,1,0x0001); // 2 + Fenetre_Definir_bouton_normal(125, 89,51,14,"Delete",0,1,0x0053); // 3 + + // Cƒdre autour des formats + Fenetre_Afficher_cadre( 7, 51,103, 35); + // Cƒdre autour des infos sur le fichier de dessin + Fenetre_Afficher_cadre(116, 51,187, 35); + // Cƒdre autour de la preview + Fenetre_Afficher_cadre_creux(179,88,124,84); + // Cƒdre autour du fileselector + Fenetre_Afficher_cadre_creux( 7,88,100,84); + + Fenetre_Definir_bouton_special(9,90,96,80); // 4 + + // Scroller du fileselector + Fenetre_Definir_bouton_scroller(110,89,82,1,10,0); // 5 + Scroller_de_fichiers=Fenetre_Liste_boutons_scroller; + + // Scroller des formats + Fenetre_Definir_bouton_scroller(12,55,27,(Load)?NB_FORMATS_LOAD+1:NB_FORMATS_SAVE,1,(Load)?Principal_Format:Principal_Format-1); // 6 + + // Texte de commentaire des dessins + Print_dans_fenetre(7,176,"Txt:",CM_Fonce,CM_Clair); + Fenetre_Definir_bouton_saisie(44,174,TAILLE_COMMENTAIRE); // 7 + + // Saisie du nom de fichier + Fenetre_Definir_bouton_saisie(200,71,12); // 8 + + Print_dans_fenetre( 27,65,"Format:",CM_Fonce,CM_Clair); + Print_dans_fenetre(120,55,"Image size :",CM_Fonce,CM_Clair); + Print_dans_fenetre(120,63,"File size :",CM_Fonce,CM_Clair); + Print_dans_fenetre(120,73,"File name:",CM_Fonce,CM_Clair); + + Print_Format(); + + // D‚finition des boutons repr‚sentant les lecteurs + Drives_Debut_Y=(Nb_drives<=13)? 23 : 18; + for (Temp=0; Temp=Liste_Nb_repertoires) + { + Print_dans_fenetre(127,107,"Delete",CM_Fonce,CM_Clair); + Print_dans_fenetre(127,115,"file ?",CM_Fonce,CM_Clair); + } + else + { + Print_dans_fenetre(127,107,"Remove",CM_Fonce,CM_Clair); + Print_dans_fenetre(127,115,"dir. ?",CM_Fonce,CM_Clair); + } + Print_dans_fenetre(127,123,"Yes/No",CM_Fonce,CM_Clair); + + do + { + Etat_Du_Clavier=SDL_GetKeyState(Bidon); + } while ((Etat_Du_Clavier[SDLK_y]==0) && (Etat_Du_Clavier[SDLK_n]==0) && (Etat_Du_Clavier[SDLK_ESCAPE]==0)); + + // On efface la demande de confirmation + Block(Fenetre_Pos_X+127*Menu_Facteur_X,Fenetre_Pos_Y+107*Menu_Facteur_Y, + Menu_Facteur_X*48,Menu_Facteur_Y*24,CM_Clair); + + // Si l'utilisateur confirme, + if (Touche=='Y') + { + // Si c'est un fichier + if (Principal_File_list_Position+Principal_File_list_Decalage>=Liste_Nb_repertoires) + // On efface le fichier (si on peut) + Temp=(!remove(Principal_Nom_fichier)); + else // Si c'est un repertoire + // On efface le repertoire (si on peut) + Temp=(!rmdir(Principal_Nom_fichier)); + + if (Temp) // Temp indique si l'effacement s'est bien pass‚ + { + // On remonte si c'‚tait le dernier ‚l‚ment de la liste + if (Principal_File_list_Position+Principal_File_list_Decalage==Liste_Nb_elements-1) + { + if (Principal_File_list_Position) + Principal_File_list_Position--; + else + if (Principal_File_list_Decalage) + Principal_File_list_Decalage--; + } + else // Si ce n'‚tait pas le dernier, il faut faire gaffe … ce + { // que ses copains d'en dessous ne remontent pas trop. + if ( (Principal_File_list_Position) + && (Principal_File_list_Position+10==Liste_Nb_elements) ) + { + Principal_File_list_Position--; + Principal_File_list_Decalage++; + } + } + // On relit les informations + Relire_liste_fichiers(Principal_Format,Principal_File_list_Position,Principal_File_list_Decalage,Scroller_de_fichiers); + // On demande la preview du nouveau fichier sur lequel on se trouve + Nouvelle_preview=1; + } + else + Erreur(0); + + // On place la barre de s‚lection du brouillon au d‚but s'il a le + // mˆme r‚pertoire que l'image principale. + if (!strcmp(Principal_Repertoire_courant,Brouillon_Repertoire_courant)) + { + Brouillon_File_list_Position=0; + Brouillon_File_list_Decalage=0; + } + } + Afficher_curseur(); + } + break; + + case 4 : // Zone d'affichage de la liste de fichiers + Effacer_curseur(); + + Temp=Calculer_decalage_click_dans_fileselector(); + if (Temp>=0) + { + if (Temp!=Principal_File_list_Decalage) + { + // On met … jour le d‚calage + Principal_File_list_Decalage=Temp; + + // On r‚cup‚re le nom du schmilblick … "acc‚der" + Determiner_element_de_la_liste(Principal_File_list_Position,Principal_File_list_Decalage,Principal_Nom_fichier); + // On affiche le nouveau nom de fichier + Print_Nom_fichier_dans_selecteur(); + // On affiche … nouveau la liste + Afficher_la_liste_des_fichiers(Principal_File_list_Position,Principal_File_list_Decalage); + + // On vient de changer de nom de fichier, donc on doit s'appreter + // a rafficher une preview + Nouvelle_preview=1; + } + else + { + // En sauvegarde, si on a double-click‚ sur un r‚pertoire, il + // faut mettre le nom de fichier au nom du r‚pertoire. Sinon, dans + // certains cas, on risque de sauvegarder avec le nom du fichier + // actuel au lieu de changer de r‚pertoire. + if (Principal_File_list_Position+Principal_File_list_Decalage On se place sur le nom de fichier qui correspond + if (Bouton_clicke<=0) + { + Temp=strlen(Fichier_recherche); + if (Temp<12) + { + Fichier_recherche[Temp]=toupper(Touche_ASCII); + Fichier_recherche[Temp+1]=0; + Fichier_le_plus_ressemblant=Nom_correspondant_le_mieux_a(Fichier_recherche); + if ( (Fichier_le_plus_ressemblant) + && (!memcmp(Fichier_recherche,FFF_Meilleur_nom,Temp+1)) ) + { + Temp=Principal_File_list_Position+Principal_File_list_Decalage; + Effacer_curseur(); + Placer_barre_de_selection_sur(Fichier_le_plus_ressemblant); + Preparer_et_afficher_liste_fichiers(Principal_File_list_Position,Principal_File_list_Decalage,Scroller_de_fichiers); + Afficher_curseur(); + if (Temp!=Principal_File_list_Position+Principal_File_list_Decalage) + Nouvelle_preview=1; + } + else + Fichier_recherche[Temp]=0; + } + } + else + *Fichier_recherche=0; + } + + if (On_a_clicke_sur_OK) + { + // Si c'est un r‚pertoire, on annule "On_a_clicke_sur_OK" et on passe + // dedans. + if (Repertoire_existe(Principal_Nom_fichier)) + { + Effacer_curseur(); + On_a_clicke_sur_OK=0; + + // On m‚morise le r‚pertoire dans lequel on ‚tait + if (strcmp(Principal_Nom_fichier,"..")) + strcpy(Repertoire_precedent,Nom_formate("..")); + else + { + for (Temp=strlen(Principal_Repertoire_courant); + (Temp>0) && (Principal_Repertoire_courant[Temp-1]!='\\'); + Temp--); + strcpy(Repertoire_precedent,Nom_formate(Principal_Repertoire_courant+Temp)); + } + + // On doit rentrer dans le r‚pertoire: + chdir(Principal_Nom_fichier); + Determiner_repertoire_courant(); + + // On lit le nouveau r‚pertoire + Lire_liste_des_fichiers(Principal_Format); + Trier_la_liste_des_fichiers(); + // On place la barre de s‚lection sur le r‚pertoire d'o— l'on vient + Placer_barre_de_selection_sur(Repertoire_precedent); + // Affichage des premiers fichiers visibles: + Preparer_et_afficher_liste_fichiers(Principal_File_list_Position,Principal_File_list_Decalage,Scroller_de_fichiers); + Afficher_curseur(); + Nouvelle_preview=1; + } + else // Sinon on essaye de charger ou sauver le fichier + { + strcpy(Principal_Repertoire_fichier,Principal_Repertoire_courant); + if (!Load) + Principal_Format_fichier=Principal_Format; + Charger_ou_sauver_l_image=1; + } + } + + // Gestion du chrono et des previews + if (Nouvelle_preview) + { + // On efface les infos de la preview pr‚c‚dente s'il y en a une + // d'affich‚e + if (Etat_chrono==2) + { + Effacer_curseur(); + // On efface le "but is:" + Block(Fenetre_Pos_X+27*Menu_Facteur_X,Fenetre_Pos_Y+74*Menu_Facteur_Y, + Menu_Facteur_X*80,Menu_Facteur_Y<<3,CM_Clair); + // On efface le commentaire pr‚c‚dent + Block(Fenetre_Pos_X+ 46*Menu_Facteur_X,Fenetre_Pos_Y+176*Menu_Facteur_Y, + Menu_Facteur_X<<8,Menu_Facteur_Y<<3,CM_Clair); + // On n‚ttoie la zone o— va s'afficher la preview: + Block(Fenetre_Pos_X+180*Menu_Facteur_X,Fenetre_Pos_Y+ 89*Menu_Facteur_Y, + Menu_Facteur_X*122,Menu_Facteur_Y*82,CM_Clair); + // On efface les dimensions de l'image + Block(Fenetre_Pos_X+226*Menu_Facteur_X,Fenetre_Pos_Y+ 55*Menu_Facteur_Y, + Menu_Facteur_X*72,Menu_Facteur_Y<<3,CM_Clair); + // On efface la taille du fichier + Block(Fenetre_Pos_X+226*Menu_Facteur_X,Fenetre_Pos_Y+ 63*Menu_Facteur_Y, + Menu_Facteur_X*72,Menu_Facteur_Y<<3,CM_Clair); + // Affichage du commentaire + if ( (!Load) && (Format_Commentaire[Principal_Format-1]) ) + Print_dans_fenetre(46,176,Principal_Commentaire,CM_Noir,CM_Clair); + Afficher_curseur(); + } + + Nouvelle_preview=0; + Etat_chrono=0; // Etat du chrono = Attente d'un XŠme de seconde + // On lit le temps de d‚part du chrono + Initialiser_chrono(Config.Chrono_delay); + } + + if (!Etat_chrono) // Prendre une nouvelle mesure du chrono et regarder + Tester_chrono(); // s'il ne faut pas afficher la preview + + if (Etat_chrono==1) // Il faut afficher la preview + { + if ( (Principal_File_list_Position+Principal_File_list_Decalage>=Liste_Nb_repertoires) && (Liste_Nb_elements) ) + { + strcpy(Principal_Repertoire_fichier,Principal_Repertoire_courant); + + Effacer_curseur(); + Charger_image(Image); + Afficher_curseur(); + + // AprŠs le chargement de la preview, on restaure tout ce qui aurait + // pu ˆtre modifi‚ par le chargement de l'image: + memcpy(Principal_Palette,Palette_initiale,sizeof(T_Palette)); + Principal_Image_modifiee=Image_modifiee_initiale; + Principal_Largeur_image=Largeur_image_initiale; + Principal_Hauteur_image=Hauteur_image_initiale; + } + + Etat_chrono=2; // On arrˆte le chrono + } + } + while ( (!On_a_clicke_sur_OK) && (Bouton_clicke!=2) ); + + // Si on annule, on restaure l'ancien commentaire + if (Bouton_clicke==2) + strcpy(Principal_Commentaire,Commentaire_initial); + + // On restaure les donn‚es de l'image qui ont certainement ‚t‚ modifi‚es + // par la preview. + memcpy(Principal_Palette,Palette_initiale,sizeof(T_Palette)); + Back_color=Back_color_initiale; + Principal_Image_modifiee=Image_modifiee_initiale; + Principal_Largeur_image=Largeur_image_initiale; + Principal_Hauteur_image=Hauteur_image_initiale; + Set_palette(Principal_Palette); + + Calculer_couleurs_menu_optimales(Principal_Palette); + Temp=(Fenetre_Pos_Y+(Fenetre_Hauteur*Menu_Facteur_Y)1024) || (Ecran_original_Y>768)) + { + Ecran_original_X=1024; + Ecran_original_Y=768; + } + + // Maintenant on peut chercher le mode qui correspond le mieux + Meilleur_mode=Resolution_actuelle; + Meilleure_largeur=0; + Meilleure_hauteur=0; + + + for (Mode=MODE_320_200; Mode<=MODE_1024_768; Mode++) + { + if (Mode_video[Mode].Etat<2) + { + Temp_X=Mode_video[Mode].Largeur; + Temp_Y=Mode_video[Mode].Hauteur; + + if ( (Ecran_original_X-TOLERANCE_X<=Temp_X) + && (Ecran_original_Y-TOLERANCE_Y<=Temp_Y) ) + return Mode; + else + { + if ( (Meilleure_largeur<=Temp_X) + && (Meilleure_hauteur<=Temp_Y) + && (Temp_X-TOLERANCE_X<=Ecran_original_X) + && (Temp_Y-TOLERANCE_Y<=Ecran_original_Y) ) + { + Meilleure_largeur=Temp_X; + Meilleure_hauteur=Temp_Y; + Meilleur_mode=Mode; + } + } + } + } + + return Meilleur_mode; +} + + +void Swapper_infos_selecteurs_image_et_brosse(void) +{ + char Chaine_temporaire[256]; + byte Octet_temporaire; + short Entier_temporaire; + + + strcpy(Chaine_temporaire ,Brosse_Repertoire_fichier); + strcpy(Brosse_Repertoire_fichier ,Principal_Repertoire_fichier); + strcpy(Principal_Repertoire_fichier,Chaine_temporaire); + + strcpy(Chaine_temporaire ,Brosse_Nom_fichier); + strcpy(Brosse_Nom_fichier ,Principal_Nom_fichier); + strcpy(Principal_Nom_fichier,Chaine_temporaire); + + Octet_temporaire =Brosse_Format_fichier; + Brosse_Format_fichier =Principal_Format_fichier; + Principal_Format_fichier=Octet_temporaire; + + Octet_temporaire=Brosse_Format; + Brosse_Format =Principal_Format; + Principal_Format=Octet_temporaire; + + Entier_temporaire =Brosse_File_list_Position; + Brosse_File_list_Position =Principal_File_list_Position; + Principal_File_list_Position=Entier_temporaire; + + Entier_temporaire =Brosse_File_list_Decalage; + Brosse_File_list_Decalage =Principal_File_list_Decalage; + Principal_File_list_Decalage=Entier_temporaire; + + strcpy(Chaine_temporaire ,Brosse_Repertoire_courant); + strcpy(Brosse_Repertoire_courant ,Principal_Repertoire_courant); + strcpy(Principal_Repertoire_courant,Chaine_temporaire); + + strcpy(Chaine_temporaire ,Brosse_Commentaire); + strcpy(Brosse_Commentaire ,Principal_Commentaire); + strcpy(Principal_Commentaire,Chaine_temporaire); +} + + +void Load_picture(byte Image) + // Image=1 => On charge/sauve une image + // Image=0 => On charge/sauve une brosse +{ + // Donn‚es initiales du fichier (au cas o— on voudrait annuler) + char Repertoire_fichier_initial[256]; + char Nom_fichier_initial[13]; + byte Format_fichier_initial; + byte Ne_pas_restaurer; + byte Utiliser_palette_brosse; + struct Composantes * Palette_initiale; + byte Ancienne_forme_curseur; + short Principal_Largeur_image_initiale=Principal_Largeur_image; + short Principal_Hauteur_image_initiale=Principal_Hauteur_image; + char Commentaire_initial[TAILLE_COMMENTAIRE+1]; + int Nouveau_mode; + + + if (!Image) + Swapper_infos_selecteurs_image_et_brosse(); + + strcpy(Repertoire_fichier_initial,Principal_Repertoire_fichier); + strcpy(Nom_fichier_initial ,Principal_Nom_fichier); + Format_fichier_initial=Principal_Format_fichier; + + if (!Image) + { + Palette_initiale=(struct Composantes *)malloc(sizeof(T_Palette)); + memcpy(Palette_initiale,Principal_Palette,sizeof(T_Palette)); + } + + Ne_pas_restaurer=Bouton_Load_ou_Save(1,Image); + + if (Ne_pas_restaurer) + { + if (Image) + { + if (Principal_Image_modifiee) + Ne_pas_restaurer=Demande_de_confirmation("Discard unsaved changes?"); + } + else + Utiliser_palette_brosse=Demande_de_confirmation("Use the palette of the brush?"); + } + + if (Ne_pas_restaurer) + { + Ancienne_forme_curseur=Forme_curseur; + Effacer_curseur(); + Forme_curseur=FORME_CURSEUR_SABLIER; + Afficher_curseur(); + + if (Image) + { + // Si c'est une image qu'on charge, on efface l'ancien commentaire + // C'est loin d'ˆtre indispensable, m'enfin bon... + if (Format_Backup_done[Principal_Format_fichier-1]) + Principal_Commentaire[0]='\0'; + + Ecran_original_X=0; + Ecran_original_Y=0; + } + else + Pixel_de_chargement=Pixel_Chargement_dans_brosse; + + Charger_image(Image); + + if (!Image) + { + if (!Utiliser_palette_brosse) + memcpy(Principal_Palette,Palette_initiale,sizeof(T_Palette)); + + if (Erreur_fichier==3) // On ne peut pas allouer la brosse + { + if (Brosse) free(Brosse); + Brosse=(byte *)malloc(1*1); + Brosse_Hauteur=1; + Brosse_Largeur=1; + *Brosse=Fore_color; + + if (Smear_Brosse) free(Smear_Brosse); + Smear_Brosse=(byte *)malloc(TAILLE_MAXI_PINCEAU*TAILLE_MAXI_PINCEAU); + Smear_Brosse_Hauteur=TAILLE_MAXI_PINCEAU; + Smear_Brosse_Largeur=TAILLE_MAXI_PINCEAU; + } + else + { + Brosse_Largeur=Principal_Largeur_image; + Brosse_Hauteur=Principal_Hauteur_image; + 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; + } + + Tiling_Decalage_X=0; + Tiling_Decalage_Y=0; + + Brosse_Decalage_X=(Brosse_Largeur>>1); + Brosse_Decalage_Y=(Brosse_Hauteur>>1); + + Principal_Largeur_image=Principal_Largeur_image_initiale; + Principal_Hauteur_image=Principal_Hauteur_image_initiale; + Pixel_de_chargement=Pixel_Chargement_dans_ecran_courant; + + Enclencher_bouton(BOUTON_DESSIN,A_GAUCHE); + if (Config.Auto_discontinuous) + { + // On se place en mode Dessin discontinu … la main + while (Operation_en_cours!=OPERATION_DESSIN_DISCONTINU) + Enclencher_bouton(BOUTON_DESSIN,A_DROITE); + } + Effacer_curseur(); + // On passe en brosse couleur: + Changer_la_forme_du_pinceau(FORME_PINCEAU_BROSSE_COULEUR); + } + else + { + Effacer_curseur(); + Forme_curseur=Ancienne_forme_curseur; + } + + if ( (Erreur_fichier==1) || (!Format_Backup_done[Principal_Format_fichier-1]) ) + { + Ne_pas_restaurer=0; + if (Erreur_fichier!=1) + Calculer_couleurs_menu_optimales(Principal_Palette); + } + else + { + if (Image) + { + if (Loupe_Mode) + { + Tracer_cadre_de_bouton_du_menu(BOUTON_LOUPE,0); + Pixel_Preview=Pixel_Preview_Normal; + Loupe_Mode=0; + } + + Nouveau_mode=Meilleur_mode_video(); + if ((Config.Auto_set_res) && (Nouveau_mode!=Resolution_actuelle)) + { + Initialiser_mode_video(Nouveau_mode); + Afficher_menu(); + } + else + { + Principal_Decalage_X=0; + Principal_Decalage_Y=0; + Calculer_limites(); + Calculer_coordonnees_pinceau(); + } + } + + Calculer_couleurs_menu_optimales(Principal_Palette); + Afficher_ecran(); + + if (Image) + Principal_Image_modifiee=0; + } + Afficher_menu(); + Afficher_curseur(); + } + + if (!Image) + free(Palette_initiale); + + if (!Ne_pas_restaurer) + { + strcpy(Principal_Nom_fichier ,Nom_fichier_initial); + strcpy(Principal_Repertoire_fichier,Repertoire_fichier_initial); + Principal_Format_fichier =Format_fichier_initial; + } + + if (!Image) + Swapper_infos_selecteurs_image_et_brosse(); + + Print_nom_fichier(); + Set_palette(Principal_Palette); +} + + +void Bouton_Load(void) +{ + // On sauve l'‚tat actuel des paramŠtres de l'image pour pouvoir les + // restituer en cas d'erreur n'affectant pas l'image + Upload_infos_page_principal(Principal_Backups->Pages); + + Load_picture(1); +} + + +void Bouton_Reload(void) +{ + byte Ancienne_forme_curseur; + int Nouveau_mode; + + // On sauve l'‚tat actuel des paramŠtres de l'image pour pouvoir les + // restituer en cas d'erreur n'affectant pas l'image + Upload_infos_page_principal(Principal_Backups->Pages); + + if ( (!Principal_Image_modifiee) || Demande_de_confirmation("Discard unsaved changes ?") ) + { + Effacer_curseur(); + Ancienne_forme_curseur=Forme_curseur; + Forme_curseur=FORME_CURSEUR_SABLIER; + Afficher_curseur(); + + Ecran_original_X=0; + Ecran_original_Y=0; + Charger_image(1); + + Effacer_curseur(); + Forme_curseur=Ancienne_forme_curseur; + + if (Erreur_fichier!=1) + { + if (Loupe_Mode) + { + Tracer_cadre_de_bouton_du_menu(BOUTON_LOUPE,0); + Pixel_Preview=Pixel_Preview_Normal; + Loupe_Mode=0; + } + + Nouveau_mode=Meilleur_mode_video(); + if ( ((Config.Auto_set_res) && (Nouveau_mode!=Resolution_actuelle)) && + (!Une_resolution_a_ete_passee_en_parametre) ) + { + Initialiser_mode_video(Nouveau_mode); + Afficher_menu(); + } + else + { + Principal_Decalage_X=0; + Principal_Decalage_Y=0; + Calculer_limites(); + Calculer_coordonnees_pinceau(); + } + + Afficher_ecran(); + + Principal_Image_modifiee=0; + } + } + else + Effacer_curseur(); + + Calculer_couleurs_menu_optimales(Principal_Palette); + Afficher_menu(); + if (Config.Afficher_limites_image) + Afficher_limites_de_l_image(); + + Desenclencher_bouton(BOUTON_CHARGER); + + Afficher_curseur(); +} + + +void Nom_fichier_backup(char * Nom, char * Nom_backup) +{ + short Curseur; + + strcpy(Nom_backup,Nom); + for (Curseur=strlen(Nom)-strlen(Principal_Nom_fichier); Nom_backup[Curseur]!='.'; Curseur++); + Nom_backup[Curseur+1]='\0'; + strcat(Nom_backup,"BAK"); +} + + +void Backup_du_fichier_sauvegarde(void) +{ + char Nom_du_fichier[256]; // Nom complet du fichier + char Nouveau_nom_du_fichier[256]; // Nom complet du fichier backup + + Nom_fichier_complet(Nom_du_fichier,0); + // Calcul du nom complet du fichier backup + Nom_fichier_backup(Nom_du_fichier,Nouveau_nom_du_fichier); + + Erreur_fichier=0; + + // On fait un backup si le nom du fichier n'est pas celui qu'on a choisi + // pour nommer les backups (c'est ‚vident!). + if (strcmp(Nouveau_nom_du_fichier,Nom_du_fichier)) + { + // S'il y avait d‚j… un fichier Backup, on l'efface + if ((Fichier_existe(Nouveau_nom_du_fichier)) + && (remove(Nouveau_nom_du_fichier)!=0)) + Erreur_fichier=1; + + if ((!Erreur_fichier) + && (rename(Nom_du_fichier,Nouveau_nom_du_fichier)!=0)) + Erreur_fichier=1; + } +} + + +void Save_picture(byte Image) + // Image=1 => On charge/sauve une image + // Image=0 => On charge/sauve une brosse +{ + // Donn‚es initiales du fichier (au cas o— on voudrait annuler) + char Repertoire_fichier_initial[256]; + char Nom_fichier_initial[13]; + byte Format_fichier_initial; + byte Ne_pas_restaurer; + byte Ancienne_forme_curseur; + short Principal_Largeur_image_Backup=Principal_Largeur_image; + short Principal_Hauteur_image_Backup=Principal_Hauteur_image; + char Commentaire_initial[TAILLE_COMMENTAIRE+1]; + + + if (!Image) + Swapper_infos_selecteurs_image_et_brosse(); + + strcpy(Repertoire_fichier_initial,Principal_Repertoire_fichier); + strcpy(Nom_fichier_initial ,Principal_Nom_fichier); + Format_fichier_initial=Principal_Format_fichier; + + Ne_pas_restaurer=Bouton_Load_ou_Save(0,Image); + + if (Ne_pas_restaurer && Fichier_existe(Principal_Nom_fichier)) + { + Ne_pas_restaurer=Demande_de_confirmation("Erase old file ?"); + if ((Ne_pas_restaurer) && (Config.Backup)) + { + Backup_du_fichier_sauvegarde(); + if (Erreur_fichier) + { + Ne_pas_restaurer=0; + Erreur(0); + } + } + } + + if (Ne_pas_restaurer) + { + Ancienne_forme_curseur=Forme_curseur; + Effacer_curseur(); + Forme_curseur=FORME_CURSEUR_SABLIER; + Afficher_curseur(); + + if (Image) + Sauver_image(Image); + else + { + Principal_Largeur_image=Brosse_Largeur; + Principal_Hauteur_image=Brosse_Hauteur; + Sauver_image(Image); + Principal_Largeur_image=Principal_Largeur_image_Backup; + Principal_Hauteur_image=Principal_Hauteur_image_Backup; + } + + Effacer_curseur(); + Forme_curseur=Ancienne_forme_curseur; + + if ((Erreur_fichier==1) || (!Format_Backup_done[Principal_Format_fichier-1])) + Ne_pas_restaurer=0; + + Afficher_curseur(); + } + + if (!Ne_pas_restaurer) + { + strcpy(Principal_Nom_fichier ,Nom_fichier_initial); + strcpy(Principal_Repertoire_fichier,Repertoire_fichier_initial); + Principal_Format_fichier =Format_fichier_initial; + } + + if (!Image) + Swapper_infos_selecteurs_image_et_brosse(); + + Print_nom_fichier(); + Set_palette(Principal_Palette); +} + + +void Bouton_Save(void) +{ + Save_picture(1); +} + + +void Bouton_Autosave(void) +{ + byte Ancienne_forme_curseur; + char Nom_du_fichier[256]; + byte Le_fichier_existe; + + + Nom_fichier_complet(Nom_du_fichier,0); + Le_fichier_existe=Fichier_existe(Nom_du_fichier); + + if ( (!Le_fichier_existe) || Demande_de_confirmation("Erase old file ?") ) + { + if ((Le_fichier_existe) && (Config.Backup)) + Backup_du_fichier_sauvegarde(); + else + Erreur_fichier=0; + + Effacer_curseur(); + + if (!Erreur_fichier) + { + Ancienne_forme_curseur=Forme_curseur; + Forme_curseur=FORME_CURSEUR_SABLIER; + Afficher_curseur(); + + Sauver_image(1); + + Effacer_curseur(); + Forme_curseur=Ancienne_forme_curseur; + } + else + Erreur(0); + } + else + Effacer_curseur(); + + Desenclencher_bouton(BOUTON_SAUVER); + + Afficher_curseur(); +} + + +// -- Gestion des boutons de ligne ------------------------------------------ + +void Bouton_Lignes(void) +{ + Effacer_curseur(); + Demarrer_pile_operation(Ligne_en_cours); + Afficher_curseur(); +} + + +void Bouton_Lignes_Switch_mode(void) +{ + if (Ligne_en_cours==OPERATION_LIGNE) + Ligne_en_cours=OPERATION_K_LIGNE; + else + { + if (Ligne_en_cours==OPERATION_K_LIGNE) + Ligne_en_cours=OPERATION_LIGNES_CENTREES; + else + Ligne_en_cours=OPERATION_LIGNE; + } + + Effacer_curseur(); + Afficher_sprite_dans_menu(BOUTON_LIGNES,Ligne_en_cours-OPERATION_LIGNE+6); + Demarrer_pile_operation(Ligne_en_cours); + Afficher_curseur(); +} + + +// -- Bouton de brosse ------------------------------------------------------ + +void Bouton_Brosse(void) +{ + Effacer_curseur(); + + if (Operation_en_cours!=OPERATION_PRISE_BROSSE) + Demarrer_pile_operation(OPERATION_PRISE_BROSSE); + else + Desenclencher_bouton(BOUTON_BROSSE); + + Afficher_curseur(); +} + + +void Bouton_desenclencher_Brosse(void) +{ + // On fait de notre mieux pour restaurer l'ancienne op‚ration: + Demarrer_pile_operation(Operation_avant_interruption); +} + + +void Bouton_Restaurer_brosse(void) +{ + Effacer_curseur(); + // On passe en brosse couleur: + Changer_la_forme_du_pinceau(FORME_PINCEAU_BROSSE_COULEUR); + + Desenclencher_bouton(BOUTON_BROSSE); + Desenclencher_bouton(BOUTON_POLYBROSSE); + + Afficher_curseur(); +} + + +// -- Bouton de prise de brosse au lasso ------------------------------------ + +void Bouton_Lasso(void) +{ + Effacer_curseur(); + + if (Operation_en_cours!=OPERATION_POLYBROSSE) + { + Pinceau_Forme_avant_lasso=Pinceau_Forme; + Pinceau_Forme=FORME_PINCEAU_POINT; + Demarrer_pile_operation(OPERATION_POLYBROSSE); + } + else + Desenclencher_bouton(BOUTON_POLYBROSSE); + + Afficher_curseur(); +} + + +void Bouton_desenclencher_Lasso(void) +{ + // On fait de notre mieux pour restaurer l'ancienne op‚ration: + Demarrer_pile_operation(Operation_avant_interruption); + Pinceau_Forme=Pinceau_Forme_avant_lasso; +} + + +// -- Bouton de pipette ----------------------------------------------------- + +void Bouton_Pipette(void) +{ + Effacer_curseur(); + + if (Operation_en_cours!=OPERATION_PIPETTE) + { + Pipette_Couleur=-1; + Demarrer_pile_operation(OPERATION_PIPETTE); + Pinceau_Forme_avant_pipette=Pinceau_Forme; + Pinceau_Forme=FORME_PINCEAU_POINT; + if (Operation_avant_interruption!=OPERATION_REMPLACER) + if ( (Mouse_Y=Principal_X_Zoom) ) ) + Print_dans_menu("X: Y: ( )",0); + } + else + Desenclencher_bouton(BOUTON_PIPETTE); + + Afficher_curseur(); +} + + +void Bouton_desenclencher_Pipette(void) +{ + if (Operation_avant_interruption!=OPERATION_REMPLACER) + if ( (Mouse_Y=Principal_X_Zoom) ) ) + Print_dans_menu("X: Y: ",0); + + // On fait de notre mieux pour restaurer l'ancienne op‚ration: + if (Operation_en_cours==OPERATION_PIPETTE) + { + Demarrer_pile_operation(Operation_avant_interruption); + Pinceau_Forme=Pinceau_Forme_avant_pipette; + } +} + + + // -- Inversion de la couleur Fore et de la couleur Back -- +void Bouton_Inverser_foreback(void) +{ + byte Couleur_temporaire; + + Effacer_curseur(); + + Encadrer_couleur_menu(CM_Noir); + + Couleur_temporaire=Fore_color; + Fore_color =Back_color; + Back_color =Couleur_temporaire; + + Recadrer_palette(); + + Encadrer_couleur_menu(CM_Blanc); + + Afficher_foreback(); + Desenclencher_bouton(BOUTON_PIPETTE); + + Afficher_curseur(); +} + + +// -- Gestion du bouton Loupe ----------------------------------------------- + +byte On_vient_du_menu_de_facteurs_de_zoom=0; + +void Bouton_Loupe(void) +{ + Effacer_curseur(); + if ( (Operation_en_cours==OPERATION_LOUPE) || (Loupe_Mode) ) + { + Desenclencher_bouton(BOUTON_LOUPE); + } + else + { + Ancien_Principal_Decalage_X=Principal_Decalage_X; + Ancien_Principal_Decalage_Y=Principal_Decalage_Y; + Calculer_donnees_loupe(); + if ((!Config.Fast_zoom) || (Mouse_Y>=Menu_Ordonnee) || On_vient_du_menu_de_facteurs_de_zoom) + { + On_vient_du_menu_de_facteurs_de_zoom=0; + Demarrer_pile_operation(OPERATION_LOUPE); + } + else + { /* Ceci est de la duplication de code de presque toute l'op‚ration de */ + /* la loupe... Il serait peut-ˆtre plus propre de faire une proc‚dure */ + /* qui s'en charge... */ + // On passe en mode loupe + Loupe_Mode=1; + + // La fonction d'affichage dans la partie image est d‚sormais un affichage + // sp‚cial loupe. + Pixel_Preview=Pixel_Preview_Loupe; + + // On calcule l'origine de la loupe + Loupe_Decalage_X=Mouse_X-(Loupe_Largeur>>1); + Loupe_Decalage_Y=Mouse_Y-(Loupe_Hauteur>>1); + + // Calcul du coin haut_gauche de la fenˆtre devant ˆtre zoom‚e DANS L'ECRAN + if (Loupe_Decalage_X+Loupe_Largeur>=Limite_Droite-Principal_Decalage_X) + Loupe_Decalage_X=Limite_Droite-Loupe_Largeur-Principal_Decalage_X+1; + if (Loupe_Decalage_Y+Loupe_Hauteur>=Limite_Bas-Principal_Decalage_Y) + Loupe_Decalage_Y=Limite_Bas-Loupe_Hauteur-Principal_Decalage_Y+1; + + // Calcul des coordonn‚es absolues de ce coin DANS L'IMAGE + Loupe_Decalage_X+=Principal_Decalage_X; + Loupe_Decalage_Y+=Principal_Decalage_Y; + + if (Loupe_Decalage_X<0) + Loupe_Decalage_X=0; + if (Loupe_Decalage_Y<0) + Loupe_Decalage_Y=0; + + // On calcule les bornes visibles dans l'‚cran + Recadrer_ecran_par_rapport_au_zoom(); + Calculer_limites(); + Afficher_ecran(); + + // Repositionner le curseur en fonction des coordonn‚es visibles + Calculer_coordonnees_pinceau(); + } + } + Afficher_curseur(); +} + + +void Bouton_Menu_Loupe(void) +{ + short Bouton_clicke; + + Ouvrir_fenetre(141,114,"Zoom factors"); + + Fenetre_Definir_bouton_normal(45,88,51,14,"Cancel",0,1,0x0001); // 1 + + Fenetre_Definir_bouton_normal( 9,25,27,14, "x2",0,Loupe_Facteur!= 2,0x003B); // 2 + Fenetre_Definir_bouton_normal( 41,25,27,14, "x3",0,Loupe_Facteur!= 3,0x003C); // 3 + Fenetre_Definir_bouton_normal( 73,25,27,14, "x4",0,Loupe_Facteur!= 4,0x003D); // 4 + Fenetre_Definir_bouton_normal(105,25,27,14, "x5",0,Loupe_Facteur!= 5,0x003E); // 5 + Fenetre_Definir_bouton_normal( 9,45,27,14, "x6",0,Loupe_Facteur!= 6,0x003F); // 6 + Fenetre_Definir_bouton_normal( 41,45,27,14, "x8",0,Loupe_Facteur!= 8,0x0040); // 7 + Fenetre_Definir_bouton_normal( 73,45,27,14,"x10",0,Loupe_Facteur!=10,0x0041); // 8 + Fenetre_Definir_bouton_normal(105,45,27,14,"x12",0,Loupe_Facteur!=12,0x0042); // 9 + Fenetre_Definir_bouton_normal( 9,65,27,14,"x14",0,Loupe_Facteur!=14,0x0043); // 10 + Fenetre_Definir_bouton_normal( 41,65,27,14,"x16",0,Loupe_Facteur!=16,0x0044); // 11 + Fenetre_Definir_bouton_normal( 73,65,27,14,"x18",0,Loupe_Facteur!=18,0x0085); // 12 + Fenetre_Definir_bouton_normal(105,65,27,14,"x20",0,Loupe_Facteur!=20,0x0086); // 13 + + Afficher_curseur(); + + do + { + Bouton_clicke=Fenetre_Bouton_clicke(); + } + while (Bouton_clicke<=0); + + if (Bouton_clicke>1) + { + Menu_Ordonnee=Menu_Ordonnee_avant_fenetre; + Changer_facteur_loupe(Bouton_clicke-2); + } + + Fermer_fenetre(); + + if ( (Bouton_clicke==1) && (!Loupe_Mode) && (Operation_en_cours!=OPERATION_LOUPE) ) + Desenclencher_bouton(BOUTON_LOUPE); + + Afficher_curseur(); + + if ( (Bouton_clicke>1) && (!Loupe_Mode) && (Operation_en_cours!=OPERATION_LOUPE) ) + { + On_vient_du_menu_de_facteurs_de_zoom=1; + Enclencher_bouton(BOUTON_LOUPE,A_GAUCHE); + } +} + + +void Bouton_desenclencher_Loupe(void) +{ + if (Loupe_Mode) + { + // On sort du mode loupe + Loupe_Mode=0; + + /* + // --> Recalculer le d‚calage de l'‚cran lorsqu'on sort de la loupe <-- + // Centrage "brut" de l‚cran par rapport … la loupe + Principal_Decalage_X=Loupe_Decalage_X-((Largeur_ecran-Loupe_Largeur)>>1); + Principal_Decalage_Y=Loupe_Decalage_Y-((Menu_Ordonnee-Loupe_Hauteur)>>1); + */ + // Correction en cas de d‚bordement de l'image + if (Ancien_Principal_Decalage_X+Largeur_ecran>Principal_Largeur_image) + Principal_Decalage_X=Principal_Largeur_image-Largeur_ecran; + else + Principal_Decalage_X=Ancien_Principal_Decalage_X; + if (Principal_Decalage_X<0) + Principal_Decalage_X=0; + + if (Ancien_Principal_Decalage_Y+Menu_Ordonnee>Principal_Hauteur_image) + Principal_Decalage_Y=Principal_Hauteur_image-Menu_Ordonnee; + else + Principal_Decalage_Y=Ancien_Principal_Decalage_Y; + if (Principal_Decalage_Y<0) + Principal_Decalage_Y=0; + + // La fonction d'affichage dans l'image est d‚sormais un affichage normal. + Pixel_Preview=Pixel_Preview_Normal; + + // Calculer les bornes visibles dans l'‚cran + Calculer_limites(); + Afficher_ecran(); // <=> Display_screen(); + // Repositionner le curseur en fonction des coordonn‚es visibles + Calculer_coordonnees_pinceau(); + } + else // On fait de notre mieux pour restaurer l'ancienne op‚ration: + Demarrer_pile_operation(Operation_avant_interruption); +} + + +// -------------------------------- Grille ----------------------------------- + +void Bouton_Snap_Mode(void) +{ + Effacer_curseur(); + Snap_Mode=!Snap_Mode; + Calculer_coordonnees_pinceau(); + Afficher_curseur(); +} + + +void Bouton_Menu_Grille(void) +{ + short Bouton_clicke; + word X_choisi =Snap_Largeur; + word Y_choisi =Snap_Hauteur; + short dX_choisi=Snap_Decalage_X; + short dY_choisi=Snap_Decalage_Y; + + struct Fenetre_Bouton_special * Bouton_saisie_X; + struct Fenetre_Bouton_special * Bouton_saisie_Y; + struct Fenetre_Bouton_special * Bouton_saisie_dX; + struct Fenetre_Bouton_special * Bouton_saisie_dY; + + char Chaine[3]; + + + Ouvrir_fenetre(133,98,"Grid"); + + Fenetre_Definir_bouton_normal(12,72,51,14,"Cancel",0,1,0x0001); // 1 + Fenetre_Definir_bouton_normal(70,72,51,14,"OK" ,0,1,0x001C); // 2 + + Print_dans_fenetre(19,26, "X:",CM_Fonce,CM_Clair); + Fenetre_Definir_bouton_saisie(37,24,2); // 3 + Bouton_saisie_X=Fenetre_Liste_boutons_special; + Num2str(X_choisi,Chaine,2); + Fenetre_Contenu_bouton_saisie(Bouton_saisie_X,Chaine); + + Print_dans_fenetre(19,47, "Y:",CM_Fonce,CM_Clair); + Fenetre_Definir_bouton_saisie(37,45,2); // 4 + Bouton_saisie_Y=Fenetre_Liste_boutons_special; + Num2str(Y_choisi,Chaine,2); + Fenetre_Contenu_bouton_saisie(Bouton_saisie_Y,Chaine); + + Print_dans_fenetre(69,26,"dX:",CM_Fonce,CM_Clair); + Fenetre_Definir_bouton_saisie(95,24,2); // 5 + Bouton_saisie_dX=Fenetre_Liste_boutons_special; + Num2str(dX_choisi,Chaine,2); + Fenetre_Contenu_bouton_saisie(Bouton_saisie_dX,Chaine); + + Print_dans_fenetre(69,47,"dY:",CM_Fonce,CM_Clair); + Fenetre_Definir_bouton_saisie(95,45,2); // 6 + Bouton_saisie_dY=Fenetre_Liste_boutons_special; + Num2str(dY_choisi,Chaine,2); + Fenetre_Contenu_bouton_saisie(Bouton_saisie_dY,Chaine); + + Afficher_curseur(); + + do + { + Bouton_clicke=Fenetre_Bouton_clicke(); + + switch (Bouton_clicke) + { + case 3 : + Effacer_curseur(); + Num2str(X_choisi,Chaine,2); + Readline(39,26,Chaine,2,1); + X_choisi=atoi(Chaine); + // On corrige les dimensions + if ((!X_choisi) || (X_choisi>80)) + { + if (!X_choisi) + X_choisi=1; + else + X_choisi=80; + Num2str(X_choisi,Chaine,2); + Fenetre_Contenu_bouton_saisie(Bouton_saisie_X,Chaine); + } + if (dX_choisi>=X_choisi) + { + dX_choisi=X_choisi-1; + Num2str(dX_choisi,Chaine,2); + Fenetre_Contenu_bouton_saisie(Bouton_saisie_dX,Chaine); + } + Afficher_curseur(); + break; + case 4 : + Effacer_curseur(); + Num2str(Y_choisi,Chaine,2); + Readline(39,47,Chaine,2,1); + Y_choisi=atoi(Chaine); + // On corrige les dimensions + if ((!Y_choisi) || (Y_choisi>80)) + { + if (!Y_choisi) + Y_choisi=1; + else + Y_choisi=80; + Num2str(Y_choisi,Chaine,2); + Fenetre_Contenu_bouton_saisie(Bouton_saisie_Y,Chaine); + } + if (dY_choisi>=Y_choisi) + { + dY_choisi=Y_choisi-1; + Num2str(dY_choisi,Chaine,2); + Fenetre_Contenu_bouton_saisie(Bouton_saisie_dY,Chaine); + } + Afficher_curseur(); + break; + case 5 : + Effacer_curseur(); + Num2str(dX_choisi,Chaine,2); + Readline(97,26,Chaine,2,1); + dX_choisi=atoi(Chaine); + // On corrige les dimensions + if (dX_choisi>79) + dX_choisi=79; + if (dX_choisi>=X_choisi) + dX_choisi=X_choisi-1; + + Num2str(dX_choisi,Chaine,2); + Fenetre_Contenu_bouton_saisie(Bouton_saisie_dX,Chaine); + + Afficher_curseur(); + break; + case 6 : + Effacer_curseur(); + Num2str(dY_choisi,Chaine,2); + Readline(97,47,Chaine,2,1); + dY_choisi=atoi(Chaine); + // On corrige les dimensions + if (dY_choisi>79) + dY_choisi=79; + if (dY_choisi>=Y_choisi) + dY_choisi=Y_choisi-1; + + Num2str(dY_choisi,Chaine,2); + Fenetre_Contenu_bouton_saisie(Bouton_saisie_dY,Chaine); + + Afficher_curseur(); + } + } + while ( (Bouton_clicke!=1) && (Bouton_clicke!=2) ); + + if (Bouton_clicke==2) // OK + { + Snap_Largeur=X_choisi; + Snap_Hauteur=Y_choisi; + Snap_Decalage_X=dX_choisi; + Snap_Decalage_Y=dY_choisi; + Snap_Mode=1; + } + + Fermer_fenetre(); + + if ( (Bouton_clicke==2) && (!Snap_Mode) ) + Bouton_Snap_Mode(); + + Afficher_curseur(); +} + + +// ----------------------- Modifications de brosse --------------------------- + +void Bouton_Brush_FX(void) +{ + short Bouton_clicke; + short Indice; + + Ouvrir_fenetre(310,162,"Brush effects"); + + Fenetre_Afficher_cadre( 6,19,298,61); + Fenetre_Afficher_cadre( 6,83,122,53); + Fenetre_Afficher_cadre(137,83,167,53); + + Fenetre_Definir_bouton_normal(236,141, 67,14,"Cancel" ,0,1,0x0001); // 1 + Fenetre_Definir_bouton_normal( 19, 46, 27,14,"X\035" ,1,1,0x002D); // 2 + Fenetre_Definir_bouton_normal( 19, 61, 27,14,"Y\022" ,1,1,0x0015); // 3 + Fenetre_Definir_bouton_normal( 58, 46, 37,14,"90ø" ,0,1,0xFFFF); // 4 + Fenetre_Definir_bouton_normal( 96, 46, 37,14,"180ø" ,0,1,0xFFFF); // 5 + Fenetre_Definir_bouton_normal( 58, 61, 75,14,"any angle" ,0,1,0xFFFF); // 6 + Fenetre_Definir_bouton_normal(145, 46, 67,14,"Stretch" ,2,1,0x0014); // 7 + Fenetre_Definir_bouton_normal(145, 61, 67,14,"Distort" ,1,1,0x0020); // 8 + Fenetre_Definir_bouton_normal(155, 99,131,14,"Recolorize" ,1,1,0x0013); // 9 + Fenetre_Definir_bouton_normal(155,117,131,14,"Get brush colors",1,1,0x0022); // 10 + + // Boutons repr‚sentant les coins du brush handle: (HG,HD,C,BG,BD) + Fenetre_Definir_bouton_normal( 75, 90,11,11,"",0,1,0x0047); // 11 + Fenetre_Definir_bouton_normal(103, 90,11,11,"",0,1,0x0049); // 12 + Fenetre_Definir_bouton_normal( 89,104,11,11,"",0,1,0x004C); // 13 + Fenetre_Definir_bouton_normal( 75,118,11,11,"",0,1,0x004F); // 14 + Fenetre_Definir_bouton_normal(103,118,11,11,"",0,1,0x0051); // 15 + + Fenetre_Definir_bouton_normal(224,46,67,14,"Outline",1,1,0x0018); // 16 + Fenetre_Definir_bouton_normal(224,61,67,14,"Nibble" ,1,1,0x0031); // 17 + + Fenetre_Definir_bouton_normal( 7,141, 60,14,"Load",1,1,0x0026); // 18 + Fenetre_Definir_bouton_normal( 70,141, 60,14,"Save",1,1,0x001F); // 19 + + Print_dans_fenetre( 80, 24,"Shape modifications",CM_Fonce,CM_Clair); + Print_dans_fenetre( 10, 36,"Mirror",CM_Fonce,CM_Clair); + Print_dans_fenetre( 72, 36,"Rotate",CM_Fonce,CM_Clair); + Print_dans_fenetre(155, 36,"Deform",CM_Fonce,CM_Clair); + Print_dans_fenetre(230, 36,"Borders",CM_Fonce,CM_Clair); + Print_dans_fenetre(141, 88,"Colors modifications",CM_Fonce,CM_Clair); + Print_dans_fenetre( 20,102,"Brush",CM_Fonce,CM_Clair); + Print_dans_fenetre( 16,110,"handle",CM_Fonce,CM_Clair); + + // Dessin des pointill‚s pour le "brush handle" + for (Indice=0; Indice<13; Indice+=2) + { + Pixel_dans_fenetre( 88+Indice, 92,CM_Fonce); + Pixel_dans_fenetre( 88+Indice,126,CM_Fonce); + Pixel_dans_fenetre( 77,103+Indice,CM_Fonce); + Pixel_dans_fenetre(111,103+Indice,CM_Fonce); + } + // Dessin des coins et du centre pour les boutons du "brush handle" + // Coin HG + Block(Fenetre_Pos_X+(Menu_Facteur_X* 77),Fenetre_Pos_Y+(Menu_Facteur_Y* 92),Menu_Facteur_X*7,Menu_Facteur_Y,CM_Noir); + Block(Fenetre_Pos_X+(Menu_Facteur_X* 77),Fenetre_Pos_Y+(Menu_Facteur_Y* 92),Menu_Facteur_X,Menu_Facteur_Y*7,CM_Noir); + // Coin HD + Block(Fenetre_Pos_X+(Menu_Facteur_X*105),Fenetre_Pos_Y+(Menu_Facteur_Y* 92),Menu_Facteur_X*7,Menu_Facteur_Y,CM_Noir); + Block(Fenetre_Pos_X+(Menu_Facteur_X*111),Fenetre_Pos_Y+(Menu_Facteur_Y* 92),Menu_Facteur_X,Menu_Facteur_Y*7,CM_Noir); + // Centre + Block(Fenetre_Pos_X+(Menu_Facteur_X* 91),Fenetre_Pos_Y+(Menu_Facteur_Y*109),Menu_Facteur_X*7,Menu_Facteur_Y,CM_Noir); + Block(Fenetre_Pos_X+(Menu_Facteur_X* 94),Fenetre_Pos_Y+(Menu_Facteur_Y*106),Menu_Facteur_X,Menu_Facteur_Y*7,CM_Noir); + // Coin BG + Block(Fenetre_Pos_X+(Menu_Facteur_X* 77),Fenetre_Pos_Y+(Menu_Facteur_Y*126),Menu_Facteur_X*7,Menu_Facteur_Y,CM_Noir); + Block(Fenetre_Pos_X+(Menu_Facteur_X* 77),Fenetre_Pos_Y+(Menu_Facteur_Y*120),Menu_Facteur_X,Menu_Facteur_Y*7,CM_Noir); + // Coin BD + Block(Fenetre_Pos_X+(Menu_Facteur_X*105),Fenetre_Pos_Y+(Menu_Facteur_Y*126),Menu_Facteur_X*7,Menu_Facteur_Y,CM_Noir); + Block(Fenetre_Pos_X+(Menu_Facteur_X*111),Fenetre_Pos_Y+(Menu_Facteur_Y*120),Menu_Facteur_X,Menu_Facteur_Y*7,CM_Noir); + + Afficher_curseur(); + + do + { + Bouton_clicke=Fenetre_Bouton_clicke(); + } + while (Bouton_clicke<=0); + + Fermer_fenetre(); + Desenclencher_bouton(BOUTON_EFFETS_BROSSE); + + // Gestion du bouton click‚ + switch (Bouton_clicke) + { + case 2 : // Flip X + Flip_X_LOWLEVEL(); + break; + case 3 : // Flip Y + Flip_Y_LOWLEVEL(); + break; + case 4 : // 90ø Rotation + Rotate_90_deg(); + break; + case 5 : // 180ø Rotation + if (Brosse_Hauteur&1) + { // Brosse de hauteur impaire + Flip_X_LOWLEVEL(); + Flip_Y_LOWLEVEL(); + } + else + Rotate_180_deg_LOWLEVEL(); + Brosse_Decalage_X=(Brosse_Largeur>>1); + Brosse_Decalage_Y=(Brosse_Hauteur>>1); + break; + case 6 : // Any angle rotation + Demarrer_pile_operation(OPERATION_TOURNER_BROSSE); + break; + case 7 : // Stretch + Demarrer_pile_operation(OPERATION_ETIRER_BROSSE); + break; + case 8 : // Distort + Afficher_curseur(); + Message_Non_disponible(); // !!! TEMPORAIRE !!! + Effacer_curseur(); + break; + case 9 : // Recolorize + Remap_brosse(); + break; + case 10 : // Get brush colors + Afficher_curseur(); + Get_colors_from_brush(); + Effacer_curseur(); + break; + case 11 : // Brush Attachment: Top-Left + Brosse_Decalage_X=0; + Brosse_Decalage_Y=0; + break; + case 12 : // Brush Attachment: Top-Right + Brosse_Decalage_X=(Brosse_Largeur-1); + Brosse_Decalage_Y=0; + break; + case 13 : // Brush Attachment: Center + Brosse_Decalage_X=(Brosse_Largeur>>1); + Brosse_Decalage_Y=(Brosse_Hauteur>>1); + break; + case 14 : // Brush Attachment: Bottom-Left + Brosse_Decalage_X=0; + Brosse_Decalage_Y=(Brosse_Hauteur-1); + break; + case 15 : // Brush Attachment: Bottom-Right + Brosse_Decalage_X=(Brosse_Largeur-1); + Brosse_Decalage_Y=(Brosse_Hauteur-1); + break; + case 16 : // Outline + Outline_brush(); + break; + case 17 : // Nibble + Nibble_brush(); + break; + case 18 : // Load + Afficher_curseur(); + Load_picture(0); + Effacer_curseur(); + break; + case 19 : // Save + Afficher_curseur(); + Save_picture(0); + Effacer_curseur(); + break; + } + + Afficher_curseur(); +} + + +// -- Mode Smooth ----------------------------------------------------------- +void Bouton_Smooth_Mode(void) +{ + if (Smooth_Mode) + Fonction_effet=Aucun_effet; + else + { + Fonction_effet=Effet_Smooth; + Shade_Mode=0; + Quick_shade_Mode=0; + Colorize_Mode=0; + Tiling_Mode=0; + Smear_Mode=0; + } + Smooth_Mode=!Smooth_Mode; +} + + +byte Smooth_Matrice_defaut[4][3][3]= +{ + { {1,2,1}, {2,4,2}, {1,2,1} }, + { {1,3,1}, {3,9,3}, {1,3,1} }, + { {0,1,0}, {1,2,1}, {0,1,0} }, + { {2,3,2}, {3,1,3}, {2,3,2} } +}; + +void Bouton_Smooth_Menu(void) +{ + short Bouton_clicke; + short X,Y,I,J; + byte Matrice_choisie[3][3]; + struct Fenetre_Bouton_special * Matrice_Zone_saisie[3][3]; + char Chaine[3]; + + Ouvrir_fenetre(142,109,"Smooth"); + + Fenetre_Definir_bouton_normal(82,59,53,14,"Cancel",0,1,0x0001); // 1 + Fenetre_Definir_bouton_normal(82,88,53,14,"OK" ,0,1,0x001C); // 2 + + Fenetre_Afficher_cadre(6,17,130,37); + for (X=11,Y=0; Y<4; X+=31,Y++) + { + Fenetre_Definir_bouton_normal(X,22,27,27,"",0,1,0xFFFF); // 3,4,5,6 + for (J=0; J<3; J++) + for (I=0; I<3; I++) + Print_char_dans_fenetre(X+2+(I<<3),24+(J<<3),'0'+Smooth_Matrice_defaut[Y][I][J],CM_Noir,CM_Clair); + } + + Fenetre_Afficher_cadre(6,58, 69,45); + for (J=0; J<3; J++) + for (I=0; I<3; I++) + { + Fenetre_Definir_bouton_saisie(10+(I*21),62+(J*13),2); // 7..15 + Matrice_Zone_saisie[I][J]=Fenetre_Liste_boutons_special; + Num2str(Matrice_choisie[I][J]=Smooth_Matrice[I][J],Chaine,2); + Fenetre_Contenu_bouton_saisie(Fenetre_Liste_boutons_special,Chaine); + } + + Afficher_curseur(); + + do + { + Bouton_clicke=Fenetre_Bouton_clicke(); + + if (Bouton_clicke>2) + { + if (Bouton_clicke<=6) + { + memcpy(Matrice_choisie,Smooth_Matrice_defaut[Bouton_clicke-3],sizeof(Matrice_choisie)); + Effacer_curseur(); + for (J=0; J<3; J++) + for (I=0; I<3; I++) + { + Num2str(Matrice_choisie[I][J],Chaine,2); + Fenetre_Contenu_bouton_saisie(Matrice_Zone_saisie[I][J],Chaine); + } + Afficher_curseur(); + } + else + { + Effacer_curseur(); + I=Bouton_clicke-7; X=I%3; Y=I/3; + Num2str(Matrice_choisie[X][Y],Chaine,2); + Readline(Matrice_Zone_saisie[X][Y]->Pos_X+2, + Matrice_Zone_saisie[X][Y]->Pos_Y+2, + Chaine,2,1); + Matrice_choisie[X][Y]=atoi(Chaine); + Afficher_curseur(); + } + } + } + while ((Bouton_clicke!=1) && (Bouton_clicke!=2)); + + Fermer_fenetre(); + + if (Bouton_clicke==2) // OK + { + memcpy(Smooth_Matrice,Matrice_choisie,sizeof(Smooth_Matrice)); + Smooth_Mode=0; // On le met … 0 car la fonctø suivante va le passer … 1 + Bouton_Smooth_Mode(); + } + + Afficher_curseur(); +} + + +// -- Mode Smear ------------------------------------------------------------ +void Bouton_Smear_Mode(void) +{ + if (!Smear_Mode) + { + if (!Colorize_Mode) + Fonction_effet=Aucun_effet; + Shade_Mode=0; + Quick_shade_Mode=0; + Smooth_Mode=0; + Tiling_Mode=0; + } + Smear_Mode=!Smear_Mode; +} + + +// -- Mode Colorize --------------------------------------------------------- +void Calculer_les_tables_de_Colorize(void) +{ + word Indice; + word Facteur_A; + word Facteur_B; + + Facteur_A=256*(100-Colorize_Opacite)/100; + Facteur_B=256*( Colorize_Opacite)/100; + + for (Indice=0;Indice<64;Indice++) + { + Table_de_multiplication_par_Facteur_A[Indice]=Indice*Facteur_A; + Table_de_multiplication_par_Facteur_B[Indice]=Indice*Facteur_B; + } +} + + +void Bouton_Colorize_Mode(void) +{ + if (Colorize_Mode) + Fonction_effet=Aucun_effet; + else + { + switch(Colorize_Mode_en_cours) + { + case 0 : + Fonction_effet=Effet_Colorize_interpole; + break; + case 1 : + Fonction_effet=Effet_Colorize_additif; + break; + case 2 : + Fonction_effet=Effet_Colorize_soustractif; + } + Shade_Mode=0; + Quick_shade_Mode=0; + Smooth_Mode=0; + Tiling_Mode=0; + } + Colorize_Mode=!Colorize_Mode; +} + + +void Bouton_Colorize_Afficher_la_selection(int Numero) +{ + short Pos_Y; // Ligne o— afficher les flŠches de s‚lection + + // On commence par effacer les anciennes s‚lections: + // Partie gauche + Print_dans_fenetre(4,37," ",CM_Noir,CM_Clair); + Print_dans_fenetre(4,57," ",CM_Noir,CM_Clair); + Print_dans_fenetre(4,74," ",CM_Noir,CM_Clair); + // Partie droite + Print_dans_fenetre(129,37," ",CM_Noir,CM_Clair); + Print_dans_fenetre(129,57," ",CM_Noir,CM_Clair); + Print_dans_fenetre(129,74," ",CM_Noir,CM_Clair); + + // Ensuite, on affiche la flŠche l… o— il le faut: + switch(Numero) + { + case 0 : // M‚thode interpol‚e + Pos_Y=37; + break; + case 1 : // M‚thode additive + Pos_Y=57; + break; + case 2 : // M‚thode soustractive + Pos_Y=74; + } + Print_dans_fenetre(4,Pos_Y,"\020",CM_Noir,CM_Clair); + Print_dans_fenetre(129,Pos_Y,"\021",CM_Noir,CM_Clair); +} + +void Bouton_Colorize_Menu(void) +{ + short Opacite_choisie; + short Mode_choisi; + short Bouton_clicke; + char Chaine[4]; + + Ouvrir_fenetre(140,118,"Transparency"); + + Print_dans_fenetre(16,23,"Opacity:",CM_Fonce,CM_Clair); + Fenetre_Definir_bouton_saisie(87,21,3); // 1 + Print_dans_fenetre(117,23,"%",CM_Fonce,CM_Clair); + Fenetre_Definir_bouton_normal(16,34,108,14,"Interpolate",1,1,0x0017); // 2 + Fenetre_Afficher_cadre(12,18,116,34); + + Fenetre_Definir_bouton_normal(16,54,108,14,"Additive" ,2,1,0x0020); // 3 + Fenetre_Definir_bouton_normal(16,71,108,14,"Subtractive",1,1,0x001F); // 4 + + Fenetre_Definir_bouton_normal(16,94, 51,14,"Cancel" ,0,1,0x0001); // 5 + Fenetre_Definir_bouton_normal(73,94, 51,14,"OK" ,0,1,0x001C); // 6 + + Num2str(Colorize_Opacite,Chaine,3); + Fenetre_Contenu_bouton_saisie(Fenetre_Liste_boutons_special,Chaine); + Bouton_Colorize_Afficher_la_selection(Colorize_Mode_en_cours); + + Opacite_choisie=Colorize_Opacite; + Mode_choisi =Colorize_Mode_en_cours; + + Afficher_curseur(); + + do + { + Bouton_clicke=Fenetre_Bouton_clicke(); + + switch(Bouton_clicke) + { + case 1: // Zone de saisie de l'opacit‚ + Effacer_curseur(); + Num2str(Opacite_choisie,Chaine,3); + Readline(89,23,Chaine,3,1); + Opacite_choisie=atoi(Chaine); + // On corrige le pourcentage + if (Opacite_choisie>100) + { + Opacite_choisie=100; + Num2str(Opacite_choisie,Chaine,3); + Fenetre_Contenu_bouton_saisie(Fenetre_Liste_boutons_special,Chaine); + } + Afficher_curseur(); + break; + case 2: // M‚thode interpol‚e + case 3: // M‚thode additive + case 4: // M‚thode soustractive + Mode_choisi=Bouton_clicke-2; + Effacer_curseur(); + Bouton_Colorize_Afficher_la_selection(Mode_choisi); + Afficher_curseur(); + } + } + while (Bouton_clicke<5); + + Fermer_fenetre(); + + if (Bouton_clicke==6) // OK + { + Colorize_Opacite =Opacite_choisie; + Colorize_Mode_en_cours=Mode_choisi; + Calculer_les_tables_de_Colorize(); + Colorize_Mode=0; // On le met … 0 car la fonctø suivante va le passer … 1 + Bouton_Colorize_Mode(); + } + + Afficher_curseur(); +} + + +// -- Mode Tiling ----------------------------------------------------------- +void Bouton_Tiling_Mode(void) +{ + if (Tiling_Mode) + Fonction_effet=Aucun_effet; + else + { + Fonction_effet=Effet_Tiling; + Shade_Mode=0; + Quick_shade_Mode=0; + Colorize_Mode=0; + Smooth_Mode=0; + Smear_Mode=0; + } + Tiling_Mode=!Tiling_Mode; +} + + +void Bouton_Tiling_Menu(void) +{ + short Bouton_clicke; + short Offset_X_choisi=Tiling_Decalage_X; + short Offset_Y_choisi=Tiling_Decalage_Y; + char Chaine[5]; + struct Fenetre_Bouton_special * Bouton_saisie_Decalage_X; + struct Fenetre_Bouton_special * Bouton_saisie_Decalage_Y; + + Ouvrir_fenetre(138,79,"Tiling"); + + Fenetre_Definir_bouton_normal(13,55,51,14,"Cancel",0,1,0x0001); // 1 + Fenetre_Definir_bouton_normal(74,55,51,14,"OK" ,0,1,0x001C); // 2 + Fenetre_Definir_bouton_saisie(91,21,4); // 3 + Bouton_saisie_Decalage_X=Fenetre_Liste_boutons_special; + Fenetre_Definir_bouton_saisie(91,35,4); // 4 + Bouton_saisie_Decalage_Y=Fenetre_Liste_boutons_special; + Print_dans_fenetre(12,23,"Offset X:",CM_Fonce,CM_Clair); + Print_dans_fenetre(12,37,"Offset Y:",CM_Fonce,CM_Clair); + + Num2str(Tiling_Decalage_X,Chaine,4); + Fenetre_Contenu_bouton_saisie(Bouton_saisie_Decalage_X,Chaine); + Num2str(Tiling_Decalage_Y,Chaine,4); + Fenetre_Contenu_bouton_saisie(Bouton_saisie_Decalage_Y,Chaine); + + Afficher_curseur(); + + do + { + Bouton_clicke=Fenetre_Bouton_clicke(); + + if (Bouton_clicke==3) // Zone de saisie du d‚calage X + { + Effacer_curseur(); + Num2str(Offset_X_choisi,Chaine,4); + Readline(93,23,Chaine,4,1); + Offset_X_choisi=atoi(Chaine); + // On corrige le d‚calage en X + if (Offset_X_choisi>=Brosse_Largeur) + { + Offset_X_choisi=Brosse_Largeur-1; + Num2str(Offset_X_choisi,Chaine,4); + Fenetre_Contenu_bouton_saisie(Bouton_saisie_Decalage_X,Chaine); + } + Afficher_curseur(); + } + else + if (Bouton_clicke==4) // Zone de saisie du d‚calage Y + { + Effacer_curseur(); + Num2str(Offset_Y_choisi,Chaine,4); + Readline(93,37,Chaine,4,1); + Offset_Y_choisi=atoi(Chaine); + // On corrige le d‚calage en Y + if (Offset_Y_choisi>=Brosse_Hauteur) + { + Offset_Y_choisi=Brosse_Hauteur-1; + Num2str(Offset_Y_choisi,Chaine,4); + Fenetre_Contenu_bouton_saisie(Bouton_saisie_Decalage_Y,Chaine); + } + Afficher_curseur(); + } + } + while ( (Bouton_clicke!=1) && (Bouton_clicke!=2) ); + + Fermer_fenetre(); + + if (Bouton_clicke==2) // OK + { + Tiling_Decalage_X=Offset_X_choisi; + Tiling_Decalage_Y=Offset_Y_choisi; + if (!Tiling_Mode) + Bouton_Tiling_Mode(); + } + + Afficher_curseur(); +} + + +//---------------------------- Courbes de B‚zier ---------------------------- + +void Bouton_Courbes(void) +{ + Effacer_curseur(); + Demarrer_pile_operation(Courbe_en_cours); + Afficher_curseur(); +} + + +void Bouton_Courbes_Switch_mode(void) +{ + if (Courbe_en_cours==OPERATION_COURBE_4_POINTS) + Courbe_en_cours=OPERATION_COURBE_3_POINTS; + else + Courbe_en_cours=OPERATION_COURBE_4_POINTS; + + Effacer_curseur(); + Afficher_sprite_dans_menu(BOUTON_COURBES,Courbe_en_cours-OPERATION_COURBE_3_POINTS+4); + Demarrer_pile_operation(Courbe_en_cours); + Afficher_curseur(); +} + + +//--------------------------------- Spray ----------------------------------- + +void Bouton_Spray(void) +{ + Effacer_curseur(); + Demarrer_pile_operation(OPERATION_SPRAY); + Afficher_curseur(); +} + + +void Spray_Rafficher_infos(byte Couleur_selectionnee, byte Rafficher_jauge) +{ + char Chaine[3]; + + if (Rafficher_jauge) + { + Fenetre_Liste_boutons_scroller->Position=49-Spray_Multi_flow[Couleur_selectionnee]; + Fenetre_Dessiner_jauge(Fenetre_Liste_boutons_scroller); + } + Num2str(Spray_Multi_flow[Couleur_selectionnee],Chaine,2); + Print_dans_fenetre(196,130,Chaine,CM_Noir,CM_Clair); +} + + +void Bouton_Spray_Menu(void) +{ + static byte Spray_Init=0; + short Bouton_clicke; + char Chaine[4]; + word Indice; + byte Couleur_selectionnee=Fore_color; + byte Old_Spray_Mode =Spray_Mode; + short Old_Spray_Size =Spray_Size; + byte Old_Spray_Delay =Spray_Delay; + byte Old_Spray_Mono_flow=Spray_Mono_flow; + byte Old_Spray_Multi_flow[256]; + struct Fenetre_Bouton_special * Saisie_Size; + struct Fenetre_Bouton_special * Saisie_Delay; + struct Fenetre_Bouton_special * Saisie_Mono_flow; + struct Fenetre_Bouton_special * Saisie_Init; + word Ancien_Mouse_X; + word Ancien_Mouse_Y; + byte Ancien_Mouse_K; + byte Couleur; + byte Click; + + + memcpy(Old_Spray_Multi_flow,Spray_Multi_flow,256); + + + Ouvrir_fenetre(226,170,"Spray"); + + Fenetre_Definir_bouton_normal(110,148,51,14,"Cancel" ,0,1,0x0001); // 1 + Fenetre_Definir_bouton_normal(166,148,51,14,"OK" ,0,1,0x001C); // 2 + + Fenetre_Definir_bouton_scroller(178,62,74,50,1,49-Spray_Multi_flow[Couleur_selectionnee]); // 3 + + Fenetre_Definir_bouton_palette(7,56); // 4 + + Fenetre_Definir_bouton_normal( 8,148,83,14,"Mode: ",0,1,0x000F); // 5 + if (Spray_Mode) + Print_dans_fenetre(50,151," Mono",CM_Noir,CM_Clair); + else + Print_dans_fenetre(50,151,"Multi",CM_Noir,CM_Clair); + + Fenetre_Definir_bouton_normal(194, 62,19,14,"+1" ,0,1,0x004E); // 6 + Fenetre_Definir_bouton_normal(194, 79,19,14,"-1" ,0,1,0x004A); // 7 + Fenetre_Definir_bouton_normal(194, 96,19,14,"x2" ,0,1,0x0037); // 8 + Fenetre_Definir_bouton_normal(194,113,19,14,"ö2" ,0,1,0x00E0); // 9 + + Fenetre_Definir_bouton_normal( 8, 37,43,14,"Clear" ,1,1,0x002E); // 10 + + Print_dans_fenetre(142,25,"Size:" ,CM_Fonce,CM_Clair); + Fenetre_Definir_bouton_saisie(186,23,3); // 11 + Saisie_Size=Fenetre_Liste_boutons_special; + Num2str(Spray_Size,Chaine,3); + Fenetre_Contenu_bouton_saisie(Saisie_Size,Chaine); + + Print_dans_fenetre(142,39,"Delay:" ,CM_Fonce,CM_Clair); + Fenetre_Definir_bouton_saisie(194,37,2); // 12 + Saisie_Delay=Fenetre_Liste_boutons_special; + Num2str(Spray_Delay,Chaine,2); + Fenetre_Contenu_bouton_saisie(Saisie_Delay,Chaine); + + Print_dans_fenetre( 27,24,"Mono-Flow:",CM_Fonce,CM_Clair); + Fenetre_Definir_bouton_saisie(111,22,2); // 13 + Saisie_Mono_flow=Fenetre_Liste_boutons_special; + Num2str(Spray_Mono_flow,Chaine,2); + Fenetre_Contenu_bouton_saisie(Saisie_Mono_flow,Chaine); + + Print_dans_fenetre( 67,40,"Init:",CM_Fonce,CM_Clair); + Fenetre_Definir_bouton_saisie(111,38,2); // 14 + Saisie_Init=Fenetre_Liste_boutons_special; + Num2str(Spray_Init,Chaine,2); + Fenetre_Contenu_bouton_saisie(Saisie_Init,Chaine); + + Fenetre_Afficher_cadre(173,56,45,86); + Fenetre_Afficher_cadre(137,19,81,33); + + // On tagge toutes les couleurs utilis‚es + for (Indice=0; Indice<256; Indice++) + if (Spray_Multi_flow[Indice]) + Stencil_Tagger_couleur(Indice,CM_Noir); + // Et enfin, on tagge la couleur s‚lectionn‚e + Stencil_Tagger_couleur(Couleur_selectionnee,CM_Blanc); + Spray_Rafficher_infos(Couleur_selectionnee,0); + + Afficher_curseur(); + + + do + { + Ancien_Mouse_X=Mouse_X; + Ancien_Mouse_Y=Mouse_Y; + Ancien_Mouse_K=Mouse_K; + + Bouton_clicke=Fenetre_Bouton_clicke(); + + switch (Bouton_clicke) + { + case 0 : + case 2 : // OK + break; + + case 1 : // Cancel + Spray_Mode =Old_Spray_Mode; + Spray_Size =Old_Spray_Size; + Spray_Delay =Old_Spray_Delay; + Spray_Mono_flow=Old_Spray_Mono_flow; + memcpy(Spray_Multi_flow,Old_Spray_Multi_flow,256); + break; + + case 3 : // Scroller + Effacer_curseur(); + Spray_Multi_flow[Couleur_selectionnee]=49-Fenetre_Attribut2; + Spray_Rafficher_infos(Couleur_selectionnee,0); + Afficher_curseur(); + break; + + case -1 : + case 4 : // Palette + if ( (Mouse_X!=Ancien_Mouse_X) || (Mouse_Y!=Ancien_Mouse_Y) || (Mouse_K!=Ancien_Mouse_K) ) + { + Effacer_curseur(); + Stencil_Tagger_couleur(Couleur_selectionnee,(Spray_Multi_flow[Couleur_selectionnee])?CM_Noir:CM_Clair); + + // Mettre la couleur s‚lectionn‚e … jour suivant le click + Couleur_selectionnee=Lit_pixel(Mouse_X,Mouse_Y); + if (Mouse_K==2) + Spray_Multi_flow[Couleur_selectionnee]=0; + else + if (Spray_Multi_flow[Couleur_selectionnee]==0) + Spray_Multi_flow[Couleur_selectionnee]=Spray_Init; + + // Tagger la couleur s‚lectionn‚e en blanc + Stencil_Tagger_couleur(Couleur_selectionnee,CM_Blanc); + Spray_Rafficher_infos(Couleur_selectionnee,1); + Afficher_curseur(); + } + break; + + case 5 : // Toggle Mode + Spray_Mode=(Spray_Mode+1)&1; + Effacer_curseur(); + if (Spray_Mode) + Print_dans_fenetre(50,151," Mono",CM_Noir,CM_Clair); + else + Print_dans_fenetre(50,151,"Multi",CM_Noir,CM_Clair); + Afficher_curseur(); + break; + + case 6 : // +1 + for (Indice=0; Indice<256; Indice++) + { + if ( (Spray_Multi_flow[Indice]) && (Spray_Multi_flow[Indice]<49) ) + Spray_Multi_flow[Indice]++; + } + Effacer_curseur(); + Spray_Rafficher_infos(Couleur_selectionnee,1); + Afficher_curseur(); + break; + + case 7 : // -1 + for (Indice=0; Indice<256; Indice++) + { + if (Spray_Multi_flow[Indice]>1) + Spray_Multi_flow[Indice]--; + } + Effacer_curseur(); + Spray_Rafficher_infos(Couleur_selectionnee,1); + Afficher_curseur(); + break; + + case 8 : // x2 + for (Indice=0; Indice<256; Indice++) + { + if (Spray_Multi_flow[Indice]) + { + Spray_Multi_flow[Indice]<<=1; + if (Spray_Multi_flow[Indice]>49) + Spray_Multi_flow[Indice]=49; + } + } + Effacer_curseur(); + Spray_Rafficher_infos(Couleur_selectionnee,1); + Afficher_curseur(); + break; + + case 9 : // ö2 + for (Indice=0; Indice<256; Indice++) + { + if (Spray_Multi_flow[Indice]>1) + Spray_Multi_flow[Indice]>>=1; + } + Effacer_curseur(); + Spray_Rafficher_infos(Couleur_selectionnee,1); + Afficher_curseur(); + break; + + case 10 : // Clear + memset(Spray_Multi_flow,0,256); + // On raffiche les infos de la couleur s‚lectionn‚e + Spray_Rafficher_infos(Couleur_selectionnee,1); + // On efface les anciens TAGs + Fenetre_Effacer_tags(); + // Tagger la couleur s‚lectionn‚e en blanc + Stencil_Tagger_couleur(Couleur_selectionnee,CM_Blanc); + break; + + case 11 : // Size + Effacer_curseur(); + Num2str(Spray_Size,Chaine,3); + Readline(188,25,Chaine,3,1); + Spray_Size=atoi(Chaine); + // On corrige les dimensions + if (Spray_Size>256) + { + Spray_Size=256; + Num2str(Spray_Size,Chaine,3); + Fenetre_Contenu_bouton_saisie(Saisie_Size,Chaine); + } + else if (!Spray_Size) + { + Spray_Size=1; + Num2str(Spray_Size,Chaine,3); + Fenetre_Contenu_bouton_saisie(Saisie_Size,Chaine); + } + Afficher_curseur(); + break; + + case 12 : // Delay + Effacer_curseur(); + Num2str(Spray_Delay,Chaine,2); + Readline(196,39,Chaine,2,1); + Spray_Delay=atoi(Chaine); + // On corrige le delai + if (Spray_Delay>10) + { + Spray_Delay=10; + Num2str(Spray_Delay,Chaine,2); + Fenetre_Contenu_bouton_saisie(Saisie_Delay,Chaine); + } + Afficher_curseur(); + break; + + case 13 : // Mono-Flow + Effacer_curseur(); + Num2str(Spray_Mono_flow,Chaine,2); + Readline(113,24,Chaine,2,1); + Spray_Mono_flow=atoi(Chaine); + // On corrige le flux + if (!Spray_Mono_flow) + { + Spray_Mono_flow=1; + Num2str(Spray_Mono_flow,Chaine,2); + Fenetre_Contenu_bouton_saisie(Saisie_Mono_flow,Chaine); + } + Afficher_curseur(); + break; + + case 14 : // Init + Effacer_curseur(); + Num2str(Spray_Init,Chaine,2); + Readline(113,40,Chaine,2,1); + Spray_Init=atoi(Chaine); + // On corrige la valeur + if (Spray_Init>=50) + { + Spray_Init=49; + Num2str(Spray_Init,Chaine,2); + Fenetre_Contenu_bouton_saisie(Saisie_Init,Chaine); + } + Afficher_curseur(); + break; + } + + if (!Mouse_K) + switch (Touche) + { + case 0x0029 : // R‚cup‚ration d'une couleur derriŠre le menu + case 0x0033 : + Recuperer_couleur_derriere_fenetre(&Couleur,&Click); + if (Click) + { + Effacer_curseur(); + Stencil_Tagger_couleur(Couleur_selectionnee,(Spray_Multi_flow[Couleur_selectionnee])?CM_Noir:CM_Clair); + + // Mettre la couleur s‚lectionn‚e … jour suivant le click + Couleur_selectionnee=Couleur; + if (Click==2) + Spray_Multi_flow[Couleur_selectionnee]=0; + else + if (Spray_Multi_flow[Couleur_selectionnee]==0) + Spray_Multi_flow[Couleur_selectionnee]=Spray_Init; + + // Tagger la couleur s‚lectionn‚e en blanc + Stencil_Tagger_couleur(Couleur_selectionnee,CM_Blanc); + Spray_Rafficher_infos(Couleur_selectionnee,1); + Afficher_curseur(); + } + } + } + while ( (Bouton_clicke!=1) && (Bouton_clicke!=2) ); + + Fermer_fenetre(); + +/* + // Tant que l'on aura pas r‚solu le problŠme du d‚senclenchement du mode + // de dessin pr‚cedent, il faudra laisser ‡a en remarque et donc passer en + // spray mˆme si on a click‚ sur Cancel (idem pour OK (un peu plus bas)). + if (Bouton_clicke==1) // Cancel + { + if (Operation_en_cours!=OPERATION_SPRAY) + Desenclencher_bouton(BOUTON_SPRAY); + } +*/ + + Afficher_curseur(); + +/* + if (Bouton_clicke==2) // OK +*/ + if (Operation_en_cours!=OPERATION_SPRAY) + Enclencher_bouton(BOUTON_SPRAY,A_GAUCHE); +} + + + +// -- Mode Trame (Sieve) ---------------------------------------------------- + +void Bouton_Trame_Mode(void) +{ + Trame_Mode=!Trame_Mode; +} + + +void Dessiner_trame_zoomee(short Orig_X, short Orig_Y) +{ + short Pos_X; + short Pos_Y; + short Taille_X; + short Taille_Y; + short Debut_X=Fenetre_Pos_X+(Menu_Facteur_X*230); + short Debut_Y=Fenetre_Pos_Y+(Menu_Facteur_Y*78); + + Taille_X=Menu_Facteur_X*5; // |_ Taille d'une case + Taille_Y=Menu_Facteur_Y*5; // | de la trame zoom‚e + + // On efface de contenu pr‚c‚dent + Block(Orig_X,Orig_Y, + Menu_Facteur_X*Fenetre_Liste_boutons_special->Largeur, + Menu_Facteur_Y*Fenetre_Liste_boutons_special->Hauteur,CM_Clair); + + for (Pos_Y=0; Pos_Y>(15-i))&1)?CM_Blanc:CM_Noir); +} + + +void Copier_trame_predefinie(byte Indice) +{ + short i,j; + + for (j=0; j<16; j++) + for (i=0; i<16; i++) + Trame[i][j]=(TRAME_PREDEFINIE[Indice][j]>>(15-i))&1; + Trame_Largeur=16; + Trame_Hauteur=16; +} + + +void Inverser_trame(void) +{ + byte Pos_X,Pos_Y; + + for (Pos_Y=0; Pos_Y plus grande + short Preview_Fin_Y; // | rapidit‚. + + + memcpy(Old_Trame,Trame,256); + + Ouvrir_fenetre(290,179,"Sieve"); + + Preview_Debut_X=Fenetre_Pos_X+(Menu_Facteur_X*230); + Preview_Debut_Y=Fenetre_Pos_Y+(Menu_Facteur_Y*78); + Preview_Fin_X=Preview_Debut_X+(Menu_Facteur_X*51); + Preview_Fin_Y=Preview_Debut_Y+(Menu_Facteur_Y*71); + + Fenetre_Afficher_cadre ( 7, 65,130,43); + Fenetre_Afficher_cadre ( 7,110,130,43); + Fenetre_Afficher_cadre_creux(142, 68, 82,82); + Fenetre_Afficher_cadre_creux(229, 77, 53,73); + + Print_dans_fenetre(228, 68,"Preview",CM_Fonce,CM_Clair); + Print_dans_fenetre( 27, 83,"Scroll" ,CM_Fonce,CM_Clair); + Print_dans_fenetre( 23,120,"Width:" ,CM_Fonce,CM_Clair); + Print_dans_fenetre( 15,136,"Height:",CM_Fonce,CM_Clair); + + Fenetre_Definir_bouton_special(143,69,80,80); // 1 + + Fenetre_Definir_bouton_normal(175,157,51,14,"Cancel",0,1,0x0001); // 2 + Fenetre_Definir_bouton_normal(230,157,51,14,"OK" ,0,1,0x001C); // 3 + + Fenetre_Definir_bouton_normal( 8,157,51,14,"Clear" ,1,1,0x002E); // 4 + Fenetre_Definir_bouton_normal( 63,157,51,14,"Invert",1,1,0x0017); // 5 + + Fenetre_Definir_bouton_normal( 8,46,131,14,"Get from brush" ,1,1,0x0022); // 6 + Fenetre_Definir_bouton_normal(142,46,139,14,"Transfer to brush",1,1,0x0014); // 7 + + Fenetre_Definir_bouton_normal(109,114,11,11,"\030",0,1,0x0148); // 8 + Fenetre_Definir_bouton_normal(109,138,11,11,"\031",0,1,0x0150); // 9 + Fenetre_Definir_bouton_normal( 97,126,11,11,"\033",0,1,0x014B); // 10 + Fenetre_Definir_bouton_normal(121,126,11,11,"\032",0,1,0x014D); // 11 + Fenetre_Definir_bouton_normal(109,126,11,11,"" ,0,1,0x0052); // 12 + Bouton_Octet_insere=Fenetre_Liste_boutons_normal; + Block(Fenetre_Pos_X+(Menu_Facteur_X*(Bouton_Octet_insere->Pos_X+2)), + Fenetre_Pos_Y+(Menu_Facteur_Y*(Bouton_Octet_insere->Pos_Y+2)), + Menu_Facteur_X*7, Menu_Facteur_Y*7, (Octet_insere)?CM_Blanc:CM_Noir); + + Fenetre_Definir_bouton_normal(109, 69,11,11,"\030",0,1,0x0048); // 13 + Fenetre_Definir_bouton_normal(109, 93,11,11,"\031",0,1,0x0050); // 14 + Fenetre_Definir_bouton_normal( 97, 81,11,11,"\033",0,1,0x004B); // 15 + Fenetre_Definir_bouton_normal(121, 81,11,11,"\032",0,1,0x004D); // 16 + + for (Indice=0; Indice<10; Indice++) + Fenetre_Definir_bouton_normal((Indice*23)+8,20,20,20,"",0,1,0x003B+Indice); // 17 -> 26 + Fenetre_Definir_bouton_normal(238,20,20,20,"",0,1,0x0085); // 27 + Fenetre_Definir_bouton_normal(261,20,20,20,"",0,1,0x0086); // 28 + Dessiner_trames_predefinies(); + + Orig_X=Fenetre_Pos_X+(Menu_Facteur_X*Fenetre_Liste_boutons_special->Pos_X); + Orig_Y=Fenetre_Pos_Y+(Menu_Facteur_Y*Fenetre_Liste_boutons_special->Pos_Y); + + Num2str(Trame_Largeur,Chaine,2); + Print_dans_fenetre(71,120,Chaine,CM_Noir,CM_Clair); + Num2str(Trame_Hauteur,Chaine,2); + Print_dans_fenetre(71,136,Chaine,CM_Noir,CM_Clair); + Dessiner_trame_zoomee(Orig_X,Orig_Y); + + + Afficher_curseur(); + + do + { + Bouton_clicke=Fenetre_Bouton_clicke(); + + switch (Bouton_clicke) + { + case -1 : + case 0 : + break; + + case 1 : // Zone de dessin de la trame + /* // Version qui n'accepte pas les clicks sur la grille + Pos_X=(Mouse_X-Orig_X)/Menu_Facteur_X; + Pos_Y=(Mouse_Y-Orig_Y)/Menu_Facteur_Y; + if ( (Pos_X%5<4) && (Pos_Y%5<4) ) + { + Pos_X/=5; + Pos_Y/=5; + if ( (Pos_X16)?16:Brosse_Largeur; + Trame_Hauteur=(Brosse_Hauteur>16)?16:Brosse_Hauteur; + for (Pos_Y=0; Pos_Y>1); + Brosse_Decalage_Y=(Brosse_Hauteur>>1); + break; + + case 8 : // R‚duire hauteur + if (Trame_Hauteur>1) + { + Effacer_curseur(); + Trame_Hauteur--; + Num2str(Trame_Hauteur,Chaine,2); + Print_dans_fenetre(71,136,Chaine,CM_Noir,CM_Clair); + Dessiner_trame_zoomee(Orig_X,Orig_Y); + Afficher_curseur(); + } + break; + + case 9 : // Agrandir hauteur + if (Trame_Hauteur<16) + { + Effacer_curseur(); + for (Indice=0; Indice1) + { + Effacer_curseur(); + Trame_Largeur--; + Num2str(Trame_Largeur,Chaine,2); + Print_dans_fenetre(71,120,Chaine,CM_Noir,CM_Clair); + Dessiner_trame_zoomee(Orig_X,Orig_Y); + Afficher_curseur(); + } + break; + + case 11 : // Agrandir largeur + if (Trame_Largeur<16) + { + Effacer_curseur(); + for (Indice=0; IndicePos_X+2)), + Fenetre_Pos_Y+(Menu_Facteur_Y*(Bouton_Octet_insere->Pos_Y+2)), + Menu_Facteur_X*7, Menu_Facteur_Y*7, (Octet_insere)?CM_Blanc:CM_Noir); + Afficher_curseur(); + break; + + case 13 : // Scroll vers le haut + Effacer_curseur(); + for (Pos_X=0; Pos_X0; Pos_Y--) + Trame[Pos_X][Pos_Y]=Trame[Pos_X][Pos_Y-1]; + Trame[Pos_X][0]=Temp; + } + Dessiner_trame_zoomee(Orig_X,Orig_Y); + Afficher_curseur(); + break; + + case 15 : // Scroll vers la gauche + Effacer_curseur(); + for (Pos_Y=0; Pos_Y0; Pos_X--) + Trame[Pos_X][Pos_Y]=Trame[Pos_X-1][Pos_Y]; + Trame[0][Pos_Y]=Temp; + } + Dessiner_trame_zoomee(Orig_X,Orig_Y); + Afficher_curseur(); + break; + + default : // Boutons de trames pr‚d‚finies + Effacer_curseur(); + Copier_trame_predefinie(Bouton_clicke-17); + Dessiner_trame_zoomee(Orig_X,Orig_Y); + Num2str(Trame_Largeur,Chaine,2); + Print_dans_fenetre(71,120,Chaine,CM_Noir,CM_Clair); + Num2str(Trame_Hauteur,Chaine,2); + Print_dans_fenetre(71,136,Chaine,CM_Noir,CM_Clair); + Dessiner_trame_zoomee(Orig_X,Orig_Y); + Afficher_curseur(); + } + } + while ( (Bouton_clicke!=2) && (Bouton_clicke!=3) ); + + + Fermer_fenetre(); + + if (Bouton_clicke==2) // Cancel + { + Trame_Largeur=Old_Trame_Largeur; + Trame_Hauteur=Old_Trame_Hauteur; + memcpy(Trame,Old_Trame,256); + } + + if ( (Bouton_clicke==3) && (!Trame_Mode) ) // OK + Bouton_Trame_Mode(); + + Afficher_curseur(); +} + + +// -- Gestion des boutons de polygone vide et plein ------------------------- + +void Bouton_Polygone(void) +{ + Effacer_curseur(); + Demarrer_pile_operation(OPERATION_POLYGONE); + Afficher_curseur(); +} + + +void Bouton_Polyform(void) +{ + Effacer_curseur(); + Demarrer_pile_operation(OPERATION_POLYFORM); + Afficher_curseur(); +} + + +void Bouton_Polyfill(void) +{ + Effacer_curseur(); + Demarrer_pile_operation(OPERATION_POLYFILL); + Afficher_curseur(); +} + + +void Bouton_Filled_polyform(void) +{ + Effacer_curseur(); + Demarrer_pile_operation(OPERATION_FILLED_POLYFORM); + Afficher_curseur(); +} + + +// -- Boutons d'ajustement de l'image --------------------------------------- + +void Bouton_Ajuster(void) +{ + Effacer_curseur(); + Demarrer_pile_operation(OPERATION_SCROLL); + Afficher_curseur(); +} + + + +// -- Menu des effets (Shade, Stencil, etc...) ------------------------------ + +void Afficher_sprite_effet(short Numero_sprite, short Debut_X, short Debut_Y) +{ + short X,Y,Pos_X,Pos_Y; + + for (Y=0,Pos_Y=Debut_Y;Y0) + then write('(',hi(Touche),',',Byte2Hexa(lo(Touche)),') '); + until Touche=$0001; +END. diff --git a/cfg/SCANCODE.PAS b/cfg/SCANCODE.PAS new file mode 100644 index 00000000..001ecf3f --- /dev/null +++ b/cfg/SCANCODE.PAS @@ -0,0 +1,1040 @@ +const + Table_Normal:array[0..255] of pchar= + ( + {00} '???' + {01},'Esc' + {02},'1 !' + {03},'2 @' + {04},'3 #' + {05},'4 $' + {06},'5 %' + {07},'6 ^' + {08},'7 &' + {09},'8 *' + {0A},'9 (' + {0B},'0 )' + {0C},'- _' + {0D},'= +' + {0E},'BkSpc' + {0F},'Tab' + {10},'Q' + {11},'W' + {12},'E' + {13},'R' + {14},'T' + {15},'Y' + {16},'U' + {17},'I' + {18},'O' + {19},'P' + {1A},'[ {' + {1B},'] }' + {1C},'Retrn' + {1D},'???' + {1E},'A' + {1F},'S' + {20},'D' + {21},'F' + {22},'G' + {23},'H' + {24},'J' + {25},'K' + {26},'L' + {27},'; :' + {28},''' "' + {29},'` ~' + {2A},'???' + {2B},'\ |' + {2C},'Z' + {2D},'X' + {2E},'C' + {2F},'V' + {30},'B' + {31},'N' + {32},'M' + {33},', <' + {34},'. >' + {35},'/ ?' + {36},'???' + {37},'Grey*' + {38},'???' + {39},'Space' + {3A},'???' + {3B},'F1' + {3C},'F2' + {3D},'F3' + {3E},'F4' + {3F},'F5' + {40},'F6' + {41},'F7' + {42},'F8' + {43},'F9' + {44},'F10' + {45},'???' + {46},'???' + {47},'Home' + {48},'Up' + {49},'PgUp' + {4A},'Grey-' + {4B},'Left' + {4C},'Kpad5' + {4D},'Right' + {4E},'Grey+' + {4F},'End' + {50},'Down' + {51},'PgDn' + {52},'Ins' + {53},'Del' + {54},'???' + {55},'???' + {56},'Lft\|' + {57},'???' + {58},'???' + {59},'???' + {5A},'???' + {5B},'???' + {5C},'???' + {5D},'???' + {5E},'???' + {5F},'???' + {60},'???' + {61},'???' + {62},'???' + {63},'???' + {64},'???' + {65},'???' + {66},'???' + {67},'???' + {68},'???' + {69},'???' + {6A},'???' + {6B},'???' + {6C},'???' + {6D},'???' + {6E},'???' + {6F},'???' + {70},'???' + {71},'???' + {72},'???' + {73},'???' + {74},'???' + {75},'???' + {76},'???' + {77},'???' + {78},'???' + {79},'???' + {7A},'???' + {7B},'???' + {7C},'???' + {7D},'???' + {7E},'???' + {7F},'???' + {80},'???' + {81},'???' + {82},'???' + {83},'???' + {84},'???' + {85},'F11' + {86},'F12' + {87},'???' + {88},'???' + {89},'???' + {8A},'???' + {8B},'???' + {8C},'???' + {8D},'???' + {8E},'???' + {8F},'???' + {90},'???' + {91},'???' + {92},'???' + {93},'???' + {94},'???' + {95},'???' + {96},'???' + {97},'???' + {98},'???' + {99},'???' + {9A},'???' + {9B},'???' + {9C},'???' + {9D},'???' + {9E},'???' + {9F},'???' + {A0},'???' + {A1},'???' + {A2},'???' + {A3},'???' + {A4},'???' + {A5},'???' + {A6},'???' + {A7},'???' + {A8},'???' + {A9},'???' + {AA},'???' + {AB},'???' + {AC},'???' + {AD},'???' + {AE},'???' + {AF},'???' + {B0},'???' + {B1},'???' + {B2},'???' + {B3},'???' + {B4},'???' + {B5},'???' + {B6},'Win L' + {B7},'Win R' + {B8},'Win M' + {B9},'???' + {BA},'???' + {BB},'???' + {BC},'???' + {BD},'???' + {BE},'???' + {BF},'???' + {C0},'???' + {C1},'???' + {C2},'???' + {C3},'???' + {C4},'???' + {C5},'???' + {C6},'???' + {C7},'???' + {C8},'???' + {C9},'???' + {CA},'???' + {CB},'???' + {CC},'???' + {CD},'???' + {CE},'???' + {CF},'???' + {D0},'???' + {D1},'???' + {D2},'???' + {D3},'???' + {D4},'???' + {D5},'???' + {D6},'???' + {D7},'???' + {D8},'???' + {D9},'???' + {DA},'???' + {DB},'???' + {DC},'???' + {DD},'???' + {DE},'???' + {DF},'???' + {E0},'Enter' + {E1},'???' + {E2},'???' + {E3},'???' + {E4},'???' + {E5},'???' + {E6},'???' + {E7},'???' + {E8},'???' + {E9},'???' + {EA},'???' + {EB},'???' + {EC},'???' + {ED},'???' + {EE},'???' + {EF},'???' + {F0},'???' + {F1},'???' + {F2},'???' + {F3},'???' + {F4},'???' + {F5},'???' + {F6},'???' + {F7},'???' + {F8},'???' + {F9},'???' + {FA},'???' + {FB},'???' + {FC},'???' + {FD},'???' + {FE},'???' + {FF},'' + ); + + Table_Shift:array[0..255] of pchar= + ( + {00} '???' + {01},'Esc' + {02},'1 !' + {03},'2 @' + {04},'3 #' + {05},'4 $' + {06},'5 %' + {07},'6 ^' + {08},'7 &' + {09},'8 *' + {0A},'9 (' + {0B},'0 )' + {0C},'- _' + {0D},'= +' + {0E},'BkSpc' + {0F},'Tab' + {10},'Q' + {11},'W' + {12},'E' + {13},'R' + {14},'T' + {15},'Y' + {16},'U' + {17},'I' + {18},'O' + {19},'P' + {1A},'[ {' + {1B},'] }' + {1C},'Retrn' + {1D},'???' + {1E},'A' + {1F},'S' + {20},'D' + {21},'F' + {22},'G' + {23},'H' + {24},'J' + {25},'K' + {26},'L' + {27},'; :' + {28},''' "' + {29},'` ~' + {2A},'???' + {2B},'\ |' + {2C},'Z' + {2D},'X' + {2E},'C' + {2F},'V' + {30},'B' + {31},'N' + {32},'M' + {33},', <' + {34},'. >' + {35},'/ ?' + {36},'???' + {37},'Grey*' + {38},'???' + {39},'Space' + {3A},'???' + {3B},'???' + {3C},'???' + {3D},'???' + {3E},'???' + {3F},'???' + {40},'???' + {41},'???' + {42},'???' + {43},'???' + {44},'???' + {45},'???' + {46},'???' + {47},'Home' + {48},'Up' + {49},'PgUp' + {4A},'Grey-' + {4B},'Left' + {4C},'Kpad5' + {4D},'Right' + {4E},'Grey+' + {4F},'End' + {50},'Down' + {51},'PgDn' + {52},'Ins' + {53},'Del' + {54},'F1' + {55},'F2' + {56},'F3' + {57},'F4' + {58},'F5' + {59},'F6' + {5A},'F7' + {5B},'F8' + {5C},'F9' + {5D},'F10' + {5E},'???' + {5F},'???' + {60},'???' + {61},'???' + {62},'???' + {63},'???' + {64},'???' + {65},'???' + {66},'???' + {67},'???' + {68},'???' + {69},'???' + {6A},'???' + {6B},'???' + {6C},'???' + {6D},'???' + {6E},'???' + {6F},'???' + {70},'???' + {71},'???' + {72},'???' + {73},'???' + {74},'???' + {75},'???' + {76},'???' + {77},'???' + {78},'???' + {79},'???' + {7A},'???' + {7B},'???' + {7C},'???' + {7D},'???' + {7E},'???' + {7F},'???' + {80},'???' + {81},'???' + {82},'???' + {83},'???' + {84},'???' + {85},'???' + {86},'???' + {87},'F11' + {88},'F12' + {89},'???' + {8A},'???' + {8B},'???' + {8C},'???' + {8D},'???' + {8E},'???' + {8F},'???' + {90},'???' + {91},'???' + {92},'???' + {93},'???' + {94},'???' + {95},'???' + {96},'???' + {97},'???' + {98},'???' + {99},'???' + {9A},'???' + {9B},'???' + {9C},'???' + {9D},'???' + {9E},'???' + {9F},'???' + {A0},'???' + {A1},'???' + {A2},'???' + {A3},'???' + {A4},'???' + {A5},'???' + {A6},'???' + {A7},'???' + {A8},'???' + {A9},'???' + {AA},'???' + {AB},'???' + {AC},'???' + {AD},'???' + {AE},'???' + {AF},'???' + {B0},'???' + {B1},'???' + {B2},'???' + {B3},'???' + {B4},'???' + {B5},'???' + {B6},'???' + {B7},'???' + {B8},'???' + {B9},'???' + {BA},'???' + {BB},'???' + {BC},'???' + {BD},'???' + {BE},'???' + {BF},'???' + {C0},'???' + {C1},'???' + {C2},'Win L' + {C3},'Win R' + {C4},'Win M' + {C5},'???' + {C6},'???' + {C7},'???' + {C8},'???' + {C9},'???' + {CA},'???' + {CB},'???' + {CC},'???' + {CD},'???' + {CE},'???' + {CF},'???' + {D0},'???' + {D1},'???' + {D2},'???' + {D3},'???' + {D4},'???' + {D5},'???' + {D6},'???' + {D7},'???' + {D8},'???' + {D9},'???' + {DA},'???' + {DB},'???' + {DC},'???' + {DD},'???' + {DE},'???' + {DF},'???' + {E0},'Enter' + {E1},'???' + {E2},'???' + {E3},'???' + {E4},'???' + {E5},'???' + {E6},'???' + {E7},'???' + {E8},'???' + {E9},'???' + {EA},'???' + {EB},'???' + {EC},'???' + {ED},'???' + {EE},'???' + {EF},'???' + {F0},'???' + {F1},'???' + {F2},'???' + {F3},'???' + {F4},'???' + {F5},'???' + {F6},'???' + {F7},'???' + {F8},'???' + {F9},'???' + {FA},'???' + {FB},'???' + {FC},'???' + {FD},'???' + {FE},'???' + {FF},'???' + ); + + Table_Ctrl:array[0..255] of pchar= + ( + {00} '???' + {01},'Esc' + {02},'???' + {03},'2 @' + {04},'???' + {05},'???' + {06},'???' + {07},'6 ^' + {08},'???' + {09},'8 *' + {0A},'???' + {0B},'???' + {0C},'- _' + {0D},'= +' + {0E},'BkSpc' + {0F},'???' + {10},'Q' + {11},'W' + {12},'E' + {13},'R' + {14},'T' + {15},'Y' + {16},'U' + {17},'I' + {18},'O' + {19},'P' + {1A},'[ {' + {1B},'] }' + {1C},'Retrn' + {1D},'???' + {1E},'A' + {1F},'S' + {20},'D' + {21},'F' + {22},'G' + {23},'H' + {24},'J' + {25},'K' + {26},'L' + {27},'; :' + {28},'???' + {29},'???' + {2A},'???' + {2B},'\ |' + {2C},'Z' + {2D},'X' + {2E},'C' + {2F},'V' + {30},'B' + {31},'N' + {32},'M' + {33},'???' + {34},'???' + {35},'???' + {36},'???' + {37},'???' + {38},'???' + {39},'Space' + {3A},'???' + {3B},'???' + {3C},'???' + {3D},'???' + {3E},'???' + {3F},'???' + {40},'???' + {41},'???' + {42},'???' + {43},'???' + {44},'???' + {45},'???' + {46},'???' + {47},'???' + {48},'???' + {49},'???' + {4A},'???' + {4B},'???' + {4C},'???' + {4D},'???' + {4E},'???' + {4F},'???' + {50},'???' + {51},'???' + {52},'???' + {53},'???' + {54},'???' + {55},'???' + {56},'???' + {57},'???' + {58},'???' + {59},'???' + {5A},'???' + {5B},'???' + {5C},'???' + {5D},'???' + {5E},'F1' + {5F},'F2' + {60},'F3' + {61},'F4' + {62},'F5' + {63},'F6' + {64},'F7' + {65},'F8' + {66},'F9' + {67},'F10' + {68},'???' + {69},'???' + {6A},'???' + {6B},'???' + {6C},'???' + {6D},'???' + {6E},'???' + {6F},'???' + {70},'???' + {71},'???' + {72},'???' + {73},'Left' + {74},'Right' + {75},'End' + {76},'PgDn' + {77},'Home' + {78},'???' + {79},'???' + {7A},'???' + {7B},'???' + {7C},'???' + {7D},'???' + {7E},'???' + {7F},'???' + {80},'???' + {81},'???' + {82},'???' + {83},'???' + {84},'PgUp' + {85},'???' + {86},'???' + {87},'???' + {88},'???' + {89},'F11' + {8A},'F12' + {8B},'???' + {8C},'???' + {8D},'Up' + {8E},'Grey-' + {8F},'Keyp5' + {90},'Grey+' + {91},'Down' + {92},'Ins' + {93},'Del' + {94},'Tab' + {95},'Grey/' + {96},'Grey*' + {97},'???' + {98},'???' + {99},'???' + {9A},'???' + {9B},'???' + {9C},'???' + {9D},'???' + {9E},'???' + {9F},'???' + {A0},'???' + {A1},'???' + {A2},'???' + {A3},'???' + {A4},'???' + {A5},'???' + {A6},'???' + {A7},'???' + {A8},'???' + {A9},'???' + {AA},'???' + {AB},'???' + {AC},'???' + {AD},'???' + {AE},'???' + {AF},'???' + {B0},'???' + {B1},'???' + {B2},'???' + {B3},'???' + {B4},'???' + {B5},'???' + {B6},'???' + {B7},'???' + {B8},'???' + {B9},'???' + {BA},'???' + {BB},'???' + {BC},'???' + {BD},'???' + {BE},'???' + {BF},'???' + {C0},'???' + {C1},'???' + {C2},'???' + {C3},'???' + {C4},'???' + {C5},'???' + {C6},'???' + {C7},'???' + {C8},'???' + {C9},'???' + {CA},'???' + {CB},'???' + {CC},'???' + {CD},'???' + {CE},'Win L' + {CF},'Win R' + {D0},'Win M' + {D1},'???' + {D2},'???' + {D3},'???' + {D4},'???' + {D5},'???' + {D6},'???' + {D7},'???' + {D8},'???' + {D9},'???' + {DA},'???' + {DB},'???' + {DC},'???' + {DD},'???' + {DE},'???' + {DF},'???' + {E0},'Enter' + {E1},'???' + {E2},'???' + {E3},'???' + {E4},'???' + {E5},'???' + {E6},'???' + {E7},'???' + {E8},'???' + {E9},'???' + {EA},'???' + {EB},'???' + {EC},'???' + {ED},'???' + {EE},'???' + {EF},'???' + {F0},'???' + {F1},'???' + {F2},'???' + {F3},'???' + {F4},'???' + {F5},'???' + {F6},'???' + {F7},'???' + {F8},'???' + {F9},'???' + {FA},'???' + {FB},'???' + {FC},'???' + {FD},'???' + {FE},'???' + {FF},'???' + ); + + Table_Alt:array[0..255] of pchar= + ( + {00} '???' + {01},'Esc' + {02},'???' + {03},'???' + {04},'???' + {05},'???' + {06},'???' + {07},'???' + {08},'???' + {09},'???' + {0A},'???' + {0B},'???' + {0C},'???' + {0D},'???' + {0E},'BkSpc' + {0F},'???' + {10},'Q' + {11},'W' + {12},'E' + {13},'R' + {14},'T' + {15},'Y' + {16},'U' + {17},'I' + {18},'O' + {19},'P' + {1A},'[ {' + {1B},'] }' + {1C},'Retrn' + {1D},'???' + {1E},'A' + {1F},'S' + {20},'D' + {21},'F' + {22},'G' + {23},'H' + {24},'J' + {25},'K' + {26},'L' + {27},'; :' + {28},''' "' + {29},'` ~' + {2A},'???' + {2B},'\ |' + {2C},'Z' + {2D},'X' + {2E},'C' + {2F},'V' + {30},'B' + {31},'N' + {32},'M' + {33},', <' + {34},'. >' + {35},'/ ?' + {36},'???' + {37},'Grey*' + {38},'???' + {39},'Space' + {3A},'???' + {3B},'???' + {3C},'???' + {3D},'???' + {3E},'???' + {3F},'???' + {40},'???' + {41},'???' + {42},'???' + {43},'???' + {44},'???' + {45},'???' + {46},'???' + {47},'???' + {48},'???' + {49},'???' + {4A},'Grey-' + {4B},'???' + {4C},'???' + {4D},'???' + {4E},'Grey+' + {4F},'???' + {50},'???' + {51},'???' + {52},'???' + {53},'???' + {54},'???' + {55},'???' + {56},'???' + {57},'???' + {58},'???' + {59},'???' + {5A},'???' + {5B},'???' + {5C},'???' + {5D},'???' + {5E},'???' + {5F},'???' + {60},'???' + {61},'???' + {62},'???' + {63},'???' + {64},'???' + {65},'???' + {66},'???' + {67},'???' + {68},'F1' + {69},'F2' + {6A},'F3' + {6B},'F4' + {6C},'F5' + {6D},'F6' + {6E},'F7' + {6F},'F8' + {70},'F9' + {71},'F10' + {72},'???' + {73},'???' + {74},'???' + {75},'???' + {76},'???' + {77},'???' + {78},'1 !' + {79},'2 @' + {7A},'3 #' + {7B},'4 $' + {7C},'5 %' + {7D},'6 ^' + {7E},'7 &' + {7F},'8 *' + {80},'9 (' + {81},'0 )' + {82},'- _' + {83},'= +' + {84},'???' + {85},'???' + {86},'???' + {87},'???' + {88},'???' + {89},'???' + {8A},'???' + {8B},'F11' + {8C},'F12' + {8D},'???' + {8E},'???' + {8F},'???' + {90},'???' + {91},'???' + {92},'???' + {93},'???' + {94},'???' + {95},'???' + {96},'???' + {97},'Home' + {98},'Up' + {99},'PgUp' + {9A},'???' + {9B},'Left' + {9C},'???' + {9D},'Right' + {9E},'???' + {9F},'End' + {A0},'Down' + {A1},'PgDn' + {A2},'Ins' + {A3},'Del' + {A4},'Grey/' + {A5},'Tab' + {A6},'Enter' + {A7},'???' + {A8},'???' + {A9},'???' + {AA},'???' + {AB},'???' + {AC},'???' + {AD},'???' + {AE},'???' + {AF},'???' + {B0},'???' + {B1},'???' + {B2},'???' + {B3},'???' + {B4},'???' + {B5},'???' + {B6},'???' + {B7},'???' + {B8},'???' + {B9},'???' + {BA},'???' + {BB},'???' + {BC},'???' + {BD},'???' + {BE},'???' + {BF},'???' + {C0},'???' + {C1},'???' + {C2},'???' + {C3},'???' + {C4},'???' + {C5},'???' + {C6},'???' + {C7},'???' + {C8},'???' + {C9},'???' + {CA},'???' + {CB},'???' + {CC},'???' + {CD},'???' + {CE},'???' + {CF},'???' + {D0},'???' + {D1},'???' + {D2},'???' + {D3},'???' + {D4},'???' + {D5},'???' + {D6},'???' + {D7},'???' + {D8},'???' + {D9},'???' + {DA},'Win L' + {DB},'Win R' + {DC},'Win M' + {DD},'???' + {DE},'???' + {DF},'???' + {E0},'???' + {E1},'???' + {E2},'???' + {E3},'???' + {E4},'???' + {E5},'???' + {E6},'???' + {E7},'???' + {E8},'???' + {E9},'???' + {EA},'???' + {EB},'???' + {EC},'???' + {ED},'???' + {EE},'???' + {EF},'???' + {F0},'???' + {F1},'???' + {F2},'???' + {F3},'???' + {F4},'???' + {F5},'???' + {F6},'???' + {F7},'???' + {F8},'???' + {F9},'???' + {FA},'???' + {FB},'???' + {FC},'???' + {FD},'???' + {FE},'???' + {FF},'???' + ); diff --git a/cfg/VIDEOMOD.PAS b/cfg/VIDEOMOD.PAS new file mode 100644 index 00000000..ab9ca4ee --- /dev/null +++ b/cfg/VIDEOMOD.PAS @@ -0,0 +1,72 @@ +const + MODE_MCGA =$00; + MODE_X =$40; + MODE_VESA =$80; + MODE_XVESA=$C0; + + Table_modes_video:array[1..NB_MODES_VIDEO,1..3] of word= + ( + (MODE_MCGA ,320,200), + (MODE_X+1 ,320,224), + (MODE_X+1 ,320,240), + (MODE_X+1 ,320,256), + (MODE_X+1 ,320,270), + (MODE_X+1 ,320,282), + (MODE_X+1 ,320,300), + (MODE_X+1 ,320,360), + (MODE_X+1 ,320,400), + (MODE_X+1 ,320,448), + (MODE_X+1 ,320,480), + (MODE_X+1 ,320,512), + (MODE_X+1 ,320,540), + (MODE_X+1 ,320,564), + (MODE_X+1 ,320,600), + + (MODE_X+1 ,360,200), + (MODE_X+1 ,360,224), + (MODE_X+1 ,360,240), + (MODE_X+1 ,360,256), + (MODE_X+1 ,360,270), + (MODE_X+1 ,360,282), + (MODE_X+1 ,360,300), + (MODE_X+1 ,360,360), + (MODE_X+1 ,360,400), + (MODE_X+1 ,360,448), + (MODE_X+1 ,360,480), + (MODE_X+1 ,360,512), + (MODE_X+1 ,360,540), + (MODE_X+1 ,360,564), + (MODE_X+1 ,360,600), + + (MODE_X+1 ,400,200), + (MODE_X+1 ,400,224), + (MODE_X+1 ,400,240), + (MODE_X+1 ,400,256), + (MODE_X+1 ,400,270), + (MODE_X+1 ,400,282), + (MODE_X+1 ,400,300), + (MODE_X+1 ,400,360), + (MODE_X+1 ,400,400), + (MODE_X+1 ,400,448), + (MODE_X+1 ,400,480), + (MODE_X+1 ,400,512), + (MODE_X+1 ,400,540), + (MODE_X+1 ,400,564), + (MODE_X+1 ,400,600), + + (MODE_XVESA+1 ,640,224), + (MODE_XVESA+1 ,640,240), + (MODE_XVESA+1 ,640,256), + (MODE_XVESA+1 ,640,270), + (MODE_XVESA+1 ,640,300), + (MODE_XVESA+1 ,640,350), + (MODE_VESA+1 ,640,400), + (MODE_XVESA+1 ,640,448), + (MODE_VESA+1 ,640,480), + (MODE_XVESA+1 ,640,512), + (MODE_XVESA+1 ,640,540), + (MODE_XVESA+1 ,640,564), + (MODE_XVESA+1 ,640,600), + (MODE_VESA+1 ,800,600), + (MODE_VESA+1 ,1024,768) + ); diff --git a/cfg/gfxcfg.pas b/cfg/gfxcfg.pas new file mode 100644 index 00000000..37f61de6 --- /dev/null +++ b/cfg/gfxcfg.pas @@ -0,0 +1,1772 @@ +program GrafX2_Setup; + +{============================================================================} +const + TAILLE_FICHIER_CONFIG=10351; + TAILLE_INI =16203; + NB_MAX_OPTIONS =134; + NB_MODES_VIDEO =60; + + VERSION1 =2; + VERSION2 =0; + BETA1 =96; + BETA2 =5; + + COULEUR_TITRE =$5D; + COULEUR_SETUP =$1B; + COULEUR_SELECT =$3F; + COULEUR_EXPLIC =$2A; + COULEUR_MESSAGE =$3F; + HAUTEUR_DEBUT_SETUP =10; + HAUTEUR_FIN_SETUP =44; + TAILLE_SETUP =(HAUTEUR_FIN_SETUP-HAUTEUR_DEBUT_SETUP)*40; + +{$I SCANCODE.PAS} +{$I VIDEOMOD.PAS} + +type + Options=record + Numero : word; + Touche : word; + Touche2: word; + Libelle: string[35]; + Explic1: string[76]; + Explic2: string[76]; + Erreur : boolean; + Suppr : boolean; + end; + +var + Config:array [1..NB_MAX_OPTIONS] of Options; + NB_OPTIONS:word; + Numero_definition_option:word; + Choix_enreg:byte; + + + +{============================================================================} + +{------------------------ Passer en mode texte 80x50 ------------------------} +procedure Text_mode_80x50; assembler; +asm + mov ax,3 + int 10h + mov ax,1112h + xor bl,bl + mov dl,50 + int 10h +end; + +{------------------------ Passer en mode texte 80x25 ------------------------} +procedure Text_mode_80x25; assembler; +asm + mov ax,3 + int 10h +end; + +{---------------------------- Gestion du curseur ----------------------------} +procedure Montrer_Curseur; assembler; +asm + mov ax,0103h + mov cx,0E0Fh + int 10h +end; + +procedure Cacher_Curseur; assembler; +asm + mov ax,0103h + mov cx,0F0Eh + int 10h +end; + +procedure Goto_XY(X,Y:byte); assembler; +asm + mov ah,2 + xor bh,bh + mov dl,X + mov dh,Y + int 10h +end; + +{------- Ecrire une chaine d'une certaine couleur … un certain endroit ------} +procedure Print(X,Y:word; Chaine:string; Attrib:byte); assembler; +asm + mov ax,0B800h + mov es,ax + mov ax,Y + mov bl,80 + mul bl + mov bx,X + add ax,bx + shl ax,1 + mov di,ax + + push ds + mov si,word ptr [Chaine] + mov ds,word ptr [Chaine+2] + + mov cl,[ds:si] + inc si + mov al,Attrib + @Ecrire_loop: + movsb + stosb + dec cl + jnz @Ecrire_loop + pop ds +end; + +{-------------- Dessiner un cadre plein d'une certaine couleur --------------} +procedure Cadre(X1,Y1,X2,Y2,Couleur:byte); +var + Tampon:string; + i,j:byte; +begin + Tampon[0]:=chr(X2-X1+1); + for j:=Y1 to Y2 do + begin + if j=Y1 then + begin + Tampon[1]:='É'; + Tampon[X2-X1+1]:='»'; + for i:=X1+1 to X2-1 do Tampon[i-X1+1]:='Í'; + end + else + if j=Y2 then + begin + Tampon[1]:='È'; + Tampon[X2-X1+1]:='¼'; + for i:=X1+1 to X2-1 do Tampon[i-X1+1]:='Í'; + end + else + begin + Tampon[1]:='º'; + Tampon[X2-X1+1]:='º'; + for i:=X1+1 to X2-1 do Tampon[i-X1+1]:=' '; + end; + + Print(X1,j,Tampon,Couleur); + end; +end; + +{---------------------- Change la couleur d'une ligne -----------------------} +procedure Set_color_of_line(Num_ligne:word; X1,X2,Couleur:byte); assembler; +asm + mov ax,0B800h + mov es,ax + mov ax,Num_ligne + mov bx,80 + mul bl + mov bl,X1 + add ax,bx + add ax,ax + mov di,ax + + mov cl,X2 + sub cl,X1 + inc cl + mov al,Couleur + @Set_col_loop: + inc di + stosb + dec cl + jnz @Set_col_loop +end; + +{--------------------------- Lecture d'une touche ---------------------------} +function Lire_touche:word; assembler; +var + Touche:word; +asm + mov Touche,0 + + mov ah,11h + int 16h + + jz @Get_input_Pas_de_touche + + mov ah,10h + int 16h + + mov byte ptr[Touche],ah + + mov ah,02h + int 16h + + and al,00001111b + + mov ah,al + and ah,00000001b + shr al,1 + or al,ah + + mov byte ptr[Touche+1],al + + @Get_input_Pas_de_touche: + mov ax,Touche +end; + +{--------------- Dessiner une jolie fenˆtre au premier plan -----------------} +function Fenetre_choix(Largeur,Hauteur:byte; Titre,Choix:string; Choix_debut,Couleur,Couleur_choix:byte):byte; +var + Temp:string; + i,Num_titre,Num_choix:byte; + X1,X2,Y1,Y2:byte; + Option_choisie:byte; + Touche:word; + Memoire_video:array[0..7999] of byte; +begin + move(mem[$B800:0000],Memoire_video,8000); + + X1:=40-(Largeur shr 1); + Y1:=25-(Hauteur shr 1); + X2:=X1+Largeur-1; + Y2:=Y1+Hauteur-1; + + Cadre(X1,Y1,X2,Y2,Couleur); + if Y2<49 then Set_color_of_line(Y2+1,X1+1,X2+1,$08); + if X2<79 then for i:=Y1+1 to Y2 do Set_color_of_line(i,X2+1,X2+1,$08); + + + Num_titre:=1; + Temp:=''; + for i:=1 to length(Titre) do + begin + if Titre[i]<>'^' + then Temp:=Temp+Titre[i] + else + begin + Print(X1+(X2-X1+1-length(Temp)) shr 1,Y1+1+Num_titre,Temp,Couleur); + Temp:=''; + inc(Num_titre); + end; + end; + + Num_choix:=1; + Temp:=''; + for i:=1 to length(Choix) do + begin + if Choix[i]<>'^' + then Temp:=Temp+Choix[i] + else + begin + Print(X1+(X2-X1+1-length(Temp)) shr 1,Y1+2+Num_choix+Num_titre,Temp,Couleur); + Temp:=''; + inc(Num_choix); + end; + end; + dec(Num_choix); + + Option_choisie:=Choix_debut; + Set_color_of_line(Y1+2+Num_titre+Option_choisie,X1+2,X2-2,Couleur_choix); + Repeat + Touche:=Lire_touche; + case Touche of + $0048 : begin + Set_color_of_line(Y1+2+Num_titre+Option_choisie,X1+2,X2-2,Couleur); + if Option_choisie=1 + then Option_choisie:=Num_choix + else dec(Option_choisie); + Set_color_of_line(Y1+2+Num_titre+Option_choisie,X1+2,X2-2,Couleur_choix); + end; + $0050 : begin + Set_color_of_line(Y1+2+Num_titre+Option_choisie,X1+2,X2-2,Couleur); + if Option_choisie=Num_choix + then Option_choisie:=1 + else inc(Option_choisie); + Set_color_of_line(Y1+2+Num_titre+Option_choisie,X1+2,X2-2,Couleur_choix); + end; + end; + until Touche=$001C; + + move(Memoire_video,mem[$B800:0000],8000); + + Fenetre_choix:=Option_choisie; +end; + +{------------------------ Passer en mode texte 80x25 ------------------------} +procedure Dessiner_ecran_principal; +var + i:byte; +begin + Cadre( 0, 0,79, 6,COULEUR_TITRE); + Print( 2, 1,'Setup program for GRAFX 2.00 (c)1996-98 Sunset Design (G.DORME & K.MARITAUD)',COULEUR_TITRE); + Print( 0, 2,'Ç',COULEUR_TITRE); + Print(79, 2,'¶',COULEUR_TITRE); + for i:=1 to 78 do + Print(i,2,'Ä',COULEUR_TITRE); + Print( 2, 3,'Use Up/Down arrows & Page-Up/Page-Down to scroll, Enter to modify, Delete to',COULEUR_TITRE); + Print( 2, 4,'remove a hot-key, and Escape to validate or cancel. (Warning: QWERTY keys!)',COULEUR_TITRE); + Print( 2, 5,'DO NOT USE Print-screen, Pause, and all other special keys!',COULEUR_TITRE); + Cadre( 0, 7,79, 9,COULEUR_SETUP); + Print( 2, 8,'Option',COULEUR_SETUP); + Print(38, 8,'³ Hot-key',COULEUR_SETUP); + Print(75, 8,'³Err',COULEUR_SETUP); + Cadre( 0, 9,79,45,COULEUR_SETUP); + Print( 0, 9,'Ì',COULEUR_SETUP); + Print(79, 9,'¹',COULEUR_SETUP); + Print(38, 7,'Ñ',COULEUR_SETUP); + Print(75, 7,'Ñ',COULEUR_SETUP); + Print(38, 9,'Ø',COULEUR_SETUP); + Print(75, 9,'Ø',COULEUR_SETUP); + Print(38,45,'Ï',COULEUR_SETUP); + Print(75,45,'Ï',COULEUR_SETUP); + Cadre( 0,46,79,49,COULEUR_EXPLIC); +end; + +{------------------------- D‚finition d'une option --------------------------} +procedure Definir_option(Numero:word;Libelle,Explic1,Explic2:string; Supprimable:boolean; Touche_par_defaut:word); +begin + Config[Numero_definition_option].Numero :=Numero; + Config[Numero_definition_option].Touche :=Touche_par_defaut; + Config[Numero_definition_option].Touche2:=$00FF; + Config[Numero_definition_option].Libelle:=Libelle; + Config[Numero_definition_option].Explic1:=Explic1; + Config[Numero_definition_option].Explic2:=Explic2; + Config[Numero_definition_option].Erreur :=false; + Config[Numero_definition_option].Suppr :=Supprimable; + inc(Numero_definition_option); +end; + +{--------------- Transformer une chaŒne AZT en String Pascal ----------------} +function Pchar2string(Chaine:pchar):string; +var + Temp:string; + i:byte; +begin + Temp:=''; + i:=0; + while Chaine[i]>#0 do + begin + Temp:=Temp+Chaine[i]; + inc(i); + end; + Pchar2string:=Temp; +end; + +{------------- Renvoyer une chaŒne donnant une touche "en clair" ------------} +function Nom_touche(Touche:word):string; +var + Temp,Temp2:string; + Num_table:byte; +begin + Num_table:=1; + Temp:=''; + if (hi(Touche) and 1)>0 then + begin + Temp:=Temp+' + '; + Num_table:=2; + end; + if (hi(Touche) and 2)>0 then + begin + Temp:=Temp+' + '; + Num_table:=3; + end; + if (hi(Touche) and 4)>0 then + begin + Temp:=Temp+' + '; + Num_table:=4; + end; + case Num_table of + 1: begin + Temp2:=Pchar2string(Table_Normal[lo(Touche)]); + if Temp2='???' + then Temp:='********** Invalid key! **********' + else if Temp2='' + then Temp:='' + else Temp:=Temp+'<'+Temp2+'>'; + end; + 2: begin + Temp2:=Pchar2string(Table_Shift[lo(Touche)]); + if Temp2='???' + then Temp:='**** Invalid key combination! ****' + else if Temp2='' + then Temp:='' + else Temp:=Temp+'<'+Temp2+'>'; + end; + 3: begin + Temp2:=Pchar2string(Table_Ctrl[lo(Touche)]); + if Temp2='???' + then Temp:='**** Invalid key combination! ****' + else if Temp2='' + then Temp:='' + else Temp:=Temp+'<'+Temp2+'>'; + end; + 4: begin + Temp2:=Pchar2string(Table_Alt[lo(Touche)]); + if Temp2='???' + then Temp:='**** Invalid key combination! ****' + else if Temp2='' + then Temp:='' + else Temp:=Temp+'<'+Temp2+'>'; + end; + end; + Nom_touche:=Temp; +end; + +{------------------- ComplŠte une chaine avec un caractŠre ------------------} +function Completer_chaine(Chaine:string; Taille:byte; Caractere:char):string; +var + i:byte; +begin + for i:=length(Chaine)+1 to Taille do + Chaine[i]:=Caractere; + Chaine[0]:=chr(Taille); + Completer_chaine:=Chaine; +end; + +{------------------- Ecrire les informations sur une option -----------------} +procedure Ecrire(Ligne:byte; Num_option:word; Couleur:byte); +begin + Print( 2,Ligne,Completer_chaine(Config[Num_option].Libelle,35,' '),Couleur); + Print(40,Ligne,Completer_chaine(Nom_touche(Config[Num_option].Touche),34,' '),Couleur); + if Config[Num_option].Erreur + then Print(77,Ligne,'X',Couleur) + else Print(77,Ligne,' ',Couleur); +end; + +{-------------------- Ecrire un commentaire sur une option ------------------} +procedure Ecrire_commentaire(Num_option:word); +begin + Print(2,47,Completer_chaine(Config[Num_option].Explic1,76,' '),COULEUR_EXPLIC); + Print(2,48,Completer_chaine(Config[Num_option].Explic2,76,' '),COULEUR_EXPLIC); +end; + +{----------------- Ecrire toutes les premieres lignes visibles --------------} +procedure Tout_ecrire(Decalage_curseur, Position_curseur:word); +var + i:byte; +begin + i:=HAUTEUR_DEBUT_SETUP; + while (i<=HAUTEUR_FIN_SETUP) and (i0 then + begin + if Position_curseur>1 then + begin + Set_color_of_line(Position_Curseur+HAUTEUR_DEBUT_SETUP-1,1,78,COULEUR_SETUP); + dec(Position_curseur); + Set_color_of_line(Position_Curseur+HAUTEUR_DEBUT_SETUP-1,1,78,COULEUR_SELECT); + end + else + begin + if Decalage_curseur>0 then + begin + Set_color_of_line(Position_Curseur+HAUTEUR_DEBUT_SETUP-1,1,78,COULEUR_SETUP); + dec(Decalage_curseur); + Tout_Scroller_bas(Decalage_curseur,Position_curseur); + end; + end; + Ecrire_commentaire(Position_curseur+Decalage_curseur); + end; +end; + +{-------------------------- Scroller vers le bas ----------------------------} +procedure Scroll_bas(var Decalage_curseur, Position_curseur:word); +begin + if Position_curseur+Decalage_Curseur0 then + begin + if Position_curseur>1 then + begin + Set_color_of_line(Position_Curseur+HAUTEUR_DEBUT_SETUP-1,1,78,COULEUR_SETUP); + Position_curseur:=1; + Set_color_of_line(Position_Curseur+HAUTEUR_DEBUT_SETUP-1,1,78,COULEUR_SELECT); + end + else + begin + if Decalage_curseur>0 then + begin + Set_color_of_line(Position_Curseur+HAUTEUR_DEBUT_SETUP-1,1,78,COULEUR_SETUP); + if Decalage_curseur>HAUTEUR_FIN_SETUP-HAUTEUR_DEBUT_SETUP + then dec(Decalage_curseur,HAUTEUR_FIN_SETUP-HAUTEUR_DEBUT_SETUP) + else Decalage_curseur:=0; + Tout_ecrire(Decalage_curseur,Position_curseur); + end; + end; + Ecrire_commentaire(Position_curseur+Decalage_curseur); + end; +end; + +{-------------------------- Scroller vers le bas ----------------------------} +procedure Page_down(var Decalage_curseur, Position_curseur:word); +begin + if Position_curseur+Decalage_Curseur$00FF) then + begin + j:=1; + Pas_encore_erreur:=true; + while (j<=NB_OPTIONS) and (Pas_encore_erreur) do + begin + if (i<>j) and (Config[i].Touche=Config[j].Touche) then + begin + Pas_encore_erreur:=false; + Config[i].Erreur:=true; + end; + inc(j); + end; + if Pas_encore_erreur then Config[i].Erreur:=false; + end; +end; + +{------------------- S‚lectionner une touche … modifier ---------------------} +procedure Select(Decalage_curseur, Position_curseur:word); +var + Touche,Num_ligne,Num_option,Num_table:word; +begin + Num_ligne:=Position_curseur+HAUTEUR_DEBUT_SETUP-1; + Num_option:=Position_curseur+Decalage_curseur; + Config[Num_option].Touche:=$00FF; + Ecrire(Num_ligne,Num_option,COULEUR_SELECT); + Goto_XY(40,Num_ligne); + Montrer_curseur; + + repeat + Touche:=Lire_touche; + until Touche<>$0000; + Config[Num_option].Touche:=Touche; + + Cacher_curseur; + Test_duplic; + + Num_table:=1; + if (hi(Touche) and 1)>0 + then Num_table:=2; + if (hi(Touche) and 2)>0 + then Num_table:=3; + if (hi(Touche) and 4)>0 + then Num_table:=4; + case Num_table of + 1: if Pchar2string(Table_Normal[lo(Touche)])='???' + then Config[Num_option].Erreur:=true; + 2: if Pchar2string(Table_Shift[lo(Touche)])='???' + then Config[Num_option].Erreur:=true; + 3: if Pchar2string(Table_Ctrl[lo(Touche)])='???' + then Config[Num_option].Erreur:=true; + 4: if Pchar2string(Table_Alt[lo(Touche)])='???' + then Config[Num_option].Erreur:=true; + end; + + Tout_ecrire(Decalage_curseur,Position_curseur); +end; + +{------------------------ D‚s‚lectionner une touche -------------------------} +procedure Unselect(Decalage_curseur, Position_curseur:word); +var + Num_option:word; +begin + Num_option:=Decalage_curseur+Position_curseur; + Config[Num_option].Erreur:=false; + Config[Num_option].Touche:=$00FF; + Test_duplic; + if not Config[Num_option].Suppr + then Config[Num_option].Erreur:=true; + Tout_ecrire(Decalage_curseur,Position_curseur); +end; + +{---------------------- Validation de la configuration ----------------------} +function Validation:boolean; +var + Y_a_des_erreurs:boolean; + i:word; +begin + Y_a_des_erreurs:=false; + i:=1; + while (i<=NB_OPTIONS) and not Y_a_des_erreurs do + begin + Y_a_des_erreurs:=Config[i].Erreur; + inc(i); + end; + + if Y_a_des_erreurs + then Choix_enreg:=4-Fenetre_choix(30,12, + 'There are errors in the^hot-keys configuration.^Check out the "Err" column^in order to correct them.^', + 'OK^Quit anyway^',1,$4C,$3F) + else Choix_enreg:=Fenetre_choix(30,10,'Save configuration?^','Yes^No^Cancel^',1,$2A,$6F); + Validation:=(Choix_enreg<>3); +end; + +{------------------------ Configuration des touches -------------------------} +procedure Setup; +var + Sortie_OK:boolean; + Touche:word; + Decalage_curseur:word; + Position_curseur:word; +begin + Sortie_OK:=false; + Decalage_curseur:=0; + Position_curseur:=1; + Test_duplic; + Tout_ecrire(0,1); + repeat + Touche:=Lire_Touche; + case Touche of + $0048 : Scroll_haut(Decalage_curseur,Position_curseur); + $0050 : Scroll_bas(Decalage_curseur,Position_curseur); + $0049 : Page_up(Decalage_curseur,Position_curseur); + $0051 : Page_down(Decalage_curseur,Position_curseur); + $001C : Select(Decalage_curseur,Position_curseur); + $0053 : Unselect(Decalage_curseur,Position_curseur); + $0001 : Sortie_OK:=Validation; + end; + until Sortie_OK; +end; + + + +{--- Lecture (et mise … jour s'il est ancien) du fichier de configuration ---} +type + Type_shade=record + Table:array[1..512] of word; + Pas:byte; + Mode:byte; + end; + Type_mode_video=record + Etat :byte; + Largeur:word; + Hauteur:word; + end; + Type_header=record + Signature:array[1..3] of char; + Version1:byte; + Version2:byte; + Beta1:byte; + Beta2:byte; + end; + Type_chunk=record + Numero:byte; + Taille:word; + end; + Type_infos_touche=record + Numero : word; + Touche : word; + Touche2: word; + end; + +var + Modes_video :array[1..NB_MODES_VIDEO] of Type_mode_video; + Shade_actuel :byte; + Shades :array[1..8] of Type_shade; + Masque :array[1..256] of byte; + Stencil :array[1..256] of byte; + Infos_degrades:array[1..225] of byte; + Smooth_Matrice:array[1..3,1..3] of byte; + Exclude_color :array[1..256] of byte; + Quick_shade :array[1..2] of byte; + + +procedure Interpretation_du_fichier_config; +var + Fichier :file; + Indice :word; + Indice2 :word; + Taille_fichier:longint; + Header :Type_header; + Chunk :Type_chunk; + Infos_touche :Type_infos_touche; + Mode_video :Type_mode_video; + OK :boolean; +begin + {- Modes vid‚os -} + for Indice:=1 to NB_MODES_VIDEO do + begin + Modes_video[Indice].Etat :=Table_modes_video[Indice,1]; + Modes_video[Indice].Largeur:=Table_modes_video[Indice,2]; + Modes_video[Indice].Hauteur:=Table_modes_video[Indice,3]; + end; + {- Shade -} + Shade_actuel:=0; {1er shade} + for Indice:=1 to 8 do + begin + for Indice2:=1 to 512 do + Shades[Indice].Table[Indice2]:=256; {Case vide pas tagg‚e} + Shades[Indice].Pas:=1; {Pas de 1} + Shades[Indice].Mode:=0; {Mode Normal} + end; + {- Masque -} + fillchar(Masque,sizeof(Masque),0); + {- Stencil -} + fillchar(Stencil,sizeof(Stencil),0); + {- Infos sur les d‚grad‚s -} + fillchar(Infos_degrades,sizeof(Infos_degrades),0); + {- Matrice du Smooth -} + Smooth_matrice[1][1]:=1; + Smooth_matrice[2][1]:=2; + Smooth_matrice[3][1]:=1; + Smooth_matrice[1][2]:=2; + Smooth_matrice[2][2]:=4; + Smooth_matrice[3][2]:=2; + Smooth_matrice[1][3]:=1; + Smooth_matrice[2][3]:=2; + Smooth_matrice[3][3]:=1; + {- Exclude colors -} + fillchar(Exclude_color,sizeof(Exclude_color),0); + {- Quick-shade -} + Quick_shade[1]:=1; {Step} + Quick_shade[2]:=0; {Loop mode (0=normal,1=loop,2=no sat.} + + Taille_fichier:=0; + assign(Fichier,'GFX2.CFG'); + {$I-} + reset(Fichier,1); + {$I+} + if (IOresult=0) then + begin {On tente de r‚cup‚rer les infos du fichier} + Taille_fichier:=filesize(Fichier); + if (Taille_fichier>=7) then + begin + blockread(Fichier,Header,7); + if Header.Signature='CFG' then + begin + {On regarde si c'est un fichier de la version actuelle} + if (Taille_fichier =TAILLE_FICHIER_CONFIG) and + (Header.Version1=VERSION1 ) and + (Header.Version2=VERSION2 ) and + (Header.Beta1 =BETA1 ) and + (Header.Beta2 =BETA2 ) then + begin {Si oui, on r‚cupŠre les touches et on s'arrˆte l…} + seek(Fichier,sizeof(Header)+Sizeof(Chunk)); + for Indice:=1 to NB_OPTIONS do + blockread(Fichier,Config[Indice],6); + close(Fichier); + exit; + end + else + begin {Si non, c'est une ancienne version et on r‚cupŠre tout ce qu'on peut} + OK:=TRUE; + {$I-} + while OK(*not eof(Fichier)*) do + begin + blockread(Fichier,Chunk,sizeof(Chunk)); + if (IOresult<>0) then + OK:=FALSE + else + case Chunk.Numero of + 0:begin {Touches} + for Indice:=1 to (Chunk.Taille div sizeof(Infos_touche)) do + begin + blockread(Fichier,Infos_touche,sizeof(Infos_touche)); + if (IOresult<>0) then + OK:=FALSE + else + begin + Indice2:=1; + while (Indice2<=NB_OPTIONS) and + (Config[Indice2].Numero<>Infos_touche.Numero) do + inc(Indice2); + if (Indice2<=NB_OPTIONS) then + begin + Config[Indice2].Touche :=Infos_touche.Touche; + Config[Indice2].Touche2:=Infos_touche.Touche2; + end; + end; + end; + end; + 1:begin {Modes vid‚o} + for Indice:=1 to (Chunk.Taille div sizeof(Mode_video)) do + begin + blockread(Fichier,Mode_video,sizeof(Mode_video)); + if (IOresult<>0) then + OK:=FALSE + else + begin + Indice2:=1; + while (Indice2<=NB_MODES_VIDEO) and + ( (Modes_video[Indice2].Largeur<>Mode_video.Largeur) or + (Modes_video[Indice2].Hauteur<>Mode_video.Hauteur) or + ((Modes_video[Indice2].Etat and $C0)<>(Mode_video.Etat and $C0)) ) do + inc(Indice2); + if (Indice2<=NB_MODES_VIDEO) then + Modes_video[Indice2].Etat:=Mode_video.Etat; + end; + end; + end; + 2:begin {Shade} + blockread(Fichier,Shade_actuel,sizeof(Shade_actuel)); + if (IOresult<>0) then + begin + OK:=FALSE; {Erreur => On remet un shade actuel propre} + Shade_actuel:=0; + end + else + begin + blockread(Fichier,Shades,sizeof(Shades)); + if (IOresult<>0) then + begin + OK:=FALSE; {Erreur => On remet des tables de shades propres} + for Indice:=1 to 8 do + begin + for Indice2:=1 to 512 do + Shades[Indice].Table[Indice2]:=256; {Case vide pas tagg‚e} + Shades[Indice].Pas:=1; {Pas de 1} + Shades[Indice].Mode:=0; {Mode Normal} + end; + end; + end; + end; + 3:begin {Masque} + blockread(Fichier,Masque,sizeof(Masque)); + if (IOresult<>0) then + begin + OK:=FALSE; {Erreur => On remet un masque propre} + fillchar(Masque,sizeof(Masque),0); + end; + end; + 4:begin {Stencil} + blockread(Fichier,Stencil,sizeof(Stencil)); + if (IOresult<>0) then + begin + OK:=FALSE; {Erreur => On remet un stencil propre} + fillchar(Stencil,sizeof(Stencil),0); + end; + end; + 5:begin {Infos sur les d‚grad‚s} + blockread(Fichier,Infos_degrades,sizeof(Infos_degrades)); + if (IOresult<>0) then + begin + OK:=FALSE; {Erreur => On remet des infos sur les d‚grad‚s propres} + fillchar(Stencil,sizeof(Infos_degrades),0); + end; + end; + 6:begin {Matrice du Smooth} + blockread(Fichier,Smooth_Matrice,sizeof(Smooth_Matrice)); + if (IOresult<>0) then + begin + OK:=FALSE; {Erreur => On remet une matrice de Smooth propre} + Smooth_matrice[1][1]:=1; + Smooth_matrice[2][1]:=2; + Smooth_matrice[3][1]:=1; + Smooth_matrice[1][2]:=2; + Smooth_matrice[2][2]:=4; + Smooth_matrice[3][2]:=2; + Smooth_matrice[1][3]:=1; + Smooth_matrice[2][3]:=2; + Smooth_matrice[3][3]:=1; + end; + end; + 7:begin {Exclude colors} + blockread(Fichier,Exclude_color,sizeof(Exclude_color)); + if (IOresult<>0) then + begin + OK:=FALSE; {Erreur => On remet une table d'exclusion propre} + fillchar(Exclude_color,sizeof(Exclude_color),0); + end; + end; + 8:begin {Quick-shade} + blockread(Fichier,Quick_shade,sizeof(Quick_shade)); + if (IOresult<>0) then + begin + OK:=FALSE; {Erreur => On remet un quick-shade propre} + Quick_shade[1]:=1; {Step} + Quick_shade[2]:=0; {Loop mode} + end; + end + else + begin + seek(Fichier,filepos(Fichier)+Chunk.Taille); + if (IOresult<>0) then + OK:=FALSE; + end; + end; + end; + {$I+} + end; + end; + end; + end; + + {- Ecriture du fichier d'options -} + assign(Fichier,'GFX2.CFG'); + rewrite(Fichier,1); + + {Ecriture du header} + Header.Signature:='CFG'; + Header.Version1 :=VERSION1; + Header.Version2 :=VERSION2; + Header.Beta1 :=BETA1; + Header.Beta2 :=BETA2; + blockwrite(Fichier,Header,sizeof(Header)); + + {Enregistrement des touches} + Chunk.Numero:=0; + Chunk.Taille:=NB_OPTIONS*sizeof(Infos_touche); + blockwrite(Fichier,Chunk,sizeof(Chunk)); + for Indice:=1 to NB_OPTIONS do + blockwrite(Fichier,Config[Indice],sizeof(Infos_touche)); {Les 3 premiers champs (words) sont: Num‚ro,Touche,Touche2} + + {Sauvegarde de l'‚tat de chaque mode vid‚o} + Chunk.Numero:=1; + Chunk.Taille:=sizeof(Modes_video); + blockwrite(Fichier,Chunk,sizeof(Chunk)); + blockwrite(Fichier,Modes_video,sizeof(Modes_video)); + + {Ecriture des donn‚es du Shade (pr‚c‚d‚es du shade en cours)} + Chunk.Numero:=2; + Chunk.Taille:=sizeof(Shades)+Sizeof(Shade_actuel); + blockwrite(Fichier,Chunk,sizeof(Chunk)); + blockwrite(Fichier,Shade_actuel,Sizeof(Shade_actuel)); + blockwrite(Fichier,Shades,Sizeof(Shades)); + + {Ecriture des donn‚es du Masque} + Chunk.Numero:=3; + Chunk.Taille:=sizeof(Masque); + blockwrite(Fichier,Chunk,sizeof(Chunk)); + blockwrite(Fichier,Masque,Sizeof(Masque)); + + {Ecriture des donn‚es du Stencil} + Chunk.Numero:=4; + Chunk.Taille:=sizeof(Stencil); + blockwrite(Fichier,Chunk,sizeof(Chunk)); + blockwrite(Fichier,Stencil,Sizeof(Stencil)); + + {Ecriture des donn‚es sur les d‚grad‚s} + Chunk.Numero:=5; + Chunk.Taille:=sizeof(Infos_degrades); + blockwrite(Fichier,Chunk,sizeof(Chunk)); + blockwrite(Fichier,Infos_degrades,Sizeof(Infos_degrades)); + + {Ecriture de la matrice de Smooth} + Chunk.Numero:=6; + Chunk.Taille:=sizeof(Smooth_Matrice); + blockwrite(Fichier,Chunk,sizeof(Chunk)); + blockwrite(Fichier,Smooth_Matrice,Sizeof(Smooth_Matrice)); + + {Ecriture de la table d'exclusion de couleurs} + Chunk.Numero:=7; + Chunk.Taille:=sizeof(Exclude_color); + blockwrite(Fichier,Chunk,sizeof(Chunk)); + blockwrite(Fichier,Exclude_color,Sizeof(Exclude_color)); + + {Ecriture des donn‚es du Quick-shade} + Chunk.Numero:=8; + Chunk.Taille:=sizeof(Quick_shade); + blockwrite(Fichier,Chunk,sizeof(Chunk)); + blockwrite(Fichier,Quick_shade,Sizeof(Quick_shade)); + + close(Fichier); +end; + + + +function Recreer_INI:boolean; +type + T_Buffer=array[1..TAILLE_INI] of byte; +var + Fichier_INI,Fichier_DAT:file; + Buffer:pointer;{^T_Buffer;} + Erreur:boolean; +begin + assign(Fichier_INI,'GFX2.INI'); + + assign(Fichier_DAT,'GFX2.DAT'); + {$I-} + reset(Fichier_DAT,1); + if IOresult<>0 then + Erreur:=true + else + begin + seek(Fichier_DAT,filesize(Fichier_DAT)-TAILLE_INI); + if IOresult<>0 then + Erreur:=true + else + begin + Erreur:=false; + rewrite(Fichier_INI,1); + getmem(Buffer,TAILLE_INI); + blockread (Fichier_DAT,Buffer^,TAILLE_INI); + blockwrite(Fichier_INI,Buffer^,TAILLE_INI); + freemem(Buffer,TAILLE_INI); + close(Fichier_INI); + end; + close(Fichier_DAT); + end; + {$I+} + + Recreer_INI:=Erreur; +end; + + +{------------------- Initialisation de la configuration ---------------------} +function Initialiser_config:boolean; +var + Erreur:boolean; + Fichier_INI:file; +begin + Erreur:=false; + + Numero_definition_option:=1; + + {!!! LES TOUCHES SONT CONFIGUREES POUR LES CLAVIERS QWERTY !!!} + + Definir_option(0,'Scroll up', + 'Used to scroll upwards in the picture, either in magnify and normal mode.', + 'This hot-key cannot be removed.', + false,$0048); {Haut} + Definir_option(1,'Scroll down', + 'Used to scroll downwards in the picture, either in magnify and normal mode.', + 'This hot-key cannot be removed.', + false,$0050); {Bas} + Definir_option(2,'Scroll left', + 'Used to scroll to the left in the picture, either in magnify and normal', + 'mode. This hot-key cannot be removed.', + false,$004B); {Gauche} + Definir_option(3,'Scroll right', + 'Used to scroll to the right in the picture, either in magnify and normal', + 'mode. This hot-key cannot be removed.', + false,$004D); {Droite} + Definir_option(4,'Faster scroll up', + 'Used to scroll upwards in the picture fast, either in magnify and normal', + 'mode.', + true,$0148); {Shift + Haut} + Definir_option(5,'Faster scroll down', + 'Used to scroll downwards in the picture fast, either in magnify and normal', + 'mode.', + true,$0150); {Shift + Bas} + Definir_option(6,'Faster scroll left', + 'Used to scroll to the left in the picture fast, either in magnify and normal', + 'mode.', + true,$014B); {Shift + Gauche} + Definir_option(7,'Faster scroll right', + 'Used to scroll to the right in the picture fast, either in magnify and', + 'normal mode.', + true,$014D); {Shift + Droite} + Definir_option(8,'Slower scroll up', + 'Used to scroll upwards in the picture pixel by pixel, either in magnify and', + 'normal mode.', + true,$0498); {Alt + Haut} + Definir_option(9,'Slower scroll down', + 'Used to scroll downwards in the picture pixel by pixel, either in magnify and', + 'normal mode.', + true,$04A0); {Alt + Bas} + Definir_option(10,'Slower scroll left', + 'Used to scroll to the left in the picture pixel by pixel, either in magnify', + 'and normal mode.', + true,$049B); {Alt + Gauche} + Definir_option(11,'Slower scroll right', + 'Used to scroll to the right in the picture pixel by pixel, either in magnify', + 'and normal mode.', + true,$049D); {Alt + Droite} + Definir_option(12,'Move mouse cursor 1 pixel up', + 'Used to simulate a very small mouse deplacement upwards.', + 'It''s very useful when you want a ultra-high precision.', + true,$028D); {Ctrl + Haut} + Definir_option(13,'Move mouse cursor 1 pixel down', + 'Used to simulate a very small mouse deplacement downwards.', + 'It''s very useful when you want a ultra-high precision.', + true,$0291); {Ctrl + Bas} + Definir_option(14,'Move mouse cursor 1 pixel left', + 'Used to simulate a very small mouse deplacement to the left.', + 'It''s very useful when you want a ultra-high precision.', + true,$0273); {Ctrl + Gauche} + Definir_option(15,'Move mouse cursor 1 pixel right', + 'Used to simulate a very small mouse deplacement to the right.', + 'It''s very useful when you want a ultra-high precision.', + true,$0274); {Ctrl + Droite} + Definir_option(16,'Simulate left mouse click', + 'Used to simulate a click with the left mouse button..', + 'It''s very useful when you want a ultra-high precision.', + true,$0039); {Space} + Definir_option(17,'Simulate right mouse click', + 'Used to simulate a click with the right mouse button..', + 'It''s very useful when you want a ultra-high precision.', + true,$0139); {Shift + Space} + Definir_option(18,'Show/hide option menu', + 'Switch the tool bar display on/off.', + 'This hot-key cannot be removed.', + false,$0044); {F10} + Definir_option(19,'Show/hide cursor', + 'Switch the cursor display on/off.', + 'This only works on the "small cross" and "hand" cursors.', + true,$0043); {F9} + Definir_option(20,'Set paintbrush to 1 pixel', + 'Useful when you want to use a "single-pixel-brush".', + '', + true,$0053); {Del} + Definir_option(21,'Paintbrush choice', + 'Opens a menu where you can choose a paintbrush out of 24 predefined ones.', + '', + true,$003E); {F4} + Definir_option(22,'Monochrome brush', + 'Turn your current user-defined brush into a single colored one.', + 'All non-transparent colors are set to current foreground color.', + true,$0157); {Shift + F4} + Definir_option(23,'Freehand drawing', + 'Set the drawing mode to the classical freehand one.', + '', + true,$0020); {D} + Definir_option(24,'Switch freehand drawing mode', + 'Switch between the 3 ways to use freehand drawing.', + 'These modes are: continuous, discontinuous and point by point.', + true,$0120); {Shift + D} + Definir_option(25,'Continuous freehand drawing', + 'Switch directly to continuous freehand drawing mode.', + '', + true,$0220); {Ctrl + D} + Definir_option(26,'Line', + 'Allows you to draw lines.', + '', + true,$0026); {L} + Definir_option(27,'Knotted lines', + 'Allows you to draw linked lines.', + 'This mode can also be called "Polyline".', + true,$0126); {Shift + L} + Definir_option(28,'Spray', + 'Allows you to spray brushes randomly in the picture.', + '', + true,$001E); {A (Q en AZERTY)} + Definir_option(29,'Spray menu', + 'Opens a menu in which you can configure the spray flow and size.', + '', + true,$011E); {Shift + A} + Definir_option(30,'Flood-fill', + 'Allows you to fill an area of the picture made of pixels of the same color.', + '', + true,$0021); {F} + Definir_option(124,'Replace color', + 'Allows you to replace all the pixels of the color pointed by the mouse with', + 'the fore-color or the back-color.', + true,$0121); {Shift + F} + Definir_option(31,'B‚zier''s curves', + 'Allows you to draw B‚zier''s curves.', + '', + true,$0017); {I} + Definir_option(32,'B‚zier''s curve with 3 or 4 points', + 'Allows you to choose whether you want to draw B‚zier''s curves with 3 or 4', + 'points.', + true,$0117); {Shift + I} + Definir_option(33,'Empty rectangle', + 'Allows you to draw a rectangle using the brush.', + '', + true,$0013); {R} + Definir_option(34,'Filled rectangle', + 'Allows you to draw a filled rectangle.', + '', + true,$0113); {Shift + R} + Definir_option(35,'Empty circle', + 'Allows you to draw a circle using the brush.', + '', + true,$002E); {C} + Definir_option(36,'Empty ellipse', + 'Allows you to draw an ellipse using the brush.', + '', + true,$022E); {Ctrl + C} + Definir_option(37,'Filled circle', + 'Allows you to draw a filled circle.', + '', + true,$012E); {Shift + C} + Definir_option(38,'Filled ellipse', + 'Allows you to draw a filled ellipse.', + '', + true,$032E); {Shift + Ctrl + C} + Definir_option(39,'Empty polygon', + 'Allows you to draw a polygon using the brush.', + '', + true,$0031); {N} + Definir_option(40,'Empty "polyform"', + 'Allows you to draw a freehand polygon using the brush.', + '', + true,$0231); {Ctrl + N} + Definir_option(41,'Filled polygon', + 'Allows you to draw a filled polygon.', + '', + true,$0131); {Shift + N} + Definir_option(42,'Filled "polyform"', + 'Allows you to draw a filled freehand polygon.', + '', + true,$0331); {Shift + Ctrl + N} + Definir_option(43,'Rectangle with gradation', + 'Allows you to draw a rectangle with a color gradation.', + '', + true,$0413); {Alt + R} + Definir_option(44,'Gradation menu', + 'Allows you to configure the way color gradations are calculated.', + '', + true,$0422); {Alt + G} + Definir_option(45,'Sphere with gradation', + 'Allows you to draw a rectangle with a color gradation.', + '', + true,$042E); {Alt + C} + Definir_option(46,'Ellipse with gradation', + 'Allows you to draw an ellipse filled with a color gradation.', + '', + true,$052E); {Shift + Alt + C} + Definir_option(47,'Adjust picture', + 'Allows you to move the whole picture in order to re-center it.', + 'Notice that what gets out from a side reappears on the other.', + true,$004C); {Kpad5} + Definir_option(48,'Flip/shrink picture menu', + 'Opens a menu which allows you to flip the picture horizontally/vertically or', + 'to shrink it to half-scale horizontally and/or vertically.', + true,$014C); {Shift + Kpad5} + Definir_option(49,'Drawing effects', + 'Opens a menu where you can enable/disable and configure the drawing effects', + 'listed below.', + true,$0012); {E} + Definir_option(50,'Shade mode', + 'Allows you to shade or lighten some pixels of the picture belonging to a', + 'color range, in addition of any drawing tool.', + true,$003F); {F5} + Definir_option(51,'Shade menu', + 'Opens a menu where you can choose color ranges to use with the Shade mode.', + 'This menu also contains parameters used both in Shade and Quick-shade modes.', + true,$0158); {Shift + F5} + Definir_option(131,'Quick-shade mode', + 'Does the same thing as shade mode with a simpler method (faster to define', + 'but a bit less powerful).', + true,$0262); {Ctrl + F5} + Definir_option(132,'Quick-shade menu', + 'Opens a menu where you can define the parameters of the quick-shade mode.', + '', + true,$0362); {Shift + Ctrl + F5} + Definir_option(52,'Stencil mode', + 'Allows you to mask colors that must not be affected when you are drawing.', + '', + true,$0040); {F6} + Definir_option(53,'Stencil menu', + 'Opens a menu where you can choose colors masked by the Stencil mode.', + '', + true,$0159); {Shift + F6} + Definir_option(54,'Mask mode', + 'Allows you to mask colors of the spare page that will keep you from ', + 'drawing. This mode should be called "True stencil".', + true,$046D); {Alt + F6} + Definir_option(55,'Mask menu', + 'Opens a menu where you can choose colors for the Mask mode.', + '', + true,$056D); {Shift + Alt + F6} + Definir_option(56,'Grid mode', + 'Force the cursor to snap up grid points.', + '', + true,$0022); {G} + Definir_option(57,'Grid menu', + 'Open a menu where you can configure the grid used by Grid mode.', + '', + true,$0122); {Shift + G} + Definir_option(58,'Sieve mode', + 'Only draws pixels on certain positions matching with a sieve.', + '', + true,$0222); {Ctrl + G} + Definir_option(59,'Sieve menu', + 'Opens a menu where you can configure the sieve.', + '', + true,$0322); {Shift + Ctrl + G} + Definir_option(60,'Invert sieve', + 'Inverts the pattern defined in the Sieve menu.', + '', + true,$0622); {Ctrl + Alt + G} + Definir_option(61,'Colorize mode', + 'Allows you to colorize the pixels on which your brush is pasted.', + 'This permits you to make transparency effects.', + true,$0041); {F7} + Definir_option(62,'Colorize menu', + 'Opens a menu where you can give the opacity percentage for Colorize mode.', + '', + true,$015A); {Shift + F7} + Definir_option(63,'Smooth mode', + 'Soften pixels on which your brush is pasted.', + '', + true,$0042); {F8} + Definir_option(123,'Smooth menu', + 'Opens a menu where you can define the Smooth matrix.', + '', + true,$015B); {Shift + F8} + Definir_option(64,'Smear mode', + 'Smears the pixels when you move your brush on the picture.', + '', + true,$046F); {Alt + F8} + Definir_option(65,'Tiling mode', + 'Puts parts of the brush where you draw.', + '', + true,$0430); {Alt + B} + Definir_option(66,'Tiling menu', + 'Opens a menu where you can configure the origin of the tiling.', + '', + true,$0530); {Shift + Alt + B} + Definir_option(67,'Classical brush grabbing', + 'Allows you to pick a brush defined within a rectangle.', + '', + true,$0030); {B} + Definir_option(68,'"Lasso" brush grabbing', + 'Allows you to pick a brush defined within a freehand polygon.', + '', + true,$0230); {Ctrl + B} + Definir_option(69,'Get previous brush back', + 'Restore the last user-defined brush.', + '', + true,$0130); {Shift + B} + Definir_option(70,'Horizontal brush flipping', + 'Reverse brush horizontally.', + '', + true,$002D); {X} + Definir_option(71,'Vertical brush flipping', + 'Reverse brush vertically.', + '', + true,$0015); {Y} + Definir_option(72,'90ø brush rotation', + 'Rotate the user-defined brush by 90ø (counter-clockwise).', + '', + true,$002C); {Z (W en AZERTY)} + Definir_option(73,'180ø brush rotation', + 'Rotate the user-defined brush by 180ø.', + '', + true,$012C); {Shift + Z} + Definir_option(74,'Strech brush', + 'Allows you to resize the user-defined brush.', + '', + true,$001F); {S} + Definir_option(75,'Distort brush', + 'Allows you to distort the user-defined brush.', + '', + true,$011F); {Shift + S} + Definir_option(76,'Outline brush', + 'Outlines the user-defined brush with the fore color.', + '', + true,$0018); {O} + Definir_option(77,'Nibble brush', + 'Deletes the borders of the user-defined brush.', + 'This does the opposite of the Outline option.', + true,$0118); {Shift + O} + Definir_option(78,'Get colors from brush', + 'Copy colors of the spare page that are used in the brush.', + '', + true,$0085); {F11} + Definir_option(79,'Recolorize brush', + 'Recolorize pixels of the user-defined brush in order to get a brush which', + 'looks like the one grabbed in the spare page.', + true,$0086); {F12} + Definir_option(80,'Rotate by any angle', + 'Rotate the brush by an angle that you can define.', + '', + true,$0011); {W (Z en AZERTY)} + Definir_option(81,'Pipette', + 'Allows you to copy the color of a pixel in the picture into the foreground', + 'or background color.', + true,$0029); {`~ (Touche sous le Esc - ý en AZERTY)} + Definir_option(82,'Swap foreground/background colors', + 'Invert foreground and background colors.', + '', + true,$0129); {Shift + `~} + Definir_option(83,'Magnifier mode', + 'Allows you to zoom into the picture.', + '', + true,$0032); {M (,? sur AZERTY)} + Definir_option(84,'Zoom factor menu', + 'Opens a menu where you can choose a magnifying factor.', + '', + true,$0132); {Shift + M} + Definir_option(85,'Zoom in', + 'Increase magnifying factor.', + '', + true,$004E); {Grey +} + Definir_option(86,'Zoom out', + 'Decrease magnifying factor.', + '', + true,$004A); {Grey -} + Definir_option(87,'Brush effects menu', + 'Opens a menu which proposes different effects on the user-defined brush.', + '', + true,$0630); {Ctrl + Alt + B} + Definir_option(88,'Text', + 'Opens a menu which permits you to type in a character string and to choose a', + 'font, and then creates a new user-defined brush fitting to your choices.', + true,$0014); {T} + Definir_option(89,'Screen resolution menu', + 'Opens a menu where you can choose the dimensions of the screen in which you', + 'want to draw among the numerous X and SVGA proposed modes.', + true,$001C); {Enter} + Definir_option(90,'"Safety" resolution', + 'Set resolution to 320x200. This can be useful if you choosed a resolution', + 'that is not supported by your monitor and video card. Cannot be removed.', + false,$011C); {Shift + Enter} + Definir_option(91,'Help and credits', + 'Opens a window where you can get information about the program.', + '', + true,$003B); {F1} + Definir_option(92,'Statistics', + 'Displays miscellaneous more or less useful information.', + '', + true,$0154); {Shift + F1} + Definir_option(93,'Jump to spare page', + 'Swap current page and spare page.', + '', + true,$000F); {Tab} + Definir_option(94,'Copy current page to spare page', + 'Copy current page to spare page.', + '', + true,$010F); {Shift + Tab} + Definir_option(95,'Save picture as...', + 'Opens a file-selector that allows you to save your picture with a new', + 'path-name.', + true,$003C); {F2} + Definir_option(96,'Save picture', + 'Saves your picture with the last name you gave it.', + '', + true,$0155); {Shift + F2} + Definir_option(97,'Load picture', + 'Opens a file-selector that allows you to load a new picture.', + '', + true,$003D); {F3} + Definir_option(98,'Re-load picture', + 'Re-load the current picture.', + 'This allows you to cancel modifications made since last saving.', + true,$0156); {Shift + F3} + Definir_option(99,'Save brush', + 'Opens a file-selector that allows you to save your current user-defined', + 'brush.', + true,$025F); {Ctrl + F2} + Definir_option(100,'Load brush', + 'Opens a file-selector that allows you to load a brush.', + '', + true,$0260); {Ctrl + F3} + Definir_option(101,'Settings', + 'Opens a menu which permits you to set the dimension of your picture, and to', + 'modify some parameters of the program.', + true,$015D); {Shift + F10} + Definir_option(102,'Undo (Oops!)', + 'Cancel the last action which modified the picture. This has no effect after', + 'a jump to the spare page, loading a picture or modifying its size.', + true,$0016); {U} + Definir_option(103,'Redo', + 'Redo the last undone action. This has no effect after a jump to the spare', + 'page, loading a picture or modifying its size.', + true,$0116); {Shift + U} + Definir_option(133,'Kill', + 'Kills the current page. It actually removes the current page from the list', + 'of "Undo" pages.', + true,$0153); {Shift + Suppr} + Definir_option(104,'Clear page', + 'Clears the picture with the first color of the palette (usually black).', + '', + true,$000E); {BackSpace} + Definir_option(105,'Clear page with backcolor', + 'Clears the picture with the backcolor.', + '', + true,$010E); {Shift + BackSpace} + Definir_option(106,'Quit program', + 'Allows you to leave the program.', + 'If modifications were not saved, confirmation is asked.', + false,$0010); {Q (A en AZERTY)} + Definir_option(107,'Palette menu', + 'Opens a menu which allows you to modify the current palette.', + '', + true,$0019); {P} + Definir_option(125,'Secondary palette menu', + 'Opens a menu which allows you to define color series and some tagged colors.', + '', + true,$0119); {Shift + P} + Definir_option(130,'Exclude colors menu', + 'Opens a menu which allows you to define the colors you don''t want to use in', + 'modes such as Smooth and Transparency, or when remapping a brush.', + true,$0219); {Ctrl + P} + Definir_option(108,'Scroll palette to the left', + 'Scroll palette in the tool bar to the left, column by column.', + '', + true,$0049); {PgUp} + Definir_option(109,'Scroll palette to the right', + 'Scroll palette in the tool bar to the right, column by column.', + '', + true,$0051); {PgDn} + Definir_option(110,'Scroll palette to the left faster', + 'Scroll palette in the tool bar to the left, 8 columns by 8 columns.', + '', + true,$0149); {Shift + PgUp} + Definir_option(111,'Scroll palette to the right faster', + 'Scroll palette in the tool bar to the right, 8 columns by 8 columns.', + '', + true,$0151); {Shift + PgDn} + Definir_option(112,'Center brush attachment point', + 'Set the attachement of the user-defined brush to its center.', + '', + true,$028F); {Ctrl + 5 (pav‚ num‚rique)} + Definir_option(113,'Top-left brush attachment point', + 'Set the attachement of the user-defined brush to its top-left corner.', + '', + true,$0277); {Ctrl + 7} + Definir_option(114,'Top-right brush attachment point', + 'Set the attachement of the user-defined brush to its top-right corner.', + '', + true,$0284); {Ctrl + 9} + Definir_option(115,'Bottom-left brush attachment point', + 'Set the attachement of the user-defined brush to its bottom-left corner.', + '', + true,$0275); {Ctrl + 1} + Definir_option(116,'Bottom-right brush attachment point', + 'Set the attachement of the user-defined brush to its bottom-right corner.', + '', + true,$0276); {Ctrl + 3} + Definir_option(117,'Next foreground color', + 'Set the foreground color to the next in the palette.', + '', + true,$001B); {] ($ en AZERTY)} + Definir_option(118,'Previous foreground color', + 'Set the foreground color to the previous in the palette.', + '', + true,$001A); {[ (^ en AZERTY)} + Definir_option(119,'Next background color', + 'Set the background color to the next in the palette.', + '', + true,$011B); {Shift + ]} + Definir_option(120,'Previous background color', + 'Set the background color to the previous in the palette.', + '', + true,$011A); {Shift + [} + Definir_option(126,'Next user-defined forecolor', + 'Set the foreground color to the next in the user-defined color series.', + '', + true,$000D); {'=+'} + Definir_option(127,'Previous user-defined forecolor', + 'Set the foreground color to the previous in the user-defined color series.', + '', + true,$000C); {'-_' (')ø' en AZERTY} + Definir_option(128,'Next user-defined backcolor', + 'Set the background color to the next in the user-defined color series.', + '', + true,$010D); {Shift + '=+'} + Definir_option(129,'Previous user-defined backcolor', + 'Set the background color to the previous in the user-defined color series.', + '', + true,$010C); {Shift + '-_' (')ø' en AZERTY} + Definir_option(121,'Shrink paintbrush', + 'Decrease the width of the paintbrush if it is special circle or square.', + '', + true,$0033); {,< (;. en AZERTY)} + Definir_option(122,'Enlarge paintbrush', + 'Increase the width of the paintbrush if it is special circle or square.', + '', + true,$0034); {.> (:/ en AZERTY)} + NB_OPTIONS:=Numero_definition_option-1; + + assign(Fichier_INI,'GFX2.INI'); + {$I-} + reset(Fichier_INI,1); + {$I+} + if IOresult<>0 then {Si GFX2.INI est absent, on l'extrait de GFX2.DAT} + Erreur:=Recreer_INI + else + close(Fichier_INI); + + if not Erreur then Interpretation_du_fichier_config; + + Initialiser_config:=Erreur; +end; + + +{------------------- Enregistrement de la configuration ---------------------} +procedure Enregistrer_config; +var + Fichier:file; + Indice:word; + Octet:byte; +begin + if Choix_enreg=1 then {Enregistrement des touches (si souhait‚)} + begin + assign(Fichier,'GFX2.CFG'); + reset(Fichier,1); + + seek(Fichier,sizeof(Type_header)+Sizeof(Type_chunk)); {Positionnement sur la 1Šre touche} + + for Indice:=1 to NB_OPTIONS do + blockwrite(Fichier,Config[Indice],sizeof(Type_infos_touche)); {Les 3 premiers champs (words) sont: Num‚ro,Touche,Touche2} + + close(Fichier); + end; +end; + +{---------- V‚rifier qu'on peut ‚crire sur le lecteur de lancement ----------} +function Verifier_ecriture_possible:boolean; +var + Fichier:file; +begin + assign(Fichier,'GFX2.$$$'); + {$I-} + rewrite(Fichier,1); + close(Fichier); + erase(Fichier); + {$I+} + Verifier_ecriture_possible:=(IOresult=0); +end; + +{============================================================================} +var + Keyb_mode:byte; + +begin + if Verifier_ecriture_possible then + begin + + asm + mov ax,0AD83h + int 2Fh + mov Keyb_mode,bl + mov ax,0AD82h + xor bl,bl + int 2Fh + end; + + Text_mode_80x50; + Cacher_curseur; + Dessiner_ecran_principal; + if not Initialiser_config then + begin + Setup; + Enregistrer_config; + + Text_mode_80x25; + Montrer_curseur; + + asm + mov ax,0AD82h + mov bl,Keyb_mode + int 2Fh + end; + + halt(0); + end + else + begin + Text_mode_80x25; + writeln('Error reading GFX2.DAT! This file is either absent or corrupt.'); + Montrer_curseur; + + asm + mov ax,0AD82h + mov bl,Keyb_mode + int 2Fh + end; + halt(1); + end; + end + else + begin + writeln('Error: You mustn''t run this setup program from a read-only drive!'); + writeln; + writeln('The most probable cause of this error is that you are either running this'); + writeln('program from a CD-ROM or a protected floppy disk.'); + writeln('You should try to copy all the files of GrafX 2.00 on a hard drive, or to'); + writeln('unprotect your floppy disk if you really want to run it from this medium.'); + halt(1); + end; +end. diff --git a/const.h b/const.h new file mode 100644 index 00000000..9b79f516 --- /dev/null +++ b/const.h @@ -0,0 +1,449 @@ +#ifndef _CONST_H_ +#define _CONST_H_ + + + +// D‚claration des constantes //////////////////////////////////////////////// + +#define M_PI 3.14159265358979323846264338328 +#define M_2PI 6.28318530717958647692528676656 + +// Note: La taille du fichier GFX2.DAT est d‚finie au d‚but de INIT.C ! +#define POURCENTAGE_VERSION "96.5%" // Libell‚ du pourcentage de la version á +#define VERSION1 2 // | +#define VERSION2 0 // |_ Num‚ro de version d‚coup‚ en +#define BETA1 96 // | plusieurs parties => 2.0 á95.5% +#define BETA2 5 // | +#define ALPHA_BETA "á" // Type de la version "à" ou "á" +#define TAILLE_FICHIER_CONFIG 10351 // Taille du fichier GFX2.CFG +#define NB_MODES_VIDEO 60 // Nombre de modes vid‚o +#define NB_BOUTONS 38 // Nombre de boutons … g‚rer +#define NB_TOUCHES 134 // Nombre de combinaisons de touches +#define NB_TOUCHES_SPECIALES 72 // Nombre de touches sp‚ciales +#define NB_OPERATIONS 32 // Nombre d'op‚rations g‚r‚es par le moteur +#define NB_FACTEURS_DE_ZOOM 12 // Nombre de facteurs de zoom +#define LARGEUR_MENU 254 // Largeur du menu en taille r‚elle +#define HAUTEUR_MENU 44 // Hauteur du menu en taille r‚elle +#define NB_SPRITES_CURSEUR 8 // Nombre de sprites de curseur +#define LARGEUR_SPRITE_CURSEUR 15 // Largeur d'un sprite de curseur en pixels +#define HAUTEUR_SPRITE_CURSEUR 15 // Hauteur d'un sprite de curseur en pixels +#define NB_SPRITES_EFFETS 9 // Nombre de sprites d'effets +#define NB_SPRITES_MENU 9 // Nombre de sprites de menu +#define LARGEUR_SPRITE_MENU 14 // Largeur d'un sprite de menu en pixels +#define HAUTEUR_SPRITE_MENU 14 // Hauteur d'un sprite de menu en pixels +#define LARGEUR_PINCEAU 16 // Largeur d'un sprite de pinceau pr‚d‚fini +#define HAUTEUR_PINCEAU 16 // Hauteur d'un sprite de pinceau pr‚d‚fini +#define TAILLE_MAXI_PINCEAU 127 // Taille maxi des pinceaux +#define NB_SPRITES_DRIVES 5 // Nombre de sprites de drives +#define LARGEUR_SPRITE_DRIVE 7 // Largeur d'un sprite de drive en pixels +#define HAUTEUR_SPRITE_DRIVE 7 // Hauteur d'un sprite de drive en pixels +#define NB_SPRITES_PINCEAU 48 // Nombre de sprites de pinceau +#define NB_TRAMES_PREDEFINIES 12 // Nombre de trames pr‚d‚finies +#define TAILLE_PILE_OPERATIONS 16 // Nombre maximum d'‚l‚ments utilis‚s par les op‚rations +#define TAILLE_MAXI_PATH 37 // Taille maximum affichable du r‚pertoire courant dans les fenˆtres du fileselect +#define TAILLE_COMMENTAIRE 32 // Taille maxi des commentaires pour le PKM +#define TAILLE_NOM_CONSTRUCTEUR 24 // Taille maxi du nom de constructeur VESA dans la fenˆtre de stats. +#define NB_PAGES_UNDO_MAX 99 // Nombre maximal de pages d'undo +#define FACTEUR_DE_ZOOM_PAR_DEFAUT 4 // Facteur de zoom initial +#define NB_SECTIONS_AIDE 3 // Nombre de sections dans l'aide + +// On impose … l'allocation dynamique des pages de backups de conserver un +// minimum de 256 Ko pour que le reste du programme puisse continuer … +// fonctionner. +#define QUANTITE_MINIMALE_DE_MEMOIRE_A_CONSERVER (256*1024) + +#define A_GAUCHE 1 // Indique une direction (ou click) … gauche +#define A_DROITE 2 // Indique une direction (ou click) … droite + +#define LARGEUR_BARRE_SPLIT 6 // [ Û±±° ] +#define PROPORTION_SPLIT 0.3 // proportion de la zone non-zoom‚e en largeur par rapport … l'‚cran +#define NB_PIXELS_ZOOMES_MIN 4 // Nombre minimal de pixels zoom‚s en largeur (Note: En dessous de 4, on ne peut plus scroller!) + + // Les diff‚rents formats de fichiers: + +#define NB_FORMATS_CONNUS 12 // Nombre de formats connus (devrait ˆtre la valeur maximale de NB_FORMATS_LOAD et NB_FORMATS_SAVE, mais plus g‚n‚ralement: Card({NB_FORMATS_LOAD} UNION {NB_FORMATS_SAVE})) +#define NB_FORMATS_LOAD 12 // Nombre de formats que l'on sait charger +#define NB_FORMATS_SAVE 12 // Nombre de formats que l'on sait sauver + +enum FORMATS_RECONNUS +{ + FORMAT_PKM=1, // | + FORMAT_LBM, // | + FORMAT_GIF, // | Il faudra penser … r‚ordonner + FORMAT_BMP, // | les donn‚es sur les formats dans + FORMAT_PCX, // | GLOBAL.H si on modifie ces cons- + FORMAT_IMG, // |_ tantes. + FORMAT_SCx, // | + FORMAT_PI1, // | Elles repr‚sentent l'indice o— + FORMAT_PC1, // | l'on doit aller piocher ces + FORMAT_CEL, // | donn‚es. + FORMAT_KCF, // | + FORMAT_PAL // | +}; + +#define FORMAT_PAR_DEFAUT FORMAT_PKM // Format par d‚faut (ah bon? oh!) + + // Les diff‚rentes erreurs: + +enum CODES_D_ERREURS +{ + ERREUR_DAT_ABSENT=1, // Le fichier GFX2.DAT est absent + ERREUR_DAT_CORROMPU, // Mauvais fichier GFX2.DAT + ERREUR_CFG_ABSENT, // Le fichier GFX2.CFG est absent + ERREUR_CFG_CORROMPU, // Mauvais fichier GFX2.CFG + ERREUR_CFG_ANCIEN, // Ancienne version du fichier GFX2.CFG + ERREUR_MEMOIRE, // Plus de m‚moire + ERREUR_LIGNE_COMMANDE, // Erreur sur la ligne de commande + ERREUR_DRIVER_SOURIS, // Pas de driver souris install‚ + ERREUR_MODE_VESA_INVALIDE, // Mode VESA demand‚ sur la ligne de commande invalide + ERREUR_MODE_INTERDIT, // Mode demand‚ sur la ligne de commande interdit (coch‚ en noir) + ERREUR_NUMERO_MODE, // Erreur de choix de mode sur la ligne de commande + ERREUR_SAUVEGARDE_CFG, // Erreur en ‚criture pour GFX2.CFG + ERREUR_REPERTOIRE_DISPARU, // Le r‚pertoire de lancement n'existe plus + ERREUR_INI_ABSENT, // Le fichier GFX2.INI est absent + ERREUR_INI_CORROMPU, // Le fichier GFX2.INI est corrompu + ERREUR_SAUVEGARDE_INI, // Le fichier GFX2.INI n'est pas inscriptible + ERREUR_SORRY_SORRY_SORRY // On le refera plus, promis +}; + + // Les diff‚rents types de modes vid‚os + +enum TYPES_DE_MODES_VIDEO +{ + MODE_SDL + /*MODE_MCGA, + MODE_X, + MODE_VESA, // Attention! Si on change la num‚rotation, il faut + MODE_XVESA // que les 2 plus grandes valeurs soient ces 2 modes!*/ +}; + + // Les diff‚rents modes vid‚os (avec leur nø d'ordre) + +enum MODES_VIDEO +{ + MODE_320_200, // !!! MODE 0 !!! + MODE_320_224, + MODE_320_240, + MODE_320_256, + MODE_320_270, + MODE_320_282, + MODE_320_300, + MODE_320_360, + MODE_320_400, + MODE_320_448, + MODE_320_480, + MODE_320_512, + MODE_320_540, + MODE_320_564, + MODE_320_600, + MODE_360_200, // 15 + MODE_360_224, + MODE_360_240, + MODE_360_256, + MODE_360_270, + MODE_360_282, + MODE_360_300, + MODE_360_360, + MODE_360_400, + MODE_360_448, + MODE_360_480, + MODE_360_512, + MODE_360_540, + MODE_360_564, + MODE_360_600, + MODE_400_200, // 30 + MODE_400_224, + MODE_400_240, + MODE_400_256, + MODE_400_270, + MODE_400_282, + MODE_400_300, + MODE_400_360, + MODE_400_400, + MODE_400_448, + MODE_400_480, + MODE_400_512, + MODE_400_540, + MODE_400_564, + MODE_400_600, + MODE_640_224, // 45 + MODE_640_240, + MODE_640_256, + MODE_640_270, + MODE_640_300, + MODE_640_350, + MODE_640_400, + MODE_640_448, + MODE_640_480, + MODE_640_512, + MODE_640_540, + MODE_640_564, + MODE_640_600, + MODE_800_600, + MODE_1024_768 // 59 +}; + + // Les diff‚rentes cat‚gories de bouton: + +enum FAMILLES_DE_BOUTONS +{ + FAMILLE_OUTIL=1, // Outils de dessin + FAMILLE_INTERRUPTION, // Op‚ration ‚ph‚mŠre + FAMILLE_INSTANTANE, // Pif paf + FAMILLE_TOOLBAR, // Cache/Montre la barre d'outils + FAMILLE_EFFETS // Effets +}; + + // Les diff‚rentes formes de bouton: + +enum FORMES_DE_BOUTONS +{ + FORME_BOUTON_SANS_CADRE, // Ex: la palette + FORME_BOUTON_RECTANGLE, // Ex: la plupart + FORME_BOUTON_TRIANGLE_HAUT_GAUCHE, // Ex: Rectangles vides + FORME_BOUTON_TRIANGLE_BAS_DROITE // Ex: Rectangles pleins +}; + + // Les diff‚rentes formes de curseur: + +enum FORMES_DE_CURSEUR +{ + FORME_CURSEUR_FLECHE, + FORME_CURSEUR_CIBLE, // Utilise le pinceau + FORME_CURSEUR_CIBLE_PIPETTE, // Utilise le pinceau + FORME_CURSEUR_SABLIER, + FORME_CURSEUR_MULTIDIRECTIONNEL, + FORME_CURSEUR_HORIZONTAL, + FORME_CURSEUR_CIBLE_FINE, // Utilise le pinceau + FORME_CURSEUR_CIBLE_PIPETTE_FINE, // Utilise le pinceau + FORME_CURSEUR_CIBLE_XOR, + FORME_CURSEUR_RECTANGLE_XOR, + FORME_CURSEUR_ROTATE_XOR +}; + + // Les diff‚rentes formes de pinceaux (les types de pinceaux doivent ˆtre au d‚but) + +enum FORMES_DE_PINCEAUX +{ + FORME_PINCEAU_ROND, + FORME_PINCEAU_CARRE, + FORME_PINCEAU_BARRE_HORIZONTALE, + FORME_PINCEAU_BARRE_VERTICALE, + FORME_PINCEAU_SLASH, + FORME_PINCEAU_ANTISLASH, + FORME_PINCEAU_ALEATOIRE, + FORME_PINCEAU_X, + FORME_PINCEAU_PLUS, + FORME_PINCEAU_LOSANGE, + FORME_PINCEAU_ROND_TRAME, + FORME_PINCEAU_CARRE_TRAME, + FORME_PINCEAU_DIVERS,// Ce doit ˆtre le dernier des types de pinceaux, comme ‡a il indique le nombre de types de pinceaux (-1) + FORME_PINCEAU_POINT, // Utilis‚ pour r‚duire de pinceau … 1 point dans certaines op‚rations + FORME_PINCEAU_BROSSE_COULEUR, + FORME_PINCEAU_BROSSE_MONOCHROME +}; + + // Les diff‚rents ‚tats de bouton: + +#define BOUTON_RELACHE 0 +#define BOUTON_ENFONCE 1 + + // Les diff‚rents modes de Shade + +enum MODES_DE_SHADE +{ + MODE_SHADE_NORMAL, + MODE_SHADE_BOUCLE, + MODE_SHADE_NOSAT +}; + + // Les diff‚rents chunks du fichier .CFG + +enum CHUNKS_CFG +{ + CHUNK_TOUCHES, + CHUNK_MODES_VIDEO, + CHUNK_SHADE, + CHUNK_MASQUE, + CHUNK_STENCIL, + CHUNK_DEGRADES, + CHUNK_SMOOTH, + CHUNK_EXCLUDE_COLORS, + CHUNK_QUICK_SHADE +}; + + // Les diff‚rents types de lecteurs: + +enum TYPES_DE_LECTEURS +{ + DRIVE_FLOPPY_3_5, // 0: Diskette 3"« + DRIVE_FLOPPY_5_25, // 1: Diskette 5"¬ + DRIVE_HDD, // 2: HDD + DRIVE_CDROM, // 3: CD-ROM + DRIVE_NETWORK // 4: Logique (r‚seau?) +}; + + // Les diff‚rents boutons: + +enum NUMEROS_DE_BOUTONS +{ + BOUTON_PINCEAUX, + BOUTON_AJUSTER, + BOUTON_DESSIN, + BOUTON_COURBES, + BOUTON_LIGNES, + BOUTON_SPRAY, + BOUTON_FLOODFILL, + BOUTON_POLYGONES, + BOUTON_POLYFILL, + BOUTON_RECTANGLES, + BOUTON_FILLRECT, + BOUTON_CERCLES, + BOUTON_FILLCERC, + BOUTON_GRADRECT, + BOUTON_GRADMENU, + BOUTON_SPHERES, + BOUTON_BROSSE, + BOUTON_POLYBROSSE, + BOUTON_EFFETS_BROSSE, + BOUTON_EFFETS, + BOUTON_TEXTE, + BOUTON_LOUPE, + BOUTON_PIPETTE, + BOUTON_RESOL, + BOUTON_PAGE, + BOUTON_SAUVER, + BOUTON_CHARGER, + BOUTON_PARAMETRES, + BOUTON_CLEAR, + BOUTON_AIDE, + BOUTON_UNDO, + BOUTON_KILL, + BOUTON_QUIT, + BOUTON_PALETTE, + BOUTON_PAL_LEFT, + BOUTON_PAL_RIGHT, + BOUTON_CHOIX_COL, + BOUTON_CACHER +}; + + // Les actions des touches sp‚ciales + +enum ACTIONS_SPECIALES +{ + SPECIAL_MOUSE_UP, // | + SPECIAL_MOUSE_DOWN, // | + SPECIAL_MOUSE_LEFT, // | + SPECIAL_MOUSE_RIGHT, // | + SPECIAL_CLICK_LEFT, // | Il faut garder + SPECIAL_CLICK_RIGHT, // | ces constantes + SPECIAL_NEXT_FORECOLOR, // | au d‚but de la + SPECIAL_PREVIOUS_FORECOLOR, // |_ liste car elles + SPECIAL_NEXT_BACKCOLOR, // | sont r‚utilis‚es + SPECIAL_PREVIOUS_BACKCOLOR, // | avec leurs valeurs + SPECIAL_RETRECIR_PINCEAU, // | brutes en ASM dans + SPECIAL_GROSSIR_PINCEAU, // | Get_input !!! + SPECIAL_NEXT_USER_FORECOLOR, // | + SPECIAL_PREVIOUS_USER_FORECOLOR, // | + SPECIAL_NEXT_USER_BACKCOLOR, // | + SPECIAL_PREVIOUS_USER_BACKCOLOR, // | + SPECIAL_SCROLL_UP, + SPECIAL_SCROLL_DOWN, + SPECIAL_SCROLL_LEFT, + SPECIAL_SCROLL_RIGHT, + SPECIAL_SCROLL_UP_FAST, + SPECIAL_SCROLL_DOWN_FAST, + SPECIAL_SCROLL_LEFT_FAST, + SPECIAL_SCROLL_RIGHT_FAST, + SPECIAL_SCROLL_UP_SLOW, + SPECIAL_SCROLL_DOWN_SLOW, + SPECIAL_SCROLL_LEFT_SLOW, + SPECIAL_SCROLL_RIGHT_SLOW, + SPECIAL_SHOW_HIDE_CURSOR, + SPECIAL_PINCEAU_POINT, + SPECIAL_DESSIN_CONTINU, + SPECIAL_FLIP_X, + SPECIAL_FLIP_Y, + SPECIAL_ROTATE_90, + SPECIAL_ROTATE_180, + SPECIAL_STRETCH, + SPECIAL_DISTORT, + SPECIAL_OUTLINE, + SPECIAL_NIBBLE, + SPECIAL_GET_BRUSH_COLORS, + SPECIAL_RECOLORIZE_BRUSH, + SPECIAL_ROTATE_ANY_ANGLE, + SPECIAL_LOAD_BRUSH, + SPECIAL_SAVE_BRUSH, + SPECIAL_INVERT_SIEVE, + SPECIAL_ZOOM_IN, + SPECIAL_ZOOM_OUT, + SPECIAL_CENTER_ATTACHMENT, + SPECIAL_TOP_LEFT_ATTACHMENT, + SPECIAL_TOP_RIGHT_ATTACHMENT, + SPECIAL_BOTTOM_LEFT_ATTACHMENT, + SPECIAL_BOTTOM_RIGHT_ATTACHMENT, + SPECIAL_EXCLUDE_COLORS_MENU, + SPECIAL_SHADE_MODE, // | + SPECIAL_SHADE_MENU, // | + SPECIAL_QUICK_SHADE_MODE, // | + SPECIAL_QUICK_SHADE_MENU, // | + SPECIAL_STENCIL_MODE, // | + SPECIAL_STENCIL_MENU, // | + SPECIAL_MASK_MODE, // | Il faut que le premier effet soit + SPECIAL_MASK_MENU, // | SPECIAL_SHADE_MODE, et que le + SPECIAL_GRID_MODE, // | dernier soit SPECIAL_TILING_MENU, + SPECIAL_GRID_MENU, // |_ et que seuls des effets soient + SPECIAL_SIEVE_MODE, // | d‚finis entre ces deux l… car + SPECIAL_SIEVE_MENU, // | des tests sur cet intervalle sont + SPECIAL_COLORIZE_MODE, // | faits dans le moteur. + SPECIAL_COLORIZE_MENU, // | + SPECIAL_SMOOTH_MODE, // | + SPECIAL_SMOOTH_MENU, // | + SPECIAL_SMEAR_MODE, // | + SPECIAL_TILING_MODE, // | + SPECIAL_TILING_MENU // | +}; + + // D‚finition des op‚rations: + +enum OPERATIONS +{ + OPERATION_DESSIN_CONTINU, // Dessin … la main continu + OPERATION_DESSIN_DISCONTINU, // Dessin … la main discontinu + OPERATION_DESSIN_POINT, // Dessin … la main point par point + OPERATION_LIGNE, // Lignes + OPERATION_K_LIGNE, // Lignes reli‚es + OPERATION_LIGNES_CENTREES, // Lignes concentriques + OPERATION_RECTANGLE_VIDE, // Rectangle vide + OPERATION_RECTANGLE_PLEIN, // Rectangle plein + OPERATION_CERCLE_VIDE, // Cercle vide + OPERATION_CERCLE_PLEIN, // Cercle plein + OPERATION_ELLIPSE_VIDE, // Ellipse vide + OPERATION_ELLIPSE_PLEINE, // Ellipse pleine + OPERATION_FILL, // Fill + OPERATION_REMPLACER, // Remplacer couleur + OPERATION_PRISE_BROSSE, // Prise de brosse rectangulaire + OPERATION_POLYBROSSE, // Prise d'une brosse multiforme + OPERATION_PIPETTE, // R‚cup‚ration d'une couleur + OPERATION_LOUPE, // Positionnement de la fenˆtre de loupe + OPERATION_COURBE_3_POINTS, // Courbe … 3 points + OPERATION_COURBE_4_POINTS, // Courbe … 4 points + OPERATION_SPRAY, // Spray + OPERATION_POLYGONE, // Polygone + OPERATION_POLYFORM, // Polyforme + OPERATION_POLYFILL, // Polyfill + OPERATION_FILLED_POLYFORM, // Polyforme rempli + OPERATION_SCROLL, // Scroll + OPERATION_CERCLE_DEGRADE, // Cercles d‚grad‚s + OPERATION_ELLIPSE_DEGRADEE, // Ellipses d‚grad‚es + OPERATION_TOURNER_BROSSE, // Faire tourner brosse + OPERATION_ETIRER_BROSSE, // Etirer brosse + OPERATION_DEFORMER_BROSSE, // Deformer brosse + + OPERATION_AUCUNE +}; + + + +#endif diff --git a/dat/FONTE1.FNT b/dat/FONTE1.FNT new file mode 100644 index 00000000..c2fa61f9 Binary files /dev/null and b/dat/FONTE1.FNT differ diff --git a/dat/FONTE2.FNT b/dat/FONTE2.FNT new file mode 100644 index 00000000..ba632692 Binary files /dev/null and b/dat/FONTE2.FNT differ diff --git a/dat/FONTS.PKM b/dat/FONTS.PKM new file mode 100644 index 00000000..f61715f5 Binary files /dev/null and b/dat/FONTS.PKM differ diff --git a/dat/GFX2.PKM b/dat/GFX2.PKM new file mode 100644 index 00000000..ba52ebe5 Binary files /dev/null and b/dat/GFX2.PKM differ diff --git a/dat/GREETS.TXT b/dat/GREETS.TXT new file mode 100644 index 00000000..2ecaa0e9 --- /dev/null +++ b/dat/GREETS.TXT @@ -0,0 +1,147 @@ +Access +Ace +AcidJam +Acryl +Alexel +Alias +Amiral +Arrakis +Avocado +Baloo +Barti +Bat +Biro +Bisounours +BlackAxe +Bonnie +Boo +Boz +Carine +Chandra +Cheetah +Chill +Cougar +Cremax +Cyclone +Dake +Danny +Danube +Darjul +Darwin +DarkAngel +Das +Decker +DerPiipo +Destop +Diabolo +DineS +Drac +DrYes +Edyx +Eller +Ellyn +EOF +Fall +Fame +Fantom +Fear +Feather +Fennec +Filter +Fiver +Flan +Fred +FreddyV +Frost +Ga‰l(GDC) +GainX +Gandalf +Goblin +Greenpix7 +Grid +GrosQuick +HackerCroll +Haplo +Hof +Hornet +Hulud +Java +JBT +J‚r“me +Julien(JCA) +KalMinDo +KaneWood +Karma +Keith303 +Lazur +LightShow +Lluvia +Louie +Luk +Made +Mamos +Mandrixx +Mangue +Mars +Mephisto +Mercure +Mirec +Moa +Moxica +MRK +Nitch +Noal +Nytrik +Optic +Orome +Pahladin +Phar +Pink +Pixel +Profil +Prowler +Puznik +Quick +Ra +Raster +Ravian +RedBug +Rem +Rez +Roudoudou +Sacrilege +Sam +SandMan +Scape +S‚bastien +Shodan +Skal +Skyfire +Sphair +Sprocket +Stef +Stony +Sumaleth +Sunday +Suny +Sybaris +TBF +Tempest +Thor +TMK +TwoFace +Underking +Unreal +VaeVictis +Vastator +Vatin +Veckman +Wain +Wally +WillBe +Xoomie +Xtrm +YannSulu +Z +Zeb +Zebig diff --git a/dat/HLP_CRDT.PAS b/dat/HLP_CRDT.PAS new file mode 100644 index 00000000..b69c295b --- /dev/null +++ b/dat/HLP_CRDT.PAS @@ -0,0 +1,109 @@ +{ + Ce fichier contient la partie "Credits" de l'aide de GRAFX 2 +} + +procedure Generer_l_aide_Credits; +begin + Demarrer_section_d_aide; + {XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX} + {XXXXXXXXXXXXXXXXXXXXXX} + Ecrire_ligne_d_aide(T,' GRAFX 2.00'); + Ecrire_ligne_d_aide(S,' THE ULTIMATE MULTI-RESOLUTION GFX EDITOR'); + Ecrire_ligne_d_aide(N,' Copyright (c) 1996-98 by SUNSET DESIGN'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(T,'CREDITS:'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(S,' WRITTEN AND DESIGNED BY:'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(S,' GUILLAUME DORME KARL MARITAUD'); + Ecrire_ligne_d_aide(N,' alias "Robinson" & alias "X-Man"'); + Ecrire_ligne_d_aide(N,' programmer programmer'); + Ecrire_ligne_d_aide(N,' GFX artist'); + Ecrire_ligne_d_aide(T,''); + Ecrire_ligne_d_aide(S,' MISCELLANEOUS:'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' This is our very first program compiled'); + Ecrire_ligne_d_aide(N,' in Watcom C (10.6).'); + Ecrire_ligne_d_aide(N,' Low-level routines were written in 80386'); + Ecrire_ligne_d_aide(N,' Assembler (optimized for 80486) and'); + Ecrire_ligne_d_aide(N,' compiled with Borland TASM 5 (4.1).'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' We were inspired by the XSetMode routine'); + Ecrire_ligne_d_aide(N,' from ''XLIB2'' to create more amazing video'); + Ecrire_ligne_d_aide(N,' resolutions.'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' Thanks to Eclipse for their EOS 3.05 dos'); + Ecrire_ligne_d_aide(N,' extender (WEOSlite).'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' Some information taken from several docs'); + Ecrire_ligne_d_aide(N,' (PCGPE, Intervue, PC Interdit...) gave us'); + Ecrire_ligne_d_aide(N,' an invaluable help.'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' Thanks to Shawn Hargreaves for his'); + Ecrire_ligne_d_aide(N,' filled polygon routine from Allegro v2.2.'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' Thanks to Carlos "Made" Pardo for his'); + Ecrire_ligne_d_aide(N,' great GrafX2 logo.'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' A thousand thanks to the authors of the'); + Ecrire_ligne_d_aide(N,' different things listed above.'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' We also would like to thank all the'); + Ecrire_ligne_d_aide(N,' people who gave us ideas to improve'); + Ecrire_ligne_d_aide(N,' GrafX2.'); + Ecrire_ligne_d_aide(T,''); + Ecrire_ligne_d_aide(S,' FILE FORMATS CREDITS:'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' PKM : Sunset Design'); + Ecrire_ligne_d_aide(N,' LBM : Electronic Arts'); + Ecrire_ligne_d_aide(N,' GIF : Compuserve'); + Ecrire_ligne_d_aide(N,' BMP : Microsoft'); + Ecrire_ligne_d_aide(N,' PCX : Z-Soft'); + Ecrire_ligne_d_aide(N,' IMG : Bivas (W. Wiedmann?)'); + Ecrire_ligne_d_aide(N,' SCx : Colorix (?)'); + Ecrire_ligne_d_aide(N,' CEL,KCF : K.O.S. (KISekae Set system)'); + Ecrire_ligne_d_aide(N,' PI1,PC1 : Degas Elite'); + Ecrire_ligne_d_aide(N,' PAL : ermmh... nobody (?)'); + Ecrire_ligne_d_aide(T,''); + Ecrire_ligne_d_aide(T,'HOW TO CONTACT US ?'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(S,' SNAIL MAIL:'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' GUILLAUME DORME (Robinson)'); + Ecrire_ligne_d_aide(N,' 15, rue de l''observatoire'); + Ecrire_ligne_d_aide(N,' 87000 LIMOGES (FRANCE)'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' KARL MARITAUD (X-Man)'); + Ecrire_ligne_d_aide(N,' 10, rue de la Brasserie'); + Ecrire_ligne_d_aide(N,' 87000 LIMOGES (FRANCE)'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(S,' E-MAIL:'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' dorme@msi.unilim.fr'); + Ecrire_ligne_d_aide(N,' maritaud@ensil.unilim.fr'); + Ecrire_ligne_d_aide(T,''); + Ecrire_ligne_d_aide(T,'USELESS INFORMATION:'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' Source size: about 1400 Kb'); + Ecrire_ligne_d_aide(N,' GrafX2''s birth date: July 20th 1996'); + Ecrire_ligne_d_aide(T,''); + Ecrire_ligne_d_aide(T,'KNOWN BUGS:'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' - + stops the program when you'); + Ecrire_ligne_d_aide(N,' are entering values. So don''t press'); + Ecrire_ligne_d_aide(N,' these keys until we fix this bug.'); + Ecrire_ligne_d_aide(N,' - A few different key combinations return'); + Ecrire_ligne_d_aide(N,' the same code.'); + Ecrire_ligne_d_aide(N,' - A red flash appears at start up when an'); + Ecrire_ligne_d_aide(N,' empty Zip drive is found.'); + Ecrire_ligne_d_aide(N,' - Some functions aren''t finished yet.'); + Ecrire_ligne_d_aide(N,' This is normal for a Beta version, so'); + Ecrire_ligne_d_aide(N,' don''t worry.'); + Ecrire_ligne_d_aide(N,' But if you still find some bugs in the'); + Ecrire_ligne_d_aide(N,' next versions, then we''d appreciate'); + Ecrire_ligne_d_aide(N,' that you tell us what they exactly are'); + Ecrire_ligne_d_aide(N,' and how and when they occur.'); + {XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX} + {XXXXXXXXXXXXXXXXXXXXXX} + Terminer_section_d_aide; +end; diff --git a/dat/HLP_GRET.PAS b/dat/HLP_GRET.PAS new file mode 100644 index 00000000..7dac365f --- /dev/null +++ b/dat/HLP_GRET.PAS @@ -0,0 +1,67 @@ +{ + Ce fichier contient la partie "Greetings ..." de l'aide de GRAFX 2 +} + +procedure Generer_l_aide_Greetings; +begin + Demarrer_section_d_aide; + {XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX} + {XXXXXXXXXXXXXXXXXXXXXX} + Ecrire_ligne_d_aide(T,'GREETINGS:'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,'Our best regards go to...'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' Access Filter Pink'); + Ecrire_ligne_d_aide(N,' Ace Fiver Pixel'); + Ecrire_ligne_d_aide(N,' AcidJam Flan Profil'); + Ecrire_ligne_d_aide(N,' Acryl Fred Prowler'); + Ecrire_ligne_d_aide(N,' Alexel FreddyV Puznik'); + Ecrire_ligne_d_aide(N,' Alias Frost Quick'); + Ecrire_ligne_d_aide(N,' Amiral Ga‰l(GDC) Ra'); + Ecrire_ligne_d_aide(N,' Arrakis GainX Raster'); + Ecrire_ligne_d_aide(N,' Avocado Gandalf Ravian'); + Ecrire_ligne_d_aide(N,' Baloo Goblin RedBug'); + Ecrire_ligne_d_aide(N,' Barti Greenpix7 Rem'); + Ecrire_ligne_d_aide(N,' Bat Grid Rez'); + Ecrire_ligne_d_aide(N,' Biro GrosQuick Roudoudou'); + Ecrire_ligne_d_aide(N,' Bisounours HackerCroll Sacrilege'); + Ecrire_ligne_d_aide(N,' BlackAxe Haplo Sam'); + Ecrire_ligne_d_aide(N,' Bonnie Hof SandMan'); + Ecrire_ligne_d_aide(N,' Boo Hornet Scape'); + Ecrire_ligne_d_aide(N,' Boz Hulud S‚bastien'); + Ecrire_ligne_d_aide(N,' Carine Java Shodan'); + Ecrire_ligne_d_aide(N,' Chandra JBT Skal'); + Ecrire_ligne_d_aide(N,' Cheetah J‚r“me Skyfire'); + Ecrire_ligne_d_aide(N,' Chill Julien(JCA) Sphair'); + Ecrire_ligne_d_aide(N,' Cougar KalMinDo Sprocket'); + Ecrire_ligne_d_aide(N,' Cremax KaneWood Stef'); + Ecrire_ligne_d_aide(N,' Cyclone Karma Stony'); + Ecrire_ligne_d_aide(N,' Dake Keith303 Sumaleth'); + Ecrire_ligne_d_aide(N,' Danny Lazur Sunday'); + Ecrire_ligne_d_aide(N,' Danube LightShow Suny'); + Ecrire_ligne_d_aide(N,' Darjul Lluvia Sybaris'); + Ecrire_ligne_d_aide(N,' Darwin Louie TBF'); + Ecrire_ligne_d_aide(N,' DarkAngel Luk Tempest'); + Ecrire_ligne_d_aide(N,' Das Made Thor'); + Ecrire_ligne_d_aide(N,' Decker Mamos TMK'); + Ecrire_ligne_d_aide(N,' DerPiipo Mandrixx TwoFace'); + Ecrire_ligne_d_aide(N,' Destop Mangue Underking'); + Ecrire_ligne_d_aide(N,' Diabolo Mars Unreal'); + Ecrire_ligne_d_aide(N,' DineS Mephisto VaeVictis'); + Ecrire_ligne_d_aide(N,' Drac Mercure Vastator'); + Ecrire_ligne_d_aide(N,' DrYes Mirec Vatin'); + Ecrire_ligne_d_aide(N,' Edyx Moa Veckman'); + Ecrire_ligne_d_aide(N,' Eller Moxica Wain'); + Ecrire_ligne_d_aide(N,' Ellyn MRK Wally'); + Ecrire_ligne_d_aide(N,' EOF Nitch WillBe'); + Ecrire_ligne_d_aide(N,' Fall Noal Xoomie'); + Ecrire_ligne_d_aide(N,' Fame Nytrik Xtrm'); + Ecrire_ligne_d_aide(N,' Fantom Optic YannSulu'); + Ecrire_ligne_d_aide(N,' Fear Orome Z'); + Ecrire_ligne_d_aide(N,' Feather Pahladin Zeb'); + Ecrire_ligne_d_aide(N,' Fennec Phar Zebig'); + Ecrire_ligne_d_aide(N,' and all #pixel, #demofr and #coders.'); + {XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX} + {XXXXXXXXXXXXXXXXXXXXXX} + Terminer_section_d_aide; +end; diff --git a/dat/HLP_RGST.PAS b/dat/HLP_RGST.PAS new file mode 100644 index 00000000..d0b7975f --- /dev/null +++ b/dat/HLP_RGST.PAS @@ -0,0 +1,52 @@ +{ Ce fichier contient la partie "Register?" de l'aide de GrafX2 } + +procedure Generer_l_aide_Register; +begin + Demarrer_section_d_aide; + {XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX} + {XXXXXXXXXXXXXXXXXXXXXX} + Ecrire_ligne_d_aide(T,'REGISTERING ?'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' You''ll probably say:'); + Ecrire_ligne_d_aide(N,' "Does this mean that I have to pay?"'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' And we''ll reply to you: No...'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(T,'GRAFX 2.00 IS FREEWARE'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' ... But, but, but...'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' Considering the amount of work (and love)'); + Ecrire_ligne_d_aide(N,' we put in this program, we would extremely'); + Ecrire_ligne_d_aide(N,' appreciate that you "give" us something in'); + Ecrire_ligne_d_aide(N,' exchange for the use you make of it.'); + Ecrire_ligne_d_aide(N,' Let''s say some money, or a nice picture'); + Ecrire_ligne_d_aide(N,' you drew with GrafX2, or a postcard...'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' If you make profit with an image you drew'); + Ecrire_ligne_d_aide(N,' with GrafX2, it would be great if you sent'); + Ecrire_ligne_d_aide(N,' us this picture. If you used it for a game,'); + Ecrire_ligne_d_aide(N,' would be wiser not to send all your graphs,'); + Ecrire_ligne_d_aide(N,' what about sending a copy of the game?'); + Ecrire_ligne_d_aide(T,''); + Ecrire_ligne_d_aide(T,'FREEWARE CONVENTIONS:'); + Ecrire_ligne_d_aide(N,''); + Ecrire_ligne_d_aide(N,' This version of GrafX2 is being released'); + Ecrire_ligne_d_aide(N,' to you as is.'); + Ecrire_ligne_d_aide(N,' All bugs should be reported to either'); + Ecrire_ligne_d_aide(N,' Robinson or X-Man.'); + Ecrire_ligne_d_aide(N,' The authors take no responsibility for'); + Ecrire_ligne_d_aide(N,' lost work, or damaged equipment caused'); + Ecrire_ligne_d_aide(N,' directly or indirectly by this program.'); + Ecrire_ligne_d_aide(N,' GrafX2 cannot be modified in any way'); + Ecrire_ligne_d_aide(N,' without our written consent.'); + Ecrire_ligne_d_aide(N,' Finally, the charging of monetary fees by'); + Ecrire_ligne_d_aide(N,' any unauthorized party for the circulation'); + Ecrire_ligne_d_aide(N,' or use of this utility is expressly'); + Ecrire_ligne_d_aide(N,' forbidden.'); + Ecrire_ligne_d_aide(N,' This means that if you had to pay for'); + Ecrire_ligne_d_aide(N,' getting GrafX2, you have been swindled.'); + {XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX} + {XXXXXXXXXXXXXXXXXXXXXX} + Terminer_section_d_aide; +end; diff --git a/dat/IMG2FNT.EXE b/dat/IMG2FNT.EXE new file mode 100644 index 00000000..a1739989 Binary files /dev/null and b/dat/IMG2FNT.EXE differ diff --git a/dat/IMG2FNT.PAS b/dat/IMG2FNT.PAS new file mode 100644 index 00000000..30c4ab8a --- /dev/null +++ b/dat/IMG2FNT.PAS @@ -0,0 +1,88 @@ +program IMG2FNT; + +const + COULEUR_TEXTE=15; + +var + Fichier:file; + Image:array[0..20479] of byte; + Fonte:array[0..2047] of byte; + Offset_dans_image:longint; + Masque:byte; + Position:word; + i,j,k,l:word; + Errcode:integer; + +begin + if (paramcount<2) or (paramcount>3) then + begin + writeln('Syntaxe: IMG2FNT [offset dans l''image]'); + writeln('Attention: ne pas taper les extensions!'); + halt(1); + end; + + if paramcount=3 then + begin + val(paramstr(3),Offset_dans_image,Errcode); + if Errcode<>0 then + begin + writeln('Syntaxe: IMG2FNT [offset dans l''image]'); + writeln('Attention: ne pas taper les extensions!'); + halt(1); + end; + end + else + Offset_dans_image:=0; + + assign(Fichier,paramstr(1)+'.img'); + reset(Fichier,1); + seek(Fichier,896+Offset_dans_image); + blockread(Fichier,Image,17280); + close(Fichier); + + {Transformation de l'image en 0 pour le fond et 255 pour le texte} + for i:=0 to 17279 do + if Image[i]<>COULEUR_TEXTE + then Image[i]:=0 + else Image[i]:=255; + + for i:=0 to 255 do + for j:=0 to 7 do + begin + Fonte[(i shl 3)+j]:=0; + Masque:=128; + for k:=0 to 7 do + begin + asm {Position:=((i DIV 45)*2880) + ((i MOD 45)*8) + (j*360) +k} + mov ax,i + mov bl,45 + div bl + push ax + xor ah,ah + mov bx,2880 + mul bx + mov dx,ax + pop ax + mov cl,8 + shr ax,cl + mov cl,3 + shl ax,cl + add dx,ax + add dx,k + mov Position,dx + mov ax,j + mov bx,360 + mul bx + add Position,ax + end; + Fonte[(i shl 3)+j]:=Fonte[(i shl 3)+j] + (Masque and Image[Position]); + Masque:=Masque shr 1; + end; + end; + + assign(Fichier,Paramstr(2)+'.fnt'); + rewrite(Fichier,1); + blockwrite(Fichier,Fonte,2048); + close(Fichier); +end. + diff --git a/dat/MAKEDAT.EXE b/dat/MAKEDAT.EXE new file mode 100644 index 00000000..1eb6a764 Binary files /dev/null and b/dat/MAKEDAT.EXE differ diff --git a/dat/MAKEDAT.PAS b/dat/MAKEDAT.PAS new file mode 100644 index 00000000..c974e000 --- /dev/null +++ b/dat/MAKEDAT.PAS @@ -0,0 +1,738 @@ +program makedat; + +type tpalette=array[0..767] of byte; +var palette:tpalette; + +{****************************************************************************} +{****************************************************************************} +{****************************************************************************} + +Procedure XMODE;assembler; +const + X360Y270 : array[0..18] of word = + ( $12E7, $6B00, $5901, $5A02, $8E03, $5E04, $8A05, $3006, $F007, $0008, + $6109, $2010, $A911, $1B12, $2D13, $0014, $1F15, $2F16, $E317 ); +asm + push ds + + mov ax,13h + int 10h + + mov dx,3c4h + mov ax,0604h + out dx,ax + mov ax,0100h + out dx,ax + + lea si,X360Y270 + lodsb + or al,al + jz @@DontSetDot + mov dx,3C2h + out dx,al + + @@DontSetDot: + mov dx,3C4h + mov ax,0300h + out dx,ax + mov dx,3D4h + mov al,11h + out dx,al + inc dx + in al,dx + and al,07fh + out dx,al + dec dx + cld + xor cx,cx + lodsb + mov cl,al + + @@SetCRTParmsLoop: + lodsw + out dx,ax + loop @@SetCRTParmsLoop + + mov dx,3C4h + mov ax,0f02h + out dx,ax + mov ax,0A000h + mov es,ax + sub di,di + sub ax,ax + mov cx,8000h + rep stosw + + mov dx,3D4h + mov al,13h + out dx,al + inc dx + mov ax,90 + shr ax,1 + out dx,al + + pop ds +end; + +Procedure pixel(x,y : word;coul : byte);assembler; +asm + mov dx,3C4h + mov ax,0102h + mov cx,x + and cx,3 + shl ah,cl + out dx,ax + + mov ax,0A000h + mov es,ax + + mov ax,y + mov bx,90 + mul bx + + mov bx,x + shr bx,2 + add ax,bx + mov di,ax + mov al,coul + stosb +end; + +Function lit_pixel(x,y : word):byte; +var a : byte; +begin + asm + mov ax,0A000h + mov es,ax + + mov ax,y + mov bx,90 + mul bx + + mov bx,x + mov cl,bl + and cl,3 + + shr bx,2 + add ax,bx + mov di,ax + + mov dx,3CEh + mov al,4 + mov ah,cl + out dx,ax + + mov al,[es:di] + mov a,al + end; + lit_pixel:=a; +end; + + +procedure set_palette; assembler; +asm + push ds + lea si,palette + mov dx,3C8h + xor al,al + out dx,al + inc dl + mov cx,768 + rep outsb + pop ds +end; + + +{----------------------------------------------------------------------------} +{----------------------------------------------------------------------------} +{----------------------------------------------------------------------------} + +type t_os_tampon=array[0..63999] of byte; +var os_index:word; +var os_tampon:^t_os_tampon; + +function octet_suivant(var f:file):byte; +var effect_result:word; +begin + inc(os_index); + if (os_index>=64000) then + begin + {$I-} + blockread(f,os_tampon^,64000,effect_result); + {$I+} + os_index:=0; + end; + octet_suivant:=os_tampon^[os_index]; +end; + +procedure init_os; +begin + new(os_tampon); + os_index:=64000; +end; + +procedure close_os; +begin + dispose(os_tampon); +end; + +{----------------------------------------------------------------------------} + +var eo_index:word; +var eo_tampon:^t_os_tampon; + +procedure ecrire_octet(var f:file; octet:byte); +var + effect_result:word; +begin + eo_tampon^[eo_index]:=octet; + inc(eo_index); + if (eo_index>=64000) then + begin + blockwrite(f,eo_tampon^,64000,effect_result); + eo_index:=0; + end; +end; + +procedure init_eo; +begin + new(eo_tampon); + eo_index:=0; +end; + +procedure close_eo(var f:file); +var effect_result:word; +begin + if eo_index>0 then blockwrite(f,eo_tampon^,eo_index,effect_result); + dispose(eo_tampon); +end; + +{----------------------------------------------------------------------------} +{----------------------------------------------------------------------------} +{----------------------------------------------------------------------------} + + + +{--------------------- DEPACKER une IMAGE au format PKM ---------------------} +procedure load_PKM(nom_fichier:string); +{errcode retourn‚: 0=OK , 1=pas un PKM , 2=taille incorrecte} +type + header = record {taille: 780 octets} + ident : array[1..3] of char; { chaŒne "PKM" } + methode : byte; { m‚thode de compression: } + { 0 = compression en ligne (c)KM } + { autres = inconnues pour le moment } + Recon1 : byte; { octet de reconnaissance sur 1 octet } + Recon2 : byte; { octet de reconnaissance sur 2 octets } + longx : word; { taille de l'image en X } + longy : word; { taille de l'image en Y } + palette : tpalette; { palette RVB 256*3 } + jump : word; { taille du saut entre le header et l'image } + end; +var + TailleX,TailleY:word; + errcode:byte; + coul,octet:byte; + taille_fichier:word; + i,j,k:word; + c:longint; + offsX,offsY,X,Y:word; + fich:file; + head: header; + taille_image: longint; +begin + offsX:=0; + offsY:=0; + assign(fich,Nom_Fichier); + reset(fich,1); + taille_fichier:=filesize(fich); + blockread(fich,head,SizeOf(Header)); + if Head.LongY>270 then Head.LongY:=270; + + if (head.ident<>'PKM') then + begin + errcode:=1; + exit; + end; + if (head.longX>360) then + begin + errcode:=2; + exit; + end; + + { d‚finition de la palette } + Palette:=head.palette; + + set_palette; + + TailleX:=Head.LongX; + TailleY:=Head.LongY; + taille_image:=Head.LongX; + taille_image:=taille_image*Head.LongY; + Seek(fich,SizeOf(Header)+Head.Jump); + + init_os; + + j:=0; + octet:=octet_suivant(fich); + c:=0; + while (cHead.Recon1) and (octet<>Head.Recon2) + then + begin + X:=c mod head.longX; + Y:=c div head.longX; + if (X<360) and (Y<270) then + pixel(X,Y,octet); + inc(j); + octet:=octet_suivant(fich); + inc(c); + end + else + begin + if octet=Head.Recon1 + then + begin + inc(j); + octet:=octet_suivant(fich); + coul:=octet; + inc(j); + octet:=octet_suivant(fich)-1; + for i:=0 to octet do + begin + X:=(c+i) mod head.longX; + Y:=(c+i) div head.longX; + if (X<360) and (Y<270) then + pixel(X,Y,coul); + end; + c:=c+octet+1; + inc(j); + octet:=octet_suivant(fich); + end + else + begin + inc(j); + octet:=octet_suivant(fich); + coul:=octet; + inc(j); + octet:=octet_suivant(fich); + k:=(octet shl 8)+octet_suivant(fich); + for i:=0 to (k-1) do + begin + X:=(c+i) mod head.longX; + Y:=(c+i) div head.longX; + if (X<360) and (Y<270) then + pixel(X,Y,coul); + end; + c:=c+k; + j:=j+2; + octet:=octet_suivant(fich); + end; + end; + end; + close_os; + close(fich); + errcode:=0; +end; + +{****************************************************************************} +{****************************************************************************} +{****************************************************************************} + +var Crypt_curseur:byte; +const Crypt_cle:string[13]='Sunset Design'; + +function crypt(octet:byte):byte; +begin + crypt:=octet xor ord(Crypt_cle[Crypt_curseur]); + Crypt_curseur:=(Crypt_curseur mod 13)+1; +end; + +procedure Ecrire_palette(var Fichier:file); +var i:word; +begin + for i:=0 to 767 do ecrire_octet(Fichier,crypt(palette[i])); +end; + +procedure Lire_et_ecrire_sprite(var Fichier:file; x1,y1,x2,y2:word); +var i,j:word; +begin + for j:=y1 to y2 do + for i:=x1 to x2 do + ecrire_octet(Fichier,crypt(lit_pixel(i,j))); +end; + + +procedure Ecrire_trames_predefinies(var Fichier:file); +var + n,i,j:word; + Octet:byte; + Pixel_lu:byte; +begin + for n:=0 to 11 do {Pour chaque trame pr‚d‚finie} + begin + for j:=0 to 15 do + begin + Octet:=0; + for i:=0 to 7 do + begin + Octet:=(Octet shl 1); + Pixel_lu:=lit_pixel(9+(17*n)+i,196+j); + if Pixel_lu>0 then + inc(Octet); + end; + ecrire_octet(Fichier,crypt(Octet)); + + Octet:=0; + for i:=0 to 7 do + begin + Octet:=(Octet shl 1); + Pixel_lu:=lit_pixel(1+(17*n)+i,196+j); + if Pixel_lu>0 then + inc(Octet); + end; + ecrire_octet(Fichier,crypt(Octet)); + end; + end; +end; + + +procedure Rajouter_fichier(var Fichier:file;Nom_fichier:string;Crypter:boolean); +var + Fichier_a_ajouter:file; + Taille :word; + Indice :word; +begin + assign (Fichier_a_ajouter,Nom_fichier); + reset (Fichier_a_ajouter,1); + Taille:=filesize(Fichier_a_ajouter); + + init_os; + if (Crypter) then + for Indice:=1 to Taille do + ecrire_octet(Fichier,crypt(octet_suivant(Fichier_a_ajouter))) + else + for Indice:=1 to Taille do + ecrire_octet(Fichier,octet_suivant(Fichier_a_ajouter)); + close_os; + + close(Fichier_a_ajouter); +end; + + +procedure Coder_partie_de_fonte(var Fichier:file;Pos_X,Pos_Y,Nb_char:word); +var + X,Y:word; + Indice_char:word; + Couleur_temporaire:byte; +begin + for Indice_char:=1 to Nb_char do + begin + for X:=0 to 5 do + for Y:=0 to 7 do + begin + Couleur_temporaire:=lit_pixel(Pos_X+X,Pos_Y+Y); + + if not (Couleur_temporaire in [25,7,15]) + then Couleur_temporaire:=0; + + ecrire_octet(Fichier,crypt(Couleur_temporaire)); + end; + + inc(Pos_X,6); + end; +end; + + +var + Fichier:file; + Position_de_depart_de_la_section_d_aide:longint; + Nombre_de_lignes_d_aide :word; + Nombre_d_octets_utilises:word; + + +procedure Demarrer_section_d_aide; +begin + Nombre_de_lignes_d_aide :=0; + Nombre_d_octets_utilises:=0; + assign(Fichier,'GFX2.DAT'); + reset (Fichier,1); + Position_de_depart_de_la_section_d_aide:=filesize(Fichier); + seek(Fichier,Position_de_depart_de_la_section_d_aide); + {On ‚crit temporairement des valeurs erron‚es dans le fichier:} + blockwrite(Fichier,Nombre_de_lignes_d_aide ,2); {Nb de lignes} + blockwrite(Fichier,Nombre_d_octets_utilises,2); {Nb d'octets utilis‚s} +end; + + +procedure Terminer_section_d_aide; +begin + seek (Fichier,Position_de_depart_de_la_section_d_aide); + {On ‚crit d‚finitivement les valeurs correctes dans le fichier:} + blockwrite(Fichier,Nombre_de_lignes_d_aide ,2); {Nb de lignes} + blockwrite(Fichier,Nombre_d_octets_utilises,2); {Nb d'octets utilis‚s} + close (Fichier); +end; + +const + TITRE = 1; + SOUS_TITRE = 2; + NORMAL = 3; + T = TITRE; + S = SOUS_TITRE; + N = NORMAL; + +{$I TABLES} + +procedure Ecrire_ligne_d_aide(De_type:byte;Chaine:string); +var + Code:byte; {Code … inscrire dans le fichier} + Indice:byte; {Indice de balayage de la chaŒne} +begin + + if length(Chaine)>44 then + begin + close (Fichier); + asm + mov ax,3 + int 10h + end; + writeln('ERREUR DANS L''AIDE !!! Il y a une ligne qui est trop longue !!!'); + halt(1); + end; + + case De_type of + + TITRE : + begin + {1Šre ligne:} + + {On code la taille de la 1Šre ligne chaŒne:} + Code:=(length(Chaine) shl 1) or $80; + blockwrite(Fichier,Code,1); + + {On code la 1Šre ligne de la chaŒne selon la table des caractŠres} + {de titrage:} + for Indice:=1 to length(Chaine) do + begin + Code:=TABLE_TITRE[ord(Chaine[Indice])]; + blockwrite(Fichier,Code,1); + inc(Code); + blockwrite(Fichier,Code,1); + end; + + {On met … jour les compteurs:} + inc(Nombre_de_lignes_d_aide); + inc(Nombre_d_octets_utilises,(length(Chaine) shl 1)+1); + + {2Šme ligne:} + + {On code la taille de la 2Šme ligne chaŒne:} + Code:=(length(Chaine) shl 1) or $80; + blockwrite(Fichier,Code,1); + + {On code la 2Šme ligne de la chaŒne selon la table des caractŠres} + {de titrage:} + for Indice:=1 to length(Chaine) do + begin + Code:=TABLE_TITRE[ord(Chaine[Indice])]; + if Chaine[Indice] in ['A'..'V'] + then inc(Code,44) + else inc(Code,40); + + blockwrite(Fichier,Code,1); + inc(Code); + blockwrite(Fichier,Code,1); + end; + + {On met … jour les compteurs:} + inc(Nombre_de_lignes_d_aide); + inc(Nombre_d_octets_utilises,(length(Chaine) shl 1)+1); + end; + + SOUS_TITRE : + begin + {On code la taille de la chaŒne:} + Code:=length(Chaine); + blockwrite(Fichier,Code,1); + + {On code la chaŒne selon la table des sous-titres:} + for Indice:=1 to length(Chaine) do + begin + Code:=TABLE_SOUS_TITRE[ord(Chaine[Indice])]; + blockwrite(Fichier,Code,1); + end; + + {On met … jour les compteurs:} + inc(Nombre_de_lignes_d_aide); + inc(Nombre_d_octets_utilises,length(Chaine)+1); + end; + + NORMAL : + begin + {On code la taille de la chaŒne:} + Code:=length(Chaine); + blockwrite(Fichier,Code,1); + + {On code la chaŒne selon la table des caractŠres normaux:} + for Indice:=1 to length(Chaine) do + begin + Code:=TABLE_NORMAL[ord(Chaine[Indice])]; + blockwrite(Fichier,Code,1); + end; + + {On met … jour les compteurs:} + inc(Nombre_de_lignes_d_aide); + inc(Nombre_d_octets_utilises,length(Chaine)+1); + end; + + end; + +end; + + +{$I HLP_GRET} +{$I HLP_CRDT} +{$I HLP_RGST} + + +BEGIN + XMODE; + + Load_PKM('GFX2.PKM'); + + assign(Fichier,'GFX2.DAT'); + rewrite(Fichier,1); + init_eo; + + Crypt_curseur:=1; + + Ecrire_palette(Fichier); + Lire_et_ecrire_sprite(Fichier, 1, 1,254, 44); {Menu} + + Lire_et_ecrire_sprite(Fichier, 2, 47, 15, 60); {Shade} + Lire_et_ecrire_sprite(Fichier, 19, 47, 32, 60); {Colorize} + Lire_et_ecrire_sprite(Fichier, 36, 47, 49, 60); {Smooth} + Lire_et_ecrire_sprite(Fichier, 53, 47, 66, 60); {Tiling} + Lire_et_ecrire_sprite(Fichier, 70, 47, 83, 60); {Stencil} + Lire_et_ecrire_sprite(Fichier, 87, 47,100, 60); {Sieve} + Lire_et_ecrire_sprite(Fichier,104, 47,117, 60); {Grid} + Lire_et_ecrire_sprite(Fichier,121, 47,134, 60); {Mask} + Lire_et_ecrire_sprite(Fichier,138, 47,151, 60); {Smear} + + Lire_et_ecrire_sprite(Fichier, 1, 85, 15, 99); {Fleche} + Lire_et_ecrire_sprite(Fichier, 17, 85, 31, 99); {Viseur} + Lire_et_ecrire_sprite(Fichier, 65, 85, 79, 99); {Viseur pipette} + Lire_et_ecrire_sprite(Fichier, 33, 85, 47, 99); {Sablier} + Lire_et_ecrire_sprite(Fichier, 49, 85, 63, 99); {Multidirectionnel} + Lire_et_ecrire_sprite(Fichier, 81, 85, 95, 99); {Horizontal} + Lire_et_ecrire_sprite(Fichier, 97, 85,111, 99); {Viseur fin} + Lire_et_ecrire_sprite(Fichier,113, 85,127, 99); {Viseur pipette fin} + + Lire_et_ecrire_sprite(Fichier, 2,102, 15,115); {Dessin continu} + Lire_et_ecrire_sprite(Fichier, 19,102, 32,115); {Dessin interrompu} + Lire_et_ecrire_sprite(Fichier, 36,102, 49,115); {Dessin point} + Lire_et_ecrire_sprite(Fichier, 53,102, 66,115); {Pinceau-brosse} + Lire_et_ecrire_sprite(Fichier, 70,102, 83,115); {Courbe 3 pts} + Lire_et_ecrire_sprite(Fichier, 87,102,100,115); {Courbe 4 pts} + Lire_et_ecrire_sprite(Fichier,104,102,117,115); {Ligne} + Lire_et_ecrire_sprite(Fichier,121,102,134,115); {K-Line} + Lire_et_ecrire_sprite(Fichier,138,102,151,115); {Lignes concentiques} + + Lire_et_ecrire_sprite(Fichier, 1,120, 16,135); {Pinceau 1} + Lire_et_ecrire_sprite(Fichier, 18,120, 33,135); {Pinceau 2} + Lire_et_ecrire_sprite(Fichier, 35,120, 50,135); {Pinceau 3} + Lire_et_ecrire_sprite(Fichier, 52,120, 67,135); {Pinceau 4} + Lire_et_ecrire_sprite(Fichier, 69,120, 84,135); {Pinceau 5} + Lire_et_ecrire_sprite(Fichier, 86,120,101,135); {Pinceau 6} + Lire_et_ecrire_sprite(Fichier,103,120,118,135); {Pinceau 7} + Lire_et_ecrire_sprite(Fichier,120,120,135,135); {Pinceau 8} + Lire_et_ecrire_sprite(Fichier,137,120,152,135); {Pinceau 9} + Lire_et_ecrire_sprite(Fichier,154,120,169,135); {Pinceau 10} + Lire_et_ecrire_sprite(Fichier,171,120,186,135); {Pinceau 11} + Lire_et_ecrire_sprite(Fichier,188,120,203,135); {Pinceau 12} + Lire_et_ecrire_sprite(Fichier, 1,137, 16,152); {Pinceau 13} + Lire_et_ecrire_sprite(Fichier, 18,137, 33,152); {Pinceau 14} + Lire_et_ecrire_sprite(Fichier, 35,137, 50,152); {Pinceau 15} + Lire_et_ecrire_sprite(Fichier, 52,137, 67,152); {Pinceau 16} + Lire_et_ecrire_sprite(Fichier, 69,137, 84,152); {Pinceau 17} + Lire_et_ecrire_sprite(Fichier, 86,137,101,152); {Pinceau 18} + Lire_et_ecrire_sprite(Fichier,103,137,118,152); {Pinceau 19} + Lire_et_ecrire_sprite(Fichier,120,137,135,152); {Pinceau 20} + Lire_et_ecrire_sprite(Fichier,137,137,152,152); {Pinceau 21} + Lire_et_ecrire_sprite(Fichier,154,137,169,152); {Pinceau 22} + Lire_et_ecrire_sprite(Fichier,171,137,186,152); {Pinceau 23} + Lire_et_ecrire_sprite(Fichier,188,137,203,152); {Pinceau 24} + Lire_et_ecrire_sprite(Fichier, 1,154, 16,169); {Pinceau 25} + Lire_et_ecrire_sprite(Fichier, 18,154, 33,169); {Pinceau 26} + Lire_et_ecrire_sprite(Fichier, 35,154, 50,169); {Pinceau 27} + Lire_et_ecrire_sprite(Fichier, 52,154, 67,169); {Pinceau 28} + Lire_et_ecrire_sprite(Fichier, 69,154, 84,169); {Pinceau 29} + Lire_et_ecrire_sprite(Fichier, 86,154,101,169); {Pinceau 30} + Lire_et_ecrire_sprite(Fichier,103,154,118,169); {Pinceau 31} + Lire_et_ecrire_sprite(Fichier,120,154,135,169); {Pinceau 32} + Lire_et_ecrire_sprite(Fichier,137,154,152,169); {Pinceau 33} + Lire_et_ecrire_sprite(Fichier,154,154,169,169); {Pinceau 34} + Lire_et_ecrire_sprite(Fichier,171,154,186,169); {Pinceau 35} + Lire_et_ecrire_sprite(Fichier,188,154,203,169); {Pinceau 36} + Lire_et_ecrire_sprite(Fichier, 1,171, 16,186); {Pinceau 37} + Lire_et_ecrire_sprite(Fichier, 18,171, 33,186); {Pinceau 38} + Lire_et_ecrire_sprite(Fichier, 35,171, 50,186); {Pinceau 39} + Lire_et_ecrire_sprite(Fichier, 52,171, 67,186); {Pinceau 40} + Lire_et_ecrire_sprite(Fichier, 69,171, 84,186); {Pinceau 41} + Lire_et_ecrire_sprite(Fichier, 86,171,101,186); {Pinceau 42} + Lire_et_ecrire_sprite(Fichier,103,171,118,186); {Pinceau 43} + Lire_et_ecrire_sprite(Fichier,120,171,135,186); {Pinceau 44} + Lire_et_ecrire_sprite(Fichier,137,171,152,186); {Pinceau 45} + Lire_et_ecrire_sprite(Fichier,154,171,169,186); {Pinceau 46} + Lire_et_ecrire_sprite(Fichier,171,171,186,186); {Pinceau 47} + Lire_et_ecrire_sprite(Fichier,188,171,203,186); {Pinceau 48} + + Lire_et_ecrire_sprite(Fichier, 1,188, 7,194); {Diskette 3"«} + Lire_et_ecrire_sprite(Fichier, 9,188, 15,194); {Diskette 5"¬} + Lire_et_ecrire_sprite(Fichier, 17,188, 23,194); {HDD} + Lire_et_ecrire_sprite(Fichier, 25,188, 31,194); {CD-ROM} + Lire_et_ecrire_sprite(Fichier, 33,188, 39,194); {Network} + + Lire_et_ecrire_sprite(Fichier, 1,213,231,268); {Logo GrafX2} + + Ecrire_trames_predefinies(Fichier); + + Rajouter_fichier(Fichier,'FONTE1.FNT',true); {Fonte systŠme} + + Rajouter_fichier(Fichier,'FONTE2.FNT',true); {Fonte exotique} + + Load_PKM('FONTS.PKM'); + + Coder_partie_de_fonte(Fichier,0,121,45); {Petites fontes} + Coder_partie_de_fonte(Fichier,0,129,45); + Coder_partie_de_fonte(Fichier,0,137,45); + Coder_partie_de_fonte(Fichier,0,145,12); + Coder_partie_de_fonte(Fichier,0,153,44); {Grosse fonte} + Coder_partie_de_fonte(Fichier,0,161,44); + Coder_partie_de_fonte(Fichier,0,169,40); + Coder_partie_de_fonte(Fichier,0,177,40); + + close_eo(Fichier); + close (Fichier); + + asm + mov ax,3 + int 10h + end; + + Generer_l_aide_Credits; + Generer_l_aide_Register; + Generer_l_aide_Greetings; + + + reset(Fichier,1); + seek(Fichier,filesize(Fichier)); + init_eo; + Rajouter_fichier(Fichier,'GFX2.INI',false); + close_eo(Fichier); + + writeln('Le fichier GFX2.DAT est cr‚‚. (taille = ',filesize(Fichier),' octets)'); + close(Fichier); +END. diff --git a/dat/MAKEFNT.BAT b/dat/MAKEFNT.BAT new file mode 100644 index 00000000..5928138f --- /dev/null +++ b/dat/MAKEFNT.BAT @@ -0,0 +1,3 @@ +@echo off +img2fnt fonts fonte1 +img2fnt fonts fonte2 17280 \ No newline at end of file diff --git a/dat/MKGREETS.EXE b/dat/MKGREETS.EXE new file mode 100644 index 00000000..9043a0ed Binary files /dev/null and b/dat/MKGREETS.EXE differ diff --git a/dat/MKGREETS.PAS b/dat/MKGREETS.PAS new file mode 100644 index 00000000..bf3d07ed --- /dev/null +++ b/dat/MKGREETS.PAS @@ -0,0 +1,105 @@ +program mkgreets; + +const + NB_MAX_LIGNES=50; + TAILLE_MAX_NICK=14; + +var + Fichier : text; + Greets : array[0..3,0..NB_MAX_LIGNES-1] of string[TAILLE_MAX_NICK]; + Total_nicks: word; + +{-----------------------------} + +procedure Init_greets; +var + i,j:word; +begin + for i:=0 to 3 do + for j:=0 to NB_MAX_LIGNES-1 do + Greets[i,j]:=''; +end; + +{-----------------------------} + +procedure Compter_greets; +var + Temp:String; +begin + Total_nicks:=0; + while not eof(Fichier) do + begin + readln(Fichier,Temp); + inc(Total_nicks); + end; +end; + +{-----------------------------} + +procedure Lire_greets; +var + Nb_nicks:word; +begin + Nb_nicks:=0; + while not eof(Fichier) do + begin + readln(Fichier,Greets[Nb_nicks div Total_nicks, Nb_nicks mod Total_nicks]); + inc(Nb_nicks); + end; +end; + +{-----------------------------} + +procedure Ecrire_greets; +var + i:word; +begin + writeln(Fichier,'{'); + writeln(Fichier,' Ce fichier contient la partie "Greetings ..." de l''aide de GRAFX 2'); + writeln(Fichier,'}'); + writeln(Fichier,''); + writeln(Fichier,'procedure Generer_l_aide_Greetings;'); + writeln(Fichier,'begin'); + writeln(Fichier,' Demarrer_section_d_aide;'); + writeln(Fichier,' {XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}'); + writeln(Fichier,' {XXXXXXXXXXXXXXXXXXXXXX}'); + writeln(Fichier,' Ecrire_ligne_d_aide(T,''GREETINGS:'');'); + writeln(Fichier,' Ecrire_ligne_d_aide(N,'''');'); + writeln(Fichier,' Ecrire_ligne_d_aide(N,''Our best regards go to...'');'); + writeln(Fichier,' Ecrire_ligne_d_aide(N,'''');'); + + for i:=0 to Total_nicks-1 do + begin + write(Fichier,' Ecrire_ligne_d_aide(N,'' ',Greets[0,i]); + if (Greets[1,i]<>'') then + write(Fichier,' ':TAILLE_MAX_NICK-length(Greets[0,i]),Greets[1,i]); + if (Greets[2,i]<>'') then + write(Fichier,' ':TAILLE_MAX_NICK-length(Greets[1,i]),Greets[2,i]); + writeln(Fichier,''');'); + end; + + writeln(Fichier,' Ecrire_ligne_d_aide(N,'' and all #pixel, #demofr and #coders.'');'); + writeln(Fichier,' {XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}'); + writeln(Fichier,' {XXXXXXXXXXXXXXXXXXXXXX}'); + writeln(Fichier,' Terminer_section_d_aide;'); + writeln(Fichier,'end;'); +end; + +{-----------------------------} + +begin + Init_greets; + assign(Fichier,'greets.txt'); + reset(Fichier); + Compter_greets; + Total_nicks:=(Total_nicks+2) div 3; + + reset(Fichier); + Lire_greets; + close(Fichier); + + assign(Fichier,'hlp_gret.pas'); + rewrite(Fichier); + Ecrire_greets; + close(Fichier); +end. diff --git a/dat/TABLES.PAS b/dat/TABLES.PAS new file mode 100644 index 00000000..e0ac2dfd --- /dev/null +++ b/dat/TABLES.PAS @@ -0,0 +1,259 @@ +{Ce fichier contient pour chaque type de fonte l'indice qu'il faut coder:} + +const + +TABLE_NORMAL:array[32..151] of byte = +( + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 0, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 0, + 0, + 93, + 94, + 95, + 96, + 0, + 97, + 0, + 98, + 99, + 100, + 101, + 0, + 0, + 0, + 0, + 0, + 0, + 102, + 0, + 103, + 0, + 0, + 104, + 105 +); + + + +TABLE_SOUS_TITRE:array[32..90] of byte = +( + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 0, + 0, + 0, + 0, + 146, + 0, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131 +); + + + + +TABLE_TITRE:array[32..90] of byte = +( + 126, + 126, + 126, + 126, + 126, + 126, + 126, + 126, + 126, + 126, + 126, + 126, + 126, + 96, + 98, + 100, + 102, + 104, + 106, + 108, + 110, + 112, + 114, + 116, + 118, + 120, + 122, + 126, + 126, + 126, + 126, + 124, + 126, + 0, {A} + 2, {B} + 4, {C} + 6, {D} + 8, {E} + 10, {F} + 12, {G} + 14, {H} + 16, {I} + 18, {J} + 20, {K} + 22, {L} + 24, {M} + 26, {N} + 28, {O} + 30, {P} + 32, {Q} + 34, {R} + 36, {S} + 38, {T} + 40, {U} + 42, {V} + 88, {W} + 90, {X} + 92, {Y} + 94 {Z} +); + diff --git a/dat/gfx2.ini b/dat/gfx2.ini new file mode 100644 index 00000000..ff02bc72 --- /dev/null +++ b/dat/gfx2.ini @@ -0,0 +1,289 @@ +###### GrafX2 initialization file ###### Fichier d'initialisation de GrafX2 ## +# # # # +# You may modify this file with any # Vous pouvez modifier ce fichier avec # +# standard ASCII text editor. # n'importe quel ‚diteur de texte # +# # ASCII standard. # +# # # +# Comments are preceded by ';' or # Les commentaires sont pr‚c‚d‚s par # +# '#'. # ';' ou '#'. # +# # # +# Options are not case sensitive and # Les options ne sont pas sensibles … # +# spaces are ignored. # la casse et les espaces sont ignor‚s.# +# # # +# You must not change the order of # Vous ne devez pas changer l'ordre # +# the sections and their options. # des sections et de leurs options. # +# You must not delete or put into # Vous ne devez pas effacer ou mettre # +# comment any section nor option. # en commentaire une section ou option.# +# # # +# Each option is preceded by a # Chaque option est pr‚c‚d‚e par un # +# comment which explains its meaning. # commentaire qui explique sa fonction.# +# # # +############################################################################## + + + +[MOUSE] # [SOURIS] + + ; The sensitivity of the mouse can ³ La sensibilit‚ de la souris peut + ; take values from 1 to 64. The ³ prendre des valeurs de 1 … 64. Plus + ; smaller values, the faster. ³ les valeurs sont petites, plus c'est + ; ³ rapide. + X_sensitivity = 3 ; (default 3) + Y_sensitivity = 3 ; (default 3) + + ; Due to the fact that those stupid ³ A cause du fait que ces imb‚ciles de + ; mouse drivers' makers don't care ³ programmeurs de gestionnaires de + ; if the mouse moves by steps of 2, ³ souris se fichent que votre souris se + ; 4 or even 8 pixels, we have to ³ deplace par pas de 2, 4 ou mˆme 8 + ; stretch the virtual area of the ³ pixels, nous devons ‚largir la zone + ; mouse and divide coordinates to ³ virtuelle de la souris et diviser les + ; get a one-pixel step motion. ³ coordonn‚es pour obtenir un pas de 1. + ; (Warning: the mouse movement can ³ (Attention: le d‚placement de la + ; be correct in some video modes ³ souris peut ˆtre correct dans certains + ; but not in others... But all the ³ modes vid‚os mais pas dans d'autres... + ; "Modes X" should behave the same ³ Mais tout les Modes X devraient se + ; way, so you won't have to test ³ comporter de la mˆme maniŠre, donc + ; them all). ³ vous n'aurez pas … tous les tester. + ; A correction factor of 0 means ³ Un facteur de correction de 0 signifie + ; that you are very lucky because ³ que vous avez de la chace car votre + ; your driver doesn't need any ³ driver n'a pas besoin de correction. + ; correction. If you set the ³ Si vous d‚finissez le facteur de + ; correction factor to 1, it means ³ correction … 1, cela signifie que + ; that your mouse moves by steps of ³ votre souris se d‚place par pas de 2 + ; 2 pixels; 2 for 4; 3 for 8, etc...³ pixels; 2 pour 4; 3 pour 8, etc... + ; If you want to use GrafX2 in a ³ Si vous d‚sirez lancer GrafX2 dans une + ; Win95 window, you should turn ³ fenˆtre Windows95, vous devriez passer + ; these values to 0 (and increase X ³ ces valeurs … 0 (et augmenter les sen- + ; and Y sensitivities above). ³ sibilit‚s X et Y d‚finies plus haut). + X_correction_factor = 3 ; (default 3) + Y_correction_factor = 3 ; (default 3) + + ; Aspect of the main cursor (cross) ³ Aspect du curseur principal (croix) + ; 1: Solid ³ 1: Solide + ; 2: Transparent ³ 2: Transparent + ; 3: Thin (solid) ³ 3: Fin (solide) + Cursor_aspect = 1 ; (default 1) + + + +[MENU] # [MENU] + + ; Colors of the menus (the black ³ Couleurs des menus (la couleur noire + ; and the white colors cannot be ³ et la couleur blanche ne peuvent pas + ; modified). ³ ˆtre modifi‚es). + ; Values are in {Red,Green,Blue} ³ Les valeurs sont dans l'ordre {Rouge, + ; order and are between 0 and 63. ³ Vert,Bleu} et vont de 0 … 63. + Light_color = 42,42,42 ; (default 42,42,42) + Dark_color = 27,27,27 ; (default 27,27,27) + ; + ; Light_color = 24,25,30 ; \_ Nightmare + ; Dark_color = 13,14,19 ; / + ; + ; Light_color = 10,45,28 ; \_ Forest + ; Dark_color = 5,27,12 ; / + ; + ; Light_color = 48,41,26 ; \_ Gold + ; Dark_color = 26,22,15 ; / + ; + ; Light_color = 10,40,55 ; \_ Oceanic + ; Dark_color = 10,20,32 ; / + + ; Aspect ratio and size of the ³ Proportion des menus et de la barre + ; menus and the tool-bar. ³ d'outils. + ; Possible values: ³ Valeurs possibles: + ; 0: Do not adapt (pixels are not ³ 0: Ne pas adapter (les pixels ne sont + ; stretched) ³ pas ‚tir‚s) + ; 1: Adapt the menus and the tool- ³ 1: Adapter les menus et la barre + ; bar according to the resolution³ d'outils suivant la r‚solution + ; 2: Slightly adapt the ratio of ³ 2: Adapter l‚gŠrement les proportions + ; the menus and tool-bar ³ des menus et de la barre d'outils + Menu_ratio = 1 ; (default 1) + + ; Font: ³ Police de caractŠres (fonte): + ; 1: Classic ³ 1: Classique + ; 2: Fun ³ 2: Fun + Font = 1 ; (default 1) + + + +[FILE_SELECTOR] # [SELECTEUR_DE_FICHIERS] + + ; Show special files and ³ Afficher les fichiers et r‚pertoires + ; directories (values are 'yes' or ³ sp‚ciaux (les valeurs sont 'yes' ou + ; 'no'). ³ 'no'). + Show_hidden_files = no ; (default 'no') + Show_hidden_directories = no ; (default 'no') + Show_system_directories = no ; (default 'no') + + ; Delay before displaying a preview ³ D‚lai avant d'afficher une preview + ; in file-selectors (in 18.2th of ³ dans les s‚lecteurs de fichiers (en + ; second). Possible values range ³ 18.2Šmes de seconde) Les valeurs + ; from 1 to 256. ³ possibles vont de 1 … 256. + Preview_delay = 8 ; (default 8) + + ; Maximize the preview of the ³ Maximiser la preview des images pour + ; pictures so that it is as big as ³ qu'elle soit aussi grande que + ; possible. If you're not in the ³ possible. + ; same resolution as the picture's ³ Si vous n'ˆtes pas dans la mˆme r‚so- + ; one, it can try to correct the ³ lution que celle de l'image, cela peut + ; aspect ratio, but if the picture ³ essayer de corriger les proportions, + ; does not fill the whole screen, ³ mais si l'image ne prend pas tout + ; it can be worse. ³ l'‚cran, cela peut ˆtre pire. + Maximize_preview = no ; (default 'no') + + ; This option is used to place the ³ Cette option est utilis‚e pour placer + ; selection bar on a filename by ³ la barre de s‚lection sur un nom de + ; typing its first letters. ³ fichier en tapant ses 1Šres lettres. + ; For example, if you want to find ³ Par exemple, si vous voulez trouver le + ; the "PICTURE.PKM" in a directory ³ fichier "PICTURE.PKM" dans un r‚per- + ; that also contains "PALETTE.PAL", ³ toire contenant ‚galement le fichier + ; you'll just have to type P and I. ³ "PALETTE.PAL", vous n'aurez qu'… taper + ; The different values of "FFF" ³ P puis I. + ; indicate if you want to find the ³ Les different valeurs de "FFF" + ; name in both files and directories³ indiquent si vous voulez trouvez le nom + ; or just in only one of these: ³ dans les fichiers ET les r‚pertoires ou + ; 0: files and directories ³ simplement dans l'un OU l'autre. + ; 1: files only ³ 0: fichiers et r‚pertoires + ; 2: directories only ³ 1: fichiers seulement + ; ³ 2: r‚pertoires seulement + Find_file_fast = 0 ; (default 0) + + +[LOADING] # [CHARGEMENT] + + ; Automatically set the resolution ³ Passer automatiquement dans la bonne + ; when loading a picture. ³ r‚solution lors du chargement d'une + ; You should set this value to ³ image. + ; 'yes' after disabling the video ³ Vous devriez d‚finir cette option … + ; modes that are not supported by ³ 'yes' aprŠs avoir inhib‚ les modes + ; your video card or monitor. ³ vid‚o qui ne sont pas support‚s par + ; ³ votre mat‚riel. + Auto_set_resolution = no ; (default 'no') + + ; If the variable above is set to ³ Si la variable ci-dessus est … 'yes', + ; 'yes', this one tells if you want ³ celle-ci indique si vous voulez + ; to set the resolution according ³ d‚finir la r‚solution suivant: + ; to: ³ 1: les dimensions de "l'‚cran + ; 1: the internal "original screen" ³ d'origine" internes … l'image + ; dimensions of the picture ³ 2: les v‚ritables dimensions de + ; 2: the actual dimensions of the ³ l'image + ; picture ³ + Set_resolution_according_to = 1 ; (default 1) + + ; If you load a picture with a ³ Si vous chargez une image ayant une + ; palette of less than 256 colors, ³ palette de moins de 256 couleurs, + ; this option defines if you want ³ cette option indique si vous souhaitez + ; to clear the palette or to keep ³ effacer la palette ou bien conserver + ; the colors of the previous ³ les couleurs de l'image pr‚c‚dente qui + ; picture that are over the number ³ se situent au-del… du nombre de la + ; of colors of the new picture. ³ nouvelle image. + ; For example, if you load a ³ Par exemple, si vous chargez une image + ; 32-color picture, the colors 32 ³ de 32 couleurs, les couleurs 32 … 255 + ; to 255 will be set to black if ³ seront pass‚es en noir si cette option + ; this option is set to 'yes', or ³ est … 'yes', ou bien elles resteront + ; they will be kept unchanged if ³ inchang‚es si elle est … 'no'. + ; this option is set to 'no'. ³ + Clear_palette = yes ; (default 'yes') + + +[MISCELLANEOUS] # [DIVERS] + + ; Draw the limits of the picture. ³ Afficher les limites de l'image + Draw_limits = yes ; (default 'yes') + + ; Adjust the brush grabbing in ³ Ajuster la capture de brosse en mode + ; "grid" mode. ³ "grille". + Adjust_brush_pick = yes ; (default 'yes') + + ; Coordinates: ³ Coordonn‚es: + ; 1: Relative ³ 1: Relatives + ; 2: Absolute ³ 2: Absolues + Coordinates = 1 ; (default 1) + + ; Create a backup file when saving. ³ Cr‚er un fichier backup lors des + ; ³ sauvegardes. + Backup = no ; (default 'no') + + ; Number of pages stored in memory ³ Nombre de pages stock‚es en m‚moire + ; for "undoing". ³ destin‚es … annuler les derniŠres + ; Values are between 1 and 99. ³ modifications. Valeurs entre 1 et 99. + Undo_pages = 1 ; (default 1) + + ; Speed of the scroll-bars (in VBLs ³ Vitesse des barre de d‚filement (en + ; waited) while clicking with the ³ VBLs attendus) lorsque l'un des + ; left or right button of the mouse.³ boutons de la souris est enfonc‚. + ; Values can be between 1 and 255. ³ Les valeurs sont comprises entre 1 et + ; The bigger values, the slower. ³ 255. Plus elles sont grandes, plus + ; ³ c'est lent. + Gauges_scrolling_speed_Left = 10 ; (default 10) + Gauges_scrolling_speed_Right = 3 ; (default 3) + + ; Automatically save the configu- ³ Enregistre automatiquement la configu- + ; ration when exiting the program. ³ ration lorsqu'on quitte le programme. + Auto_save = yes ; (default 'yes') + + ; Maximum number of vertices used ³ Nombre maximum de vertex utilis‚s dans + ; in filled polygons and polyforms, ³ les polyg“nes et polyformes pleins, et + ; and lasso. Possible values range ³ le lasso. Les valeurs possibles vont + ; from 2 to 16384. ³ de 2 … 16384. + ; Each vertex takes 4 bytes. ³ Chaque vertex prend 4 octets. + Vertices_per_polygon = 1024 ; (default 1024) + + ; Automatically zoom into the ³ Zoomer automatiquement la zone point‚e + ; pointed area when you press the ³ par la souris lorsque vous appuyez sur + ; short-key of the Magnifier button ³ la touche de raccourci de la loupe. + ; while being above the picture. ³ + Fast_zoom = yes ; (default 'yes') + + ; Separate the colors in the tool- ³ S‚parer les couleurs dans la barre + ; bar by a black squaring. ³ d'outils par un quadrillage noir. + Separate_colors = yes ; (default 'yes') + + ; Initial value of the feedback for ³ Valeur initiale du "feedback" pour les + ; the drawing modes (cf. docs). ³ modes de dessin (cf. docs). + FX_feedback = yes ; (default 'yes') + + ; When you reduce the palette or ³ Si vous r‚duisez la palette ou "zappez" + ; "zap" some colors out of it, it is³ quelques couleurs, il est possible + ; possible that there are not enough³ qu'il ne reste pas assez de couleurs + ; colors left to draw the menus. ³ pour afficher les menus. Mettre cette + ; Switching the following variable ³ variable … 'yes' ramŠnera automatiquent + ; on will bring back the colors of ³ les couleurs du menu s'il reste moins + ; the menu if there are less than 4 ³ de 4 couleurs aprŠs une "r‚duction" ou + ; colors left after "reducing" or ³ un "zapping". + ; "zapping". ³ + Safety_colors = yes ; (default 'yes') + + ; Display a message at startup ³ Afficher un message au d‚marrage + ; telling the version number of the ³ indiquant le num‚ro de version du + ; program. ³ programme. + Opening_message = yes ; (default 'yes') + + ; Take the Stencil into account when³ Prendre le Stencil en compte lorsqu'on + ; clearing the image. ³ efface l'image. + Clear_with_stencil = yes ; (default 'yes') + + ; Directly set the discontinuous ³ Passer automatiquement en mode de + ; freehand drawing mode after brush ³ dessin discontinu aprŠs la prise d'une + ; grabbing. ³ brosse. + Auto_discontinuous = no ; (default 'no') + + ; Save the screen dimensions in GIF ³ Sauver les dimensions de l'‚cran dans + ; files. If you want to read these ³ les fichiers GIF. Si vous voulez lire + ; files with Photoshop or Alchemy, ³ ces fichiers avec Photoshop ou Alchemy, + ; and maybe some other programs, you³ et peut-ˆtre d'autres programmes, vous + ; must set this option to 'no'. ³ devez mettre cette option … 'no'. + Save_screen_size_in_GIF = no ; (default 'no') + + ; Automaticaly count the number of ³ Compter automatiquement le nombre de + ; different colors used when opening³ couleurs diff‚rentes utilis‚es lors de + ; the palette editor window. (Set it³ d'ouverture de la fenˆtre d'‚dition de + ; to 'no' if you have a slow PC or ³ la palette. (Mettez-le … 'no' si vous + ; if you edit huge pictures) ³ avez un PC lent ou bien si vous ‚ditez + ; ³ d'‚normes images). + Auto_nb_colors_used = yes ; (default 'yes') + + ; Number of the default video mode ³ Num‚ro du mode vid‚o par d‚faut au + ; at startup (see the list by typing³ d‚marrage (voir la liste en tapant + ; "gfx2 /?" at the DOS prompt). ³ "gfx2 /?" sur la ligne de commande). + Default_video_mode = 0 ; (default 0) diff --git a/divers.c b/divers.c new file mode 100644 index 00000000..b64d625b --- /dev/null +++ b/divers.c @@ -0,0 +1,93 @@ +#include + +#include "struct.h" +#include "sdlscreen.h" +#include "global.h" + +word Palette_Compter_nb_couleurs_utilisees(dword* Tableau) +{ + int Nombre_De_Pixels=0; //ECX + Uint8* Pixel_Courant=Ecran; //ESI + Uint8 Couleur; //AL/EAX + word Nombre_Couleurs=0; + int i; + + + + //Calcul du nombre de pixels dans l'image + Nombre_De_Pixels=Principal_Hauteur_image*Principal_Largeur_image; + + // On parcourt l'‚cran courant pour compter les utilisations des couleurs + for(i=0;i++;i>Nombre_De_Pixels) + { + Couleur=*Pixel_Courant; //on lit la couleur dans l'écran + + Tableau[Couleur]++; //Un point de plus pour cette couleur + + // On passe au pixel suivant + Pixel_Courant++; + } + + //On va maintenant compter dans la table les couleurs utilis‚es: + + Couleur=0; //EDX + + do + { + if (Tableau[Couleur]!=0) + Nombre_Couleurs++; + + Couleur++; + + }while (Couleur<256); + + return Nombre_Couleurs; +} + +void Set_palette(T_Palette Palette) +{ + SDL_SetPalette(Ecran, SDL_LOGPAL|SDL_PHYSPAL, Palette, 0, 256); +} + +void Attendre_fin_de_click(void) +{ + do + SDL_PumpEvents(); + while (SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(0)); +} + +void Effacer_image_courante_Stencil(byte Couleur, byte * Pochoir) +//Effacer l'image courante avec une certaine couleur en mode Stencil +{ + int Nombre_De_Pixels=0; //ECX + //al=Couleur + //edi=Ecran + Uint8* Pixel_Courant=Ecran; //dl + int i; + + Nombre_De_Pixels=Principal_Hauteur_image*Principal_Largeur_image; + + for(i=0;i++;i0 = … droite, Ellipse_Curseur_X<0 = … gauche) et … +// Ellipse_Curseur_Y pixels (Ellipse_Curseur_Y>0 = en bas, +// Ellipse_Curseur_Y<0 = en haut) du centre se trouve dans l'ellipse en +// cours. + +byte Pixel_dans_cercle(void); +// Indique si le pixel se trouvant … Cercle_Curseur_X pixels +// (Cercle_Curseur_X>0 = … droite, Cercle_Curseur_X<0 = … gauche) et … +// Cercle_Curseur_Y pixels (Cercle_Curseur_Y>0 = en bas, +// Cercle_Curseur_Y<0 = en haut) du centre se trouve dans le cercle en +// cours. + +byte Bit(byte Octet, byte Rang); +// Extrait un bit d'un certain rang … partir d'un octet. + +byte Couleur_ILBM_line(word Pos_X, word Vraie_taille_ligne); +// Renvoie la couleur du pixel (ILBM) en Pos_X. + +// Gestion du chrono dans les fileselects +void Initialiser_chrono(long Delai); +void Tester_chrono(void); + +void Remplacer_une_couleur(byte Ancienne_couleur, byte Nouvelle_couleur); +void Remplacer_toutes_les_couleurs_dans_limites(byte * Table_de_remplacement); + +byte Meilleure_couleur(byte Rouge,byte Vert,byte Bleu); +byte Meilleure_couleur_sans_exclusion(byte Rouge,byte Vert,byte Bleu); + +byte Effet_Colorize_interpole (word X,word Y,byte Couleur); +byte Effet_Colorize_additif (word X,word Y,byte Couleur); +byte Effet_Colorize_soustractif(word X,word Y,byte Couleur); +byte Effet_Trame(word X,word Y); + +void Flip_Y_LOWLEVEL(void); +void Flip_X_LOWLEVEL(void); +void Rotate_90_deg_LOWLEVEL(byte * Source,byte * Destination); +void Rotate_180_deg_LOWLEVEL(void); +void Zoomer_une_ligne(byte * Ligne_originale,byte * Ligne_zoomee,word Facteur,word Largeur); +void Copier_une_partie_d_image_dans_une_autre(byte * Source,word S_Pos_X,word S_Pos_Y,word Largeur,word Hauteur,word Largeur_source,byte * Destination,word D_Pos_X,word D_Pos_Y,word Largeur_destination); diff --git a/doc/Le moteur des opérations.html b/doc/Le moteur des opérations.html new file mode 100644 index 00000000..95b43913 --- /dev/null +++ b/doc/Le moteur des opérations.html @@ -0,0 +1,384 @@ + + + + + + + +GrafX2 - Le moteur des opérations + + + + +

GrafX2 - Le moteur des opérations

+ +
+ +

Explication du principe :

+ +

Qu'appelle-t'on une opération? C'est l'emploi d'un outil de +dessin. Par exemple, le tracé libre à la main d'un pinceau (ou +d'une brosse) est une opération. Plus exactement, c'est tout +comportement de la souris lorsqu'elle se trouve sur les pixels de +l'image éditée. De ce fait, la gestion de la pipette se fait +également au travers des opérations.

+ +

Le moteur chargé de gérer ces opérations est simplifié +autant que possible. Son principe est le suivant : lorsque +la souris est au-dessus de l'image, la boucle principale de +gestion de GrafX2 (située dans MOTEUR.C) détermine la partie +atomique d'instructions à exécuter, puis l'exécute, pour +chaque combinaison d'un type d'opération (un entier, que l'on +nommera pour les besoins de cette page ID_OP), d'un état de la +souris (état de ses boutons plus exactement, codé sur un entier +également), et d'un nombre de valeurs présentes dans une pile +(pas la pile système, mais une pile de mots 16-bits +spécialement mise en place pour les opérations, afin qu'elles y +stockent des paramètres pour les opérations suivantes). On +appelle "partie atomique" une séquence d'instructions +qui doivent être exécutées intégralement à chaque itération +de la boucle principale. Elle se contente de ne faire que ce +qu'elle doit faire face à la situation qu'implique la +combinaison (ID_OP,Code souris, Etat pile) pour laquelle elle est +appelée.

+ +

En fait, le moteur doit être aidé pour déterminer les +insctructions à exécuter. Chacune de ces parties atomiques est +écrite sous la forme d'une fonction contenant tout le code qui +lui est nécessaire. Ces fonctions sont ce que l'on a appelé des +"fonction_action" (définition dans STRUCT.H), c'est à +dire une simple fonction qui ne reçoit pas de paramètres et qui +n'en renvoie pas. Un simple void Ma_fonction(void)...

+ +

Il n'est pas dans mon intention de vous apprendre à écrire +ces fonctions atomiques. Dans le cas des opérations les plus +simples à implémenter selon ce principe, la conception des +parties atomiques est assez intuitive, mais il arrive dans +certains cas que la méthode trouve certaines limites, il faut +alors tricher un peu (mais gentiment! - en plaçant des valeurs +arbitraires dans la pile uniquement pour permettre la transition +vers une autre combinaison choisie, donc une autre partie +atomique, par exemple). Vous pourrez trouver tous les exemples +que vous voudrez dans le fichier OPERATIO.C.

+ +

Après avoir écrit les parties atomiques qui vont être +nécessaires pour la gestion complète d'une opération (dans le +fichier OPERATIO.C), et avoir renseigné les prototypes de ces +fonctions (dans OPERATIO.H), il faut indiquer au moteur dans +quelles conditions utiliser ces fonctions. Cela se fait dans la +phase d'initialisation du programme (située dans le fichier +INIT.C), où l'on renseigne chacune des fonctions atomiques, en +décrivant les valeurs de combinaison qui doivent déclencher +leur appel. La fonction appelée se contente d'en prendre note en +remplissant un tableau nommé "Operation" (variable +globale déclarée dans GLOBAL.H, et indexée par les 3 valeurs +de la combinaison : ID_OP, code souris, état pile) à l'aide de +l'adresse de la fonction à appeler. Ce tableau va servir au +moteur à faire un appel direct de la fonction atomique d'après +la combinaison, sans avoir à faire toute une série de tests +(swich/case) fastidieux.

+ +

Comme nous avons pressenti qu'il arriverait fréquemment que +des fonctions atomiques auraient besoin systématiquement +d'effacer la souris pour faire des affichages à l'écran ou dans +l'image, et de la rafficher ensuite, et dans le souci d'éviter +de faire abusivement du copier/coller de code, nous avons +rajouté un booléen dans le tableau Operation qui permet +d'indiquer que la fonction atomique demande au moteur de se +charger lui-même de l'effacement et de la restauration du +curseur de la souris à l'écran. Finalement, je ne suis pas +certain que cela s'est révelé d'une grande utilité, mais je +vous le signale tout de même pour que vous compreniez +l'existance du paramètre "Effacer souris" qu'il faut +indiquer lorsqu'on renseigne une fonction atomique lors de +l'initialisation.

+ +

Il est important de noter qu'une fonction atomique est +appelée en permanence par la boucle principale, indépendamment +du fait que la souris change d'état ou non. Ces appels +répétés permettent par exemple d'avoir un spray qui continue +à agir lorsqu'on presse le bouton de la souris sans la +déplacer.

+ +

De plus, les fonctions atomiques n'ont pas à se soucier du +positionnement de la souris car dès que la pile contient des +données (généralement dès le premier clic), la souris est +limitée par le moteur afin de ne pas sortir de l'image. Le +moteur s'assure également que la souris ne franchis pas la barre +de split en mode "loupe". Enfin, n'oubliez pas de vider +complètement la pile en temps voulu, lorsque l'opération peut +s'achever! ;-)

+ +
+ +

Informations pour l'implémentation :

+ +
    +
  • Le renseignement d'une fonction atomique se fait dans + INIT.C à l'aide de :
  • +
+ +
+

Initialisation_operation(ID_OP, Etat souris, Taille pile, + Callback, Effacer souris);

+
+ +
    +
  • La pile à disposition des opérations pour le stockage + des paramètres :
      +
    • Elle contient des mots 16-bits (type word, + définit dans STRUCT.H)
    • +
    • Pour y poser une valeur : + Operation_PUSH(val)
    • +
    • Pour en retirer une valeur : + Operation_POP(&var)
    • +
    • Exemples de valeurs à y mettre : + coordonnées de souris, de pinceau... des + couleurs... des valeurs bidons pour changer + l'état de la pile...
      +
    • +
    +
  • +
  • A l'intérieur d'une fonction atomique :
      +
    • Si la fonction correspond à la première étape + d'une opération, appeler + Initialiser_debut_operation()
    • +
    • Si la fonction correspond à la première étape + d'une opération qui peut modifier l'image, + appeler Backup() avant modification de l'image ; + ce qui permettra à l'utilisateur d'annuler la + modification avec "undo" s'il le + souhaite.
    • +
    • Pour afficher les coordonnées de la souris, + appeler Print_coordonnees() sans vous soucier de + savoir si la barre d'outils est visible. Si vous + avez besoin d'afficher une coordonnée qui doit + s'adapter au mode relatif ou absolu (selon le + paramétrage effectué par l'utilisateur), + utilisez Aff_coords_rel_ou_abs(RefX,RefY). Si les + coordonnées sont configurées pour être + relatives, cette fonction affichera la + différence entre les coordonnées actuelles du + pinceau et les coordonnées de référence + passées en paramètres. Dans le cas d'infos + spéciales à afficher dans la barre de menu, on + pourra se servir de la fonction + Print_dans_menu(texte,position en caractères).
    • +
    • Si vous avez besoin de vous assurer que les + boutons de la souris sont relâchés à un moment + de la fonction, utilisez Attendre_fin_de_click()
    • +
    • Etudiez OPERATIO.C pour avoir des exemples.
      +
    • +
    +
  • +
  • Pour démarrer une opération (après avoir cliqué sur + un bouton de la barre d'outils par exemple), appeler + Demarrer_pile_operation(ID_OP). Note: il faut que le + curseur soit caché avant l'appel (et son état n'est pas + changé après). (voir exemples dans BOUTONS.C)
    +
  • +
  • On peut connaître l'ID_OP de l'opération en cours + grâce à la variable globale Operation_en_cours
    +
  • +
  • La variable globale Operation_Taille_pile correspond à + la taille de la pile d'opérations. Elle peut être + consultée et éventuellement modifiée (même s'il est + préférable d'utiliser Operation_PUSH et Operation_POP + dans ce dernier cas).
  • +
+ +
+ +

Comment rajouter une opération?

+
+ + + + + + + + + + + + + + + + + +
Dans CONST.H :
    +
  • rajouter un identifiant (ID_OP) dans l'enum + OPERATIONS (exemple : OPERATION_DUMMY)
  • +
+
Dans GLOBAL.H :
    +
  • rajouter l'identifiant de la forme de curseur à + utiliser pour cette opération dans la table + CURSEUR_D_OPERATION[]. Faites bien attention à + l'insérer au bon endroit (place correspondant à + ID_OP).
  • +
+
Dans OPERATIO.C :
    +
  • Ecrire chaque fonction atomique de l'opération.
  • +
+
+

Exemple :

+
+
+
+

void Dummy_1_0(void)
+ // Opération : OPERATION_DUMMY
+ // Click Souris: 1
+ // Taille_Pile : 0
+ // Souris effacée: Oui (précisé grâce à + Initialiser_operation() dans INIT.C)
+ {
+      Initialiser_debut_operation();
+      Backup();
+
+      // ACTIONS...
+
+      Operation_PUSH(une_valeur_nécessaire_pour_les_prochaines_étapes);
+      Operation_PUSH(une_autre_valeur_nécessaire_plus_tard);
+ }

+
+
+
+
+

(Pour cet exemple, l'étape suivante à + définir sera donc une étape avec la taille de + pile à 2)

+
+
+
    +
  • Il y a une action par défaut qui se contente + d'afficher les coordonnées de la souris + lorsqu'on ne définit pas explicitement de + fonction atomique gérant une certaine + combinaison (ID_OP, Etat souris, Taille pile).
  • +
  • Si l'opération représente une interruption + temporaire, et qu'il vous paraît juste de + restaurer l'opération précédente une fois + qu'elle est terminée (cas de la loupe, de la + pipette, des prises de brosse, ...), rajouter + l'ID_OP dans la section correspondante de la + fonction Demarrer_pile_operation(), en début de + fichier.
  • +
  • Si l'opération voit un intérêt à accepter que + l'utilisateur change de couleur de pinceau en + cours d'opération (cas du dessin continu, + discontinu, le spray, et les lignes centrées), + rajouter l'ID_OP dans la section correspondante + de la fonction Demarrer_pile_operation(), en + début de fichier.
  • +
+
Dans OPERATIO.H :
    +
  • Ecrire le prototype des ces fonctions atomiques.
  • +
+
Dans INIT.C :
    +
  • Dans Initialisation_des_operations(), pour chaque + fonction atomique de l'opération, écrire un + appel à Initialiser_operation(ID_OP, Etat + souris, Taille pile, Callback, Effacer souris);
      +
    • ID_OP : identifiant de l'opération + dont dépend la fonction atomique + (défini dans CONST.H)
    • +
    • Etat souris :
        +
      • 0 = boutons relachés
      • +
      • 1 = bouton gauche enfoncé
      • +
      • 2 = bouton droit enfoncé
      • +
      • (note : l'état "boutons + gauche et droit enfoncés" + n'existe pas, seuls les 3 états + ci-dessus sont autorisés)
      • +
      +
    • +
    • Taille pile : nombre de paramètres + dans la pile
    • +
    • Callback : nom de la fonction + atomique à appeler pour la combinaison + des 3 paramètres précédents
    • +
    • Effacer souris : booléen indiquant + que le moteur se chargera d'effacer le + curseur souris avant l'appel à la + fonction atomique, et de le rafficher + après sa sortie.
    • +
    +
  • +
+
+

Exemple :

+
+
+
+

Initialiser_operation(OPERATION_DUMMY, 1, 0, + Dummy_1_0, 1);

+
+
+
+
+ + + + + diff --git a/doc/Les entrées.html b/doc/Les entrées.html new file mode 100644 index 00000000..d01ee1ba --- /dev/null +++ b/doc/Les entrées.html @@ -0,0 +1,176 @@ + + + + + + + +GrafX2 - Les entrées + + + + +

GrafX2 - Les entrées

+ +
+ +

Get_input() (dans DIVERS.ASM):

+ +
    +
  • Touches :
      +
    • Met à jour la variable "Touche", un + mot 16-bits qui contient dans sa partie basse la + valeur du scan-code (valeur plutôt liée à la + géographie de la touche) de la touche enfoncée + à traiter, et dans sa partie haute un codage des + touches de contrôles enfoncées au moment de + l'appel.
        +
      • (Touche & 0x0100) => Shift
      • +
      • (Touche & 0x0200) => Control
      • +
      • (Touche & 0x0400) => Alt
      • +
      +
    • +
    • Met dans la variable "Touche_ASCII" la + valeur ASCII (valeur liée au caractère que + représente la touche) de la touche enfoncée à + traiter.
    • +
    • Dans le cas où la variable globale + "Autoriser_changement_de_couleur_pendant_operation" + serait à 0, et qu'il existerait au moins une + valeur dans la pile des opérations, la fonction + filtre les touches. Cela signifie que l'on ne + peut pas interrompre une opération en cours, + sauf pour changer la couleur du pinceau si + l'opération l'autorise (utile pour faire varier + la couleur du pinceau à l'aide des touches + pendant qu'on dessine).
    • +
    +
  • +
  • Souris :
      +
    • Met à jour la position (Mouse_X,Mouse_Y) de la + souris en fonction de sa position dans un écran + virtuel. Cet écran est volontairement plus grand + que la résolution réelle du mode vidéo car de + nombreux drivers ne fournissent pas la position + de la souris au pixel près...
    • +
    • Met à jour l'état des boutons de la souris + (Mouse_K). La variable vaut 0 si aucun bouton + n'est enfoncé, 1 si seul le bouton gauche est + enfoncé, et 2 si seul le bouton droit est + enfoncé. Dans le cas où les 2 boutons seraient + enfoncé, Get_input() considère qu'aucun bouton + n'est enfoncé (Mouse_K = 0).
    • +
    • La fonction corrige la position de la souris afin + de l'empêcher de sortir de la surface d'image + sur laquelle elle se trouve si au moins une + valeur est dans la pile des opérations (la + souris ne sort pas de la zone de dessin tant que + l'opération de dessin n'est pas terminée), et + elle simule également le déplacement et les + clics de la souris si la combinaison de touches + courante correspond à de telles commandes. Dans + ce dernier cas, la touche est ensuite filtrée + afin d'éviter de faire travailler la fonction + appelante pour rien.
    • +
    • Dans le cas où la souris change d'état ou que + la variable globale + "Forcer_affichage_curseur" est placée + à 1, le curseur de la souris est réaffiché. La + fonction laisse toujours la variable + Forcer_affichage_curseur à 0 en fin d'appel.
    • +
    • La fonction fait appel à + Calculer_coordonnees_pinceau() qui se charge de + calculer convenablement les coordonnées du + pinceau (Pinceau_X,Pinceau_Y) en fonction de la + position de la souris à l'écran, de la position + de la zone de dessin dans l'image, du facteur de + zoom et de l'effet de la grille.
    • +
    +

    Important : Dans la plupart des cas, + vous n'avez pas à appeler cette fonction car le moteur + (boucle principale, gestionnaire de fenêtre, sélecteurs + de fichier, ...) s'en est déjà chargé. Vous pouvez + donc considérer que les variables concernées sont + déjà à jour. Si vous appeliez vous-même la fonction + Get_input() à un moment inoportun, certaines commandes + de l'utilisateur, prises en compte par le moteur, ne + seraient pas traitées.

    +
  • +
+ +

Attendre_fin_de_click() (dans DIVERS.ASM):

+ +
+

S'il vous arrive d'avoir besoin de vous assurer que + l'utilisateur n'appuie plus sur les boutons de la souris à + un instant donné, cette fonction attend jusqu'à ce que + l'utilisateur relache le bouton. La valeur de Mouse_K vaut + alors 0, mais s'il a déplacé la souris avant de suspendre + sa pression, la position (Mouse_X,Mouse_Y) n'est pas encore + à jour. Cependant, cela ne devrait pas être génant (au + pire, un appel à Get_input() mettra ces valeurs à jour).

+
+ + + + + diff --git a/doc_eng.txt b/doc_eng.txt new file mode 100644 index 00000000..4e7afbe0 --- /dev/null +++ b/doc_eng.txt @@ -0,0 +1,1983 @@ + ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + ³ ÜÜÜÜ ÜÜÜÜ ÜÜÜ ÜÜÜÜÜ Ü Ü ÜÜÜÜ ³ + ³ Û Û Û Û Û Û ßÜ Üß Û ³ + ³ Û ÜÜ ÛÜÜÜß ÛÜÜÜÛ ÛÜÜ ßÜß Üßß ³ + ³ Û Û Û ßÜ Û Û Û Û Û Û .00 ³ + ³ ßÜÜÜÛ Û Û Û Û Û Û Û ÛÜÜÜÜ ³ + ³ ³ + ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + + + GRAFX 2.00 á96.5% + + - USER'S MANUAL - + + + ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + ³ CONTENTS ³ + ³ ÍÍÍÍÍÍÍÍ ³ + ³ ³ + ³ - Presentation ³ + ³ - Required equipment ³ + ³ - Configuration files ³ + ³ - Available options ³ + ³ - Let's talk about $$$, baby ³ + ³ - Drawing tips ³ + ³ - Trouble-shooting/General hints/FAQ ³ + ³ ³ + ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + + + + +Presentation: +ÍÍÍÍÍÍÍÍÍÍÍÍÍ + + This program is designed for drawing 256-color pictures in a huge range of + resolutions (actually, there are 60 with some coming from the Amiga world). + No one can contest that most of the beautiful GFX of the Scene were drawn + on Amiga. But these GFX are in video resolutions that aren't the common PC + modes. So we wanted to make the first paint program on PC that could + visualize those pictures, and that could allow you, of course, to draw yours + in the video mode that you want. + + This program was first shown at the Wired'96 where it met a big success + (bigger than all our expects) so we hope you'll like it too. + + It's made up of many drawing tools, effects and menus. All the effects + will work with any drawing tool. + + This software has been created for YOU, PC users who envy Amiga owners + for their fantastic paint programs. This software doesn't pretend to replace + the best programs on Amiga, but it modestly tries to fill the gap between PC + and Amiga in the field of bitmap drawing. + If you dream about a very useful option we haven't thought of yet, do not + hesitate to tell us. If we also think it can be useful, and above all if it + is possible to include it in the program :), then we'll implement it as soon + as possible. + + + + +Required equipment: +ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ + + To run GrafX2, you'll need: + + - a PC (386DX or higher), + - DOS 5 or higher (maybe it works with DOS 3.1 but we don't remember which + functions of the INT 21h we use), + - a VGA compatible video card (a VLB or PCI card is strongly recommended) + - a mouse (and its driver), + - 3 Megabytes of RAM (can work with less if you use the DOS4GW or Windows + disk-cache). + + But if you want to use it more efficiently, you'll need: + + - at least a 486DXý66 (to improve global speed), + - at least 8 Mb of RAM for grabbing very big brushes and to use multi-undo, + - a VESA 1.2 (or later) compatible video card (to access more video modes). + + + + +Configuration files: +ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ + + GrafX2 needs two files to store its configuration: 'GFX2.INI' and + 'GFX2.CFG'. + + GFX2.INI: + ÄÄÄÄÄÄÄÄÄ + + This file contains the parameters defined in the settings menu and some + others. You may edit this file with any standard ASCII editor. + When you click on Reload in the settings menu, all the data contained in + this file are restored. When you click on Save or when you quit the + program with the Auto-save option on, all the current parameters are + written into (updated in) this file. + + If you corrupted this file and don't manage to fix the problem, then + delete it and run GFXCFG.EXE. It will automatically create a default + initialization file when it is absent. + + + GFX2.CFG: + ÄÄÄÄÄÄÄÄÄ + + This file contains the keyboard configuration plus the state of the + following variables in the program: + þ video modes + þ shade tables + þ stencil + þ mask + þ gradients + + All these variables are saved when clicking on the Save button in the + settings menu or when exiting the program with the Auto-save option on. + However, when you click on Reload in the settings menu, only the state + of each video mode is restored. + + Note: the GFX2_FRA.CFG file is a default configuration file for AZERTY + keyboards. If you have got an AZERTY keyboard, you may replace the + GFX2.CFG file by GFX2_FRA.CFG. + + Important: from version 2.00 á95.5%, .CFG files will have ascending + compatibility. This means that you'll be able to retrieve most of their + contents from a release to another by copying your old .CFG file into + your new GrafX2 directory and running GFXCFG.EXE. Indeed, this program + will convert your old file for it is usable by the new version of GrafX2. + But copying a .CFG file from an earlier version than version 95.5% won't + work. Moreover, (I don't see why you would do that, but...) copying a + recent .CFG file to an older version shouldn't work neither. + + + Note: We highly recommand not to modify the keys related to the mouse + emulation in the GFXCFG program because the values you could use may inter- + fere with the keyboard shortcuts used in the menus. + + + + +Available options: +ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ + + The different options available in GrafX2 will be listed and detailed + below. They will be described as follows: + + ÉÍÍÍÍËÍÍÍÍËÍúúúÍ» ÉÍÍÍÍ» + º 1 º 3 º º triangular buttons will º1 / º + º º º º be detailed like this: º / 2º + ÌÍÍÍÍÎÍÍÍÍÎÍúúú͹ ÈÍÍÍͼ + º 2 º 4 º º + º º º º + ÈÍÍÍÍÊÍÍÍÍÊÍúúúͼ + + + 1 - Paintbrushes + 2 - Adjust picture / Effects on the picture + 3 - Hand-drawing + 4 - Splines + 5 - Lines + 6 - Spray + 7 - Floodfill + 8 - Polygons / Polyforms + 9 - Polyfills / Filled polyforms + 10 - Empty rectangles + 11 - Filled rectangles + 12 - Empty circles/ellipses + 13 - Filled circles/ellipses + 14 - Rectangles with gradation + 15 - Gradation menu + 16 - Spheres / Ellipses with gradation + 17 - Brush grabbing / restore + 18 - Polyformed brush grabbing (lasso) / restore + 19 - Brush effects + 20 - Drawing modes + 21 - Text + 22 - Magnifier mode / Menu + 23 - Pipette / Invert colors + 24 - Screen size / Safety resolution + 25 - Spare page / Copy current to spare + 26 - Save picture / Autosave + 27 - Load picture / Reload + 28 - Settings + 29 - Clear picture + 30 - Help / Statistics + 31 - Oops (Undo/Redo) + 32 - Kill current page + 33 - Quit program + 34 - Palette menu + 35 - Scroll palette left / right + 36 - Palette window + 37 - Hide menu + + + + When you will use any drawing tool, left-clicking will draw with the Fore + color while right-clicking will draw with the Back-color. + + When dialog boxes or windows will come on the screen, Cancel (or No) will + always be emulated by the key, and OK (or Yes) by the key. + + In the different menus, the titles of the buttons that contain an under- + lined letter can be emulated by pressing this letter on the keyboard. + + In some menus, you can select a color range in the palette. This means + that you can click on a color and move the mouse to another by maintaining + the button pressed to select a color range. + + + + 1 - Paintbrushes: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Displays a menu where you can choose the shape of your paintbrush. + + Paintbrushes are sorted by family. You can see some paintbrushes of + the same family but with different sizes. There is at least one paint- + brush from each family displayed in this menu. + Here is the list of all the different paintbrush families: + + ÛÛÛÛÛÛÛ ÛÛÛ Û Û Û Û Û Û Û Û + ÛÛÛÛÛÛÛ ÛÛÛÛÛ Û Û Û Û Û Û ÛÛÛ Û Û + ÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛ Û Û Û Û Û Û Û Û ÛÛÛÛÛ Û + ÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛ Û Û Û Û Û Û ÛÛÛÛÛÛÛ + ÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛ Û Û Û Û Û Û Û Û ÛÛÛÛÛ Û Û Û + ÛÛÛÛÛÛÛ ÛÛÛÛÛ Û Û Û Û Û Û ÛÛÛ + ÛÛÛÛÛÛÛ ÛÛÛ Û Û Û Û Û Û Û Û Û + + Square Disc Sieve Sieve Diamond Random + square disc shaped + ______________________________________________________________ + + Û Û Û Û Û Û + Û Û Û Û Û Û + Û Û Û Û Û Û + ÛÛÛÛÛÛÛ Û Û Û Û ÛÛÛÛÛÛÛ + Û Û Û Û Û Û + Û Û Û Û Û Û + Û Û Û Û Û Û + + Horiz. Vertical Slash Back- Cross X Cross + + bar bar slash + + The 3 last paintbrushes in the menu belong to the "miscellaneous" + family and their size cannot be modified. + + + Right click: + ============> + + Transforms your current user-defined brush into a paintbrush. This is + actually a "monochromisation" of your user-defined brush. This means + that every color of the brush that aren't the Back-color will be set to + the Fore-color. But this option doesn't alter the brush: you'll just + have to right-click on the "Get brush" buttons to get your brush back. + + + Note: When you press (not in the menu) the key (default value), + the current paintbrush becomes the smallest member of the "Disc" family: + i.e one pixel. + + + + 2 - Adjust picture / Effects on the picture: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Allows you to scroll the picture to re-center your graph for example. + + Any part of the picture that goes out of the image by a side comes + back by the opposite one. + + It is assimilated to the drawing tools family. + + + Right click: + ============> + + *** Not implemented yet *** + + + + 3 - Hand-drawing: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Selects the current hand-drawing mode as the active drawing tool. + There are 3 hand-drawing modes: + + - Continuous hand-drawing: as you move the mouse, the paintbrush is + regularily pasted on the picture. This drawing tool allows to change + the fore and back colors when being in use. + + - Discontinuous hand-drawing: as you move the mouse, the paintbrush is + pasted on the picture every time a delay is passed (actually, the + delay is 1 VBL (vertical blanking)). This drawing tool allows to + change the fore and back colors when being in use. + + - Dot by dot hand-drawing: the paintbrush is only pasted at the + position where you first clicked. + + + Right click: + ============> + + Toggles the different hand-drawing modes and activates, at the same + time, the hand-drawing tool. + + + + 4 - Splines: + ÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Selects the current curve-drawing mode as the active drawing tool. + There are 2 different curve-drawing modes: + + - 4 control points curves: define the basic line like a classical + line, then move, with the left mouse button, the inner control + points to choose the shape of your curve. When the curve has the + shape you want, click with the right mouse button to draw it + definitively. + + - 3 control points curves: the same as above, but you'll have only one + inner control point to place. Moreover, the spline will be traced + just after placing this point. + + + Right click: + ============> + + Toggles the different curve-drawing modes and activates, at the same + time, the curve-drawing tool. + + + + 5 - Lines: + ÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Selects the current line-drawing mode as the active drawing tool. + There are 3 line-drawing modes: + + - Classical lines: when first clicking on the picture, you'll define + the start of the line. Maintain your click to choose the end of the + line and release the mouse button to set it. + + - Knotted lines: works like classical lines, but the end of your line + will automatically become the start of the next one. When you want + to stop chaining lines, use the opposite mouse button. "The opposite + button" means that if you started to draw lignes with the left + button (Fore-color), you'll have to stop the procedure with the + right button; and conversely. + + - Concentric lines: when first clicking on the picture, you'll define + the center of the lines. In fact, the center is defined by the + position of the mouse when you release the mouse button. Then you + can draw lines from the center to the current mouse position by + clicking. To stop drawing concentric lines, use the opposite mouse + button. This drawing tool allows to change the fore and back colors + when being in use. + + + Right click: + ============> + + Toggles the different line-drawing modes and activates, at the same + time, the line-drawing tool. + + + + 6 - Spray: + ÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Selects the spray as the active drawing tool. This drawing tool allows + to change the fore and back colors when being in use. + + + Right click: + ============> + + Displays a menu where you can configure the spray: + + - Size: Defines the diameter of the circle in which will effectively + fit the spray. + + - Delay: Defines the number of VBLs that will be waited for between + two flows of spray. + + - Mode: Defines whether you want to use a monochrome spray or a multi- + colored one. + + - Mono-flow: Defines the number of paintbrushes that will be pasted in + the circle of the spray at each cycle. + + - Palette: Left-click on a color of the palette to see how much it + will be used in the multicolored flow, and modify it by using the + gauge on the right. If the flow of this color was equal to 0, then + the "Init" value will be applied. Or set the flow of a color to 0 by + clicking on it with the right mouse button. + + - Clear: Removes all the colors from the multicolored flow. + Actually, this puts a 0 value in the use of each color. + + - Init: Allows you to define a value that will be set to the color you + click on in the palette if its value is equal to 0. This permits to + tag a set of colors more quickly. + + - +1,-1,x2,ö2: Modify the values of all the tagged colors (and only + them). + + + Tip: If you often use the Shade mode, and are bored to click many + times on a color to reach the color you want, you can define a + spray with "Size"=1, "Mono-flow"=1, and "Delay"=2 (or more, + according to your reflexes). And then, you'll just have to click + a few hundredths of second to modify a color. + + + + 7 - Floodfill: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Selects the filler as the active drawing tool. The filler, as any + drawing tool, will be affected by all the effects! + + Note that only the visible part of the picture will be filled (as + every other drawing tools, the floodfill only alters the visible part of + the picture; this avoids unwanted effects that wouldn't be controlled by + the user). + + + Right click: + ============> + + Selects the color replacement as the active drawing tool. + + Any rule has its exceptions and this one doesn't depart from that. + Indeed, this tool is the only one to be affected by no effect (except + Stencil) and to be able to modify non visible parts of the picture. + The function of this tool being replacing all the occurences of a + color in the picture by another, if would have been a shame to limit + modifications only to the visible part of the picture. + + + + 8 - Polygons / Polyforms: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Selects the polygons as the active drawing tool. + + This works just like knotted-lines but loops the extremities when + you're finished. + + + Right click: + ============> + + Selects the polyforms as the active drawing tool. + + This works like a combination of free-hand drawing and knotted-lines. + If you keep the mouse button pressed, you'll draw as if you were in + free-hand drawing mode. And, if you release the mouse button, it will + work like knotted lines. + + Click on the opposite mouse button (i.e.: click right if you started + to draw with the left mouse button, and vice versa) to terminate the + operation. The two extremities will be linked automatically. + + + + 9 - Polyfills / Filled polyforms: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Work exactly the same way as the polygons et polyforms above, but fill + in the interior of the drawn shapes. + + + + 10 - Empty rectangles: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Any click: + ==========> + + Selects the empty rectangles as the active drawing tool. + + Set a corner of a rectangle. Maintain the click to move the opposite + corner and release the mouse button to set it definitively. + + + + 11 - Filled rectangles: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Any click: + ==========> + + Selects the filled rectangles as the active drawing tool. + + Works like an empty rectangle. + + + + 12 - Empty circles/ellipses: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Selects the empty circles as the active drawing tool. + + Position the center of the cercle and maintain the mouse button to + select its radius. + + + Right click: + ============> + + Selects the empty ellipses as the active drawing tool. + + Position the center of the cercle and maintain the mouse button to + select its dimensions. + + + + 13 - Filled circles/ellipses: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Work like empty circles and ellipses. + + + + 14 - Rectangles with gradation: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + *** Not implemented yet *** + + + + 15 - Gradation menu: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Any click: + ==========> + + Opens a window where you can define the way gradations are processed. + The different sections of this menu are: + + - Direction (arrow): Switches the direction of the gradation. + + - Dithering method: Toggles the 3 following methods: + - No dithering + - Basical dithering + - Enhanced dithering + + - Mix: Mixes the gradation with a more or less random factor. + + - Palette: Select a color range to build a gradation. + + - Index scroller: Defines the current gradation among a set of 16 that + will be memorised. + + + + 16 - Spheres / Ellipses with gradation: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Selects the spheres as the active drawing tool. + + Position the center of the sphere and maintain the mouse button to + select its radius. Then place the spot-light. + + + Right click: + ============> + + Selects the ellipses with gradation as the active drawing tool. + + *** The current version of this tool isn't the right one; *** + *** so we'll explain how to use it when it will be done *** + + + If you trace a sphere or an ellipse with gradation with the right mouse + button, the result will be the same figure filled with the Back-color. + + + + 17 - Brush grabbing / restore: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Engages a brush grabbing. + + Click on a corner of the rectangle containing the brush then maintain + the click to define the opposite corner of the rectangle. Release the + mouse button to grab the brush. Performing this operation with the right + mouse button will erase the area where the brush was grabbed with the + Back-color. + + + Right click: + ============> + + Restores the old brush. + + + + 18 - Polyformed brush grabbing (Lasso) / restore: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Grabs a brush of any shape by defining a polyform (please refer to + section 8 for more explanations). + + + Right click: + ============> + + Restores the old brush (same as above). + + + + 19 - Brush effects: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Any click: + ==========> + + Displays a menu where the following options are available: + + - X: Flip-X. + + - Y: Flip-Y. + + - Rotate by 90ø: Rotates the brush by an angle of 90 degrees. + + - Rotate by 180ø: Rotates the brush by an angle of 180 degrees. + + - Rotate by any angle: Triggers an interactive operation that allows + you to rotate the brush. For this, start by placing the center or + rotation with the left mouse button (if, at this moment, you press + the right button, the operation with be cancelled). After that, you + can define the angle of rotation as many times as you want by moving + the mouse and left-clicking. Then validate with the right button + when you are satisfied. + Meanwhile, you can press on the 8 outer digits of the numeric pad + for defining angles multiple of 45ø: + 135ø 90ø 45ø + \ | / + '7' '8' '9' + 180ø -'4' '6'- 0ø + '1' '2' '3' + / | \ + 225ø 270ø 315ø + + + - Stretch: Triggers an interactive operation that enables you to stretch + the brush. For this, start by placing the upper-left cornerof the + brush with the left mouse button (if, at this moment, you press the + right button, the operation will be cancelled). after that, you can + place the opposite corner as many times as you need, then validate + with the right mouse button when you are satisfied. If you place + this point at coordinates inferior to the ones of the first point, + the brush will be inverted. + Meanwhile, you can press the following keys whose effects are: + 'D' : double the brush in X and Y + 'H' : reduce the brush by half in X and Y + 'X' : double the brush in X + 'Shift+X': reduce the brush by half in X + 'Y' : double the brush in Y + 'Shift+Y': reduce the brush by half in Y + 'N' : restore the normal size of the brush (can be useful + because it's the only way for cancelling) + + - Distort: *** Not implemented yet *** + + - Outline: + This option permits to draw the outlines of the brush with the Fore- + color. + + - Nibble: + This option "nibbles" the outlines of the brush. It's in some way + the opposite effect of the Outline option. + + - Recolorize: Remaps the brush so that it looks like it would in the + spare page, using the current palette. + + - Get brush colors: Transfers the spare page's colors used by the + brush to the current palette. + + - Brush handle: Allows you to choose where to place the handle of the + brush. + + - Load / Save: load or save a brush from disk. + + + + 20 - Drawing modes: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + This button opens a menu where you can switch on or off the different + drawing modes. ([F1]-[F9] keys correspond to the 9 buttons) + + In this menu, the "All off" button switches all the drawing modes off. + The [Del] key is the keyboard shortcut for this button. + + The "Feedback" button is only used in "Shade", "Quick-shade, "Transpa- + rency" and "Smooth" modes. When it is set, it means that the _current_ + state of the picture has to be taken into account for the effect instead + of the state in which the image was when you started to click for drawing. + The best, as often, is that you try by yourself with and without Feedback + to see the difference. + + The other buttons are the following: + + + * Shade mode / Menu: + -------------------- + + It consists in increasing or decreasing the color number within a user- + defined range. This shows its real dimension when used with a range of + colors that shade off. Then, you can work on a part of your picture where + colors belong to the same range without having to change your brush color + all the time. + You can choose the incrementation or decrementation of the color by + pressing the left or right mouse button while drawing. If you click on a + color that does not belong to the range, it will remain unchanged. + + Left click: + ============> + + Switches the Shade mode. + + + Right click: + ============> + + Opens a menu where you can define one table of shades within a range + of 8 memorised by the program. + The different sections of this menu are: + + - Palette: You can define in it the color blocks that will be inserted + into the table of shades. + + - Scroller: Used to change flick through the tables of shades. + + - table of shades definition area: The 512 squares should be widely + sufficient to define the different shades since every 256 colors of + the palette cannot be present more than once in each table. + + - A window (on the top-right side) permits to visualize the different + shades defined in he current table. + + - Copy: Copy the contents of the table in a buffer. + (Each time you open this menu, the current table is automatically + transfered into this buffer). + + - Paste: Copy the contents of the buffer above in the current table. + + - Clear: Reset the "shades" table. + + - Insert: Used to insert the block selected in the palette at the + cursor's position in the table of shades. + IF you click with the left mouse button on this button THEN + IF a block of more than one color is selected in the table THEN + It is deleted and the block defined in the palette is inserted. + ELSE + The block defined in the palette is inserted at the postion just + before the selected square. + END IF + ELSE + The block defined in the palette is inserted by erasing the colors + following the beginning of the bloc selected in the table. + END IF + + - Delete: Delete the block selected in the table. + + - Blank: Follows this algorithm: + IF you click with the left mouse button on this button THEN + Replace the block selected in the table by blank squares. + ELSE + IF a block of more than one color is selected in the table THEN + Insert blank squares to the left and to the right of the block. + (this is useful for isolating a shade quickly) + ELSE + Insert blank squares to the left of the selected square. + END IF + END IF + + - Invert: Invert the order of the block selected in the table. + + - Swap: Allows you you move a block (this exchanges it with what is + where you want to move it). + + - Undo: Cancel the last modification of the table. + + - The 2 numbers displayed on the right of these buttons are: + (above) - the number of the color selected in the palette if only + one color is selected. + (below) - the number of the color contained in a square in the + shades table if this square is the only one selected. + + - The "mode" button displays 3 different modes: + "Normal": + Shades in the range and saturates to its boundaries. + "Loop": + Shades in the range and loops if boundaries are passed. + "No saturation": + Shades in the range and doesn't saturate if boundaries are passed. + If the Step (see below) is set to 1, this option does exactly the + same as the Normal mode. + + - Set/Disable: If you want to define several shades in the same table + but you'd like these shades not to be effective at the same time, you + can mask (disable) some parts of the table so that they will be + interpreted a blank squares. + To do that, select a block in the table of shades and click on "Set". + The block will be underlined with a white line; this means that it is + disabled. + + - Clear/Enable: This does exactly the opposite as the button above. + + - Step: Defines the step of incrementation of the shade. The bigger, + the faster you run through the colors of the shade. + For example: if the step is 2 and that you have defined a shade with + the colors 0,1,4,5,9 and that you click on a pixel of color 1, it will + take the value 5 which is 2 positions next in the la table. + + (We are sorry for these technical considerations quite far from a + purely artistic point of view; but know that this effect is really very + useful and it is preferable that you understand its whole functionment + if you want to fully take advantage of it). + + + + * Quick-shade mode / Menu: + -------------------------- + + This drawing mode has about the same effect as Shade mode's except that + it is faster to configurate but a little bit less powerful. + When you draw on a color of the image which is between the fore- and the + back-color in the palette, the color tends towards the fore-color + (according to the step defined) if you draw with the left mouse button, or + it tends towards the back-color if you are using the right mouse button. + + Left click: + ============> + + Switches the Quick-shade mode. + + + Right click: + ============> + + Opens a menu with a few parameters that mean exactly the same as in + the menu of Shade mode. These parameters are the step and the loop/satu- + ration mode (normal, loop, no saturation). + + + + * Stencil mode / Menu: + ---------------------- + + It is used to prevent some colors from being modified if you draw on + them. The main application of the stencil is when you want to change one + color or more into another. + + Left click: + ============> + + Switches the Stencil mode. + + + Right click: + ============> + + Opens a menu where you can define a stencil. + The different sections of this menu are: + + - Clear: No color is protected. + + - Invert: Colors that were protected are unprotected and vice versa. + + - Palette: Select colors that should be protected with the left mouse + button or unprotect colors with the right mouse button. + + + + * Mask mode / Menu: + ---------------------- + + This effect could have been called "True stencil" because it protects + some parts of the picture instead of some colors. The colors you tag + represent the pixels in the spare page, corresponding to the pixels in the + current page, that you don't want to alter. + For example, draw a simple white figure on a black background in the + spare page. Then, tag the black color in the menu of the Mask mode. When + you'll draw in the current page, only the pixels corresponding to the + white (non-black) ones in the spare page will be modified. + + Left click: + ============> + + Switches the Mask mode. + + + Right click: + ============> + + Opens a menu where you can set the colors of the Mask. + This menu works the same way as the one of the Stencil, so please + refer to the Stencil paragraph to know how to use it. + + + + * Grid mode / Menu: + ------------------- + + This is useful to snap the cursor to the cross-points of a grid. It's + generally used to draw a grid before drawing sprites of the same size such + as a font or tiles, or for drawing figures or grabbing brushes with their + dimensions multiple of the step of the grid.'); + + Left click: + ============> + + Switches the Grid mode. + + + Right click: + ============> + + Opens a menu where you can define the grid parameters. + These parameters are: + + - X,Y: Steps of the grid. + + - dX,dY: Offsets of the grid. + + + + * Sieve mode / Menu: + -------------------- + + This effect allows you, by defining a pattern, to draw only on + particular points of the picture. + If you are a Manga drawer, you might find this useful to make patterned + shades or color transitions. + + Left click: + ============> + + Switches the Sieve mode. + + + Right click: + ============> + + Opens a menu where you can define the Sieve parameters. + This menu consists in: + + - 16x16 drawing area: You can define a pattern in it (left click => + white pixel / right click => black pixel). + All the white pixels indicate that, when you'll draw, pixels will be + applied on the picture at the corresponding positions whereas black + pixels won't modify the picture: whites pixels are the "holes of the + sieve". + + - 12 default patterns: They can be copied to the drawing area. + + - "Transfer to brush": Copies the pattern to the brush (white pixels + => Fore-color / black pixels => Back-color). + + - "Get from brush": Puts the brush into the drawing area (back-color + => black pixels / others => white pixels). + + - Scrolling 4-arrows pad: Scrolls the pattern in the drawing area. + + - Resizing 4-arrows pad: Defines the dimensions of the pattern. + + - Default-value (black or white square): Indicates which value must be + inserted when you increase the dimensions of the pattern. + + - "Clear": Sets the whole pattern with the default value (see above). + + - "Invert": It... inverts :) ... black and white pixels. + + + + * Transparency mode (Colorize) / Menu: + -------------------------------------- + + This allows to mix the color(s) of the paintbrush with the colors of the + picture. It's used to make transparency effects like with watercolors. + + Left click: + ============> + + Switches the Transparency mode. + + + Right click: + ============> + + Opens a menu where you can define the Transparency parameters. + These parameters are: + + - Interpolation rate: Indicates the percentage of the applied color + that will be considered upon the replaced color. + + - Interpolation method: Uses an interpolation algorithm to compute the + color, according to the interpolation rate. + + - Additive method: Uses the lightest colors to choose the color to + apply. + For example: if you want to apply a color RGB:30,20,40 on a color + RGB:10,50,20, the color applied will be the one, in the palette, + that is the closest to the theoretic color RGB:30,50,40. + + - Subtractive method: uses the darkest colors to choose the color to + apply. + For example: if you want to apply a color RGB:30,20,40 on a color + RGB:10,50,20, the color applied will be the one, in the palette, + that is the closest to the theoretic color RGB:10,20,20. + + + + * Smooth mode / Menu: + --------------------- + + It provides an easy but not as efficient anti-aliasing as any artist's + touch. Anyway this effect finds a better use in making a blurry aspect. + + Left click: + ============> + + Switches the Smooth mode. + + + Right click: + ============> + + Opens a menu where you can define the Smooth matrix or choose one + among the 4 ones predefined. + The middle square represents the pixel on which you draw and the 8 + others represent the neighbour pixels. Then, the point on which one draw + will be replaced by the weighted average (according to values of each + squares) of the 9 defined points. + + + + * Smear mode / Menu: + --------------------- + + It smears pixels in the direction you are moving your paintbrush, just + as if you wanted to spread fresh paint with your fingers. You can combine + this effect with the transparency effect. + + Any click: + ==========> + + Switches the Smear mode. + + + + * Tiling mode / Menu: + --------------------- + + It consists in displaying parts of the brush that are adjusted on a + tiling when you are drawing. It's mainly used for quickly drawing a + background with a pattern, but there is a great number of other + possibilities. + + Left click: + ============> + + Switches the Tiling mode. + + + Right click: + ============> + + Opens a menu where you can define the Tiling parameters. + These parameters are the offsets of the tiling. + + + + 21 - Text: + ÄÄÄÄÄÄÄÄÄÄ + + *** Not implemented yet *** + + + + 22 - Magnifier mode / Menu: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Engages/Disengages the choice of the zoomed window. If you're already + in magnifier mode, you'll return to normal mode. + + + Right click: + ============> + + Displays a menu where you can choose the magnifying factor. + + + Note: When you are in Zoom mode, you can move the "split" bar by + clicking on it and moving your mouse left or right while holding the mouse + button down. + + + + 23 - Pipette / Invert colors: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Engages a color grabbing. + + Click on the picture to get the color of the pixel you're on. You can + either get a new Fore-color or Back-color with respectively left or + right mouse button. + + + Right click: + ============> + + Swap Fore-color and Back-color. + + + The color currently pointed will be displayed in the tool-bar right + after the coordinates. + If you click outside the picture, the color 0 will be returned. + + + + 24 - Screen size / Safety resolution: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Displays a menu where you can define the size of your picture (up to + 1024x768) by clicking in the boxes named "Width" and "Height"; and the + resolution in which you want to draw (in the list). + + Clicking on a resolution button with the right mouse button will not + only set the resolution of the screen, but also set the picture + dimensions to the screen ones. + + Resolutions written in dark gray are VESA modes that aren't supported + by your video card. If you have some modes like that, you should try to + run a VESA driver such as Univesa or Univbe before running the program. + If these modes still aren't available, then this means that your video + card really doesn't support them. + + The small buttons on the left-hand side of the lines in the list of + modes have been designed to allow you to disable some modes that are not + supported by your card. So, the modes that you will disable won't be + used when loading pictures with "Auto-set resolution" ON. + + When you click on one of these buttons, its color changes to one of + the 4 following. The signification for each color of these buttons is: + + - Light gray: The video mode is OK. It can be used by the auto-set + resolution option when you load picture, and you can select it in + the menu of resolutions. + + - White: It works exactly the same as above. Moreover, it allows you + to tag your favourite modes. Indeed, the huge number of video modes + makes it more difficult to find the mode your want in the list; so + you can tag your favoutite ones in white, so that it will be easier + to locate them. (Note: you cannot disable the standard 320x200 mode) + + - Dark gray: It allows you to indicate which modes are not really + perfect (flickering, not centered, etc...) but which can be used + even so. The difference with the light grey button is that these + modes won't be used by the auto-set resolution option. + + - Black: Use it for totally unsupported modes. Thus, these modes won't + be selected the "auto-set res." and the program will prevent you + from selecting them from the menu of resolutions. + + + Right click: + ============> + + Automaticaly switches to the 320x200 MCGA mode. + + + + 25 - Spare page / Copy current to spare: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Jumps to spare page. The current page is then considered as the new + spare page, and the spare page considered as the new current page. + + + Right click: + ============> + + Opens a menu where you can choose whether you want to copy the whole + picture (keyboard short-cut in this menu is [Return]), only the pixels, + only the palette, or only some colors. + In this last case, a second menu (stencil-like) will propose you to + tag the colors you want to copy (they are all selected by default). + Please refer to section "18 - Stencil" to know how to use this last + menu. + The last option the menu ("Copy palette and remap"), remaps the spare + page with the current palette and replicates this palette to the spare + page. This option is useful to quickly remap a picture with the palette + of another. + + + + 26 - Save picture / Autosave: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Displays a fileselector where the following options are available: + + - Drives: Allow you to change the current drive. You can use + + to change drives too. + + - Format: Allows you to choose the file format you want. (PAL and KCF + file formats are "palette" files). + + - Filename: Allows you to give a new name to the picture. If no + extension is given, the default (according to the format) will be + used. + + - File-list: Allows you to flick through the disk tree or to overwrite + an existing file. + + - Delete: Allows you to delete the item under the selection bar. + If the item is a directory, it must be empty to be removed. + + - Save: Saves the picture with the current filename, with the chosen + format and with the current comment (for PKM files). If the current + filename represents a directory, you'll enter it. + + - Comment (Txt): If you're using the PKM format, you can type in a + comment on your picture. + + Note: The Backspace key brings you directly to the parent directory. + Type in the 1st lettets of a filename you are looking for to + access it faster. + + + Right click: + ============> + + Save the current picture with its current filename, format and + comment. + + If the file already exists, a confirmation box will appear. + + + + 27 - Load picture / Reload: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + This works the same way as Save. + + You'll have access in the format selector to a "*.*" filter. And of + course, you won't be able to type in any comment. + + + Right click: + ============> + + Reloads the picture. + + If you want to load a picture and that you haven't saved the last + modifications of the current picture, a confirmation box will appear. + + + + 28 - Settings: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Any click: + ==========> + + Displays a menu where you can configure some miscellaneous elements of + the program: + + - Number of UNDO pages: indicates the total number of pages that + GrafX2 will memorize. Each time you modify the picture, its current + state is memorized in one of these pages. To flick through these + pages, use the "Oops" button (Undo/Redo). + + - Font: determines whether you want to use GrafX2 with a classical + font, or another one a bit funnier. + + - Mouse sensibility: Modifies the speed of the mouse. + + - Show/Hide in file list: Defines whether some particular files or + directories must be displayed by the fileselectors or not. + + - Show/Hide picture limits: Indicates if the picture boundaries must + be displayed when you are in a resolution bigger than the picture. + + - Clear palette: Indicates if loading a file with a palette of less + than 256 colors must erase the rest of the current palette (replace + by the black color). + + - Maximize preview: maximizes the preview of the pictures so that it + is as big as possible. If you're not in the same resolution as the + picture's one, it can try to correct the aspect ratio, but if the + picture does not fill the whole screen, it can be worse. + + - Backup: when you'll save a picture over an existing file, the + program will rename this file to "*.BAK" where * is the name of the + picture without its extension. If the backup file already exists in + the directory, it will be replaced. If you save a picture with the + name of the backup file, no backup file will be created (of course!) + ;). + + - Cursor: allows you to choose whether you prefer a solid cursor or a + transparent cursor. + + - Safety colors: Brings back the 4 default colors of the menus if you + run an operation that passes the image in less than four colors in + the palette editor. + + - Adjust brush pick: This option is used when you grab a brush in Grid + (Snap) mode. Then, the right-most and down-most pixels won't be + picked up with the rest of the brush. This option has been made + because, if people grab brushes in Grid mode, that's mostly when + they want to grab sprites. + For example: if you have 16x16 sprites on your page, you'll set the + grid mode to 16x16. But the cursor will snap at points like (0,0), + (16,0), (16,16) and so on... And the problem is that, from (0,0) to + (16,16), there are 17 pixels! But if you keep the adjust-brush-pick + option on, the unwanted pixels will be ignored. + Moreover, this option adjusts the brush handle so that the brush + still fits in the grid, instead of placing the handle in the center + of the brush. + + - Separate colors: Draws a squaring around the colors of the tool-bar. + + - Auto-set resolution: sets the best resolution for the loaded image. + + - Coordinates: Choose if you want to display relative or absolute + coordinates when using tools such as circles, rectangles, etc... + for example, if you draw a circle: if coords are relative, the + radius of the circle will be displayed, while in absolute coords, + the coordinates of the cursor will be displayed. + + - Reload: loads the previously saved configuration. + + - Auto-save: means that the configuration will be automatically saved + when you'll quit the program. + + - Save: saves the configuration at once. + + All modifications will be effective just after closing the menu. + + + + 29 - Clear picture: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Clears the picture with the color number 0. + + + Right click: + ============> + + Clears the picture with the Back-color. + + + + 30 - Help / Statistics: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Displays an info window where you'll find some credits, help about the + credits, different effects, greetings, registering... + + + Right click: + ============> + + Displays a window where you'll find miscellaneous informations about + the system. + + Note: you should take care to keep more than 128 Kb in order to let the + program run in a proper way. + + + + 31 - Oops (Undo/Redo): + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> Allows you to undo the last modification on the picture. + + Right click: + ============> Allows you to redo the last modification undone on the + picture. + + The maximum number of UNDO that you can perform can be defined in the + settings menu. + + Undo/Redo aren't effective after page switching, picture loading and + picture size modifications. + + + + 32 - Kill currenty page: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Any click: + ==========> + + Removes the current page from the list of "Undo" pages. This allows + you to free some memory if you need it. For instance, this will allow + you to delete the start-up page after having loaded an image. A message + will appear if you've already erased all the pages except the last one. + + Note: Another way to free some memory is to decrease the number of + "Undo" pages. Or else, if you have recentlt grabbed a very big + brush that you don't use any more, you can grab a new smaller one. + The memory allocated by the big brush will be thus freed. + + + + 33 - Quit program: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Any click: + ==========> + + Allows you to leave GrafX2. If there are unsaved modifications in the + current or spare page, a confirmation box will ask you if you really + want to quit GrafX2, if you want to save (Auto-save, no fileselector) or + if you want to stay in GrafX2. + + + + 34 - Palette menu: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Displays a menu where the following options are available: + + - Palette: Allows you to choose a color-block to edit. If you click + with the right mouse button, you'll choose a new Back-color. + + - RGB gauges: Allow you to modify the current selection. + + - "+" and "-": Allow you to lighten or darken the current selection. + + - Default: Restores the predifined GrafX2 palette. + + - Gray: Transforms the current selection into its gray-scaled + equivalent. + + - Negative: Transforms the current selection into its reverse video + equivalent. + + - Invert: Swaps the colors of the current selection so that the first + colors become the last ones. + + - X-Invert: Works as above but modifies the picture so that it looks + the same. + + - Swap: Swaps the current selection with another color-block. Click on + the beginning of the new color-block. + + - X-Swap: Works as above but modifies the picture so that it looks the + same. This may be useful if you want to sort your palette. + + - Copy: Copies the current selection to another color-block. Click on + the beginning of the new color-block. + + - Spread: Computes a gradation between two colors. If your selection + is only made up of one color, select the second color in the + palette. Otherwise, the two colors used will be its extremities. + + - Used: Indicates the number of colors used in the picture. + + - Zap unused: Erases the unused colors with copies of the current + selection. (The keyboard shortcut for this button is ). + + - Reduce: Allows you to reduce the palette to the number of colors you + want (and modifies the picture). + + - Undo: Allows you to recover the last modifications made on the + palette. If the last operation modified the picture, it won't + recover them: you'll have to click on Cancel to do so. + + + If you press , the program will replace, as well as + possible, some unused colors by the four default colors of the menu. + The image won't look altered because the modified colors (in the case + they were used on a few points) will be replaced by the closest colors + in the rest of the palette. + This option is really useful when you modify the palette so that there + are no colors that fit for the menu (eg: "Zap unused" while very little + colors are used in the picture; or "Reduce" with a very small number of + colors). + + If you press the key below or <,> (QWERTY), the menu will + disappear and you will be able to pick up a color from the picture + easily. Press to cancel. + + If only one color is selected (not a block), the <[> and <]> keys can + be used to select the previous or next Forecolor (Backcolor if you press + at the same time). + + Warning! If you press Undo after an action that modifies the picture + (X-Swap, X-Invert and Reduce colors), the picture won't be remapped as + it was just before this action. Only Cancel will. + + + Right click: + ============> + + Opens a menu from where you can access the following menus: + + - A menu in which you can select the colors that have not to be used + for smoothing, for the transparency mode and for remapping. + + - A menu in which you can define color series. + *** Not implemented yet *** + + + + 35 - Scroll palette left / right: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Scrolls the palette window in the right of the menu. + + + Right click: + ============> + + Same as above, but faster. + + + + 36 - Palette window: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Left click: + ============> + + Defines the Fore-color. + + + Right click: + ============> + + Defines the Back-color. + + + + 37 - Hide menu: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Any click: + ==========> + + Allows you to hide the menu. If you do this, take care to watch before + the key to press to show the menu back (the default key is ). + + + + +Let's talk about $$$, baby: +ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ + + Please refer to the "Register?" section in the internal help of GrafX2. + + To sum up this section, let's just say that GrafX2 is freeware. But you + can anyway send us money, graphics, or just a postcard to show us that we + made a useful program. + + You must note that the version you have is already the "complete" version + (the same as the registered version) so we won't send you any other copy of + GrafX2. But if you register for one version, we'll consider that you won't + have to register for the next ones. + + + + +Drawing tips: +ÍÍÍÍÍÍÍÍÍÍÍÍÍ + + This section deals with tips that can help you to draw some cool effects, + or just to draw faster. + Note that, in most cases, these tips only make a big part of the work and + that you'll have to touch up in zoom mode if you want to draw a picture + worthy of the name! ;) + Moreover, if you've found out nice tips by yourself, and if you want to + share them with the others, don't hesitate to tell us. + + Anti-aliasing: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + This is not an effect proposed by GrafX2 but a drawing method. It + consists in placing medium colored pixels in the angles formed by + contrasted pixels for artistically smoothing their aspect. + From our point of view, this is essential for drawing really nice + pictures. + An easy but tiresome way (the best way!) is to start by adding 1 middle + color, then antialias the new colors "recursively" while you have + intermediate colors in your palette. + + ÛÛÛÛÛÛÛÛÛÛÛÛ + ÛÛÛÛÛÛÛÛÛÛÛÛ + + ÛÛÛÛÛÛÛÛ±±±±±±±± + ±±±±±±±±ÛÛÛÛÛÛÛÛ + + ÛÛÛÛ²²²²²±±±±°°°° + °°°°±±±±²²²²²ÛÛÛÛ + + + Smear mode combined with concentric lines: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + By combining this effect and this drawing tool, you can spread an area + from a central point. + If you aren't in high resolution, it can be useful to switch on the + transparency mode too (see next section). + + þ A possible application is to draw fluffy hair. For that, you can choose + one of the pre-defined paintbrushes loking like random points. According + to the hair density you wish to obtain, you can choose a paintbrush with + more or less points. Then, place the center of the concentric lines in the + middle of the plush, and rotate the mouse around it keeping the mouse + button pressed. + With the same method, by turning around more, you can manage to give + an explosion effect to an object. + + þ You can also create easily and quickly sun rays with this method. For + that, after having drawn the primary shape of the sun in the sky, choose + a paintbrush according to the size of the rays you want (but a small one + will often be prefered), and place the center of the lines in the center + of the sun. Then trace the ray at the length you want. If you didn't take + a big paintbrush, you'll be able first to draw an aura around the sun by + rotating quickly, and then to add more important rays with precision. + + + Smear mode combined with Transparency mode: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + This two drawing modes, once combined, permit to spread parts of the + picture as fresh paint. + It is recommanded to use the transparency method which consists in + interpolating with an opacity of about 60% and the effects "Feedback" on. + + þ As in the prvious section, it can be useful for drawing hair and + especially eyelashes if you have got a good palette (i.e. a palette that + contains color gradations between every colors you'll draw on during the + operation. + For drawing eyelashes for example, after having drawn the eye and the + eyelid, trace a quite thick black line representing the base of the eye- + lashes (this is that black line you'll spread out on the eyelid). Then, in + smear+transparency mode, draw with the freehand continuous tool (with a + small paintbrush: 1, 2 or 3 pixels wide according to what you draw: a face + or a close-up on an eye) starting from the base of the eyelashes in giving + their shape. You'll see your black bar looking more and more like eye- + lashes. + + þ One can also use these effects for mixing colors on the screen like + paint. For example, if one want to draw a background made of abstract + shapes composed of color mixings, one can proceed like what follows: + - Define a palette containing a gradation between the different colors you + wish to use . + - Draw very vaguely the different colored areas with a big paintbrush (in + normal mode). + - With a smaller paintbrush, and with the spray, apply these same colors + but lighter or darker on the previously defined areas. + - Always with the same paintbrush in spray, but this time in smear mode + (not necessarily with transparency... but why not?), mix all these colors + on the screen to obtain a "multicolored pulp" vaguely conserving the + different color areas. + - At last, in Smear+Transparency mode, with a medium rounded paintbrush, + hand-draw by whirling or making waves, etc... conserving the same movement + to avoid breaks. This aims at eliminating the pixellisation made by the + spray and giving the final mixed paint aspect. + - Now, if it's ugly, it's either because my explanations are incomprehen- + sible, or because you have no talent! :p + + + Spray combined with shade mode: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + þ If you often use Shade mode, and you are tired of clicking plenty of + times on a pixel for reaching the color you want, you can define a spray + with "Size"=1, "Mono-flow"=1, and "Delay"=2 (or more, according to your + reflexes). Then you'll just have to click a few hundredth of second for + modifying a color. + + þ With a wider diameter, it permits to add granularity to a texture, + because placing lighter or darker pixels creates some ruggedness. + Different textures appropriated to this effect are: sand, rock, etc... + Of course, you'll need a color gradation corresponding to color of the + texture. + + þ You can also draw more elaborated textures - \ + using a paintbrush of the shape of a small curve \ \ + or line as these figures "try" to show. ;) ` \ + Thus, you can create textures of straw, hair, | \ + rock, marble (although hand-drawing would be + more recommanded than spray for this last one). + + + Shade mode used for replacing a color gradation by another one: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + þ If you drew something with colors belonging to a gradation and you'd + like to replace all these colors by the ones of another gradation (with + the same number of colors), proceed as follows: + - Define these 2 gradations in the same shade table in the shade menu + without separating them by a blank square. + - Set the "no saturation" shade mode. + - Define the step of the shade with the size of the two gradations (e.g.: + enter 16 if each gradation contains 16 colors). + - Now, you just have to draw on the area you want the colors to change + (with the left mouse button if you placed the gradation to replace first + in the shade table, or inversely). + + + Spheres combined with additive transparency mode: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + þ Starting from a dark background (if possible all of the same color), + trace overlapping spheres with their lighting point at their center. + You'll quickly obtain a "blob" effect. + + + How to draw drops: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + þ Here is a fast and efficient method to draw drops. + Just draw very bright pixels on the side of the drop where the main light + is, and less bright ones on the opposite side. Then draw shadows according + to the position of the light. + + Here are examples with a light ±±±±±±±±±±±± ±±±±±±±± + coming from the top-left corner. ±±±±±±±±±±±± ±±±±±±±± + (they are best viewed in 80x50 ±±±±²±°±±±±± ±±Û°±±±± + text mode) ±±±²Û°°±±±±± ±±±°²°±± + ±±±Û²°±²°±±± ±±±±°±±± + You may think that the smallest ±±±²±°²²°±±± ±±±±±±±± + drop doesn't really look like a ±±±±±²Û±°±±± ±±±±±±±± + drop, but draw it in graph mode ±±±±±°°°±±±± + and you'll see it DOES look ±±±±±±±±±±±± + like a drop. ±±±±±±±±±±±± + + If you don't trust me, then know that it's by looking at Lazur's graphs + that I found this method. And in a general way, it's always good to study + the work of the best artists to learn new techniques. + + + + +Trouble-shooting / General hints / FAQ: +ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ + + * Video card problems: + + - VESA modes are disabled by Windows NT. And it is said that it will be + the same under Windows 2000 (we haven't tried it yet, and we aren't in a + hurry!). + + - If your video card is not VESA compatible in hardware, you should try to + run a VESA driver such as Univesa or Univbe. + + - If your card is VESA compatible but doesn't display the screen correctly + in VESA resolutions, that's probably because they don't fulfil all the + criteria that we expect. The explanation is that, for a better efficiency, + we have had to neglect some specificities on some video cards. However, + we always try to improve the compatibility with any kind of the VESA + standard in each new version. + + - If you have an ATI Mach 64 video card (e.g. ATI Xpert), you should use + the m64vbe TSR supplied with the card to fully support our fancy XVESA + modes by typing "m64vbe vga". + + + * Memory problems: + + - Since the 94.666% version, we use the EOS dos-extender Copyright (c)1996 + Eclipse instead of the usual DOS4GW. The reason is that it is much + smaller in disk space (a smaller zip should please your phone bills) and + in memory (so you'll be able to run GrafX2 with more device handlers + using conventionnal memory). In addition, this dos-extender is inside + the main file, which reduces the number of files (your FAT will be happy + for that). + + The backdraw is that this dos-extender doesn't manage disk-cache. So, if + you haven't at least 4 Megabytes of RAM, you'll have to use the batch + file GFX2_MEM.BAT . + + Notice that: + - you'll have to configure this file according to the location of some + files in the tree of your hard-disk(s). + - you'll have to have the file DOS4GW.EXE somewhere in the tree of + your hard-disk(s). + - you'll need at least 16 Megabytes of free space on your current + hard-disk. + + If you ever encounter problems using GrafX2 (with at least 4 Megabytes + of RAM) that would vanish using GFX2_MEM, we would thank you to let us + know. + + EOS is a shareware dos-extender, with very interesting libraries for + music, graphism, ... for Watcom, Tasm or Masm applications. If you want + more informations on its features or its libraries, don't hesitate to + contact us in order to be put in relationship with its authors. + + + * Sound card problems: + + Q: No sound comes out from my Ultra-maxi-sound-blaster-galaxy-64-3D-pnp, + so what can I do? + A: Well... You must understand that this program is not a soundtracker nor + a music-player :) ... So if you want some music, you'll have either to + play modules with a good player that can run background (with a DOS + shell), or to switch your Hi-Fi on. + + + * Miscellaneous: + + - If you corrupted the GFX2.CFG file and that GrafX2 uses it as is, with + an incorrect behavior, don't hesitate to erase GFX2.CFG and to re-run + GFXCFG to create a new correct one. Indeed, the only tests of validity + we do on the configuration file are checking its size and its version + number. + + - It may happen that you get a version already configured by one of your + friends who could have used some "Windows 95" keys while you haven't got + such keyboard yourself. In this case, you'll have to reconfigure these + combinations using GFXCFG. + + + * Frequently asked questions: + + Q: How can I set the dimensions of the picture? + A: We thought it was obvious that you had to click in the areas where the + dimensions are written in the resolution menu (Width & Height) but many + people asked this question (?!). So, to sum up, everywhere you'll see a + value or text written in black in a sort of encrusted area, this means + that if you click on it, you'll be able to modify its value. + Moreover, if you want the picture dimensions to be the same as the ones + of the screen, you just have to right-click on the resolution in the + list. + + Q: Where can I get the latest version of GrafX2? + A: The only place where you will find the latest version for sure is our + web site: http://www-msi.ensil.unilim.fr/~maritaud/sunset + Nevertheless, it isn't impossible that GrafX2 may also be found on FTP + sites dedicated to the "demo-scene" (e.g. ftp://ftp.scene.org). + + Q: How can I make the brush become monochrome, and how can I get it back + to its normal state? + A: You can do it (assuming that you haven't modified the default keys) + with the keys + to make the brush become monochrome, and + + to get the multi-coloured brush back. + + Q: Why is the tool bar at the bottom of the screen instead of at the right + side like in Deluxe Paint (copyright Electronic Arts)? + A: Well... GrafX2 IS NOT Deluxe Paint! We know that you are used to Deluxe + Paint but you'll have to get used to GrafX2! ;) If you really can't + stand using GrafX2 like this, then you'll have to wait for GrafX3 but + we probably won't release it before year 2000! Actually, the main + reason why we put the tool bar with such a basical aspect is that it + was easier (therefore faster) to redraw the whole screen just by + telling the routine where to stop (where starts the tool bar). + Moreover, one of the best Amiga paint programs (Brilliance) has got the + tool bar at the bottom of the screen too. + + Q: Why aren't the hidden parts of the picture filled when I use the "Flood + fill" tool? + A: For the simple and "quite" good reason that it is preferable that the + user controls perfectly what he is drawing. Thus, he won't see too late + that he has fucked up a part of his picture. The other tools work the + same way. And for the less good reason that is was more convenient for + us. ;) + + Q: Is it possible to launch the program in a different resolution than + 320x200? + A: Yes, you just have to type GFX2 at the DOS prompt. Type + GFX2 /? to get the list of all the video modes. + + Q: Is it normal that some buttons don't work (e.g.: the Text button)? + A: Yes, this is because we haven't had the time to make them (I remind you + that GrafX2 is still at a Beta version state). + However, here is the list of the buttons that don't respond in GrafX2: + - Grad. rectangles + - Text + - Effects on the picture + - and the following button in the "Brush effects" menu: Distort. + + Q: Will you release a Windows version? + A: GrafX2 would lose its soul by being adapted to a windowed system or a + system that doesn't support all its video modes. And anyway, it can be + run from Windows 9x (we don't know about Windows 2000 but we don't + care). So that's OK the way it is. The only interesting thing that + Windows could bring is the clipboard. + + Q: Will you release a Linux version? + A: Although this is about the same problem as with the Windows version, + Linux lacks programs like GrafX2; so, even a limited version would be + interesting in this OS. Therefore, we would like to release a Linux + version. But we have no experience in Linux programming and our code is + completely indecipherable for others. So you'll have to wait... + + Q: How can I contact you? + A: Actually, this is not really this question since those people managed + to contact us ;) but... + + * Snail mail: + GUILLAUME DORME (Robinson) KARL MARITAUD (X-Man) + 15, rue de l'observatoire 10, rue de la Brasserie + 87000 LIMOGES (FRANCE) 87000 LIMOGES (FRANCE) + + * E-mail: + dorme@msi.unilim.fr maritaud@ensil.unilim.fr + + Do not hesitate to contact us; we love that! :) + We'll try to reply to every e-mails (if any answer is needed), and also + to certain normal letters (Yes of course, we won't ruin ourselves for + stamps just to say "Thanks for writing!" :)). diff --git a/doc_fra.txt b/doc_fra.txt new file mode 100644 index 00000000..12b66a5a --- /dev/null +++ b/doc_fra.txt @@ -0,0 +1,2113 @@ + ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + ³ ÜÜÜÜ ÜÜÜÜ ÜÜÜ ÜÜÜÜÜ Ü Ü ÜÜÜÜ ³ + ³ Û Û Û Û Û Û ßÜ Üß Û ³ + ³ Û ÜÜ ÛÜÜÜß ÛÜÜÜÛ ÛÜÜ ßÜß Üßß ³ + ³ Û Û Û ßÜ Û Û Û Û Û Û .00 ³ + ³ ßÜÜÜÛ Û Û Û Û Û Û Û ÛÜÜÜÜ ³ + ³ ³ + ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + + + GRAFX 2.00 á96.5% + + - MANUEL D'UTILISATION - + + + ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + ³ SOMMAIRE ³ + ³ ÍÍÍÍÍÍÍÍ ³ + ³ ³ + ³ - Pr‚sentation ³ + ³ - Equipement requis ³ + ³ - Fichiers de configuration ³ + ³ - Options disponibles ³ + ³ - Let's talk about $$$, baby ³ + ³ - Astuces de dessin ³ + ³ - ProblŠmes/Astuces g‚n‚rales/Questions ³ + ³ fr‚quentes (FAQ) ³ + ³ ³ + ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + + + + +Pr‚sentation: +ÍÍÍÍÍÍÍÍÍÍÍÍÍ + + Ce programme a ‚t‚ con‡u pour pouvoir dessiner des images en 256 couleurs + dans un trŠs grand nombre de r‚solutions (en fait, il y en a pour l'instant + 60 avec quelques-unes venant du monde Amiga). + Personne ne peut contester que la majeure partie des superbes GFX de la + "ScŠne" ont ‚t‚ dessin‚s sur Amiga. Mais ces GFX sont dans des r‚solutions + diff‚rentes des modes PC habituels. Alors nous avons voulu cr‚er le premier + logiciel de dessin sur PC qui pourrait visualiser ces images, et qui + pourrait bien s–r vous permettre de dessiner les v“tres dans le mode vid‚o + que vous voulez. + + Ce logiciel a ‚t‚ pr‚sent‚ pour la premiŠre … fois la Wired'96 o— il a eu + un gros succŠs (bien plus que ce … quoi nous nous attendions), alors nous + esp‚rons que vous l'aimerez aussi. + + Il consiste en un certain nombre d'outils de dessin, d'effets et de menus. + Tous les effets fonctionnent avec n'importe quel outil de dessin. + + Sachez que ce logiciel a ‚t‚ cr‚‚ pour VOUS, utilisateurs de PC qui enviez + les possesseurs d'Amiga pour les fantastiques logiciels de dessin dont ils + disposent. Ce logiciel n'a pas la pr‚tention de remplacer les meilleurs + programmes de dessin Amiga, mais tente modestement de combler le gouffre + qu'il y a entre les logiciels PC et Amiga dans le domaine du dessin bitmap. + Si vous rˆvez d'une option trŠs utile que nous n'ayons pas encore pr‚vue, + n'h‚sitez pas … nous en faire part. Si nous la jugeons utile ‚galement, et + surtout s'il est possible de l'inclure dans le programme :), nous l'y + mettrons dŠs que possible. + + + + +Equipement requis: +ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ + + Pour pouvoir utiliser GrafX2, vous aurez besoin de: + + - un PC (386DX ou sup‚rieur), + - DOS 5 ou sup‚rieur (‡a marche peut-ˆtre avec le DOS 3.1 mais on ne se + rappelle pas quelles sont les fonctions de l'INT 21h que nous utilisons), + - une carte vid‚o compatible VGA (une carte VLB ou PCI est fortement recom- + mand‚e), + - une souris … 2 boutons (et son gestionnaire), + - 3 Megaoctets de RAM (‡a peut marcher avec moins si vous utilisez le cache + disque de DOS4GW ou bien celui de Windows :/). + + Mais pour une utilisation plus efficace, vous aurez besoin de: + + - au moins un 486DXý66 (pour augmenter la vitesse globale), + - au moins 8 Mo de RAM pour capturer de trŠs grosses brosses et pour uti- + liser le multi-undo, + - une carte vid‚o compatible VESA 1.2 (pour acc‚der … plus de modes vid‚o). + + + + +Fichiers de configuration: +ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ + + GrafX2 n‚cessite deux fichiers pour stocker sa configuration: 'GFX2.INI' + et 'GFX2.CFG'. + + GFX2.INI: + ÄÄÄÄÄÄÄÄÄ + + Ce fichier contient les paramŠtres d‚finis dans le menu de configuration + (settings) ainsi que quelques autres. Vous pouvez ‚diter ce fichier … + l'aide d'un ‚diteur de texte ASCII standard. + Lorsque vous cliquez sur Reload (recharger) dans le menu des "settings", + toutes les donn‚es contenues dans ce fichier sont restaur‚es. Lorsque vous + cliquez sur Save (sauvegarder) ou bien lorsque vous quittez le programme + alors que l'option Auto-save (sauvegarde automatique) est enclench‚e, tous + les paramŠtres actuels sont ‚crits (mis … jour) dans ce fichier. + + Si vous avez corrompu ce fichier et que vous n'arrivez pas … corriger le + problŠme, alors effacez-le et lancez GFXCFG.EXE. I cr‚era automatiquement + un fichier d'initialisation par d‚faut lorsque celui-ci est absent. + + + GFX2.CFG: + ÄÄÄÄÄÄÄÄÄ + + Ce fichier contient la configuration du clavier ainsi que l'‚tat des + variables du programme suivantes: + þ modes vid‚o + þ tables de "shade" + þ stencil (pochoir) + þ masque + þ d‚grad‚s + + Toutes ces variables sont enregistr‚es lorsqu'on clique sur le bouton + Save (sauvegarder) dans le menu de configuration ou bien lorsqu'on sort du + programme avec l'option Auto-save (sauvegarde automatique) enclench‚e. + Cependant, lorsque vous cliquez sur Reload (recharger) dans le menu des + "settings", seul l'‚tat de chaque mode vid‚o est restaur‚. + + Note: le fichier GFX2_FRA.CFG est un fichier de configuration par d‚faut + pour les claviers AZERTY. Si vous utilisez un clavier AZERTY, vous devriez + remplacer le fichier GFX2.CFG par GFX2_FRA.CFG. + + Important: … partir de la version 2.00 á95.5%, les fichiers .CFG auront + une compatibilit‚ ascendante. Ceci signifie que vous pourrez r‚cup‚rer la + majeure partie de leur contenu d'une version … l'autre en copiant votre + ancien fichier .CFG dans le r‚pertoire de votre nouvelle version de GrafX2 + et en lan‡ant GFXCFG.EXE. En effet, ce programme convertira votre ancien + fichier afin qu'il soit utilisable par la nouvelle version de GrafX2. + Mais, copier un fichier .CFG d'une version ant‚rieure … la version 95.5% + ne marchera pas. De plus, (je ne vois pas pourquoi vous le feriez mais...) + copier un fichier .CFG r‚cent dans une version plus ancienne ne devrait + pas fonctionner non plus. + + + Note: Nous vous recommandons de ne pas modifier les touches affect‚es … + l'‚mulation de la souris dans le programme GFXCFG car les valeurs que vous + donneriez pourraient interf‚rer avec les raccourcis utilis‚s dans les menus. + + + + +Options disponibles: +ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ + + Les diff‚rentes options disponibles dans GrafX2 seront list‚es et + d‚taill‚es ci-dessous. Elles seront d‚crites comme suit: + + ÉÍÍÍÍËÍÍÍÍËÍúúúÍ» ÉÍÍÍÍ» + º 1 º 3 º º Les boutons triangulaires º1 / º + º º º º seront d‚taill‚s comme ‡a: º / 2º + ÌÍÍÍÍÎÍÍÍÍÎÍúúú͹ ÈÍÍÍͼ + º 2 º 4 º º + º º º º + ÈÍÍÍÍÊÍÍÍÍÊÍúúúͼ + + + 1 - Pinceaux + 2 - Ajuster l'image / Effets sur l'image + 3 - Bouton Dessin … la main + 4 - Courbes de B‚zier (Splines) + 5 - Lignes + 6 - A‚rographe (Spray) + 7 - Remplissage (Flood-fill) / Remplacement de couleur + 8 - Polyg“nes / Polyformes + 9 - Polyg“nes/Polyformes plein(e)s + 10 - Rectangles vides + 11 - Rectangles pleins + 12 - Cercles/Ellipses vides + 13 - Cercles/Ellipses plein(e)s + 14 - Rectangles avec d‚grad‚ + 15 - Menu de d‚grad‚ + 16 - SphŠres / Ellipses avec d‚grad‚ + 17 - Prise de brosse / Restauration + 18 - Prise de brosse par polyforme (lasso) / Restauration + 19 - Effets sur la brosse + 20 - Modes de dessin + 21 - Texte + 22 - Mode Loupe / Menu + 23 - Pipette / Inverser les couleurs + 24 - Taille de l'‚cran / R‚solution de s‚curit‚ + 25 - Page de brouillon / Copier vers le brouillon + 26 - Sauver l'image / Sauvegarde automatique + 27 - Charger une image / Recharger + 28 - ParamŠtres g‚n‚raux (Settings) + 29 - Effacer l'image + 30 - Aide / Statistiques + 31 - Oops (D‚faire/Refaire) + 32 - D‚truire la page courante + 33 - Quitter le programme + 34 - Menu de palette + 35 - D‚placer la palette … gauche / droite + 36 - Fenˆtre de palette + 37 - Cacher le menu + + + + Quand vous utiliserez n'importe quel outil de dessin, un clic gauche + dessinera avec la couleur principale, tandis qu'un clic droit dessinera avec + la couleur de fond. + + Lorsque des boŒtes de dialogue apparaŒtront … l'‚cran, Cancel (ou No) sera + toujours ‚mul‚ par la touche , et OK (ou Yes) par . + + Dans les diff‚rents menus, les titres sur les boutons contenant une lettre + soulign‚e peuvent ˆtre ‚mul‚s en tapant cette lettre au clavier. + + Dans quelques menus, vous pouvez s‚lectionner un bloc de couleurs dans la + palette. Cela signifie que vous pouvez cliquer sur une couleur et d‚placer + la souris vers une autre en maintenant le bouton appuy‚ pour s‚lectionner + un bloc de couleurs. + + Vous pouvez d‚placer une fenˆtre pour rendre visible l'image qui est + derriŠre en cliquant en haut de la fenˆtre (sur le titre) et en maintenant + le bouton de la souris enfonc‚ tout en la d‚pla‡ant. + + + + 1 - Pinceaux: + ÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + Affiche un menu ou vous pouvez choisir la forme de votre pinceau. + + Les pinceaux sont rang‚s par famille. Vous pouvez voir quelques + pinceaux de la mˆme famille mais avec des tailles diff‚rentes. Il y a au + moins un pinceau de chaque famille affich‚ dans ce menu. + Voici la liste de toutes les diff‚rentes familles de pinceaux: + + ÛÛÛÛÛÛÛ ÛÛÛ Û Û Û Û Û Û Û Û + ÛÛÛÛÛÛÛ ÛÛÛÛÛ Û Û Û Û Û Û ÛÛÛ Û Û + ÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛ Û Û Û Û Û Û Û Û ÛÛÛÛÛ Û + ÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛ Û Û Û Û Û Û ÛÛÛÛÛÛÛ + ÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛ Û Û Û Û Û Û Û Û ÛÛÛÛÛ Û Û Û + ÛÛÛÛÛÛÛ ÛÛÛÛÛ Û Û Û Û Û Û ÛÛÛ + ÛÛÛÛÛÛÛ ÛÛÛ Û Û Û Û Û Û Û Û Û + + Carr‚ Disque Carr‚ Disque Losange Al‚atoire + tram‚ tram‚ + _______________________________________________________________ + + Û Û Û Û Û Û + Û Û Û Û Û Û + Û Û Û Û Û Û + ÛÛÛÛÛÛÛ Û Û Û Û ÛÛÛÛÛÛÛ + Û Û Û Û Û Û + Û Û Û Û Û Û + Û Û Û Û Û Û + + Barre Barre Slash Anti- Croix X Croix + + horiz. verticale slash + + Les 3 derniers pinceaux dans le menu appartiennent … la famille + "divers" et leur taille ne peut pas ˆtre modifi‚e. + + + Clic droit: + ============> + + Transforme votre brosse actuelle en pinceau. En fait, c'est une + "monochromisation" de la brosse. C'est-…-dire que toutes les couleurs de + la brosse qui ne sont pas la couleur de fond passeront de la mˆme + couleur que la couleur principale. Mais cette option ne modifie pas la + brosse: vous n'avez qu'… cliquer avec le bouton droit sur une des + boutons "Get brush" pour r‚cup‚rer la brosse en couleur. + + + Note: Lorsque vous appuyez (pas dans le menu) sur la touche + (valeur par d‚faut), le pinceau actuel devient le plus petit membre de la + famille "Disque": c'est-…-dire 1 pixel. + + + + 2 - Ajuster l'image / Effets sur l'image: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + Vous permet de d‚placer ("scroller") l'image pour recentrer votre + graphe par exemple. + Toute partie du dessin qui sort d'un cot‚ de l'image revient par le + c“t‚ oppos‚. + + Ceci est consid‚r‚ comme ‚tant de la famille des outils de dessin. + + + Clic droit: + ============> + + *** Pas encore impl‚ment‚ *** + + + + 3 - Bouton Dessin … la main: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + Selectionne le mode dessin … la main actuel comme outil de dessin + actif. Il y a 3 modes de dessin … la main: + + - Dessin continu: Lorsque vous d‚placez le curseur de la souris, le + pinceau est r‚guliŠrement appliqu‚ sur l'image, reliant les + diff‚rents points de l'‚cran sur lesquels vous ˆtes pass‚s. Cet + outil de dessin autorise le changement de la couleur principale et + de la couleur de fond durant son utilisation. + + - Dessin discontinu: Lorsque vous d‚placez la souris, le pinceau est + appliqu‚ … la position actuelle de la souris … chaque VBL (balayage + vertical de l'‚cran). Cet outil de dessin autorise le changement de + la couleur principale et de la couleur de fond durant son + utilisation. + + - Dessin point par point: Le pinceau est simplement appliqu‚ … la + position o— vous avez cliqu‚ en premier. + + + Clic droit: + ============> + + Permute les diff‚rents modes de dessin … la main, et active en mˆme + temps l'outil de dessin … la main. + + + + 4 - Courbes de B‚zier (Splines): + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + Selectionne le mode de courbe courant comme outil de dessin actif. + Il y a deux modes de courbes diff‚rents: + + - Courbes … 4 points de contr“le: D‚finissez la ligne de base comme + une ligne classique; puis d‚placez, avec le bouton gauche de la + souris, les points de contr“le internes afin de choisir la forme de + la courbe. Quand la courbe a la forme que vous d‚sirez, cliquez sur + le bouton droit de la souris pour la tracer d‚finitivement. + + - Courbes … 3 points de contr“le: Fonctionne comme d‚crit ci-dessus, + mais vous n'aurez qu'un seul point de contr“le interne … placer. + De plus, la courbe sera trac‚e juste aprŠs avoir plac‚ ce point. + + + Clic droit: + ============> + + Permute les diff‚rents modes de courbes, et active en mˆme temps + l'outil de dessin de courbes. + + + + 5 - Lignes: + ÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + Selectionne le mode de dessin de lignes actuel comme outil de dessin + actif. Il y a 2 modes de dessin de lignes: + + - Lignes classiques: En cliquant une premiŠre fois sur l'image, vous + d‚finirez de d‚but de la ligne. Maintenez le bouton appuy‚ pour + placer la fin de la ligne; et relƒchez le bouton pour tracer la + ligne. + + - Lignes reli‚es: Fonctionne de la mˆme maniŠre que pr‚c‚demment, mais + la fin d'une ligne deviendra automatiquement le d‚but de la + suivante. Lorsque vous voudrez arrˆter l'enchƒinement de lignes, + utilisez le bouton oppos‚ de la souris. "Le bouton oppos‚" signifie + que si vous avez commenc‚ … tracer les lignes avec le bouton gauche + (couleur principale), il faudra interrompre le traitement avec le + bouton de droite; et r‚ciproquement. + + - Lignes concentriques: lors du premier clic sur l'image, vous + d‚finirez le centre des lignes. En r‚alit‚, le centre est d‚fini + par la position de la souris lorsque vous relƒchez son bouton. + Ensuite vous pouvez dessiner des lignes partant du centre vers la + position actuelle de la souris en cliquant. Pour arrˆter de dessiner + des lignes concentriques, utilisez le bouton oppos‚ de la souris. + Cet outil de dessin autorise le changement de la couleur principale + et de la couleur de fond durant son utilisation. + + + Clic droit: + ============> + + Permute les diff‚rents modes de dessin de lignes, et active en mˆme + temps l'outil de dessin de lignes. + + + + 6 - A‚rographe (Spray): + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + Selectionne l'a‚rographe comme outil de dessin actif. Cet outil de + dessin autorise le changement de la couleur principale et de la + couleur de fond durant son utilisation. + + + Clic droit: + ============> + + Affiche le menu de configuration de l'a‚rographe: + + - Size (Taille): D‚finit le diamŠtre du cercle dans lequel l'a‚ro- + graphe fonctionnera. + + - Delay (D‚lai): D‚finit le nombre de VBL (balayage vertical de + l'‚cran) qui seront attendus entre deux jets (cycles) de l'a‚ro- + graphe. + + - Mode: D‚finit si vous d‚sirez utiliser un a‚rographe monochrome ou + multicolore. + + - Mono-flow (flux en monochrome): D‚finit le nombre de fois que le + pinceau sera al‚atoirement appliqu‚ dans le cercle de l'a‚rographe + … chaque jet (cycle). + + - Palette: Un clic gauche sur une couleur de la palette vous permettra + de voir en quelle quantit‚ elle sera utilis‚e dans le flux multi- + colore, et de la modifier en utilisant la jauge sur la droite. Si le + flux de cette couleur ‚tait ‚gal … 0, il sera mis … la valeur + "Init". Un clic droit sur une couleur fera automatiquement passer sa + quantit‚ … 0, ce qui revient … la supprimer du flux multicolore. + + - Clear (Effacer): Supprime toutes les couleurs du flux multicolore. + En fait, cela place une valeur nulle dans l'utilisation de chacune + des couleurs. + + - Init: Ceci vous permet de d‚finir une valeur qui sera automatique- + ment appliqu‚e aux couleurs ayant un flux nul lorsque vous cliquerez + dans la palette … l'aide du bouton gauche. Cette option permet de + d‚finir plus rapidement un ensemble de couleurs. + + - +1,-1,x2,ö2: Modifie la valeur de toutes les couleurs selectionn‚es + (et seulement celles-ci). + + + + 7 - Remplissage (Flood-fill) / Remplacement de couleur: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + S‚lectionne le remplisseur comme outil de dessin actif. + Le remplisseur, comme n'importe quel outil de dessin, sera affect‚ par + tous les effets. + + Remarquez que seule la partie visible de l'image sera remplie (de mˆme + que pour tous les autres outils de dessin, le remplissage n'affecte que + la partie visible du dessin; ceci ‚vitant des effets ind‚sirables et non + contr“l‚s par l'utilisateur). + + + Clic droit: + ============> + + S‚lectionne le remplacement de couleur comme outil de dessin. + + Chaque rŠgle a ses exceptions et la rŠgle ‚nonc‚e ci-dessus n'y d‚roge + pas. Cet outil est en effet le seul … n'ˆtre affect‚ par aucun effet (… + l'exception du Stencil) et … pouvoir ‚galement modifier les parties non + visibles de l'image. + Le but de cet outil ‚tant de remplacer toutes les occurences d'une + couleur dans l'image par une autre, il aurait ‚t‚ dommage de se limiter + … modifier uniquement la partie visible de l'image. + + + + 8 - Polyg“nes / Polyformes: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + S‚lectionne les polyg“nes comme outil de dessin actif. + + Ceci fonctionne exactement comme les lignes reli‚es en reliant les + extrˆmit‚s quand vous avez termin‚. + + + Clic droit: + ============> + + S‚lectionne les polyformes comme outil de dessin actif. + + Cet outil fonctionne comme une combinaison du dessin … la main et des + lignes reli‚es. + Si vous maintenez le bouton de la souris press‚, vous dessinerez comme + si vous ‚tiez en mode de dessin … la main. Et, si vous relƒchez le + bouton de la souris, cela fonctionnera comme les lignes reli‚es. + + Cliquez sur le bouton de la souris oppos‚ (i.e.: cliquez … droite si + vous avez commenc‚ … dessiner avec le bouton gauche de la souris, et + vice versa) pour terminer l'op‚ration. Les deux extr‚mit‚s seront + reli‚es automatiquement. + + + + 9 - Polygones/Polyformes plein(e)s: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Fonctionnent exactement de la mˆme maniŠre que les polyg“nes et poly- + formes ci-dessus, mais remplissent l'int‚rieur des formes ainsi d‚finies. + + + + 10 - Rectangles vides: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + N'importe quel clic: + ====================> + + Selectionne les rectangles vides comme outil de dessin actif. + + Placez le coin d'un rectangle. Maintenez le clic pour d‚placer le coin + oppos‚ et relachez le bouton de la souris pour le placer d‚finitivement. + + + + 11 - Rectangles pleins: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + N'importe quel clic: + ====================> + + S‚lectionne les rectangles pleins comme outil de dessin actif. + + Fonctionne comme un rectangle vide. + + + + 12 - Cercles/Ellipses vides: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + S‚lectionne les cercles vides comme outil de dessin actif. + + Positionnez le centre du cercle et maintenez le bouton de la souris + pour choisir son rayon. + + + Clic droit: + ============> + + S‚lectionne les ellipses vides comme outil de dessin actif. + + Positionnez le centre du cercle et maintenez le bouton de la souris + pour choisir ses dimensions. + + + + 13 - Cercles/Ellipses plein(e)s: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Fonctionne comme les cercles et les ellipses vides. + + + + 14 - Rectangles avec d‚grad‚: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + *** Pas encore impl‚ment‚ *** + + + + 15 - Menu de d‚grad‚: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + N'importe quel clic: + ====================> + + Ouvre une fenˆtre dans laquelle vous pouvez d‚finir la fa‡on dont les + d‚grad‚s sont trait‚s. + Les diff‚rentes sections de ce menu sont: + + - Direction (flŠche): Change le sens du d‚grad‚. + + - M‚thode de transition: Permute parmi les trois m‚thodes suivantes: + - Pas de transition + - Transition de base + - Transition am‚lior‚e + + - Mix (M‚lange): M‚lange le d‚grad‚ avec un facteur al‚atoire plus ou + moins important. + + - Palette: Selectionnez un intervale de couleurs pour constituer un + d‚grad‚. + + - Ascenseur d'index: D‚finit le d‚grad‚ courant parmi un ensemble de + 16 m‚moris‚s. + + + + 16 - SphŠres / Ellipses avec d‚grad‚: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + S‚lectionne les sphŠres comme outil de dessin actif. + + Positionnez le centre de la sphŠre et maintenez le bouton de la souris + pour choisir son rayon. Ensuite placez la source de l'‚clairage. + + + Clic droit: + ============> + + S‚lectionne les ellipses avec d‚grad‚ comme outil de dessin actif. + + *** La version actuelle de cet outil n'est pas la bonne, donc *** + *** nous expliquerons son fonctionnement quand elle sera achev‚e. *** + + + Si vous tracez une sphŠre ou une ellipse d‚grad‚e avec le bouton droit + de la souris, le r‚sultat sera la mˆme figure remplie avec la couleur de + fond. + + + + 17 - Prise de brosse / Restauration: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + D‚marre une prise de brosse. + + Cliquez sur un coin du rectangle contenant la brosse puis maintenez le + clic pour d‚finir le coin oppos‚ du rectangle. Relachez le bouton de la + souris pour prendre la brosse. Effectuer cette op‚ration avec le bouton + droit de la souris effacera la zone dans laquelle la brosse a ‚t‚ prise + avec la couleur de fond. + + + Clic droit: + ============> + + Restaure l'ancienne brosse. + + + + 18 - Prise de brosse par polyforme / Restauration: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + Capture une brosse de forme quelconque en d‚finissant un "polyforme" + (veuillez vous r‚ferer … la section 8 pour plus d'explications). + + + Clic droit: + ============> + + Restaure l'ancienne brosse (pareil que ci-dessus). + + + + 19 - Effets sur la brosse: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + N'importe quel clic: + ====================> + + Affiche un menu dans lequel les options suivantes sont disponibles: + + - X: Inversion selon X (sym‚trie par rapport … (Oy)). + + - Y: Inversion selon Y (sym‚trie par rapport … (Ox)). + + - Rotate by 90ø: Effectue sur la brosse une rotation de 90 degr‚s. + + - Rotate by 180ø: Effectue sur la brosse une rotation de 180 degr‚s. + + - Rotate by any angle (Rotation de n'importe quel angle): Engendre une + op‚ration interactive qui permet de faire tourner la brosse. Pour + cela, commencez par placer le centre de rotation avec le bouton + gauche de la souris (si, … ce moment-l…, vous appuyez sur le bouton + droit, l'op‚ration sera annul‚e). Ensuite vous pouvez d‚finir + l'angle de rotation autant de fois que vous le voulez en d‚pla‡ant + la souris et en cliquant avec le bouton gauche. Puis vous validerez + avec le bouton droit lorsque vous serez satisfait. + Pendant ce temps, vous pouvez appuyer sur les 8 chiffres ext‚rieurs + du pav‚ num‚rique pour d‚finir des angles multiples de 45ø: + 135ø 90ø 45ø + \ | / + '7' '8' '9' + 180ø -'4' '6'- 0ø + '1' '2' '3' + / | \ + 225ø 270ø 315ø + + - Stretch (Etirement): Engendre une op‚ration interactive qui permet + d'‚tirer la brosse. Pour cela, commencez par placer le coin haut- + gauche de la brosse avec le bouton gauche de la souris (si, … ce + moment-l…, vous appuyez sur le bouton droit, l'op‚ration sera + annul‚e). Ensuite vous pouvez placer le coin oppos‚ autant de fois + que vous le voulez, puis vous validerez avec le bouton droit lorsque + vous serez satisfait. Si vous placez ce point … des coordonn‚es + inf‚rieures … celles du point de d‚part, la brosse sera invers‚e. + Pendant ce temps, vous pouvez appuyer sur les touches suivantes dont + voici les effets: + 'D' : double la brosse en X et en Y + 'H' : r‚duit la brosse de moiti‚ en X et en Y + 'X' : double la brosse en X + 'Shift+X': r‚duit la brosse de moiti‚ en X + 'Y' : double la brosse en Y + 'Shift+Y': r‚duit la brosse de moiti‚ en Y + 'N' : restaure la taille normale de la brosse (peut se + r‚v‚ler utile car c'est le seul moyen d'annuler) + + - Distort (D‚formation): + *** Pas encore impl‚ment‚ *** + + - Outline (Contours): + Cette option permet de dessiner les contours de la brosse avec la + couleur principale (Fore-color). + + - Nibble (Grignotter): + Cette option "grignotte" les contours de la brosse. C'est en quelque + sorte l'effet inverse de l'option Outline. + + - Recolorize: Modifie la brosse de fa‡on … ce qu'elle ressemble … + l'aspect qu'elle aurait dans la page de brouillon, en utilisant la + palette courante. + + - Get brush colors: TransfŠre les couleurs de la page de brouillon + utilis‚es par la brosse, dans la palette courante. + + - Brush handle: Vous permet de choisir o— placer la prise (poign‚e) de + la brosse. + + - Load / Save: charger ou sauvegarder une brosse. + + + + 20 - Modes de dessin: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Ce bouton ouvre un menu dans lequel vous pouvez activer/d‚sactiver les + diff‚rents modes de dessin. (Les touches [F1]-[F9] correspondent aux 9 + boutons) + + Dans ce menu, le bouton "All off" (tout ‚teint) d‚sactive tous les modes + de dessin. La touche [Suppr] est le raccourci clavier pour ce bouton. + + Le bouton "Feedback" sert uniquement pour les modes "Shade", "Quick- + shade", "Smooth" et "Transparence". Lorsqu'il est activ‚, il indique que + l'‚tat _actuel_ de l'image doit ˆtre pris en compte pour l'effet au lieu + de l'‚tat dans lequel ‚tait l'image lorsqu'on a click‚ pour commencer … + tracer. Le mieux, comme bien souvent, est que vous testiez par vous-mˆme + avec et sans Feedback pour constater la diff‚rence. + + Les autres boutons sont les suivants: + + + * Mode Shade (Ombrage) / Menu: + ------------------------------ + + Cet effet consiste … incr‚menter ou d‚cr‚menter le num‚ro de la couleur + dans un ensemble d‚fini par l'utilisateur. Cela montre sa vraie + dimension lorsque l'ensemble de couleurs est un d‚grad‚. Alors, vous + pouvez travailler sur une partie de l'image o— les couleurs appartiennent + … ce mˆme ensemble sans avoir … changer la couleur de votre pinceau + syst‚matiquement. + Vous pouvez choisir d'incr‚menter ou de d‚cr‚menter la couleur en + cliquant sur le bouton gauche ou droit de la souris lorsque vous dessinez. + Si vous cliquez sur une couleur qui n'appartient pas … l'ensemble de + couleurs, elle restera inchang‚e. + + Clic gauche: + ============> + + Active/D‚sactive le mode Shade. + + + Clic droit: + ============> + + Ouvre un menu dans lequel vous pouvez d‚finir une table de shades + parmi les 8 m‚moris‚es par le programme. + Les diff‚rentes sections de ce menu sont: + + - Palette: Vous pouvez d‚finir dans celle-ci les blocs de couleurs … + ins‚rer dans la table des shades. + + - Scroller: Sert … changer de table de shades. + + - Zone de d‚finition de table de Shades: Les 512 cases fournies + sont largement suffisantes pour d‚finir les diff‚rents shades puisque + chacune des 256 couleurs de la palette ne peut ˆtre pr‚sente qu'une + seule fois dans chaque table. + + - Une fenˆtre (celle situ‚e en haut … droite) qui vous permet de + visualiser les diff‚rents shades d‚finis dans la table actuelle. + + - Copy (copier): Copie le contenu actuel de la table dans un buffer. + (Lors de l'ouverture du menu, la table courante est automatiquement + rang‚e dans le buffer). + + - Paste (coller): Copie le contenu du buffer ci-dessus dans la table + actuelle. + + - Clear (tout effacer): Permet de r‚initialiser la table de "shades". + + - Insert (ins‚rer): Sert … ins‚rer le bloc s‚lectionn‚ dans la palette + … la position du curseur dans la table des shades. + SI vous clickez avec le bouton gauche de la souris sur ce bouton ALORS + SI un bloc de plus d'une case est s‚lectionn‚ dans la table ALORS + Il est effac‚ puis on insŠre le bloc d‚fini dans la palette. + SINON + On insŠre le bloc d‚fini dans la palette juste avant la case + s‚lectionn‚e. + FIN SI + SINON + Le bloc d‚fini dans la palette est ins‚r‚ en ‚crasant les couleurs + suivant le d‚but du bloc s‚lectionn‚ dans la table. + FIN SI + + - Delete (effacer): Supprime le bloc s‚lectionn‚ dans la table. + + - Blank (vide): Suit l'algorithme suivant: + SI vous clickez avec le bouton gauche de la souris sur ce bouton ALORS + On remplace le bloc s‚lectionn‚ dans la table par des cases vides + SINON + SI un bloc de plus d'une case est s‚lectionn‚ dans la table ALORS + Ins‚rer une case vide … gauche et une case vide … droite du bloc + (ceci sert … isoler un shade rapidement) + SINON + Ins‚rer une case vide … gauche de la case s‚lectionn‚e + FIN SI + FIN SI + + - Invert (inverser): Inverse l'ordre du bloc s‚lectionn‚ dans la + table. + + - Swap (‚changer): Permet de d‚placer un bloc (cela l'‚change avec ce + qu'il y a l… ou veut le d‚placer). + + - Undo (d‚faire): Permet d'annuler la derniŠre modification de la + table. + + - Les 2 num‚ros qui s'affichent … droite de ces boutons sont: + (en haut)- le num‚ro de la couleur s‚lectionn‚e dans la palette si + une seule est s‚lectionn‚e. + (en bas) - le num‚ro de la couleur contenue dans la case de la table + de shades si cette case est la seule s‚lectionn‚e. + + - Le bouton de "mode" affiche 3 ‚tats diff‚rents: + "Normal": + OpŠre … l'int‚rieur de l'intervalle de couleurs et sature … ses + bordures. + "Loop" (Boucle): + Boucle lorsque les bornes de l'intervalle sont d‚pass‚es. + "No saturation": + Ne sature pas aux bornes de l'intervalle si elles sont d‚pass‚es. + Si le Pas (voir plus bas) est de 1, cette option fait exactement la + mˆme chose que le mode Normal. + + - Set/Disable (placer un masque): Si vous voulez d‚finir plusieurs + shades dans une mˆme table mais que vous souhaiteriez qu'ils ne soient + pas tous effectifs en mˆme temps, vous pouvez en masquer certains ce + qui aura pour effet qu'ils seront interpr‚t‚s comme des cases vides. + Pour ce faire, s‚lectionnez un bloc dans la table des shades et + clickez sur "Set". Le bloc sera alors soulign‚ d'un trait blanc; ce + qui signifie qu'il est d‚sactiv‚. + + - Clear/Enable (enlever le masque): fait exactement l'inverse du + bouton pr‚c‚dent. + + - Step (pas): D‚finit un pas d'incr‚mentation du shade. Plus le pas + est grand et plus vous parcourerez rapidement les couleurs du shade. + Par exemple: si le pas est de 2 et que vous avez d‚fini un shade avec + les couleurs 0,1,4,5,9 et que vous clickez sur un pixel de couleur 1, + il prendra alors la couleur 5 qui est 2 cases plus loin dans la table. + + (Nous sommes d‚sol‚s pour ces consid‚rations techniques assez + lointaines d'une vision p–rement artistique; mais sachez que cet effet + est vraiment trŠs utile et qu'il est pr‚f‚rable que vous compreniez son + fonctionnement si vous voulez en profiter pleinement). + + + + * Mode Quick-shade (Ombrage) / Menu: + ------------------------------------ + + Ce mode de dessin a … peu prŠs le mˆme effet que le mode Shade si ce + n'est qu'il est beaucoup plus rapide … configurer mais un peu moins + puissant. + Lorsque vous dessinez sur une couleur de l'image qui se situe entre la + couleur principale (fore-color) et la couleur de fond (back-color) dans la + palette, la couleur tend … se rapprocher de la fore-color (suivant le pas + d‚fini) si l'on dessine avec le bouton gauche de la souris, ou bien tend + vers la back-color si l'on dessine avec le bouton droit. + + Clic gauche: + ============> + + Active/D‚sactive le mode Quick-shade. + + + Clic droit: + ============> + + Ouvre un menu avec quelques paramŠtres qui repr‚sentent exactement la + mˆme chose que dans le menu du mode Shade. Ces paramŠtres sont le pas et + le mode de bouclage/saturation (normal, loop, no saturation). + + + + * Mode Stencil (Pochoir) / Menu: + -------------------------------- + + C'est utilis‚ pour empˆcher la modification de certaines couleurs si + vous essayez de dessiner sur elles. L'application principale du stencil + est lorsque vous voulez remplacer une ou plusieurs couleurs par une autre. + + Clic gauche: + ============> + + Active/D‚sactive le mode Stencil. + + Clic droit: + ============> + + Ouvre un menu dans lequel vous pouvez d‚finir un stencil. + Les diff‚rentes sections de ce menu sont: + + - Clear (Effacer): D‚protŠge toutes les couleurs. + + - Invert (Inverser): Les couleurs qui ‚taient prot‚g‚es ne le sont + plus et vice versa. + + - Palette: Selectionnez les couleurs qui doivent ˆtre prot‚g‚es avec + le bouton gauche de la souris ou d‚prot‚gez-les avec le bouton + droit. + + + + * Mode Masque / Menu: + --------------------- + + Cet effet aurait pu ˆtre appel‚ "True stencil" (vrai pochoir) car il + protŠge des parties de l'image au lieu de prot‚ger des couleurs. Les + couleurs que vous s‚lectionnez repr‚sentent les pixels dans la page de + brouillon, correspondant aux pixels dans la page actuelle, que vous ne + voulez pas modifier. + Par exemple, dessinez une simple figure blanche sur un fond noir dans la + page de brouillon. Puis, s‚lectionnez la couleur noire dans le menu du + mode Masque. Lorsque vous dessinerez dans la page actuelle, seulement les + pixels correspondant aux pixels blancs (non-noirs) dans la page de + brouillon seront modifi‚s. + + Clic gauche: + ============> + + Active/D‚sactive le mode Masque. + + Clic droit: + ============> + + Ouvre un menu dans lequel vous pouvez d‚finir les couleurs du masque. + Ce menu fonctionne de la mˆme fa‡on que celui du Stencil. Veuillez + donc vous r‚f‚rer au paragraphe consacr‚ au Stencil pour savoir comment + utiliser ce menu. + + + + * Mode Grille / Menu: + --------------------- + + C'est utile pour accrocher le curseur aux points de croisement d'une + grille. C'est g‚n‚ralement utilis‚ pour dessiner une grille avant de + dessiner des sprites de la mˆme taille tels que des "tiles" ou une fonte, + ou bien pour dessiner des figures ou prendre des brosses avec des + dimensions multiples du pas de la grille.'); + + Clic gauche: + ============> + + Active/D‚sactive le mode Grille. + + + Clic droit: + ============> + + Ouvre un menu dans lequel vous pouvez d‚finir les paramŠtres de la + grille. Ces paramŠtres sont: + + - X,Y: Pas de la grille. + + - dX,dY: D‚calages de la grille. + + + + * Mode Trame (Passoire) / Menu: + ------------------------------- + + Cet effect permet, en d‚finissant un motif, de dessiner seulement sur + des points particuliers de l'image. + Si vous ˆtes un dessinateur Manga, vous pourriez trouver ‡a utile pour + dessiner des ombres avec diff‚rentes trames ou bien des transitions de + couleurs. + + Clic gauche: + ============> + + Active/D‚sactive le mode Trame. + + + Clic droit: + ============> + + Ouvre un menu dans lequel vous pouvez d‚finir les paramŠtres des + trames. Ce menu est constitu‚ de: + + - Zone de dessin 16x16: Vous pouvez d‚finir une trame dedans (clic + gauche => pixel blanc / clic droit => pixel noir). + Tous les pixel blancs indiquent que lorsque vous dessinerez, des + pixels seront appliqu‚es sur l'image aux positions correspondantes + tandis que des pixels noirs n'entrŒneront aucun affichage: les + points blancs correspondent aux "trous de la passoire". + + - 12 trames par d‚faut: Elles peuvent ˆtres recopi‚es vers la zone de + dessin (16x16). + + - "Transfer to brush" (transf‚rer vers la brosse): Copie la trame vers + la brosse (pixels blancs => couleur principale / pixels noirs => + couleur de fond). + + - "Get from brush" (r‚cup‚rer … partir de la brosse): Place la brosse + dans la zone de dessin (couleur de fond => pixels noirs / les autres + => pixels blancs). + + - 4 flŠches de d‚placement (scrolling): D‚placent la trame dans la + zone de dessin. + + - 4 flŠches de dimensionnement: D‚finissent les dimensions de la + trame. + + - Valeur par d‚faut (carr‚ noir ou blanc): Indique quelle couleur doit + ˆtre ins‚r‚e quand vous augmentez les dimensions de la trame. + + - "Clear" (Effacer): Remplit toute la trame avec la valeur par d‚faut + (voir ci-dessus). + + - "Invert" (Inversion): Il ... inverse :) ... les pixels noirs et + blancs. + + + + * Mode Transparence (Colorize) / Menu: + -------------------------------------- + + Cela permet de m‚langer les couleur(s) du pinceau (brosse) avec les + couleurs de l'image. C'est utilis‚ pour faire des effets de transparence + comme avec de l'aquarelle. + + Clic gauche: + ============> + + Active/D‚sactive le mode Transparence. + + + Clic droit: + ============> + + Ouvre un menu dans lequel vous pouvez d‚finir les paramŠtres de + transparence. Ces paramŠtres sont: + + - Taux d'interpolation: Indique le pourcentage de la couleur appliqu‚e + qui sera consid‚r‚e sur la couleur remplac‚e. + + - M‚thode par interpolation: Utilise une m‚thode de moyenne pond‚r‚e + pour calculer la couleur, selon le taux d'interpolation. + + - M‚thode additive: Utilise les teintes les plus claires pour choisir + la couleur … appliquer. + Par exemple: si vous voulez appliquer une couleur ayant les teintes + 30,20,40 sur une couleur 10,50,20, la couleur qui sera appliqu‚e + sera celle qui, dans la palette, sera la plus proche de la couleur + th‚orique 30,50,40. + + - M‚thode soustractive: Utilise les teintes les plus sombres pour + choisir la couleur … appliquer. + Par exemple: si vous voulez appliquer une couleur ayant les teintes + 30,20,40 sur une couleur 10,50,20, la couleur qui sera appliqu‚e + sera celle qui, dans la palette, sera la plus proche de la couleur + th‚orique 10,20,20. + + + + * Mode Smooth (adouci) / Menu: + ------------------------------ + + Cela permet d'obtenit un effet d'anti-aliasing primaire mais ce n'est + vraiment pas aussi efficace que si c'‚tait fait par un artiste. De toutes + fa‡on, cet effet est surtout utile pour donner un aspect flou. + + Click gauche: + =============> + + Active/D‚sactive le mode Smooth. + + + Clic droit: + ============> + + Ouvre un menu dans lequel vous pouvez d‚finir la matrice du Smooth ou + bien en choisir une parmi les 4 pr‚d‚finies. + La case du milieu repr‚sente le pixel sur lequel on dessine et les 8 + cases qui l'entourent repr‚sentent les pixels voisins. Le point sur + lequel on dessine sera alors remplac‚ par la moyenne pond‚r‚e (suivant + les valeurs de chaque case) des 9 points d‚finis. + + + + * Mode Smear (‚taler) / Menu: + ------------------------------ + + Cet effet ‚tale les pixels dans la direction dans laquelle vous bougez + votre pinceau, comme si vous vouliez ‚taler de la peinture fraiche avec + le doigt. Vous pouvez combiner cet effet avec l'effet de transparence. + + N'importe quel clic: + ====================> + + Active/D‚sactive le mode Smear. + + + + * Mode Tiling (Dallage) / Menu: + ------------------------------- + + Cela consiste … appliquer des parties de la brosse ajust‚es sur une + sorte de carrelage lorsque vous dessinez. C'est principalement utilis‚ + pour dessiner rapidement un fond avec un certain motif, mais un grand + nombre d'autres utilisations est possible. + + Clic gauche: + ============> + + Active/D‚sactive le mode Tiling. + + + Clic droit: + ============> + + Ouvre un menu dans lequel vous pouvez choisir les paramŠtres de + Tiling. Ces paramŠtres sont les d‚calages du dallage. (Daaaallaaaage... + Ton univers impitoyaaable... :) Je suis vraiment d‚sol‚... j'ai pas pu + m'en empˆcher :)) + + + + 21 - Texte: + ÄÄÄÄÄÄÄÄÄÄ + + *** Pas encore impl‚ment‚ *** + + + + 22 - Mode Loupe / Menu: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + D‚marre/Annule le choix de la partie zoom‚e. Si vous ˆtes d‚j… en mode + Loupe, vous retournerez en mode normal. + + + Clic droit: + ============> + + Affiche un menu dans lequel vous pouvez choisir le facteur de loupe. + + + Note: Lorsque vous ˆtes en mode Loupe, vous pouvez d‚placer la barre de + s‚paration ("split") en cliquant dessus et en d‚pla‡ant la souris vers la + gauche ou vers la droite en maintenant enfonc‚ le bouton de la souris. + + + + 23 - Pipette / Inverser les couleurs: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + D‚marre une prise de couleur. + + Cliquez sur l'image pour r‚cup‚rer la couleur du pixel sur lequel vous + ˆtes. Vous pouvez prendre indiff‚rement une nouvelle couleur principale + ou couleur de fond en utilisant respectivement le bouton gauche ou droit + de la souris. + + + Clic droit: + ============> + + Echange la couleur principale et la couleur de fond. + + + La couleur sur laquelle vous pointez actuellement sera affich‚e dans la + barre d'outils … la suite des coordonn‚es. + Si vous clickez en dehors de l'image, la couleur 0 vous sera renvoy‚e. + + + + 24 - Taille de l'‚cran / R‚solution de s‚curit‚: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + Affiche un menu dans lequel vous pouvez d‚finir la taille de votre + image (jusqu'… 1024x768) en cliquant dans les boŒtes nomm‚es "Width" + (Largeur) et "Height" (Hauteur); et la r‚solution (dans la liste) dans + laquelle vous souhaitez dessiner. + + Cliquer sur une r‚solution avec le bouton droit de la souris ne + changera pas seulement la r‚solution de l'‚cran, mais changera aussi les + dimensions de l'image par celles de l'‚cran. + + Les r‚solutions affich‚es en gris fonc‚ sont des modes VESA qui ne + sont pas support‚s par votre carte vid‚o. Si vous avez des modes comme + cela, vous devriez essayer de lancer un driver VESA tel que Univesa ou + Univbe avant de lancer le programme. Si ces modes restent indisponibles, + alors cela signifie que votre carte vid‚o ne les supporte vraiment pas. + + Les petits boutons sur le c“t‚ gauche des lignes dans la liste des + modes ont ‚t‚ con‡us pour vous permettre d'inhiber certains modes qui ne + sont pas support‚s par votre carte. + + Lorsque vous clickez sur l'un de ces boutons, sa couleur change vers + l'une des 4 suivantes. La signification de chacune de ces couleurs est: + + - Gris clair: Le mode vid‚o est correct. Il peut ˆtre utilis‚ par + l'option de changement de r‚solution automatique lorsque vous + chargez une image, et vous pouvez le s‚lectionner dans le menu des + r‚solutions. + + - Blanc: Cela fonctionne exactement comme ci-dessus. De plus, cela + vous permet de cocher vos modes pr‚f‚r‚s. En effet, le nombre + impressionnant de modes vid‚o rendant difficile la recherche d'un + mode en particulier dans la liste, aussi vous pouvez mettre ceux que + vous utilisez fr‚quemment en blanc afin qu'ils soient plus facile … + localiser ult‚rieurement. (Note: vous ne pouvez pas inhiber le mode + 320x200 standard) + + - Gris fonc‚: Il vous permet d'indiquer quels modes ne sont pas + parfaits (clignotements, d‚centrage, surbrillance, etc...) mais qui + peuvent tout de mˆme ˆtres utilis‚s par "l'auto-r‚solution". La + diff‚rence avec les boutons gris clair est que ces modes ne seront + pas utilis‚s par l'option de changement de r‚solution automatique. + + - Black: Utilisez cette couleur pour les modes qui ne fonctionnent + vraiment pas. Ainsi, ces modes ne seront pas utilis‚s par l'option + "auto-set res." et le programme vous empˆchera de les s‚lectionner + … partir du menu des r‚solutions. + + + Clic droit: + ============> + + Passe automatiquement au mode 320x200 MCGA. + + + + 25 - Page de brouillon / Copier vers le brouillon: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + Passe … la page de brouillon. La page courante est alors consid‚r‚e + comme la nouvelle page de brouillon, et la page de brouillon comme la + nouvelle page courante. + + + Clic droit: + ============> + + Ouvre un menu dans lequel vous pouvez choisir si vous voulez copier + toute l'image (touche de raccourci dans ce menu: [Return]), seulement + les pixels, seulement la palette, ou seulement quelques couleurs. + Dans ce dernier cas, un second menu (genre stencil) vous proposera de + s‚lectionner les couleurs … copier (par d‚faut, elles sont toutes + s‚lectionn‚es). + Veuillez vous reporter … la section "18 - Stencil" pour savoir comment + utiliser ce dernier menu. + La derniŠre option du menu ("Copier palette et remapper"), adapte la + page de brouillon avec la palette actelle puis recopie cette palette sur + la page de brouillon. Cette option est utile pour remapper rapidement + une image avec la palette d'une autre. + + + + 26 - Sauver l'image / Sauvegarde automatique: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + Affiche un selecteur de fichier dans lequel les options suivantes sont + disponibles: + + - Lecteurs: Vous permettent de changer le lecteur courant. Vous pouvez + aussi utiliser + pour changer de lecteur. + + - Format: Vous permet de choisir le format de fichier que vous voulez + (les formats PAL et KCF sont des formats de palette). + + - Filename (Nom de fichier): Vous permet de donner un nouveau nom … + l'image. Si aucune extension n'est donn‚e, une par d‚faut (d‚pendant + du format) sera utilis‚e. + + - Liste de fichiers: Vous permet de parcourir l'arborescence du disque + ou de remplacer un fichier d‚j… existant. + + - Delete (Supprimer): Permet d'effacer le fichier ou le r‚pertoire (si + celui-ci est vide) se trouvant sous la barre de s‚lection. + + - Save (Sauver): Sauve l'image avec le nom de fichier courant, le + format choisi et le commentaire courant (pour les fichiers PKM). + Si le nom de fichier courant repr‚sente un r‚pertoire, vous entrerez + dedans. + + - Commentaire (Txt): Si vous utilisez le format PKM, vous pouvez + saisir un commentaire de votre image. + + Note: La touche Backspace vous amŠne directement au r‚pertoire parent. + Tapez les 1Šres lettres d'un nom de fichier que vous recherchez + pour y acc‚der plus rapidement. + + Clic droit: + ============> + + Sauve l'image courante avec son nom de fichier, son format et son + commentaire actuels. + + + Si le nom de fichier utilis‚ pour sauver l'image existe d‚j…, une + demande de confirmation apparaŒtra. + + + + 27 - Charger une image / Recharger: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + Cela fonctionne de la mˆme fa‡on que la sauvegarde. + + Vous aurez accŠs dans le selecteur de format … un filtre "*.*". + Et bien ‚videmment, vous ne pourrez pas saisir de commentaire. + + + Clic droit: + ============> + + Recharge l'image. + + + Si vous voulez charger une image et que vous n'avez pas sauv‚ les + derniŠres modifications de l'image courante, une demande de confimation + apparaŒtra. + + + + 28 - ParamŠtres g‚n‚raux (Settings): + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + N'importe quel clic: + ====================> + + Affiche un menu dans lequel vous pouvez configurer divers ‚l‚ments du + programme: + + - Nombre de pages d'UNDO: Indique le nombre total de pages que GrafX2 + m‚morisera. Chaque fois que vous modifiez l'image, son ‚tat courant + est m‚moris‚ dans l'une de ces pages. Pour parcourir ces pages, + utilisez le bouton Oops(Undo/Redo). + + - Fonte: D‚termine si vous voulez utiliser GrafX2 avec une police de + caractŠres classique ou une autre un peu plus amusante. + + - Sensibilit‚ de la souris: Modifie la vitesse de la souris. + + - Montrer/Cacher les fichiers dans les listes: D‚finit si certains + fichiers/r‚pertoires aux attributs particuliers doivent apparaŒtre + ou non dans les s‚lecteurs de fichiers. + + - Montrer/Cacher les limites de l'image: Indique si les limites de + l'image doivent ˆtre affich‚es lorsque vous ˆtes dans une r‚solution + plus grande que l'image. + + - Ecraser la palette: Indique si le chargement d'un fichier dont la + palette fait moins de 256 couleurs doit ‚craser le reste de la + palette actuelle (remplacer par du noir). + + - Maximiser la preview: Maximise la preview des images de fa‡on … ce + qu'elle prenne le plus de place. Si vous n'ˆtes pas dans la mˆme + r‚solution que celle utilis‚e par l'image, cela peut corriger + l'aspect ratio, mais si l'image ne remplit pas tout l'‚cran, cela + peut ˆtre pire. + + - Backup: Lorsque vous sauverez une image sur un fichier existant, le + programme renommera ce fichier en "*.BAK" o— * est le nom de l'image + sans son extension. Si le fichier de backup existe d‚j… dans le + r‚pertoire, il sera remplac‚. Si vous sauvez une image avec le nom + du fichier de backup, aucun fichier de backup ne sera cr‚‚ (bien + ‚videmment!) ;). + + - Curseur: Vous permet de choisir un curseur solide (sprite) ou + transparent. + + - Couleurs de s–ret‚: Remet les 4 couleurs par d‚faut des menus si + vous effectuez une op‚ration qui passe l'image en moins de quatre + couleurs dans l'‚diteur de palette. + + - Adjust brush pick (ajuster la prise de brosse): Cette option est + utilis‚e lorsque vous capturez une brosse en mode Grille. Alors, les + pixels en bas et … droite ne seront pas pris avec le rest de la + brosse. Cette option … ‚t‚ faite car, si les gens r‚cupŠrent des + brosses en mode Grille, c'est principalement lorsqu'ils veulent + r‚cup‚rer des sprites. + Par exemple: si vous avez des sprites 16x16 sur votre page, vous + d‚finirez une grille de 16x16. Mais le curseur se positionnera sur + des points tels que (0,0), (16,0), (16,16) etc... Et le problŠme est + que, de (0,0) … (16,16), il y a 17 pixels! Mais si vous s‚lectionnez + l'option adjust-brush-pick, les pixels ind‚sirables seront ignor‚s. + De plus, cette option ajuste la "poign‚e" de la brosse de fa‡on … ce + que la brosse co‹ncide toujours avec la grille, au lieu de placer + syst‚matiquement l'attache au centre de la brosse. + + - S‚parer les couleurs: Dessiner un quadrillage autour des couleurs + de la barre d'outil. + + - Changer automatiquement de r‚solution: Passe dans la meilleure + r‚solution pour l'image charg‚e. + + - Coordonn‚es: Choisissez si vous souhaitez afficher des coordonn‚es + relatives ou absolues lorsque vous utilisez des outils tels que les + cercles, les rectangles, etc... Par exemple, si vous dessinez un + cercle: si les coordonn‚es sont relatives, le rayon du cercle sera + affich‚, tandis qu'en coordonn‚es absolues coords, ce sont les + coordonn‚es du curseur qui seront affich‚es. + + - Reload (Recharger): Charge la configuration pr‚c‚demment sauv‚e. + + - Auto-save (Sauvegarde automatique): Signifie que la configuration + sera automatiquement sauv‚e quand vous quitterez le programme. + + - Save (Sauver): Sauve la configuration tout de suite. + + + Toutes les modifications prennent effet juste aprŠs avoir ferm‚ le menu + des paramŠtres g‚n‚raux. + + + + 29 - Effacer l'image: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + Efface l'image avec la couleur num‚ro 0. + + + Clic droit: + ============> + + Efface l'image avec la couleur de fond. + + + + 30 - Aide / Statistiques: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + Affiche une fenˆtre d'information o— vous trouverez quelques cr‚dits, + de l'aide sur les diff‚rents effets, des greetings, des information sur + l'enregistrement, etc... + + + Clic droit: + ============> + + Affiche une fenˆtre d'informations o— vous trouverez diverses + informations sur le systŠme. + + Note: pour assurer le bon fonctionnement du programme, il est conseill‚ + de disposer de plus de 128 Ko de libres. + + + + 31 - Oops (D‚faire/Refaire): + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + Vous permet d'annuler la derniŠre modification sur l'image. + + + Clic droit: + ============> + + Vous permet de refaire la derniŠre modification annul‚e sur l'image. + + + Le nombre maximum d'annulations (UNDO) que vous pouvez effectuer peut + ˆtre d‚fini dans le menu des paramŠtres g‚n‚raux. + + D‚faire/Refaire une modification est impossible aprŠs un changement de + page, une chargement d'image ou la modification de la taille de l'image. + + + + 32 - D‚truire la page courante (Kill): + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + N'importe quel clic: + ====================> + + Supprime la page courante de la liste des pages "Undo". Cela vous + permet de lib‚rer un peu de m‚moire si le besoin s'en fait sentir. Cela + permet notamment d'effacer de la m‚moire la page de d‚marrage aprŠs + avoir charg‚ une image. Un message s'affichera lorsque vous aurez + supprim‚ toutes les pages sauf la derniŠre. + + Note: Un autre moyen de lib‚rer de la m‚moire est de r‚duire le nombre + de pages "Undo". Ou encore, si vous avez r‚cemment captur‚ une + trŠs grosse brosse dont vous ne vous servez plus, vous pouvez en + prendre une plus petite. La m‚moire allou‚e pas la grosse brosse + sera alors lib‚r‚e. + + + + 33 - Quitter le programme: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + N'importe quel clic: + ====================> + + Vous permet de quitter GrafX2. S'il y a des modifications non sauv‚es + dans la page courante ou de brouillon, une boite de confirmation vous + demandera si vous d‚sirez r‚ellement quitter GrafX2, si vous voulez + sauver (sauvegarde automatique, pas de s‚lecteur de fichier) ou si vous + voulez rester dans GrafX2. + + + + 34 - Menu de palette: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + Affiche un menu dans lequel les options suivantes sont disponibles: + + - Palette: Vous permet de choisir un bloc de couleurs … ‚diter. Si + vous cliquez avec le bouton droit de la souris, vous d‚finirez une + nouvelle couleur de fond. + + - Jauges RGB: Vous permettent de modifier la s‚lection courante. + + - "+" et "-": Vous permettent d'‚claircir ou d'assombrir la s‚lection + courante. + + - Default (Palette par d‚faut): Restaure la palette pr‚d‚finie de + GrafX2. + + - Gray (Gris): Transforme la s‚lection courante en son ‚quivalent en + niveaux de gris. + + - Negative (N‚gatif): Transforme la s‚lection courante en son + ‚quivalent en vid‚o inverse. + + - Invert (Invertion): Echange les couleurs de la s‚lection courante de + fa‡on … ce que les premiŠres couleurs deviennent les derniŠres. + + - X-Invert (Inverser de fa‡on ‚tendue): Fonctionne comme ci-dessus + mais modifie l'image de fa‡on … ce qu'elle semble inchang‚e. + + - Swap (Echanger): Echange la s‚lection courante avec un autre bloc de + couleurs. Cliquez sur le d‚but du nouveau bloc de couleur. + + - X-Swap (Echanger de fa‡on ‚tendue): Fonctionne comme ci-dessus mais + modifie l'image de fa‡on … ce qu'elle semble inchang‚e. Cela peut + ˆtre utile si vous voulez r‚ordonner votre palette. + + - Copy (Copier): Copie la s‚lection courante vers un autre bloc de + couleurs. Cliquez sur le d‚but du nouveau bloc de couleurs. + + - Spread (D‚grad‚): Calcule un d‚grad‚ entre deux couleurs. Si votre + s‚lection n'est faite que d'une seule couleur, s‚lectionnez la + deuxiŠme couleur dans la palette. Sinon, les deux couleurs seront + les extrˆmit‚s de la s‚lection. + + - Used (Comptage): Indique le nombre de couleurs utilis‚es dans + l'image. + + - Zap unused (Supprimer les couleurs inutilis‚es): ‚crase les couleurs + inutilis‚es avec des copies de la s‚lection courante. (La touche de + raccourci de ce bouton est ). + + - Reduce (R‚duire): Vous permet de r‚duire la palette au nombre de + couleurs que vous d‚sirez (modifie l'image). + + - Undo (D‚faire): Vous permet d'annuler la derniŠre op‚ration faite + sur la palette. Si la derniŠre op‚ration a modifi‚ l'image, cela + n'annulera pas les modifications de l'image: vous devrez cliquer sur + Cancel pour cela. + + + Si vous appuyez sur , le programme insŠrera au mieux les + quatre couleurs par d‚faut du menu … la place de couleurs peu ou pas + utilis‚es. L'image ne paraŒtra pas alt‚r‚e car les couleurs modifi‚es + (dans le cas o— elles ‚taient utilis‚es) seront remplac‚es par les plus + proches couleurs dans le reste de la palette. + Cette option se r‚vŠle fort utile lorsque vous passez la palette dans un + ‚tat ou aucune couleur ne convient pour le menu (ex: "Zap unused" alors + que trŠs peu de couleurs sont utilis‚es dans l'image; ou encore "Reduce" + avec un trŠs faible nombre de couleurs). + + Si vous appuyez sur la touche en dessous de ou <,> (QWERTY), + le menu disparaŒtra et vous pourrez ainsi piocher ais‚ment une couleur + de l'image. Appuyez sur Pour annuler. + + Si une seule couleur est s‚lectionn‚e (pas un bloc), les touches <[> + et <]> (<^> et <$> en AZERTY) peuvent ˆtre utilis‚es pour passer … la + couleur principale pr‚c‚dente ou suivante (couleur de fond si vous + appuyez sur en mˆme temps). + + Attention! Si vous appuyez sur Undo aprŠs une action qui modifie + l'image (X-Swap, X-Invert et Reduce colors), l'image ne sera pas + remapp‚e comme elle ‚tait juste avant cette action. Elle le sera + uniquement avec Cancel (Annuler). + + + Clic droit: + ============> + + Ouvre un menu permettant d'acc‚der aux menus suivants: + + - Menu dans lequel on s‚lectionne les couleurs qui ne doivent pas ˆtre + employ‚es pour le Smooth, le mode de transparence et le remappage. + + - Un menu dans lequel on peut d‚finir des suites de couleurs. + *** Pas encore impl‚ment‚ *** + + + + 35 - D‚placer la palette … gauche / droite: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + D‚place la fenˆtre de palette (… la droite du menu). + + + Clic droit: + ============> + + Idem, mais plus rapidement. + + + + 36 - Fenˆtre de palette: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Clic gauche: + ============> + + D‚finit la couleur principale. + + + Clic droit: + ============> + + D‚finit la couleur de fond. + + + + 37 - Cacher le menu: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + N'importe quel clic: + ====================> + + Vous permet de cacher le menu. Si vous faites cela, prenez soin de + regarder pr‚alablement la touche … presser pour rafficher le menu (la + touche par d‚faut est ). + + + + +Let's talk about $$$, baby: +ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ + + Veuillez vous r‚f‚rer … la section "Register?" de l'aide interne de + GrafX2. + + Pour r‚sumer cette section, disons que GrafX2 est freeware. Mais vous + pouvez quand mˆme nous envoyer de l'argent, des dessins, ou simplement une + carte postale pour nous montrer que nous avons fait un programme qui vous + est utile. + + Nous attirons votre attention sur le fait que la version que vous avez + entre les mains est d‚j… la version "complŠte" (la mˆme que la version + enregistr‚e) aussi nous ne vous enverrons pas d'autre copie de GrafX2. Mais + si vous vous enregistrez pour une version, nous considererons que vous + n'avez pas … vous enregistrer pour les suivantes. + + + + +Astuces de dessin: +ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ + + Cette section parle des astuces qui permettent d'obtenir des effets + sympathiques, ou qui servent simplement … dessiner plus vite. + Notez que, dans la plupart des cas, ces astuces ne permettent que de faire + une grosse partie du travail et qu'il vous faudra bien s–r fignoler … la + loupe si vous souhaitez faire un dessin digne de ce nom! ;) + De plus, si vous avez vous aussi des astuces sympa et que vous souhaitez + en faire profiter les autres, n'h‚sitez pas on nous les signaler. + + + Anti-aliasing: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Ce n'est pas un effet propos‚ par GrafX2 mais une m‚thode de dessin. + Cela consiste … placer des pixels de couleur moyennes dans les angles + form‚s par des pixels contrast‚s pour adoucir de fa‡on esth‚tique leur + aspect. + A notre avis, c'est essential pour dessiner des images vraiment belles. + Une m‚thode facile mais fatigante (la meilleure m‚thode!) est de + commencer par ajouter 1 couleur moyenne puis d'antialiaser les nouvelles + couleurs "r‚cursivement" tant qu'il y a des couleurs interm‚diaires dans + votre palette. + + ÛÛÛÛÛÛÛÛÛÛÛÛ + ÛÛÛÛÛÛÛÛÛÛÛÛ + + ÛÛÛÛÛÛÛÛ±±±±±±±± + ±±±±±±±±ÛÛÛÛÛÛÛÛ + + ÛÛÛÛ²²²²²±±±±°°°° + °°°°±±±±²²²²²ÛÛÛÛ + + + Mode "Smear" combin‚ avec les lignes concentriques: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + En combinant cet effet et cet outil de dessin, vous pouvez arriver … + "‚parpiller" une zone … partir d'un point central. + Si vous n'ˆtes pas en haute r‚solution, il peut s'av‚rer utile d'en- + clencher ‚galement le mode de Transparence (cf. section suivante). + + þ Une application possible est de dessiner des poils sur une peluche. Pour + cela, vous pouvez choisir un des pinceaux pr‚d‚finis qui ressemblent … un + ensemble al‚atoire de points. Selon la densit‚ de poils que vous souhaitez + donner … votre peluche, vous pouvez choisir un pinceau contenant plus ou + moins de points. Placez ensuite le centre des lignes concentriques environ + au centre de la peluche, puis faites tourner la souris autour de la + peluche en maintenant le bouton de la souris enfonc‚. + Avec la mˆme m‚thode, mais en insistant plus longtemps, vous pouvez + donner un effet d'explosion sur un objet. + + þ Vous pouvez ‚galement cr‚er facilement et rapidement des rayons de + soleil avec cette m‚thode. Pour cela, aprŠs avoir plac‚ la forme premiŠre + du soleil sur le ciel, choisissez un pinceau en fonction de la taille des + rayons que vous voulez cr‚er (mais un petit pinceau sera souvent + pr‚f‚rable), et placez le centre des lignes au centre du soleil. Puis + tracez les rayons … la longueur que vous voulez. Si vous n'avez pas pris + un trop gros pinceau, vous pourrez dans un premier temps tracer + rapidement une aur‚ole autour du soleil en tournant rapidement autour et + en maintenant le bouton de la souris enfonc‚, et dans un deuxiŠme temps + vous rajouterez des rayons plus importants avec pr‚cision. + + + Mode "Smear" combin‚ avec l'effet de Transparence: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + Ces deux modes de dessin combin‚s permettent d'‚taler des parties + d'image comme de la peinture fraiche. + Il est recommand‚ d'utiliser la m‚thode de transparence qui consiste … + interpoler avec une opacit‚ d'environ 60% et le "Feedback" des effets + enclench‚. + + þ Tout comme dans la section pr‚c‚dente, cela peut servir … dessiner des + poils et notamment des cils si vous avez une palette adapt‚e (c'est-…-dire + une palette contenant des d‚grad‚s de couleurs entre toutes les couleurs + sur lesquelles vous dessinerez pendant cette op‚ration. + Pour dessiner des cils par exemple, aprŠs avoir dessin‚ l'oeil et la + paupiŠre, tracez un trait noir assez ‚pais repr‚sentant la base des cils (c'est ce + noir que vous ‚talerez sur la paupiŠre). Puis, en mode smear+transparence, + dessinez des traits … la main (avec un petit pinceau: 1, 2 ou 3 pixels de + large suivant que vous dessiniez un visage ou un oeil en gros plan) en + partant de la base des cils et en donnant leur forme. Vous verrez petit-…- + petit votre barre noire s'effiler en forme de cils. + + þ On peut ‚galement se servir de ces effets pour m‚langer des couleurs … + l'‚cran et donner ainsi un aspect de peinture. Par exemple, si l'on + souhaite r‚aliser un fond comportant des formes abstraites compos‚es de + m‚langes de couleurs, on peut proc‚der comme suit: + - D‚finir un palette comportant un d‚grad‚ entre les diff‚rentes teintes + que vous souhaitez utiliser. + - Dessiner trŠs vaguement … l'aide d'un gros pinceau les diff‚rentes zones + de couleurs (en mode normal). + - Avec un plus petit pinceau, et … l'aide du spray, appliquer ces mˆmes + teintes mais en plus clair ou plus fonc‚ sur les zones pr‚c‚demment + d‚finies. + - Toujours avec le mˆme pinceau en spray, mais cette fois-ci en mode smear + (pas forc‚ment avec transparence... mais pourquoi pas?), m‚langez un peu + toutes les couleurs … l'‚cran pour obtenir une "bouillie multicolore" tout + en conservant vaguement les diff‚rentes zones de couleurs. + - Enfin, en mode Smear+Transparence, avec un pinceau moyen arrondi, + dessinez … la main en faisant des tourbillons, des vagues, etc... en + conservant a peu prŠs le mˆme mouvement pour ‚viter les cassures. Ceci + a pour but d'‚liminer la pixellisation op‚r‚e par le spray et de donner + l'aspect final de peinture m‚lang‚e. + - Maintenant, si c'est moche, c'est soit que j'explique mal, soit que vous + n'avez pas de talent! :p + + + Spray combin‚ au mode shade: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + þ Si vous utilisez souvent le mode Shade, et que ‡a vous fatigue de + cliquer plein de fois sur une couleur pour atteindre celle que vous + voulez, vous pouvez definir un spray avec "Size"=1, "Mono-flow"=1, et + "Delay"=2 (ou plus, selon vos r‚flexes). Et vous n'aurez alors plus qu'… + cliquer quelques centiŠmes de seconde pour modifier une couleur. + + þ Avec un diamŠtre plus large, cela permet de rajouter de la granularit‚ + … une texture, car placer des petits pixels plus fonc‚s ou plus clairs + permet de cr‚er des asp‚rit‚s. Diff‚rentes textures appropri‚es … cet + effet sont: du sable, de la pierre, etc... + Il faut bien s–r que vous ayez un d‚grad‚ adapt‚ … la couleur de la + texture. + + þ Vous pouvez ‚galement r‚aliser des textures - \ + plus ‚labor‚es en employant un pinceau en forme \ \ + de petite courbe ou ligne comme "tentent" de le ` \ + montrer les figures ci-contre. ;) | \ + Vous pourrez ainsi r‚aliser des textures de paille, + de cheveux, de pierres stri‚es ou de marbre (le spray ‚tant + toutefois moins recommand‚ que le dessin … la main pour ce dernier). + + + Mode shade pour remplacer les couleurs d'un d‚grad‚ par un autre: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + þ Si vous avec dessin‚ quelque chose avec des couleurs appartenant … un + d‚grad‚ et que vous souhaitiez remplacer toutes ces couleurs par celles + d'un autre d‚grad‚ (du mˆme nombre de couleurs), proc‚dez comme suit: + - D‚finissez dans le menu du mode shade les 2 d‚grad‚s en question sans + les s‚parer par une case vide. + - Passez le shade en mode "no saturation" + - D‚finissez le pas du shade avec la taille des d‚grad‚s (ex: entrez 16 si + vos d‚grad‚s comportent chacun 16 couleurs). + - Et voil…, vous n'avez plus qu'… dessiner par dessus la zone qui doit + changer de teinte (avec le bouton gauche de la souris si vous avez plac‚ + le d‚grad‚ … remplacer en premier dans la table de shade, ou inversement). + + + SphŠres combin‚es avec le mode de transparence additive: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + þ En partant d'un fond sombre (et si possible de couleur unie), tracez des + sphŠres qui se chevauchent avec leur point d'‚clairage au centre. Vous + obtiendrez rapidement un effet de "blobs". + + + Comment dessiner une goutte: + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + þ Voici une m‚thode rapide et efficace pour dessiner des gouttes. + Dessinez simplement des pixels trŠs brillants sur le c“t‚ de la goutte + d'o— vient la lumiŠre, et des pixels moins brillants sur le c“t‚ oppos‚. + Enfin, dessinez les ombres suivant la position de la lumiŠre. + + Voici des exemples avec une lumiŠre ±±±±±±±±±±±± ±±±±±±±± + venant du coin haut-gauche. ±±±±±±±±±±±± ±±±±±±±± + (il est pr‚f‚rable de les regarder ±±±±²±°±±±±± ±±Û°±±±± + en mode texte 80x50) ±±±²Û°°±±±±± ±±±°²°±± + ±±±Û²°±²°±±± ±±±±°±±± + Vous pouvez penser que la plus ±±±²±°²²°±±± ±±±±±±±± + petite goutte ne ressemble pas a ±±±±±²Û±°±±± ±±±±±±±± + une goutte, mais dessinez-la en mode ±±±±±°°°±±±± + graphique et vous verrez qu'elle a ±±±±±±±±±±±± + bien l'air d'une goutte. ±±±±±±±±±±±± + + Si vous n'avez pas confiance, dites-vous que c'est en observant les graphs + de Lazur que j'ai trouv‚ cette m‚thode. Et d'une fa‡on g‚n‚rale, il est + toujours bon de regarder le travail des artistes confirm‚s pour apprendre + de nouvelles techniques. + + + + +ProblŠmes/Astuces g‚n‚rales/Questions fr‚quentes (FAQ): +ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ + + * ProblŠmes de carte vid‚o: + + - Les modes VESA sont rendus inaccessibles par Windows NT. Et il parait + que ‡a va ˆtre pareil sous Windows 2000 (on n'a pas encore essay‚, mais on + n'est pas press‚s!). + + - Si votre carte vid‚o n'est pas compatible VESA mat‚riellement, vous + devriez essayer de lancer un driver VESA tel que Univesa ou Univbe. + + - Si votre carte est compatible VESA mais n'affiche pas correctement le + contenu de l'‚cran dans les r‚solutions VESA, c'est probablement parce + qu'elle ne r‚pond pas … tous les critŠres que nous attendons. L'explica- + tion est que, pour une plus grande efficacit‚, nous avons d– n‚gliger + certaines sp‚cificit‚s de quelques cartes vid‚os. Cependant, nous tentons + … chaque nouvelle version d'augmenter la compatibilit‚ avec toutes les + formes du standard VESA. + + - Si vous poss‚dez une carte vid‚o ATI Mach 64 (e.g. ATI Xpert), vous + devriez utiliser le programme r‚sident m64vbe fourni avec la carte pour + supporter complŠtement nos modes XVESA en tapant: "m64vbe vga". + + + * ProblŠmes de m‚moire: + + - Depuis la version 94.666%, nous utilisons le dos-extender EOS Copyright + (c) 1996 Eclipse, au lieu du traditionnel DOS4GW. La raison en est qu'il + est beaucoup plus petit en place disque (un zip plus petit, ‡a devrait + faire plaisir … vos factures de t‚l‚phone) et en m‚moire (vous pouvez + donc lancer GrafX2 avec plus de gestionnaires utilisant la m‚moire + conventionnelle). De plus, ce dos-extender est int‚gr‚ … l'‚x‚cutable de + GrafX2, ce qui diminue ‚galement le nombre de fichiers (votre FAT vous + en sera reconnaissante). + + L'inconv‚nient est que ce dos-extender ne gŠre pas de cache disque. + Ainsi, si vous ne disposez pas d'au moins 4 M‚gaoctets de RAM, vous + devrez utiliser le fichier batch GFX2_MEM.BAT . + + Il est … noter que: + - vous devrez configurer ce fichier selon l'emplacement de certains + fichiers dans l'arborescence de votre (vos) disque(s) dur(s) + - vous devrez avoir quelque part dans l'arborescence de votre (vos) + disque(s) dur(s) le fichier DOS4GW.EXE . + - vous devrez disposer d'au moins 16 M‚gaoctets de libre sur votre + disque dur courant. + + Si vous avez rencontr‚ des problŠmes dans l'utilisation de GrafX2 (avec + au moins 4 M‚gaoctets de m‚moire) qui se seraient r‚solus en utilisant + GFX2_MEM, nous vous serions reconnaissant de nous en faire part. + + EOS est un dos-extender shareware, accompagn‚ de bibliothŠques trŠs + int‚ressantes pour la musique, le graphisme, ... pour des applications + Watcom, Tasm ou Masm. Si vous d‚sirez avoir plus d'informations sur ses + fonctionnalit‚s ou les bibliothŠques qui l'accompagne, n'h‚sitez pas … + nous contacter pour que nous vous mettions en relation avec ses auteurs. + + + * ProblŠmes de carte son: + + Q: Aucun son ne sort de ma Ultra-maxi-sound-blaster-galaxy-64-3D-pnp, + alors que puis-je faire ? + R: Et bien... Vous devez comprendre que ce programme n'est ni un + soundtracker ni un player de musique :) ... Aussi, si vous voulez de la + musique, vous devrez soit jouer des modules avec un bon player qui peut + tourner en arriŠre-plan (avec une session DOS), soit allumer votre + chaine Hi-Fi. + + + * Divers: + + - Si vous avez foutu en l'air le fichier GFX2.CFG et que GrafX2 l'utilise + tel quel, avec un comportement anormal, n'h‚sitez pas … effacer GFX2.CFG + et … relancer GFXCFG pour en cr‚er un nouveau, et correct. En effet les + seuls tests de validit‚ que nous faisons sur le fichier de configuration + sont sa taille et son num‚ro de version. + + - Il se peut que vous ayez r‚cup‚r‚ une version de GrafX2 d‚j… configur‚e + par un ami qui aurait pu utiliser des touches "Windows 95" alors que + vous ne disposez pas vous-mˆme d'un clavier adapt‚. Dans ce cas, il vous + faudra reconfigurer ces combinaisons … l'aide de GFXCFG. + + + * Questions fr‚quemment pos‚es: + + Q: Comment puis-je choisir les dimensions de l'image ? + R: Nous pensions qu'il ‚tait ‚vident que vous deviez cliquer dans les + zones o— les dimensions sont affich‚es, dans le menu de r‚solution + (Width & Height) mais beaucoup de personnes nous ont pos‚ cette + question (?!). Alors, pour r‚sumer, partout o— vous verrez une valeur + ou un texte affich‚ en noir dans une sorte de zone incrust‚e, cela + signifie qu'en cliquant dessus vous pourrez modifier cette valeur. + De plus, si vous voulez que les dimensions de l'image soient celles + de l'‚cran, il vous suffit de cliquer sur la r‚solution dans la liste + avec le bouton droit de la souris. + + Q: O— puis-je obtenir la derniŠre version de GrafX2 ? + R: Le seul endroit o— vous puissiez ˆtre s–r de trouver la toute derniŠre + version est sur notre site web: + http://www-msi.ensil.unilim.fr/~maritaud/sunset + Toutefois, il n'est pas impossible que GrafX2 se retrouve ‚galement sur + des sites FTP d‚di‚s … la "demo-scene" (e.g. ftp://ftp.scene.org). + + Q: Comment puis-je passer la brosse en monochrome, et comment puis-je la + r‚cup‚rer dans son ‚tat normal? + R: Vous pouvez le faire (… supposer que vous n'avez pas chang‚ les touches + par d‚faut) avec les touches + pour rendre la brosse + monochrome, et + pour r‚cup‚rer la brosse en couleur. + + Q: Pourquoi est-ce que la barre d'outil est en bas de l'‚cran et non pas + sur le c“t‚ droit comme dans Deluxe Paint (Copyright Electronic Arts) ? + R: Eh bien... GrafX2 N'EST PAS Deluxe Paint! Nous savons que vous ˆtes + habitu‚s … Deluxe Paint mais vous allez devoir vous habituer … GrafX2! + ;) Si vous ne supportez vraiment pas d'utiliser GrafX2 comme cela, vous + devrez attendre GrafX3 mais nous ne le r‚aliserons certainement pas + avant l'an 2013! En fait, la principale raison pour laquelle nous avons + con‡u la barre d'outil avec un aspect aussi basique est que cela + facilitait (et acc‚l‚rait) l'affichage de l'‚cran, en indiquant aux + routines o— s'arrˆter (l… o— commence la barre d'outil). + De plus, l'un des meilleurs logiciels de dessin sur Amiga (Brilliance) + affiche ‚galement la barre du menu en bas de l'‚cran. + + Q: Pourquoi est-ce que la partie de l'image cach‚e par le menu n'est pas + remplie lorsque j'utilise l'outil "Flood-fill"? + R: Pour la simple et "assez" bonne raison qu'il est pr‚f‚rable que l'uti- + lisateur contr“le parfaitement ce qu'il dessine. Ainsi il ne pourra pas + remarquer trop tard qu'il a saccag‚ une partie de son dessin. Il en est + de mˆme pour tous les autres outils. Et puis pour une moins bonne + raison qui est que c'‚tait plus pratique pour nous. ;) + + Q: Y'a-t-il un moyen pour lancer le programme dans une autre r‚solution + que 320x200 ? + R: Oui, il suffit de taper GFX2 sur la ligne de commande + du DOS. Pour obtenir la liste de tous les modes vid‚o, tapez: GFX2 /?. + + Q: Est-ce normal que certains boutons ne marchent pas (par exemple: le + bouton Texte) ? + R: Oui, c'est que nous n'avons pas encore eu le temps de les faire (je + vous rappelle que GrafX2 en est encore au stade des Beta versions). + Voici cependant la liste des boutons qui ne repondent pas dans GrafX2: + - Rectangles d‚grad‚s (Grad. rectangles) + - Texte + - Effets sur l'image + - et le bouton suivant dans le menu "Brush effects": Torsion (Distort) + + Q: Allez-vous sortir une version Windows? + R: GrafX2 perdrait son ƒme en ‚tant adapt‚ … un systŠme fenˆtr‚ ou … un + systŠme qui ne supporte pas tous ses modes vid‚os. Et de toutes fa‡ons, + il peut se lancer … partir de Windows 9x (on ne sait pas pour Windows + 2000 mais on s'en fiche). Alors c'est bien comme ‡a. La seule chose + int‚ressante que pourrait apporter Windows est le presse-papier. + + Q: Allez-vous sortir une version Linux? + R: Bien que ce soit … peu prŠs le mˆme problŠme qu'avec la version + Windows, Linux manque de programmes comme GrafX2; donc, mˆme une + version limit‚e serait int‚ressante pour cet OS. Par cons‚quent, nous + aimerions sortir une version Linux. Mais nous n'avons aucune exp‚rience + de programmation Linux et notre code est complŠtement indechiffrable + pour les autres. Alors vous devrez attendre... + + Q: Comment puis-je vous contacter ? + R: En fait, ce n'est pas exactement cette question qu'on nous pose puisque + ces gens arrivent … nous contacter ;) mais... + + * Poste: + GUILLAUME DORME (Robinson) KARL MARITAUD (X-Man) + 15, rue de l'observatoire 10, rue de la Brasserie + 87000 LIMOGES (FRANCE) 87000 LIMOGES (FRANCE) + + * E-mail: + dorme@msi.unilim.fr maritaud@ensil.unilim.fr + + N'h‚sitez pas … nous contacter; on adore ‡a! :) + Nous essaierons de r‚pondre … tous les e-mails (s'il n‚cessitent une + r‚ponse), et … certains courriers (Bah oui! On ne va pas se ruiner en + timbres juste pour vous dire "merci d'avoir ‚crit!" :)). diff --git a/dpmi.asm b/dpmi.asm new file mode 100644 index 00000000..a09a5659 --- /dev/null +++ b/dpmi.asm @@ -0,0 +1,472 @@ +.386P +.MODEL FLAT + + + +_TEXT Segment dword public 'code' + Assume cs:_TEXT, ds:_DATA + + +; -- Fonctions DPMI -- +public Physical_address_mapping +public Free_physical_address_mapping +public Lock_linear_region +public Unlock_linear_region +public Allocate_ldt_descriptor +public Free_ldt_descriptor +public Set_segment_base_address +public Set_segment_limit +public Set_descriptor_access_rights +public Get_segment_base_address + + + + + +Physical_address_mapping proc near + + push ebp + mov ebp,esp + + arg Physical_address:dword,Physical_size:dword,Linear_address_pointer:dword + + push ebx + push esi + push edi + + ; On met dans BX:CX l'adresse physique … mapper + mov eax,Physical_address + mov cx,ax + shr eax,16 + mov bx,ax + + ; On met dans SI:DI la taille de l'adresse physique … mapper + mov eax,Physical_size + mov di,ax + shr eax,16 + mov si,ax + + ; On appelle le service DPMI de mappage d'adresse physique + mov ax,0800h + int 31h + + jc Physical_address_mapping_Erreur + + ; On sauve l'adresse lin‚aire … l'adresse donn‚e + mov eax,Linear_address_pointer + mov [eax+00h],cx + mov [eax+02h],bx + ; Et on renvoie un code d'erreur nul + xor ax,ax + + Physical_address_mapping_Erreur: + + pop edi + pop esi + pop ebx + + mov esp,ebp + pop ebp + + ret + +Physical_address_mapping endp + + + + + +Free_physical_address_mapping proc near + + push ebp + mov ebp,esp + + arg Linear_address:dword + + push ebx + + ; On met dans BX:CX l'adresse lin‚aire … d‚mapper + mov eax,Linear_address + mov cx,ax + shr eax,16 + mov bx,ax + + ; On appel le service DPMI de lib‚ration d'un mappage d'adresse physique + mov ax,0801h + int 31h + + jc Free_physical_address_mapping_Erreur + + ; On renvoie un code d'erreur nul + xor ax,ax + + Free_physical_address_mapping_Erreur: + + pop ebx + + mov esp,ebp + pop ebp + + ret + +Free_physical_address_mapping endp + + + + + +Lock_linear_region proc near + + push ebp + mov ebp,esp + + arg Linear_address:dword,Linear_size:dword + + push ebx + push esi + push edi + + ; On met dans BX:CX l'adresse lin‚aire … locker + mov eax,Linear_address + mov cx,ax + shr eax,16 + mov bx,ax + + ; On met dans SI:DI la taille de l'adresse lin‚aire … locker + mov eax,Linear_size + mov di,ax + shr eax,16 + mov si,ax + + ; On appel le service DPMI de lockage d'adresse lin‚aire + mov ax,0600h + int 31h + + jc Lock_linear_region_Erreur + + ; On renvoie un code d'erreur nul + xor ax,ax + + Lock_linear_region_Erreur: + + pop edi + pop esi + pop ebx + + mov esp,ebp + pop ebp + + ret + +Lock_linear_region endp + + + + + + +Unlock_linear_region proc near + + push ebp + mov ebp,esp + + arg Linear_address:dword,Linear_size:dword + + push ebx + push esi + push edi + + ; On met dans BX:CX l'adresse lin‚aire … d‚locker + mov eax,Linear_address + mov cx,ax + shr eax,16 + mov bx,ax + + ; On met dans SI:DI la taille de l'adresse lin‚aire … d‚locker + mov eax,Linear_size + mov di,ax + shr eax,16 + mov si,ax + + ; On appel le service DPMI de d‚lockage d'adresse lin‚aire + mov ax,0601h + int 31h + + jc Unlock_linear_region_Erreur + + ; On renvoie un code d'erreur nul + xor ax,ax + + Unlock_linear_region_Erreur: + + pop edi + pop esi + pop ebx + + mov esp,ebp + pop ebp + + ret + +Unlock_linear_region endp + + + + + + + +Allocate_ldt_descriptor proc near + + push ebp + mov ebp,esp + + arg Nombre_de_descripteurs:word,Base_selector_pointer:dword + + push ebx + push esi + push edi + + ; On met dans CX le nombre de descripteurs ldt … allouer + mov cx,Nombre_de_descripteurs + + ; On appel le service DPMI d'allocation de descripteurs ldt + mov ax,0000h + int 31h + + jc Allocate_ldt_descriptor_Erreur + + ; On sauve la valeur du s‚lecteur de base + mov ebx,Base_selector_pointer + mov [ebx],ax + ; Et on renvoie un code d'erreur nul + xor ax,ax + + Allocate_ldt_descriptor_Erreur: + + pop edi + pop esi + pop ebx + + mov esp,ebp + pop ebp + + ret + +Allocate_ldt_descriptor endp + + + + + + +Free_ldt_descriptor proc near + + push ebp + mov ebp,esp + + arg Selector:word + + push ebx + push esi + push edi + + ; On met dans BX le descripteur ldt … lib‚rer + mov bx,Selector + + ; On appel le service DPMI de lib‚ration de descripteur ldt + mov ax,0001h + int 31h + + jc Free_ldt_descriptor_Erreur + + ; On renvoie un code d'erreur nul + xor ax,ax + + Free_ldt_descriptor_Erreur: + + pop edi + pop esi + pop ebx + + mov esp,ebp + pop ebp + + ret + +Free_ldt_descriptor endp + + + + + + +Set_segment_base_address proc near + + push ebp + mov ebp,esp + + arg Selector:word,Linear_base_address:dword + + push ebx + + ; On met dans CX:DX l'adresse de base lin‚aire … assigner au segment + mov eax,Linear_base_address + mov dx,ax + shr eax,16 + mov cx,ax + + ; On met dans BX le s‚lecteur auquel il faut assigner l'adresse de base + mov bx,Selector + + ; On appel le service DPMI d'assignation d'adresse de base … un segment + mov ax,0007h + int 31h + + jc Set_segment_base_address_Erreur + + ; On renvoie un code d'erreur nul + xor ax,ax + + Set_segment_base_address_Erreur: + + pop ebx + + mov esp,ebp + pop ebp + + ret + +Set_segment_base_address endp + + + + + + +Set_segment_limit proc near + + push ebp + mov ebp,esp + + arg Selector:word,Segment_limit:dword + + push ebx + + ; On met dans CX:DX la limite (taille) … assigner au segment + mov eax,Segment_limit + mov dx,ax + shr eax,16 + mov cx,ax + + ; On met dans BX le s‚lecteur auquel il faut assigner une limite + mov bx,Selector + + ; On appel le service DPMI d'assignation de limite … un segment + mov ax,0008h + int 31h + + jc Set_segment_limit_Erreur + + ; On renvoie un code d'erreur nul + xor ax,ax + + Set_segment_limit_Erreur: + + pop ebx + + mov esp,ebp + pop ebp + + ret + +Set_segment_limit endp + + + + + +Set_descriptor_access_rights proc near + + push ebp + mov ebp,esp + + arg Selector:word,Rights:word + + push ebx + + ; On met dans CX les droits … assigner au segment + mov cx,Rights + + ; On met dans BX le s‚lecteur auquel il faut assigner des droits + mov bx,Selector + + ; On appel le service DPMI d'assignation de droits … un segment + mov ax,0009h + int 31h + + jc Set_descriptor_access_rights_Erreur + + ; On renvoie un code d'erreur nul + xor ax,ax + + Set_descriptor_access_rights_Erreur: + + pop ebx + + mov esp,ebp + pop ebp + + ret + + + +Set_descriptor_access_rights endp + + + + + + +Get_segment_base_address proc near + + push ebp + mov ebp,esp + + arg Selector:word,Linear_base_address_pointer:dword + + push ebx + + ; On met dans BX le s‚lecteur dont il faut lire l'adresse de base + mov bx,Selector + + ; On appel le service DPMI de lecture d'adresse de base d'un segment + mov ax,0006h + int 31h + + jc Get_segment_base_address_Erreur + + ; On sauve l'adresse de base lin‚aire du segment + mov eax,Linear_base_address_pointer + mov [eax+00h],dx + mov [eax+02h],cx + ; On renvoie un code d'erreur nul + xor ax,ax + + Get_segment_base_address_Erreur: + + pop ebx + + mov esp,ebp + pop ebp + + ret + +Get_segment_base_address endp + + + + + +_TEXT ENDS +END diff --git a/dpmi.h b/dpmi.h new file mode 100644 index 00000000..7e525d61 --- /dev/null +++ b/dpmi.h @@ -0,0 +1,20 @@ + +#ifndef _DPMI_H_ +#define _DPMI_H_ + + + + word Physical_address_mapping(byte * Physical_address,dword Size,byte * * Linear_address_pointer); + word Free_physical_address_mapping(byte * Linear_address); + word Lock_linear_region(byte * Linear_address,dword Size); + word Unlock_linear_region(byte * Linear_address,dword Size); + word Allocate_ldt_descriptor(word Nombre_de_descripteurs,word * Base_selector_pointer); + word Free_ldt_descriptor(word Selector); + word Set_segment_base_address(word Selector,byte * Linear_base_address); + word Set_segment_limit(word Selector,dword Segment_limit); + word Set_descriptor_access_rights(word Selector,word Rights); + word Get_segment_base_address(word Selector,byte * * Linear_base_address_pointer); + + + +#endif diff --git a/file_id.diz b/file_id.diz new file mode 100644 index 00000000..c0437ca5 --- /dev/null +++ b/file_id.diz @@ -0,0 +1,21 @@ +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +³ Sunset-Design presents á96.5%³ +³ ÜÜÜÜ ÜÜÜÜ ÜÜÜ ÜÜÜÜÜ Ü Ü ÜÜÜÜ ³ +³ Û Û Û Û Û Û ßÜ Üß Û ³ +³ Û ÜÜ ÛÜÜÜß ÛÜÜÜÛ ÛÜÜ ßÜß Üßß ³ +³ Û Û Û ßÜ Û Û Û Û Û Û .00 ³ +³ ßÜÜÜÛ Û Û Û Û Û Û Û ÛÜÜÜÜ ³ +³ ³ +³ GrafX 2.00 Beta 96.5% ³ +³ ³ +³ °±²Û The ultimate multi-resolution Û²±° ³ +³ °±²Û bitmap paint program for PC Û²±° ³ +³ ³ +³ features: ³ +³ - all the useful tools and much more ³ +³ - 60 resolutions! (MCGA, Mode-X, VESA) ³ +³ (including Amiga resolutions!) ³ +³ - GIF,LBM,BMP,PCX,PKM,... file support ³ +³ ³ +³ Try it! You'll love it! ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ diff --git a/files.c b/files.c new file mode 100644 index 00000000..4542c406 --- /dev/null +++ b/files.c @@ -0,0 +1,539 @@ +#include "const.h" +#include "struct.h" +#include "global.h" +#include "graph.h" +#include "divers.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +#include "linux.h" + +#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‚ +#define COULEUR_FOND_NORMAL CM_Noir // Couleur du fond pour une ligne non s‚lectionn‚e +#define COULEUR_FICHIER_SELECT CM_Blanc // Couleur du texte pour une ligne de fichier s‚lectionn‚e +#define COULEUR_REPERTOIRE_SELECT CM_Clair // Couleur du texte pour une ligne de rep‚rtoire s‚lectionn‚e +#define COULEUR_FOND_SELECT CM_Fonce // Couleur du fond pour une ligne s‚lectionn‚e + + +int Determiner_repertoire_courant(void) +// Modifie Principal_Repertoire_courant en y mettant sa nouvelle valeur (avec le nom du +// disque) +// +// Renvoie 1 s'il y a e–t une erreur d'accŠs +{ + return (getcwd(Principal_Repertoire_courant,256)==NULL); +} + + +int Repertoire_existe(char * Repertoire) +// D‚termine si un r‚pertoire pass‚ en paramŠtre existe ou non dans le +// r‚pertoire courant. +{ + DIR* Enreg; // Structure de lecture des ‚l‚ments + + if (strcmp(Repertoire,"..")==0) + return 1; + else + { + // On va chercher si le r‚pertoire existe … l'aide d'un Opendir. S'il + // renvoie NULL c'est que le répertoire n'est pas accessible... + + Enreg=opendir(Repertoire); + if (Enreg==NULL) + return 0; + else + { + closedir(Enreg); + return 1; + } + } +} + + +int Fichier_existe(char * Fichier) +// D‚termine si un fichier pass‚ en paramŠtre existe ou non dans le +// r‚pertoire courant. +{ + struct stat* buf; + int Resultat; + + Resultat=stat(Fichier,buf); + if (Resultat!=0) + return(errno!=ENOENT); + else + return 1; + +} + + + +// Conventions: +// +// * Le fileselect modifie le r‚pertoire courant. Ceci permet de n'avoir +// qu'un findfirst dans le r‚pertoire courant … faire: + + +// -- D‚struction de la liste chaŒn‚e --------------------------------------- +void Detruire_liste_du_fileselect(void) +// Cette proc‚dure d‚truit la chaine des fichiers. Elle doit ˆtre appel‚e +// avant de rappeler la fonction Lire_liste_des_fichiers, ainsi qu'en fin de +// programme. +{ + // Pointeur temporaire de destruction + struct Element_de_liste_de_fileselect * Element_temporaire; + + while (Liste_du_fileselect!=NULL) + { + // On m‚morise l'adresse du premier ‚l‚ment de la liste + Element_temporaire =Liste_du_fileselect; + // On fait avancer la tˆte de la liste + Liste_du_fileselect=Liste_du_fileselect->Suivant; + // Et on efface l'ancien premier ‚l‚ment de la liste + free(Element_temporaire); + } +} + + +// -- Formatage graphique des noms de fichier / r‚pertoire ------------------ +char * Nom_formate(char * Nom) +{ + static char Resultat[13]; + int Curseur; + int Autre_curseur; + + if (strcmp(Nom,"..")==0) + { + strcpy(Resultat,".. "); + } + else + { + strcpy(Resultat," . "); + // On commence par recopier la partie pr‚c‚dent le point: + for (Curseur=0;( (Nom[Curseur]!='.') && (Nom[Curseur]!='\0') );Curseur++) + Resultat[Curseur]=Nom[Curseur]; + + // Ensuite on recopie la partie qui suit le point (si n‚cessaire): + if (Nom[Curseur]) + { + for (Curseur++,Autre_curseur=9;Nom[Curseur]!='\0';Curseur++,Autre_curseur++) + Resultat[Autre_curseur]=Nom[Curseur]; + } + } + return Resultat; +} + + +// -- Rajouter … la liste des ‚l‚ments de la liste un ‚l‚ment --------------- +void Ajouter_element_a_la_liste(struct dirent* Enreg) +// Cette proc‚dure ajoute … la liste chain‚e 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 + Element_temporaire=(struct Element_de_liste_de_fileselect *)malloc(sizeof(struct Element_de_liste_de_fileselect)); + + // On met … jour le nouvel emplacement: + strcpy(Element_temporaire->Nom,Nom_formate(Enreg->d_name)); + Element_temporaire->Type =(Enreg->d_type == DT_DIR); + + Element_temporaire->Suivant =Liste_du_fileselect; + Element_temporaire->Precedent=NULL; + + if (Liste_du_fileselect!=NULL) + Liste_du_fileselect->Precedent=Element_temporaire; + Liste_du_fileselect=Element_temporaire; +} + + +// -- Lecture d'une liste de fichiers --------------------------------------- +void Lire_liste_des_fichiers(byte Format_demande) +// Cette proc‚dure charge dans la liste chain‚e les fichiers dont l'extension +// correspond au format demand‚. +{ + int Attribut; // Attribut des fichiers/r‚pertoires … lire + DIR* Repertoire_Courant; //Répertoire courant + struct dirent* Enreg; // Structure de lecture des ‚l‚ments + char Filtre[6]="*."; // Place pour ‚crire "*.XXX" et un '\0' + + char Chaine[20]; + + // Tout d'abord, on d‚duit du format demand‚ un filtre … utiliser: + if (Format_demande) // Format (extension) sp‚cifique + strcat(Filtre,Format_Extension[Format_demande-1]); + else // *.* + strcat(Filtre,"*"); + + + // Ensuite, on vide la liste actuelle: + Detruire_liste_du_fileselect(); + // AprŠs effacement, il ne reste ni fichier ni r‚pertoire dans la liste + Liste_Nb_fichiers=0; + Liste_Nb_repertoires=0; + + // On lit tous les r‚pertoires: + + Repertoire_Courant=opendir(getcwd(NULL,0)); +/* +Ceci est à revoir... pas tout à fait géré pareil sous linux... + Attribut=(_A_NORMAL|_A_SUBDIR|//_A_RDONLY|_A_ARCH| + (_A_HIDDEN & Config.Lire_les_repertoires_caches)| + (_A_SYSTEM & Config.Lire_les_repertoires_systemes)); +*/ + Enreg=readdir(Repertoire_Courant); + while (Enreg) + { + // Si l'‚l‚ment n'est pas le r‚pertoire courant + if ( (strcmp(Enreg->d_name,".")!=0) && + // et que l'‚l‚ment trouv‚ est r‚ellement un r‚pertoire + (Enreg->d_type == DT_DIR) ) + { + // On rajoute le r‚pertore … la liste + Ajouter_element_a_la_liste(Enreg); + Liste_Nb_repertoires++; + } + // On cherche l'‚l‚ment suivant + Enreg=readdir(Repertoire_Courant); + } + + // Enfin, on lit les fichiers du format demand‚: + +/* +Ici aussi, à revoir... + Attribut=(_A_NORMAL|_A_SYSTEM|//_A_RDONLY|_A_ARCH| + (_A_HIDDEN & Config.Lire_les_fichiers_caches)); +*/ + + rewinddir(Repertoire_Courant); + Enreg=readdir(Repertoire_Courant); + while (Enreg) + { + if (Enreg->d_type==DT_REG) //Il s'agit bien d'un fichier + { + // On rajoute le fichier … la liste + Ajouter_element_a_la_liste(Enreg); + Liste_Nb_fichiers++; + } + // On cherche l'‚l‚ment suivant + Enreg=readdir(Repertoire_Courant); + } + + closedir(Repertoire_Courant); + + Liste_Nb_elements=Liste_Nb_repertoires+Liste_Nb_fichiers; +} + + +// -- Tri de la liste des fichiers et r‚pertoires --------------------------- +void Trier_la_liste_des_fichiers(void) +// Tri la liste chain‚e existante dans l'ordre suivant: +// +// * Les r‚pertoires d'abord, dans l'ordre alphab‚tique de leur nom +// * Les fichiers ensuite, dans l'ordre alphab‚tique de leur nom +{ + byte La_liste_est_triee; // Bool‚en "La liste est tri‚e" + byte Inversion; // Bool‚en "Il faut inverser les ‚l‚ments" + struct Element_de_liste_de_fileselect * Element_precedent; + struct Element_de_liste_de_fileselect * Element_courant; + struct Element_de_liste_de_fileselect * Element_suivant; + struct Element_de_liste_de_fileselect * Element_suivant_le_suivant; + + // Avant de trier quoi que ce soit, on v‚rifie qu'il y ait suffisamment + // d'‚l‚ments pour qu'il soit possibles qu'ils soient en d‚sordre: + if (Liste_Nb_elements>1) + { + do + { + // Par d‚faut, on considŠre que la liste est tri‚e + La_liste_est_triee=1; + + Element_courant=Liste_du_fileselect; + Element_suivant=Element_courant->Suivant; + + while ( (Element_courant!=NULL) && (Element_suivant!=NULL) ) + { + // On commence par supposer qu'il n'y pas pas besoin d'inversion + Inversion=0; + + // Ensuite, on v‚rifie si les deux ‚l‚ments sont bien dans l'ordre ou + // non: + + // Si l'‚l‚ment courant est un fichier est que le suivant est + // un r‚pertoire -> Inversion + if ( (Element_courant->Type==0) && (Element_suivant->Type==1) ) + Inversion=1; + // Si les deux ‚l‚ments sont de mˆme type et que le nom du suivant + // est plus petit que celui du courant -> Inversion + else if ( (Element_courant->Type==Element_suivant->Type) && + (strcmp(Element_courant->Nom,Element_suivant->Nom)>0) ) + Inversion=1; + + + if (Inversion) + { + // Si les deux ‚l‚ments n‚cessitent d'ˆtre invers‚: + + // On les inverses: + + // On note avant tout les ‚l‚ments qui encapsulent nos deux amis + Element_precedent =Element_courant->Precedent; + Element_suivant_le_suivant=Element_suivant->Suivant; + + // On permute le chaŒnage des deux ‚l‚ments entree eux + Element_courant->Suivant =Element_suivant_le_suivant; + Element_courant->Precedent=Element_suivant; + Element_suivant->Suivant =Element_courant; + Element_suivant->Precedent=Element_precedent; + + // On tente un chaŒnage des ‚l‚ments encapsulant les compŠres: + if (Element_precedent!=NULL) + Element_precedent->Suivant=Element_suivant; + if (Element_suivant_le_suivant!=NULL) + Element_suivant_le_suivant->Precedent=Element_courant; + + // On fait bien attention … modifier la tˆte de liste en cas de besoin + if (Element_courant==Liste_du_fileselect) + Liste_du_fileselect=Element_suivant; + + // Ensuite, on se pr‚pare … ‚tudier les ‚l‚ments pr‚c‚dents: + Element_courant=Element_precedent; + + // Et on constate que la liste n'‚tait pas encore g‚nialement tri‚e + La_liste_est_triee=0; + } + else + { + // Si les deux ‚l‚ments sont dans l'ordre: + + // On passe aux suivants + Element_courant=Element_courant->Suivant; + Element_suivant=Element_suivant->Suivant; + } + } + } + while (!La_liste_est_triee); + } +} + + +// -- Affichage des ‚l‚ments de la liste de fichier / r‚pertoire ------------ +void Afficher_la_liste_des_fichiers(short Decalage_premier,short Decalage_select) +// +// Decalage_premier = D‚calage entre le premier fichier visible dans le +// s‚lecteur et le premier fichier de la liste +// +// Decalage_select = D‚calage entre le premier fichier visible dans le +// s‚lecteur et le fichier s‚lectionn‚ dans la liste +// +{ + struct Element_de_liste_de_fileselect * Element_courant; + byte Indice; // Indice du fichier qu'on affiche (0 -> 9) + byte Couleur_texte; + byte Couleur_fond; + + + // On v‚rifie s'il y a au moins 1 fichier dans la liste: + if (Liste_Nb_elements>0) + { + // On commence par chercher … pointer sur le premier fichier visible: + Element_courant=Liste_du_fileselect; + for (;Decalage_premier>0;Decalage_premier--) + Element_courant=Element_courant->Suivant; + + // Pour chacun des 10 ‚l‚ments inscriptibles … l'‚cran + for (Indice=0;Indice<10;Indice++) + { + // S'il est s‚lectionn‚: + if (!Decalage_select) + { + // Si c'est un fichier + if (Element_courant->Type==0) + Couleur_texte=COULEUR_FICHIER_SELECT; + else + Couleur_texte=COULEUR_REPERTOIRE_SELECT; + + Couleur_fond=COULEUR_FOND_SELECT; + } + else + { + // Si c'est un fichier + if (Element_courant->Type==0) + Couleur_texte=COULEUR_FICHIER_NORMAL; + else + Couleur_texte=COULEUR_REPERTOIRE_NORMAL; + + Couleur_fond=COULEUR_FOND_NORMAL; + } + + // On affiche l'‚l‚ment + Print_dans_fenetre(9,90+(Indice<<3),Element_courant->Nom,Couleur_texte,Couleur_fond); + + // On passe … la ligne suivante + Decalage_select--; + Element_courant=Element_courant->Suivant; + if (!Element_courant) + break; + } // Fin de la boucle d'affichage + + } // Fin du test d'existence de fichiers +} + + +// -- R‚cup‚rer le libell‚ d'un ‚l‚ment de la liste ------------------------- +void Determiner_element_de_la_liste(short Decalage_premier,short Decalage_select,char * Libelle) +// +// Decalage_premier = D‚calage entre le premier fichier visible dans le +// s‚lecteur et le premier fichier de la liste +// +// Decalage_select = D‚calage entre le premier fichier visible dans le +// s‚lecteur et le fichier … r‚cup‚rer +// +// Libelle = Chaine de r‚ception du libell‚ de l'‚l‚ment +// +{ + struct Element_de_liste_de_fileselect * Element_courant; + char * Curseur; + + + // On v‚rifie s'il y a au moins 1 fichier dans la liste: + if (Liste_Nb_elements>0) + { + // On commence par chercher … pointer sur le premier fichier visible: + Element_courant=Liste_du_fileselect; + for (;Decalage_premier>0;Decalage_premier--) + Element_courant=Element_courant->Suivant; + + // Ensuite, on saute autant d'‚l‚ments que le d‚calage demand‚: + for (;Decalage_select>0;Decalage_select--) + Element_courant=Element_courant->Suivant; + + // On recopie la chaŒne en la d‚formatant (i.e. tous les chars sauf ' ') + for (Curseur=Element_courant->Nom;*Curseur!='\0';Curseur++) + if (*Curseur!=' ') + *(Libelle++)=*Curseur; + *Libelle='\0'; + } // Fin du test d'existence de fichiers +} + + +// ----------------- D‚placements dans la liste de fichiers ----------------- + +void Select_Scroll_Down(short * Decalage_premier,short * Decalage_select) +// Fait scroller vers le bas le s‚lecteur de fichier... (si possible) +{ + if ( ((*Decalage_select)<9) + && ( (*Decalage_select)+1 < Liste_Nb_elements ) ) + // Si la s‚lection peut descendre + Afficher_la_liste_des_fichiers(*Decalage_premier,++(*Decalage_select)); + else // Sinon, descendre la fenˆtre (si possible) + if ((*Decalage_premier)+100) + // Si la s‚lection peut monter + Afficher_la_liste_des_fichiers(*Decalage_premier,--(*Decalage_select)); + else // Sinon, monter la fenˆtre (si possible) + if ((*Decalage_premier)>0) + Afficher_la_liste_des_fichiers(--(*Decalage_premier),*Decalage_select); +} + + +void Select_Page_Down(short * Decalage_premier,short * Decalage_select) +{ + if (Liste_Nb_elements-1>*Decalage_premier+*Decalage_select) + { + if (*Decalage_select<9) + { + if (Liste_Nb_elements<10) + { + *Decalage_premier=0; + *Decalage_select=Liste_Nb_elements-1; + } + else *Decalage_select=9; + } + else + { + if (Liste_Nb_elements>*Decalage_premier+18) + *Decalage_premier+=9; + else + { + *Decalage_premier=Liste_Nb_elements-10; + *Decalage_select=9; + } + } + } + Afficher_la_liste_des_fichiers(*Decalage_premier,*Decalage_select); +} + + +void Select_Page_Up(short * Decalage_premier,short * Decalage_select) +{ + if (*Decalage_premier+*Decalage_select>0) + { + if (*Decalage_select>0) + *Decalage_select=0; + else + { + if (*Decalage_premier>9) + *Decalage_premier-=9; + else + *Decalage_premier=0; + } + } + Afficher_la_liste_des_fichiers(*Decalage_premier,*Decalage_select); +} + + +void Select_End(short * Decalage_premier,short * Decalage_select) +{ + if (Liste_Nb_elements<10) + { + *Decalage_premier=0; + *Decalage_select=Liste_Nb_elements-1; + } + else + { + *Decalage_premier=Liste_Nb_elements-10; + *Decalage_select=9; + } + Afficher_la_liste_des_fichiers(*Decalage_premier,*Decalage_select); +} + + +void Select_Home(short * Decalage_premier,short * Decalage_select) +{ + Afficher_la_liste_des_fichiers((*Decalage_premier)=0,(*Decalage_select)=0); +} + + + +short Calculer_decalage_click_dans_fileselector(void) +/* + Renvoie le d‚calage dans le s‚lecteur de fichier sur lequel on a click‚. + Renvoie le d‚calage du dernier fichier si on a click‚ au del…. + Renvoie -1 si le s‚lecteur est vide. +*/ +{ + short Decalage_calcule; + + Decalage_calcule=(((Mouse_Y-Fenetre_Pos_Y)/Menu_Facteur_Y)-90)>>3; + if (Decalage_calcule>=Liste_Nb_elements) + Decalage_calcule=Liste_Nb_elements-1; + + return Decalage_calcule; +} diff --git a/files.h b/files.h new file mode 100644 index 00000000..e8da20e8 --- /dev/null +++ b/files.h @@ -0,0 +1,33 @@ +// Modifie Principal_Repertoire_courant en y mettant sa nouvelle valeur +// (avec le nom du disque) +int Determiner_repertoire_courant(void); +// D‚termine si un r‚pertoire pass‚ en paramŠtre existe ou non dans le +// r‚pertoire courant. +int Repertoire_existe(char * Repertoire); +// D‚termine si un fichier pass‚ en paramŠtre existe ou non dans le +// r‚pertoire courant. +int Fichier_existe(char * Fichier); + +// -- Destruction de la liste chaŒn‚e --------------------------------------- +void Detruire_liste_du_fileselect(void); +// -- Lecture d'une liste de fichiers --------------------------------------- +void Lire_liste_des_fichiers(byte Format_demande); +// -- Tri de la liste des fichiers et r‚pertoires --------------------------- +void Trier_la_liste_des_fichiers(void); +// -- Affichage des ‚l‚ments de la liste de fichier / r‚pertoire ------------ +void Afficher_la_liste_des_fichiers(short Decalage_premier,short Decalage_select); +// -- R‚cup‚rer le libell‚ d'un ‚l‚ment de la liste ------------------------- +void Determiner_element_de_la_liste(short Decalage_premier,short Decalage_select,char * Libelle); + +// -- D‚placements dans la liste des fichiers ------------------------------- + +void Select_Scroll_Down(short * Decalage_premier,short * Decalage_select); +void Select_Scroll_Up (short * Decalage_premier,short * Decalage_select); +void Select_Page_Down (short * Decalage_premier,short * Decalage_select); +void Select_Page_Up (short * Decalage_premier,short * Decalage_select); +void Select_End (short * Decalage_premier,short * Decalage_select); +void Select_Home (short * Decalage_premier,short * Decalage_select); + +short Calculer_decalage_click_dans_fileselector(void); + +char * Nom_formate(char * Nom); diff --git a/gfx2.cfg b/gfx2.cfg new file mode 100644 index 00000000..a15e8851 Binary files /dev/null and b/gfx2.cfg differ diff --git a/gfx2.dat b/gfx2.dat new file mode 100644 index 00000000..24f77a13 --- /dev/null +++ b/gfx2.dat @@ -0,0 +1,322 @@ +Sunse^ nesCMDSuDsO^5DOYCr{F`{LpK5QZLVr{l`QLZa{ZLVXUhNYDRGwJ\FLExRITFW[zlr|uDby`vg/KjxbliTrmpfK D^siPnSFnsJt oesNgnpunlet;Dedig}Suase DbsidnSJQs^O sRsZTn|ZnXNtcePJgqLuuhec7Dv`ihaS~esbs GfsiXnSNnsRt wesFgnxunTetDeliguSuyseg DjsilnSrnsft {ZsR\ndBn@VtkeXBgItuMPek?D~hipySf}sj{ Onsn`nPvnsZt es^gn`un\et DeTigMSuqseo DrsitnSznsnt CesjXnlNnHRtwe@FgAxuETeSDFlixuSnysrg WjsflnXrntft#{esRcjd}f@ixTuY|rHJlLnxjeVLrDyd@]hFMSEl]TSJQsZt$a{^ob`y~\ua +Q|UpzLNTpR@nnpYGv@ax\ElBA_LiXnSJjw^|(siZw~|`{Y|mYxQHFpvPtYOajtA[jXe|TI`KDZsiXnTJn|Zt7{elVgIluALeCDZKiX^SJFsZT {}sVwnl}nLetDbLihQSbQszK cZsFXndJnLZt|eLYgQ{uQSeK8DZciXfSJntZt/{edVgqluILe[DRLiXQSJVsZD {MsVGnlmnLutLeLFOSPTZGL[PPuTNJEseHn3nrcOscpddlksXyopsiTrigbÿ'Csen`iTcnset DesignSunset DespszGgyin:^is~wKc{gvf2Vtcyw~Ce~jyh;_~hr{pSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset Dyo2{5Omzgq`4Pq`zszBipoyo7Pqtn`iGritbs'CbtnpnSunset DesignSunset Drg}sKotin:_yhuynSkri}b4Wwcyw~Anuh~n:]|nignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset{X>o2/{?)sqtOitgq`4Pq|}szGazgbs'CîtnqiTcxe}i DesignSunset DesignSunsq`3Pvkp~wJoth~oZ{mvxqLunset DesignSu4(9(=Yyou{rIazgv`4Pqg}szGazgbs«Cseq;Eonset DesignSunset DesignSuz`q`3S|jp~wInuh~h?Desiga\g|awf2Vv`zt}@f}e}oDydzt}@f}`vg3Wv`sgnSuwawf2Vwb{v|Ag|set ZxnsszGf}`vg4Wv`zquSunsej=X~k|szGazgq`'Pqgn`iTrigbs'Cbt~nSunset DesignSunset DesignSunset Sq`zt}Eltin;Xyor{sMixgpa5Qpg}t}@fzgvg3Pqg|r{Iiuo~b4Pqg}szGazgqb>Zye}s{F`{fpa5Qp`~Ygzt}@azgqa5QsktgpNirira4Pqg}szGazgq`4Pbtn`iTritbs'_esignSunset DesignSunset DesignSunsem4Wv`ztxJoti~h(5g0 +0set~;siyxGaz`q`3PvgzuvHoumet Dei}szGazgq`4Pqi7gyGazgè`4Vw`zsrSunset D;signMhro|`4Pqg}s/{;s79nSun-;* Dek}t}@f}`vg3Wvcs~wJhnset=Qqg}szGazgq`8;j}szGaã`wf3WqktgnSunset Den5;2Da) ;signSunset:Qv`zt}@f}`vg3T}js|rOoyssg3Wv`}szGaze{*f;5>Ga#5`rPqf|r{Ecxesb6R}itgnSunset}>(2Bd>`qatQseqxEcxki~;-ignS+ns;)z?*0yDbydrc7S}kqpyDmrset DesignSunset DesignSunset DesignSunsei9Sbtn`iTritbs'Cbtn`iTritbb6Rse`iØþåøîø¬Èéÿå?5+nse*~8.5;3(3/9n¯ËucæwáCú|üwûz?(2<5.5üud0Têcyè|Ügá)?i¯ËëüçéàÞûzýél~;-490 *1se*~î#y7A'zfpa5RseptNu0-;*~Des49nSu1-8(z=+qyDbydrc7SrkrynSunset DesignSunset DesignSunset DesignSuns{h9Rbtn`iTritbs'Cbtn`iTcxerc7Srts<4 +-6+?(}esignSu0-;)}8/5;2 /4*< x1#:28-6*<-y=+109#; 5 u2+1?7 +,7*?.|9/3;3(0-;*~;-79n +0se,wTu#xtDesignSunset DesignSunset DesignSunset DesignSunset<^}d`iTrxd}m:_bepyDmvk}c«\=$>=2+0-;*~;-793(3.8)|>)?7~Üeácuû0Tucyw~Ce~cud0Tucyw~Ce~cuû0Tucæw~C%4)9(|9/4:3(3.9*~;-7gnS+4//z?)?è~Üe~cêd0Tucy>5,4/8)zucyw~Ce~cêd¯Tê+3=4)2/9)}8.790,3-;*~Des7:5!5cwgrQse{nSu2*;)}8(2;3(0-;*~;-i;nunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunse*}>+7gnS+3-;*~;-790 (3.8)~;-4;2.5(>.z3cyw~Ce~cud0T3(1<2(3/9-0TucywáCe~cê&y9/5<4 (3.8*~:,7:0 +0-;*~8(>:3g}gpb6Xesig3 (2(9/y8.4;0 (0-;* 9s4g2+n/8* 9.ignSunset DesignSunset DesignSunset DesignSunset DesignSunset Desig0 +0-;(y9.4:0 +3/8)}8.4:3(3.;*~9/2<5 /7*3'pTêcyw~Ce~cu&x>/5;2)5"ud0Tucyw~Ce~&2.|>(5:3 +0-;+;-7;0 +2(?/~8-5;yFcxi{t Des2;3(0-8t D;/493 u0-9(}e.4:nu3s9t}DesignSunset DesignSunset DesignSunset DesignSunset DesignSun-;t~e-793 +3(>)};s4<3)3/9(|9/5;2(3.9/z?)0>7#:!ud0Tucyw~Ce>*>.|>(5<6e~cud0Tucæw~-6'?/{8.794 +0-8*~;-7;3(0,et 8.pqxIknset 8.2:0 +nset ;signu3s8t}D8s4:0S(3.8t DesignSunset DesignSunset DesignSunset DesignSunset DesignS+0-;*~D;-793)4+;*};-792)2/9({>(3?3(7/9.z=+0=4e~cud¯Tucyw~.5)>.{=*>w~Ce~cud¯Tuü>>7 +/4)>({8.4:2 +0-;*~8-ignSun-9) Zykq}pMnnse({8.79nSunset De-ignS(nset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset Design u0set~8.5;3(3(;*~D;-4;3)5/?/{9)5;2)5(>/{>)1wáCe~cud0Tuc==4 /6$0.zucyw~Ce~cud0?)3;2 )2.8)}8-795(2.8)}8-790+nset>_}krgnSuns;*~esignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset Design +0-;)};.4;2(3-;*~8.4:3(2)9)}8/2<5)5(?.zucyw~Üeácud0T1*0?<"9%0d0Tucyw~Ce~cu'w?/5<2.6/9)}9.4;2+0-;t D;-ignSun-et DesignS+0-et De-ignSnse DesSe +esignSunset DesignSunset DesignSunset DesignSunset Desig0 +n-e*~;-490(3-;*~e.7g0 (3(8*~;-4:3(3.9(|>.4:3/8cêd0Têcyè~Üe~üuû0Tucyw~Ce~cud¯TucæwáÜe~cu$w9/3;2)2/8*~:,681 unset Desig0 unset DesignS+n-et DesSet + +siSu +t DesignSunset DesignSunset DesignSunset DesignSunset Desi90 unset~;.4;0+3.8)}8/2<5(0-;*~;-4:0)2(>(|;.2<4 /4)?.z<*0?6 -9+=,x6+:?7-7*?.y=$>09 ,4)9(|8.5;2(0-:+:signSunset DesignSunset DesignSunset D +sin.z?)3=5 +"9$0!x?)3=7 /4(>/|9.4:3(3.8)}8.790 *1,:t DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSu0-et e-790 (3-;*~;-ign u0-8)}8.490 +3.8)}8/5;2)2/9)}9(0?4 /5(9(|9(3<5)2/8*~8.4:3(3.;*~:,6gnSunset DesignSunset DesignSunset DesignSe +ei/y9/5:3(0-;)|9/4:3 *1,;*}8-4:3 +0-;+:,6gnSunset DesignSunset DesignSunset Desi¹cYW^SM~K!0T]¯¡•³s²¢Æ£‡gR5E¿© D û™Suf³¢ö8EsW®­µMeLL‚£µ¯¡nS‹neŠ D}kvS n³]r„eiaV“Mhs›t'HikqvSmvk}D¤esqgSmnse@xDQ+igvwQvset DesqnSunsed DesfofÃ%>Se,`AWignkqvSYt DesQ_VSunset DesignSunsetÏñÓ#VSM¥›²\|e—™/M~suL\ºKygVk£¥uL T]—~kunsuL0Des—™€•›et!7Qgn­³ÔÉß²ÞDkuïæÛnK!0T]ciwvGe~thQ_£rKeV7£0Te󉟫•îsgzº[}kg~k ~]d (  n?uR'1@4PqsqGv{EfCet 8ignCMcL0ºuKw~Cencud08]cigf_‹b{et d GnSu.3%4\DesA ?]nsud|—g/ VKud DesignSuvkud0D}s SunseLº  nC ¾sˆ0D#ß1W +™ñnK LV˜©ivcunset8tUCYWvSEvk}l8tes=_k!nsel8:}kignSuns}lDesgnSunset tUskabKE³eHFг•¯nKMvk}lDµo{±ÉnO#h,Bãi¹itÞ„•oo¡SI™²æ8eokvKE^s²î8ƒµgR5Puã DekqgvKuns}l \}Ce^3Evet 8eign3Ev}D@Dõo{^SEnO'îŠØ%Oikrgµ£tØ=?/a’SIµ¥´Fxe‹¥!(5–s[@¼¥³g“• x3§«¢/u¬±£ŠÂ†§si[vKE^ e +8\)¿¥n•¹¶ƒ¸æD 3 n±ƒŠú†§±ia¨µ²¿©t 8ƒµ¯¡S‰¨5#ˆ@$e¯¡¸ hs¸ì¼½½¯g‘rµã ºucyW^cuµ£²æ‚s¯¡¨5Vcer¦Ò±#n•›VKºæD£½W“µn il$¥ i_^cE^C]t „CqkhSMvk}l8|ekUnSunset Des—g^cmnset De e¨-u®³½æ‚™sigR5µ¨er&2«µ¯nSuR›´\Dkkq^cEnseæŠu§®“¨µ£t8DYkYWSynoix,ˆ©«¶£­ s}l0tUCugnS™¸¥£² De¯5unsYæ‚sig’•³ˆ¯¥t :£µ§hSu²•£´àDesWRÕ nk} +tUoign5³¨µt D£¿_~Sun£¢Þ(esi¡‚k¨setæ‚«onS âKˆ \UC W^Kuvk}l8\}sYv_mvCetF’©signCMµçöÞDY©§¨/meæ‚£ i^o³t(¡Sn iæ:eCqb/³s]\XHµgnS ¨³lP| O™®/usYÞ„sYR5‹®e |}CYnknK}lDUki_vKIneh µi_FoA + £t8t³‘§SunŸw +°:eE1?‹­°s] 8£µgn?uµ£ t}s¡¨/uVeæ‚sYn5³¨e ‚£½a?uR£²\D s¡¨• nk}H@$Ykqy^c ^›tæ(]y~S…¶ƒ©ºì‚e}qRKmžs}DXHµgvcuVk}H \Us¡¨/uvCeæ‚s]?ne@xDµ«nS b£ + 8eO¡¨/ukelP„£ig5.3et 8awmcnSóâëUâÀkõåÿ^;¿àq}t8\}kqg|wWwt AE_C&SuÄsÏtŠDÏsÃ2Äß;Ù0ÞßîšÙ–Í‘Ce~cud0Tucy—~Ce~cu„0´ucyOF{F[M\ De‹AOF{unƒu„0Tu[Af»]F[M\lM[AOnSf›M\lM›aŸnSuF[MŒ DesywžC…nset D•cyw~Ce~let Ducy˜nSunsetßTucyw~Cj~cud DeŒignSe~cšd0Tucyx~Le~cM\kM[AOF{ZNLet DeLIHF{]F[ŠtßDesig‘SšF[M\kE\AOFSu‘sšt DM[†g{]Fcu‹ »esiOF{Šnset Dšs–w~Cunsš\lM[AOQSunsud?TzsignSj~lud0DesVOF{]F[M‹lM[yw‘CŠ~cud0T•signSunlud0TšŒ–˜‘¬Š‘set »šŒ–—ž£…žƒ•„/Kj|fha\Š‘Œšt Des ‘òσ syB(µ•畳®³¥´ º  •uUl&›si¦Ÿ¹¢ eBr©çnS²cUDD]cQ#*keV£²Þ‚£i¨Ñ÷¨‹t"U ¥«Su÷ŠLDe{±¸… Ns[ລWgV?³¨µ£² D›s—gSuvkl8Ds©_hkµner„]ui™nTybk}l8D}kq^c•ns}t^D}sigZ uZ+et8`AkignSuns}l Desig~Sunsj|(Ô5#Ig6wQJWet |akI[nSuns]LDesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunsbs'CetignSunset DesignSunset DesignSunses'DesignSunset DbtignSunset DesignSunset DbsngnSuitbs'Desi`nTunses'CbtignSrntet DesignSunjbm Cesi`wTuises'Cbtn`nSrnt|s Deti~iJunset Desi`iSuwtet'Cejn~nSunjbm Desp`wSrises9DetngnSunset ]bjn`wSuijbm9Cesp`wTliset D|tpgnSunt|s DesignSunset Desi~iSunset']esignSunset DesignSunset DesignSunset DesignSuwtbs']esn~nSliset DesignSunset DesignSunset Desi`wSuwtet9Cbtn~nSunset DesignSunses9C|tignJrit|t Dbtn`iSunjbs']esi`wTliset DesignSuntet Desi`nSunsbs'CbsignSrnset DetignSunset DesignSunset DesignSuns|s DesigiJunset DesignSunset DesignSuntet Desi`nSunset'DesignSunset DesignSunset DesignSunset DetignSunset DesignSunset DesignSliset D|tpgnSuwt|t Dejn~nSunsbm DesignSunset9Cbtn~nSrwjbm'Detp`wSrnsbs9D|tigwTrit|t DesignSunset Desi`nSuises'CbtngnSunses DesignSunset Desi`nJritet'Dbji`nSrntet'Detp`nSrns|s9DetignSunset CesigiSuiset CesngiSuises9C|jngnJrwtbm DesignSuntbs'DesignSrnset DetignSuntbs'DesigiSunset DesigiTrnsbt CetigiSuisbt CesngiJlises ]btpgnSunset D|tn`iJunt|s ]bsi`nTuntet'Dbjp`nSlnjbs9DesignSunsbt DesigiSunset Cejn`iSuijbm Desn`wSunset DesignJrwtbm Dbjn~wTuntes Dbsi`wTlwtet9C|tn~nSunset Dejn~nSlnsbm'DetigiSrnsbt C|ti~iSuwtbs']esignSunset DesignSunset DetigiSunset DesignSunset DesignSunset DesignSunset D|tignTunt|t DesignSunset DesignSunset ]bjignSlijbm D|tpgwTlnt|t D|tignSunset DesignSuntes Desi`nTunset'DbsignSunset DesignSunset Desn~nSuwtem']ejn~nSlijbm Desp`wSunset Desi~iSunset']esignSrnjbt'Detp`wSuns|s9DesignSunset ]btn`wSuijet9CesngiTuises9CbsngnJrites DesignSunjbs'Cbsi`wSrnset'DetignSrwsbt Dejn`iTrnset DesigiTritbt CetigiSuisbt Cesn~iJlisem']btpgnSunset Dejn`iJunjbm ]bsi`wSuntet'Desi`nSrnset'DesignSunsbs'CbtigiSunsbt C|sigiSuwt|t9Cesi~iTrwset DesignTritbs DbsngnTuntes Dbsi`nSuntet'Desi`nSunset Detn`iTrnsbt'DesigiSrnset CesignSuiset DesignSunset9CbtpgnJrws|s DbjignTuntet'Dbsi`nSritet DesignSritbs'Desi`nSunset'DesignSrnset Cbtn`iSunset DesignSunses DesngnTritbs DbsignTunset DesignSunset Detn~nSunsem'DetignJrnsbs'CbjigiSunset DesignSuitbs'Cesi~iJunsem']bjignTlnjbm DesigwTunset Desi`iTritet Desi`nSunset'DesignSrnset DetignSunset Cbtn`iSuwt|t Desi~iJunsem']esignTritbs DesignSuntbs'Cbsi~iJunset ]bjignSunjbm Detn`iTrnset DesignJrit|t ]bji~iSuijet Cesn~nSlisem'CbtpgnSunset Dbtn`iTuntet'Desi`nSrnset']|tignSlit|t DesignSunsem'CbjigwTlnjbt C|sn~iSuijem']esp`iTliset DesignTritbs Dbsi`wSuntet'C|si`wJrwtet9Cbji`nSunset Dejn~nSrnsbm'DetigiSrnsbt Cetp~iSuis|s']esignSunses DesignTunset Dbtn`iTuntet Desi`nSunset DesignSritbs9DesignJrnset DetignSunjbt Cbtn`wSunset Desn`iJunset ]btpgnSuns|s Desp`iJuntbs9DesignSunset'Cbtn`nSuns|s9Desi~iJunset ]bjigiTritbt DesignSuijem'Cesp`wTlnset9C|signJrwt|t Dbji~iTunset Desi`iJunset ]bjignSunjbs'Desp`wSunsbs9DesignSunset Cesp`iSuis|s9Cesn~iJuises']esngnTlnses DesignSunset DesignSunset'Cbtn`nSrnset'DesignSunset DesignTlnset D|tpgnSuns|s9DesignJrwset DejngnSunset DesignSunset Desi`nSuntet'Cbtn`nSunset DesignSunset DesngnSunses DesignTunset DbsignSuntet DesignSunset DesignSunt|t Desi~iSunset DesignSunset DespgwTlnses C|tignTuisbt DbjngiSunjbs'CesignSunses'CbtngnSuises DesngnTunses9]bsignJrijet DesignSuwtbs9Desn~nJrnses DetignTunjbt D|si`wSunset DesigwTrwset C|jngnSuises DesngnTuntbs'CbsignSunset ]btn~nSuijbm'DesngiSrnses9CetignJrisbt DesignSunses Desp`iTrites9DbsignTuntet DbsignSunset DesigwTrijes C|sp`nTuiset'DbsngnSrwtes'Cbtn~nSunset Cbtn`iSunsbt DesigiSunset C|signSuwtbs DesignSunset DesignJunjet'Dbtn`nSunset9DesignSunset DesignSunset'DesignSrns|t D|tngiTrit|t DesignSunset DesignSuntbs'CbsignJrwset ]bjn~nSuijem'DesignSunset DesignSunset Cbtn`wSunset9CesignSunset DesignSritbs DetpgnSuns|s'DesigiJunset ]btn`nSunset Desn`iTrnses DesignTunset DbjignSunjbs'CesignSunset9CbtpgnSrws|s DetignTunsbm ]bsigwTrijet DesignSuitbs'CbsngnSrnses DetignTlnjbt D|tn`wSunset Desi~iTrwset']ejngnSrnses DetignTunsbs'CbtngnSunset Cbtn`nSuwt|t Desn~nSunses9DesignJriset DesignSunjbm Cesi`wTuiset'DbsngnSrnt|s Deti~iJunset DesigiSunset'Cbtn~nSuisem'DesngnSrnset DetignSunset Dbtn`wSunset9CesignSuiset DesngnSritbs DesignSunsbs9DesignJrijet Desp`nSunjbs9Desn`wSunset DesignTrit|t Desi~iSunses']esignSliset'CbtpgnSunset DetpgwTuns|s9C|signJrwset ]bjn~nSuijem'DesignSunses'Cbji`nSunjbt'DesigiSrnset C|ti`iTrit|t DesignSrns|s Deti~iTunsbm']bsigiTlntet C|si`nSunset DesignSunset9C|sigwTrwtbm C|sigwTuiset DbsignSunset DesignSunset Dbtn`iTrnset DesignSunset DesignSunset DetignSuisbm DejngwTrwtbm Dejn~nSunset Desi~iTrwsem']ejngiTlnses9CbsignTrwtet DbsignSunset Dbtn~nSrnsem'DesignSrnsbt DetignSritbt DesignSunjbs']esi`wTlisem'DbsngnTrntes Dejn`nTunset DesignJuwt|t9Cbsn~iSrwtes Cejn`wTuiset9CbtngnSunset D|sp`wSuites9Cesp`nTuiset'DbsngnSlitbs DesignSuns|s'C|sigiJuwt|s Cesi`iJuisem']espgnTlnset DesignSlitbm ]btp`wTuijbt'Dbsp`iJrntet ]bti`nSunset Dejn`iJuntbm']bsigiSrntet'C|ti`nSuwtbt'DesignSunsem'CbjigiTlijbt ]bsngiSunt|s Cesi~iTuiset DesignSrnjbm Detp`wTuns|s'CbsigiJrntet ]bti`nSunset Desi~iTlns|s']|tigiJrnsbt ]btp~iSuns|s']esignSunset DbtpgnJrns|s DbjignTunjbt DbsignSritet DesignSuntbs9DetpgnJrns|s DetignSunsbt Detn`iSunset Desnha\zase{9Djsign\un|et DjjihnSuntj{/KjsignSunset/Kj|fhnSzn|et/De|ihnSznsjs/C||igi\ra|bt DesignSuntj{/CesnhwSlase{9Desfgn\unse{ Djsign\unset Desiha\za|et/DesihnSzwset/Detf~nJznses/KjtignSunset Kj|fhaSuasjt KesfgaSuase{ Desfgn\unse{ DesignSun|j{/Kjsihn\unset/DjsignSznset De|ignSunset DesignTza|bt Cjji~aSuajet Kesfgn\uase{ Dj|fgnSunset Dj|fha\unse{ Design\unset DjsignSza|j{/DesignSunset DesigaSunsjt Kj|fhaSuaset KesignSunset DesignSun|js Desigw\un|et ]jsiha\zatet/DesignSunset De|fha\znsem/]esigw\lajet K|sphwSuwset9KesignSunse{/Kj|fgnSunse{ Design\unset DjsignSun|et DesignSza|j{/Dejf~nSunsem/]esigw\lnset Kj|fhaSunset Desfha\zasem/]esignSlajet DesphwSun|j{/KjsignSunset Cj|f`nSrajem/De|pgnSznsjm D||igi\za|bt DesignSua|j{/Kesfgn\unse{ Djsign\lw|et Db|f`nSunset Desigi\zatet'K|sphnSzwsjm/De|pgw\rnsb{/Kb|ignSunset Kj|fhaSuase{9Desfgn\zwse{9]jtfgnTzate{ DesignSuntjs Djsihw\un|et/DjsihnSzn||m/De|i`a\rnset DesigaSunset KesignSua|j{/KesfgnSunse{ DesignSunset Dj|fhaTunset ]jsignSun|et DesphnSza|j{'DesignSunsj{/CesignSla||t Desi`aSuns|{/]esfhaTunset Design\za|j{ Desi~aJunsem/]esignSlajet/Kj|fhnSunset De|pgw\zns|{9K|signJzwset ]jjf~nSuajem/KesignSunse{/]esignSlajet Despha\uns|{9DesihaJunset DesignSzns|{/De|i~aJznsjm/]e|iga\lnsjt K|sigaSunset DesignSunset DjsignSun|et DesihnSunset DesignSunset DesignSunset DesignSznset DesignSunset DesignSunset9KesignJzwset ]jjignSlajet De|pgnSunset Desi`a\zatet/]||phnSzw||t/De|f~nJznsb{/KjtignSunset DesignSun|et Kesfha\zaset DesfgnSunset DesignSun|es/Kjsihn\ln|et/DjsihnSzw|et/Detf`nSznset DesigaSunsjt KesigaSuasjt Kesf~aJlases/Cj|ngnSunset Dj|fhnSunset/DesignSznset Dj|fhnSunsjt DesignSunsj{/De|igaSznsjt Ke|igaSuasjm9Kesfgi\ziset DesignTza|js Djjfgw\un|e{ Djsihn\lw|et9Db|f`nSunset De|ignSunsjt DesigaSla|jt K||pgnSua||t DesignSunses/Cj|ngn\laj|{ Djsfgn\un||{9]jsi`aTzatet DesignSratet9De|phnSznsjt/De|igaJznjjt Cj|fhiSunset DesignSunset DesignSznsjt DesignSunset DesignSunset'KesignSzwset De|i`aSznsjm/]esigi\rnset DesignSuntj{/Kj|nha\za|j{/Kj|fha\rnset/DjsignSzn|et De|ihnSunsjt/CesigaSza|j{/Kjtfha\za|es/Kj|fhnSunset Kj|fha\za|j{/Kj|fha\za|j{ Desihn\unset/DjsignSzn|et De|ihiSuntjs/Kj|fha\ra|j{/Cjsnha\rntet DesignTza|j{/Cj|fha\za|j{/Kj|f`nSunse{ Design\unset DjsignSun|bt Desiha\unset'KjsignSui|et DesignSunsj{/Kj|fha\za|j{/Kj|fha\zaset DesfgnSunse{ Design\rnset Dj|ngnSuntj{/Kj|fgi\za|j{ Db|fha\unset De|fha\za|j{/Kj|fha\za|j{/Kesign\uaset DjsfgnSun|e{ Desihn\unset/DjsignSun|et DesihnSunset DesignSza|j{/Kj|fha\za|j{/Kj|fhaSunse{ Kesign\uaset DjsfgnSun|e{ Desihn\unset DjsignSun|et DesignSunset Cj|fha\ra|j{/Kj|fha\za|js DesigaSunset KesignSuaset Djsf`nSun|e{/KesihaTzaset/KetfgnSzaset Desiha\za|j{/Kj|fha\za|j{/KjsignSuaset DesfgnSunse{ Design\unset Djsfha\za|j{/Kj|fha\za|j{/KesignSunset DesignSunset DesignSunset De|fha\za|j{/Kj|fha\za|j{/DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset Desiga\za|j{/Kj|fha\za|j{/Kj|ignSunset Design\za|j{/Kj|fha\za|j{/Kj|fgnSuw||t DejfhaJunjj{/Kjspha\la||{/K|spha\zwset9KjjignSuajet DesignSunse{/Kj|fha\za|j{/Kj|fha\zaset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset Desfha\za|j{/Kj|fha\za|j{/K||fhwSuns|{/K|signJza||t ]j|f~nSla|jm De|fha\za|j{/Kj|fha\za|j{/DesignSua|j{/Kj|fha\za|j{/Kj|fhaJza||t DejfhaJunsem/KjjignSla|jm Despha\za|j{/Kj|fha\za|j{/Kj|fhnSunset Db|fha\zi|j{/Kj|fha\za|j{'Design\unset DjsignSun|et DesihiSunset/Kj|fha\ra|j{/Kjsnha\za|et Desiga\za|j{/Kj|fha\za|j{/Kj|fgnSun|e{ Desihn\unset/DjsignSzn|bt Db|iha\za|jt'Kj|fhiSui|j{'DesignSunses/Kj|fhi\za|j{/Kj|fha\zatet DesfgnSunse{ Design\unset DjtignSun|j{/Kj|f`a\za|j{ Cj|fha\unset De|fha\za|j{/Kj|fha\za|j{/Kesign\uaset DjsfgnSun|e{ Desiha\rnses/Kj|fha\zatj{/Kjtigi\zatet DesignSui|j{'Detfha\zisj{/Kj|fgaTunsb{ Kesign\uaset DjsfgnSun|e{'Desihi\zaset/Kb|fgnSrasb{ DesngnSunset/DesignSznset De|ignSunsjt Desiga\za|j{/Kj|fha\za|j{/Kj|fgnSunse{ Design\unset DjsignSunset Desiha\za|j{/Kj|fha\za|j{/KjsignSunset DesignSunset DesignSunset Desfha\za|j{/Kj|fha\za|j{/KesignSun|j{/Kj|fha\za|j{/Kj|fha\unset DesignSunset DesignSunset DesignSua|j{/Kj|fha\za|j{/Kj|fhaSunset Dj|fha\un|j{/Kjsiha\za|et DesignSunset DesignSunset DesignSunset Kj|fhaSua|j{/Kesfha\zaset Design\za|j{ Dj|fha\un|j{/KjsignSun|et DesihnSunset/DesignSznset Db|iga\za|jt Kj|fhiSua|j{'DesignSunse{/Kjtign\za|js Dj|fha\unset CjsignSun|et DesihnSunset/DesignTznset Kj|ignSua|bt Desf`nSunset Desfha\zase{/Kj|fgn\za|j{ Design\unset DjsignSun|et DesihnSunses/De|fha\znsj{/Kjtiga\zatet DesignSua|j{/Kesfha\zase{/Kj|fgnSunse{ Design\unset DjsignSun|et DesihnSunset/DesignSznset De|ignSunset Kj|fhaSua|j{/Kesfha\zaset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset Desiga\zatet Kj|fhiSua|j{/KesignSraset DesfgnSunse{ Design\unset Djsiha\za|et/Kj|fhnSza|j{/DesignSunsj{/Kj|iga\za|jt Kj|fhaSunset DesignSunset DesignSunset DesignSun|j{/Kjsiha\za|et/Kj|fhnSunset DesignSunset DesignSunset DesignSua|j{/Kesfha\zase{/Kj|fgnSunset DesignSunset DesignSunset DesignSua|js Desfha\rnse{/Kj|ignSuntjt DesigaSunset KesignSrase{/Kj|fgn\za|js Dj|fhiSunset DesignSunset/Kj|fhnSza|j{/De|fha\znset DesignSunset ]esignSuajet DesfhiSunse{/Kj|fgnSza|j{ Desnha\unset Desiha\za|et/Kj|fhnSza|j{/DesignSznset De|ignSunsjt DesigaSunset KesignSuaset DesfgnSunse{ DesignSun|j{/Kjsiha\za|et/Kj|fhnSunset DesignSunset DesignSunset DesignSua|j{/Kesfha\zase{/Kj|fgnSunset Dj|fha\un|j{/Kjsiha\za|et DesignSunset DesignSunset DesigwSunset Kj|fhaSua|j{/Kesfha\zaset Design\za|bt Dj|fhaTun|j{/KjsignSui|et DesihnSunset/DesignSznset Db|iga\za|jt Kj|fhiSua|j{'DesignSunse{/Kj|fgn\za|j{ Dj|fha\unset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset Desfha\rnse{/Kj|ngn\za|j{ Desigi\unse{9Djsign\zw|et Db|fhnSunsb{/]e|fha\zasj{/Kjtfga\zates DesignSua|j{/Kesfha\zase{/Kj|fgnSunset DesignSunset DesignSunset/CesignSza|j{/De|fha\znses/Kj|ignSunset Desf`nSunse{/Cesign\zaset DetfgnSunse{ Design\unset DjsignSui|et/Kj|fhnSza|j{'De|fhaTunset DesignSunset DesignSunset DesignSunse{/Kj|fgn\za|j{ Dj|fha\unset DesignSunset DesignSunset DesignSunsj{/Kbsiga\za|bt Kj|fhaSunset'KesignSuaset DesfgnSunse{ Desigi\un|j{/Kjsiha\zatet/Kj|ngnSunset DetignSunsj{ Desiga\zwset Cj|f~nSunjj{/]esigw\zaset9Kj|pgnTza||t Dj|f~nSun|jt Desi`nSunset DesignSza|j{/Kj|fha\za|j{/Kj|fhnSunset DesignSunset DejignSunset Design\za|j{/Kj|fha\za|j{/Kj|fgnSunset/KbsignSza|jt De|fha\lnjet'Kj|phnSuw|j{/Desi~a\znsem/Kj|igi\zajj{/Kj|pgw\za|et Dj|ngnSunset DesihaTunset/Kj|ignSza|j{9Desi`a\zwset ]j|fhnSunjj{/Despha\znsb{/K|sfha\zwse{/Kjsign\ziset DesignSun|et DesihnSunset/DesignJznset ]j|ignSla|jt D||fhaSuw|j{9KetfhaJua|j{/]esfha\unse{/CesignSunset DesignSunset DesignSunset DesigaSunset KesignSuaset DesfgnSunse{ DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DespgnSuns|{ Desi~a\unsem/Kjsigw\zajet9Kj|pgnJza||t Dj|f~nSunset Desi`a\za|js/Kj|fha\za|j{/KjtignJza|et ]j|fhnSla|jm/D||fhwSzi|j{9De|fha\za|b{/Kj|fhnTza|j{/DesignSunset DesignSunset DesignJznset Dj|fha\za|j{/Kj|fha\za|j{ DesignSunset DesignSunset DesignSunset Db|ignSri|jt Db|fhaSun|j{'Desihi\unset/DjsignSzn|et De|ihiSuntjt/Kj|fhaSra|j{/Cesnha\rnset DesignTznset Cj|ignSua|jt Desf`nSun|e{ Desihn\unset/DjsignSzn|bt Db|nha\za|j{'Kj|fhi\ui|j{'DbsignSunsj{/Kj|fga\za|j{ Kj|fha\unset DjsignSun|et DesihnSunsj{/Kesiga\zaset Kj|fgnSunsjt DesigaSunset De|fha\zasj{/Kj|fga\za|j{ Kesign\uaset DjsfgnSun|e{ Desihn\unset/CjsignSza|et DetfhnSunses DesignSui|j{/Kjtfha\za|j{/Kj|fhaTunse{ Kesign\uaset DjsfgnSun|e{'Desihi\zaset/Kb|fgnSrasb{ DesngnSunset/DesignSznset De|ignSunsjt DesigaSuns|s/Kesi`a\zas|{/Kj|f~a\zije{/Kjjign\zajet Dj|pgnSunset Desigi\zates'Kj|fhi\za|j{/Kj|ngnSratjt DesfgaSunse{ Kesign\uatet Cjtfha\za|js/Kj|f`aSra|js CesignSunsb{/Kbsi`a\za|bt/Kj|fhaSziset'Ke|ignSuasjt DesfgaSunse{ Kbsign\ua|j{/Kj|nha\za|jt'Kj|fhaSunset DesignSunset DesignSunset DesignSunset'KbsignSza|et Detf`nSunset DesignSunset DesignSunset DesignSraset Db|fgnSun|j{ DesihiSunset/DesignTznset Cj|ignSua|js Detf`a\za|j{ Cj|fhaTuntj{/CesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset Desfha\zase{/Kj|fgn\za|j{ DejfhaJunjj{/]esiha\lnset9Kj|pgnSuw|j{9De|fha\znsj{/Kj|iga\za|jt DesignSunsb{/Kesiha\zase{/Kj|fgn\zijet DjjignSunjet DesihwSunset/KbjignSza|j{/Desfha\znset'Kj|ignSunset DesignSunset DesignSunset Design\za|j{ Dj|fha\un|j{/KjsignSunset DesignSunset DesignSunset DesignSra|jt Dj|fhaSua|j{/KesfhiSuase{9DesfgnJunse{ Design\unset DjsignSun|et DesihnSunset/DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunses/Cesign\zaset Db|ngnSunset DesignSunset DesignSunset DesignSunjj{/Despha\lns|{/K|siga\zwset KjjignSuajet DespgnSunset DesignSunset DesignSunset DesignSunset/Kj|ngnSza|j{'De|fha\znsjm Db|igwSunsjt DesigaSunset KesignSrase{/Kj|fgn\za|js Dj|fhiSunset DesignSunset DesignSunset DesignSznsj{/Kj|iga\za|jt Kj|fhaSunset KesignSunset DesignSunset DesignSun|j{/Kjsiha\za|et/Kj|fhnSunset/DesignSznset De|ignSunsjt DesigaSunset KesignSuaset DesfgnSunset DesihiSunset/KbsignSza|et DesnhnSunset/DesignSznset De|ignSuntjt Kj|fhaSua|j{/Cesfha\rnset DesignSunset DesignSunset DesignSunset DesignSunset De|fha\znsj{/Kj|iga\za|jt DesignSunset DesignSunset DjtignSun|js Desiha\unset CjsignSun|et DesihnSunset/DesignTznsj{/Kj|iga\za|bt Kj|f`nSunset Desfha\rnse{/Kj|ngn\za|j{ Desigi\unset DjsignSun|et DesihnSunses/De|fha\znsj{/Kjtiga\zatet DesignSunset DesignSunset DesignSunset Dj|fha\un|j{/Kjsiha\za|et DesignSunset DesignSunset DesignSunset Kj|f`nSua|j{/Cesfha\zaset DetfgnSunse{ Design\unset DjsignSui|et/Kj|fhnSza|j{'De|fhaTunset DesignSuatet DesfhiSunse{/KesignSraset DesfgnSunse{ Design\unset Cjsiha\za|et/Kj|f`nSza|js DesignSunset DesignSunset DesignSunset DesignTziset Dj|fgnSuntjs DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSua|es/Cesfhn\zase{/Db|ngnSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunset DesignSunsetjá  ~~~~~~ "# + Z[~jkbcfgfg ¦§¦§¦§¦§¦§¦§89NO,-67‚ƒ¦§’“Š‹ŽŽ*}qn~u}rvj}nv~u}r„{n|xu~}rxwponmr}x{)#NOXQHFGSB  AX35.3%4$%3)'."# &'$%z{01NO4523<=RSPQ¢£€{r}}nwjwmmn|rpwnmk‚‘'p~ruuj~vnmx{vntj{uvj{r}j~m'@KH@R2NAHMRNM@KH@R8 -@M$OQNFQ@LLDQOQNFQ@LLDQ$'&8@QSHRS€€vr|lnuujwnx~|‘+4GHRHRNTQUDQXEHQRSOQNFQ@LBNLOHKDCHM7@SBNL# ,,NV KDUDKQNTSHMDRVDQDVQHSSDMHM&!RRDLAKDQNOSHLHYDCENQ @MC&BNLOHKDCVHSG"NQK@MC4!3- ,7DVDQDHMROHQDCAXSGD83DS-NCDQNTSHMD,EQNL8,)"SNBQD@SDLNQD@L@YHMFUHCDNQDRNKTSHNMR,4G@MJRSN%BKHORDENQSGDHQ%/3CNRDWSDMCDQ7%/3KHSD ,3NLDHMENQL@SHNMS@JDMEQNLRDUDQ@KCNBR,0#'0% )MSDQUTD 0#)MSDQCHS F@UDTR@MHMU@KT@AKDGDKO&4G@MJRSN3G@VM(@QFQD@UDRENQGHR,EHKKDCONKXFNMQNTSHMDEQNL!KKDFQNU)4G@MJRSN#@QKNR-@CD0@QCNENQGHRFQD@S'Q@E8KNFN+!SGNTR@MCSG@MJRSNSGD@TSGNQRNESGD!CHEEDQDMSSGHMFRKHRSDC@ANUD'7D@KRNVNTKCKHJDSNSG@MJ@KKSGD&ODNOKDVGNF@UDTRHCD@RSNHLOQNUD +'Q@E8€€orunox{vj}|l{nmr}|‘0+-3TMRDS$DRHFM,"-%KDBSQNMHB!QSR')&#NLOTRDQUD"-0-HBQNRNES0#8: 3NES)-'"HU@R77HDCL@MM 3#W#NKNQHW (#%, +#&+/3+)3DJ@D3DSRXRSDL 0) 0#$DF@R%KHSD0!,DQLLGMNANCX €€¦XY~&'~&'&'~()$%~|}¦:;HI€¦§RSHI¦§01HIFGRS,-01RS¦§TUPQ¦§¤¥ |wjruvjru‘'5),,!5-%$/2-%2NAHMRNM  QTDCDKNARDQU@SNHQD,)-/'%3&2!.#% +!2,-!2)4!5$8 -@M  QTDCDK@"Q@RRDQHD,)-/'%3&2!.#% n„vjru‘CNQLD LRHTMHKHLEQL@QHS@TC DMRHKTMHKHLEQ€€¨()$%  $%$%~ + "#&'z{¨TUPQ45BC45PQPQ¦§<=FG67HINODE,-RS<=HIFG¢£3NTQBDRHYD@ANTS+A&'Q@E8RAHQSGC@SD*TKXSG€€–XY~() $%z{–@AFGHI€FG¦§./TU89PQ¢£* #SQK #RSNORSGDOQNFQ@LVGDMXNT(@QDDMSDQHMFU@KTDR3NCNMSOQDRR&SGDRDJDXRTMSHKVDEHWSGHRATF, !EDVCHEEDQDMSJDXBNLAHM@SHNMRQDSTQMSGDR@LDBNCD, !QDCEK@RG@OOD@QR@SRS@QSTOVGDM@MDLOSX:HOCQHUDHRENTMC( 3NLDETMBSHNMR@QDMSEHMHRGDCXDS*4GHRHRMNQL@KENQ@"DS@UDQRHNM RNCNMSVNQQX+"TSHEXNTRSHKKEHMCRNLDATFRHMSGD(MDWSUDQRHNMR SGDMVDC@OOQDBH@SD+SG@SXNTSDKKTRVG@SSGDXDW@BSKX@QD!@MCGNV@MCVGDMSGDXNBBTQ-dš"# $%&' "# ~|}šNO4589<=PQRS45NO<=FG89¦§¤¥9NTKKOQNA@AKXR@X($NDRSGHRLD@MSG@S)G@UDSNO@X!MCVDKKQDOKXSNXNT.N¬ "# + Z[~jkbcfgfg~$%~ + "#  XY"# ¬89NO,-67‚ƒ¦§’“Š‹ŽŽ¦§<=PQ¦§67NO4545€,-NO45 "TS ATS ATS+#NMRHCDQHMFSGD@LNTMSNEVNQJ@MCKNUD +VDOTSHMSGHROQNFQ@L VDVNTKCDWSQDLDKX+@OOQDBH@SDSG@SXNTFHUDTRRNLDSGHMFHM%DWBG@MFDENQSGDTRDXNTL@JDNEHS),DSRR@XRNLDLNMDX NQ@MHBDOHBSTQD'XNTCQDVVHSG'Q@E8 NQ@ONRSB@QC+)EXNTL@JDOQNEHSVHSG@MHL@FDXNTCQDV+VHSG'Q@E8 HSVNTKCADFQD@SHEXNTRDMS,TRSGHROHBSTQD)EXNTTRDCHSENQ@F@LD ,VNTKCADVHRDQMNSSNRDMC@KKXNTQFQ@OGR 'VG@S@ANTSRDMCHMF@BNOXNESGDF@LD€€ª + "#  XY"# ~*+ &'$%z{ª67NO4545€,-NO45¦§01HIFGVW45FGRS<=HIFGPQ¢£+4GHRUDQRHNMNE'Q@E8HRADHMFQDKD@RDCSNXNT@RHR(!KKATFRRGNTKCADQDONQSDCSNDHSGDQ2NAHMRNMNQ8 -@M)4GD@TSGNQRS@JDMNQDRONMRHAHKHSXENQ(KNRSVNQJ NQC@L@FDCDPTHOLDMSB@TRDC)CHQDBSKXNQHMCHQDBSKXAXSGHROQNFQ@L''Q@E8B@MMNSADLNCHEHDCHM@MXV@XVHSGNTSNTQVQHSSDMBNMRDMS,&HM@KKX SGDBG@QFHMFNELNMDS@QXEDDRAX,@MXTM@TSGNQHYDCO@QSXENQSGDBHQBTK@SHNM%NQTRDNESGHRTSHKHSXHRDWOQDRRKX ENQAHCCDM(4GHRLD@MRSG@SHEXNTG@CSNO@XENQ)FDSSHMF'Q@E8 XNTG@UDADDMRVHMCKDC7p” "#  &' $%z{”89NO4545RS<=FG89PQ¢£/TQADRSQDF@QCRFNSN"!BBDRR&HKSDQ0HMJ#!BD&HUDQ0HWDK$!BHC*@L&K@M0QNEHK%!BQXK&QDC0QNVKDQ$!KDWDK&QDCCX60TYMHJ#!KH@R&QNRS1THBJ !LHQ@K'@dK'$# 2@$!QQ@JHR'@HM82@RSDQ$!UNB@CN'@MC@KE2@UH@M$"@KNN'NAKHM2DC"TF!"@QSH'QDDMOHW2DL!"@S'QHC2DY'"HQN'QNR1THBJ2NTCNTCNT'"HRNTMNTQR(@BJDQ#QNKK3@BQHKDFD!"K@BJ!WD(@OKN3@L%"NMMHD(NE3@MC-@M#"NN(NQMDS3B@OD'"NY(TKTC3_A@RSHDM$#@QHMD*@U@3GNC@M"#G@MCQ@*"43J@K%#GDDS@G*_QgLD3JXEHQD$#GHKK*TKHDM*#! 3OG@HQ&#NTF@Q+@K-HM$N3OQNBJDS"#QDL@W+@MD7NNC3SDE##XBKNMD+@QL@3SNMX&$@JD+DHSG3TL@KDSG$$@MMX,@YTQ3TMC@X"$@MTAD,HFGS3GNV3TMX%$@QITK,KTUH@3XA@QHR!$@QVHM,NTHD4"&%$@QJ!MFDK,TJ4DLODRS"$@R-@CD4GNQ!$DBJDQ-@LNR4-+%$DQ0HHON-@MCQHWW4VN&@BD'$DRSNO-@MFTD5MCDQJHMF$$H@ANKN-@QR5MQD@K'$HMD3-DOGHRSN6@D6HBSHR&$Q@B-DQBTQD6@RS@SNQ#$Q9DR-HQDB6@SHM%%CXW-N@6DBJL@M"%KKDQ-NWHB@7@HM#%KKXM-2+7@KKX$%/&.HSBG7HKK"D$&@KK.N@K8NNLHD"&@LD.XSQHJ8SQL&&@MSNL/OSHB9@MM3TKT&D@Q/QNLD:!&D@SGDQ0@GK@CHM:DA#&DMMDB0G@Q:DAHF&@MC@KKOHWDK CDLNEQ@MCBNCDQR###### GrafX2 initialization file ###### Fichier d'initialisation de GrafX2 ## +# # # # +# You may modify this file with any # Vous pouvez modifier ce fichier avec # +# standard ASCII text editor. # n'importe quel ‚diteur de texte # +# # ASCII standard. # +# # # +# Comments are preceded by ';' or # Les commentaires sont pr‚c‚d‚s par # +# '#'. # ';' ou '#'. # +# # # +# Options are not case sensitive and # Les options ne sont pas sensibles … # +# spaces are ignored. # la casse et les espaces sont ignor‚s.# +# # # +# You must not change the order of # Vous ne devez pas changer l'ordre # +# the sections and their options. # des sections et de leurs options. # +# You must not delete or put into # Vous ne devez pas effacer ou mettre # +# comment any section nor option. # en commentaire une section ou option.# +# # # +# Each option is preceded by a # Chaque option est pr‚c‚d‚e par un # +# comment which explains its meaning. # commentaire qui explique sa fonction.# +# # # +############################################################################## + + + +[MOUSE] # [SOURIS] + + ; The sensitivity of the mouse can ³ La sensibilit‚ de la souris peut + ; take values from 1 to 64. The ³ prendre des valeurs de 1 … 64. Plus + ; smaller values, the faster. ³ les valeurs sont petites, plus c'est + ; ³ rapide. + X_sensitivity = 3 ; (default 3) + Y_sensitivity = 3 ; (default 3) + + ; Due to the fact that those stupid ³ A cause du fait que ces imb‚ciles de + ; mouse drivers' makers don't care ³ programmeurs de gestionnaires de + ; if the mouse moves by steps of 2, ³ souris se fichent que votre souris se + ; 4 or even 8 pixels, we have to ³ deplace par pas de 2, 4 ou mˆme 8 + ; stretch the virtual area of the ³ pixels, nous devons ‚largir la zone + ; mouse and divide coordinates to ³ virtuelle de la souris et diviser les + ; get a one-pixel step motion. ³ coordonn‚es pour obtenir un pas de 1. + ; (Warning: the mouse movement can ³ (Attention: le d‚placement de la + ; be correct in some video modes ³ souris peut ˆtre correct dans certains + ; but not in others... But all the ³ modes vid‚os mais pas dans d'autres... + ; "Modes X" should behave the same ³ Mais tout les Modes X devraient se + ; way, so you won't have to test ³ comporter de la mˆme maniŠre, donc + ; them all). ³ vous n'aurez pas … tous les tester. + ; A correction factor of 0 means ³ Un facteur de correction de 0 signifie + ; that you are very lucky because ³ que vous avez de la chace car votre + ; your driver doesn't need any ³ driver n'a pas besoin de correction. + ; correction. If you set the ³ Si vous d‚finissez le facteur de + ; correction factor to 1, it means ³ correction … 1, cela signifie que + ; that your mouse moves by steps of ³ votre souris se d‚place par pas de 2 + ; 2 pixels; 2 for 4; 3 for 8, etc...³ pixels; 2 pour 4; 3 pour 8, etc... + ; If you want to use GrafX2 in a ³ Si vous d‚sirez lancer GrafX2 dans une + ; Win95 window, you should turn ³ fenˆtre Windows95, vous devriez passer + ; these values to 0 (and increase X ³ ces valeurs … 0 (et augmenter les sen- + ; and Y sensitivities above). ³ sibilit‚s X et Y d‚finies plus haut). + X_correction_factor = 3 ; (default 3) + Y_correction_factor = 3 ; (default 3) + + ; Aspect of the main cursor (cross) ³ Aspect du curseur principal (croix) + ; 1: Solid ³ 1: Solide + ; 2: Transparent ³ 2: Transparent + ; 3: Thin (solid) ³ 3: Fin (solide) + Cursor_aspect = 1 ; (default 1) + + + +[MENU] # [MENU] + + ; Colors of the menus (the black ³ Couleurs des menus (la couleur noire + ; and the white colors cannot be ³ et la couleur blanche ne peuvent pas + ; modified). ³ ˆtre modifi‚es). + ; Values are in {Red,Green,Blue} ³ Les valeurs sont dans l'ordre {Rouge, + ; order and are between 0 and 63. ³ Vert,Bleu} et vont de 0 … 63. + Light_color = 42,42,42 ; (default 42,42,42) + Dark_color = 27,27,27 ; (default 27,27,27) + ; + ; Light_color = 24,25,30 ; \_ Nightmare + ; Dark_color = 13,14,19 ; / + ; + ; Light_color = 10,45,28 ; \_ Forest + ; Dark_color = 5,27,12 ; / + ; + ; Light_color = 48,41,26 ; \_ Gold + ; Dark_color = 26,22,15 ; / + ; + ; Light_color = 10,40,55 ; \_ Oceanic + ; Dark_color = 10,20,32 ; / + + ; Aspect ratio and size of the ³ Proportion des menus et de la barre + ; menus and the tool-bar. ³ d'outils. + ; Possible values: ³ Valeurs possibles: + ; 0: Do not adapt (pixels are not ³ 0: Ne pas adapter (les pixels ne sont + ; stretched) ³ pas ‚tir‚s) + ; 1: Adapt the menus and the tool- ³ 1: Adapter les menus et la barre + ; bar according to the resolution³ d'outils suivant la r‚solution + ; 2: Slightly adapt the ratio of ³ 2: Adapter l‚gŠrement les proportions + ; the menus and tool-bar ³ des menus et de la barre d'outils + Menu_ratio = 1 ; (default 1) + + ; Font: ³ Police de caractŠres (fonte): + ; 1: Classic ³ 1: Classique + ; 2: Fun ³ 2: Fun + Font = 1 ; (default 1) + + + +[FILE_SELECTOR] # [SELECTEUR_DE_FICHIERS] + + ; Show special files and ³ Afficher les fichiers et r‚pertoires + ; directories (values are 'yes' or ³ sp‚ciaux (les valeurs sont 'yes' ou + ; 'no'). ³ 'no'). + Show_hidden_files = no ; (default 'no') + Show_hidden_directories = no ; (default 'no') + Show_system_directories = no ; (default 'no') + + ; Delay before displaying a preview ³ D‚lai avant d'afficher une preview + ; in file-selectors (in 18.2th of ³ dans les s‚lecteurs de fichiers (en + ; second). Possible values range ³ 18.2Šmes de seconde) Les valeurs + ; from 1 to 256. ³ possibles vont de 1 … 256. + Preview_delay = 8 ; (default 8) + + ; Maximize the preview of the ³ Maximiser la preview des images pour + ; pictures so that it is as big as ³ qu'elle soit aussi grande que + ; possible. If you're not in the ³ possible. + ; same resolution as the picture's ³ Si vous n'ˆtes pas dans la mˆme r‚so- + ; one, it can try to correct the ³ lution que celle de l'image, cela peut + ; aspect ratio, but if the picture ³ essayer de corriger les proportions, + ; does not fill the whole screen, ³ mais si l'image ne prend pas tout + ; it can be worse. ³ l'‚cran, cela peut ˆtre pire. + Maximize_preview = no ; (default 'no') + + ; This option is used to place the ³ Cette option est utilis‚e pour placer + ; selection bar on a filename by ³ la barre de s‚lection sur un nom de + ; typing its first letters. ³ fichier en tapant ses 1Šres lettres. + ; For example, if you want to find ³ Par exemple, si vous voulez trouver le + ; the "PICTURE.PKM" in a directory ³ fichier "PICTURE.PKM" dans un r‚per- + ; that also contains "PALETTE.PAL", ³ toire contenant ‚galement le fichier + ; you'll just have to type P and I. ³ "PALETTE.PAL", vous n'aurez qu'… taper + ; The different values of "FFF" ³ P puis I. + ; indicate if you want to find the ³ Les different valeurs de "FFF" + ; name in both files and directories³ indiquent si vous voulez trouvez le nom + ; or just in only one of these: ³ dans les fichiers ET les r‚pertoires ou + ; 0: files and directories ³ simplement dans l'un OU l'autre. + ; 1: files only ³ 0: fichiers et r‚pertoires + ; 2: directories only ³ 1: fichiers seulement + ; ³ 2: r‚pertoires seulement + Find_file_fast = 0 ; (default 0) + + +[LOADING] # [CHARGEMENT] + + ; Automatically set the resolution ³ Passer automatiquement dans la bonne + ; when loading a picture. ³ r‚solution lors du chargement d'une + ; You should set this value to ³ image. + ; 'yes' after disabling the video ³ Vous devriez d‚finir cette option … + ; modes that are not supported by ³ 'yes' aprŠs avoir inhib‚ les modes + ; your video card or monitor. ³ vid‚o qui ne sont pas support‚s par + ; ³ votre mat‚riel. + Auto_set_resolution = no ; (default 'no') + + ; If the variable above is set to ³ Si la variable ci-dessus est … 'yes', + ; 'yes', this one tells if you want ³ celle-ci indique si vous voulez + ; to set the resolution according ³ d‚finir la r‚solution suivant: + ; to: ³ 1: les dimensions de "l'‚cran + ; 1: the internal "original screen" ³ d'origine" internes … l'image + ; dimensions of the picture ³ 2: les v‚ritables dimensions de + ; 2: the actual dimensions of the ³ l'image + ; picture ³ + Set_resolution_according_to = 1 ; (default 1) + + ; If you load a picture with a ³ Si vous chargez une image ayant une + ; palette of less than 256 colors, ³ palette de moins de 256 couleurs, + ; this option defines if you want ³ cette option indique si vous souhaitez + ; to clear the palette or to keep ³ effacer la palette ou bien conserver + ; the colors of the previous ³ les couleurs de l'image pr‚c‚dente qui + ; picture that are over the number ³ se situent au-del… du nombre de la + ; of colors of the new picture. ³ nouvelle image. + ; For example, if you load a ³ Par exemple, si vous chargez une image + ; 32-color picture, the colors 32 ³ de 32 couleurs, les couleurs 32 … 255 + ; to 255 will be set to black if ³ seront pass‚es en noir si cette option + ; this option is set to 'yes', or ³ est … 'yes', ou bien elles resteront + ; they will be kept unchanged if ³ inchang‚es si elle est … 'no'. + ; this option is set to 'no'. ³ + Clear_palette = yes ; (default 'yes') + + +[MISCELLANEOUS] # [DIVERS] + + ; Draw the limits of the picture. ³ Afficher les limites de l'image + Draw_limits = yes ; (default 'yes') + + ; Adjust the brush grabbing in ³ Ajuster la capture de brosse en mode + ; "grid" mode. ³ "grille". + Adjust_brush_pick = yes ; (default 'yes') + + ; Coordinates: ³ Coordonn‚es: + ; 1: Relative ³ 1: Relatives + ; 2: Absolute ³ 2: Absolues + Coordinates = 1 ; (default 1) + + ; Create a backup file when saving. ³ Cr‚er un fichier backup lors des + ; ³ sauvegardes. + Backup = no ; (default 'no') + + ; Number of pages stored in memory ³ Nombre de pages stock‚es en m‚moire + ; for "undoing". ³ destin‚es … annuler les derniŠres + ; Values are between 1 and 99. ³ modifications. Valeurs entre 1 et 99. + Undo_pages = 1 ; (default 1) + + ; Speed of the scroll-bars (in VBLs ³ Vitesse des barre de d‚filement (en + ; waited) while clicking with the ³ VBLs attendus) lorsque l'un des + ; left or right button of the mouse.³ boutons de la souris est enfonc‚. + ; Values can be between 1 and 255. ³ Les valeurs sont comprises entre 1 et + ; The bigger values, the slower. ³ 255. Plus elles sont grandes, plus + ; ³ c'est lent. + Gauges_scrolling_speed_Left = 10 ; (default 10) + Gauges_scrolling_speed_Right = 3 ; (default 3) + + ; Automatically save the configu- ³ Enregistre automatiquement la configu- + ; ration when exiting the program. ³ ration lorsqu'on quitte le programme. + Auto_save = yes ; (default 'yes') + + ; Maximum number of vertices used ³ Nombre maximum de vertex utilis‚s dans + ; in filled polygons and polyforms, ³ les polyg“nes et polyformes pleins, et + ; and lasso. Possible values range ³ le lasso. Les valeurs possibles vont + ; from 2 to 16384. ³ de 2 … 16384. + ; Each vertex takes 4 bytes. ³ Chaque vertex prend 4 octets. + Vertices_per_polygon = 1024 ; (default 1024) + + ; Automatically zoom into the ³ Zoomer automatiquement la zone point‚e + ; pointed area when you press the ³ par la souris lorsque vous appuyez sur + ; short-key of the Magnifier button ³ la touche de raccourci de la loupe. + ; while being above the picture. ³ + Fast_zoom = yes ; (default 'yes') + + ; Separate the colors in the tool- ³ S‚parer les couleurs dans la barre + ; bar by a black squaring. ³ d'outils par un quadrillage noir. + Separate_colors = yes ; (default 'yes') + + ; Initial value of the feedback for ³ Valeur initiale du "feedback" pour les + ; the drawing modes (cf. docs). ³ modes de dessin (cf. docs). + FX_feedback = yes ; (default 'yes') + + ; When you reduce the palette or ³ Si vous r‚duisez la palette ou "zappez" + ; "zap" some colors out of it, it is³ quelques couleurs, il est possible + ; possible that there are not enough³ qu'il ne reste pas assez de couleurs + ; colors left to draw the menus. ³ pour afficher les menus. Mettre cette + ; Switching the following variable ³ variable … 'yes' ramŠnera automatiquent + ; on will bring back the colors of ³ les couleurs du menu s'il reste moins + ; the menu if there are less than 4 ³ de 4 couleurs aprŠs une "r‚duction" ou + ; colors left after "reducing" or ³ un "zapping". + ; "zapping". ³ + Safety_colors = yes ; (default 'yes') + + ; Display a message at startup ³ Afficher un message au d‚marrage + ; telling the version number of the ³ indiquant le num‚ro de version du + ; program. ³ programme. + Opening_message = yes ; (default 'yes') + + ; Take the Stencil into account when³ Prendre le Stencil en compte lorsqu'on + ; clearing the image. ³ efface l'image. + Clear_with_stencil = yes ; (default 'yes') + + ; Directly set the discontinuous ³ Passer automatiquement en mode de + ; freehand drawing mode after brush ³ dessin discontinu aprŠs la prise d'une + ; grabbing. ³ brosse. + Auto_discontinuous = no ; (default 'no') + + ; Save the screen dimensions in GIF ³ Sauver les dimensions de l'‚cran dans + ; files. If you want to read these ³ les fichiers GIF. Si vous voulez lire + ; files with Photoshop or Alchemy, ³ ces fichiers avec Photoshop ou Alchemy, + ; and maybe some other programs, you³ et peut-ˆtre d'autres programmes, vous + ; must set this option to 'no'. ³ devez mettre cette option … 'no'. + Save_screen_size_in_GIF = no ; (default 'no') + + ; Automaticaly count the number of ³ Compter automatiquement le nombre de + ; different colors used when opening³ couleurs diff‚rentes utilis‚es lors de + ; the palette editor window. (Set it³ d'ouverture de la fenˆtre d'‚dition de + ; to 'no' if you have a slow PC or ³ la palette. (Mettez-le … 'no' si vous + ; if you edit huge pictures) ³ avez un PC lent ou bien si vous ‚ditez + ; ³ d'‚normes images). + Auto_nb_colors_used = yes ; (default 'yes') + + ; Number of the default video mode ³ Num‚ro du mode vid‚o par d‚faut au + ; at startup (see the list by typing³ d‚marrage (voir la liste en tapant + ; "gfx2 /?" at the DOS prompt). ³ "gfx2 /?" sur la ligne de commande). + Default_video_mode = 0 ; (default 0) diff --git a/gfx2.gif b/gfx2.gif new file mode 100644 index 00000000..bd327aab Binary files /dev/null and b/gfx2.gif differ diff --git a/gfx2.ico b/gfx2.ico new file mode 100644 index 00000000..0c78ce5e Binary files /dev/null and b/gfx2.ico differ diff --git a/gfx2.ini b/gfx2.ini new file mode 100644 index 00000000..ff02bc72 --- /dev/null +++ b/gfx2.ini @@ -0,0 +1,289 @@ +###### GrafX2 initialization file ###### Fichier d'initialisation de GrafX2 ## +# # # # +# You may modify this file with any # Vous pouvez modifier ce fichier avec # +# standard ASCII text editor. # n'importe quel ‚diteur de texte # +# # ASCII standard. # +# # # +# Comments are preceded by ';' or # Les commentaires sont pr‚c‚d‚s par # +# '#'. # ';' ou '#'. # +# # # +# Options are not case sensitive and # Les options ne sont pas sensibles … # +# spaces are ignored. # la casse et les espaces sont ignor‚s.# +# # # +# You must not change the order of # Vous ne devez pas changer l'ordre # +# the sections and their options. # des sections et de leurs options. # +# You must not delete or put into # Vous ne devez pas effacer ou mettre # +# comment any section nor option. # en commentaire une section ou option.# +# # # +# Each option is preceded by a # Chaque option est pr‚c‚d‚e par un # +# comment which explains its meaning. # commentaire qui explique sa fonction.# +# # # +############################################################################## + + + +[MOUSE] # [SOURIS] + + ; The sensitivity of the mouse can ³ La sensibilit‚ de la souris peut + ; take values from 1 to 64. The ³ prendre des valeurs de 1 … 64. Plus + ; smaller values, the faster. ³ les valeurs sont petites, plus c'est + ; ³ rapide. + X_sensitivity = 3 ; (default 3) + Y_sensitivity = 3 ; (default 3) + + ; Due to the fact that those stupid ³ A cause du fait que ces imb‚ciles de + ; mouse drivers' makers don't care ³ programmeurs de gestionnaires de + ; if the mouse moves by steps of 2, ³ souris se fichent que votre souris se + ; 4 or even 8 pixels, we have to ³ deplace par pas de 2, 4 ou mˆme 8 + ; stretch the virtual area of the ³ pixels, nous devons ‚largir la zone + ; mouse and divide coordinates to ³ virtuelle de la souris et diviser les + ; get a one-pixel step motion. ³ coordonn‚es pour obtenir un pas de 1. + ; (Warning: the mouse movement can ³ (Attention: le d‚placement de la + ; be correct in some video modes ³ souris peut ˆtre correct dans certains + ; but not in others... But all the ³ modes vid‚os mais pas dans d'autres... + ; "Modes X" should behave the same ³ Mais tout les Modes X devraient se + ; way, so you won't have to test ³ comporter de la mˆme maniŠre, donc + ; them all). ³ vous n'aurez pas … tous les tester. + ; A correction factor of 0 means ³ Un facteur de correction de 0 signifie + ; that you are very lucky because ³ que vous avez de la chace car votre + ; your driver doesn't need any ³ driver n'a pas besoin de correction. + ; correction. If you set the ³ Si vous d‚finissez le facteur de + ; correction factor to 1, it means ³ correction … 1, cela signifie que + ; that your mouse moves by steps of ³ votre souris se d‚place par pas de 2 + ; 2 pixels; 2 for 4; 3 for 8, etc...³ pixels; 2 pour 4; 3 pour 8, etc... + ; If you want to use GrafX2 in a ³ Si vous d‚sirez lancer GrafX2 dans une + ; Win95 window, you should turn ³ fenˆtre Windows95, vous devriez passer + ; these values to 0 (and increase X ³ ces valeurs … 0 (et augmenter les sen- + ; and Y sensitivities above). ³ sibilit‚s X et Y d‚finies plus haut). + X_correction_factor = 3 ; (default 3) + Y_correction_factor = 3 ; (default 3) + + ; Aspect of the main cursor (cross) ³ Aspect du curseur principal (croix) + ; 1: Solid ³ 1: Solide + ; 2: Transparent ³ 2: Transparent + ; 3: Thin (solid) ³ 3: Fin (solide) + Cursor_aspect = 1 ; (default 1) + + + +[MENU] # [MENU] + + ; Colors of the menus (the black ³ Couleurs des menus (la couleur noire + ; and the white colors cannot be ³ et la couleur blanche ne peuvent pas + ; modified). ³ ˆtre modifi‚es). + ; Values are in {Red,Green,Blue} ³ Les valeurs sont dans l'ordre {Rouge, + ; order and are between 0 and 63. ³ Vert,Bleu} et vont de 0 … 63. + Light_color = 42,42,42 ; (default 42,42,42) + Dark_color = 27,27,27 ; (default 27,27,27) + ; + ; Light_color = 24,25,30 ; \_ Nightmare + ; Dark_color = 13,14,19 ; / + ; + ; Light_color = 10,45,28 ; \_ Forest + ; Dark_color = 5,27,12 ; / + ; + ; Light_color = 48,41,26 ; \_ Gold + ; Dark_color = 26,22,15 ; / + ; + ; Light_color = 10,40,55 ; \_ Oceanic + ; Dark_color = 10,20,32 ; / + + ; Aspect ratio and size of the ³ Proportion des menus et de la barre + ; menus and the tool-bar. ³ d'outils. + ; Possible values: ³ Valeurs possibles: + ; 0: Do not adapt (pixels are not ³ 0: Ne pas adapter (les pixels ne sont + ; stretched) ³ pas ‚tir‚s) + ; 1: Adapt the menus and the tool- ³ 1: Adapter les menus et la barre + ; bar according to the resolution³ d'outils suivant la r‚solution + ; 2: Slightly adapt the ratio of ³ 2: Adapter l‚gŠrement les proportions + ; the menus and tool-bar ³ des menus et de la barre d'outils + Menu_ratio = 1 ; (default 1) + + ; Font: ³ Police de caractŠres (fonte): + ; 1: Classic ³ 1: Classique + ; 2: Fun ³ 2: Fun + Font = 1 ; (default 1) + + + +[FILE_SELECTOR] # [SELECTEUR_DE_FICHIERS] + + ; Show special files and ³ Afficher les fichiers et r‚pertoires + ; directories (values are 'yes' or ³ sp‚ciaux (les valeurs sont 'yes' ou + ; 'no'). ³ 'no'). + Show_hidden_files = no ; (default 'no') + Show_hidden_directories = no ; (default 'no') + Show_system_directories = no ; (default 'no') + + ; Delay before displaying a preview ³ D‚lai avant d'afficher une preview + ; in file-selectors (in 18.2th of ³ dans les s‚lecteurs de fichiers (en + ; second). Possible values range ³ 18.2Šmes de seconde) Les valeurs + ; from 1 to 256. ³ possibles vont de 1 … 256. + Preview_delay = 8 ; (default 8) + + ; Maximize the preview of the ³ Maximiser la preview des images pour + ; pictures so that it is as big as ³ qu'elle soit aussi grande que + ; possible. If you're not in the ³ possible. + ; same resolution as the picture's ³ Si vous n'ˆtes pas dans la mˆme r‚so- + ; one, it can try to correct the ³ lution que celle de l'image, cela peut + ; aspect ratio, but if the picture ³ essayer de corriger les proportions, + ; does not fill the whole screen, ³ mais si l'image ne prend pas tout + ; it can be worse. ³ l'‚cran, cela peut ˆtre pire. + Maximize_preview = no ; (default 'no') + + ; This option is used to place the ³ Cette option est utilis‚e pour placer + ; selection bar on a filename by ³ la barre de s‚lection sur un nom de + ; typing its first letters. ³ fichier en tapant ses 1Šres lettres. + ; For example, if you want to find ³ Par exemple, si vous voulez trouver le + ; the "PICTURE.PKM" in a directory ³ fichier "PICTURE.PKM" dans un r‚per- + ; that also contains "PALETTE.PAL", ³ toire contenant ‚galement le fichier + ; you'll just have to type P and I. ³ "PALETTE.PAL", vous n'aurez qu'… taper + ; The different values of "FFF" ³ P puis I. + ; indicate if you want to find the ³ Les different valeurs de "FFF" + ; name in both files and directories³ indiquent si vous voulez trouvez le nom + ; or just in only one of these: ³ dans les fichiers ET les r‚pertoires ou + ; 0: files and directories ³ simplement dans l'un OU l'autre. + ; 1: files only ³ 0: fichiers et r‚pertoires + ; 2: directories only ³ 1: fichiers seulement + ; ³ 2: r‚pertoires seulement + Find_file_fast = 0 ; (default 0) + + +[LOADING] # [CHARGEMENT] + + ; Automatically set the resolution ³ Passer automatiquement dans la bonne + ; when loading a picture. ³ r‚solution lors du chargement d'une + ; You should set this value to ³ image. + ; 'yes' after disabling the video ³ Vous devriez d‚finir cette option … + ; modes that are not supported by ³ 'yes' aprŠs avoir inhib‚ les modes + ; your video card or monitor. ³ vid‚o qui ne sont pas support‚s par + ; ³ votre mat‚riel. + Auto_set_resolution = no ; (default 'no') + + ; If the variable above is set to ³ Si la variable ci-dessus est … 'yes', + ; 'yes', this one tells if you want ³ celle-ci indique si vous voulez + ; to set the resolution according ³ d‚finir la r‚solution suivant: + ; to: ³ 1: les dimensions de "l'‚cran + ; 1: the internal "original screen" ³ d'origine" internes … l'image + ; dimensions of the picture ³ 2: les v‚ritables dimensions de + ; 2: the actual dimensions of the ³ l'image + ; picture ³ + Set_resolution_according_to = 1 ; (default 1) + + ; If you load a picture with a ³ Si vous chargez une image ayant une + ; palette of less than 256 colors, ³ palette de moins de 256 couleurs, + ; this option defines if you want ³ cette option indique si vous souhaitez + ; to clear the palette or to keep ³ effacer la palette ou bien conserver + ; the colors of the previous ³ les couleurs de l'image pr‚c‚dente qui + ; picture that are over the number ³ se situent au-del… du nombre de la + ; of colors of the new picture. ³ nouvelle image. + ; For example, if you load a ³ Par exemple, si vous chargez une image + ; 32-color picture, the colors 32 ³ de 32 couleurs, les couleurs 32 … 255 + ; to 255 will be set to black if ³ seront pass‚es en noir si cette option + ; this option is set to 'yes', or ³ est … 'yes', ou bien elles resteront + ; they will be kept unchanged if ³ inchang‚es si elle est … 'no'. + ; this option is set to 'no'. ³ + Clear_palette = yes ; (default 'yes') + + +[MISCELLANEOUS] # [DIVERS] + + ; Draw the limits of the picture. ³ Afficher les limites de l'image + Draw_limits = yes ; (default 'yes') + + ; Adjust the brush grabbing in ³ Ajuster la capture de brosse en mode + ; "grid" mode. ³ "grille". + Adjust_brush_pick = yes ; (default 'yes') + + ; Coordinates: ³ Coordonn‚es: + ; 1: Relative ³ 1: Relatives + ; 2: Absolute ³ 2: Absolues + Coordinates = 1 ; (default 1) + + ; Create a backup file when saving. ³ Cr‚er un fichier backup lors des + ; ³ sauvegardes. + Backup = no ; (default 'no') + + ; Number of pages stored in memory ³ Nombre de pages stock‚es en m‚moire + ; for "undoing". ³ destin‚es … annuler les derniŠres + ; Values are between 1 and 99. ³ modifications. Valeurs entre 1 et 99. + Undo_pages = 1 ; (default 1) + + ; Speed of the scroll-bars (in VBLs ³ Vitesse des barre de d‚filement (en + ; waited) while clicking with the ³ VBLs attendus) lorsque l'un des + ; left or right button of the mouse.³ boutons de la souris est enfonc‚. + ; Values can be between 1 and 255. ³ Les valeurs sont comprises entre 1 et + ; The bigger values, the slower. ³ 255. Plus elles sont grandes, plus + ; ³ c'est lent. + Gauges_scrolling_speed_Left = 10 ; (default 10) + Gauges_scrolling_speed_Right = 3 ; (default 3) + + ; Automatically save the configu- ³ Enregistre automatiquement la configu- + ; ration when exiting the program. ³ ration lorsqu'on quitte le programme. + Auto_save = yes ; (default 'yes') + + ; Maximum number of vertices used ³ Nombre maximum de vertex utilis‚s dans + ; in filled polygons and polyforms, ³ les polyg“nes et polyformes pleins, et + ; and lasso. Possible values range ³ le lasso. Les valeurs possibles vont + ; from 2 to 16384. ³ de 2 … 16384. + ; Each vertex takes 4 bytes. ³ Chaque vertex prend 4 octets. + Vertices_per_polygon = 1024 ; (default 1024) + + ; Automatically zoom into the ³ Zoomer automatiquement la zone point‚e + ; pointed area when you press the ³ par la souris lorsque vous appuyez sur + ; short-key of the Magnifier button ³ la touche de raccourci de la loupe. + ; while being above the picture. ³ + Fast_zoom = yes ; (default 'yes') + + ; Separate the colors in the tool- ³ S‚parer les couleurs dans la barre + ; bar by a black squaring. ³ d'outils par un quadrillage noir. + Separate_colors = yes ; (default 'yes') + + ; Initial value of the feedback for ³ Valeur initiale du "feedback" pour les + ; the drawing modes (cf. docs). ³ modes de dessin (cf. docs). + FX_feedback = yes ; (default 'yes') + + ; When you reduce the palette or ³ Si vous r‚duisez la palette ou "zappez" + ; "zap" some colors out of it, it is³ quelques couleurs, il est possible + ; possible that there are not enough³ qu'il ne reste pas assez de couleurs + ; colors left to draw the menus. ³ pour afficher les menus. Mettre cette + ; Switching the following variable ³ variable … 'yes' ramŠnera automatiquent + ; on will bring back the colors of ³ les couleurs du menu s'il reste moins + ; the menu if there are less than 4 ³ de 4 couleurs aprŠs une "r‚duction" ou + ; colors left after "reducing" or ³ un "zapping". + ; "zapping". ³ + Safety_colors = yes ; (default 'yes') + + ; Display a message at startup ³ Afficher un message au d‚marrage + ; telling the version number of the ³ indiquant le num‚ro de version du + ; program. ³ programme. + Opening_message = yes ; (default 'yes') + + ; Take the Stencil into account when³ Prendre le Stencil en compte lorsqu'on + ; clearing the image. ³ efface l'image. + Clear_with_stencil = yes ; (default 'yes') + + ; Directly set the discontinuous ³ Passer automatiquement en mode de + ; freehand drawing mode after brush ³ dessin discontinu aprŠs la prise d'une + ; grabbing. ³ brosse. + Auto_discontinuous = no ; (default 'no') + + ; Save the screen dimensions in GIF ³ Sauver les dimensions de l'‚cran dans + ; files. If you want to read these ³ les fichiers GIF. Si vous voulez lire + ; files with Photoshop or Alchemy, ³ ces fichiers avec Photoshop ou Alchemy, + ; and maybe some other programs, you³ et peut-ˆtre d'autres programmes, vous + ; must set this option to 'no'. ³ devez mettre cette option … 'no'. + Save_screen_size_in_GIF = no ; (default 'no') + + ; Automaticaly count the number of ³ Compter automatiquement le nombre de + ; different colors used when opening³ couleurs diff‚rentes utilis‚es lors de + ; the palette editor window. (Set it³ d'ouverture de la fenˆtre d'‚dition de + ; to 'no' if you have a slow PC or ³ la palette. (Mettez-le … 'no' si vous + ; if you edit huge pictures) ³ avez un PC lent ou bien si vous ‚ditez + ; ³ d'‚normes images). + Auto_nb_colors_used = yes ; (default 'yes') + + ; Number of the default video mode ³ Num‚ro du mode vid‚o par d‚faut au + ; at startup (see the list by typing³ d‚marrage (voir la liste en tapant + ; "gfx2 /?" at the DOS prompt). ³ "gfx2 /?" sur la ligne de commande). + Default_video_mode = 0 ; (default 0) diff --git a/gfx2_fra.cfg b/gfx2_fra.cfg new file mode 100644 index 00000000..d14370a5 Binary files /dev/null and b/gfx2_fra.cfg differ diff --git a/gfx2_mem.bat b/gfx2_mem.bat new file mode 100644 index 00000000..d130e00e --- /dev/null +++ b/gfx2_mem.bat @@ -0,0 +1,73 @@ +@echo off + +rem +rem This batch file will run GrafX2 with a disk cache of 16 megabytes. +rem Use it ONLY IF you don't have enough memory to run GrafX2. +rem +rem (Ce fichier de commandes lancera GrafX2 avec un cache disque de 16 Mo. +rem Ne l'utilisez QUE SI vous n'avez pas assez de m‚moire pour lancer GrafX2.) +rem + + + +rem +rem Modify the following line in order to indicate the path to DOS4GW.EXE. +rem (Modifiez la ligne suivante afin d'indiquer le chemin de DOS4GW.EXE) +rem + +set PATHDOS4GW=DOS4GW.EXE + + +rem +rem Modify the following line in order to indicate the path to GFX2.EXE. +rem (Modifiez la ligne suivante afin d'indiquer le chemin de GFX2.EXE) +rem + +set PATHGFX2=C:\GFX2\GFX2.EXE + + +if "%1"=="/novm" goto NOVM +rem +rem The following line may not work correctly on some computers. In this case, +rem please read the DOS4GW manual which is not supplied with GrafX2. +rem +rem (La ligne suivante peut ne pas fonctionner correctement sur certains +rem ordinateurs. Dans ce cas, veuillez vous r‚f‚rer au manuel de DOS4GW qui +rem n'est pas fourni avec GrafX2) +rem + +set DOS4GVM=1 +:NOVM + + +rem +rem The following lines will execute GrafX2 +rem (Les lignes suivantes ‚x‚cuteront GrafX2) +rem + +if not exist %PATHDOS4GW% goto DOSNOTFOUND +if not exist %PATHGFX2% goto GFXNOTFOUND + +if "%1"=="/novm" goto RUNNOVM +%PATHDOS4GW% %PATHGFX2% %1 +goto END +:RUNNOVM +%PATHDOS4GW% %PATHGFX2% %2 +goto END + +:DOSNOTFOUND +echo DOS4GW.EXE not found: please edit the GFX2_MEM.BAT file and enter its location. +goto END +:GFXNOTFOUND +echo GFX2.EXE not found: please edit the GFX2_MEM.BAT file and enter its location. +:END + + +rem +rem The following lines will remove all the environnement variables. +rem (Les lignes suivantes supprimeront toutes les variables d'environnement) +rem + +set DOS4GVM= +set PATHGFX2= +set PATHDOS4GW= diff --git a/global.h b/global.h new file mode 100644 index 00000000..3626651f --- /dev/null +++ b/global.h @@ -0,0 +1,756 @@ +#ifdef VARIABLES_GLOBALES + #define GLOBAL +#else + #define GLOBAL extern +#endif + +////////////////////////////////////////////////////////////////////////////// +// // +// Ce fichier contient les d‚claration des variables globales // +// // +////////////////////////////////////////////////////////////////////////////// + + +// -- Section des variables de CONFIGURATION --------------------------------- + +#ifndef _GLOBAL_H_ +#define _GLOBAL_H_ + +#include +#include "struct.h" + +GLOBAL struct S_Config +{ + byte Fonte; + int Lire_les_fichiers_caches; + int Lire_les_repertoires_caches; + int Lire_les_repertoires_systemes; + byte Afficher_limites_image; + byte Curseur; + byte Maximize_preview; + byte Auto_set_res; + byte Coords_rel; + byte Backup; + byte Adjust_brush_pick; + byte Auto_save; + byte Nb_pages_Undo; + byte Indice_Sensibilite_souris_X; + byte Indice_Sensibilite_souris_Y; + byte Mouse_Facteur_de_correction_X; + byte Mouse_Facteur_de_correction_Y; + byte Valeur_tempo_jauge_gauche; + byte Valeur_tempo_jauge_droite; + long Chrono_delay; + struct Composantes Coul_menu_pref[4]; + int Nb_max_de_vertex_par_polygon; + byte Clear_palette; + byte Set_resolution_according_to; + byte Ratio; + byte Fast_zoom; + byte Find_file_fast; + byte Couleurs_separees; + byte FX_Feedback; + byte Safety_colors; + byte Opening_message; + byte Clear_with_stencil; + byte Auto_discontinuous; + byte Taille_ecran_dans_GIF; + byte Auto_nb_used; + byte Resolution_par_defaut; +} Config; + + // Tableau des touches sp‚ciales +GLOBAL word Config_Touche[NB_TOUCHES_SPECIALES]; + + +GLOBAL struct S_Mode_video +{ + short Largeur; + short Hauteur; + byte Mode; + word Facteur_X; + word Facteur_Y; + char Ratio[5]; + signed char Refresh; // <0 => entrelac‚ + word Mode_VESA_de_base; + void * Pointeur; + byte Etat; // 0:Cool 1:OK ; 2:Bof ; 3:Naze ; si on rajoute +128 => incompatible +}; +GLOBAL struct S_Mode_video Mode_video[NB_MODES_VIDEO]; + + +GLOBAL struct +{ + byte Granularite; // Facteur de gestion de la granularit‚ + byte Code_fenetres; // Utilisation des fenˆtres: 0=AA 1=BB 2=AB 3=BA + byte * WinFuncPtr; + byte * Adresse_physique_LFB; // Si = 0 => Pas de LFB + dword Taille_LFB; // Taille de la m‚moire LFB +} VESA_Mode_Infos[4]; + + + + // Palette par d‚faut + +GLOBAL T_Palette Palette_defaut; + + // Couleurs du menu + +GLOBAL byte CM_Noir; +GLOBAL byte CM_Fonce; +GLOBAL byte CM_Clair; +GLOBAL byte CM_Blanc; +GLOBAL byte CM_Trans; +GLOBAL struct Composantes Coul_menu_pref[4]; + + // Etat des entr‚es + +GLOBAL word Mouse_X; // Abscisse de la souris +GLOBAL word Mouse_Y; // Ordonn‚e de la souris +GLOBAL byte Mouse_K; // Etat des boutons de la souris +GLOBAL word Touche; +GLOBAL Uint8* Etat_Du_Clavier; // Scancode de la touche en cours et etat des touches de ctrl +GLOBAL byte Touche_ASCII; // Code ASCII de la touche en cours + +GLOBAL byte Mouse_Facteur_de_correction_X; +GLOBAL byte Mouse_Facteur_de_correction_Y; + +GLOBAL byte Autoriser_changement_de_couleur_pendant_operation; + + // Donn‚es sur le curseur + +GLOBAL byte Forme_curseur; +GLOBAL byte Forme_curseur_avant_fenetre; // Forme du curseur avant l'ouverture d'une fenˆtre +GLOBAL byte Forcer_affichage_curseur; // Forcer l'affichage du curseur au prochain Get_input(); +GLOBAL byte Cacher_curseur; +GLOBAL byte Curseur_dans_menu; // Bool‚en "Le curseur se trouve dans le menu" +GLOBAL byte Curseur_dans_menu_precedent; // Bool‚en "Le curseur se trouvait pr‚c‚demment dans le menu" +GLOBAL word Curseur_Decalage_X[NB_SPRITES_CURSEUR]; // Coordonn‚es X du point sensible de curseurs en sprite +GLOBAL word Curseur_Decalage_Y[NB_SPRITES_CURSEUR]; // Coordonn‚es Y du point sensible de curseurs en sprite +GLOBAL byte SPRITE_CURSEUR[NB_SPRITES_CURSEUR][HAUTEUR_SPRITE_CURSEUR][LARGEUR_SPRITE_CURSEUR]; // Dessins des sprites de curseur +GLOBAL byte FOND_CURSEUR[HAUTEUR_SPRITE_CURSEUR][LARGEUR_SPRITE_CURSEUR]; // Contenu du dessous du curseur + + // Donn‚es sur le pinceau + +GLOBAL byte Pinceau_Forme; +GLOBAL byte Pinceau_Forme_avant_fill; +GLOBAL byte Pinceau_Forme_avant_pipette; +GLOBAL byte Pinceau_Forme_avant_lasso; +GLOBAL byte Cacher_pinceau; +GLOBAL short Pinceau_X; +GLOBAL short Pinceau_Y; +GLOBAL byte SPRITE_PINCEAU [NB_SPRITES_PINCEAU][HAUTEUR_PINCEAU][LARGEUR_PINCEAU]; +GLOBAL word Pinceau_predefini_Largeur[NB_SPRITES_PINCEAU]; +GLOBAL word Pinceau_predefini_Hauteur[NB_SPRITES_PINCEAU]; +GLOBAL byte Pinceau_Type[NB_SPRITES_PINCEAU]; +GLOBAL word Pinceau_predefini_Decalage_X[NB_SPRITES_PINCEAU]; +GLOBAL word Pinceau_predefini_Decalage_Y[NB_SPRITES_PINCEAU]; +GLOBAL byte * Pinceau_Sprite; +GLOBAL short Pinceau_Largeur; +GLOBAL short Pinceau_Hauteur; +GLOBAL short Pinceau_Decalage_X; +GLOBAL short Pinceau_Decalage_Y; + + // Commandes graphiques + +GLOBAL fonction_afficheur Pixel; // Affiche un point … l'‚cran +GLOBAL fonction_afficheur Pixel_dans_menu;// Affiche un point dans le menu (ou pas si le menu est invisible) +GLOBAL fonction_lecteur Lit_pixel; // Teste la couleur d'un pixel dans l'‚cran +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_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 +GLOBAL fonction_Ligne_XOR Ligne_horizontale_XOR;// Affiche une ligne horizontale en XOR (pour placer la loupe) +GLOBAL fonction_Ligne_XOR Ligne_verticale_XOR; // Affiche une ligne verticale en XOR (pour placer la loupe) +GLOBAL fonction_display_brush_Color Display_brush_Color; // Affiche une partie de la brosse en couleur +GLOBAL fonction_display_brush_Mono Display_brush_Mono; // Affiche une partie de la brosse en monochrome +GLOBAL fonction_display_brush_Color Clear_brush; // Efface la partie de la brosse affich‚e … l'‚cran +GLOBAL fonction_remap Remap_screen; // Remappe une partie de l'‚cran avec les nouvelles couleurs du menu +GLOBAL fonction_procsline Afficher_ligne; // Afficher une ligne +GLOBAL fonction_procsline Lire_ligne; // Afficher ou lire une ligne +GLOBAL fonction_display_zoom Display_zoomed_screen; // Affiche rapidement toute la partie zoom‚e … l'‚cran (en faisant attention de ne pas effacer le menu) +GLOBAL fonction_display_brush_Color_zoom Display_brush_Color_zoom; +GLOBAL fonction_display_brush_Mono_zoom Display_brush_Mono_zoom; +GLOBAL fonction_display_brush_Color_zoom Clear_brush_zoom; + + // Donn‚es sur les dimensions de l'‚cran + +GLOBAL int Resolution_actuelle; // R‚solution graphique courante +GLOBAL short Ecran_original_X; // |_ Dimensions de l'‚cran d'origine de +GLOBAL short Ecran_original_Y; // | l'image qui vient d'ˆtre charg‚e. +GLOBAL short Largeur_ecran; // Largeur de l'‚cran +GLOBAL short Hauteur_ecran; // Hauteur de l'‚cran +GLOBAL short Limite_Haut; // | +GLOBAL short Limite_Bas; // |_ Limites dans lesquelles +GLOBAL short Limite_Gauche; // | on peut ‚crire +GLOBAL short Limite_Droite; // | +GLOBAL short Limite_visible_Bas; // |_ Derniers points visibles +GLOBAL short Limite_visible_Droite; // | "… l'image" + +GLOBAL short Limite_Haut_Zoom; // | +GLOBAL short Limite_Bas_Zoom; // |_ Limites dans lesquelles on peut +GLOBAL short Limite_Gauche_Zoom; // | ‚crire dans la partie zoom‚e +GLOBAL short Limite_Droite_Zoom; // | +GLOBAL short Limite_visible_Bas_Zoom; // |_ Derniers points visibles "… +GLOBAL short Limite_visible_Droite_Zoom; // | l'image" dans la partie zoom‚e + +GLOBAL byte * Buffer_de_ligne_horizontale; // Buffer d'affichage de lignes + + // Donn‚es sur l'image actuelle: + +GLOBAL byte * Principal_Ecran; // Ecran virtuel courant +GLOBAL T_Palette Principal_Palette; // Palette de l'‚cran en cours + +GLOBAL byte Principal_Image_modifiee; // L'image courante a ‚t‚ modifi‚e +GLOBAL short Principal_Largeur_image; // Largeur de l'image dans laquelle l'utilisateur d‚sire travailler +GLOBAL short Principal_Hauteur_image; // Hauteur de l'image dans laquelle l'utilisateur d‚sire travailler +GLOBAL short Principal_Decalage_X; // D‚calage en X de l'‚cran par rapport au d‚but de l'image +GLOBAL short Principal_Decalage_Y; // D‚calage en Y de l'‚cran par rapport au d‚but de l'image +GLOBAL short Ancien_Principal_Decalage_X; +GLOBAL short Ancien_Principal_Decalage_Y; + +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 +GLOBAL byte Principal_Format; // Format du fileselect +GLOBAL short Principal_File_list_Position; // D‚but de la partie affich‚e dans la liste de fichiers +GLOBAL short Principal_File_list_Decalage; // D‚calage de la barre de s‚lection dans le fileselector +GLOBAL char Principal_Repertoire_courant[256]; // R‚pertoire actuel sur disque +GLOBAL char Principal_Commentaire[TAILLE_COMMENTAIRE+1]; // Commentaire de l'image + +GLOBAL short Principal_Split; // Position en X du bord gauche du split de la loupe +GLOBAL short Principal_X_Zoom; // (Menu_Facteur_X) + Position en X du bord droit du split de la loupe +GLOBAL float Principal_Proportion_split; // Proportion de la zone non-zoom‚e par rapport … l'‚cran + + // Donn‚es sur le brouillon: + +GLOBAL byte * Brouillon_Ecran; // Ecran virtuel brouillon +GLOBAL T_Palette Brouillon_Palette; // Palette de l'‚cran de brouillon + +GLOBAL byte Brouillon_Image_modifiee; // Le brouillon a ‚t‚ modifi‚ +GLOBAL short Brouillon_Largeur_image; // Largeur du brouillon dans laquelle l'utilisateur d‚sire travailler +GLOBAL short Brouillon_Hauteur_image; // Hauteur du brouillon dans laquelle l'utilisateur d‚sire travailler +GLOBAL short Brouillon_Decalage_X; // D‚calage en X du brouillon par rapport au d‚but de l'image +GLOBAL short Brouillon_Decalage_Y; // D‚calage en Y du brouillon par rapport au d‚but de l'image +GLOBAL short Ancien_Brouillon_Decalage_X; +GLOBAL short Ancien_Brouillon_Decalage_Y; + +GLOBAL char Brouillon_Repertoire_fichier[256]; // |_ Nom complet = +GLOBAL char Brouillon_Nom_fichier[13]; // | Repertoire_fichier+"\"+Nom_fichier +GLOBAL byte Brouillon_Format_fichier; // Format auquel il faut lire et ‚crire le fichier +GLOBAL byte Brouillon_Format; // Format du fileselect +GLOBAL short Brouillon_File_list_Position; // D‚but de la partie affich‚e dans la liste de fichiers +GLOBAL short Brouillon_File_list_Decalage; // D‚calage de la barre de s‚lection dans le fileselector +GLOBAL char Brouillon_Repertoire_courant[256]; // R‚pertoire actuel sur disque +GLOBAL char Brouillon_Commentaire[TAILLE_COMMENTAIRE+1]; // Commentaire de l'image + +GLOBAL short Brouillon_Split; // Position en X du bord gauche du split de la loupe +GLOBAL short Brouillon_X_Zoom; // (Menu_Facteur_X) + Position en X du bord droit du split de la loupe +GLOBAL float Brouillon_Proportion_split; // Proportion de la zone non-zoom‚e par rapport … l'‚cran + +GLOBAL byte Brouillon_Loupe_Mode; // On est en mode loupe dans le brouillon +GLOBAL word Brouillon_Loupe_Facteur; // Facteur de zoom dans le brouillon +GLOBAL word Brouillon_Loupe_Hauteur; // Largeur de la fenˆtre de zoom dans le brouillon +GLOBAL word Brouillon_Loupe_Largeur; // Hauteur de la fenˆtre de zoom dans le brouillon +GLOBAL short Brouillon_Loupe_Decalage_X;// Decalage horizontal de la fenˆtre de zoom dans le brouillon +GLOBAL short Brouillon_Loupe_Decalage_Y;// Decalage vertical de la fenˆtre de zoom dans le brouillon + +GLOBAL byte Masque_copie_couleurs[256]; // Tableau des couleurs … copier vers le brouillon + + // Sauvegarde de l'image: + +GLOBAL byte * Ecran_backup; // Sauvegarde de l'‚cran virtuel courant +GLOBAL S_Liste_de_pages * Principal_Backups; // Liste des pages de backup de la page principale +GLOBAL S_Liste_de_pages * Brouillon_Backups; // Liste des pages de backup de la page de brouillon + + + // Donn‚es sur la brosse: + +GLOBAL byte * Brosse; // Sprite de la brosse +GLOBAL word Brosse_Decalage_X; // Centre horizontal de la brosse +GLOBAL word Brosse_Decalage_Y; // Centre vertical de la brosse +GLOBAL word Brosse_Largeur; // Largeur de la brosse +GLOBAL word Brosse_Hauteur; // Hauteur de la brosse + +GLOBAL char Brosse_Repertoire_fichier[256]; // | +GLOBAL char Brosse_Nom_fichier[13]; // | +GLOBAL byte Brosse_Format_fichier; // | Infos sur le +GLOBAL byte Brosse_Format; // |_ s‚lecteur de +GLOBAL short Brosse_File_list_Position; // | fichiers de la +GLOBAL short Brosse_File_list_Decalage; // | brosse. +GLOBAL char Brosse_Repertoire_courant[256]; // | +GLOBAL char Brosse_Commentaire[TAILLE_COMMENTAIRE+1]; // | + +GLOBAL byte Brosse_Centre_rotation_defini; // | Infos sur le +GLOBAL short Brosse_Centre_rotation_X; // |- centre de rotation +GLOBAL short Brosse_Centre_rotation_Y; // | de la brosse + + // Donn‚es sur le menu + +GLOBAL byte Menu_visible; // Le menu est actif … l'‚cran +GLOBAL word Menu_Ordonnee; // Ordonn‚e o— commence le menu +GLOBAL word Menu_Ordonnee_Texte; // Ordonn‚e o— commence le texte dans le menu +GLOBAL word Menu_Facteur_X; // Facteur de grossissement du menu en X +GLOBAL word Menu_Facteur_Y; // Facteur de grossissement du menu en Y +GLOBAL word Menu_Taille_couleur; // Taille d'une couleur de la palette du menu + + + // Donn‚es sur la fenˆtre de menu + +GLOBAL byte Une_fenetre_est_ouverte; + +GLOBAL word Fenetre_Pos_X; // Position du bord gauche de la fenˆtre dans l'‚cran +GLOBAL word Fenetre_Pos_Y; // Position du bord haut de la fenˆtre dans l'‚cran +GLOBAL word Fenetre_Largeur; // Largeur de la fenˆtre +GLOBAL word Fenetre_Hauteur; // Hauteur de la fenˆtre + +GLOBAL byte Menu_visible_avant_fenetre; // Le menu ‚tait visible avant d'ouvir une fenˆtre +GLOBAL word Menu_Ordonnee_avant_fenetre; // Ordonn‚e du menu avant d'ouvrir une fenˆtre +GLOBAL byte Cacher_pinceau_avant_fenetre;// Le pinceau ‚tatit d‚j… cach‚ avant l'ouverture de la fenetre? + +GLOBAL word Nb_boutons_fenetre; +GLOBAL struct Fenetre_Bouton_normal * Fenetre_Liste_boutons_normal; +GLOBAL struct Fenetre_Bouton_palette * Fenetre_Liste_boutons_palette; +GLOBAL struct Fenetre_Bouton_scroller * Fenetre_Liste_boutons_scroller; +GLOBAL struct Fenetre_Bouton_special * Fenetre_Liste_boutons_special; +GLOBAL int Fenetre_Attribut1; +GLOBAL int Fenetre_Attribut2; + + + + +// D‚finition des boutons //////////////////////////////////////////////////// + +GLOBAL struct +{ + // Informations sur l'aspect du bouton (graphisme): + word Decalage_X; // D‚calage par rapport … la gauche du menu + word Decalage_Y; // D‚calage par rapport au haut du menu + word Largeur; // Largeur du bouton + word Hauteur; // Hauteur du bouton + byte Enfonce; // Le bouton est enfonc‚ + byte Forme; // Forme du bouton + + // Information sur les clicks de la souris: + fonction_action Gauche; // Action d‚clench‚e par un click gauche sur le bouton + fonction_action Droite; // Action d‚clench‚e par un click droit sur le bouton + word Raccourci_gauche; // Raccourci clavier ‚quivalent … un click gauche sur le bouton + word Raccourci_droite; // Raccourci clavier ‚quivalent … un click droit sur le bouton + + // Informations sur le d‚senclenchement du bouton g‚r‚ par le moteur: + fonction_action Desenclencher; // Action appel‚e lors du d‚senclenchement du bouton + byte Famille; // Ensemble de boutons auquel celui-ci appartient + +} Bouton[NB_BOUTONS]; + + + +// Informations sur les diff‚rents modes de dessin + +GLOBAL fonction_effet Fonction_effet; + +GLOBAL byte * FX_Feedback_Ecran; + +GLOBAL byte Exclude_color[256]; // Couleurs … exclure pour Meilleure_couleur + + // Mode smear: + +GLOBAL byte Smear_Mode; // Le mode smear est enclench‚ +GLOBAL byte Smear_Debut; // On vient juste de commencer une op‚ration en Smear +GLOBAL byte * Smear_Brosse; // Sprite de la brosse de Smear +GLOBAL word Smear_Brosse_Largeur; // Largeur de la brosse de Smear +GLOBAL word Smear_Brosse_Hauteur; // Hauteur de la brosse de Smear +GLOBAL short Smear_Min_X,Smear_Max_X,Smear_Min_Y,Smear_Max_Y; // Bornes de la Brosse du smear + + // Mode shade: + +GLOBAL struct T_Shade Shade_Liste[8]; // Listes de shade +GLOBAL byte Shade_Actuel; // Num‚ro du shade en cours +GLOBAL byte * Shade_Table; // Table de conversion de shade en cours +GLOBAL byte Shade_Table_gauche[256]; // Table de conversion de shade pour un clic gauche +GLOBAL byte Shade_Table_droite[256]; // Table de conversion de shade pour un clic droit +GLOBAL byte Shade_Mode; // Le mode shade est enclench‚ + +GLOBAL byte Quick_shade_Mode; // Le mode quick-shade est enclench‚ +GLOBAL byte Quick_shade_Step; // Pas du mode quick-shade +GLOBAL byte Quick_shade_Loop; // Normal / Loop / No sat. + + // Mode stencil: + +GLOBAL byte Stencil_Mode; // Le mode stencil est enclench‚ +GLOBAL byte Stencil[256]; // Tableau des couleurs prot‚g‚es + + // Mode grille: + +GLOBAL byte Snap_Mode; // Le mode grille est enclench‚ +GLOBAL short Snap_Largeur; // Largeur entre 2 points de la grille +GLOBAL short Snap_Hauteur; // Hauteur entre 2 points de la grille +GLOBAL short Snap_Decalage_X; // Position en X du point le + … gauche +GLOBAL short Snap_Decalage_Y; // Position en Y du point le + en haut + + // Mode trame: + +GLOBAL byte Trame_Mode; // Le mode Trame est enclench‚ +GLOBAL byte Trame[16][16]; // Sprite de la trame +GLOBAL word TRAME_PREDEFINIE[12][16]; // Trames pr‚s‚finies (compact‚es sur 16*16 bits) +GLOBAL short Trame_Largeur; // Largeur de la trame +GLOBAL short Trame_Hauteur; // Hauteur de la trame + + // Mode colorize: + +GLOBAL byte Colorize_Mode; // Le mode Colorize est enclench‚ +GLOBAL byte Colorize_Opacite; // Intensit‚ du Colorize +GLOBAL byte Colorize_Mode_en_cours; // Le type de Colorize en cours (0-2) +GLOBAL word Table_de_multiplication_par_Facteur_A[64]; +GLOBAL word Table_de_multiplication_par_Facteur_B[64]; + + // Mode smooth: + +GLOBAL byte Smooth_Mode; // Le mode Smooth est enclench‚ +GLOBAL byte Smooth_Matrice[3][3]; // La matrice du Smooth actuel + + // Mode Tiling: + +GLOBAL byte Tiling_Mode; // Le mode Tiling est enclench‚ +GLOBAL short Tiling_Decalage_X; // D‚calage du tiling en X +GLOBAL short Tiling_Decalage_Y; // D‚calage du tiling en Y + + // Mode Mask + +GLOBAL byte Mask_Mode; // Le mode Masque est enclench‚ +GLOBAL byte Mask[256]; // Tableau des couleurs constituant le masque + + // Mode loupe: + +GLOBAL byte Loupe_Mode; +GLOBAL word Loupe_Facteur; +GLOBAL word Loupe_Hauteur; +GLOBAL word Loupe_Largeur; +GLOBAL short Loupe_Decalage_X; +GLOBAL short Loupe_Decalage_Y; +GLOBAL word * Table_mul_facteur_zoom; +GLOBAL word TABLE_ZOOM[NB_FACTEURS_DE_ZOOM][512]; + +#ifdef VARIABLES_GLOBALES + word FACTEUR_ZOOM[NB_FACTEURS_DE_ZOOM]={2,3,4,5,6,8,10,12,14,16,18,20}; +#else + extern word FACTEUR_ZOOM[NB_FACTEURS_DE_ZOOM]; +#endif + + // Donn‚es sur les ellipses et les cercles: + +GLOBAL dword Table_des_carres[1025]; +GLOBAL long Ellipse_Curseur_X; +GLOBAL long Ellipse_Curseur_Y; +GLOBAL long Ellipse_Rayon_vertical_au_carre; +GLOBAL long Ellipse_Rayon_horizontal_au_carre; +GLOBAL long Ellipse_Limite_High; +GLOBAL long Ellipse_Limite_Low; +GLOBAL long Cercle_Curseur_X; +GLOBAL long Cercle_Curseur_Y; +GLOBAL long Cercle_Limite; + + // Donn‚es sur les d‚grad‚s: + +GLOBAL short Degrade_Borne_Inferieure; // Plus petite couleur englob‚e par le d‚grad‚ +GLOBAL short Degrade_Borne_Superieure; // Plus grande couleur englob‚e par le d‚grad‚ +GLOBAL int Degrade_Inverse; // Bool‚en "Le d‚grad‚ est en r‚alit‚ invers‚" +GLOBAL long Degrade_Intervalle_bornes; // = Abs(Degrade_Borne_Inferieure-Degrade_Borne_Superieure)+1 +GLOBAL long Degrade_Intervalle_total; // Valeur maximum des indices pass‚s … la fonction de d‚grad‚ (!!! >0 !!!) +GLOBAL long Degrade_Melange_aleatoire; // Facteur de m‚lange (1-256+) du d‚grad‚ +GLOBAL fonction_degrade Traiter_degrade; // Fonction de traitement du d‚grad‚, varie selon la m‚thode choisie par l'utilisateur. +GLOBAL fonction_afficheur Traiter_pixel_de_degrade; // Redirection de l'affichage + +GLOBAL struct T_Degrade_Tableau Degrade_Tableau[16]; // Donn‚es de tous les d‚grad‚s +GLOBAL int Degrade_Courant; // Indice du tableau correspondant au d‚grad‚ courant + + + + // Donn‚es sur le Spray: + +GLOBAL byte Spray_Mode; // Mode Mono(1) ou Multicolore(0) +GLOBAL short Spray_Size; // DiamŠtre du spray en pixels +GLOBAL byte Spray_Delay; // D‚lai en VBLs entre 2 "pschiitt" +GLOBAL byte Spray_Mono_flow; // Nombre de pixels qui sortent en mˆme temps en mono +GLOBAL byte Spray_Multi_flow[256]; // Idem pour chaque couleur + + + // Donn‚es diverses sur le programme: + +GLOBAL byte Sortir_du_programme; +GLOBAL char Repertoire_du_programme[256]; // R‚pertoire dans lequel se trouve le programme +GLOBAL char Repertoire_initial[256]; // R‚pertoire … partir duquel … ‚t‚ lanc‚ le programme +GLOBAL byte Fore_color; +GLOBAL byte Back_color; +GLOBAL byte Mode_de_dessin_en_cours; +GLOBAL byte Courbe_en_cours; +GLOBAL byte Ligne_en_cours; +GLOBAL byte Couleur_debut_palette; +GLOBAL byte Un_fichier_a_ete_passe_en_parametre; +GLOBAL byte Une_resolution_a_ete_passee_en_parametre; // utilis‚e uniquement si la variable pr‚c‚dente est … 1 + + // Variables concernant l'OBJ DIVERS + +GLOBAL word INPUT_Nouveau_Mouse_X; +GLOBAL word INPUT_Nouveau_Mouse_Y; +GLOBAL byte INPUT_Nouveau_Mouse_K; +GLOBAL byte INPUT_Keyb_mode; + +GLOBAL int MC_Indice; +GLOBAL int MC_DR; +GLOBAL int MC_DV; +GLOBAL int MC_DB; +GLOBAL int * MC_Table_differences; + + // Variables concernant l'OBJ VIDEO + + // Partie concernant le mode X: +GLOBAL dword MODE_X_Decalage_synchro; +GLOBAL word MODE_X_Largeur_de_ligne; +GLOBAL dword MODE_X_Valeur_initiale_de_esi; +GLOBAL dword MODE_X_Valeur_initiale_de_edi; + // Partie concernant le VESA: +GLOBAL byte Granularite; // Facteur de gestion de la granularit‚ de la carte +GLOBAL byte VESA_Erreur; +GLOBAL byte * VESA_WinFuncPtr; // Handler software de changement de banque +GLOBAL word * VESA_Liste_des_modes; +GLOBAL dword VESA_Decalage_synchro; +GLOBAL word VESA_Largeur_ecran_en_dword; +GLOBAL byte VESA_Banque_en_cours; // Variable normalement locale … VIDEO.ASM +GLOBAL byte VESA_Derniere_banque_Fenetre_A_utilisee; +GLOBAL byte VESA_Derniere_banque_Fenetre_B_utilisee; +GLOBAL fonction_action VESA_Change_banque_lecture; +GLOBAL fonction_action VESA_Change_banque_ecriture; +GLOBAL fonction_action VESA_Change_banque_lect_ecr; +GLOBAL byte VESA_Version_Unite; +GLOBAL byte VESA_Version_Decimale; +GLOBAL char VESA_Constructeur[TAILLE_NOM_CONSTRUCTEUR+1]; +GLOBAL word VESA_Taille_memoire; + + // Les diff‚rents sprites: + +GLOBAL byte BLOCK_MENU[HAUTEUR_MENU][LARGEUR_MENU]; +GLOBAL byte SPRITE_MENU[NB_SPRITES_MENU][HAUTEUR_SPRITE_MENU][LARGEUR_SPRITE_MENU]; +GLOBAL byte SPRITE_EFFET[NB_SPRITES_EFFETS][HAUTEUR_SPRITE_MENU][LARGEUR_SPRITE_MENU]; + +GLOBAL byte * Logo_GrafX2; + +GLOBAL byte Fonte_systeme[256*8*8]; +GLOBAL byte Fonte_fun [256*8*8]; +GLOBAL byte Fonte_help [315][6][8]; +GLOBAL byte * Fonte; + + // Les donn‚es de l'aide: + +GLOBAL struct Section_d_aide Table_d_aide[NB_SECTIONS_AIDE]; +GLOBAL byte Section_d_aide_en_cours; // Indice de la table d'aide en cours de consultation +GLOBAL word Position_d_aide_en_cours; // Num‚ro de la ligne d'aide en cours de consultation + + // Donn‚es sur les op‚rations + +GLOBAL word Operation_avant_interruption; // Nø de l'op‚ration en cours avant l'utilisation d'une interruption +GLOBAL word Operation_en_cours; // Nø de l'op‚ration en cours +GLOBAL word Operation_Pile[TAILLE_PILE_OPERATIONS]; // Pile simplifi‚e +GLOBAL byte Operation_Taille_pile; // Taille effective de la pile (0=vide) +GLOBAL byte Operation_dans_loupe; // Indique si l'op‚ration a commenc‚ dans la partie Zoom‚e ou non + +GLOBAL short Pipette_Couleur; +GLOBAL short Pipette_X; +GLOBAL short Pipette_Y; + + +#ifdef VARIABLES_GLOBALES + byte CURSEUR_D_OPERATION[NB_OPERATIONS]= + { + FORME_CURSEUR_CIBLE , // Dessin … la main continu + FORME_CURSEUR_CIBLE , // Dessin … la main discontinu + FORME_CURSEUR_CIBLE , // Dessin … la main point par point + FORME_CURSEUR_CIBLE , // Lignes + FORME_CURSEUR_CIBLE , // Lignes reli‚es + FORME_CURSEUR_CIBLE , // Lignes centr‚es + FORME_CURSEUR_CIBLE_XOR , // Rectangle vide + FORME_CURSEUR_CIBLE_XOR , // Rectangle plein + FORME_CURSEUR_CIBLE , // Cercles vides + FORME_CURSEUR_CIBLE , // Cercles pleins + FORME_CURSEUR_CIBLE , // Ellipses vides + FORME_CURSEUR_CIBLE , // Ellipses pleines + FORME_CURSEUR_CIBLE , // Fill + FORME_CURSEUR_CIBLE , // Remplacer + FORME_CURSEUR_CIBLE_XOR , // Prise de brosse rectangulaire + FORME_CURSEUR_CIBLE , // Prise d'une brosse multiforme + FORME_CURSEUR_CIBLE_PIPETTE , // R‚cup‚ration d'une couleur + FORME_CURSEUR_RECTANGLE_XOR , // Positionnement de la fenˆtre de loupe + FORME_CURSEUR_CIBLE , // Courbe … 3 points + FORME_CURSEUR_CIBLE , // Courbe … 4 points + FORME_CURSEUR_CIBLE , // Spray + FORME_CURSEUR_CIBLE , // Polygone + FORME_CURSEUR_CIBLE , // Polyforme + FORME_CURSEUR_CIBLE , // Polyfill + FORME_CURSEUR_CIBLE , // Polyforme rempli + FORME_CURSEUR_MULTIDIRECTIONNEL, // Scroll + FORME_CURSEUR_CIBLE , // Cercles d‚grad‚s + FORME_CURSEUR_CIBLE , // Ellipses d‚grad‚es + FORME_CURSEUR_ROTATE_XOR , // Faire tourner brosse + FORME_CURSEUR_CIBLE_XOR , // Etirer brosse + FORME_CURSEUR_CIBLE // Deformer brosse + }; +#else + extern byte CURSEUR_D_OPERATION[NB_OPERATIONS]; +#endif + + + // Proc‚dures … appeler: Op‚ration,Mouse_K,Etat de la pile + +GLOBAL struct +{ + byte Effacer_curseur; // Bool‚en "il faut effacer le curseur pour l'op‚ra." + fonction_action Action; // Action appel‚e +} Operation[NB_OPERATIONS][3][TAILLE_PILE_OPERATIONS]; + + + +// Informations sur les lecteurs + +GLOBAL byte Nb_drives; +GLOBAL struct T_Drive Drive[26]; +GLOBAL byte SPRITE_DRIVE[NB_SPRITES_DRIVES][HAUTEUR_SPRITE_DRIVE][LARGEUR_SPRITE_DRIVE]; + + +// -- Section des informations sur les formats de fichiers ------------------ + + // Comptage du nb d'‚l‚ments dans la liste: +GLOBAL short Liste_Nb_elements; +GLOBAL short Liste_Nb_fichiers; +GLOBAL short Liste_Nb_repertoires; + // Tˆte de la liste chaŒn‚e: +GLOBAL struct Element_de_liste_de_fileselect * Liste_du_fileselect; + +// ------------------- Inititialisation des formats connus ------------------- + +#include "loadsave.h" +void Rien_du_tout(void); + +#ifdef VARIABLES_GLOBALES + // Extension du format + char Format_Extension[NB_FORMATS_CONNUS][4]= + { + "PKM", // PKM + "LBM", // LBM + "GIF", // GIF + "BMP", // BMP + "PCX", // PCX + "IMG", // IMG + "SC?", // SCx + "PI1", // PI1 + "PC1", // PC1 + "CEL", // CEL + "KCF", // KCF + "PAL" // PAL + }; + + // Fonction … appeler pour v‚rifier la signature du fichier + fonction_action Format_Test[NB_FORMATS_LOAD]= + { + Test_PKM, // PKM + Test_LBM, // LBM + Test_GIF, // GIF + Test_BMP, // BMP + Test_PCX, // PCX + Test_IMG, // IMG + Test_SCx, // SCx + Test_PI1, // PI1 + Test_PC1, // PC1 + Test_CEL, // CEL + Test_KCF, // KCF + Test_PAL // PAL + }; + + // Fonction … appeler pour charger l'image + fonction_action Format_Load[NB_FORMATS_LOAD]= + { + Load_PKM, // PKM + Load_LBM, // LBM + Load_GIF, // GIF + Load_BMP, // BMP + Load_PCX, // PCX + Load_IMG, // IMG + Load_SCx, // SCx + Load_PI1, // PI1 + Load_PC1, // PC1 + Load_CEL, // CEL + Load_KCF, // KCF + Load_PAL // PAL + }; + + // Fonction … appeler pour sauvegarder l'image + fonction_action Format_Save[NB_FORMATS_SAVE]= + { + Save_PKM, // PKM + Save_LBM, // LBM + Save_GIF, // GIF + Save_BMP, // BMP + Save_PCX, // PCX + Save_IMG, // IMG + Save_SCx, // SCx + Save_PI1, // PI1 + Save_PC1, // PC1 + Save_CEL, // CEL + Save_KCF, // KCF + Save_PAL // PAL + }; + + // indique si l'on doit consid‚rer que l'image n'est plus modifi‚e + byte Format_Backup_done[NB_FORMATS_CONNUS]= + { + 1, // PKM + 1, // LBM + 1, // GIF + 1, // BMP + 1, // PCX + 1, // IMG + 1, // SCx + 1, // PI1 + 1, // PC1 + 1, // CEL + 0, // KCF + 0 // PAL + }; + + // Le format de fichier autorise un commentaire + byte Format_Commentaire[NB_FORMATS_CONNUS]= + { + 1, // PKM + 0, // LBM + 0, // GIF + 0, // BMP + 0, // PCX + 0, // IMG + 0, // SCx + 0, // PI1 + 0, // PC1 + 0, // CEL + 0, // KCF + 0 // PAL + }; +#else + extern char Format_Extension[NB_FORMATS_CONNUS][4]; + extern fonction_action Format_Load[NB_FORMATS_LOAD]; + extern fonction_action Format_Save[NB_FORMATS_SAVE]; + extern fonction_action Format_Test[NB_FORMATS_LOAD]; + extern byte Format_Backup_done[NB_FORMATS_CONNUS]; + extern byte Format_Commentaire[NB_FORMATS_CONNUS]; +#endif + +GLOBAL signed char Erreur_fichier; // 0: op‚ration I/O OK + // 1: Erreur dŠs le d‚but de l'op‚ration + // 2: Erreur durant l'op‚ration => donn‚es modifi‚es + //-1: Interruption du chargement d'une preview + +GLOBAL int Ligne_INI; + +GLOBAL fonction_afficheur Pixel_de_chargement; +GLOBAL fonction_lecteur Lit_pixel_de_sauvegarde; + +#endif diff --git a/graph.c b/graph.c new file mode 100644 index 00000000..3b666f27 --- /dev/null +++ b/graph.c @@ -0,0 +1,5750 @@ +#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" + + +// On d‚clare m‚chamment le prototype de Erreur pour ‚viter de faire un +// fichier "main.h": +void Erreur(int Code); + +/* +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; + + 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); + } + } + } + } + } + } +} + + +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; + 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; + + switch(Mode_video[Numero].Mode_VESA_de_base) + { + case 0x100 : Indice_VESA=0; // 640x400 + break; + case 0x101 : Indice_VESA=1; // 640x480 + break; + case 0x103 : Indice_VESA=2; // 800x600 + break; + default : Indice_VESA=3; // 1024x768 + } + + // On regarde si le mode supporte le LFB + if (VESA_Mode_Infos[Indice_VESA].Adresse_physique_LFB!=0) + { + // C'est le cas => on va s'en servir + + Set_VESA_mode(Mode_video[Numero].Mode_VESA_de_base | 0x4000); + Initialiser_le_LFB(VESA_Mode_Infos[Indice_VESA].Adresse_physique_LFB, + VESA_Mode_Infos[Indice_VESA].Taille_LFB); + if (Mode_X_Ptr!=NULL) + Retoucher_CRTC(); + } + else + { + // Ce n'est pas le cas, on continue comme si de rien n'‚tait + Granularite =VESA_Mode_Infos[Indice_VESA].Granularite; + VESA_WinFuncPtr=VESA_Mode_Infos[Indice_VESA].WinFuncPtr; + + Initialiser_mode_video_VESA(Mode_video[Numero].Mode_VESA_de_base); + if (Mode_X_Ptr!=NULL) + Retoucher_CRTC(); + } + } + 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(short X,short 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(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((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(); + } + } +} + + +// -- 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; + + if (!(Preview && Mouse_K)) + 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); + 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 d–es 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); + 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; + } + } + 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 d–es 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); + 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; + } + } + 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 d–es 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); + 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; + } + } + 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=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)); + 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) ) + { + FOND_CURSEUR[Compteur_Y][Compteur_X]=Lit_pixel(Pos_X,Pos_Y); + if (Couleur!=CM_Trans) + Pixel(Pos_X,Pos_Y,Couleur); + } + } + 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); + + if ((Pos_X=Limite_Gauche)) + Ligne_verticale_XOR(Pinceau_X-Principal_Decalage_X,0,Menu_Ordonnee); + + if (Loupe_Mode) + { + 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 !!! + 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); + + 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); + 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; + short Debut_X; + short Debut_Y; + short Fin_X; + short Fin_Y; + short Pos_X; + short Pos_Y; + short Compteur_X; + short Compteur_Y; + short Fin_Compteur_X; // Position X ou s'arrˆ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>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++) + 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) ) + Pixel(Pos_X,Pos_Y,FOND_CURSEUR[Compteur_Y][Compteur_X]); + 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); + + if ((Pos_X=Limite_Gauche)) + Ligne_verticale_XOR(Pinceau_X-Principal_Decalage_X,0,Menu_Ordonnee); + + if (Loupe_Mode) + { + 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 !!! + 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); + + 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); + 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 + 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-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); + 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(short Pos_X,short 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(short Pos_X,short 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(short Pos_X,short 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); +} + + + // -- 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(Pos_X,Pos_Y,Couleur); +} + + + + + // -- 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/graph.h b/graph.h new file mode 100644 index 00000000..1d7ec5bc --- /dev/null +++ b/graph.h @@ -0,0 +1,154 @@ +//byte Meilleure_couleur(byte Rouge, byte Vert, byte Bleu); + +void Remapper_ecran_apres_changement_couleurs_menu(void); +void Calculer_couleurs_menu_optimales(struct Composantes * Palette); + +dword Memoire_libre(void); + +void Liste2tables(word * Liste,short Pas,byte Mode,byte * Table_inc,byte * Table_dec); + +void Num2str(dword Nombre,char * Chaine,byte Taille); +int Str2num(char * Chaine); + +short Round(float Valeur); +short Round_max(short Numerateur,short Diviseur); +short Round_div_max(short Numerateur,short Diviseur); + +int Min(int A,int B); + +void Transformer_point(short X, short Y, + float cosA, float sinA, short * Xr, short * Yr); + +void Recadrer_ecran_par_rapport_au_zoom(void); +void Calculer_split(void); +void Calculer_donnees_loupe(void); +void Calculer_limites(void); +void Calculer_coordonnees_pinceau(void); + +char* Libelle_mode(int Mode); + +void Initialiser_mode_video(int Numero); +void Pixel_dans_barre_d_outil(word X,word Y,byte Couleur); +void Pixel_dans_fenetre(word X,word Y,byte Couleur); +void Encadrer_couleur_menu(byte Couleur); +void Afficher_palette_du_menu(void); +void Afficher_menu(void); +void Recadrer_palette(void); + +void Print_general(short X,short Y,char * Chaine,byte Couleur_texte,byte Couleur_fond); +void Print_dans_fenetre(short X,short Y,char * Chaine,byte Couleur_texte,byte Couleur_fond); +void Print_char_dans_fenetre(short Pos_X,short Pos_Y,char Caractere,byte Couleur_texte,byte Couleur_fond); +void Print_char_transparent_dans_fenetre(short Pos_X,short Pos_Y,char Caractere,byte Couleur); +void Print_dans_menu(char * Chaine, short Position); +void Print_coordonnees(void); +void Print_nom_fichier(void); + +byte Aucun_effet(word X,word Y,byte Couleur); +byte Effet_Shade(word X,word Y,byte Couleur); +byte Effet_Quick_shade(word X,word Y,byte Couleur); +byte Effet_Tiling(word X,word Y,byte Couleur); +byte Effet_Smooth(word X,word Y,byte Couleur); + +void Afficher_foreback(void); + + +void Afficher_pixel(short X,short Y,byte Couleur); + +void Afficher_pinceau(short X,short Y,byte Couleur,byte Preview); +void Effacer_pinceau(short X,short Y); +void Effacer_curseur(void); +void Afficher_curseur(void); + +byte Demande_de_confirmation(char * Message); +void Warning_message(char * Message); + +void Afficher_limites_de_l_image(void); +void Afficher_ecran(void); +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); +void Fenetre_Afficher_cadre_mono(word Pos_X,word Pos_Y,word Largeur,word Hauteur,byte Couleur); +void Fenetre_Afficher_cadre_creux(word Pos_X,word Pos_Y,word Largeur,word Hauteur); +void Fenetre_Afficher_cadre_bombe(word Pos_X,word Pos_Y,word Largeur,word Hauteur); +void Fenetre_Afficher_cadre(word Pos_X,word Pos_Y,word Largeur,word Hauteur); + +void Afficher_sprite_dans_menu(int Numero_bouton,int Numero_sprite); +void Afficher_pinceau_dans_menu(void); +void Afficher_pinceau_dans_fenetre(word X,word Y,int Numero); + +void Dessiner_zigouigoui(word X,word Y, byte Couleur, short Sens); +void Bloc_degrade_dans_fenetre(word Pos_X,word Pos_Y,word Debut_block,word Fin_block); +void Redimentionner_image(word Largeur_choisie,word Hauteur_choisie); + +void Fenetre_Afficher_sprite_drive(word Pos_X,word Pos_Y,byte Type); + +void Capturer_brosse(short Debut_X,short Debut_Y,short Fin_X,short Fin_Y,short Effacement); +void Rotate_90_deg(void); +void Etirer_brosse(short X1, short Y1, short X2, short Y2); +void Etirer_brosse_preview(short X1, short Y1, short X2, short Y2); +void Tourner_brosse(float Angle); +void Tourner_brosse_preview(float Angle); + +void Remap_brosse(void); +void Get_colors_from_brush(void); +void Outline_brush(void); +void Nibble_brush(void); + +void Remplir(byte Couleur_de_remplissage); +void Remplacer(byte Nouvelle_couleur); + +void Pixel_figure_Preview (short Pos_X,short Pos_Y,byte Couleur); +void Pixel_figure_Preview_xor(short Pos_X,short Pos_Y,byte Couleur); + +void Tracer_cercle_vide_Definitif(short Centre_X,short Centre_Y,short Rayon,byte Couleur); +void Tracer_cercle_vide_Preview (short Centre_X,short Centre_Y,short Rayon,byte Couleur); +void Effacer_cercle_vide_Preview (short Centre_X,short Centre_Y,short Rayon); +void Tracer_cercle_plein (short Centre_X,short Centre_Y,short Rayon,byte Couleur); + +void Tracer_ellipse_vide_Definitif(short Centre_X,short Centre_Y,short Rayon_horizontal,short Rayon_vertical,byte Couleur); +void Tracer_ellipse_vide_Preview (short Centre_X,short Centre_Y,short Rayon_horizontal,short Rayon_vertical,byte Couleur); +void Effacer_ellipse_vide_Preview (short Centre_X,short Centre_Y,short Rayon_horizontal,short Rayon_vertical); +void Tracer_ellipse_pleine (short Centre_X,short Centre_Y,short Rayon_horizontal,short Rayon_vertical,byte Couleur); + +void Tracer_ligne_Definitif (short Debut_X,short Debut_Y,short Fin_X,short Fin_Y,byte Couleur); +void Tracer_ligne_Preview (short Debut_X,short Debut_Y,short Fin_X,short Fin_Y,byte Couleur); +void Tracer_ligne_Preview_xor(short Debut_X,short Debut_Y,short Fin_X,short Fin_Y,byte Couleur); +void Effacer_ligne_Preview (short Debut_X,short Debut_Y,short Fin_X,short Fin_Y); + +void Tracer_rectangle_vide(short Debut_X,short Debut_Y,short Fin_X,short Fin_Y,byte Couleur); +void Tracer_rectangle_plein(short Debut_X,short Debut_Y,short Fin_X,short Fin_Y,byte Couleur); + +void Tracer_courbe_Definitif(short X1, short Y1, short X2, short Y2, short X3, short Y3, short X4, short Y4, byte Couleur); +void Tracer_courbe_Preview (short X1, short Y1, short X2, short Y2, short X3, short Y3, short X4, short Y4, byte Couleur); +void Effacer_courbe_Preview (short X1, short Y1, short X2, short Y2, short X3, short Y3, short X4, short Y4, byte Couleur); + +void Aerographe(short Bouton_clicke); + +void Degrade_de_base (long Indice,short Pos_X,short Pos_Y); +void Degrade_de_trames_simples (long Indice,short Pos_X,short Pos_Y); +void Degrade_de_trames_etendues(long Indice,short Pos_X,short Pos_Y); +void Degrade_aleatoire (long Indice,short Pos_X,short Pos_Y); + +void Tracer_cercle_degrade (short Centre_X,short Centre_Y,short Rayon,short Eclairage_X,short Eclairage_Y); +void Tracer_ellipse_degradee(short Centre_X,short Centre_Y,short Rayon_horizontal,short Rayon_vertical,short Eclairage_X,short Eclairage_Y); + +void Polyfill(int Vertices, short * Points, int Color); +void Capturer_brosse_au_lasso(int Vertices, short * Points,short Effacement); + +// Gestion des backups: +void Download_infos_page_principal(S_Page * Page); +void Upload_infos_page_principal(S_Page * Page); +void Download_infos_page_brouillon(S_Page * Page); +void Upload_infos_page_brouillon(S_Page * Page); +void Download_infos_backup(S_Liste_de_pages * Liste); +int Initialiser_les_listes_de_backups_en_debut_de_programme(int Taille,int Largeur,int Hauteur); +void Detruire_les_listes_de_backups_en_fin_de_programme(void); +void Nouveau_nombre_de_backups(int Nouveau); +int Backup_avec_nouvelles_dimensions(int Upload,int Largeur,int Hauteur); +int Backuper_et_redimensionner_brouillon(int Largeur,int Hauteur); +void Backup(void); +void Undo(void); +void Redo(void); +void Detruire_la_page_courante(void); +void Interchanger_image_principale_et_brouillon(void); + +void Changer_facteur_loupe(byte Indice_facteur); diff --git a/history.txt b/history.txt new file mode 100644 index 00000000..eab074ab --- /dev/null +++ b/history.txt @@ -0,0 +1,273 @@ +HISTORY of GRAFX: (in chronological order: latest version at the end) + +* GRAFX 1.0á -> 1.02 (09/??/1995 -> 07/??/1996) + Forget it! + +* GRAFX 2.00 Beta 90% (11/01/1996) - Wired'96 release + This version was 1st shown at the Wired'96 demo party in Belgium. + We gave it to many people there, so let's start history from here. + Note that there were a few different "90%" versions because we didn't + want to change the number just for tiny bug-fixes. + +* GRAFX 2.00 Beta 91% (11/20/1996) + - Fixed: Terrific bug in Help/Messages (one line was too long and + crashed the program!). + - Added: Some new parameters for the settings. + - Added: Now, you can automatically set the best resolution for the + picture loaded and/or slightly adapt the picture to keep the colors of + the menu (for those who want to use GrafX2 as a viewer). + - Fixed: Bug that occured when you wanted to restore your previous + brush while being in "grab brush" mode. + - Added: English user's manual written (will be updated later, and + translated into French). + - Fixed: No more displays pixels out of the preview window when + loading corrupt pictures. + - Fixed: Small bug in LBM loading (for non-standard widths). + - Fixed: Minor error when saving the original screen dimensions in PKM + files. (we didn't save words with Intel conventions) + - Fixed: Exactly the same bug for LBM (but with Motorola conventions) + - Removed: No more saving the current palette when exiting the program + (that was useless and boring when pictures had a weird palette). + +* GRAFX 2.00 Beta 92% (11/27/1996) + - Fixed/Removed: Error message occuring when accessing a drive with no + disk or so finally suppressed! + - Fixed: BMP loading was almost completely bugged and it should now be + completely debugged. + - Fixed/Modified: Set_palette routine (the previous one was fast but + did not work with some weird cards that don't support a REP OUTSB). + - Added: Multi-Undo. + - Added: Backup (*.BAK) files. + +* GRAFX 2.00 Beta 93% (12/12/1996) + - Fixed: Bug that occured when approaching the borders of the screen + in grid mode with the type of cursor used for brush grabbing. + - Fixed: Small but annoying bug when saving files with a name of 9 + characters. + - Fixed: Saved PAL files no longer modify the picture's name (some + mistake must have been done when we implemented the backup option). + - Added: Now, you can stop the loading of previews by pressing a key. + - Improved: Video cards that don't use the same VESA bank for reading + and writing should now work correctly. + - Improved: Frame displayed around the magnifier's preview. + - Improved: Menu of resolutions completely modified, and many new + modes added. + - Modified: The default colors of the menu have been slightly + lightened. + - Improved: The whole configuration is now saved and reloaded in the + settings menu. + +* GRAFX 2.00 Beta 94.0|1|2% (02/13-23/1997) - ACE CD #4 & Volcanic3 releases + (These different versions were too close from each other to be + separated in this file. Just check the last modifications to know + which version you have) + - Added/Improved: (approximative) HAM6 and HAM8 support in IFF(LBM) + files, and improved compatibily with Amiga IFF files => should be + total now. + - Added: The absolutely useless :) CEL and KCF (KISS) file formats. + - Added: The not much more useful SCx (ColoRIX) file format. + - Improved: You can now use the keys to scroll the text in the Help. + - Fixed: Small bug in the scrolling list of resolutions (1 extra line + was displayed at the end of the list when current mode was 640x512). + - Added: English user's manual translated into French (and corrected.. + There can be bugs in text files :)). + - Improved: Now, you can use the brush as an eraser by right clicking. + - Added: X-Invert in the palette editor. + - Fixed: Small bug in the reduce-palette function. + - Improved: GIF saving strongly accelerated (finally!). + - Improved: Shade mode completely modified (customized shades added). + - Fixed: Tiny bug in the block definition of the palette editor. + - Improved: Non-standard PCX files that don't reset the compression + after each line should be supported now (at least for 256-color + pictures). + - Added: Undo in the Shade menu. + - Added: Statistics screen. + +* GRAFX 2.00 Beta 94.666% (03/20/1997) + - Fixed: Statistics screen no longer displays that VESA 1.2 is not + supported. + - Fixed: A few bugs of no consequence. + - Fixed: Bug in the mode-X initialization introduced in the previous + version. + - Added: It is possible to choose between Relative and Absolute + coordinates in the settings menu. + - Improved: The colors of the menu are now calculated from the current + palette, so you won't have to be concerned by the colors of the menu + any more. + - Fixed: The VESA modes are no longer disabled for some video cards. + - Imporoved: "Windows 95" keys are now usable. + - Modified: We now use the EOS dos-extender Copyright (c) 1996 by + Eclipse, so read carefully the docs if you can't use GrafX2 anymore. + +* GRAFX 2.00 Beta 95% (07/18/1997) - Wired'97 release + (It's GrafX2 creation's 1st anniversary! =D (...but still Beta :/) + We wrote the usual "void main(int argc, char * argv[])" one year ago!) + - Fixed: PCX files with odd widths should be supported now. (We fixed + a bug in version 94.1% which added a new one) :( + - Fixed: Small display bug in the grid of the Sieve menu. + - Fixed: Oops! We forgot to remap the colors of the menu when loading + a PAL file. That's stupid! :) + - Improved: The number of predefined paintbrushes has been doubled. + - Added: Outline and Nibble effects for brushes. + - Improved: The "Brush grabbing", "Zoom" and "Pipette" options are no + more stopped by hiding/showing the tool-bar. + - Improved: Now, you can change the current color while drawing. + - Improved: The "auto-set resolution" option works better. + - Added: The 3 color components are displayed in the toolbar when you + want to choose a color. + - Added: A small preview of the color selected by the pipette is + displayed in the tool-bar. + - Fixed: GIF saving (the bug didn't corrupt the file but resulted in a + file that wasn't as well compressed as it should have been). + - Fixed: GIF loading doesn't flash any more on some pictures that were + not corrupt; and LBM neither when loading is interrupted by user. + - Added: Menu where you can choose what you want to copy to the spare + page (pixels, palette, or both...). + - Modified: The size of the palette editor has been very slightly + reduced. + - Modified: The Stencil is now taken into account when using the + "Clear" button. + - Improved: The "magnify" mode is finally displayed with a splitted + screen where you can see both zoomed and unzoomed parts of the picture. + - Added: Now, you can load a picture from the command line (type + "gfx2 /?" for the syntax). + - Added: The preview of a PAL file is now displayed in file-selectors. + - Modified: The tool-bar has been reduced vertically by about 1/3. + - Fixed: Bug in the Grid menu. (The user was able to enter a null grid + step. Doh!) + - Added: "Adjust brush pick" option. + - Fixed: DP2e (LBM-"PBM") files (including new BBM files) with odd + width are now loaded correctly. + - Improved: LBM files are now saved with their exact width and not + with a multiple-of-16 witdh (viewers that can't read these files are + "badly coded" because we save them correctly). + - Improved: The selector bar is now placed on last visited directory + when you change directory. + - Added: "Mask" drawing mode. + - Added: "Smear" drawing mode. + - Improved: "Shade" mode options (normal, loop, saturation). + - Added: You can define if you want Feedback (or not) while drawing + in the drawing modes (effects). + - Improved: The amount of memory used for brushes has been reduced. + - Improved: Scrolling lists speed slightly accelerated. + - Improved: FloodFill slightly accelerated. + +* GRAFX 2.00 Beta 95.5% (09/04/1997) + - Improved: SCx files with less than 256 colors are now supported. + - Fixed: Bug when double-clicking on the Floodfill button. + - Fixed: Bug when "flood-filling" with an effect with feedback. + - Fixed: Bug when filling a vertical-1-pixel-wide area. + - Fixed: Bug of the shape of the cursor when a window is open in + magnify mode. + - Added: Special cursor shape for the pipette. + - Modified: The method to recenter the page when exiting magnifier + mode (the picture recovers its position as it was before zooming). + - Added: Linear Frame Buffer (VESA 2.0 LFB) supported. + - Added: You can now load and save brushes (from the Brush FX menu). + - Fixed: A few video modes (Modes X with a height multiple of 270). + - Fixed: You couldn't save the configuration in the settings menu if + the Auto-save option was off. + - Improved: Polyform has now reached its definitive behaviour. + - Added: Polyfill and filled polyform. + - Added: Lasso (polyformed brushes). + - Added: Concentric lines. + - Added: GFX2.INI file (check its contents for new options). + - Improved: GFX2.CFG file will have ascending compatibility with + future versions from now. + - Added: Some drawing tips have been detailed in the documentation + files. + - Improved: Pipette handling. + +* GRAFX 2.00 Beta 96% (11/03/1997) - Saturne (aborted) party 5 release + - Added: Now, you can increase or decrease the size of the paintbrush. + The default keys are [,<] and [.>] ([;.] and [:/] for azerty). + - Added: Typing the first letters of a filename in file-selectors will + place the selection bar onto it. + - Fixed: Small but annoying bugs in the writing of the GFX2.CFG file + in GFXCFG. The data concerning Shade and Stencil modes were destroyed. + - Added/Improved: It is now possible to define the matrix of the + Smooth mode. We also seized the opportunity to improve the Smooth on + the boundaries of the picture, and to improve the function that + calculates nearest colors. + - Added: The "Replace color" option that replaces all the pixels of + the color pointed by the mouse with the paintbrush color. This tool is + accessible by right clicking on the Floodfill button. + - Improved: FloodFill slightly accelerated (especially with small + surfaces). + - Fixed: The picture was automatically zoomed when choosing a zoom + factor in the menu if the Fast_zoom option was set. + - Added: "Stretch brush". + - Added: Now, you can move windows (menus) and even hide the palette + menu for picking a color that is behind it (with the key just below + ). + - Fixed: Small bug in "Menu_ratio=2" mode when remapping the screen + after color changes. + - Added: "Thin" cursor type (looks like VGApaint's one). + - Fixed: A few video modes (Modes X with a height multiple of 224 and + some others). + - Added: It is now possible to select the colors that can be used for + the smooth and transparency modes, and remapping. + - Fixed: Clicking twice on the Lasso button did not restore the paint- + brush correctly. + - Fixed: the absolute coordinates option wasn't correctly saved in + the .INI file. + - Added: A few new parameters can be defined in the .INI file. + - Added: "Copy palette to spare page and remap destination" option + (accessible from the "Copy to spare page" menu (default: Shift+Tab)). + +* GRAFX 2.00 Beta 96.1% (02/28/1998) - Volcanic Party 4 release + - Fixed: File selector gauges don't bug any more when there are more + than 584 entries :) in the current directory. + - Fixed: The file selector _should_ hang no more on non-image (or + corrupt image) files containing data that look like a known format + signature. + - Fixed: Old and horrible :) video bug. Most of the VESA video cards + that displayed unexpected pixels (when moving the mouse for instance) + should work better (perfectly?) now. + - Fixed: The mouse correction factors didn't work properly. + - Added: Quick-shade mode. + - Improved: You can hide any menu that needs a color selection to pick + up a color behind the window. + - Added: A couple of new parameters in the GFX2.INI file. + +* GRAFX 2.00 Alpha 96.3% (04/11/1998) - Lucky n' Tigrou Party 2 release + !!! Warning: possibly unstable version !!! + - Improved: You can edit pictures bigger than 1024x768, and small + pictures take much less memory, allowing to have many more undo pages! + - Improved: The list of undo pages is preserved when you load a + picture, modify its size, or just go to the spare page. + - Added: You can "kill" a page (i.e. removing it from the list of undo + pages). + - Modified: The Settings menu has been reorganized. + - Improved: The drawing mode is no more set to "discontinuous" by + default. + - Improved: The function to compute the best matching RGB color used + in smooth, colorize, and some other operations has been strongly + accelerated on 486 and Cyrix processors, while it should be about the + same speed or very slightly slower on Intel Pentiums (II) than before. + - Fixed: The program finally works under Windows NT (without dos4gw)! + +* GRAFX 2.00 Beta 96.5% (12/23/1999) - Xmas'99 release + - Fixed: This version seems (is!) stable even with huge pictures. :) + - Fixed: A few options on brushes kept modifying the continuity of the + free-hand drawing mode. + - Fixed: The "nibble brush" operation crashed sometimes. + - Fixed: Remapping the screen after modifying colors in the palette + editor displayed, in rare cases, unexpected pixels or even crashed. + It didn't remap correctly the picture in "Magnify" mode, too. + - Fixed: Catastrophic bug occuring when you "flood-filled" an area + starting at the bottom of the picture. + - Added: An option in GFX2.INI to tell if the number of colors used + must be automatically calculated, and another one for the default + video mode at startup. + - Fixed: The colors of the menu are now correctly remapped when + getting colors from the brush. + - Added: Degas Elite's file formats (PI1,PC1,...) support. + - Added: True-color BMP (Windows) and PCX images can be loaded. They + will be converted to a 256-color image with palette optimization and + Floyd/Steinberg dithering. Note: some other true-color formats will be + added in the next release. + - Fixed: Loading corrupt pictures with null dimensions could crash. + - Improved: Brush streching is now in "real time" (and snaps to the + grid if "Adjust brush picking" is set). + - Added: Brush rotation by any angle. diff --git a/init.c b/init.c new file mode 100644 index 00000000..89f5dce9 --- /dev/null +++ b/init.c @@ -0,0 +1,2137 @@ +#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" + +// 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--); + Repertoire_du_programme[Position+1]='\0'; +} + + +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; + 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); + } + +} + + +// 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;Indicest_size; + if (Taille_fichier!=TAILLE_FICHIER_DATA) + Erreur(ERREUR_DAT_CORROMPU); + + if (read(Handle,Palette_defaut,sizeof(T_Palette))!=sizeof(T_Palette)) + Erreur(ERREUR_DAT_CORROMPU); + Decrypte((byte *)Palette_defaut,sizeof(T_Palette)); + + if (read(Handle,BLOCK_MENU,LARGEUR_MENU*HAUTEUR_MENU)!=LARGEUR_MENU*HAUTEUR_MENU) + Erreur(ERREUR_DAT_CORROMPU); + Decrypte(BLOCK_MENU,LARGEUR_MENU*HAUTEUR_MENU); + + if (read(Handle,SPRITE_EFFET,LARGEUR_SPRITE_MENU*HAUTEUR_SPRITE_MENU*NB_SPRITES_EFFETS)!= + LARGEUR_SPRITE_MENU*HAUTEUR_SPRITE_MENU*NB_SPRITES_EFFETS) + Erreur(ERREUR_DAT_CORROMPU); + Decrypte((byte *)SPRITE_EFFET,LARGEUR_SPRITE_MENU*HAUTEUR_SPRITE_MENU*NB_SPRITES_EFFETS); + + if (read(Handle,SPRITE_CURSEUR,LARGEUR_SPRITE_CURSEUR*HAUTEUR_SPRITE_CURSEUR*NB_SPRITES_CURSEUR)!= + LARGEUR_SPRITE_CURSEUR*HAUTEUR_SPRITE_CURSEUR*NB_SPRITES_CURSEUR) + Erreur(ERREUR_DAT_CORROMPU); + Decrypte((byte *)SPRITE_CURSEUR,LARGEUR_SPRITE_CURSEUR*HAUTEUR_SPRITE_CURSEUR*NB_SPRITES_CURSEUR); + + if (read(Handle,SPRITE_MENU,LARGEUR_SPRITE_MENU*HAUTEUR_SPRITE_MENU*NB_SPRITES_MENU)!= + LARGEUR_SPRITE_MENU*HAUTEUR_SPRITE_MENU*NB_SPRITES_MENU) + Erreur(ERREUR_DAT_CORROMPU); + Decrypte((byte *)SPRITE_MENU,LARGEUR_SPRITE_MENU*HAUTEUR_SPRITE_MENU*NB_SPRITES_MENU); + + if (read(Handle,SPRITE_PINCEAU,LARGEUR_PINCEAU*HAUTEUR_PINCEAU*NB_SPRITES_PINCEAU)!= + LARGEUR_PINCEAU*HAUTEUR_PINCEAU*NB_SPRITES_PINCEAU) + Erreur(ERREUR_DAT_CORROMPU); + Decrypte((byte *)SPRITE_PINCEAU,LARGEUR_PINCEAU*HAUTEUR_PINCEAU*NB_SPRITES_PINCEAU); + + if (read(Handle,SPRITE_DRIVE,LARGEUR_SPRITE_DRIVE*HAUTEUR_SPRITE_DRIVE*NB_SPRITES_DRIVES)!= + LARGEUR_SPRITE_DRIVE*HAUTEUR_SPRITE_DRIVE*NB_SPRITES_DRIVES) + Erreur(ERREUR_DAT_CORROMPU); + Decrypte((byte *)SPRITE_DRIVE,LARGEUR_SPRITE_DRIVE*HAUTEUR_SPRITE_DRIVE*NB_SPRITES_DRIVES); + + if (!(Logo_GrafX2=(byte *)malloc(231*56))) + Erreur(ERREUR_MEMOIRE); + if (read(Handle,Logo_GrafX2,231*56)!=(231*56)) + Erreur(ERREUR_DAT_CORROMPU); + Decrypte(Logo_GrafX2,231*56); + + if (read(Handle,TRAME_PREDEFINIE,2*16*NB_TRAMES_PREDEFINIES)!=2*16*NB_TRAMES_PREDEFINIES) + Erreur(ERREUR_DAT_CORROMPU); + Decrypte((byte *)TRAME_PREDEFINIE,2*16*NB_TRAMES_PREDEFINIES); + + // Lecture des fontes 8x8: + if (!(Fonte_temporaire=(byte *)malloc(2048))) + Erreur(ERREUR_MEMOIRE); + + // Lecture de la fonte systŠme + 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_systeme[(Indice<<6)+(Pos_X<<3)+Pos_Y]=( ((*(Fonte_temporaire+(Indice*8)+Pos_Y))&(0x80>>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_boutonst_size; + + if ( (Taille_fichier>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/sizeof(CFG_Mode_video))!=NB_MODES_VIDEO) + goto Erreur_lecture_config; + for (Indice=1; Indice<=NB_MODES_VIDEO; Indice++) + { + if (read(Handle,&CFG_Mode_video,sizeof(CFG_Mode_video))!=sizeof(CFG_Mode_video)) + 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 (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*sizeof(CFG_Mode_video); + if (write(Handle,&Chunk,sizeof(Chunk))!=sizeof(Chunk)) + goto Erreur_sauvegarde_config; + for (Indice=0; Indice + +void _splitpath(char* Buffer, char* Chemin, char* Nom_Fichier) +{ + int i=0, Position_Du_Dernier_Slash; + do + { + Chemin[i]=Buffer[i]; + if (Buffer[i]=='/') + Position_Du_Dernier_Slash=i; + i++; + }while (Buffer[i]!=0); + + i=Position_Du_Dernier_Slash+1; + Chemin[i]=0; + strcpy(Nom_Fichier,Buffer+i); +} diff --git a/linux.h b/linux.h new file mode 100644 index 00000000..79f98714 --- /dev/null +++ b/linux.h @@ -0,0 +1,9 @@ +void _splitpath(char* Buffer, char* Chemin, char* Nom_Fichier); +/* Sépare dans la chaîne passée dans Buffer le chemin d'accès du nom de fichier */ + +struct find_t { + unsigned char attrib; + char name[256]; +}; + +#define _A_SUBDIR 1 diff --git a/loadsave.c b/loadsave.c new file mode 100644 index 00000000..875a48ec --- /dev/null +++ b/loadsave.c @@ -0,0 +1,5321 @@ +#define _XOPEN_SOURCE + +#include "const.h" +#include "struct.h" +#include "global.h" +#include "graph.h" +#include "divers.h" +#include "pages.h" +#include "op_c.h" +#include +#include +#include +#include + +#include +#include +#include "boutons.h" + +// On d‚clare m‚chamment le prototype de Erreur pour ‚viter de faire un +// fichier "main.h": +void Erreur(int Code); + + +// Chargement des pixels dans l'‚cran principal +void Pixel_Chargement_dans_ecran_courant(short Pos_X,short Pos_Y,byte Couleur) +{ + if ((Pos_X>=0) && (Pos_Y>=0)) + if ((Pos_X=0) && (Pos_Y>=0)) + if ((Pos_X=0) && (Pos_Y>=0)) + if ((Pos_X> 5) << 5) | + ((V >> 5) << 2) | + ((B >> 6)); + Pixel(Preview_Pos_X+(Pos_X/Preview_Facteur_X), + Preview_Pos_Y+(Pos_Y/Preview_Facteur_Y), + Couleur); + } +} + +// Cr‚ation d'une palette fake +void Palette_fake_24b(T_Palette Palette) +{ + int Couleur; + + // G‚n‚ration de la palette + for (Couleur=0;Couleur<256;Couleur++) + { + Palette[Couleur].R=((Couleur & 0xE0)>>5)<<3; + Palette[Couleur].V=((Couleur & 0x1C)>>2)<<3; + Palette[Couleur].B=((Couleur & 0x03)>>0)<<4; + } +} + +// Suppl‚ment … faire lors de l'initialisation d'une preview dans le cas +// d'une image 24b +void Initialiser_preview_24b(int Largeur,int Hauteur) +{ + if (Pixel_de_chargement==Pixel_Chargement_dans_preview) + { + // Aiguillage du chargement 24b + Pixel_Chargement_24b=Pixel_Chargement_dans_preview_24b; + + // Changement de palette + Palette_fake_24b(Principal_Palette); + Set_palette(Principal_Palette); + Remapper_fileselect(); + } + else + { + // Aiguillage du chargement 24b + Pixel_Chargement_24b=Pixel_Chargement_dans_buffer_24b; + + // Allocation du buffer 24b + Buffer_image_24b= + (struct Composantes *)Emprunter_memoire_de_page(Largeur*Hauteur*sizeof(struct Composantes)); + if (!Buffer_image_24b) + { + // Afficher un message d'erreur + + // Pour ˆtre s–r que ce soit lisible. + Calculer_couleurs_menu_optimales(Principal_Palette); + Message_Memoire_insuffisante(); + if (Pixel_de_chargement==Pixel_Chargement_dans_ecran_courant) + Erreur_fichier=1; // 1 => On n'a pas perdu l'image courante + else + Erreur_fichier=3; // 3 => Chargement de brosse ‚chou‚ + } + else + Image_24b=1; // On a un buffer … traiter en fin de chargement + } +} + + + + +void Initialiser_preview(short Largeur,short Hauteur,long Taille,int Format) +// +// Cette proc‚dure doit ˆtre appel‚e par les routines de chargement +// d'images. +// Elle doit ˆtre appel‚e entre le moment o— l'on connait la dimension de +// l'image (dimension r‚elle, pas dimension tronqu‚e) et l'affichage du +// premier point. +// +{ + char Chaine[256]; + int Image_en_24b; + + Image_en_24b=Format & FORMAT_24B; + Format =Format & (~FORMAT_24B); + + if (Pixel_de_chargement==Pixel_Chargement_dans_preview) + { + // Pr‚paration du chargement d'une preview: + + // Affichage des donn‚es "Image size:" + if ((Largeur<10000) && (Hauteur<10000)) + { + Num2str(Largeur,Chaine,4); + Num2str(Hauteur,Chaine+5,4); + Chaine[4]='x'; + Print_dans_fenetre(226,55,Chaine,CM_Noir,CM_Clair); + } + else + { + Print_dans_fenetre(226,55,"VERY BIG!",CM_Noir,CM_Clair); + } + + // Affichage de la taille du fichier + if (Taille<1048576) + { + // Le fichier fait moins d'un Mega, on affiche sa taille direct + Num2str(Taille,Chaine,9); + Print_dans_fenetre(226,63,Chaine,CM_Noir,CM_Clair); + } + else if ((Taille/1024)<10000000) + { + // Le fichier fait plus d'un Mega, on peut afficher sa taille en Ko + Num2str(Taille/1024,Chaine,7); + Chaine[7]='K'; + Chaine[8]='b'; + Print_dans_fenetre(226,63,Chaine,CM_Noir,CM_Clair); + } + else + { + // Le fichier fait plus de 10 Giga octets (cas trŠs rare :)) + Print_dans_fenetre(226,63,"TOO BIG!!",CM_Noir,CM_Clair); + } + + // Affichage du vrai format + if (Format!=Principal_Format) + { + Print_dans_fenetre( 27,74,"but is:",CM_Fonce,CM_Clair); + Print_dans_fenetre( 83,74,Format_Extension[Format-1],CM_Noir,CM_Clair); + } + + // On efface le commentaire pr‚c‚dent + Block(Fenetre_Pos_X+46*Menu_Facteur_X,Fenetre_Pos_Y+176*Menu_Facteur_Y, + Menu_Facteur_X<<8,Menu_Facteur_Y<<3,CM_Clair); + // Affichage du commentaire + if (Format_Commentaire[Format-1]) + Print_dans_fenetre(46,176,Principal_Commentaire,CM_Noir,CM_Clair); + + // Calculs des donn‚es n‚cessaires … l'affichage de la preview: + Preview_Facteur_X=Round_div_max(Largeur,122*Menu_Facteur_X); + Preview_Facteur_Y=Round_div_max(Hauteur, 82*Menu_Facteur_Y); + + if ( (!Config.Maximize_preview) && (Preview_Facteur_X!=Preview_Facteur_Y) ) + { + if (Preview_Facteur_X>Preview_Facteur_Y) + Preview_Facteur_Y=Preview_Facteur_X; + else + Preview_Facteur_X=Preview_Facteur_Y; + } + + Preview_Pos_X=Fenetre_Pos_X+180*Menu_Facteur_X; + Preview_Pos_Y=Fenetre_Pos_Y+ 89*Menu_Facteur_Y; + + // On nettoie la zone o— va s'afficher la preview: + Block(Preview_Pos_X,Preview_Pos_Y, + Round_div_max(Largeur,Preview_Facteur_X), + Round_div_max(Hauteur,Preview_Facteur_Y), + CM_Noir); + } + else + { + if (Pixel_de_chargement==Pixel_Chargement_dans_ecran_courant) + { + if (Backup_avec_nouvelles_dimensions(0,Largeur,Hauteur)) + { + // La nouvelle page a pu ˆtre allou‚e, elle est pour l'instant pleine + // de 0s. Elle fait Principal_Largeur_image de large. + // Normalement tout va bien, tout est sous contr“le... + } + else + { + // Afficher un message d'erreur + + // Pour ˆtre s–r que ce soit lisible. + Calculer_couleurs_menu_optimales(Principal_Palette); + Message_Memoire_insuffisante(); + Erreur_fichier=1; // 1 => On n'a pas perdu l'image courante + } + } + else // chargement dans la brosse + { + free(Brosse); + free(Smear_Brosse); + Brosse=(byte *)malloc(Largeur*Hauteur); + Brosse_Largeur=Largeur; + Brosse_Hauteur=Hauteur; + if (Brosse) + { + Smear_Brosse=(byte *)malloc(Largeur*Hauteur); + if (!Smear_Brosse) + Erreur_fichier=3; + } + else + Erreur_fichier=3; + } + } + + if (!Erreur_fichier) + if (Image_en_24b) + Initialiser_preview_24b(Largeur,Hauteur); +} + + + +void Dessiner_preview_palette(void) +{ + short Indice; + short Preview_Pos_X=Fenetre_Pos_X+186*Menu_Facteur_X; + short Preview_Pos_Y=Fenetre_Pos_Y+ 90*Menu_Facteur_Y; + + if (Pixel_de_chargement==Pixel_Chargement_dans_preview) + for (Indice=0; Indice<256; Indice++) + Block(Preview_Pos_X+(((Indice>>4)*7)*Menu_Facteur_X), + Preview_Pos_Y+(((Indice&15)*5)*Menu_Facteur_Y), + 5*Menu_Facteur_X,5*Menu_Facteur_Y,Indice); +} + + + +// Calcul du nom complet du fichier +void Nom_fichier_complet(char * Nom_du_fichier, byte Sauve_Colorix) +{ + byte Pos; + + strcpy(Nom_du_fichier,Principal_Repertoire_fichier); + + if (Nom_du_fichier[strlen(Nom_du_fichier)-1]!='\\') + strcat(Nom_du_fichier,"\\"); + + // Si on est en train de sauvegarder une image Colorix, on calcule son ext. + if (Sauve_Colorix) + { + Pos=strlen(Principal_Nom_fichier)-1; + if (Principal_Nom_fichier[Pos]=='?') + { + if (Principal_Largeur_image<=320) + Principal_Nom_fichier[Pos]='I'; + else + { + if (Principal_Largeur_image<=360) + Principal_Nom_fichier[Pos]='Q'; + else + { + if (Principal_Largeur_image<=640) + Principal_Nom_fichier[Pos]='F'; + else + { + if (Principal_Largeur_image<=800) + Principal_Nom_fichier[Pos]='N'; + else + Principal_Nom_fichier[Pos]='O'; + } + } + } + } + } + + strcat(Nom_du_fichier,Principal_Nom_fichier); +} + + +///////////////////////////////////////////////////////////////////////////// +// Gestion des lectures et ‚critures // +///////////////////////////////////////////////////////////////////////////// + +byte * Tampon_lecture; +word Index_lecture; + +void Init_lecture(void) +{ + Tampon_lecture=(byte *)malloc(64000); + Index_lecture=64000; +} + +byte Lire_octet(int Fichier) +{ + if (++Index_lecture>=64000) + { + if (read(Fichier,Tampon_lecture,64000)<=0) + Erreur_fichier=2; + Index_lecture=0; + } + return Tampon_lecture[Index_lecture]; +} + +void Close_lecture(void) +{ + free(Tampon_lecture); +} + +// -------------------------------------------------------------------------- + +byte * Tampon_ecriture; +word Index_ecriture; + +void Init_ecriture(void) +{ + Tampon_ecriture=(byte *)malloc(64000); + Index_ecriture=0; +} + +void Ecrire_octet(int Fichier, byte Octet) +{ + Tampon_ecriture[Index_ecriture++]=Octet; + if (Index_ecriture>=64000) + { + if (write(Fichier,Tampon_ecriture,64000)==-1) + Erreur_fichier=1; + Index_ecriture=0; + } +} + +void Close_ecriture(int Fichier) +{ + if (Index_ecriture) + if (write(Fichier,Tampon_ecriture,Index_ecriture)==-1) + Erreur_fichier=1; + free(Tampon_ecriture); +} + + + +///////////////////////////////////////////////////////////////////////////// + +void (/*__interrupt __near*/ *Ancien_handler_clavier)(void); +void /*__interrupt __near*/ Nouveau_handler_clavier(void) +{ + /* A revoir ... + _disable(); + if (!Erreur_fichier) + Erreur_fichier=-1; + _enable(); + _chain_intr(Ancien_handler_clavier); + */ + ; +} + + +// -------- Modifier la valeur du code d'erreur d'accŠs … un fichier -------- +// On n'est pas oblig‚ d'utiliser cette fonction … chaque fois mais il est +// important de l'utiliser dans les cas du type: +// if (!Erreur_fichier) *** else Erreur_fichier=***; +// En fait, dans le cas o— l'on modifie Erreur_fichier alors qu'elle contient +// dŠj… un code d'erreur. +void Modif_Erreur_fichier(int Nouvelle_valeur) +{ + if (Erreur_fichier>=0) + Erreur_fichier=Nouvelle_valeur; +} + + +// -- Charger n'importe connu quel type de fichier d'image (ou palette) ----- +void Charger_image(byte Image) +{ + int Indice; // Indice de balayage des formats + int Format; // Format du fichier … charger + + + // On place par d‚faut Erreur_fichier … vrai au cas o— on ne sache pas + // charger le format du fichier: + Erreur_fichier=1; + + if (Principal_Format!=0) + { + Format_Test[Principal_Format-1](); + if (!Erreur_fichier) + // Si dans le s‚lecteur il y a un format valide on le prend tout de suite + Format=Principal_Format-1; + } + + if (Erreur_fichier) + { + // Sinon, on va devoir scanner les diff‚rents formats qu'on connait pour + // savoir … quel format est le fichier: + for (Indice=0;Indice0) + Erreur(0); + + if (Image_24b) + { + // On vient de charger une image 24b + if (!Erreur_fichier) + { + // Le chargement a r‚ussi, on peut faire la conversion en 256 couleurs + if (Pixel_de_chargement==Pixel_Chargement_dans_ecran_courant) + { + // Cas d'un chargement dans l'image + if (Convert_bitmap_24B_to_256(Principal_Ecran,Buffer_image_24b,Principal_Largeur_image,Principal_Hauteur_image,Principal_Palette)) + Erreur_fichier=2; + } + else + { + // Cas d'un chargement dans la brosse + if (Convert_bitmap_24B_to_256(Brosse,Buffer_image_24b,Brosse_Largeur,Brosse_Hauteur,Principal_Palette)) + Erreur_fichier=2; + } + if (!Erreur_fichier) + Palette_256_to_64(Principal_Palette); + } + + free(Buffer_image_24b); + } + + if (Image) + { + if ( (Erreur_fichier!=1) && (Format_Backup_done[Format]) ) + { + // On considŠre que l'image charg‚e n'est plus modifi‚e + Principal_Image_modifiee=0; + // Et on documente la variable Principal_Format_fichier avec la valeur: + Principal_Format_fichier=Format+1; + + // Correction des dimensions + if (Principal_Largeur_image<1) + Principal_Largeur_image=1; + if (Principal_Hauteur_image<1) + Principal_Hauteur_image=1; + } + else if (Erreur_fichier!=1) + { + // On considŠre que l'image charg‚e est encore modifi‚e + Principal_Image_modifiee=1; + // Et on documente la variable Principal_Format_fichier avec la valeur: + Principal_Format_fichier=Format+1; + } + else + { + // Dans ce cas, on sait que l'image n'a pas chang‚, mais ses + // paramŠtres (dimension, palette, ...) si. Donc on les restaures. + Download_infos_page_principal(Principal_Backups->Pages); + } + } + } + else + // Sinon, l'appelant sera au courant de l'‚chec grƒce … Erreur_fichier; + // et si on s'apprˆtait … faire un chargement d‚finitif de l'image (pas + // une preview), alors on flash l'utilisateur. + if (Pixel_de_chargement!=Pixel_Chargement_dans_preview) + Erreur(0); +} + + +// -- Sauver n'importe quel type connu de fichier d'image (ou palette) ------ +void Sauver_image(byte Image) +{ + // On place par d‚faut Erreur_fichier … vrai au cas o— on ne sache pas + // sauver le format du fichier: (Est-ce vraiment utile??? Je ne crois pas!) + Erreur_fichier=1; + + Lit_pixel_de_sauvegarde=(Image)?Lit_pixel_dans_ecran_courant:Lit_pixel_dans_brosse; + + Format_Save[Principal_Format_fichier-1](); + + if (Erreur_fichier) + Erreur(0); + else + { + if ((Image) && (Format_Backup_done[Principal_Format_fichier-1])) + Principal_Image_modifiee=0; + } +} + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +//////////////////////////////////// PAL //////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +// -- Tester si un fichier est au format PAL -------------------------------- +void Test_PAL(void) +{ + int Fichier; // Handle du fichier + char Nom_du_fichier[256]; // Nom complet du fichier + long Taille_du_fichier; // Taille du fichier + struct stat* Informations_Fichier=NULL; + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=1; + + // Ouverture du fichier + Fichier=open(Nom_du_fichier,O_RDONLY); + if (Fichier!=-1) + { + stat(Nom_du_fichier,Informations_Fichier); + // Lecture de la taille du fichier + Taille_du_fichier=Informations_Fichier->st_size; + close(Fichier); + // Le fichier ne peut ˆtre au format PAL que si sa taille vaut 768 octets + if (Taille_du_fichier==sizeof(T_Palette)) + Erreur_fichier=0; + } +} + + +// -- Lire un fichier au format PAL ----------------------------------------- +void Load_PAL(void) +{ + int Handle; // Handle du fichier + char Nom_du_fichier[256]; // Nom complet du fichier + long Taille_du_fichier; // Taille du fichier + + + Nom_fichier_complet(Nom_du_fichier,0); + Erreur_fichier=0; + + // Ouverture du fichier + Handle=open(Nom_du_fichier,O_RDONLY); + if (Handle!=-1) + { + // Initialiser_preview(???); // Pas possible... pas d'image... + + // Lecture du fichier dans Principal_Palette + if (read(Handle,Principal_Palette,sizeof(T_Palette))==sizeof(T_Palette)) + { + Set_palette(Principal_Palette); + Remapper_fileselect(); + + // On dessine une preview de la palette (si chargement=preview) + Dessiner_preview_palette(); + } + else + Erreur_fichier=2; + + // Fermeture du fichier + close(Handle); + } + else + // Si on n'a pas r‚ussi … ouvrir le fichier, alors il y a eu une erreur + Erreur_fichier=1; +} + + +// -- Sauver un fichier au format PAL --------------------------------------- +void Save_PAL(void) +{ + int Fichier; // Handle du fichier + char Nom_du_fichier[256]; // Nom complet du fichier + long Taille_du_fichier; // Taille du fichier + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + + // Ouverture du fichier + Fichier=open(Nom_du_fichier,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP); + if (Fichier!=-1) + { + // Enregistrement de Principal_Palette dans le fichier + if (write(Fichier,Principal_Palette,sizeof(T_Palette))==-1) + { + Erreur_fichier=1; + close(Fichier); + remove(Nom_du_fichier); + } + else // Ecriture correcte => Fermeture normale du fichier + close(Fichier); + } + else // Si on n'a pas r‚ussi … ouvrir le fichier, alors il y a eu une erreur + { + Erreur_fichier=1; + 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! + } +} + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +//////////////////////////////////// IMG //////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + + +// -- Tester si un fichier est au format IMG -------------------------------- +void Test_IMG(void) +{ + int Handle; // Handle du fichier + char Nom_du_fichier[256]; // Nom complet du fichier + struct Header + { + byte Filler1[6]; + word Largeur; + word Hauteur; + byte Filler2[118]; + T_Palette Palette; + } IMG_Header; + byte Signature[6]={0x01,0x00,0x47,0x12,0x6D,0xB0}; + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=1; + + // Ouverture du fichier + Handle=open(Nom_du_fichier,O_RDONLY); + if (Handle!=-1) + { + // Lecture et v‚rification de la signature + if ((read(Handle,&IMG_Header,sizeof(struct Header)))==sizeof(struct Header)) + { + if ( (!memcmp(IMG_Header.Filler1,Signature,6)) + && IMG_Header.Largeur && IMG_Header.Hauteur) + Erreur_fichier=0; + } + // Fermeture du fichier + close(Handle); + } +} + + +// -- Lire un fichier au format IMG ----------------------------------------- +void Load_IMG(void) +{ + char Nom_du_fichier[256]; // Nom complet du fichier + byte * Buffer; + int Fichier; + word Pos_X,Pos_Y; + long Largeur_lue; + long Taille_du_fichier; + struct Header + { + byte Filler1[6]; + word Largeur; + word Hauteur; + byte Filler2[118]; + T_Palette Palette; + } IMG_Header; + struct stat* Informations_Fichier=NULL; + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + stat(Nom_du_fichier,Informations_Fichier); + Taille_du_fichier=Informations_Fichier->st_size; + + if (read(Fichier,&IMG_Header,sizeof(struct Header))==sizeof(struct Header)) + { + Buffer=(byte *)malloc(IMG_Header.Largeur); + + Initialiser_preview(IMG_Header.Largeur,IMG_Header.Hauteur,Taille_du_fichier,FORMAT_IMG); + if (Erreur_fichier==0) + { + // On commence par passer la palette en 256 comme ‡a, si la nouvelle + // palette a moins de 256 coul, la pr‚c‚dente ne souffrira pas d'un + // assombrissement pr‚judiciable. + Palette_64_to_256(Principal_Palette); + // On peut maintenant transf‚rer la nouvelle palette + memcpy(Principal_Palette,IMG_Header.Palette,sizeof(T_Palette)); + Palette_256_to_64(Principal_Palette); + Set_palette(Principal_Palette); + Remapper_fileselect(); + + Principal_Largeur_image=IMG_Header.Largeur; + Principal_Hauteur_image=IMG_Header.Hauteur; + + for (Pos_Y=0;(Pos_Yst_size; + + if (read(Fichier,&Head,sizeof(struct Header))==sizeof(struct Header)) + { + Principal_Commentaire[0]='\0'; // On efface le commentaire + if (Head.Jump) + { + Indice=0; + while ( (IndiceTAILLE_COMMENTAIRE) + { + Couleur=Octet; // On se sert de Couleur comme + Octet=TAILLE_COMMENTAIRE; // variable temporaire + Couleur-=TAILLE_COMMENTAIRE; + } + else + Couleur=0; + + if (read(Fichier,Principal_Commentaire,Octet)==Octet) + { + Indice+=Octet; + Principal_Commentaire[Octet]='\0'; + if (Couleur) + if (lseek(Fichier,Couleur,SEEK_CUR)==-1) + Erreur_fichier=2; + } + else + Erreur_fichier=2; + } + else + Erreur_fichier=2; + break; + + case 1 : // Dimensions de l'‚cran d'origine + if (read(Fichier,&Octet,1)==1) + { + if (Octet==4) + { + Indice+=4; + if ( (read(Fichier,&Ecran_original_X,2)!=2) + || (read(Fichier,&Ecran_original_Y,2)!=2) ) + Erreur_fichier=2; + } + else + Erreur_fichier=2; + } + else + Erreur_fichier=2; + break; + + case 2 : // Couleur de transparence + if (read(Fichier,&Octet,1)==1) + { + if (Octet==1) + { + Indice++; + if (read(Fichier,&Back_color,1)!=1) + Erreur_fichier=2; + } + else + Erreur_fichier=2; + } + else + Erreur_fichier=2; + break; + + default: + if (read(Fichier,&Octet,1)==1) + { + Indice+=Octet; + if (lseek(Fichier,Octet,SEEK_CUR)==-1) + Erreur_fichier=2; + } + else + Erreur_fichier=2; + } + } + else + Erreur_fichier=2; + } + if ( (!Erreur_fichier) && (Indice!=Head.Jump) ) + Erreur_fichier=2; + } + + Init_lecture(); + + if (!Erreur_fichier) + { + Initialiser_preview(Head.Largeur,Head.Hauteur,Taille_du_fichier,FORMAT_PKM); + if (Erreur_fichier==0) + { + Principal_Largeur_image=Head.Largeur; + Principal_Hauteur_image=Head.Hauteur; + Taille_image=(dword)(Principal_Largeur_image*Principal_Hauteur_image); + + memcpy(Principal_Palette,Head.Palette,sizeof(T_Palette)); + Set_palette(Principal_Palette); + Remapper_fileselect(); + + Compteur_de_donnees_packees=0; + Compteur_de_pixels=0; + Taille_pack=(Informations_Fichier->st_size)-sizeof(struct Header)-Head.Jump; + + // Boucle de d‚compression: + while ( (Compteur_de_pixels>8); + Ecrire_octet(Fichier,Hauteur_ecran&0xFF); + Ecrire_octet(Fichier,Hauteur_ecran>>8); + // Ecriture de la back-color + Ecrire_octet(Fichier,2); + Ecrire_octet(Fichier,1); + Ecrire_octet(Fichier,Back_color); + + // Routine de compression PKM de l'image + Taille_image=(dword)(Principal_Largeur_image*Principal_Hauteur_image); + Compteur_de_pixels=0; + Valeur_pixel=Lit_pixel_de_sauvegarde(0,0); + + while ( (Compteur_de_pixels2) && (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); + } + } + else + { + 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); + } + } + } + + Close_ecriture(Fichier); + } + else + Erreur_fichier=1; + close(Fichier); + } + else + { + Erreur_fichier=1; + close(Fichier); + } + // S'il y a eu une erreur de sauvegarde, on ne va tout de mˆme pas laisser + // ce fichier pourri traŒner... Ca fait pas propre. + if (Erreur_fichier) + remove(Nom_du_fichier); +} + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +//////////////////////////////////// LBM //////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + + +// -- Tester si un fichier est au format LBM -------------------------------- + + int LBM_Fichier; + + // ------------ Lire et traduire une valeur au format Motorola ------------ + dword Lire_long(void) + { + dword Temp; + dword Valeur; + + if (read(LBM_Fichier,&Valeur,4)!=4) + Erreur_fichier=1; + swab((char *)&Valeur,(char *)&Temp,4); + return ((Temp>>16)+(Temp<<16)); + } + + +void Test_LBM(void) +{ + char Nom_du_fichier[256]; + char Format[4]; + char Section[4]; + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + + if ((LBM_Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + if (read(LBM_Fichier,Section,4)!=4) + Erreur_fichier=1; + else + if (memcmp(Section,"FORM",4)) + Erreur_fichier=1; + else + { + Lire_long(); // On aurait pu v‚rifier que ce long est ‚gal … la taille + // du fichier - 8, mais ‡a aurait interdit de charger des + // fichiers tronqu‚s (et d‚j… que c'est chiant de perdre + // une partie du fichier il faut quand mˆme pouvoir en + // garder un peu... Sinon, moi je pleure :'( !!! ) + if (read(LBM_Fichier,Format,4)!=4) + Erreur_fichier=1; + else + if ( (memcmp(Format,"ILBM",4)) && (memcmp(Format,"PBM ",4)) ) + Erreur_fichier=1; + } + close(LBM_Fichier); + } + else + Erreur_fichier=1; +} + + +// -- Lire un fichier au format LBM ----------------------------------------- + + byte * LBM_Buffer; + byte Image_HAM; + byte HBPm1; // Header.BitPlanes-1 + + // ---------------- Adapter la palette pour les images HAM ---------------- + void Adapter_Palette_HAM(void) + { + short I,J,Temp; + byte Couleur; + + if (Image_HAM==6) + { + for (I=1; I<=14; I++) + { + // On recopie a palette de base + memcpy(Principal_Palette+(I<<4),Principal_Palette,48); + // On modifie les teintes de cette palette + for (J=0; J<16; J++) + { + Couleur=(I<<4)+J; + if (I<=7) + { + if (I&1) + { + Temp=Principal_Palette[J].R+16; + Principal_Palette[Couleur].R=(Temp<63)?Temp:63; + } + if (I&2) + { + Temp=Principal_Palette[J].V+16; + Principal_Palette[Couleur].V=(Temp<63)?Temp:63; + } + if (I&4) + { + Temp=Principal_Palette[J].B+16; + Principal_Palette[Couleur].B=(Temp<63)?Temp:63; + } + } + else + { + if ((I-7)&1) + { + Temp=Principal_Palette[J].R-16; + Principal_Palette[Couleur].R=(Temp>=0)?Temp:0; + } + if ((I-7)&2) + { + Temp=Principal_Palette[J].V-16; + Principal_Palette[Couleur].V=(Temp>=0)?Temp:0; + } + if ((I-7)&4) + { + Temp=Principal_Palette[J].B-16; + Principal_Palette[Couleur].B=(Temp>=0)?Temp:0; + } + } + } + } + // Ici, il reste les 16 derniŠres couleurs … modifier + for (I=240,J=0; J<16; I++,J++) + { + Temp=Principal_Palette[J].R+8; + Principal_Palette[I].R=(Temp<63)?Temp:63; + Temp=Principal_Palette[J].V+8; + Principal_Palette[I].V=(Temp<63)?Temp:63; + Temp=Principal_Palette[J].B+8; + Principal_Palette[I].B=(Temp<63)?Temp:63; + } + } + else if (Image_HAM==8) + { + for (I=1; I<=3; I++) + { + // On recopie la palette de base + memcpy(Principal_Palette+(I<<6),Principal_Palette,192); + // On modifie les teintes de cette palette + for (J=0; J<64; J++) + { + Couleur=(I<<6)+J; + switch (I) + { + case 1 : + Temp=Principal_Palette[J].R+16; + Principal_Palette[Couleur].R=(Temp<63)?Temp:63; + break; + case 2 : + Temp=Principal_Palette[J].V+16; + Principal_Palette[Couleur].V=(Temp<63)?Temp:63; + break; + default: + Temp=Principal_Palette[J].B+16; + Principal_Palette[Couleur].B=(Temp<63)?Temp:63; + } + } + } + } + else // Image 64 couleurs sauv‚e en 32. + { + for (I=0; I<32; I++) + { + J=I+32; + Principal_Palette[J].R=Principal_Palette[I].R>>1; + Principal_Palette[J].V=Principal_Palette[I].V>>1; + Principal_Palette[J].B=Principal_Palette[I].B>>1; + } + } + } + + // ------------------------- Attendre une section ------------------------- + byte Wait_for(byte * Section_attendue) + { + // Valeur retourn‚e: 1=Section trouv‚e, 0=Section non trouv‚e (erreur) + dword Taille_section; + byte Section_lue[4]; + + if (read(LBM_Fichier,Section_lue,4)!=4) + return 0; + while (memcmp(Section_lue,Section_attendue,4)) // Sect. pas encore trouv‚e + { + Taille_section=Lire_long(); + if (Erreur_fichier) + return 0; + if (Taille_section&1) + Taille_section++; + if (lseek(LBM_Fichier,Taille_section,SEEK_CUR)==-1) + return 0; + if (read(LBM_Fichier,Section_lue,4)!=4) + return 0; + } + return 1; + } + + // ----------------------- Afficher une ligne ILBM ------------------------ + void Draw_ILBM_line(short Pos_Y, short Vraie_taille_ligne) + { + byte Couleur; + byte Rouge,Vert,Bleu; + byte Temp; + short Pos_X; + + if (Image_HAM<=1) // ILBM + { + for (Pos_X=0; Pos_X>2; + Couleur=Meilleure_couleur(Rouge,Vert,Bleu); + break; + case 0x02: // Rouge + Rouge=Temp>>2; + Couleur=Meilleure_couleur(Rouge,Vert,Bleu); + break; + case 0x03: // Vert + Vert=Temp>>2; + Couleur=Meilleure_couleur(Rouge,Vert,Bleu); + break; + default: // Nouvelle couleur + Couleur=Temp; + Rouge=Principal_Palette[Couleur].R; + Vert =Principal_Palette[Couleur].V; + Bleu =Principal_Palette[Couleur].B; + } + Pixel_de_chargement(Pos_X,Pos_Y,Couleur); + } + } + } + + +void Load_LBM(void) +{ + char Nom_du_fichier[256]; + int Fichier; + struct Header_LBM + { + word Width; + word Height; + short Xorg; // Inutile + short Yorg; // Inutile + byte Bit_planes; + byte Mask; + byte Compression; + byte Pad1; // Inutile + word Transp_col; + byte Xaspect; // Inutile + byte Yaspect; // Inutile + short Xscreen; + short Yscreen; + } Header; + char Format[4]; + char Section[4]; + byte Octet; + short B256; + dword Nb_couleurs; + dword Taille_image; + short Pos_X; + short Pos_Y; + short Compteur; + short Taille_ligne; // Taille d'une ligne en octets + short Vraie_taille_ligne; // Taille d'une ligne en pixels + byte Couleur; + long Taille_du_fichier; + struct stat* Informations_Fichier=NULL; + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + + if ((LBM_Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + stat(Nom_du_fichier,Informations_Fichier); + Taille_du_fichier=Informations_Fichier->st_size; + + // On avance dans le fichier (pas besoin de tester ce qui l'a d‚j… ‚t‚) + read(LBM_Fichier,Section,4); + Lire_long(); + read(LBM_Fichier,Format,4); + if (!Wait_for("BMHD")) + Erreur_fichier=1; + Lire_long(); + + // Maintenant on lit le header pour pouvoir commencer le chargement de l'image + if ( (read(LBM_Fichier,&Header,sizeof(struct Header_LBM))==sizeof(struct Header_LBM)) + && Header.Width && Header.Height) + { + if ( (Header.Bit_planes) && (Wait_for("CMAP")) ) + { + Nb_couleurs=Lire_long()/3; + + if (((int)1< il faut copier les 32 coul. + } // sur les 32 suivantes et assombrir ces derniŠres. + else + { + if ((Header.Bit_planes==6) || (Header.Bit_planes==8)) + Image_HAM=Header.Bit_planes; + else + // Erreur_fichier=1; /* C'est cens‚ ˆtre incorrect mais j'ai */ + Image_HAM=0; /* trouv‚ un fichier comme ‡a, alors... */ + } + } + else + Image_HAM=0; + + if ( (!Erreur_fichier) && (Nb_couleurs>=2) && (Nb_couleurs<=256) ) + { + HBPm1=Header.Bit_planes-1; + if (Header.Mask==1) + Header.Bit_planes++; + + // Deluxe paint le fait... alors on le fait... + Back_color=Header.Transp_col; + + // On commence par passer la palette en 256 comme ‡a, si la nouvelle + // palette a moins de 256 coul, la pr‚c‚dente ne souffrira pas d'un + // assombrissement pr‚judiciable. + if (Config.Clear_palette) + memset(Principal_Palette,0,sizeof(T_Palette)); + else + Palette_64_to_256(Principal_Palette); + // On peut maintenant charger la nouvelle palette + if (read(LBM_Fichier,Principal_Palette,3*Nb_couleurs)==(3*Nb_couleurs)) + { + Palette_256_to_64(Principal_Palette); + if (Image_HAM) + Adapter_Palette_HAM(); + Set_palette(Principal_Palette); + Remapper_fileselect(); + + // On lit l'octet de padding du CMAP si la taille est impaire + if (Nb_couleurs&1) + if (read(LBM_Fichier,&Octet,1)==1) + Erreur_fichier=2; + + if ( (Wait_for("BODY")) && (!Erreur_fichier) ) + { + Taille_image=Lire_long(); + swab((char *)&Header.Width ,(char *)&Principal_Largeur_image,2); + swab((char *)&Header.Height,(char *)&Principal_Hauteur_image,2); + + swab((char *)&Header.Xscreen,(char *)&Ecran_original_X,2); + swab((char *)&Header.Yscreen,(char *)&Ecran_original_Y,2); + + Initialiser_preview(Principal_Largeur_image,Principal_Hauteur_image,Taille_du_fichier,FORMAT_LBM); + if (Erreur_fichier==0) + { + if (!memcmp(Format,"ILBM",4)) // "ILBM": InterLeaved BitMap + { + // Calcul de la taille d'une ligne ILBM (pour les images ayant des dimensions exotiques) + if (Principal_Largeur_image & 15) + { + Vraie_taille_ligne=( (Principal_Largeur_image+16) >> 4 ) << 4; + Taille_ligne=( (Principal_Largeur_image+16) >> 4 )*(Header.Bit_planes<<1); + } + else + { + Vraie_taille_ligne=Principal_Largeur_image; + Taille_ligne=(Principal_Largeur_image>>3)*Header.Bit_planes; + } + + if (!Header.Compression) + { // non compress‚ + LBM_Buffer=(byte *)malloc(Taille_ligne); + for (Pos_Y=0; ((Pos_Y127) + { + Couleur=Lire_octet(LBM_Fichier); + B256=(short)(256-Octet); + for (Compteur=0; Compteur<=B256; Compteur++) + if (Pos_X127) + { + Couleur=Lire_octet(LBM_Fichier); + B256=256-Octet; + for (Compteur=0; Compteur<=B256; Compteur++) + Pixel_de_chargement(Pos_X++,Pos_Y,Couleur); + } + else + for (Compteur=0; Compteur<=Octet; Compteur++) + Pixel_de_chargement(Pos_X++,Pos_Y,Lire_octet(LBM_Fichier)); + } + } + Close_lecture(); + } + } + } + } + else + Modif_Erreur_fichier(2); + } + else + { + // On restore l'ancienne palette en cas d'erreur... + Palette_256_to_64(Principal_Palette); + // ... ce qui permet de ne renvoyer qu'une erreur 1 (pas de modif) + Erreur_fichier=1; + } + } + else + Modif_Erreur_fichier(1); + } + else + Erreur_fichier=1; + } + else + Erreur_fichier=1; + + close(LBM_Fichier); + } + else + Erreur_fichier=1; +} + + +// -- Sauver un fichier au format LBM --------------------------------------- + + byte LBM_File_de_couleurs[129]; + word LBM_Taille_de_file; + byte LBM_Mode_repetition; + + // ----------- Traduire et ‚crire une valeur au format Motorola ----------- + void Ecrire_long(dword Valeur) + { + dword Temp; + + swab((char *)&Valeur,(char *)&Temp,4); + Valeur=(Temp>>16)+(Temp<<16); + if (write(LBM_Fichier,&Valeur,4)==-1) + Erreur_fichier=1; + } + + // ------------- Ecrire les couleurs que l'on vient de traiter ------------ + void Transferer_couleurs(void) + { + byte Indice; + + if (LBM_Taille_de_file>0) + { + if (LBM_Mode_repetition) + { + Ecrire_octet(LBM_Fichier,257-LBM_Taille_de_file); + Ecrire_octet(LBM_Fichier,LBM_File_de_couleurs[0]); + } + else + { + Ecrire_octet(LBM_Fichier,LBM_Taille_de_file-1); + for (Indice=0; Indice et on a 3 couleurs qui se suivent + { + LBM_Taille_de_file-=2; + Transferer_couleurs(); + LBM_File_de_couleurs[0]=Couleur; + LBM_File_de_couleurs[1]=Couleur; + LBM_File_de_couleurs[2]=Couleur; + LBM_Taille_de_file=3; + LBM_Mode_repetition=1; + } + } + else // La couleur n'est pas la mˆme que la pr‚c‚dente + { + if (!LBM_Mode_repetition) // On conserve le mode... + { + LBM_File_de_couleurs[LBM_Taille_de_file++]=Couleur; + if (LBM_Taille_de_file==128) + Transferer_couleurs(); + } + else // On change de mode... + { + Transferer_couleurs(); + LBM_File_de_couleurs[LBM_Taille_de_file]=Couleur; + LBM_Taille_de_file++; + } + } + } + } + + +void Save_LBM(void) +{ + char Nom_du_fichier[256]; + struct Header_LBM + { + word Width; + word Height; + short Xorg; // Inutile + short Yorg; // Inutile + byte BitPlanes; + byte Mask; + byte Compression; + byte Pad1; // Inutile + word Transp_col; // Inutile + byte Xaspect; // Inutile + byte Yaspect; // Inutile + short Xscreen; + short Yscreen; + } Header; + word Pos_X; + word Pos_Y; + byte Octet; + word Vraie_largeur; + struct stat* Informations_Fichier=NULL; + + + Erreur_fichier=0; + Nom_fichier_complet(Nom_du_fichier,0); + + // Ouverture du fichier + LBM_Fichier=open(Nom_du_fichier,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP); + if (LBM_Fichier!=-1) + { + write(LBM_Fichier,"FORM",4); + Ecrire_long(0); // On mettra la taille … jour … la fin + + write(LBM_Fichier,"PBM BMHD",8); + Ecrire_long(20); + + // On corrige la largeur de l'image pour qu'elle soit multiple de 2 + Vraie_largeur=Principal_Largeur_image+(Principal_Largeur_image&1); + + //swab((byte *)&Vraie_largeur,(byte *)&Header.Width,2); + swab((byte *)&Principal_Largeur_image,(byte *)&Header.Width,2); + swab((byte *)&Principal_Hauteur_image,(byte *)&Header.Height,2); + Header.Xorg=0; + Header.Yorg=0; + Header.BitPlanes=8; + Header.Mask=0; + Header.Compression=1; + Header.Pad1=0; + Header.Transp_col=Back_color; + Header.Xaspect=1; + Header.Yaspect=1; + swab((byte *)&Largeur_ecran,(byte *)&Header.Xscreen,2); + swab((byte *)&Hauteur_ecran,(byte *)&Header.Yscreen,2); + + write(LBM_Fichier,&Header,sizeof(struct Header_LBM)); + + write(LBM_Fichier,"CMAP",4); + Ecrire_long(sizeof(T_Palette)); + + Palette_64_to_256(Principal_Palette); + write(LBM_Fichier,Principal_Palette,sizeof(T_Palette)); + Palette_256_to_64(Principal_Palette); + + write(LBM_Fichier,"BODY",4); + Ecrire_long(0); // On mettra la taille … jour … la fin + + Init_ecriture(); + + LBM_Taille_de_file=0; + + for (Pos_Y=0; ((Pos_Yst_size)-824); + + if (!Erreur_fichier) + { + lseek(LBM_Fichier,4,SEEK_SET); + + // Si la taille de la section de l'image (taille fichier-8) est + // impaire, on rajoute un 0 (Padding) … la fin. + if ((Informations_Fichier->st_size) & 1) + { + Ecrire_long((Informations_Fichier->st_size)-7); + lseek(LBM_Fichier,0,SEEK_END); + Octet=0; + if (write(LBM_Fichier,&Octet,1)==-1) + Erreur_fichier=1; + } + else + Ecrire_long((Informations_Fichier->st_size)-8); + + close(LBM_Fichier); + + if (Erreur_fichier) + remove(Nom_du_fichier); + } + else + { + Erreur_fichier=1; + close(LBM_Fichier); + remove(Nom_du_fichier); + } + } + else // Il y a eu une erreur lors du compactage => on efface le fichier + remove(Nom_du_fichier); + } + else + Erreur_fichier=1; +} + + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +//////////////////////////////////// BMP //////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + + +// -- Tester si un fichier est au format BMP -------------------------------- +void Test_BMP(void) +{ + char Nom_du_fichier[256]; + int Fichier; + struct BMP_Header + { + word Signature; // ='BM' = 0x4D42 + long Taille_1; // =Taille du fichier + word Reserv_1; // =0 + word Reserv_2; // =0 + long Decalage; // Nb octets avant les donn‚es bitmap + + long Taille_2; // =40 + long Largeur; + long Hauteur; + word Plans; // =1 + word Nb_bits; // =1,4,8 ou 24 + long Compression; + long Taille_3; + long XPM; + long YPM; + long Nb_Clr; + long Clr_Imprt; + } Header; + + + Erreur_fichier=1; + Nom_fichier_complet(Nom_du_fichier,0); + + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + if (read(Fichier,&Header,sizeof(struct BMP_Header))==sizeof(struct BMP_Header)) + if ( (Header.Signature==0x4D42) && (Header.Taille_2==40) + && Header.Largeur && Header.Hauteur ) + Erreur_fichier=0; + close(Fichier); + } +} + + +// -- Charger un fichier au format BMP -------------------------------------- +void Load_BMP(void) +{ + char Nom_du_fichier[256]; + int Fichier; + struct BMP_Header + { + word Signature; // ='BM' = 0x4D42 + long Taille_1; // =Taille du fichier + word Reserv_1; // =0 + word Reserv_2; // =0 + long Decalage; // Nb octets avant les donn‚es bitmap + + long Taille_2; // =40 + long Largeur; + long Hauteur; + word Plans; // =1 + word Nb_bits; // =1,4,8 ou 24 + long Compression; + long Taille_3; + long XPM; + long YPM; + long Nb_Clr; + long Clr_Imprt; + } Header; + byte * Buffer; + word Indice; + byte Palette_locale[256][4]; // R,V,B,0 + word Nb_Couleurs; + short Pos_X; + short Pos_Y; + word Taille_ligne; + byte A,B,C=0; + long Taille_du_fichier; + struct stat* Informations_Fichier=NULL; + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + stat(Nom_du_fichier,Informations_Fichier); + Taille_du_fichier=Informations_Fichier->st_size; + + if (read(Fichier,&Header,sizeof(struct BMP_Header))==sizeof(struct BMP_Header)) + { + switch (Header.Nb_bits) + { + case 1 : + case 4 : + case 8 : + if (Header.Nb_Clr) + Nb_Couleurs=Header.Nb_Clr; + else + Nb_Couleurs=1<>3; + + Buffer=(byte *)malloc(Taille_ligne); + for (Pos_Y=Principal_Hauteur_image-1; ((Pos_Y>=0) && (!Erreur_fichier)); Pos_Y--) + { + if (read(Fichier,Buffer,Taille_ligne)==Taille_ligne) + for (Pos_X=0; Pos_X>1] & 0xF); + else + Pixel_de_chargement(Pos_X,Pos_Y,Buffer[Pos_X>>1] >> 4 ); + break; + case 1 : + if ( Buffer[Pos_X>>3] & (0x80>>(Pos_X&7)) ) + Pixel_de_chargement(Pos_X,Pos_Y,1); + else + Pixel_de_chargement(Pos_X,Pos_Y,0); + } + else + Erreur_fichier=2; + } + free(Buffer); + break; + + case 1 : // Compression RLE 8 bits + Pos_X=0; + Pos_Y=Principal_Hauteur_image-1; + + Init_lecture(); + A=Lire_octet(Fichier); + B=Lire_octet(Fichier); + while ( (!Erreur_fichier) && ((A)||(B!=1)) ) + { + if (A) // Encoded mode + for (Indice=1; Indice<=A; Indice++) + Pixel_de_chargement(Pos_X++,Pos_Y,B); + else // Absolute mode + switch (B) + { + case 0 : // End of line + Pos_X=0; + Pos_Y--; + break; + case 1 : // End of bitmap + break; + case 2 : // Delta + A=Lire_octet(Fichier); + B=Lire_octet(Fichier); + Pos_X+=A; + Pos_Y-=B; + break; + default: // Nouvelle s‚rie + while (B) + { + A=Lire_octet(Fichier); + C=Lire_octet(Fichier); + Pixel_de_chargement(Pos_X++,Pos_Y,A); + if (--B) + { + Pixel_de_chargement(Pos_X++,Pos_Y,C); + B--; + } + } + } + A=Lire_octet(Fichier); + B=Lire_octet(Fichier); + } + Close_lecture(); + break; + + case 2 : // Compression RLE 4 bits + Pos_X=0; + Pos_Y=Principal_Hauteur_image-1; + + Init_lecture(); + A=Lire_octet(Fichier); + B=Lire_octet(Fichier); + while ( (!Erreur_fichier) && ((A)||(B!=1)) ) + { + if (A) // Encoded mode (A fois les 1/2 pixels de B) + for (Indice=1; Indice<=A; Indice++) + { + if (Indice & 1) + Pixel_de_chargement(Pos_X,Pos_Y,B>>4); + else + Pixel_de_chargement(Pos_X,Pos_Y,B&0xF); + Pos_X++; + } + else // Absolute mode + switch (B) + { + case 0 : //End of line + Pos_X=0; + Pos_Y--; + break; + case 1 : // End of bitmap + break; + case 2 : // Delta + A=Lire_octet(Fichier); + B=Lire_octet(Fichier); + Pos_X+=A; + Pos_Y-=B; + break; + default: // Nouvelle s‚rie (B 1/2 pixels bruts) + for (Indice=1; ((Indice<=B) && (!Erreur_fichier)); Indice++,Pos_X++) + { + if (Indice&1) + { + C=Lire_octet(Fichier); + Pixel_de_chargement(Pos_X,Pos_Y,C>>4); + } + else + Pixel_de_chargement(Pos_X,Pos_Y,C&0xF); + } + // On lit l'octet rendant le nombre d'octets pair, si + // n‚cessaire. Encore un truc de cr‚tin "made in MS". + if ( ((B&3)==1) || ((B&3)==2) ) + Lire_octet(Fichier); + } + A=Lire_octet(Fichier); + B=Lire_octet(Fichier); + } + Close_lecture(); + } + close(Fichier); + } + else + { + close(Fichier); + Erreur_fichier=1; + } + } + } + else + { + // Image 24 bits!!! + Erreur_fichier=0; + + Principal_Largeur_image=Header.Largeur; + Principal_Hauteur_image=Header.Hauteur; + Initialiser_preview(Header.Largeur,Header.Hauteur,Taille_du_fichier,FORMAT_BMP | FORMAT_24B); + + if (Erreur_fichier==0) + { + Taille_ligne=Principal_Largeur_image*3; + Pos_X=(Taille_ligne % 4); // Pos_X sert de variable temporaire + if (Pos_X>0) + Taille_ligne+=(4-Pos_X); + + Buffer=(byte *)malloc(Taille_ligne); + for (Pos_Y=Principal_Hauteur_image-1; ((Pos_Y>=0) && (!Erreur_fichier)); Pos_Y--) + { + if (read(Fichier,Buffer,Taille_ligne)==Taille_ligne) + for (Pos_X=0,Indice=0; Pos_X> 3)+1) << 3; + else + Taille_ligne=Principal_Largeur_image; + + Header.Signature =0x4D42; + Header.Taille_1 =(Taille_ligne*Principal_Hauteur_image)+1078; + Header.Reserv_1 =0; + Header.Reserv_2 =0; + Header.Decalage =1078; + Header.Taille_2 =40; + Header.Largeur =Taille_ligne; + Header.Hauteur =Principal_Hauteur_image; + Header.Plans =1; + Header.Nb_bits =8; + Header.Compression=0; + Header.Taille_3 =0; + Header.XPM =0; + Header.YPM =0; + Header.Nb_Clr =0; + Header.Clr_Imprt =0; + + if (write(Fichier,&Header,sizeof(struct BMP_Header))!=-1) + { + // Chez Bill, ils ont dit: "On va mettre les couleur dans l'ordre + // inverse, et pour faire chier, on va les mettre sur une ‚chelle de + // 0 … 255 parce que le standard VGA c'est de 0 … 63 (logique!). Et + // puis comme c'est pas assez d‚bile, on va aussi y rajouter un octet + // toujours … 0 pour forcer les gens … s'acheter des gros disques + // durs... Comme ‡a, ‡a fera passer la pillule lorsqu'on sortira + // Windows 95." ... + Palette_64_to_256(Principal_Palette); + for (Indice=0; Indice<256; Indice++) + { + Palette_locale[Indice][0]=Principal_Palette[Indice].B; + Palette_locale[Indice][1]=Principal_Palette[Indice].V; + Palette_locale[Indice][2]=Principal_Palette[Indice].R; + Palette_locale[Indice][3]=0; + } + Palette_256_to_64(Principal_Palette); + + if (write(Fichier,Palette_locale,1024)!=-1) + { + Init_ecriture(); + + // ... Et Bill, il a dit: "OK les gars! Mais seulement si vous rangez + // les pixels dans l'ordre inverse, mais que sur les Y quand-mˆme + // parce que faut pas pousser." + for (Pos_Y=Principal_Hauteur_image-1; ((Pos_Y>=0) && (!Erreur_fichier)); Pos_Y--) + for (Pos_X=0; Pos_X>=Nb_bits_en_cours; + Nb_bits_traites +=Nb_bits_en_cours; + Nb_bits_a_traiter-=Nb_bits_en_cours; + GIF_Rest_bits -=Nb_bits_en_cours; + } + + return GIF_Code_actuel; + } + + // -- Affiche un nouveau pixel -- + + void GIF_Nouveau_pixel(byte Couleur) + { + Pixel_de_chargement(GIF_Pos_X,GIF_Pos_Y,Couleur); + + GIF_Pos_X++; + + if (GIF_Pos_X>=Principal_Largeur_image) + { + GIF_Pos_X=0; + + if (!GIF_Entrelacee) + GIF_Pos_Y++; + else + { + switch (GIF_Passe) + { + case 0 : GIF_Pos_Y+=8; + break; + case 1 : GIF_Pos_Y+=8; + break; + case 2 : GIF_Pos_Y+=4; + break; + default: GIF_Pos_Y+=2; + } + + if (GIF_Pos_Y>=Principal_Hauteur_image) + { + switch(++GIF_Passe) + { + case 1 : GIF_Pos_Y=4; + break; + case 2 : GIF_Pos_Y=2; + break; + case 3 : GIF_Pos_Y=1; + break; + case 4 : GIF_Image_entrelacee_terminee=1; + } + } + } + } + } + + +void Load_GIF(void) +{ + char Nom_du_fichier[256]; + char Signature[6]; + + word * Alphabet_Pile; // Pile de d‚codage d'une chaŒne + word * Alphabet_Prefixe; // Table des pr‚fixes des codes + word * Alphabet_Suffixe; // Table des suffixes des codes + word Alphabet_Free; // Position libre dans l'alphabet + word Alphabet_Max; // Nombre d'entr‚es possibles dans l'alphabet + word Alphabet_Pos_pile; // Position dans la pile de d‚codage d'un chaŒne + + struct Type_LSDB + { + word Largeur; // Largeur de l'‚cran virtuel + word Hauteur; // Hauteur de l'‚cran virtuel + byte Resol; // Informations sur la r‚solution (et autres) + byte Backcol; // Couleur de fond + byte Aspect; // Informations sur l'aspect ratio (et autres) + } LSDB; // Logical Screen Descriptor Block + + struct Type_IDB + { + word Pos_X; // Abscisse o— devrait ˆtre affich‚e l'image + word Pos_Y; // Ordonn‚e o— devrait ˆtre affich‚e l'image + word Largeur_image; // Largeur de l'image + word Hauteur_image; // Hauteur de l'image + byte Indicateur; // Informations diverses sur l'image + byte Nb_bits_pixel; // Nb de bits par pixel + } IDB; // Image Descriptor Block + + word Nb_couleurs; // Nombre de couleurs dans l'image + word Indice_de_couleur; // Indice de traitement d'une couleur + word Taille_de_lecture; // Nombre de donn‚es … lire (divers) + word Indice_de_lecture; // Indice de lecture des donn‚es (divers) + byte Block_indicateur; // Code indicateur du type de bloc en cours + word Nb_bits_initial; // Nb de bits au d‚but du traitement LZW + word Cas_special=0; // M‚moire pour le cas sp‚cial + word Code_ancien=0; // Code pr‚c‚dent + word Read_byte; // Sauvegarde du code en cours de lecture + word Valeur_Clr; // Valeur <=> Clear tables + word Valeur_Eof; // Valeur <=> Fin d'image + long Taille_du_fichier; + struct stat* Informations_Fichier=NULL; + + + /////////////////////////////////////////////////// FIN DES DECLARATIONS // + + + GIF_Pos_X=0; + GIF_Pos_Y=0; + GIF_Last_byte=0; + GIF_Rest_bits=0; + GIF_Rest_byte=0; + + Nom_fichier_complet(Nom_du_fichier,0); + + if ((GIF_Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + stat(Nom_du_fichier,Informations_Fichier); + Taille_du_fichier=Informations_Fichier->st_size; + + if ( (read(GIF_Fichier,Signature,6)==6) && + ( (memcmp(Signature,"GIF87a",6)==0) || + (memcmp(Signature,"GIF89a",6)==0) ) ) + { + // Allocation de m‚moire pour les tables & piles de traitement: + Alphabet_Pile =(word *)malloc(4096*sizeof(word)); + Alphabet_Prefixe=(word *)malloc(4096*sizeof(word)); + Alphabet_Suffixe=(word *)malloc(4096*sizeof(word)); + + if (read(GIF_Fichier,&LSDB,sizeof(struct Type_LSDB))==sizeof(struct Type_LSDB)) + { + // Lecture du Logical Screen Descriptor Block r‚ussie: + + Ecran_original_X=LSDB.Largeur; + Ecran_original_Y=LSDB.Hauteur; + + // Palette globale dispo = (LSDB.Resol and $80) + // Profondeur de couleur =((LSDB.Resol and $70) shr 4)+1 + // Nombre de bits/pixel = (LSDB.Resol and $07)+1 + // Ordre de Classement = (LSDB.Aspect and $80) + + Alphabet_Pos_pile=0; + GIF_Last_byte =0; + GIF_Rest_bits =0; + GIF_Rest_byte =0; + + Nb_couleurs=(1 << ((LSDB.Resol & 0x07)+1)); + Nb_bits_initial=(LSDB.Resol & 0x07)+2; + + if (LSDB.Resol & 0x80) + { + // Palette globale dispo: + + // On commence par passer la palette en 256 comme ‡a, si la + // nouvelle palette a moins de 256 coul, la pr‚c‚dente ne souffrira + // pas d'un assombrissement pr‚judiciable. + if (Config.Clear_palette) + memset(Principal_Palette,0,sizeof(T_Palette)); + else + Palette_64_to_256(Principal_Palette); + + // On peut maintenant charger la nouvelle palette: + if (!(LSDB.Aspect & 0x80)) + // Palette dans l'ordre: + read(GIF_Fichier,Principal_Palette,Nb_couleurs*3); + else + { + // Palette tri‚e par composantes: + for (Indice_de_couleur=0;Indice_de_couleurValeur_Clr) + { + Alphabet_Pile[Alphabet_Pos_pile++]=Alphabet_Suffixe[GIF_Code_actuel]; + GIF_Code_actuel=Alphabet_Prefixe[GIF_Code_actuel]; + } + + Cas_special=Alphabet_Pile[Alphabet_Pos_pile++]=GIF_Code_actuel; + + do + GIF_Nouveau_pixel(Alphabet_Pile[--Alphabet_Pos_pile]); + while (Alphabet_Pos_pile!=0); + + Alphabet_Prefixe[Alphabet_Free ]=Code_ancien; + Alphabet_Suffixe[Alphabet_Free++]=GIF_Code_actuel; + Code_ancien=Read_byte; + + if (Alphabet_Free>Alphabet_Max) + { + if (GIF_Nb_bits<12) + Alphabet_Max =((1 << (++GIF_Nb_bits))-1); + } + } + else // Code Clear rencontr‚ + { + GIF_Nb_bits =Nb_bits_initial; + Alphabet_Max =((1 << GIF_Nb_bits)-1); + Alphabet_Free =Nb_couleurs+2; + Cas_special =GIF_Get_next_code(); + Code_ancien =GIF_Code_actuel; + GIF_Nouveau_pixel(GIF_Code_actuel); + } + } + else + Erreur_fichier=2; + } // Code End-Of-Information ou erreur de fichier rencontr‚ + + Close_lecture(); + + if (Erreur_fichier>=0) + if ( /* (GIF_Pos_X!=0) || */ + ( ( (!GIF_Entrelacee) && (GIF_Pos_Y!=Principal_Hauteur_image) ) || + ( (GIF_Entrelacee) && (!GIF_Image_entrelacee_terminee) ) + ) ) + Erreur_fichier=2; + } // Le fichier contenait un IDB + else + Erreur_fichier=2; + + } // Le fichier contenait une image + else + Erreur_fichier=2; + + } // Le fichier contenait un LSDB + else + Erreur_fichier=1; + + // Lib‚ration de la m‚moire utilis‚e par les tables & piles de traitement: + free(Alphabet_Suffixe); + free(Alphabet_Prefixe); + free(Alphabet_Pile); + } // Le fichier contenait au moins la signature GIF87a ou GIF89a + else + Erreur_fichier=1; + + close(GIF_Fichier); + + } // Le fichier ‚tait ouvrable + else + Erreur_fichier=1; +} + + +// -- Sauver un fichier au format GIF --------------------------------------- + + int GIF_Arret; // "On peut arrˆter la sauvegarde du fichier" + byte GIF_Buffer[256]; // Buffer d'‚criture de bloc de donn‚es compil‚es + + // -- Vider le buffer GIF dans le buffer KM -- + + void GIF_Vider_le_buffer(void) + { + word Indice; + + if (GIF_Rest_byte) + { + GIF_Buffer[0]=GIF_Rest_byte; + + for (Indice=0;Indice<=GIF_Rest_byte;Indice++) + Ecrire_octet(GIF_Fichier,GIF_Buffer[Indice]); + + GIF_Rest_byte=0; + } + } + + // -- Ecrit un code … GIF_Nb_bits -- + + void GIF_Set_code(word Code) + { + word Nb_bits_a_traiter=GIF_Nb_bits; + word Nb_bits_traites =0; + word Nb_bits_en_cours; + + while (Nb_bits_a_traiter) + { + Nb_bits_en_cours=(Nb_bits_a_traiter<=(8-GIF_Rest_bits))?Nb_bits_a_traiter:(8-GIF_Rest_bits); + + GIF_Last_byte|=(Code & ((1<>=Nb_bits_en_cours; + GIF_Rest_bits +=Nb_bits_en_cours; + Nb_bits_traites +=Nb_bits_en_cours; + Nb_bits_a_traiter-=Nb_bits_en_cours; + + if (GIF_Rest_bits==8) // Il ne reste plus de bits … coder sur l'octet courant + { + // Ecrire l'octet … balancer: + GIF_Buffer[++GIF_Rest_byte]=GIF_Last_byte; + + // Si on a atteint la fin du bloc de Raster Data + if (GIF_Rest_byte==255) + // On doit vider le buffer qui est maintenant plein + GIF_Vider_le_buffer(); + + GIF_Last_byte=0; + GIF_Rest_bits=0; + } + } + } + + + // -- Lire le pixel suivant -- + + byte GIF_Pixel_suivant(void) + { + byte Temp; + + Temp=Lit_pixel_de_sauvegarde(GIF_Pos_X,GIF_Pos_Y); + + if (++GIF_Pos_X>=Principal_Largeur_image) + { + GIF_Pos_X=0; + if (++GIF_Pos_Y>=Principal_Hauteur_image) + GIF_Arret=1; + } + + return Temp; + } + + + +void Save_GIF(void) +{ + char Nom_du_fichier[256]; + + word * Alphabet_Prefixe; // Table des pr‚fixes des codes + word * Alphabet_Suffixe; // Table des suffixes des codes + word * Alphabet_Fille; // Table des chaŒnes filles (plus longues) + word * Alphabet_Soeur; // Table des chaŒnes soeurs (mˆme longueur) + word Alphabet_Free; // Position libre dans l'alphabet + word Alphabet_Max; // Nombre d'entr‚es possibles dans l'alphabet + word Depart; // Code pr‚c‚dent (sert au linkage des chaŒnes) + int Descente; // Bool‚en "On vient de descendre" + + struct Type_LSDB + { + word Largeur; // Largeur de l'‚cran virtuel |_ Dimensions de l'image si 1 + word Hauteur; // Hauteur de l'‚cran virtuel | seule image dans le fichier (ce qui est notre cas) + byte Resol; // Informations sur la r‚solution (et autres) + byte Backcol; // Couleur de fond + byte Aspect; // Informations sur l'aspect ratio (et autres) + } LSDB; // Logical Screen Descriptor Block + + struct Type_IDB + { + word Pos_X; // Abscisse o— devrait ˆtre affich‚e l'image + word Pos_Y; // Ordonn‚e o— devrait ˆtre affich‚e l'image + word Largeur_image; // Largeur de l'image + word Hauteur_image; // Hauteur de l'image + byte Indicateur; // Informations diverses sur l'image + byte Nb_bits_pixel; // Nb de bits par pixel + } IDB; // Image Descriptor Block + + byte Block_indicateur; // Code indicateur du type de bloc en cours + word Chaine_en_cours; // Code de la chaŒne en cours de traitement + byte Caractere; // CaractŠre … coder + word Indice; // Indice de recherche de chaŒne + + + /////////////////////////////////////////////////// FIN DES DECLARATIONS // + + + GIF_Pos_X=0; + GIF_Pos_Y=0; + GIF_Last_byte=0; + GIF_Rest_bits=0; + GIF_Rest_byte=0; + + Nom_fichier_complet(Nom_du_fichier,0); + + GIF_Fichier=open(Nom_du_fichier,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP); + if (GIF_Fichier!=-1) + { + // On ‚crit la signature du fichier + if (write(GIF_Fichier,"GIF87a",6)==6) + { + // La signature du fichier a ‚t‚ correctement ‚crite. + + // Allocation de m‚moire pour les tables + Alphabet_Prefixe=(word *)malloc(4096*sizeof(word)); + Alphabet_Suffixe=(word *)malloc(4096*sizeof(word)); + Alphabet_Fille =(word *)malloc(4096*sizeof(word)); + Alphabet_Soeur =(word *)malloc(4096*sizeof(word)); + + // On initialise le LSDB du fichier + if (Config.Taille_ecran_dans_GIF) + { + LSDB.Largeur=Largeur_ecran; + LSDB.Hauteur=Hauteur_ecran; + } + else + { + LSDB.Largeur=Principal_Largeur_image; + LSDB.Hauteur=Principal_Hauteur_image; + } + LSDB.Resol =0x97; // Image en 256 couleurs, avec une palette + LSDB.Backcol=0; + LSDB.Aspect =0; // Palette normale + + // On sauve le LSDB dans le fichier + + if (write(GIF_Fichier,&LSDB,sizeof(struct Type_LSDB))==sizeof(struct Type_LSDB)) + { + // Le LSDB a ‚t‚ correctement ‚crit. + + // On sauve la palette + + Palette_64_to_256(Principal_Palette); + if (write(GIF_Fichier,Principal_Palette,768)==768) + { + // La palette a ‚t‚ correctement ‚crite. + + // Le jour o— on se servira des blocks d'extensions pour placer + // des commentaires, on le fera ici. + + // On va ‚crire un block indicateur d'IDB et l'IDB du fichier + + Block_indicateur=0x2C; + IDB.Pos_X=0; + IDB.Pos_Y=0; + IDB.Largeur_image=Principal_Largeur_image; + IDB.Hauteur_image=Principal_Hauteur_image; + IDB.Indicateur=0x07; // Image non entrelac‚e, pas de palette locale. + IDB.Nb_bits_pixel=8; // Image 256 couleurs; + + if ( (write(GIF_Fichier,&Block_indicateur,1)==1) && + (write(GIF_Fichier,&IDB,sizeof(struct Type_IDB))==sizeof(struct Type_IDB)) ) + { + // Le block indicateur d'IDB et l'IDB ont ‚t‚s correctements + // ‚crits. + + Init_ecriture(); + + Indice=4096; + Erreur_fichier=0; + GIF_Arret=0; + + // R‚intialisation de la table: + Alphabet_Free=258; + GIF_Nb_bits =9; + Alphabet_Max =511; + GIF_Set_code(256); + for (Depart=0;Depart<4096;Depart++) + { + Alphabet_Fille[Depart]=4096; + Alphabet_Soeur[Depart]=4096; + } + + ////////////////////////////////////////////// COMPRESSION LZW // + + Depart=Chaine_en_cours=GIF_Pixel_suivant(); + Descente=1; + + do + { + Caractere=GIF_Pixel_suivant(); + + // On regarde si dans la table on aurait pas une chaŒne + // ‚quivalente … Chaine_en_cours+Caractere + + while ( (Indice0xFFF) + { + // R‚intialisation de la table: + GIF_Set_code(256); + Alphabet_Free=258; + GIF_Nb_bits =9; + Alphabet_Max =511; + for (Depart=0;Depart<4096;Depart++) + { + Alphabet_Fille[Depart]=4096; + Alphabet_Soeur[Depart]=4096; + } + } + else if (Alphabet_Free>Alphabet_Max+1) + { + // On augmente le nb de bits + + GIF_Nb_bits++; + Alphabet_Max=(1< 16c , 1 => 256c + word Bytes_per_plane_line;// Doit toujours ˆtre pair + word Palette_info; // 1 => Couleur , 2 => Gris (ignor‚ … partir de la version 4) + word Screen_X; // |_ Dimensions de + word Screen_Y; // | l'‚cran d'origine + byte Filler[54]; // Ca... J'adore! + } Header; // Je hais ce header! + + + Erreur_fichier=0; + Nom_fichier_complet(Nom_du_fichier,0); + + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + if (read(Fichier,&Header,sizeof(struct PCX_Header))==sizeof(struct PCX_Header)) + { + // Vu que ce header a une signature de merde et peu significative, il + // va falloir que je teste diff‚rentes petites valeurs dont je connais + // l'intervalle. Grrr! + if ( (Header.Manufacturer!=10) + || (Header.Compression>1) + || ( (Header.Depth!=1) && (Header.Depth!=2) && (Header.Depth!=4) && (Header.Depth!=8) ) + || ( (Header.Plane!=1) && (Header.Plane!=2) && (Header.Plane!=4) && (Header.Plane!=8) && (Header.Plane!=3) ) + || (Header.X_max>((Reduction_moins_1-(Pos_X%Reduction))*Depth)) & Masque; + Pixel_de_chargement(Pos_X,Pos_Y,Couleur); + } + } + +void Load_PCX(void) +{ + char Nom_du_fichier[256]; + int Fichier; + struct PCX_Header + { + byte Manufacturer; // |_ Il font chier ces cons! Ils auraient pu + byte Version; // | mettre une vraie signature! + byte Compression; // L'image est-elle compress‚e? + byte Depth; // Nombre de bits pour coder un pixel (inutile puisqu'on se sert de Plane) + word X_min; // |_ Coin haut-gauche | + word Y_min; // | de l'image |_ (Cr‚tin!) + word X_max; // |_ Coin bas-droit | + word Y_max; // | de l'image | + word X_dpi; // |_ Densit‚ de |_ (Presque inutile parce que + word Y_dpi; // | l'image | aucun moniteur n'est pareil!) + byte Palette_16c[48]; // Palette 16 coul (inutile pour 256c) (d‚bile!) + byte Reserved; // Ca me plait ‡a aussi! + byte Plane; // 4 => 16c , 1 => 256c , ... + word Bytes_per_plane_line;// Doit toujours ˆtre pair + word Palette_info; // 1 => Couleur , 2 => Gris (ignor‚ … partir de la version 4) + word Screen_X; // |_ Dimensions de + word Screen_Y; // | l'‚cran d'origine + byte Filler[54]; // Ca... J'adore! + } Header; // Je hais ce header! + short Taille_ligne; + short Vraie_taille_ligne; // Largeur de l'image corrig‚e + short Largeur_lue; + short Pos_X; + short Pos_Y; + byte Octet1; + byte Octet2; + byte Indice; + dword Nb_couleurs; + long Taille_du_fichier; + byte Palette_CGA[9]={ 84,252,252, 252, 84,252, 252,252,252}; + + long Position; + long Taille_image; + byte * Buffer; + struct stat* Informations_Fichier =NULL; + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + stat(Nom_du_fichier,Informations_Fichier); + Taille_du_fichier=Informations_Fichier->st_size; + + if (read(Fichier,&Header,sizeof(struct PCX_Header))==sizeof(struct PCX_Header)) + { + Principal_Largeur_image=Header.X_max-Header.X_min+1; + Principal_Hauteur_image=Header.Y_max-Header.Y_min+1; + + Ecran_original_X=Header.Screen_X; + Ecran_original_Y=Header.Screen_Y; + + if (Header.Plane!=3) + { + Initialiser_preview(Principal_Largeur_image,Principal_Hauteur_image,Taille_du_fichier,FORMAT_PCX); + if (Erreur_fichier==0) + { + // On pr‚pare la palette … accueillir les valeurs du fichier PCX + if (Config.Clear_palette) + memset(Principal_Palette,0,sizeof(T_Palette)); + else + Palette_64_to_256(Principal_Palette); + Nb_couleurs=(dword)(1<4) + memcpy(Principal_Palette,Header.Palette_16c,48); + else + { + Principal_Palette[1].R=0; + Principal_Palette[1].V=0; + Principal_Palette[1].B=0; + Octet1=Header.Palette_16c[3]>>5; + if (Nb_couleurs==4) + { // Pal. CGA "alakon" (du Turc Allahkoum qui signifie "… la con" :)) + memcpy(Principal_Palette+1,Palette_CGA,9); + if (!(Octet1&2)) + { + Principal_Palette[1].B=84; + Principal_Palette[2].B=84; + Principal_Palette[3].B=84; + } + } // Palette monochrome (on va dire que c'est du N&B) + else + { + Principal_Palette[1].R=252; + Principal_Palette[1].V=252; + Principal_Palette[1].B=252; + } + } + + // On se positionne … la fin du fichier - 769 octets pour voir s'il y + // a une palette. + if ( (Header.Depth==8) && (Header.Version>=5) && (Taille_du_fichier>sizeof(T_Palette)) ) + { + lseek(Fichier,Taille_du_fichier-(sizeof(T_Palette)+1),SEEK_SET); + // On regarde s'il y a une palette aprŠs les donn‚es de l'image + if (read(Fichier,&Octet1,1)==1) + if (Octet1==12) // Lire la palette si c'est une image en 256 couleurs + { + // On lit la palette 256c que ces cr‚tins ont foutue … la fin du fichier + if (read(Fichier,Principal_Palette,sizeof(T_Palette))!=sizeof(T_Palette)) + Erreur_fichier=2; + } + } + Palette_256_to_64(Principal_Palette); + Set_palette(Principal_Palette); + Remapper_fileselect(); + + // Maintenant qu'on a lu la palette que ces cr‚tins sont all‚s foutre + // … la fin, on retourne juste aprŠs le header pour lire l'image. + lseek(Fichier,sizeof(struct PCX_Header),SEEK_SET); + + if (!Erreur_fichier) + { + Taille_ligne=Header.Bytes_per_plane_line*Header.Plane; + Vraie_taille_ligne=(short)Header.Bytes_per_plane_line<<3; + // On se sert de donn‚es LBM car le dessin de ligne en moins de 256 + // couleurs se fait comme avec la structure ILBM. + Image_HAM=0; + HBPm1=Header.Plane-1; + LBM_Buffer=(byte *)malloc(Taille_ligne); + + // Chargement de l'image + if (Header.Compression) // Image compress‚e + { + Init_lecture(); + + Taille_image=(long)Header.Bytes_per_plane_line*Principal_Hauteur_image; + + if (Header.Depth==8) // 256 couleurs (1 plan) + { + for (Position=0; ((Position=Taille_ligne) + { + for (Pos_X=0; Pos_X=Taille_ligne) + { + for (Pos_X=0; Pos_X1) || (Last_pixel>=0xC0) ) + Ecrire_octet(Fichier,Compteur|0xC0); + Ecrire_octet(Fichier,Last_pixel); + + } + } + + // Ecriture de l'octet (12) indiquant que la palette arrive + if (!Erreur_fichier) + Ecrire_octet(Fichier,12); + + Close_ecriture(Fichier); + + // Ecriture de la palette + if (!Erreur_fichier) + { + if (write(Fichier,Principal_Palette,sizeof(T_Palette))==-1) + Erreur_fichier=1; + } + } + else + Erreur_fichier=1; + + close(Fichier); + + if (Erreur_fichier) + remove(Nom_du_fichier); + + // On remet la palette … son ‚tat normal + Palette_256_to_64(Principal_Palette); + } + else + Erreur_fichier=1; +} + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +//////////////////////////////////// CEL //////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + + +// -- Tester si un fichier est au format CEL -------------------------------- + +void Test_CEL(void) +{ + char Nom_du_fichier[256]; + int Taille; + int Fichier; + struct CEL_Header1 + { + word Width; // Largeur de l'image + word Height; // Hauteur de l'image + } Header1; + struct CEL_Header2 + { + byte Signa[4]; // Signature du format + byte Kind; // Type de fichier ($10=PALette $20=BitMaP) + byte Nbbits; // Nombre de bits + word Filler1; // ??? + word Largeur; // Largeur de l'image + word Hauteur; // Hauteur de l'image + word Decalage_X; // Decalage en X de l'image + word Decalage_Y; // Decalage en Y de l'image + byte Filler2[16]; // ??? + } Header2; + struct stat* Informations_Fichier =NULL; + + Erreur_fichier=0; + Nom_fichier_complet(Nom_du_fichier,0); + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + if (read(Fichier,&Header1,sizeof(struct CEL_Header1))==sizeof(struct CEL_Header1)) + { + // Vu que ce header n'a pas de signature, il va falloir tester la + // coh‚rence de la dimension de l'image avec celle du fichier. + stat(Nom_du_fichier,Informations_Fichier); + Taille=(Informations_Fichier->st_size)-sizeof(struct CEL_Header1); + if ( (!Taille) || ( (((Header1.Width+1)>>1)*Header1.Height)!=Taille ) ) + { + // Tentative de reconnaissance de la signature des nouveaux fichiers + + lseek(Fichier,0,SEEK_SET); + if (read(Fichier,&Header2,sizeof(struct CEL_Header2))==sizeof(struct CEL_Header2)) + { + if (memcmp(Header2.Signa,"KiSS",4)==0) + { + if (Header2.Kind!=0x20) + Erreur_fichier=1; + } + else + Erreur_fichier=1; + } + else + Erreur_fichier=1; + } + } + else + Erreur_fichier=1; + + close(Fichier); + } + else + Erreur_fichier=1; +} + + +// -- Lire un fichier au format CEL ----------------------------------------- + +void Load_CEL(void) +{ + char Nom_du_fichier[256]; + int Fichier; + struct CEL_Header1 + { + word Width; // Largeur de l'image + word Height; // Hauteur de l'image + } Header1; + struct CEL_Header2 + { + byte Signa[4]; // Signature du format + byte Kind; // Type de fichier ($10=PALette $20=BitMaP) + byte Nbbits; // Nombre de bits + word Filler1; // ??? + word Largeur; // Largeur de l'image + word Hauteur; // Hauteur de l'image + word Decalage_X; // Decalage en X de l'image + word Decalage_Y; // Decalage en Y de l'image + byte Filler2[16]; // ??? + } Header2; + short Pos_X; + short Pos_Y; + byte Dernier_octet=0; + long Taille_du_fichier; + struct stat* Informations_Fichier=NULL; + + + Erreur_fichier=0; + Nom_fichier_complet(Nom_du_fichier,0); + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + if (read(Fichier,&Header1,sizeof(struct CEL_Header1))==sizeof(struct CEL_Header1)) + { + stat(Nom_du_fichier,Informations_Fichier); + Taille_du_fichier=Informations_Fichier->st_size; + if ( (Taille_du_fichier>sizeof(struct CEL_Header1)) + && ( (((Header1.Width+1)>>1)*Header1.Height)==(Taille_du_fichier-sizeof(struct CEL_Header1)) ) ) + { + // Chargement d'un fichier CEL sans signature (vieux fichiers) + Principal_Largeur_image=Header1.Width; + Principal_Hauteur_image=Header1.Height; + Ecran_original_X=Principal_Largeur_image; + Ecran_original_Y=Principal_Hauteur_image; + Initialiser_preview(Principal_Largeur_image,Principal_Hauteur_image,Taille_du_fichier,FORMAT_CEL); + if (Erreur_fichier==0) + { + // Chargement de l'image + Init_lecture(); + for (Pos_Y=0;((Pos_Y> 4)); + } + else + Pixel_de_chargement(Pos_X,Pos_Y,(Dernier_octet & 15)); + Close_lecture(); + } + } + else + { + // On r‚essaye avec le nouveau format + + lseek(Fichier,0,SEEK_SET); + if (read(Fichier,&Header2,sizeof(struct CEL_Header2))==sizeof(struct CEL_Header2)) + { + // Chargement d'un fichier CEL avec signature (nouveaux fichiers) + + Principal_Largeur_image=Header2.Largeur+Header2.Decalage_X; + Principal_Hauteur_image=Header2.Hauteur+Header2.Decalage_Y; + Ecran_original_X=Principal_Largeur_image; + Ecran_original_Y=Principal_Hauteur_image; + Initialiser_preview(Principal_Largeur_image,Principal_Hauteur_image,Taille_du_fichier,FORMAT_CEL); + if (Erreur_fichier==0) + { + // Chargement de l'image + Init_lecture(); + + if (!Erreur_fichier) + { + // Effacement du d‚calage + for (Pos_Y=0;Pos_Y> 4)); + } + else + Pixel_de_chargement(Pos_X+Header2.Decalage_X,Pos_Y+Header2.Decalage_Y,(Dernier_octet & 15)); + break; + + case 8: + for (Pos_Y=0;((Pos_Y16 sont utilis‚es dans l'image + for (Pos_X=16;((Pos_X<256) && (!Utilisation[Pos_X]));Pos_X++); + + if (Pos_X==256) + { + // Cas d'une image 16 couleurs (‚criture … l'ancien format) + + Header1.Width =Principal_Largeur_image; + Header1.Height=Principal_Hauteur_image; + + if (write(Fichier,&Header1,sizeof(struct CEL_Header1))!=-1) + { + // Sauvegarde de l'image + Init_ecriture(); + for (Pos_Y=0;((Pos_Y>4)!=0) + Erreur_fichier=1; + } + else + { + if (read(Fichier,&Header2,sizeof(struct CEL_Header2))==sizeof(struct CEL_Header2)) + { + if (memcmp(Header2.Signa,"KiSS",4)==0) + { + if (Header2.Kind!=0x10) + Erreur_fichier=1; + } + else + Erreur_fichier=1; + } + else + Erreur_fichier=1; + } + close(Fichier); + } + else + Erreur_fichier=1; +} + + +// -- Lire un fichier au format KCF ----------------------------------------- + +void Load_KCF(void) +{ + char Nom_du_fichier[256]; + int Fichier; + struct KCF_Header + { + struct + { + struct + { + byte Octet1; + byte Octet2; + } Couleur[16]; + } Palette[10]; + } Buffer; + struct CEL_Header2 + { + byte Signa[4]; // Signature du format + byte Kind; // Type de fichier ($10=PALette $20=BitMaP) + byte Nbbits; // Nombre de bits + word Filler1; // ??? + word Largeur; // Largeur de l'image ou nb de couleurs d‚finies + word Hauteur; // Hauteur de l'image ou nb de palettes d‚finies + word Decalage_X; // Decalage en X de l'image + word Decalage_Y; // Decalage en Y de l'image + byte Filler2[16]; // ??? + } Header2; + byte Octet[3]; + int Indice_palette; + int Indice_couleur; + int Indice; + long Taille_du_fichier; + + + Erreur_fichier=0; + Nom_fichier_complet(Nom_du_fichier,0); + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + Taille_du_fichier=filelength(Fichier); + if (Taille_du_fichier==sizeof(struct KCF_Header)) + { + // Fichier KCF … l'ancien format + + if (read(Fichier,&Buffer,sizeof(struct KCF_Header))==sizeof(struct KCF_Header)) + { + // Initialiser_preview(???); // Pas possible... pas d'image... + + if (Config.Clear_palette) + memset(Principal_Palette,0,sizeof(T_Palette)); + + // Chargement de la palette + for (Indice_palette=0;Indice_palette<10;Indice_palette++) + for (Indice_couleur=0;Indice_couleur<16;Indice_couleur++) + { + Indice=16+(Indice_palette*16)+Indice_couleur; + Principal_Palette[Indice].R=((Buffer.Palette[Indice_palette].Couleur[Indice_couleur].Octet1 >> 4) << 2); + Principal_Palette[Indice].B=((Buffer.Palette[Indice_palette].Couleur[Indice_couleur].Octet1 & 15) << 2); + Principal_Palette[Indice].V=((Buffer.Palette[Indice_palette].Couleur[Indice_couleur].Octet2 & 15) << 2); + } + + for (Indice=0;Indice<16;Indice++) + { + Principal_Palette[Indice].R=Principal_Palette[Indice+16].R; + Principal_Palette[Indice].V=Principal_Palette[Indice+16].V; + Principal_Palette[Indice].B=Principal_Palette[Indice+16].B; + } + + Set_palette(Principal_Palette); + Remapper_fileselect(); + } + else + Erreur_fichier=1; + } + else + { + // Fichier KCF au nouveau format + + if (read(Fichier,&Header2,sizeof(struct CEL_Header2))==sizeof(struct CEL_Header2)) + { + // Initialiser_preview(???); // Pas possible... pas d'image... + + Indice=(Header2.Nbbits==12)?16:0; + for (Indice_palette=0;Indice_palette> 4) << 2; + Principal_Palette[Indice].B=(Octet[0] & 15) << 2; + Principal_Palette[Indice].V=(Octet[1] & 15) << 2; + break; + + case 24: // RRRR RRRR | VVVV VVVV | BBBB BBBB + read(Fichier,Octet,3); + Principal_Palette[Indice].R=Octet[0]>>2; + Principal_Palette[Indice].V=Octet[1]>>2; + Principal_Palette[Indice].B=Octet[2]>>2; + } + + Indice++; + } + } + + if (Header2.Nbbits==12) + for (Indice=0;Indice<16;Indice++) + { + Principal_Palette[Indice].R=Principal_Palette[Indice+16].R; + Principal_Palette[Indice].V=Principal_Palette[Indice+16].V; + Principal_Palette[Indice].B=Principal_Palette[Indice+16].B; + } + + Set_palette(Principal_Palette); + Remapper_fileselect(); + } + else + Erreur_fichier=1; + } + close(Fichier); + } + else + Erreur_fichier=1; + + if (!Erreur_fichier) Dessiner_preview_palette(); +} + + +// -- Ecrire un fichier au format KCF --------------------------------------- + +void Save_KCF(void) +{ + char Nom_du_fichier[256]; + int Fichier; + struct KCF_Header + { + struct + { + struct + { + byte Octet1; + byte Octet2; + } Couleur[16]; + } Palette[10]; + } Buffer; + struct CEL_Header2 + { + byte Signa[4]; // Signature du format + byte Kind; // Type de fichier ($10=PALette $20=BitMaP) + byte Nbbits; // Nombre de bits + word Filler1; // ??? + word Largeur; // Largeur de l'image ou nb de couleurs d‚finies + word Hauteur; // Hauteur de l'image ou nb de palettes d‚finies + word Decalage_X; // Decalage en X de l'image + word Decalage_Y; // Decalage en Y de l'image + byte Filler2[16]; // ??? + } Header2; + byte Octet[3]; + int Indice_palette; + int Indice_couleur; + int Indice; + dword Utilisation[256]; // Table d'utilisation de couleurs + + // On commence par compter l'utilisation de chaque couleurs + Palette_Compter_nb_couleurs_utilisees(Utilisation); + + Erreur_fichier=0; + Nom_fichier_complet(Nom_du_fichier,0); + if ((Fichier=open(Nom_du_fichier,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP))!=-1) + { + // Sauvegarde de la palette + + // On regarde si des couleurs >16 sont utilis‚es dans l'image + for (Indice=16;((Indice<256) && (!Utilisation[Indice]));Indice++); + + if (Indice==256) + { + // Cas d'une image 16 couleurs (‚criture … l'ancien format) + + for (Indice_palette=0;Indice_palette<10;Indice_palette++) + for (Indice_couleur=0;Indice_couleur<16;Indice_couleur++) + { + Indice=16+(Indice_palette*16)+Indice_couleur; + Buffer.Palette[Indice_palette].Couleur[Indice_couleur].Octet1=((Principal_Palette[Indice].R>>2)<<4) | (Principal_Palette[Indice].B>>2); + Buffer.Palette[Indice_palette].Couleur[Indice_couleur].Octet2=Principal_Palette[Indice].V>>2; + } + + if (write(Fichier,&Buffer,sizeof(struct KCF_Header))!=sizeof(struct KCF_Header)) + Erreur_fichier=1; + } + else + { + // Cas d'une image 256 couleurs (‚criture au nouveau format) + + memcpy(Header2.Signa,"KiSS",4); // Initialisation de la signature + Header2.Kind=0x10; // Initialisation du type (PALette) + Header2.Nbbits=24; // Initialisation du nombre de bits + Header2.Filler1=0; // Initialisation du filler 1 (???) + Header2.Largeur=256; // Initialisation du nombre de couleurs + Header2.Hauteur=1; // Initialisation du nombre de palettes + Header2.Decalage_X=0; // Initialisation du d‚calage X + Header2.Decalage_Y=0; // Initialisation du d‚calage Y + for (Indice=0;Indice<16;Indice++) // Initialisation du filler 2 (???) + Header2.Filler2[Indice]=0; + + if (write(Fichier,&Header2,sizeof(struct CEL_Header2))!=sizeof(struct CEL_Header2)) + Erreur_fichier=1; + + for (Indice=0;(Indice<256) && (!Erreur_fichier);Indice++) + { + Octet[0]=Principal_Palette[Indice].R<<2; + Octet[1]=Principal_Palette[Indice].V<<2; + Octet[2]=Principal_Palette[Indice].B<<2; + if (write(Fichier,Octet,3)!=3) + Erreur_fichier=1; + } + } + + close(Fichier); + + if (Erreur_fichier) + remove(Nom_du_fichier); + } + else + Erreur_fichier=1; +} + + + + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +//////////////////////////////////// SCx //////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + + +// -- Tester si un fichier est au format SCx -------------------------------- +void Test_SCx(void) +{ + int Handle; // Handle du fichier + char Nom_du_fichier[256]; // Nom complet du fichier + byte Signature[3]; + struct Header + { + byte Filler1[4]; + word Largeur; + word Hauteur; + byte Filler2; + byte Plans; + } SCx_Header; + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=1; + + // Ouverture du fichier + Handle=open(Nom_du_fichier,O_RDONLY); + if (Handle!=-1) + { + // Lecture et v‚rification de la signature + if ((read(Handle,&SCx_Header,sizeof(struct Header)))==sizeof(struct Header)) + { + if ( (!memcmp(SCx_Header.Filler1,"RIX",3)) + && SCx_Header.Largeur && SCx_Header.Hauteur) + Erreur_fichier=0; + } + // Fermeture du fichier + close(Handle); + } +} + + +// -- Lire un fichier au format SCx ----------------------------------------- +void Load_SCx(void) +{ + char Nom_du_fichier[256]; // Nom complet du fichier + int Fichier; + word Pos_X,Pos_Y; + long Taille,Vraie_taille; + long Taille_du_fichier; + struct Header + { + byte Filler1[4]; + word Largeur; + word Hauteur; + byte Filler2; + byte Plans; + } SCx_Header; + T_Palette SCx_Palette; + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + Taille_du_fichier=filelength(Fichier); + + if ((read(Fichier,&SCx_Header,sizeof(struct Header)))==sizeof(struct Header)) + { + Initialiser_preview(SCx_Header.Largeur,SCx_Header.Hauteur,Taille_du_fichier,FORMAT_SCx); + if (Erreur_fichier==0) + { + if (!SCx_Header.Plans) + Taille=sizeof(T_Palette); + else + Taille=sizeof(struct Composantes)*(1<>3)*SCx_Header.Plans; + Vraie_taille=(Taille/SCx_Header.Plans)<<3; + LBM_Buffer=(byte *)malloc(Taille); + HBPm1=SCx_Header.Plans-1; + Image_HAM=0; + + for (Pos_Y=0;(Pos_Y>=1; + } +} + +//// CODAGE d'une partie d'IMAGE //// + +void PI1_16p_to_8b(byte * Src,byte * Dst) +{ + int i; // Indice du pixel … calculer + word masque; // Masque de codage + word w0,w1,w2,w3; // Les 4 words bien ordonn‚s de la destination + + masque=0x8000; + w0=w1=w2=w3=0; + for (i=0;i<16;i++) + { + // Pour coder le pixel nøi, il faut modifier les 4 words sur leur bit + // correspondant … celui du masque + + w0|=(Src[i] & 0x01)?masque:0x00; + w1|=(Src[i] & 0x02)?masque:0x00; + w2|=(Src[i] & 0x04)?masque:0x00; + w3|=(Src[i] & 0x08)?masque:0x00; + masque>>=1; + } + Dst[0]=w0 >> 8; + Dst[1]=w0 & 0x00FF; + Dst[2]=w1 >> 8; + Dst[3]=w1 & 0x00FF; + Dst[4]=w2 >> 8; + Dst[5]=w2 & 0x00FF; + Dst[6]=w3 >> 8; + Dst[7]=w3 & 0x00FF; +} + +//// DECODAGE de la PALETTE //// + +void PI1_Decoder_palette(byte * Src,byte * Pal) +{ + int i; // Num‚ro de la couleur trait‚e + int ip; // Indice dans la palette + word w; // Word contenant le code + + // Sch‚ma d'un word = + // + // Low High + // VVVV RRRR | 0000 BBBB + // 0321 0321 | 0321 + + ip=0; + for (i=0;i<16;i++) + { + w=((word)Src[(i*2)+1]<<8) | Src[(i*2)+0]; + + // Traitement des couleurs rouge, verte et bleue: + Pal[ip++]=(((w & 0x0007) << 1) | ((w & 0x0008) >> 3)) << 2; + Pal[ip++]=(((w & 0x7000) >> 11) | ((w & 0x8000) >> 15)) << 2; + Pal[ip++]=(((w & 0x0700) >> 7) | ((w & 0x0800) >> 11)) << 2; + } +} + +//// CODAGE de la PALETTE //// + +void PI1_Coder_palette(byte * Pal,byte * Dst) +{ + int i; // Num‚ro de la couleur trait‚e + int ip; // Indice dans la palette + word w; // Word contenant le code + + // Sch‚ma d'un word = + // + // Low High + // VVVV RRRR | 0000 BBBB + // 0321 0321 | 0321 + + ip=0; + for (i=0;i<16;i++) + { + // Traitement des couleurs rouge, verte et bleue: + w =(((word)Pal[ip] & 0x38) >> 3) | (((word)Pal[ip] & 0x04) << 1); ip++; + w|=(((word)Pal[ip] & 0x38) << 9) | (((word)Pal[ip] & 0x04) << 13); ip++; + w|=(((word)Pal[ip] & 0x38) << 5) | (((word)Pal[ip] & 0x04) << 9); ip++; + + Dst[(i*2)+0]=w & 0x00FF; + Dst[(i*2)+1]=(w>>8); + } +} + + +// -- Tester si un fichier est au format PI1 -------------------------------- +void Test_PI1(void) +{ + int Handle; // Handle du fichier + char Nom_du_fichier[256]; // Nom complet du fichier + int Taille; // Taille du fichier + word Res; // R‚solution de l'image + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=1; + + // Ouverture du fichier + Handle=open(Nom_du_fichier,O_RDONLY); + if (Handle!=-1) + { + // V‚rification de la taille + Taille=filelength(Handle); + if ((Taille==32034) || (Taille==32066)) + { + // Lecture et v‚rification de la r‚solution + if ((read(Handle,&Res,2))==2) + { + if (Res==0x0000) + Erreur_fichier=0; + } + } + // Fermeture du fichier + close(Handle); + } +} + + +// -- Lire un fichier au format PI1 ----------------------------------------- +void Load_PI1(void) +{ + char Nom_du_fichier[256]; // Nom complet du fichier + int Fichier; + word Pos_X,Pos_Y; + byte * buffer; + byte * ptr; + byte pixels[320]; + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + // allocation d'un buffer m‚moire + buffer=(byte *)malloc(32034); + if (buffer!=NULL) + { + // Lecture du fichier dans le buffer + if (read(Fichier,buffer,32034)==32034) + { + // Initialisation de la preview + Initialiser_preview(320,200,filelength(Fichier),FORMAT_PI1); + if (Erreur_fichier==0) + { + // Initialisation de la palette + if (Config.Clear_palette) + memset(Principal_Palette,0,sizeof(T_Palette)); + PI1_Decoder_palette(buffer+2,(byte *)Principal_Palette); + Set_palette(Principal_Palette); + Remapper_fileselect(); + + Principal_Largeur_image=320; + Principal_Hauteur_image=200; + + // Chargement/d‚compression de l'image + ptr=buffer+34; + for (Pos_Y=0;Pos_Y<200;Pos_Y++) + { + for (Pos_X=0;Pos_X<(320>>4);Pos_X++) + { + PI1_8b_to_16p(ptr,pixels+(Pos_X<<4)); + ptr+=8; + } + for (Pos_X=0;Pos_X<320;Pos_X++) + Pixel_de_chargement(Pos_X,Pos_Y,pixels[Pos_X]); + } + } + } + else + Erreur_fichier=1; + free(buffer); + } + else + Erreur_fichier=1; + close(Fichier); + } + else + Erreur_fichier=1; +} + + +// -- Sauver un fichier au format PI1 --------------------------------------- +void Save_PI1(void) +{ + char Nom_du_fichier[256]; // Nom complet du fichier + int Fichier; + short Pos_X,Pos_Y; + byte * buffer; + byte * ptr; + byte pixels[320]; + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + // Ouverture du fichier + Fichier=open(Nom_du_fichier,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP); + if (Fichier!=-1) + { + // allocation d'un buffer m‚moire + buffer=(byte *)malloc(32034); + // Codage de la r‚solution + buffer[0]=0x00; + buffer[1]=0x00; + // Codage de la palette + PI1_Coder_palette((byte *)Principal_Palette,buffer+2); + // Codage de l'image + ptr=buffer+34; + for (Pos_Y=0;Pos_Y<200;Pos_Y++) + { + // Codage de la ligne + memset(pixels,0,320); + if (Pos_Y>4);Pos_X++) + { + PI1_16p_to_8b(pixels+(Pos_X<<4),ptr); + ptr+=8; + } + } + + if (write(Fichier,buffer,32034)==32034) + { + close(Fichier); + } + else // Erreur d'‚criture (disque plein ou prot‚g‚) + { + close(Fichier); + remove(Nom_du_fichier); + Erreur_fichier=1; + } + // Lib‚ration du buffer m‚moire + free(buffer); + } + else + { + close(Fichier); + remove(Nom_du_fichier); + Erreur_fichier=1; + } +} + + + + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +//////////////////////////////////// PC1 //////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + + +//// DECOMPRESSION d'un buffer selon la m‚thode PACKBITS //// + +void PC1_Decompresser_PackBits(byte * Src,byte * Dst) +{ + int is,id; // Les indices de parcour des buffers + int n; // Octet de contr“le + + for (is=id=0;id<32000;) + { + n=Src[is++]; + + if (n & 0x80) + { + // Recopier Src[is] -n+1 fois + n=257-n; + for (;(n>0) && (id<32000);n--) + Dst[id++]=Src[is]; + is++; + } + else + { + // Recopier n+1 octets litt‚ralement + n=n+1; + for (;(n>0) && (id<32000);n--) + Dst[id++]=Src[is++]; + } + + // Contr“le des erreurs + if (n>0) + Erreur_fichier=1; + } +} + +//// COMPRESSION d'un buffer selon la m‚thode PACKBITS //// + +void PC1_Compresser_PackBits(byte * Src,byte * Dst,int TailleS,int * TailleD) +{ + int is; // Indice dans la source + int id; // Indice dans la destination + int ir; // Indice de la r‚p‚tition + int n; // Taille des s‚quences + int repet; // "Il y a r‚p‚tition" + + for (is=id=0;is0;n--) + Dst[id++]=Src[is++]; + } + + // On code la partie sans r‚p‚titions + if (repet) + { + // On compte la quantit‚ de fois qu'il faut r‚p‚ter la valeur + for (ir+=3;ir>=1; + } + } +} + +//// CODAGE d'une partie d'IMAGE //// + +// Transformation d'1 ligne de pixels en 4 plans de bits + +void PC1_1lp_to_4pb(byte * Src,byte * Dst0,byte * Dst1,byte * Dst2,byte * Dst3) +{ + int i,j; // Compteurs + int ip; // Indice du pixel … calculer + byte masque; // Masque de decodage + byte b0,b1,b2,b3; // Les 4 octets des plans bits sources + + ip=0; + // Pour chacun des 40 octets des plans de bits + for (i=0;i<40;i++) + { + // Pour chacun des 8 bits des octets + masque=0x80; + b0=b1=b2=b3=0; + for (j=0;j<8;j++) + { + b0|=(Src[ip] & 0x01)?masque:0x00; + b1|=(Src[ip] & 0x02)?masque:0x00; + b2|=(Src[ip] & 0x04)?masque:0x00; + b3|=(Src[ip] & 0x08)?masque:0x00; + ip++; + masque>>=1; + } + Dst0[i]=b0; + Dst1[i]=b1; + Dst2[i]=b2; + Dst3[i]=b3; + } +} + + +// -- Tester si un fichier est au format PC1 -------------------------------- +void Test_PC1(void) +{ + int Handle; // Handle du fichier + char Nom_du_fichier[256]; // Nom complet du fichier + int Taille; // Taille du fichier + word Res; // R‚solution de l'image + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=1; + + // Ouverture du fichier + Handle=open(Nom_du_fichier,O_RDONLY); + if (Handle!=-1) + { + // V‚rification de la taille + Taille=filelength(Handle); + if ((Taille<=32066)) + { + // Lecture et v‚rification de la r‚solution + if ((read(Handle,&Res,2))==2) + { + if (Res==0x0080) + Erreur_fichier=0; + } + } + // Fermeture du fichier + close(Handle); + } +} + + +// -- Lire un fichier au format PC1 ----------------------------------------- +void Load_PC1(void) +{ + char Nom_du_fichier[256]; // Nom complet du fichier + int Fichier; + int Taille; + word Pos_X,Pos_Y; + byte * buffercomp; + byte * bufferdecomp; + byte * ptr; + byte pixels[320]; + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + Taille=filelength(Fichier); + // allocation des buffers m‚moire + buffercomp=(byte *)malloc(Taille); + bufferdecomp=(byte *)malloc(32000); + if ( (buffercomp!=NULL) && (bufferdecomp!=NULL) ) + { + // Lecture du fichier dans le buffer + if (read(Fichier,buffercomp,Taille)==Taille) + { + // Initialisation de la preview + Initialiser_preview(320,200,filelength(Fichier),FORMAT_PC1); + if (Erreur_fichier==0) + { + // Initialisation de la palette + if (Config.Clear_palette) + memset(Principal_Palette,0,sizeof(T_Palette)); + PI1_Decoder_palette(buffercomp+2,(byte *)Principal_Palette); + Set_palette(Principal_Palette); + Remapper_fileselect(); + + Principal_Largeur_image=320; + Principal_Hauteur_image=200; + + // D‚compression du buffer + PC1_Decompresser_PackBits(buffercomp+34,bufferdecomp); + + // D‚codage de l'image + ptr=bufferdecomp; + for (Pos_Y=0;Pos_Y<200;Pos_Y++) + { + // D‚codage de la scanline + PC1_4pb_to_1lp(ptr,ptr+40,ptr+80,ptr+120,pixels); + ptr+=160; + // Chargement de la ligne + for (Pos_X=0;Pos_X<320;Pos_X++) + Pixel_de_chargement(Pos_X,Pos_Y,pixels[Pos_X]); + } + } + } + else + Erreur_fichier=1; + free(bufferdecomp); + free(buffercomp); + } + else + { + Erreur_fichier=1; + if (bufferdecomp) free(bufferdecomp); + if (buffercomp) free(buffercomp); + } + close(Fichier); + } + else + Erreur_fichier=1; +} + + +// -- Sauver un fichier au format PC1 --------------------------------------- +void Save_PC1(void) +{ + char Nom_du_fichier[256]; // Nom complet du fichier + int Fichier; + int Taille; + short Pos_X,Pos_Y; + byte * buffercomp; + byte * bufferdecomp; + byte * ptr; + byte pixels[320]; + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + // Ouverture du fichier + Fichier=open(Nom_du_fichier,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP); + if (Fichier!=-1) + { + // Allocation des buffers m‚moire + bufferdecomp=(byte *)malloc(32000); + buffercomp =(byte *)malloc(64066); + // Codage de la r‚solution + buffercomp[0]=0x80; + buffercomp[1]=0x00; + // Codage de la palette + PI1_Coder_palette((byte *)Principal_Palette,buffercomp+2); + // Codage de l'image + ptr=bufferdecomp; + for (Pos_Y=0;Pos_Y<200;Pos_Y++) + { + // Codage de la ligne + memset(pixels,0,320); + if (Pos_Y +#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" + +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 [] [