home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / 2d / line.c < prev    next >
Text File  |  1998-06-08  |  8KB  |  349 lines

  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  12. */
  13. /*
  14.  * $Source: f:/miner/source/2d/rcs/line.c $
  15.  * $Revision: 1.10 $
  16.  * $Author: john $
  17.  * $Date: 1994/11/18 22:50:02 $
  18.  *
  19.  * Graphical routines for drawing lines.
  20.  *
  21.  * $Log: line.c $
  22.  * Revision 1.10  1994/11/18  22:50:02  john
  23.  * Changed shorts to ints in parameters.
  24.  * 
  25.  * Revision 1.9  1994/07/13  12:03:04  john
  26.  * Added assembly modex line-drawer.
  27.  * 
  28.  * Revision 1.8  1993/12/06  18:18:03  john
  29.  * took out aaline.
  30.  * 
  31.  * Revision 1.7  1993/12/03  12:11:17  john
  32.  * ,
  33.  * 
  34.  * Revision 1.6  1993/11/18  09:40:22  john
  35.  * Added laser-line
  36.  * 
  37.  * Revision 1.5  1993/10/15  16:23:36  john
  38.  * y
  39.  * 
  40.  * Revision 1.4  1993/09/29  16:13:58  john
  41.  * optimized
  42.  * 
  43.  * Revision 1.3  1993/09/26  18:44:12  matt
  44.  * Added gr_uline(), which just calls gr_line(), and made both take
  45.  * fixes, and shift down themselves.
  46.  * 
  47.  * Revision 1.2  1993/09/11  19:50:15  matt
  48.  * In gr_vline() & gr_hline(), check for start > end, and EXCHG if so
  49.  * 
  50.  * Revision 1.1  1993/09/08  11:43:54  john
  51.  * Initial revision
  52.  * 
  53.  *
  54.  */
  55.  
  56. #include <stdlib.h>
  57.  
  58. #include "mem.h"
  59.  
  60. #include "gr.h"
  61. #include "grdef.h"
  62. #include "fix.h"
  63.  
  64. #include "clip.h"
  65.  
  66. extern void gr_modex_line();
  67. int modex_line_vertincr;
  68. int modex_line_incr1;
  69. int modex_line_incr2;        
  70. int modex_line_x1;        
  71. int modex_line_y1;        
  72. int modex_line_x2;        
  73. int modex_line_y2;        
  74. ubyte modex_line_Color;
  75.  
  76. /*
  77. Symmetric Double Step Line Algorithm
  78. by Brian Wyvill
  79. from "Graphics Gems", Academic Press, 1990
  80. */
  81.  
  82. /* non-zero flag indicates the pixels needing EXCHG back. */
  83. void plot(int x,int y,int flag)
  84. {   if (flag)
  85.         gr_upixel(y, x);
  86.     else
  87.         gr_upixel(x, y);
  88. }
  89.  
  90. int gr_hline(int x1, int x2, int y)
  91. {   int i;
  92.  
  93.     if (x1 > x2) EXCHG(x1,x2);
  94.     for (i=x1; i<=x2; i++ )
  95.         gr_upixel( i, y );
  96.     return 0;
  97. }
  98.  
  99. int gr_vline(int y1, int y2, int x)
  100. {   int i;
  101.     if (y1 > y2) EXCHG(y1,y2);
  102.     for (i=y1; i<=y2; i++ )
  103.         gr_upixel( x, i );
  104.     return 0;
  105. }
  106.  
  107. void gr_universal_uline(int a1, int b1, int a2, int b2)
  108. {
  109.     int dx, dy, incr1, incr2, D, x, y, xend, c, pixels_left;
  110.     int x1, y1;
  111.     int sign_x = 1, sign_y = 1, step, reverse, i;
  112.  
  113.     if (a1==a2) {
  114.         gr_vline(b1,b2,a1);
  115.         return;
  116.     }
  117.  
  118.     if (b1==b2) {
  119.         gr_hline(a1,a2,b1);
  120.         return;
  121.     }
  122.  
  123.     dx = a2 - a1;
  124.     dy = b2 - b1;
  125.  
  126.     if (dx < 0) {
  127.         sign_x = -1;
  128.         dx *= -1;
  129.     }
  130.     if (dy < 0) {
  131.         sign_y = -1;
  132.         dy *= -1;
  133.     }
  134.  
  135.     /* decide increment sign by the slope sign */
  136.     if (sign_x == sign_y)
  137.         step = 1;
  138.     else
  139.         step = -1;
  140.  
  141.     if (dy > dx) {          /* chooses axis of greatest movement (make * dx) */
  142.         EXCHG(a1, b1);
  143.         EXCHG(a2, b2);
  144.         EXCHG(dx, dy);
  145.         reverse = 1;
  146.     } else
  147.         reverse = 0;
  148.     /* note error check for dx==0 should be included here */
  149.     if (a1 > a2) {          /* start from the smaller coordinate */
  150.         x = a2;
  151.         y = b2;
  152.         x1 = a1;
  153.         y1 = b1;
  154.     } else {
  155.         x = a1;
  156.         y = b1;
  157.         x1 = a2;
  158.         y1 = b2;
  159.     }
  160.  
  161.  
  162.     /* Note dx=n implies 0 - n or (dx+1) pixels to be set */
  163.     /* Go round loop dx/4 times then plot last 0,1,2 or 3 pixels */
  164.     /* In fact (dx-1)/4 as 2 pixels are already plottted */
  165.     xend = (dx - 1) / 4;
  166.     pixels_left = (dx - 1) % 4;     /* number of pixels left over at the
  167.                                  * end */
  168.     plot(x, y, reverse);
  169.     plot(x1, y1, reverse);  /* plot first two points */
  170.     incr2 = 4 * dy - 2 * dx;
  171.     if (incr2 < 0) {        /* slope less than 1/2 */
  172.         c = 2 * dy;
  173.         incr1 = 2 * c;
  174.         D = incr1 - dx;
  175.  
  176.         for (i = 0; i < xend; i++) {    /* plotting loop */
  177.             ++x;
  178.             --x1;
  179.             if (D < 0) {
  180.                     /* pattern 1 forwards */
  181.                 plot(x, y, reverse);
  182.                 plot(++x, y, reverse);
  183.                 /* pattern 1 backwards */
  184.                 plot(x1, y1, reverse);
  185.                 plot(--x1, y1, reverse);
  186.                 D += incr1;
  187.             } else {
  188.                 if (D < c) {
  189.                     /* pattern 2 forwards */
  190.                     plot(x, y, reverse);
  191.                     plot(++x, y += step, reverse);
  192.                     /* pattern 2 backwards */
  193.                     plot(x1, y1, reverse);
  194.                     plot(--x1, y1 -= step, reverse);
  195.                 } else {
  196.                     /* pattern 3 forwards */
  197.                     plot(x, y += step, reverse);
  198.                     plot(++x, y, reverse);
  199.                     /* pattern 3 backwards */
  200.                     plot(x1, y1 -= step, reverse);
  201.                     plot(--x1, y1, reverse);
  202.                 }
  203.                 D += incr2;
  204.             }
  205.         }               /* end for */
  206.  
  207.         /* plot last pattern */
  208.         if (pixels_left) {
  209.             if (D < 0) {
  210.                 plot(++x, y, reverse);  /* pattern 1 */
  211.                 if (pixels_left > 1)
  212.                     plot(++x, y, reverse);
  213.                 if (pixels_left > 2)
  214.                     plot(--x1, y1, reverse);
  215.             } else {
  216.                 if (D < c) {
  217.                     plot(++x, y, reverse);  /* pattern 2  */
  218.                     if (pixels_left > 1)
  219.                         plot(++x, y += step, reverse);
  220.                     if (pixels_left > 2)
  221.                         plot(--x1, y1, reverse);
  222.                 } else {
  223.                   /* pattern 3 */
  224.                     plot(++x, y += step, reverse);
  225.                     if (pixels_left > 1)
  226.                         plot(++x, y, reverse);
  227.                     if (pixels_left > 2)
  228.                         plot(--x1, y1 -= step, reverse);
  229.                 }
  230.             }
  231.         }               /* end if pixels_left */
  232.     }
  233.     /* end slope < 1/2 */
  234.     else {                  /* slope greater than 1/2 */
  235.         c = 2 * (dy - dx);
  236.         incr1 = 2 * c;
  237.         D = incr1 + dx;
  238.         for (i = 0; i < xend; i++) {
  239.             ++x;
  240.             --x1;
  241.             if (D > 0) {
  242.               /* pattern 4 forwards */
  243.                 plot(x, y += step, reverse);
  244.                 plot(++x, y += step, reverse);
  245.               /* pattern 4 backwards */
  246.                 plot(x1, y1 -= step, reverse);
  247.                 plot(--x1, y1 -= step, reverse);
  248.                 D += incr1;
  249.             } else {
  250.                 if (D < c) {
  251.                   /* pattern 2 forwards */
  252.                     plot(x, y, reverse);
  253.                     plot(++x, y += step, reverse);
  254.  
  255.                   /* pattern 2 backwards */
  256.                     plot(x1, y1, reverse);
  257.                     plot(--x1, y1 -= step, reverse);
  258.                 } else {
  259.                   /* pattern 3 forwards */
  260.                     plot(x, y += step, reverse);
  261.                     plot(++x, y, reverse);
  262.                   /* pattern 3 backwards */
  263.                     plot(x1, y1 -= step, reverse);
  264.                     plot(--x1, y1, reverse);
  265.                 }
  266.                 D += incr2;
  267.             }
  268.         }               /* end for */
  269.         /* plot last pattern */
  270.         if (pixels_left) {
  271.             if (D > 0) {
  272.                 plot(++x, y += step, reverse);  /* pattern 4 */
  273.                 if (pixels_left > 1)
  274.                     plot(++x, y += step, reverse);
  275.                 if (pixels_left > 2)
  276.                     plot(--x1, y1 -= step, reverse);
  277.             } else {
  278.                 if (D < c) {
  279.                     plot(++x, y, reverse);  /* pattern 2  */
  280.                     if (pixels_left > 1)
  281.                         plot(++x, y += step, reverse);
  282.                     if (pixels_left > 2)
  283.                         plot(--x1, y1, reverse);
  284.                 } else {
  285.                   /* pattern 3 */
  286.                     plot(++x, y += step, reverse);
  287.                     if (pixels_left > 1)
  288.                         plot(++x, y, reverse);
  289.                     if (pixels_left > 2) {
  290.                         if (D > c) /* step 3 */
  291.                            plot(--x1, y1 -= step, reverse);
  292.                         else /* step 2 */
  293.                             plot(--x1, y1, reverse);
  294.                     }
  295.                 }
  296.             }
  297.         }
  298.     }
  299. }
  300.  
  301.  
  302. //unclipped version just calls clipping version for now
  303. int gr_uline(fix _a1, fix _b1, fix _a2, fix _b2)
  304. {
  305.     int a1,b1,a2,b2;
  306.     a1 = f2i(_a1); b1 = f2i(_b1); a2 = f2i(_a2); b2 = f2i(_b2);
  307.  
  308.     switch(TYPE)
  309.     {
  310.     case BM_LINEAR:
  311.         gr_linear_line( a1, b1, a2, b2 );
  312.         return 0;
  313.     case BM_MODEX:
  314.         modex_line_x1 = a1+XOFFSET;        
  315.         modex_line_y1 = b1+YOFFSET;        
  316.         modex_line_x2 = a2+XOFFSET;        
  317.         modex_line_y2 = b2+YOFFSET;        
  318.         modex_line_Color = grd_curcanv->cv_color;
  319.         gr_modex_line();
  320.         return 0;
  321.     default:
  322.         gr_universal_uline( a1, b1, a2, b2 );
  323.         return 0;
  324.     }
  325. }
  326.  
  327. // Returns 0 if drawn with no clipping, 1 if drawn but clipped, and
  328. // 2 if not drawn at all.
  329.  
  330. int gr_line(fix a1, fix b1, fix a2, fix b2)
  331. {
  332.     int x1, y1, x2, y2;
  333.     int clipped=0;
  334.  
  335.     x1 = i2f(MINX);
  336.     y1 = i2f(MINY);
  337.     x2 = i2f(MAXX);
  338.     y2 = i2f(MAXY);
  339.  
  340.     CLIPLINE(a1,b1,a2,b2,x1,y1,x2,y2,return 2,clipped=1, FSCALE );
  341.  
  342.     gr_uline( a1, b1, a2, b2 );
  343.  
  344.     return clipped;
  345.  
  346. }
  347.  
  348. 
  349.