home *** CD-ROM | disk | FTP | other *** search
/ PC Media 23 / PC MEDIA CD23.iso / share / prog / anubis / graficos.h < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-04  |  8.8 KB  |  421 lines

  1. // Libreria de subrrutinas : GRAFICOS.H
  2. // Esta es una libreria de tratamiento gráfico encontrada en el libro
  3. // Geometría fractal. Algoritmica y representacion- Hay que destacar que no
  4. // necesita del BGI para realizar lo que quiere hacer.
  5. // Por exclusión, los procedimientos de circulo, linea, ...
  6. // aparecidos en esta librería sólo son útiles en el modo
  7. // 640x480x16 que entra con la función vga640x480.
  8. // en los demás modos son imprevisibles, además, hay que poner
  9. // antes la VGA en modo puntos para que funcione bien.
  10.  
  11. // (C) Bartolomé Borrás Riera Enero 1994
  12.  
  13. #ifndef __GRAFICOS_H
  14. #define __GRAFICOS_H
  15. #pragma inline
  16.  
  17. #include <dos.h>
  18. #include <stdio.h>
  19. #include <conio.h>
  20. #include <stdlib.h>
  21.  
  22. #define ABS(x)  ((x)<0?-(x):(x))
  23.  
  24. //---------------------------------------
  25. // Definición de las estructuras a seguir
  26. //---------------------------------------
  27. typedef struct PALETA  {
  28.     unsigned char rojo;
  29.     unsigned char verde;
  30.     unsigned char azul;
  31. } paleta;
  32.  
  33. //-------------------------------------------------
  34. // Declaración de los procedimientos de la librería
  35. //-------------------------------------------------
  36. void vga320x200(void);
  37. void vga640x480(void);
  38. void punto(int,int,int);
  39. int lee_punto(int,int);
  40. void paleta16(int[],int[],int[]);
  41. void paleta256(paleta *);
  42. void linea(int,int,int,int,char);
  43. void linrsg(int,int,int,int,int,int);
  44. void parar_pantalla(void);
  45. void activar_pantalla(void);
  46. int video_mode(void);
  47. void set_video_mode(int);
  48.  
  49. //---------------------------------------------
  50. // Implementación de las rutinas de la librería
  51. //---------------------------------------------
  52. void parar_pantalla(void)
  53. {
  54.     union REGS regs;
  55.     regs.x.ax=0x1201;
  56.     regs.h.bl=0x36;
  57.     int86(0x10,®s,®s);
  58. }
  59.  
  60. void activar_pantalla(void)
  61. {
  62.     union REGS regs;
  63.     regs.x.ax=0x1200;
  64.     regs.h.bl=0x36;
  65.     int86(0x10,®s,®s);
  66. }
  67.  
  68. void vga320x200(void)
  69. {
  70.     union REGS regs;
  71.     regs.x.ax=0x13;
  72.     int86(0x10,®s,®s);
  73. }
  74.  
  75. void vga640x480(void)
  76. {
  77.     union REGS regs;
  78.     regs.x.ax=0x12;
  79.     int86(0x10,®s,®s);
  80. }
  81.  
  82. void set_video_mode(int modo)
  83. {
  84.    union REGS regs;
  85.    regs.x.ax=modo;
  86.    int86(0x10,®s,®s);
  87. }
  88.  
  89. void punto(int x,int y,int color)
  90. {
  91.     union REGS regs;
  92.     regs.h.ah=0x0c;
  93.     regs.h.al=color;
  94.     regs.h.bh=0;
  95.     regs.x.cx=x;
  96.     regs.x.dx=y;
  97.     int86(0x10,®s,®s);
  98. }
  99.  
  100.  
  101. // =====================================================================
  102. // Esta función, pone un punto en la pantalla, lo hace directamente
  103. // programando el puerto 03CEH que es el de video, y de esta forma se
  104. // consigue una velocidad asombrosa.
  105. // IMPORTANTE:
  106. //      Sólo sirve, para el modo de video de 640x480x16Colores, en otros
  107. // modos de video es imprevisible.
  108. //      Para utilizar esta función hay que estar en modo puntos
  109. // y al finalizar su utilización hay que ponerse en modo planos
  110. //      Programada grácias a la colaboración de A.Tejada y a Wilfred The
  111. // Mouse.
  112. // =====================================================================
  113. void putpunto(int x,int y,int color)
  114. {
  115.    asm  mov cx,x
  116.     asm     mov di,cx
  117.     asm     shr di,3
  118.     asm     and cx,7
  119.     asm     mov ax,8008h
  120.     asm     shr ah,cl
  121.  
  122.     asm     mov dx,03ceh
  123.     asm     out dx,ax
  124.  
  125.     asm     mov ax,y
  126.     asm     shl ax,2
  127.     asm     add ax,y
  128.     asm     shl ax,4
  129.     asm     add di,ax
  130.     asm     mov ax,0a000h
  131.     asm     mov es,ax
  132.     asm     mov ax,color
  133.     asm     test al,es:[di]
  134.     asm     mov es:[di],al
  135. }// end putpunto
  136.  
  137.  
  138. void modo_puntos(void)
  139. {
  140.     asm     mov dx,03ceh
  141.     asm     mov ax,0205h
  142.     asm     out dx,ax
  143. }// end modo_puntos
  144.  
  145. void modo_planos(void)
  146. {
  147.     asm     mov ax,0005h
  148.     asm     mov dx,03ceh
  149.     asm     out dx,ax
  150. }// end modo_planos
  151.  
  152. int lee_punto(int x, int y)
  153. {
  154.     union REGS regs;
  155.     regs.h.ah=0x0d;
  156.     regs.h.bh=0;
  157.     regs.x.cx=x;
  158.     regs.x.dx=y;
  159.     int86(0x10,®s,®s);
  160.     return(regs.h.al);
  161. }// end lee_punto
  162.  
  163. void paleta16(int rojo[],int verde[],int azul[])
  164. {
  165.     int i;
  166.     int paleta[16]={0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63};
  167.     union REGS regs;
  168.     for(i=0;i<16;i++)  {
  169.         regs.h.ah=0x10;
  170.         regs.h.al=0x10;
  171.         regs.x.bx=paleta[i];
  172.         regs.h.dh=rojo[i];
  173.         regs.h.ch=verde[i];
  174.         regs.h.cl=azul[i];
  175.         int86(0x10,®s,®s);
  176.     }// end for
  177. }// end paleta16
  178.  
  179. void paleta256(paleta*pal)
  180. {
  181.     union REGS regs;
  182.     regs.x.ax=0x1012;
  183.     regs.x.bx=0x00;
  184.     regs.x.cx=0xff;
  185.     regs.x.dx=(unsigned int) pal;
  186.     int86(0x10,®s,®s);
  187. }// end paleta256
  188.  
  189.  
  190.  
  191. // Ahora utilizamos la función de A.Tejada, y el sistema de RPP para trazar la linea.
  192. // Esto significa que este algoritmo de linea sólo sirve para el modo 640x480x16 colores
  193. void SwapInt(int *a, int *b)
  194. {
  195.     int aux;
  196.  
  197.     aux=*a;
  198.     *a=*b;
  199.     *b=aux;
  200. }
  201.  
  202. void linea(int x0, int y0, int x1, int y1, char color)
  203. {
  204.    int dx, dy, IncrS, IncrN, d, x, y, IncrX, IncrY;
  205.    if (abs(y1-y0) < abs(x1-x0))  {
  206.       if (x0 > x1)  {
  207.      SwapInt(&x0,&x1);
  208.      SwapInt(&y0,&y1);
  209.       };
  210.       IncrY = (y1 > y0) ? 1:-1;
  211.       dx=x1-x0;
  212.       dy=abs(y1-y0);
  213.       d=2*dy-dx;
  214.       IncrS=2*dy;
  215.       IncrN=2*(dy-dx);
  216.       x=x0;
  217.       y=y0;
  218.       putpunto(x,y,color);
  219.       while (x < x1)  {
  220.      if (d <= 0)  {
  221.         d+=IncrS;
  222.         x+=1;
  223.      }  else  {
  224.         d+=IncrN;
  225.         x+=1;
  226.         y+=IncrY;
  227.      };
  228.      putpunto(x,y,color);
  229.       };
  230.    }       /* if (abs(y1-y0) < abs(x1-x0)) */  
  231.    else  {
  232.       if (y0 > y1)  {
  233.      SwapInt(&x1,&x0);
  234.      SwapInt(&y1,&y0);
  235.       }
  236.       IncrX = (x1 > x0) ? 1:-1;
  237.       dy=y1-y0;
  238.       dx=abs(x1-x0);
  239.       d=2*dx-dy;
  240.       IncrS=2*dx;
  241.       IncrN=2*(dx-dy);
  242.       x=x0;
  243.       y=y0;
  244.       putpunto(x,y,color);
  245.       while (y < y1)  {
  246.      if (d <= 0)  {
  247.         d+=IncrS;
  248.         y+=1;
  249.      }  else  {
  250.         d+=IncrN;
  251.         y+=1;
  252.         x+=IncrX;
  253.      };
  254.      putpunto(x,y,color);
  255.       };
  256.    };
  257. }// end linea
  258.  
  259. void lineag(int x1,int y1,int x2,int y2,int anchura,int color)
  260. {
  261.     int i,dx,dy,fila,col,final,g,inc1,inc2,tan;
  262.  
  263.     dx=x2-x1;
  264.     dy=y2-y1;
  265.     tan=dx>0;
  266.     if(dy<0)
  267.         tan=!tan;
  268.     if(ABS(dx)>ABS(dy))  {
  269.         if(dx>0)  {
  270.             col=x1;
  271.             fila=y1;
  272.             final=x2;
  273.         }  else  {
  274.             col=x2;
  275.             fila=y2;
  276.             final=x1;
  277.         }// end if
  278.         inc1=2*ABS(dy);
  279.         g=inc1-ABS(dx);
  280.         inc2=2*(ABS(dy)-ABS(dx));
  281.         if(tan)  {
  282.             while(col <=final)  {
  283.                 for(i=-anchura/2;i<anchura/2;i++)
  284.                     putpunto(col,fila+i,color);
  285.                 col++;
  286.                 if(g>=0)  {
  287.                     fila++;
  288.                     g+=inc2;
  289.                 }  else
  290.                     g+=inc1;
  291.             }// end while
  292.         }  else  {
  293.             while(col<=final)  {
  294.                 for(i=-anchura/2;i<anchura/2;i++)
  295.                     putpunto(col,fila+i,color);
  296.                 col++;
  297.                 if(g>0)  {
  298.                     fila--;
  299.                     g+=inc2;
  300.                 }  else
  301.                     g+=inc1;
  302.             }// end while
  303.         }// end if
  304.     }  else  {
  305.         if(dy>0)  {
  306.             col=x1;
  307.             fila=y1;
  308.             final=y2;
  309.         }  else  {
  310.             col=x2;
  311.             fila=y2;
  312.             final=y1;
  313.         }// end if
  314.         inc1=2*ABS(dx);
  315.         g=inc1-ABS(dy);
  316.         inc2=2*(ABS(dx)-ABS(dy));
  317.         if(tan)  {
  318.             while(fila<=final)  {
  319.                 for(i=-anchura/2;i<anchura/2;i++)
  320.                     putpunto(col+i,fila,color);
  321.                 fila++;
  322.                 if(g>=0)  {
  323.                     col++;
  324.                     g+=inc2;
  325.                 }  else
  326.                     g+=inc1;
  327.             }// end while
  328.         }  else  {
  329.             while(fila<=final)  {
  330.                 for(i=-anchura/2;i<anchura/2;i++)
  331.                     putpunto(col+i,fila,color);
  332.                 fila++;
  333.                 if(g>0)  {
  334.                     col--;
  335.                     g+=inc2;
  336.                 }  else
  337.                     g+=inc1;
  338.             }// end while
  339.         }// end if
  340.     }// end if
  341. }// end lineag
  342.  
  343. // En estos momentos, voy a utilizar el algoritmo de Computer Graphics para
  344. // trazar círculos.
  345. void p_circ(int x0, int y0,int x, int y, char color)
  346. {
  347.    putpunto(x0+x,y0+y,color);
  348.    putpunto(x0+x,y0-y,color);
  349.    putpunto(x0-x,y0+y,color);
  350.    putpunto(x0-x,y0-y,color);
  351.    putpunto(x0+y,y0+x,color);
  352.    putpunto(x0+y,y0-x,color);
  353.    putpunto(x0-y,y0+x,color);
  354.    putpunto(x0-y,y0-x,color);
  355. }// end p_circ
  356.    
  357. void circulo(int x0,int y0,int radio,char color)
  358. {
  359.    int x=0,y=radio,d,deltaE=3, deltaSE;
  360.    d= 1-radio;
  361.    deltaSE=-2 * radio +5;
  362.    p_circ(x0,y0,x,y,color);
  363.  
  364.    while (y>x)  {
  365.       if (d<0)  {
  366.      d += deltaE;
  367.      deltaE += 2;
  368.      deltaSE += 2;
  369.      x++;
  370.       }  else  {
  371.      d += deltaSE;
  372.      deltaE += 2;
  373.      deltaSE += 4;
  374.      x++;
  375.      y--;
  376.       }// end if
  377.       p_circ(x0,y0,x,y,color);
  378.    }// end while
  379. }// end circulo
  380.  
  381.  
  382. int video_mode(void)
  383. {
  384.     union REGS r;
  385.     r.h.ah = 15;
  386.     return ( int86(0x10, &r, &r) & 255 );
  387. }
  388.  
  389. int main(int argc,char *argv[])
  390. {
  391.    int incx,incy,x=100,y=100,radio,color=0,modo;
  392.    if(argc != 4)  {
  393.       puts("\n Sintaxis: GRAFICOS Coord X, Coord Y, Radio \n");
  394.       exit(1);
  395.    }// end if
  396.    incx = atoi(argv[1]);
  397.    incy = atoi(argv[2]);
  398.    radio = atoi(argv[3]);
  399.  
  400.    modo = video_mode();
  401.    vga640x480();
  402.    modo_puntos();
  403.    while (x<540)  {
  404.       while (y<380)  {
  405.      circulo(x,y,radio,color);
  406.      linea(x-radio,y,x+radio,y,color);
  407.      linea(x,y-radio,x,y+radio,color);
  408.      y+= incy;
  409.      color = ++color %16;
  410.       }// end while
  411.       y=100;
  412.       x +=incx;
  413.       color= ++color % 16;
  414.    }// end while
  415.    modo_planos();
  416.    getch();
  417.    set_video_mode(modo);
  418.    return(0);
  419. }
  420. #endif
  421.