home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / graphics / gl.pak / N_DRAW.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-31  |  7.2 KB  |  203 lines

  1. #ifndef lint
  2. static char sccsid[] = "@(#) n_draw.c 5.1 89/02/20";
  3. #endif
  4.  
  5. /*
  6.  *    Copyright (c) David T. Lewis 1987, 1988, 1989
  7.  *    All rights reserved.
  8.  *
  9.  *    Permission is granted to use this for any personal noncommercial use.
  10.  *    You may not distribute source or executable code for profit, nor
  11.  *    may you distribute it with a commercial product without the written
  12.  *    consent of the author.  Please send modifications to the author for
  13.  *    inclusion in updates to the program.  Thanks.
  14.  */
  15.  
  16. /*  Sat Mar 21 22:59:10 EST 1987 */
  17. /*  dtl 2-8-87
  18. **
  19. **    Write a line on the CGA or Hercules adapter.
  20. **    This routine assumes that the current graphics cursor position is
  21. **    set, and draws a line to the indicated point.
  22. */
  23.  
  24. #include "config.h"
  25. #include "bitmaps.h"
  26. #include "graphics.h"
  27. #include "gf_types.h"
  28.  
  29. #define ROT_MASK (0x80000000L)
  30.  
  31. extern struct GL_graphics graphics;
  32. extern int (*p_do_pix)();
  33.  
  34. n_draw(new_x_cursor,new_y_cursor)  
  35.     int new_x_cursor, new_y_cursor;
  36. {
  37.  
  38.         /* Draw line from current cursor to new position. */
  39.         /* Parameters are in normalized 2-D coordinates. */
  40.  
  41.         int x_dist;     /* Pixel coordinates */
  42.         int y_dist;     /* Pixel coordinates */
  43.         int x_start;    /* Pixel coordinates */
  44.         int y_start;    /* Pixel coordinates */
  45.         int x_final;     /* Pixel coordinates */
  46.         int y_final;     /* Pixel coordinates */
  47.         int x_current;  /* Pixel coordinates */
  48.         int y_current;  /* Pixel coordinates */
  49.     int x_pixels;    /* X distance in pixels */
  50.     int y_pixels;    /* Y distance in pixels */
  51.         long int slope;
  52.         int offset;
  53.         long int idx;
  54.  
  55.     /* Check for out of range.  If either the start or end    */
  56.     /* point would be off the screen, then we have a    */
  57.     /* problem.                        */
  58.  
  59. #if INT16
  60.     /* 16 bit integers, use simple check.            */
  61.     if (graphics.x_cursor < 0 || graphics.y_cursor < 0 || 
  62.         new_x_cursor < 0 || new_y_cursor < 0)
  63. #else
  64.     /* Use explicit check.                    */
  65.     if (    (graphics.x_cursor < 0) 
  66.         || (graphics.x_cursor > NRM_X_RANGE) 
  67.         || (graphics.y_cursor < 0) 
  68.         || (graphics.y_cursor > NRM_Y_RANGE) 
  69.         || (new_x_cursor < 0)
  70.         || (new_x_cursor > NRM_X_RANGE)
  71.         || (new_y_cursor < 0)
  72.         || (new_y_cursor > NRM_Y_RANGE))
  73. #endif /* INT16 */
  74.     {
  75.         /* Advance the cursor to the new position, even if    */
  76.         /* it is not a valid location.  In the case where the    */
  77.         /* current cursor is invalid but the new value is good,    */
  78.         /* this will correct the problem.  In the case where    */
  79.         /* the new value is bad, we will want to leave it that    */
  80.         /* way for the next invocation of n_draw().        */
  81.         graphics.x_cursor = new_x_cursor;
  82.         graphics.y_cursor = new_y_cursor;
  83.         return(1);
  84.     }
  85.  
  86.         /* Find the starting point in pixel coordinates. */
  87.   
  88.         x_current = x_start = n_to_p_x(graphics.x_cursor);
  89.         y_current = y_start = n_to_p_y(graphics.y_cursor);
  90.  
  91.         /* Find the end point in pixel coordinates. */
  92.   
  93.         x_final = n_to_p_x(new_x_cursor);
  94.         y_final = n_to_p_y(new_y_cursor);
  95.  
  96.     /* Find the distances in pixel coordinates. */
  97.  
  98.         x_dist = x_final - x_start;
  99.         y_dist = y_final - y_start;
  100.  
  101.     /* Find the number of pixels to travel in the x any y directions. */
  102.  
  103.     x_pixels = abs(x_dist);
  104.     y_pixels = abs(y_dist);
  105.  
  106.         /* Step across the screen pixel by pixel.  Do this in the x     */
  107.         /* direction if x_dist is greater than y_dist; else, do it in    */
  108.         /* the y direction.                        */
  109.  
  110.         if (x_pixels > y_pixels) {
  111.                 /* Stepwise in x direction. */
  112.  
  113.                 /* Calculate the slope to use (rise over run). */
  114.                 /* Shift left 16 bits for precision. */
  115.                 if (x_dist != 0) slope = (long)y_dist * 0x010000L / 
  116.                 (long)x_dist;
  117.                 else slope = 0x7FFFFFFFL; /* Infinity */
  118.  
  119.                 /* Figure a fudge factor to be used in offsetting the */
  120.                 /* pixels by 1/2 pixel. */
  121.                 if (slope > 0) offset = 1;
  122.                 else if (slope < 0) offset = -1;
  123.                 else offset = 0;
  124.  
  125.                 /* Write the line on the screen. */
  126.  
  127.                 if (x_final - x_start >= 0)  {
  128.                         if (slope==0)  {
  129.                                 while (x_current <= x_final)
  130.                     if ((*p_do_pix)(x_current++, 
  131.                         y_current)) return(1);
  132.                         }
  133.                         else for (idx=0; idx <= x_pixels; idx++, x_current++)  {
  134.                                 y_current = y_start + (idx*slope/0x08000L 
  135.                                 + offset)/2;
  136.                                 if ((*p_do_pix)(x_current, y_current))
  137.                     return(1);
  138.                         }
  139.                 }
  140.                 else  {
  141.                         if (slope==0)  {
  142.                 while (x_current >= x_final)
  143.                                         if ((*p_do_pix)(x_current--, 
  144.                         y_current)) return(1);
  145.                         }
  146.                         else for (idx=0; idx <= x_pixels; idx++, x_current--)  {
  147.                                 y_current = y_start - (idx*slope/0x08000L 
  148.                                 + offset)/2;
  149.                                 if ((*p_do_pix)(x_current, y_current)) 
  150.                     return(1);
  151.                         }
  152.                 }
  153.         }
  154.         else  {
  155.                 /* Stepwise in y direction. */
  156.  
  157.                 /* Calculate the inverse slope to use (run over rise). */
  158.                 /* Shift left 16 bits for precision. */
  159.                 if (y_dist != 0) slope = (long)x_dist * 0x010000L / 
  160.                 (long)y_dist;
  161.                 else slope = 0x7FFFFFFF; /* Infinity */
  162.  
  163.                 /* Figure a fudge factor to be used in offsetting the */
  164.                 /* pixels by 1/2 pixel. */
  165.                 if (slope > 0) offset = 1;
  166.                 else if (slope < 0) offset = -1;
  167.                 else offset = 0;
  168.  
  169.                /* Write the line on the screen. */
  170.  
  171.                 if (y_final - y_start >= 0)  {
  172.                         if (slope==0)  {
  173.                                 while (y_current <= y_final)
  174.                                         if ((*p_do_pix)(x_current, 
  175.                         y_current++)) return(1);
  176.                         }
  177.                         else for (idx=0; idx <= y_pixels; idx++, y_current++)  {
  178.                                 x_current = x_start + (idx*slope/0x08000L 
  179.                                 + offset)/2;
  180.                                 if ((*p_do_pix)(x_current, y_current))
  181.                     return(1);
  182.                         }
  183.                 }
  184.                 else  {
  185.                         if (slope==0)  {
  186.                 while (y_current >= y_final)
  187.                                         if ((*p_do_pix)(x_current, 
  188.                         y_current--)) return(1);
  189.                         }
  190.                         else for (idx=0; idx <= y_pixels; idx++, y_current--)  {
  191.                                 x_current = x_start - (idx*slope/0x08000L 
  192.                                 + offset)/2;
  193.                                 if ((*p_do_pix)(x_current, y_current))
  194.                     return(1);
  195.                         }
  196.                 }
  197.         }
  198.         /* Advance the cursor to the new position. */
  199.         graphics.x_cursor = new_x_cursor;
  200.         graphics.y_cursor = new_y_cursor;
  201.     return(0);
  202. }
  203.