home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 15 / CDACTUAL15.iso / cdactual / program / asm / PJGRAPH.ZIP / CHAP13.2 < prev    next >
Encoding:
Text File  |  1989-09-26  |  6.4 KB  |  201 lines

  1. /* Sample program to illustrate VGA line drawing in 360x480
  2.  * 256-color mode.
  3.  *
  4.  * Compiled with Turbo C 2.0.
  5.  *
  6.  * Must be linked with Listing 13.1 with a command line like:
  7.  *
  8.  *    tcc lst13-2 lst13-1.asm
  9.  *
  10.  * By Michael Abrash.  6/2/89.
  11.  * Updated 6/30/89.
  12.  */
  13. #include <dos.h>                 /* contains geninterrupt */
  14.  
  15. #define TEXT_MODE       0x03
  16. #define BIOS_VIDEO_INT  0x10
  17. #define X_MAX           360      /* working screen width */
  18. #define Y_MAX           480      /* working screen height */
  19.  
  20. extern void Draw360x480Dot();
  21. extern void Set360x480Mode();
  22.  
  23. /*
  24.  * Draws a line in octant 0 or 3 ( |DeltaX| >= DeltaY ).
  25.  * |DeltaX|+1 points are drawn.
  26.  */
  27. void Octant0(X0, Y0, DeltaX, DeltaY, XDirection, Color)
  28. unsigned int X0, Y0;          /* coordinates of start of the line */
  29. unsigned int DeltaX, DeltaY;  /* length of the line */
  30. int XDirection;               /* 1 if line is drawn left to right,
  31.                                  -1 if drawn right to left */
  32. int Color;                    /* color in which to draw line */
  33. {
  34.    int DeltaYx2;
  35.    int DeltaYx2MinusDeltaXx2;
  36.    int ErrorTerm;
  37.  
  38.    /* Set up initial error term and values used inside drawing loop */
  39.    DeltaYx2 = DeltaY * 2;
  40.    DeltaYx2MinusDeltaXx2 = DeltaYx2 - (int) ( DeltaX * 2 );
  41.    ErrorTerm = DeltaYx2 - (int) DeltaX;
  42.  
  43.    /* Draw the line */
  44.    Draw360x480Dot(X0, Y0, Color);   /* draw the first pixel */
  45.    while ( DeltaX-- ) {
  46.       /* See if it's time to advance the Y coordinate */
  47.       if ( ErrorTerm >= 0 ) {
  48.          /* Advance the Y coordinate & adjust the error term
  49.             back down */
  50.          Y0++;
  51.          ErrorTerm += DeltaYx2MinusDeltaXx2;
  52.       } else {
  53.          /* Add to the error term */
  54.          ErrorTerm += DeltaYx2;
  55.       }
  56.       X0 += XDirection;          /* advance the X coordinate */
  57.       Draw360x480Dot(X0, Y0, Color);    /* draw a pixel */
  58.    }
  59. }
  60.  
  61. /*
  62.  * Draws a line in octant 1 or 2 ( |DeltaX| < DeltaY ).
  63.  * |DeltaY|+1 points are drawn.
  64.  */
  65. void Octant1(X0, Y0, DeltaX, DeltaY, XDirection, Color)
  66. unsigned int X0, Y0;          /* coordinates of start of the line */
  67. unsigned int DeltaX, DeltaY;  /* length of the line */
  68. int XDirection;               /* 1 if line is drawn left to right,
  69.                                  -1 if drawn right to left */
  70. int Color;                    /* color in which to draw line */
  71. {
  72.    int DeltaXx2;
  73.    int DeltaXx2MinusDeltaYx2;
  74.    int ErrorTerm;
  75.  
  76.    /* Set up initial error term and values used inside drawing loop */
  77.    DeltaXx2 = DeltaX * 2;
  78.    DeltaXx2MinusDeltaYx2 = DeltaXx2 - (int) ( DeltaY * 2 );
  79.    ErrorTerm = DeltaXx2 - (int) DeltaY;
  80.  
  81.    Draw360x480Dot(X0, Y0, Color);    /* draw the first pixel */
  82.    while ( DeltaY-- ) {
  83.       /* See if it's time to advance the X coordinate */
  84.       if ( ErrorTerm >= 0 ) {
  85.          /* Advance the X coordinate & adjust the error term
  86.             back down */
  87.          X0 += XDirection;
  88.          ErrorTerm += DeltaXx2MinusDeltaYx2;
  89.       } else {
  90.          /* Add to the error term */
  91.          ErrorTerm += DeltaXx2;
  92.       }
  93.       Y0++;                   /* advance the Y coordinate */
  94.       Draw360x480Dot(X0, Y0,Color);  /* draw a pixel */
  95.    }
  96. }
  97.  
  98. /*
  99.  * Draws a line on the EGA or VGA.
  100.  */
  101. void EVGALine(X0, Y0, X1, Y1, Color)
  102. int X0, Y0;    /* coordinates of one end of the line */
  103. int X1, Y1;    /* coordinates of the other end of the line */
  104. unsigned char Color;    /* color in which to draw line */
  105. {
  106.    int DeltaX, DeltaY;
  107.    int Temp;
  108.  
  109.    /* Save half the line-drawing cases by swapping Y0 with Y1
  110.       and X0 with X1 if Y0 is greater than Y1. As a result, DeltaY
  111.       is always > 0, and only the octant 0-3 cases need to be
  112.       handled. */
  113.    if ( Y0 > Y1 ) {
  114.       Temp = Y0;
  115.       Y0 = Y1;
  116.       Y1 = Temp;
  117.       Temp = X0;
  118.       X0 = X1;
  119.       X1 = Temp;
  120.    }
  121.  
  122.    /* Handle as four separate cases, for the four octants in which
  123.       Y1 is greater than Y0 */
  124.    DeltaX = X1 - X0;    /* calculate the length of the line
  125.                            in each coordinate */
  126.    DeltaY = Y1 - Y0;
  127.    if ( DeltaX > 0 ) {
  128.       if ( DeltaX > DeltaY ) {
  129.          Octant0(X0, Y0, DeltaX, DeltaY, 1, Color);
  130.       } else {
  131.          Octant1(X0, Y0, DeltaX, DeltaY, 1, Color);
  132.       }
  133.    } else {
  134.       DeltaX = -DeltaX;             /* absolute value of DeltaX */
  135.       if ( DeltaX > DeltaY ) {
  136.          Octant0(X0, Y0, DeltaX, DeltaY, -1, Color);
  137.       } else {
  138.          Octant1(X0, Y0, DeltaX, DeltaY, -1, Color);
  139.       }
  140.    }
  141. }
  142.  
  143. /*
  144.  * Subroutine to draw a rectangle full of vectors, of the
  145.  * specified length and in varying colors, around the
  146.  * specified rectangle center.
  147.  */
  148. void VectorsUp(XCenter, YCenter, XLength, YLength)
  149. int XCenter, YCenter;   /* center of rectangle to fill */
  150. int XLength, YLength;   /* distance from center to edge
  151.                            of rectangle */
  152. {
  153.    int WorkingX, WorkingY, Color = 1;
  154.  
  155.    /* Lines from center to top of rectangle */
  156.    WorkingX = XCenter - XLength;
  157.    WorkingY = YCenter - YLength;
  158.    for ( ; WorkingX < ( XCenter + XLength ); WorkingX++ )
  159.       EVGALine(XCenter, YCenter, WorkingX, WorkingY, Color++);
  160.  
  161.    /* Lines from center to right of rectangle */
  162.    WorkingX = XCenter + XLength - 1;
  163.    WorkingY = YCenter - YLength;
  164.    for ( ; WorkingY < ( YCenter + YLength ); WorkingY++ )
  165.       EVGALine(XCenter, YCenter, WorkingX, WorkingY, Color++);
  166.  
  167.    /* Lines from center to bottom of rectangle */
  168.    WorkingX = XCenter + XLength - 1;
  169.    WorkingY = YCenter + YLength - 1;
  170.    for ( ; WorkingX >= ( XCenter - XLength ); WorkingX-- )
  171.       EVGALine(XCenter, YCenter, WorkingX, WorkingY, Color++);
  172.  
  173.    /* Lines from center to left of rectangle */
  174.    WorkingX = XCenter - XLength;
  175.    WorkingY = YCenter + YLength - 1;
  176.    for ( ; WorkingY >= ( YCenter - YLength ); WorkingY-- )
  177.       EVGALine(XCenter, YCenter, WorkingX, WorkingY, Color++);
  178. }
  179.  
  180. /*
  181.  * Sample program to draw four rectangles full of lines.
  182.  */
  183. int main()
  184. {
  185.    char temp;
  186.  
  187.    Set360x480Mode();
  188.  
  189.    /* Draw each of four rectangles full of vectors */
  190.    VectorsUp(X_MAX / 4, Y_MAX / 4, X_MAX / 4, Y_MAX / 4, 1);
  191.    VectorsUp(X_MAX * 3 / 4, Y_MAX / 4, X_MAX / 4, Y_MAX / 4, 2);
  192.    VectorsUp(X_MAX / 4, Y_MAX * 3 / 4, X_MAX / 4, Y_MAX / 4, 3);
  193.    VectorsUp(X_MAX * 3 / 4, Y_MAX * 3 / 4, X_MAX / 4, Y_MAX / 4, 4);
  194.  
  195.    /* Wait for the enter key to be pressed */
  196.    scanf("%c", &temp);
  197.  
  198.    /* Back to text mode */
  199.    _AX = TEXT_MODE;
  200.    geninterrupt(BIOS_VIDEO_INT);
  201. }