From d2300cc2c1c86320b916798984a005d6c6eaa1a0 Mon Sep 17 00:00:00 2001 From: Yves Rizoud Date: Sat, 13 Dec 2008 16:20:37 +0000 Subject: [PATCH] Support for "tall pixel" mode (Each pixel is 1x2). Run the program with "/tall" argument to test. The following tools don't take the ratio into account; Circle, Grad rectangle, Brush rotation, Resizable brushes (diamond, squares, circles...) git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@376 416bcca6-2ee7-4201-b75f-2eb2f807beb1 --- Makefile | 2 +- Makefile.dep | 8 +- aide.c | 2 + boutons.c | 6 +- const.h | 9 +- divers.c | 16 +- global.h | 6 +- graph.c | 118 ++++++++----- graph.h | 2 +- init.c | 124 +++++++------- main.c | 14 +- moteur.c | 17 +- pxsimple.c | 471 +++++++++++++++++++++++++++++++++++++++++++++++++++ pxsimple.h | 47 +++++ pxtall.c | 451 ++++++++++++++++++++++++++++++++++++++++++++++++ pxtall.h | 42 +++++ sdlscreen.c | 457 +------------------------------------------------ sdlscreen.h | 22 +-- struct.h | 1 + 19 files changed, 1206 insertions(+), 609 deletions(-) create mode 100644 pxsimple.c create mode 100644 pxsimple.h create mode 100644 pxtall.c create mode 100644 pxtall.h diff --git a/Makefile b/Makefile index 43578a37..b40e1912 100644 --- a/Makefile +++ b/Makefile @@ -133,7 +133,7 @@ endif .PHONY : all debug release clean depend zip version force install uninstall -OBJ = $(OBJDIR)/main.o $(OBJDIR)/init.o $(OBJDIR)/graph.o $(OBJDIR)/sdlscreen.o $(OBJDIR)/divers.o $(OBJDIR)/special.o $(OBJDIR)/boutons.o $(OBJDIR)/palette.o $(OBJDIR)/aide.o $(OBJDIR)/operatio.o $(OBJDIR)/pages.o $(OBJDIR)/loadsave.o $(OBJDIR)/readline.o $(OBJDIR)/moteur.o $(OBJDIR)/files.o $(OBJDIR)/op_c.o $(OBJDIR)/readini.o $(OBJDIR)/saveini.o $(OBJDIR)/shade.o $(OBJDIR)/clavier.o $(OBJDIR)/io.o $(OBJDIR)/version.o $(OBJDIR)/texte.o $(OBJDIR)/SFont.o $(OBJDIR)/setup.o +OBJ = $(OBJDIR)/main.o $(OBJDIR)/init.o $(OBJDIR)/graph.o $(OBJDIR)/sdlscreen.o $(OBJDIR)/divers.o $(OBJDIR)/special.o $(OBJDIR)/boutons.o $(OBJDIR)/palette.o $(OBJDIR)/aide.o $(OBJDIR)/operatio.o $(OBJDIR)/pages.o $(OBJDIR)/loadsave.o $(OBJDIR)/readline.o $(OBJDIR)/moteur.o $(OBJDIR)/files.o $(OBJDIR)/op_c.o $(OBJDIR)/readini.o $(OBJDIR)/saveini.o $(OBJDIR)/shade.o $(OBJDIR)/clavier.o $(OBJDIR)/io.o $(OBJDIR)/version.o $(OBJDIR)/texte.o $(OBJDIR)/SFont.o $(OBJDIR)/setup.o $(OBJDIR)/pxsimple.o $(OBJDIR)/pxtall.o CFGOBJ = $(OBJDIR)/gfxcfg.o $(OBJDIR)/SFont.o $(OBJDIR)/clavier.o $(OBJDIR)/io.o $(OBJDIR)/setup.o all : $(BIN) $(CFGBIN) diff --git a/Makefile.dep b/Makefile.dep index cae63e4b..33c73bea 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -12,7 +12,7 @@ $(OBJDIR)/files.o: files.c const.h struct.h global.h loadsave.h graph.h divers.h $(OBJDIR)/gfxcfg.o: gfxcfg.c SFont.h struct.h const.h clavier.h io.h hotkeys.h \ setup.h $(OBJDIR)/graph.o: graph.c global.h struct.h const.h loadsave.h moteur.h boutons.h \ - pages.h erreurs.h sdlscreen.h graph.h divers.h + pages.h erreurs.h sdlscreen.h graph.h divers.h pxsimple.h pxtall.h $(OBJDIR)/init.o: init.c const.h struct.h global.h loadsave.h graph.h boutons.h \ palette.h aide.h operatio.h divers.h erreurs.h clavier.h io.h hotkeys.h \ files.h setup.h @@ -32,13 +32,17 @@ $(OBJDIR)/pages.o: pages.c global.h struct.h const.h loadsave.h pages.h graph.h $(OBJDIR)/palette.o: palette.c const.h struct.h global.h loadsave.h divers.h \ graph.h moteur.h readline.h boutons.h pages.h aide.h sdlscreen.h \ erreurs.h op_c.h +$(OBJDIR)/pxsimple.o: pxsimple.c global.h struct.h const.h loadsave.h sdlscreen.h \ + divers.h +$(OBJDIR)/pxtall.o: pxtall.c global.h struct.h const.h loadsave.h sdlscreen.h \ + divers.h pxsimple.h $(OBJDIR)/readini.o: readini.c const.h global.h struct.h loadsave.h graph.h $(OBJDIR)/readline.o: readline.c const.h struct.h global.h loadsave.h graph.h \ divers.h erreurs.h sdlscreen.h readline.h $(OBJDIR)/saveini.o: saveini.c const.h global.h struct.h loadsave.h readini.h io.h \ erreurs.h graph.h $(OBJDIR)/sdlscreen.o: sdlscreen.c global.h struct.h const.h loadsave.h sdlscreen.h \ - divers.h erreurs.h graph.h + erreurs.h graph.h $(OBJDIR)/setup.o: setup.c struct.h const.h io.h files.h $(OBJDIR)/shade.o: shade.c global.h struct.h const.h loadsave.h graph.h moteur.h \ divers.h readline.h aide.h sdlscreen.h diff --git a/aide.c b/aide.c index 2ab928f9..2fd21e9a 100644 --- a/aide.c +++ b/aide.c @@ -177,6 +177,8 @@ void Afficher_aide(void) Couleur=CM_Fonce; } Buffer_de_ligne_horizontale[Position_X++]=Couleur; + if (Pixel_width>1) + Buffer_de_ligne_horizontale[Position_X++]=Couleur; } } // On la splotche diff --git a/boutons.c b/boutons.c index b7ee79d7..c8986563 100644 --- a/boutons.c +++ b/boutons.c @@ -1488,11 +1488,11 @@ void Bouton_Resol(void) if (Mouse_K==2) { // On affecte également les dimensions de l'image: - Largeur_choisie=Mode_video[Mode_choisi].Largeur; + Largeur_choisie=Mode_video[Mode_choisi].Largeur/Pixel_width; Num2str(Largeur_choisie,Chaine,4); Fenetre_Contenu_bouton_saisie(Bouton_saisie_Width,Chaine); - Hauteur_choisie=Mode_video[Mode_choisi].Hauteur; + Hauteur_choisie=Mode_video[Mode_choisi].Hauteur/Pixel_height; Num2str(Hauteur_choisie,Chaine,4); Fenetre_Contenu_bouton_saisie(Bouton_saisie_Height,Chaine); } @@ -5915,7 +5915,7 @@ void Bouton_Texte() Nouvelle_Brosse = Rendu_Texte(Chaine_preview, Position_curseur+Debut_liste, Taille_police, AntiAlias, Style_Bold, Style_Italic, &Nouvelle_Largeur, &Nouvelle_Hauteur); if (Nouvelle_Brosse) { - Affiche_brosse_SDL( + Affiche_brosse( Nouvelle_Brosse, Fenetre_Pos_X+Bouton_preview->Pos_X*Menu_Facteur_X, Fenetre_Pos_Y+Bouton_preview->Pos_Y*Menu_Facteur_Y, diff --git a/const.h b/const.h index 62c0fd28..106b40df 100644 --- a/const.h +++ b/const.h @@ -126,11 +126,14 @@ enum CODES_D_ERREURS ERREUR_SORRY_SORRY_SORRY // On le refera plus, promis }; - // Les différents types de modes vidéos + // Les différents types de pixels -enum TYPES_DE_MODES_VIDEO +enum PIXEL_RATIO { - MODE_SDL + PIXEL_SIMPLE, + PIXEL_WIDE, + PIXEL_TALL, + PIXEL_DOUBLE }; // Les différentes catégories de bouton: diff --git a/divers.c b/divers.c index 316a5aed..23e42fcf 100644 --- a/divers.c +++ b/divers.c @@ -159,8 +159,8 @@ void Get_input(void) { case SDL_MOUSEMOTION: //Mouvement de la souris - INPUT_Nouveau_Mouse_X = event.motion.x>>Mouse_Facteur_de_correction_X; - INPUT_Nouveau_Mouse_Y = event.motion.y>>Mouse_Facteur_de_correction_Y; + INPUT_Nouveau_Mouse_X = event.motion.x/Pixel_width; + INPUT_Nouveau_Mouse_Y = event.motion.y/Pixel_height; break; case SDL_MOUSEBUTTONDOWN: //Clic sur un des boutons de la souris @@ -256,8 +256,8 @@ void Get_input(void) if(ok) { SDL_WarpMouse( - INPUT_Nouveau_Mouse_X< Hauteur/200) - Facteur=Hauteur/200; + if (Largeur_ecran/320 > Hauteur_ecran/200) + Facteur=Hauteur_ecran/200; else - Facteur=Largeur/320; - - Largeur_ecran = Largeur; - Hauteur_ecran = Hauteur; - Plein_ecran = Fullscreen; + Facteur=Largeur_ecran/320; switch (Config.Ratio) { @@ -1093,36 +1153,14 @@ void Initialiser_mode_video(int Largeur, int Hauteur, int Fullscreen) Menu_Facteur_X=1; Menu_Facteur_Y=1; } - + if (Pixel_height>Pixel_width) + Menu_Facteur_X*=2; + else if (Pixel_width>Pixel_height) + Menu_Facteur_Y*=2; 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_SDL) - { - case MODE_SDL: - Pixel = Pixel_SDL; - Lit_pixel= Lit_Pixel_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; - } + Buffer_de_ligne_horizontale=(byte *)malloc(Pixel_width*((Largeur_ecran>Principal_Largeur_image)?Largeur_ecran:Principal_Largeur_image)); Set_palette(Principal_Palette); @@ -1359,7 +1397,7 @@ void Encadrer_couleur_menu(byte Couleur) Menu_Facteur_X,Menu_Facteur_Y, ((Indice+Fin_Y)&1)?CM_Blanc:CM_Noir); - UpdateRect(Debut_X*Menu_Facteur_X,Debut_Y*Menu_Facteur_X,Menu_Taille_couleur*Menu_Facteur_X,Menu_Ordonnee+Menu_Facteur_Y*4); + UpdateRect(Debut_X*Menu_Facteur_X,Debut_Y*Menu_Facteur_Y,Menu_Taille_couleur*Menu_Facteur_X,Menu_Ordonnee+Menu_Facteur_Y*4); } } } @@ -1548,7 +1586,7 @@ void Print_general(short X,short Y,char * Chaine,byte Couleur_texte,byte Couleur { Caractere=(Chaine[Indice])<<6; for (Pos_X=0;Pos_X<8<<3;Pos_X+=1<<3) - for (Repeat_Menu_Facteur_X=0;Repeat_Menu_Facteur_X= Nb_modes_video) { // Nouveau mode à ajouter à la liste - Definir_mode_video(Modes[Indice]->w,Modes[Indice]->h,MODE_SDL, 1); + Definir_mode_video(Modes[Indice]->w,Modes[Indice]->h,0, 1); } } // Tri des modes : ceux trouvés par SDL ont été listés à la fin. diff --git a/main.c b/main.c index 9ef29825..d2e51e4a 100644 --- a/main.c +++ b/main.c @@ -202,6 +202,10 @@ void Analyse_de_la_ligne_de_commande(int argc,char * argv[]) exit(0); } } + else if ( !strcmp(argv[Indice],"/tall") ) + { + Pixel_ratio = PIXEL_TALL; + } else { // Si ce n'est pas un paramètre, c'est le nom du fichier à ouvrir @@ -357,7 +361,7 @@ void Initialisation_du_programme(int argc,char * argv[]) // On initialise tous les modes vidéo Definition_des_modes_video(); - + Pixel_ratio=PIXEL_SIMPLE; // On initialise les données sur l'état du programme: // Donnée sur la sortie du programme: Quit_demande=0; @@ -508,10 +512,10 @@ void Initialisation_du_programme(int argc,char * argv[]) Mode_video[Mode_dans_lequel_on_demarre].Hauteur, Mode_video[Mode_dans_lequel_on_demarre].Fullscreen); - Principal_Largeur_image=Largeur_ecran; - Principal_Hauteur_image=Hauteur_ecran; - Brouillon_Largeur_image=Largeur_ecran; - Brouillon_Hauteur_image=Hauteur_ecran; + Principal_Largeur_image=Largeur_ecran/Pixel_width; + Principal_Hauteur_image=Hauteur_ecran/Pixel_height; + Brouillon_Largeur_image=Largeur_ecran/Pixel_width; + Brouillon_Hauteur_image=Hauteur_ecran/Pixel_height; // Allocation de mémoire pour les différents écrans virtuels (et brosse) if (Initialiser_les_listes_de_backups_en_debut_de_programme(Config.Nb_pages_Undo+1,Largeur_ecran,Hauteur_ecran)==0) Erreur(ERREUR_MEMOIRE); diff --git a/moteur.c b/moteur.c index fc493248..d409d0ca 100644 --- a/moteur.c +++ b/moteur.c @@ -148,7 +148,7 @@ void Restaure_fond(byte *Buffer, int Pos_X, int Pos_Y, int Largeur, int Hauteur) { int Indice; for (Indice=0; Indice>2); + Temp=Temp_color+ + ((((Mouse_X/Menu_Facteur_X)-(LARGEUR_MENU+1))/Menu_Taille_couleur)<<3)+ + ((((Mouse_Y-Menu_Ordonnee)/Menu_Facteur_Y)-2)>>2); strcpy(Chaine,TITRE_BOUTON[Indice_bouton]); sprintf(Chaine+strlen(Chaine),"%d",Temp); diff --git a/pxsimple.c b/pxsimple.c new file mode 100644 index 00000000..3d890dcf --- /dev/null +++ b/pxsimple.c @@ -0,0 +1,471 @@ +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 Yves Rizoud + Copyright 2008 Franck Charlet + Copyright 2007 Adrien Destugues + Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud) + + Grafx2 is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 + of the License. + + Grafx2 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Grafx2; if not, see or + write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include +#include "global.h" +#include "sdlscreen.h" +#include "divers.h" + +void Pixel_Simple (word X,word Y,byte Couleur) +/* Affiche un pixel de la Couleur aux coords X;Y à l'écran */ +{ + *(Ecran + X + Y * Largeur_ecran)=Couleur; +} + +byte Lit_Pixel_Simple (word X,word Y) +/* On retourne la couleur du pixel aux coords données */ +{ + return *( Ecran + Y * Largeur_ecran + X ); +} + +void Block_Simple (word Debut_X,word Debut_Y,word Largeur,word Hauteur,byte Couleur) +/* On affiche un rectangle de la couleur donnée */ +{ + SDL_Rect rectangle; + rectangle.x=Debut_X; + rectangle.y=Debut_Y; + rectangle.w=Largeur; + rectangle.h=Hauteur; + SDL_FillRect(Ecran_SDL,&rectangle,Couleur); +} + +void Afficher_partie_de_l_ecran_Simple (word Largeur,word Hauteur,word Largeur_image) +/* Afficher une partie de l'image telle quelle sur l'écran */ +{ + byte* Dest=Ecran; //On va se mettre en 0,0 dans l'écran (EDI) + byte* Src=Principal_Decalage_Y*Largeur_image+Principal_Decalage_X+Principal_Ecran; //Coords de départ ds la source (ESI) + int dx; + + for(dx=Hauteur;dx!=0;dx--) + // Pour chaque ligne + { + // On fait une copie de la ligne + memcpy(Dest,Src,Largeur); + + // On passe à la ligne suivante + Src+=Largeur_image; + Dest+=Largeur_ecran; + } + UpdateRect(0,0,Largeur,Hauteur); +} + +void Pixel_Preview_Normal_Simple (word X,word Y,byte Couleur) +/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image + * dans l'écran, en mode normal (pas en mode loupe) + * Note: si on modifie cette procédure, il faudra penser à faire également + * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ +{ +// if(X-Principal_Decalage_X >= 0 && Y - Principal_Decalage_Y >= 0) + Pixel_Simple(X-Principal_Decalage_X,Y-Principal_Decalage_Y,Couleur); +} + +void Pixel_Preview_Loupe_Simple (word X,word Y,byte Couleur) +{ + // Affiche le pixel dans la partie non zoomée + Pixel_Simple(X-Principal_Decalage_X,Y-Principal_Decalage_Y,Couleur); + + // Regarde si on doit aussi l'afficher dans la partie zoomée + if (Y >= Limite_Haut_Zoom && Y <= Limite_visible_Bas_Zoom + && X >= Limite_Gauche_Zoom && X <= Limite_visible_Droite_Zoom) + { + // On est dedans + int hauteur; + int Y_Zoom = Table_mul_facteur_zoom[Y-Loupe_Decalage_Y]; + + if (Menu_Ordonnee - Y_Zoom < Loupe_Facteur) + // On ne doit dessiner qu'un morceau du pixel + // sinon on dépasse sur le menu + hauteur = Menu_Ordonnee - Y_Zoom; + else + hauteur = Loupe_Facteur; + + Block_Simple( + Table_mul_facteur_zoom[X-Loupe_Decalage_X]+Principal_X_Zoom, + Y_Zoom, Loupe_Facteur, hauteur, Couleur + ); + } +} + +void Ligne_horizontale_XOR_Simple(word Pos_X,word Pos_Y,word Largeur) +{ + //On calcule la valeur initiale de EDI: + byte* edi=Pos_Y*Largeur_ecran+Pos_X+Ecran; + + int ecx; + + for (ecx=0;ecx 0; DX--) + { + // Pour chaque pixel + for(CX = Largeur;CX > 0; CX--) + { + // On vérifie que ce n'est pas la transparence + if(*ESI != Couleur_de_transparence) + { + *EDI = *ESI; + } + + // Pixel suivant + ESI++; EDI++; + } + + // On passe à la ligne suivante + EDI = EDI + Largeur_ecran - Largeur; + ESI = ESI + Largeur_brosse - Largeur; + } + UpdateRect(Pos_X,Pos_Y,Largeur,Hauteur); +} + +void Display_brush_Mono_Simple(word Pos_X, word Pos_Y, + word Decalage_X, word Decalage_Y, word Largeur, word Hauteur, + byte Couleur_de_transparence, byte Couleur, word Largeur_brosse) +/* On affiche la brosse en monochrome */ +{ + byte* Dest=Pos_Y*Largeur_ecran+Pos_X+Ecran; // EDI = adr destination à + // l'écran + byte* Src=Largeur_brosse*Decalage_Y+Decalage_X+Brosse; // ESI = adr ds + // la brosse + int dx,cx; + + for(dx=Hauteur;dx!=0;dx--) + //Pour chaque ligne + { + for(cx=Largeur;cx!=0;cx--) + //Pour chaque pixel + { + if (*Src!=Couleur_de_transparence) + *Dest=Couleur; + + // On passe au pixel suivant + Src++; + Dest++; + } + + // On passe à la ligne suivante + Src+=Largeur_brosse-Largeur; + Dest+=Largeur_ecran-Largeur; + } + UpdateRect(Pos_X,Pos_Y,Largeur,Hauteur); +} + +void Clear_brush_Simple(word Pos_X,word Pos_Y,__attribute__((unused)) word Decalage_X,__attribute__((unused)) word Decalage_Y,word Largeur,word Hauteur,__attribute__((unused))byte Couleur_de_transparence,word Largeur_image) +{ + byte* Dest=Ecran+Pos_X+Pos_Y*Largeur_ecran; //On va se mettre en 0,0 dans l'écran (EDI) + byte* Src = ( Pos_Y + Principal_Decalage_Y ) * Largeur_image + Pos_X + Principal_Decalage_X + Principal_Ecran; //Coords de départ ds la source (ESI) + int dx; + + for(dx=Hauteur;dx!=0;dx--) + // Pour chaque ligne + { + // On fait une copie de la ligne + memcpy(Dest,Src,Largeur); + + // On passe à la ligne suivante + Src+=Largeur_image; + Dest+=Largeur_ecran; + } + UpdateRect(Pos_X,Pos_Y,Largeur,Hauteur); +} + +// Affiche une brosse (arbitraire) à l'écran +void Affiche_brosse_Simple(byte * B, word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Hauteur,byte Couleur_de_transparence,word Largeur_brosse) +{ + // EDI = Position à l'écran + byte* EDI = Ecran + Pos_Y * Largeur_ecran + Pos_X; + // ESI = Position dans la brosse + byte* ESI = B + Decalage_Y * Largeur_brosse + Decalage_X; + + word DX,CX; + + // Pour chaque ligne + for(DX = Hauteur;DX > 0; DX--) + { + // Pour chaque pixel + for(CX = Largeur;CX > 0; CX--) + { + // On vérifie que ce n'est pas la transparence + if(*ESI != Couleur_de_transparence) + { + *EDI = *ESI; + } + + // Pixel suivant + ESI++; EDI++; + } + + // On passe à la ligne suivante + EDI = EDI + Largeur_ecran - Largeur; + ESI = ESI + Largeur_brosse - Largeur; + } +} + +void Remap_screen_Simple(word Pos_X,word Pos_Y,word Largeur,word Hauteur,byte * Table_de_conversion) +{ + // EDI = coords a l'écran + byte* EDI = Ecran + Pos_Y * Largeur_ecran + Pos_X; + int dx,cx; + + // Pour chaque ligne + for(dx=Hauteur;dx>0;dx--) + { + // Pour chaque pixel + for(cx=Largeur;cx>0;cx--) + { + *EDI = Table_de_conversion[*EDI]; + EDI ++; + } + + EDI = EDI + Largeur_ecran - Largeur; + } + + UpdateRect(Pos_X,Pos_Y,Largeur,Hauteur); +} + +void Afficher_une_ligne_ecran_Simple(word Pos_X,word Pos_Y,word Largeur,byte * Ligne) +/* On affiche toute une ligne de pixels. Utilisé pour les textes. */ +{ + memcpy(Ecran+Pos_X+Pos_Y*Largeur_ecran,Ligne,Largeur); +} + +void Afficher_une_ligne_transparente_mono_a_l_ecran_Simple( + word Pos_X, word Pos_Y, word Largeur, byte* Ligne, + byte Couleur_transparence, byte Couleur) +// Affiche une ligne à l'écran avec une couleur + transparence. +// Utilisé par les brosses en mode zoom +{ + byte* Dest = Ecran+ Pos_Y * Largeur_ecran + Pos_X; + int Compteur; + // Pour chaque pixel + for(Compteur=0;Compteur 0); + ESI += Largeur_image; + } +// ATTENTION on n'arrive jamais ici ! +} + +void Afficher_une_ligne_transparente_a_l_ecran_Simple(word Pos_X,word Pos_Y,word Largeur,byte* Ligne,byte Couleur_transparence) +{ + byte* ESI = Ligne; + byte* EDI = Ecran + Pos_Y * Largeur_ecran + Pos_X; + + word cx; + + // Pour chaque pixel de la ligne + for(cx = Largeur;cx > 0;cx--) + { + if(*ESI!=Couleur_transparence) + *EDI = *ESI; + ESI++; + EDI++; + } +} + +// Affiche une partie de la brosse couleur zoomée +void Display_brush_Color_zoom_Simple(word Pos_X,word Pos_Y, + word Decalage_X,word Decalage_Y, + word Largeur, // Largeur non zoomée + word Pos_Y_Fin,byte Couleur_de_transparence, + word Largeur_brosse, // Largeur réelle de la brosse + byte * Buffer) +{ + byte* ESI = Brosse+Decalage_Y*Largeur_brosse + Decalage_X; + word DX = Pos_Y; + byte bx; + + // Pour chaque ligne + while(1) + { + Zoomer_une_ligne(ESI,Buffer,Loupe_Facteur,Largeur); + // On affiche facteur fois la ligne zoomée + for(bx=Loupe_Facteur;bx>0;bx--) + { + Afficher_une_ligne_transparente_a_l_ecran_Simple(Pos_X,DX,Largeur*Loupe_Facteur,Buffer,Couleur_de_transparence); + DX++; + if(DX==Pos_Y_Fin) + { + return; + } + } + ESI += Largeur_brosse; + } + // ATTENTION zone jamais atteinte +} + +void Display_brush_Mono_zoom_Simple(word Pos_X, word Pos_Y, + word Decalage_X, word Decalage_Y, + word Largeur, // Largeur non zoomée + word Pos_Y_Fin, + byte Couleur_de_transparence, byte Couleur, + word Largeur_brosse, // Largeur réelle de la brosse + byte * Buffer +) + +{ + byte* ESI = Brosse + Decalage_Y * Largeur_brosse + Decalage_X; + int DX=Pos_Y; + + //Pour chaque ligne à zoomer : + while(1) + { + int BX; + // ESI = Ligne originale + // On éclate la ligne + Zoomer_une_ligne(ESI,Buffer,Loupe_Facteur,Largeur); + + // On affiche la ligne Facteur fois à l'écran (sur des + // lignes consécutives) + BX = Loupe_Facteur; + + // Pour chaque ligne écran + do + { + // On affiche la ligne zoomée + Afficher_une_ligne_transparente_mono_a_l_ecran_Simple( + Pos_X, DX, Largeur * Loupe_Facteur, + Buffer, Couleur_de_transparence, Couleur + ); + // On passe à la ligne suivante + DX++; + // On vérifie qu'on est pas à la ligne finale + if(DX == Pos_Y_Fin) + { + UpdateRect( Pos_X, Pos_Y, + Largeur * Loupe_Facteur, Pos_Y_Fin - Pos_Y ); + return; + } + BX --; + } + while (BX > 0); + + // Passage à la ligne suivante dans la brosse aussi + ESI+=Largeur_brosse; + } +} + +void Clear_brush_zoom_Simple(word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Pos_Y_Fin,__attribute__((unused)) byte Couleur_de_transparence,word Largeur_image,byte * Buffer) +{ + // En fait on va recopier l'image non zoomée dans la partie zoomée ! + byte* ESI = Principal_Ecran + Decalage_Y * Largeur_image + Decalage_X; + int DX = Pos_Y; + int bx; + + // Pour chaque ligne à zoomer + while(1){ + Zoomer_une_ligne(ESI,Buffer,Loupe_Facteur,Largeur); + + bx=Loupe_Facteur; + + // Pour chaque ligne + do{ + Afficher_une_ligne_ecran_Simple(Pos_X,DX, + Largeur * Loupe_Facteur,Buffer); + + // Ligne suivante + DX++; + if(DX==Pos_Y_Fin) + { + UpdateRect(Pos_X,Pos_Y, + Largeur*Loupe_Facteur,Pos_Y_Fin-Pos_Y); + return; + } + bx--; + }while(bx!=0); + + ESI+= Largeur_image; + } +} + + diff --git a/pxsimple.h b/pxsimple.h new file mode 100644 index 00000000..47ad2ad2 --- /dev/null +++ b/pxsimple.h @@ -0,0 +1,47 @@ +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 Yves Rizoud + Copyright 2007 Adrien Destugues + Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud) + + Grafx2 is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 + of the License. + + Grafx2 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Grafx2; if not, see or + write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "struct.h" + + void Pixel_Simple (word X,word Y,byte Couleur); + byte Lit_Pixel_Simple (word X,word Y); + void Block_Simple (word Debut_X,word Debut_Y,word Largeur,word Hauteur,byte Couleur); + void Pixel_Preview_Normal_Simple (word X,word Y,byte Couleur); + void Pixel_Preview_Loupe_Simple (word X,word Y,byte Couleur); + void Ligne_horizontale_XOR_Simple (word Pos_X,word Pos_Y,word Largeur); + void Ligne_verticale_XOR_Simple (word Pos_X,word Pos_Y,word Hauteur); + void Display_brush_Color_Simple (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Hauteur,byte Couleur_de_transparence,word Largeur_brosse); + void Display_brush_Mono_Simple (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Hauteur,byte Couleur_de_transparence,byte Couleur,word Largeur_brosse); + void Clear_brush_Simple (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Hauteur,byte Couleur_de_transparence,word Largeur_image); + void Remap_screen_Simple (word Pos_X,word Pos_Y,word Largeur,word Hauteur,byte * Table_de_conversion); + void Afficher_partie_de_l_ecran_Simple (word Largeur,word Hauteur,word Largeur_image); + void Afficher_une_ligne_ecran_Simple (word Pos_X,word Pos_Y,word Largeur,byte * Ligne); + void Lire_une_ligne_ecran_Simple (word Pos_X,word Pos_Y,word Largeur,byte * Ligne); + void Afficher_partie_de_l_ecran_zoomee_Simple(word Largeur,word Hauteur,word Largeur_image,byte * Buffer); + void Display_brush_Color_zoom_Simple (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Pos_Y_Fin,byte Couleur_de_transparence,word Largeur_brosse,byte * Buffer); + void Display_brush_Mono_zoom_Simple (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Pos_Y_Fin,byte Couleur_de_transparence,byte Couleur,word Largeur_brosse,byte * Buffer); + void Clear_brush_zoom_Simple (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Pos_Y_Fin,byte Couleur_de_transparence,word Largeur_image,byte * Buffer); + void Affiche_brosse_Simple (byte * B, word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Hauteur,byte Couleur_de_transparence,word Largeur_brosse); + +void Afficher_une_ligne_transparente_mono_a_l_ecran_Simple( + word Pos_X, word Pos_Y, word Largeur, byte* Ligne, + byte Couleur_transparence, byte Couleur); +void Afficher_une_ligne_transparente_a_l_ecran_Simple(word Pos_X,word Pos_Y,word Largeur,byte* Ligne,byte Couleur_transparence); diff --git a/pxtall.c b/pxtall.c new file mode 100644 index 00000000..0fa169db --- /dev/null +++ b/pxtall.c @@ -0,0 +1,451 @@ +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 Yves Rizoud + Copyright 2008 Franck Charlet + Copyright 2007 Adrien Destugues + Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud) + + Grafx2 is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 + of the License. + + Grafx2 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Grafx2; if not, see or + write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include +#include "global.h" +#include "sdlscreen.h" +#include "divers.h" +#include "pxsimple.h" + +void Pixel_Tall (word X,word Y,byte Couleur) +/* Affiche un pixel de la Couleur aux coords X;Y à l'écran */ +{ + *(Ecran + X + Y * 2 * Largeur_ecran)=Couleur; + *(Ecran + X + (Y * 2 + 1) * Largeur_ecran)=Couleur; +} + +byte Lit_Pixel_Tall (word X,word Y) +/* On retourne la couleur du pixel aux coords données */ +{ + return *( Ecran + Y * 2 * Largeur_ecran + X ); +} + +void Block_Tall (word Debut_X,word Debut_Y,word Largeur,word Hauteur,byte Couleur) +/* On affiche un rectangle de la couleur donnée */ +{ + SDL_Rect rectangle; + rectangle.x=Debut_X; + rectangle.y=Debut_Y*2; + rectangle.w=Largeur; + rectangle.h=Hauteur*2; + SDL_FillRect(Ecran_SDL,&rectangle,Couleur); +} + +void Afficher_partie_de_l_ecran_Tall (word Largeur,word Hauteur,word Largeur_image) +/* Afficher une partie de l'image telle quelle sur l'écran */ +{ + byte* Dest=Ecran; //On va se mettre en 0,0 dans l'écran (EDI) + byte* Src=Principal_Decalage_Y*Largeur_image+Principal_Decalage_X+Principal_Ecran; //Coords de départ ds la source (ESI) + int dx; + + for(dx=Hauteur;dx!=0;dx--) + // Pour chaque ligne + { + // On fait une copie de la ligne + memcpy(Dest,Src,Largeur); + Dest+=Largeur_ecran; + memcpy(Dest,Src,Largeur); + + // On passe à la ligne suivante + Src+=Largeur_image; + Dest+=Largeur_ecran; + } + UpdateRect(0,0,Largeur,Hauteur); +} + +void Pixel_Preview_Normal_Tall (word X,word Y,byte Couleur) +/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image + * dans l'écran, en mode normal (pas en mode loupe) + * Note: si on modifie cette procédure, il faudra penser à faire également + * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ +{ +// if(X-Principal_Decalage_X >= 0 && Y - Principal_Decalage_Y >= 0) + Pixel_Tall(X-Principal_Decalage_X,Y-Principal_Decalage_Y,Couleur); +} + +void Pixel_Preview_Loupe_Tall (word X,word Y,byte Couleur) +{ + // Affiche le pixel dans la partie non zoomée + Pixel_Tall(X-Principal_Decalage_X,Y-Principal_Decalage_Y,Couleur); + + // Regarde si on doit aussi l'afficher dans la partie zoomée + if (Y >= Limite_Haut_Zoom && Y <= Limite_visible_Bas_Zoom + && X >= Limite_Gauche_Zoom && X <= Limite_visible_Droite_Zoom) + { + // On est dedans + int hauteur; + int Y_Zoom = Table_mul_facteur_zoom[Y-Loupe_Decalage_Y]; + + if (Menu_Ordonnee - Y_Zoom < Loupe_Facteur) + // On ne doit dessiner qu'un morceau du pixel + // sinon on dépasse sur le menu + hauteur = Menu_Ordonnee - Y_Zoom; + else + hauteur = Loupe_Facteur; + + Block_Tall( + Table_mul_facteur_zoom[X-Loupe_Decalage_X]+Principal_X_Zoom, + Y_Zoom, Loupe_Facteur, hauteur, Couleur + ); + } +} + +void Ligne_horizontale_XOR_Tall(word Pos_X,word Pos_Y,word Largeur) +{ + //On calcule la valeur initiale de EDI: + byte* edi=Pos_Y*2*Largeur_ecran+Pos_X+Ecran; + + int ecx; + + for (ecx=0;ecx 0; DX--) + { + // Pour chaque pixel + for(CX = Largeur;CX > 0; CX--) + { + // On vérifie que ce n'est pas la transparence + if(*ESI != Couleur_de_transparence) + { + *EDI = *ESI; + *(EDI+Largeur_ecran) = *ESI; + } + + // Pixel suivant + ESI++; EDI++; + } + + // On passe à la ligne suivante + EDI = EDI + 2 * Largeur_ecran - Largeur; + ESI = ESI + Largeur_brosse - Largeur; + } + UpdateRect(Pos_X,Pos_Y,Largeur,Hauteur); +} + +void Display_brush_Mono_Tall(word Pos_X, word Pos_Y, + word Decalage_X, word Decalage_Y, word Largeur, word Hauteur, + byte Couleur_de_transparence, byte Couleur, word Largeur_brosse) +/* On affiche la brosse en monochrome */ +{ + byte* Dest=Pos_Y*2*Largeur_ecran+Pos_X+Ecran; // EDI = adr destination à + // l'écran + byte* Src=Largeur_brosse*Decalage_Y+Decalage_X+Brosse; // ESI = adr ds + // la brosse + int dx,cx; + + for(dx=Hauteur;dx!=0;dx--) + //Pour chaque ligne + { + for(cx=Largeur;cx!=0;cx--) + //Pour chaque pixel + { + if (*Src!=Couleur_de_transparence) + { + *Dest=Couleur; + *(Dest+Largeur_ecran)=Couleur; + } + + // On passe au pixel suivant + Src++; + Dest++; + } + + // On passe à la ligne suivante + Src+=Largeur_brosse-Largeur; + Dest+=2*Largeur_ecran-Largeur; + } + UpdateRect(Pos_X,Pos_Y,Largeur,Hauteur); +} + +void Clear_brush_Tall(word Pos_X,word Pos_Y,__attribute__((unused)) word Decalage_X,__attribute__((unused)) word Decalage_Y,word Largeur,word Hauteur,__attribute__((unused))byte Couleur_de_transparence,word Largeur_image) +{ + byte* Dest=Ecran+Pos_X+Pos_Y*2*Largeur_ecran; //On va se mettre en 0,0 dans l'écran (EDI) + byte* Src = ( Pos_Y + Principal_Decalage_Y ) * Largeur_image + Pos_X + Principal_Decalage_X + Principal_Ecran; //Coords de départ ds la source (ESI) + int dx; + + for(dx=Hauteur;dx!=0;dx--) + // Pour chaque ligne + { + // On fait une copie de la ligne + memcpy(Dest,Src,Largeur); + Dest+=Largeur_ecran; + memcpy(Dest,Src,Largeur); + + // On passe à la ligne suivante + Src+=Largeur_image; + Dest+=Largeur_ecran; + } + UpdateRect(Pos_X,Pos_Y,Largeur,Hauteur); +} + +// Affiche une brosse (arbitraire) à l'écran +void Affiche_brosse_Tall(byte * B, word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Hauteur,byte Couleur_de_transparence,word Largeur_brosse) +{ + // EDI = Position à l'écran + byte* EDI = Ecran + Pos_Y * 2 * Largeur_ecran + Pos_X; + // ESI = Position dans la brosse + byte* ESI = B + Decalage_Y * Largeur_brosse + Decalage_X; + + word DX,CX; + + // Pour chaque ligne + for(DX = Hauteur;DX > 0; DX--) + { + // Pour chaque pixel + for(CX = Largeur;CX > 0; CX--) + { + // On vérifie que ce n'est pas la transparence + if(*ESI != Couleur_de_transparence) + { + *EDI = *ESI; + *(EDI+Largeur_ecran) = *ESI; + } + + // Pixel suivant + ESI++; EDI++; + } + + // On passe à la ligne suivante + EDI = EDI + Largeur_ecran * 2 - Largeur; + ESI = ESI + Largeur_brosse - Largeur; + } +} + +void Remap_screen_Tall(word Pos_X,word Pos_Y,word Largeur,word Hauteur,byte * Table_de_conversion) +{ + // EDI = coords a l'écran + byte* EDI = Ecran + Pos_Y * 2 * Largeur_ecran + Pos_X; + int dx,cx; + + // Pour chaque ligne + for(dx=Hauteur*2;dx>0;dx--) + { + // Pour chaque pixel + for(cx=Largeur;cx>0;cx--) + { + *EDI = Table_de_conversion[*EDI]; + EDI ++; + } + + EDI = EDI + Largeur_ecran - Largeur; + } + + UpdateRect(Pos_X,Pos_Y,Largeur,Hauteur); +} + +void Afficher_une_ligne_ecran_Tall(word Pos_X,word Pos_Y,word Largeur,byte * Ligne) +/* On affiche toute une ligne de pixels. Utilisé pour les textes. */ +{ + memcpy(Ecran+Pos_X+Pos_Y*2*Largeur_ecran,Ligne,Largeur); + memcpy(Ecran+Pos_X+(Pos_Y*2+1)*Largeur_ecran,Ligne,Largeur); +} + +void Lire_une_ligne_ecran_Tall(word Pos_X,word Pos_Y,word Largeur,byte * Ligne) +{ + memcpy(Ligne,Largeur_ecran * 2 * Pos_Y + Pos_X + Ecran,Largeur); +} + +void Afficher_partie_de_l_ecran_zoomee_Tall( + word Largeur, // Largeur non zoomée + word Hauteur, // Hauteur zoomée + word Largeur_image,byte * Buffer) +{ + byte* ESI = Principal_Ecran + Loupe_Decalage_Y * Largeur_image + + Loupe_Decalage_X; + int EDX = 0; // Ligne en cours de traitement + + // Pour chaque ligne à zoomer + while(1) + { + int CX; + + // On éclate la ligne + Zoomer_une_ligne(ESI,Buffer,Loupe_Facteur,Largeur); + // On l'affiche Facteur fois, sur des lignes consécutives + CX = Loupe_Facteur*2; + // Pour chaque ligne + do{ + // On affiche la ligne zoomée + Afficher_une_ligne_ecran_Simple( + Principal_X_Zoom, EDX, Largeur*Loupe_Facteur, + Buffer + ); + // On passe à la suivante + EDX++; + if(EDX==Hauteur*2) + { + UpdateRect(Principal_X_Zoom,0, + Largeur*Loupe_Facteur,Hauteur); + return; + } + CX--; + }while (CX > 0); + ESI += Largeur_image; + } +// ATTENTION on n'arrive jamais ici ! +} + +// Affiche une partie de la brosse couleur zoomée +void Display_brush_Color_zoom_Tall(word Pos_X,word Pos_Y, + word Decalage_X,word Decalage_Y, + word Largeur, // Largeur non zoomée + word Pos_Y_Fin,byte Couleur_de_transparence, + word Largeur_brosse, // Largeur réelle de la brosse + byte * Buffer) +{ + byte* ESI = Brosse+Decalage_Y*Largeur_brosse + Decalage_X; + word DX = Pos_Y; + byte bx; + + // Pour chaque ligne + while(1) + { + Zoomer_une_ligne(ESI,Buffer,Loupe_Facteur,Largeur); + // On affiche facteur fois la ligne zoomée + for(bx=Loupe_Facteur;bx>0;bx--) + { + Afficher_une_ligne_transparente_a_l_ecran_Simple(Pos_X,DX*2,Largeur*Loupe_Facteur,Buffer,Couleur_de_transparence); + memcpy(Ecran + (DX*2 +1) * Largeur_ecran + Pos_X, Ecran + DX*2* Largeur_ecran + Pos_X, Largeur*Loupe_Facteur); + DX++; + if(DX==Pos_Y_Fin) + { + return; + } + } + ESI += Largeur_brosse; + } + // ATTENTION zone jamais atteinte +} + +void Display_brush_Mono_zoom_Tall(word Pos_X, word Pos_Y, + word Decalage_X, word Decalage_Y, + word Largeur, // Largeur non zoomée + word Pos_Y_Fin, + byte Couleur_de_transparence, byte Couleur, + word Largeur_brosse, // Largeur réelle de la brosse + byte * Buffer +) + +{ + byte* ESI = Brosse + Decalage_Y * Largeur_brosse + Decalage_X; + int DX=Pos_Y*2; + + //Pour chaque ligne à zoomer : + while(1) + { + int BX; + // ESI = Ligne originale + // On éclate la ligne + Zoomer_une_ligne(ESI,Buffer,Loupe_Facteur,Largeur); + + // On affiche la ligne Facteur fois à l'écran (sur des + // lignes consécutives) + BX = Loupe_Facteur*2; + + // Pour chaque ligne écran + do + { + // On affiche la ligne zoomée + Afficher_une_ligne_transparente_mono_a_l_ecran_Simple( + Pos_X, DX, Largeur * Loupe_Facteur, + Buffer, Couleur_de_transparence, Couleur + ); + // On passe à la ligne suivante + DX++; + // On vérifie qu'on est pas à la ligne finale + if(DX == Pos_Y_Fin*2) + { + UpdateRect( Pos_X, Pos_Y, + Largeur * Loupe_Facteur, Pos_Y_Fin - Pos_Y ); + return; + } + BX --; + } + while (BX > 0); + + // Passage à la ligne suivante dans la brosse aussi + ESI+=Largeur_brosse; + } +} + +void Clear_brush_zoom_Tall(word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Pos_Y_Fin,__attribute__((unused)) byte Couleur_de_transparence,word Largeur_image,byte * Buffer) +{ + // En fait on va recopier l'image non zoomée dans la partie zoomée ! + byte* ESI = Principal_Ecran + Decalage_Y * Largeur_image + Decalage_X; + int DX = Pos_Y; + int bx; + + // Pour chaque ligne à zoomer + while(1){ + Zoomer_une_ligne(ESI,Buffer,Loupe_Facteur,Largeur); + + bx=Loupe_Facteur; + + // Pour chaque ligne + do{ + Afficher_une_ligne_ecran_Tall(Pos_X,DX, + Largeur * Loupe_Facteur,Buffer); + + // Ligne suivante + DX++; + if(DX==Pos_Y_Fin) + { + UpdateRect(Pos_X,Pos_Y, + Largeur*Loupe_Facteur,Pos_Y_Fin-Pos_Y); + return; + } + bx--; + }while(bx!=0); + + ESI+= Largeur_image; + } +} diff --git a/pxtall.h b/pxtall.h new file mode 100644 index 00000000..058327a6 --- /dev/null +++ b/pxtall.h @@ -0,0 +1,42 @@ +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 Yves Rizoud + Copyright 2007 Adrien Destugues + Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud) + + Grafx2 is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 + of the License. + + Grafx2 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Grafx2; if not, see or + write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "struct.h" + + void Pixel_Tall (word X,word Y,byte Couleur); + byte Lit_Pixel_Tall (word X,word Y); + void Block_Tall (word Debut_X,word Debut_Y,word Largeur,word Hauteur,byte Couleur); + void Pixel_Preview_Normal_Tall (word X,word Y,byte Couleur); + void Pixel_Preview_Loupe_Tall (word X,word Y,byte Couleur); + void Ligne_horizontale_XOR_Tall (word Pos_X,word Pos_Y,word Largeur); + void Ligne_verticale_XOR_Tall (word Pos_X,word Pos_Y,word Hauteur); + void Display_brush_Color_Tall (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Hauteur,byte Couleur_de_transparence,word Largeur_brosse); + void Display_brush_Mono_Tall (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Hauteur,byte Couleur_de_transparence,byte Couleur,word Largeur_brosse); + void Clear_brush_Tall (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Hauteur,byte Couleur_de_transparence,word Largeur_image); + void Remap_screen_Tall (word Pos_X,word Pos_Y,word Largeur,word Hauteur,byte * Table_de_conversion); + void Afficher_partie_de_l_ecran_Tall (word Largeur,word Hauteur,word Largeur_image); + void Afficher_une_ligne_ecran_Tall (word Pos_X,word Pos_Y,word Largeur,byte * Ligne); + void Lire_une_ligne_ecran_Tall (word Pos_X,word Pos_Y,word Largeur,byte * Ligne); + void Afficher_partie_de_l_ecran_zoomee_Tall(word Largeur,word Hauteur,word Largeur_image,byte * Buffer); + void Display_brush_Color_zoom_Tall (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Pos_Y_Fin,byte Couleur_de_transparence,word Largeur_brosse,byte * Buffer); + void Display_brush_Mono_zoom_Tall (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Pos_Y_Fin,byte Couleur_de_transparence,byte Couleur,word Largeur_brosse,byte * Buffer); + void Clear_brush_zoom_Tall (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Pos_Y_Fin,byte Couleur_de_transparence,word Largeur_image,byte * Buffer); + void Affiche_brosse_Tall (byte * B, word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Hauteur,byte Couleur_de_transparence,word Largeur_brosse); diff --git a/sdlscreen.c b/sdlscreen.c index 036362e8..4ede65fd 100644 --- a/sdlscreen.c +++ b/sdlscreen.c @@ -25,7 +25,6 @@ #include #include "global.h" #include "sdlscreen.h" -#include "divers.h" #include "erreurs.h" #include "graph.h" @@ -45,460 +44,18 @@ #endif #endif - -void Pixel_SDL (word X,word Y,byte Couleur) -/* Affiche un pixel de la Couleur aux coords X;Y à l'écran */ -{ - *(Ecran + X + Y * Largeur_ecran)=Couleur; -} - -byte Lit_Pixel_SDL (word X,word Y) -/* On retourne la couleur du pixel aux coords données */ -{ - return *( Ecran + Y * Largeur_ecran + X ); -} - -void Afficher_partie_de_l_ecran_SDL (word Largeur,word Hauteur,word Largeur_image) -/* Afficher une partie de l'image telle quelle sur l'écran */ -{ - byte* Dest=Ecran; //On va se mettre en 0,0 dans l'écran (EDI) - byte* Src=Principal_Decalage_Y*Largeur_image+Principal_Decalage_X+Principal_Ecran; //Coords de départ ds la source (ESI) - int dx; - - for(dx=Hauteur;dx!=0;dx--) - // Pour chaque ligne - { - // On fait une copie de la ligne - memcpy(Dest,Src,Largeur); - - // On passe à la ligne suivante - Src+=Largeur_image; - Dest+=Largeur_ecran; - } - UpdateRect(0,0,Largeur,Hauteur); -} - -void Block_SDL (word Debut_X,word Debut_Y,word Largeur,word Hauteur,byte Couleur) -/* On affiche un rectangle de la couleur donnée */ -{ - SDL_Rect rectangle; - rectangle.x=Debut_X; - rectangle.y=Debut_Y; - rectangle.w=Largeur; - rectangle.h=Hauteur; - SDL_FillRect(Ecran_SDL,&rectangle,Couleur); -// UpdateRect(Debut_X,Debut_Y,Largeur,Hauteur); -} - -void Pixel_Preview_Normal_SDL (word X,word Y,byte Couleur) -/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image - * dans l'écran, en mode normal (pas en mode loupe) - * Note: si on modifie cette procédure, il faudra penser à faire également - * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ -{ -// if(X-Principal_Decalage_X >= 0 && Y - Principal_Decalage_Y >= 0) - Pixel_SDL(X-Principal_Decalage_X,Y-Principal_Decalage_Y,Couleur); -} - -void Pixel_Preview_Loupe_SDL (word X,word Y,byte Couleur) -{ - // Affiche le pixel dans la partie non zoomée - Pixel_SDL(X-Principal_Decalage_X,Y-Principal_Decalage_Y,Couleur); - - // Regarde si on doit aussi l'afficher dans la partie zoomée - if (Y >= Limite_Haut_Zoom && Y <= Limite_visible_Bas_Zoom - && X >= Limite_Gauche_Zoom && X <= Limite_visible_Droite_Zoom) - { - // On est dedans - int hauteur; - int Y_Zoom = Table_mul_facteur_zoom[Y-Loupe_Decalage_Y]; - - if (Menu_Ordonnee - Y_Zoom < Loupe_Facteur) - // On ne doit dessiner qu'un morceau du pixel - // sinon on dépasse sur le menu - hauteur = Menu_Ordonnee - Y_Zoom; - else - hauteur = Loupe_Facteur; - - Block_SDL( - Table_mul_facteur_zoom[X-Loupe_Decalage_X]+Principal_X_Zoom, - Y_Zoom, Loupe_Facteur, hauteur, Couleur - ); - } -} - -void Ligne_horizontale_XOR_SDL(word Pos_X,word Pos_Y,word Largeur) -{ - //On calcule la valeur initiale de EDI: - byte* edi=Pos_Y*Largeur_ecran+Pos_X+Ecran; - - int ecx; - - for (ecx=0;ecx 0; DX--) - { - // Pour chaque pixel - for(CX = Largeur;CX > 0; CX--) - { - // On vérifie que ce n'est pas la transparence - if(*ESI != Couleur_de_transparence) - { - *EDI = *ESI; - } - - // Pixel suivant - ESI++; EDI++; - } - - // On passe à la ligne suivante - EDI = EDI + Largeur_ecran - Largeur; - ESI = ESI + Largeur_brosse - Largeur; - } - UpdateRect(Pos_X,Pos_Y,Largeur,Hauteur); -} - -void Display_brush_Mono_SDL (word Pos_X, word Pos_Y, - word Decalage_X, word Decalage_Y, word Largeur, word Hauteur, - byte Couleur_de_transparence, byte Couleur, word Largeur_brosse) -/* On affiche la brosse en monochrome */ -{ - byte* Dest=Pos_Y*Largeur_ecran+Pos_X+Ecran; // EDI = adr destination à - // l'écran - byte* Src=Largeur_brosse*Decalage_Y+Decalage_X+Brosse; // ESI = adr ds - // la brosse - int dx,cx; - - for(dx=Hauteur;dx!=0;dx--) - //Pour chaque ligne - { - for(cx=Largeur;cx!=0;cx--) - //Pour chaque pixel - { - if (*Src!=Couleur_de_transparence) - *Dest=Couleur; - - // On passe au pixel suivant - Src++; - Dest++; - } - - // On passe à la ligne suivante - Src+=Largeur_brosse-Largeur; - Dest+=Largeur_ecran-Largeur; - } - UpdateRect(Pos_X,Pos_Y,Largeur,Hauteur); -} - -void Clear_brush_SDL (word Pos_X,word Pos_Y,__attribute__((unused)) word Decalage_X,__attribute__((unused)) word Decalage_Y,word Largeur,word Hauteur,__attribute__((unused))byte Couleur_de_transparence,word Largeur_image) -{ - byte* Dest=Ecran+Pos_X+Pos_Y*Largeur_ecran; //On va se mettre en 0,0 dans l'écran (EDI) - byte* Src = ( Pos_Y + Principal_Decalage_Y ) * Largeur_image + Pos_X + Principal_Decalage_X + Principal_Ecran; //Coords de départ ds la source (ESI) - int dx; - - for(dx=Hauteur;dx!=0;dx--) - // Pour chaque ligne - { - // On fait une copie de la ligne - memcpy(Dest,Src,Largeur); - - // On passe à la ligne suivante - Src+=Largeur_image; - Dest+=Largeur_ecran; - } - UpdateRect(Pos_X,Pos_Y,Largeur,Hauteur); -} - -// Affiche une brosse (arbitraire) à l'écran -void Affiche_brosse_SDL(byte * B, word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Hauteur,byte Couleur_de_transparence,word Largeur_brosse) -{ - // EDI = Position à l'écran - byte* EDI = Ecran + Pos_Y * Largeur_ecran + Pos_X; - // ESI = Position dans la brosse - byte* ESI = B + Decalage_Y * Largeur_brosse + Decalage_X; - - word DX,CX; - - // Pour chaque ligne - for(DX = Hauteur;DX > 0; DX--) - { - // Pour chaque pixel - for(CX = Largeur;CX > 0; CX--) - { - // On vérifie que ce n'est pas la transparence - if(*ESI != Couleur_de_transparence) - { - *EDI = *ESI; - } - - // Pixel suivant - ESI++; EDI++; - } - - // On passe à la ligne suivante - EDI = EDI + Largeur_ecran - Largeur; - ESI = ESI + Largeur_brosse - Largeur; - } -} - -void Remap_screen_SDL (word Pos_X,word Pos_Y,word Largeur,word Hauteur,byte * Table_de_conversion) -{ - // EDI = coords a l'écran - byte* EDI = Ecran + Pos_Y * Largeur_ecran + Pos_X; - int dx,cx; - - // Pour chaque ligne - for(dx=Hauteur;dx>0;dx--) - { - // Pour chaque pixel - for(cx=Largeur;cx>0;cx--) - { - *EDI = Table_de_conversion[*EDI]; - EDI ++; - } - - EDI = EDI + Largeur_ecran - Largeur; - } - - UpdateRect(Pos_X,Pos_Y,Largeur,Hauteur); -} - -void Afficher_une_ligne_ecran_SDL (word Pos_X,word Pos_Y,word Largeur,byte * Ligne) -/* On affiche toute une ligne de pixels. Utilisé pour les textes. */ -{ - memcpy(Ecran+Pos_X+Pos_Y*Largeur_ecran,Ligne,Largeur); -} - -void Afficher_une_ligne_transparente_mono_a_l_ecran_SDL( - word Pos_X, word Pos_Y, word Largeur, byte* Ligne, - byte Couleur_transparence, byte Couleur) -// Affiche une ligne à l'écran avec une couleur + transparence. -// Utilisé par les brosses en mode zoom -{ - byte* Dest = Ecran+ Pos_Y * Largeur_ecran + Pos_X; - int Compteur; - // Pour chaque pixel - for(Compteur=0;Compteur 0); - ESI += Largeur_image; - } -// ATTENTION on n'arrive jamais ici ! -} - -void Afficher_une_ligne_transparente_a_l_ecran_SDL(word Pos_X,word Pos_Y,word Largeur,byte* Ligne,byte Couleur_transparence) -{ - byte* ESI = Ligne; - byte* EDI = Ecran + Pos_Y * Largeur_ecran + Pos_X; - - word cx; - - // Pour chaque pixel de la ligne - for(cx = Largeur;cx > 0;cx--) - { - if(*ESI!=Couleur_transparence) - *EDI = *ESI; - ESI++; - EDI++; - } -} - -// Affiche une partie de la brosse couleur zoomée -void Display_brush_Color_zoom_SDL (word Pos_X,word Pos_Y, - word Decalage_X,word Decalage_Y, - word Largeur, // Largeur non zoomée - word Pos_Y_Fin,byte Couleur_de_transparence, - word Largeur_brosse, // Largeur réelle de la brosse - byte * Buffer) -{ - byte* ESI = Brosse+Decalage_Y*Largeur_brosse + Decalage_X; - word DX = Pos_Y; - byte bx; - - // Pour chaque ligne - while(1) - { - Zoomer_une_ligne(ESI,Buffer,Loupe_Facteur,Largeur); - // On affiche facteur fois la ligne zoomée - for(bx=Loupe_Facteur;bx>0;bx--) - { - Afficher_une_ligne_transparente_a_l_ecran_SDL(Pos_X,DX,Largeur*Loupe_Facteur,Buffer,Couleur_de_transparence); - DX++; - if(DX==Pos_Y_Fin) - { - return; - } - } - ESI += Largeur_brosse; - } - // ATTENTION zone jamais atteinte -} - -void Display_brush_Mono_zoom_SDL (word Pos_X, word Pos_Y, - word Decalage_X, word Decalage_Y, - word Largeur, // Largeur non zoomée - word Pos_Y_Fin, - byte Couleur_de_transparence, byte Couleur, - word Largeur_brosse, // Largeur réelle de la brosse - byte * Buffer -) - -{ - byte* ESI = Brosse + Decalage_Y * Largeur_brosse + Decalage_X; - int DX=Pos_Y; - - //Pour chaque ligne à zoomer : - while(1) - { - int BX; - // ESI = Ligne originale - // On éclate la ligne - Zoomer_une_ligne(ESI,Buffer,Loupe_Facteur,Largeur); - - // On affiche la ligne Facteur fois à l'écran (sur des - // lignes consécutives) - BX = Loupe_Facteur; - - // Pour chaque ligne écran - do - { - // On affiche la ligne zoomée - Afficher_une_ligne_transparente_mono_a_l_ecran_SDL( - Pos_X, DX, Largeur * Loupe_Facteur, - Buffer, Couleur_de_transparence, Couleur - ); - // On passe à la ligne suivante - DX++; - // On vérifie qu'on est pas à la ligne finale - if(DX == Pos_Y_Fin) - { - UpdateRect( Pos_X, Pos_Y, - Largeur * Loupe_Facteur, Pos_Y_Fin - Pos_Y ); - return; - } - BX --; - } - while (BX > 0); - - // Passage à la ligne suivante dans la brosse aussi - ESI+=Largeur_brosse; - } -} - -void Clear_brush_zoom_SDL (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Pos_Y_Fin,__attribute__((unused)) byte Couleur_de_transparence,word Largeur_image,byte * Buffer) -{ - // En fait on va recopier l'image non zoomée dans la partie zoomée ! - byte* ESI = Principal_Ecran + Decalage_Y * Largeur_image + Decalage_X; - int DX = Pos_Y; - int bx; - - // Pour chaque ligne à zoomer - while(1){ - Zoomer_une_ligne(ESI,Buffer,Loupe_Facteur,Largeur); - - bx=Loupe_Facteur; - - // Pour chaque ligne - do{ - Afficher_une_ligne_ecran_SDL(Pos_X,DX, - Largeur * Loupe_Facteur,Buffer); - - // Ligne suivante - DX++; - if(DX==Pos_Y_Fin) - { - UpdateRect(Pos_X,Pos_Y, - Largeur*Loupe_Facteur,Pos_Y_Fin-Pos_Y); - return; - } - bx--; - }while(bx!=0); - - ESI+= Largeur_image; - } -} - -void Set_Mode_SDL() +void Set_Mode_SDL(int *Largeur, int *Hauteur, int Fullscreen) /* On règle la résolution de l'écran */ { - Ecran_SDL=SDL_SetVideoMode(Largeur_ecran,Hauteur_ecran,8,SDL_FULLSCREEN*Plein_ecran|SDL_RESIZABLE); + Ecran_SDL=SDL_SetVideoMode(*Largeur,*Hauteur,8,(Fullscreen?SDL_FULLSCREEN:0)|SDL_RESIZABLE); if(Ecran_SDL != NULL) { // Vérification du mode obtenu (ce n'est pas toujours celui demandé) - if (Ecran_SDL->w != Largeur_ecran || Ecran_SDL->h != Hauteur_ecran) + if (Ecran_SDL->w != *Largeur || Ecran_SDL->h != *Hauteur) { DEBUG("Erreur mode video obtenu différent de celui demandé !!",0); - Largeur_ecran = Ecran_SDL->w; - Hauteur_ecran = Ecran_SDL->h; + *Largeur = Ecran_SDL->w; + *Hauteur = Ecran_SDL->h; } Ecran=Ecran_SDL->pixels; } @@ -552,7 +109,7 @@ void Flush_update(void) } else { - SDL_UpdateRect(Ecran_SDL, Max(Min_X,0), Max(Min_Y,0), Min(Largeur_ecran, Max_X-Min_X), Min(Hauteur_ecran, Max_Y-Min_Y)); + SDL_UpdateRect(Ecran_SDL, Max(Min_X,0)*Pixel_width, Max(Min_Y,0)*Pixel_height, Min(Largeur_ecran, Max_X-Min_X)*Pixel_width, Min(Hauteur_ecran, Max_Y-Min_Y)*Pixel_height); Min_X=Min_Y=10000; Max_X=Max_Y=0; @@ -564,7 +121,7 @@ void Flush_update(void) void UpdateRect(short X, short Y, unsigned short Largeur, unsigned short Hauteur) { #if (METHODE_UPDATE == METHODE_UPDATE_MULTI_RECTANGLE) - SDL_UpdateRect(Ecran_SDL, (X), (Y), (Largeur), (Hauteur)); + SDL_UpdateRect(Ecran_SDL, X*Pixel_width, Y*Pixel_height, Largeur*Pixel_width, Hauteur*Pixel_height); #endif #if (METHODE_UPDATE == METHODE_UPDATE_PAR_CUMUL) diff --git a/sdlscreen.h b/sdlscreen.h index 5b728e64..caf3278b 100644 --- a/sdlscreen.h +++ b/sdlscreen.h @@ -25,26 +25,7 @@ #include #include "struct.h" - void Pixel_SDL (word X,word Y,byte Couleur); - byte Lit_Pixel_SDL (word X,word Y); - void Block_SDL (word Debut_X,word Debut_Y,word Largeur,word Hauteur,byte Couleur); - void Block_SDL_Fast (word Debut_X,word Debut_Y,word Largeur,word Hauteur,byte Couleur); - void Pixel_Preview_Normal_SDL (word X,word Y,byte Couleur); - void Pixel_Preview_Loupe_SDL (word X,word Y,byte Couleur); - void Ligne_horizontale_XOR_SDL(word Pos_X,word Pos_Y,word Largeur); - void Ligne_verticale_XOR_SDL (word Pos_X,word Pos_Y,word Hauteur); - void Display_brush_Color_SDL (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Hauteur,byte Couleur_de_transparence,word Largeur_brosse); - void Display_brush_Mono_SDL (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Hauteur,byte Couleur_de_transparence,byte Couleur,word Largeur_brosse); - void Clear_brush_SDL (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Hauteur,byte Couleur_de_transparence,word Largeur_image); - void Remap_screen_SDL (word Pos_X,word Pos_Y,word Largeur,word Hauteur,byte * Table_de_conversion); - void Afficher_partie_de_l_ecran_SDL (word Largeur,word Hauteur,word Largeur_image); - void Afficher_une_ligne_ecran_SDL (word Pos_X,word Pos_Y,word Largeur,byte * Ligne); - void Lire_une_ligne_ecran_SDL (word Pos_X,word Pos_Y,word Largeur,byte * Ligne); - void Afficher_partie_de_l_ecran_zoomee_SDL(word Largeur,word Hauteur,word Largeur_image,byte * Buffer); - void Display_brush_Color_zoom_SDL(word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Pos_Y_Fin,byte Couleur_de_transparence,word Largeur_brosse,byte * Buffer); - void Display_brush_Mono_zoom_SDL (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Pos_Y_Fin,byte Couleur_de_transparence,byte Couleur,word Largeur_brosse,byte * Buffer); - void Clear_brush_zoom_SDL (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Pos_Y_Fin,byte Couleur_de_transparence,word Largeur_image,byte * Buffer); - void Set_Mode_SDL(); + void Set_Mode_SDL(int *,int *,int); void Gere_Evenement_SDL(SDL_Event * event); SDL_Rect ** Liste_Modes_Videos_SDL; @@ -54,6 +35,5 @@ void Flush_update(void); byte * Surface_en_bytefield(SDL_Surface *Source, byte * Destination); SDL_Color Conversion_couleur_SDL(byte); - void Affiche_brosse_SDL(byte * B, word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Hauteur,byte Couleur_de_transparence,word Largeur_brosse); #endif // SDLSCREEN_H_INCLUDED diff --git a/struct.h b/struct.h index 6baf15d0..88b9d2cf 100644 --- a/struct.h +++ b/struct.h @@ -48,6 +48,7 @@ typedef void (* fonction_procsline) (word,word,word,byte *); typedef void (* fonction_display_zoom) (word,word,word,byte *); typedef void (* fonction_display_brush_Color_zoom) (word,word,word,word,word,word,byte,word,byte *); typedef void (* fonction_display_brush_Mono_zoom) (word,word,word,word,word,word,byte,byte,word,byte *); +typedef void (* fonction_affiche_brosse) (byte *,word,word,word,word,word,word,byte,word); struct __attribute__ ((__packed__)) Composantes {