From 21dacf51f177fb85ef157f1b03cbc35d33cb345e Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Fri, 1 Aug 2008 11:18:56 +0000 Subject: [PATCH] Some work on brush operations. Resize, rotate, flip,... Still some work needed for correct brush preview in zoomed mode. git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@87 416bcca6-2ee7-4201-b75f-2eb2f807beb1 --- divers.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++----- graph.c | 2 + sdlscreen.c | 62 +++++++++++++++++++++++-- 3 files changed, 178 insertions(+), 14 deletions(-) diff --git a/divers.c b/divers.c index 78e60a37..f46bf2cc 100644 --- a/divers.c +++ b/divers.c @@ -336,7 +336,7 @@ void Initialiser_chrono(dword Delai) void Wait_VBL(void) // Attente de VBL. Pour avoir des scrollbars qui ont une vitesse raisonnable par exemple. SDL ne sait pas faire ? { - puts("Wait_VBL non implémenté!"); + UNIMPLEMENTED } void Passer_en_mode_texte(byte Nb_lignes) @@ -346,28 +346,27 @@ void Passer_en_mode_texte(byte Nb_lignes) void Pixel_dans_brosse (word X,word Y,byte Couleur) { - puts("Pixel_dans_brosse non implémenté!"); + *(Brosse+Y*Brosse_Largeur+X)=Couleur; } byte Lit_pixel_dans_brosse (word X,word Y) { - puts("Lit_pixel_dans_brosse non implémenté!"); - return 0; + return *(Brosse + Y * Brosse_Largeur + X); } void Clavier_de_depart(void) { - puts("Clavier_de_depart non implémenté!"); + UNIMPLEMENTED } void Clavier_americain(void) { - puts("Clavier_americain non implémenté!"); + UNIMPLEMENTED } word Detection_souris(void) { - puts("Detection_souris non implémenté!"); + UNIMPLEMENTED return 0; } @@ -458,7 +457,31 @@ byte Lit_pixel_dans_ecran_brouillon(word X,word Y) void Rotate_90_deg_LOWLEVEL(byte * Source,byte * Destination) { - UNIMPLEMENTED + byte* esi; + byte* edi; + word dx,bx,cx; + + //ESI = Point haut droit de la source + byte* Debut_de_colonne = Source + Brosse_Largeur - 1; + edi = Destination; + + // Largeur de la source = Hauteur de la destination + dx = bx = Brosse_Largeur; + + // Pour chaque ligne + for(dx = Brosse_Largeur;dx>0;dx--) + { + esi = Debut_de_colonne; + // Pout chaque colonne + for(cx=Brosse_Hauteur;cx>0;cx--) + { + *edi = *esi; + esi+=Brosse_Largeur; + edi++; + } + + Debut_de_colonne--; + } } void Remap_general_LOWLEVEL(byte * Table_conv,byte * Buffer,short Largeur,short Hauteur,short Largeur_buffer) @@ -620,19 +643,102 @@ void Tester_chrono(void) if((SDL_GetTicks()/55)-Chrono_delay>Chrono_cmp) Etat_chrono=1; } +// Effectue uyne inversion de la brosse selon une droite horizontale void Flip_Y_LOWLEVEL(void) { - UNIMPLEMENTED + // ESI pointe sur la partie haute de la brosse + // EDI sur la partie basse + byte* ESI = Brosse ; + byte* EDI = Brosse + (Brosse_Hauteur - 1) *Brosse_Largeur; + byte tmp; + word cx; + + while(ESI < EDI) + { + // Il faut inverser les lignes pointées par ESI et + // EDI ("Brosse_Largeur" octets en tout) + + for(cx = Brosse_Largeur;cx>0;cx--) + { + tmp = *ESI; + *ESI = *EDI; + *EDI = tmp; + ESI++; + EDI++; + } + + // On change de ligne : + // ESI pointe déjà sur le début de la ligne suivante + // EDI pointe sur la fin de la ligne en cours, il + // doit pointer sur le début de la précédente... + EDI -= 2 * Brosse_Largeur; // On recule de 2 lignes + } } +// Effectue une inversion de la brosse selon une droite verticale void Flip_X_LOWLEVEL(void) { - UNIMPLEMENTED + // ESI pointe sur la partie gauche et EDI sur la partie + // droite + byte* ESI = Brosse; + byte* EDI = Brosse + Brosse_Largeur - 1; + + byte* Debut_Ligne; + byte* Fin_Ligne; + byte tmp; + word cx; + + while(ESI0;cx--) + { + tmp=*ESI; + *ESI=*EDI; + *EDI=tmp; + EDI+=Brosse_Largeur; + ESI+=Brosse_Largeur; + } + + // On change de colonne + // ESI > colonne suivante + // EDI > colonne précédente + ESI = Debut_Ligne + 1; + EDI = Fin_Ligne - 1; + } } +// Faire une rotation de 180º de la brosse void Rotate_180_deg_LOWLEVEL(void) { - UNIMPLEMENTED + // ESI pointe sur la partie supérieure de la brosse + // EDI pointe sur la partie basse + byte* ESI = Brosse; + byte* EDI = Brosse + Brosse_Hauteur*Brosse_Largeur - 1; + // EDI pointe sur le dernier pixel de la derniere ligne + byte tmp; + word cx; + + while(ESI < EDI) + { + // On échange les deux lignes pointées par EDI et + // ESI (Brosse_Largeur octets) + // En même temps, on échange les pixels, donc EDI + // pointe sur la FIN de sa ligne + + for(cx=Brosse_Largeur;cx>0;cx--) + { + tmp = *ESI; + *ESI = *EDI; + *EDI = tmp; + + EDI--; // Attention ici on recule ! + ESI++; + } + } } void Tempo_jauge(byte Vitesse) diff --git a/graph.c b/graph.c index 9db3d366..c13eada9 100644 --- a/graph.c +++ b/graph.c @@ -5550,6 +5550,8 @@ void Etirer_brosse_preview(short X1, short Y1, short X2, short Y2) Pos_Y_src+=Delta_Y; } + + SDL_UpdateRect(Ecran_SDL,Pos_X_dest_Initiale,Pos_Y_dest_Initiale,Largeur_dest,Hauteur_dest); } diff --git a/sdlscreen.c b/sdlscreen.c index b835ee97..0882737a 100644 --- a/sdlscreen.c +++ b/sdlscreen.c @@ -126,7 +126,34 @@ 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) { - UNIMPLEMENTED + // EDI = Position à l'écran + byte* EDI = Ecran + Pos_Y * Largeur_ecran + Pos_X; + // ESI = Position dans la brosse + byte* ESI = Brosse + 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; + } + SDL_UpdateRect(Ecran_SDL,Pos_X,Pos_Y,Largeur,Hauteur); } void Display_brush_Mono_SDL (word Pos_X, word Pos_Y, @@ -255,9 +282,38 @@ void Afficher_partie_de_l_ecran_zoomee_SDL( // ATTENTION on n'arrive jamais ici ! } -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 Afficher_une_ligne_transparente_a_l_ecran_SDL(word Pos_X,word Pos_Y,word Largeur,byte* Ligne,byte Couleur_transparence) { - UNIMPLEMENTED + UNIMPLEMENTED +} + +// 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,