/**************************************************************************/ /* */ /* DROITE_C.C */ /* Auteur Olivier P‚cheux */ /* opecheux@multimania.com */ /* http://www.multimania.com/opecheux */ /* */ /* Ce programme donne la realisation de l'algorithme de Martin */ /* pour tracer des droites et donne une implantaion possible */ /* pour les droites particulieres, les cadres et les rectangles */ /* */ /**************************************************************************/ #include #include /* intr et pokeb */ #include /* kbhit */ #include /* abs */ #include /* bioskey */ #define ecran 0xa000 #define largeur_ecran 320 typedef unsigned char byte; typedef unsigned short word; /* Trace de droites quelconques */ void droite(int x1, int y1, int x2, int y2, byte couleur) /* dessine une ligne inclinee */ { word offset_P,offset_P_plus_Q; /* points que l'on dessine */ int deltaX,deltaY, /* variations totales suivant x et suivant y */ delta_delta, /*differnece deltaY-deltaX ou l'inverse */ reste_a_faire, /* nombre de calculs a faire */ signe, signe_largeur_ecran, erreur; /* contient une valeur negative si l'erreur est inferieur a un demi-pixel */ /* Pour avoir le code de inc, dec, add, sub */ /* choix du sens de dessin */ deltaX=abs(x2-x1); deltaY=abs(y2-y1); delta_delta=deltaX-deltaY; if (delta_delta>=0) { /* droite peu inclinee */ /* on doit aller de la gauche vers la droite */ if (x2=y1) signe_largeur_ecran=320; else signe_largeur_ecran=-320; /* initialisations */ reste_a_faire=deltaX>>1; erreur=deltaY-reste_a_faire; if ((deltaX & 1)>0) reste_a_faire++; offset_P=(y1 << 8)+(y1 << 6)+x1; offset_P_plus_Q=(y2 << 8)+(y2 << 6)+x2+offset_P; do { pokeb(ecran,offset_P,couleur); /* dessiner le point P et Q */ pokeb(ecran,offset_P_plus_Q-offset_P,couleur); offset_P++; /* incrementer x */ if (erreur>0) { offset_P+=signe_largeur_ecran; /* incrementer Y */ erreur-=delta_delta; } else erreur+=deltaY; } while (reste_a_faire--!=0); if ((deltaX & 1)==0) pokeb(ecran,offset_P,couleur); } /* droite peu inclinee */ else /* deltaX=x1) signe=1; else signe=-1; /* initialisations */ reste_a_faire=deltaY >> 1; erreur=deltaX-reste_a_faire; if ((deltaY & 1)>0) reste_a_faire++; offset_P=(y1 << 8)+(y1 << 6)+x1; offset_P_plus_Q=(y2 << 8)+(y2 << 6)+x2+offset_P; do { pokeb(ecran,offset_P,couleur); /* dessiner le point P et Q */ pokeb(ecran,offset_P_plus_Q-offset_P,couleur); offset_P+=largeur_ecran; /* incrementer Y */ if (erreur>0) { offset_P+=signe; /* incrementer x */ erreur-=delta_delta; } else erreur+=deltaX; } while (reste_a_faire--!=0); if ((deltaY & 1)==0) pokeb(ecran,offset_P,couleur); } /* droite tres inclinee */ } /* Trace de droites horizontales avec x2>x1 */ void droite_horizontale(int x1, int y, int x2, byte couleur) { word boucle; y=(y << 8)+(y << 6)+x1; #if (sizeof(void *)==2) for (boucle=0; boucle<=x2-x1; pokeb(ecran,y+boucle++,couleur)); #else setmem(&ecran[y],x2-x1+1,couleur); #endif } /* Trace de droites verticales avec y2>y1 */ void droite_verticale(int x, int y1, int y2, byte couleur) { y1=(y1 << 8)+(y1 << 6)+x; y2=(y2 << 8)+(y2 << 6)+x; do { pokeb(ecran,y1,couleur); y1+=largeur_ecran; } while ((word)y1<=(word)y2); } /* trace de cadres avec x2>x1 et y2>y1 */ void cadre(int x1, int y1, int x2, int y2, byte couleur) { droite_horizontale(x1,y1,x2,couleur); droite_verticale(x1,y1+1,y2-1,couleur); droite_verticale(x2,y1+1,y2-1,couleur); droite_horizontale(x1,y2,x2,couleur); } /* trace de rectangles avec x2>x1 et y2>y1 */ void rectangle(int x1, int y1, int x2, int y2, byte couleur) { word boucle; y1=(y1 << 8)+(y1 << 6)+x1; /* offset de depart */ y2=(y2 << 8)+(y2 << 6)+x2; /* offset d'arrivee */ x2-=x1-1; /* x2 contient dorenavent la largeur */ do { #if (sizeof(void *)==2) for (boucle=0; boucle<=x2-1; pokeb(ecran,y1+boucle++,couleur)); #else setmem(&ecran[y1],x2,couleur); #endif y1+=largeur_ecran; } while ((word)y1<=(word)y2); } int i,j; byte couleur; struct REGPACK registres; void main(void) { /* Passage en mode 13 */ registres.r_ax=0x13; intr(0x10,®istres); /* test des lignes horizontales */ j=0; do { for (i=j; i<=199-j; i++) droite_horizontale(j,i,319-j,++couleur); for (i=j; i<=199-j; i++) droite_horizontale(j,199-i,319-j,++couleur); j=(j+1) % 99; } while(bioskey(1)==0); getch(); /* test des lignes verticales */ j=0; do { for (i=j; i<=319-j; i++) droite_verticale(i,j,199-j,++couleur); for (i=j; i<=319-j; i++) droite_verticale(319-i,j,199-j,++couleur); j=(j+1) % 99; } while(bioskey(1)==0); getch(); /* test des cadres */ do { for (j=0; j<=99; j++) for (i=0; i<=49; i++) cadre(i+j,i,219-i+j,99-i,++couleur); for (j=0; j<=99; j++) for (i=0; i<=49; i++) cadre(i+100,i+j,319-i,99-i+j,++couleur); for (j=0; j<=99; j++) for (i=0; i<=49; i++) cadre(100+i-j,100+i,319-i-j,199-i,++couleur); for (j=0; j<=99; j++) for (i=0; i<=49; i++) cadre(i,i+100-j,219-i,199-i-j,++couleur); } while(bioskey(1)==0); getch(); /* test des rectangles */ do { for (j=0; j<=99; j++) rectangle(j,0,219+j,99,++couleur); for (j=0; j<=99; j++) rectangle(100,j,319,99+j,++couleur); for (j=0; j<=99; j++) rectangle(100-j,100,319-j,199,++couleur); for (j=0; j<=99; j++) rectangle(0,100-j,219,199 -j,++couleur); } while(bioskey(1)==0); getch(); /* test des lignes quelconques */ j=0; do { for (i=0; i<=319-j; i++) droite(i+j,j,319-i,199,++couleur); for (i=0; i<=199-j; i++) droite(319,i+j,j,199-i,++couleur); j=(j+1) % 199; } while(bioskey(1)==0); getch(); /* Retour au mode texte */ registres.r_ax=3; intr(0x10,®istres); }