home *** CD-ROM | disk | FTP | other *** search
/ Game Developers Magazine 2 / GDM002.ZIP / SOURCE / LINEDRAW.C < prev    next >
C/C++ Source or Header  |  1993-11-09  |  4KB  |  182 lines

  1. // LINEDRAW.C - General Line Drawing
  2.  
  3. // Written by Phil Inch for Game Developers Magazine (issue 2).
  4. // Contributed to the public domain.
  5.  
  6. // This program written and compiled with Borland C++ v3.1
  7. // Compatibility with other compilers is not guaranteed.
  8.  
  9. // Usage of this program is subject to the disclaimer printed
  10. // in the magazine.  You assume all risks associated with the use
  11. // of this program.
  12.  
  13. // Note to experienced C programmers: I'm deliberately using 'double'
  14. // instead of 'int' to exaggerate the optimisation.  I don't know if
  15. // other languages optimise integer calculations as well as C does
  16. // so by doing this I hope to present a more general result.
  17.  
  18.  
  19.  
  20. #include <stdio.h>
  21. #include <conio.h>
  22. #include <stdlib.h>
  23. #include <time.h>
  24. #include <dos.h>
  25.  
  26.  
  27.  
  28. // Routine to swap to integers
  29. void swap( int a, int b ) {
  30.     int temp;
  31.     temp = a;
  32.     a = b;
  33.     b = temp;
  34. }
  35.  
  36.  
  37. // Routine to put screen into mode 13h
  38. void set_mode_13h( void ) {
  39.     asm {
  40.         mov ax,0x13
  41.         int 0x10
  42.         }
  43. }
  44.  
  45.  
  46. // Routine to put screen into mode 3h (text mode)
  47. void set_text_mode( void ) {
  48.     asm {
  49.         mov ax,0x03
  50.         int 0x10
  51.         }
  52. }
  53.  
  54.  
  55. // Fast horizontal line drawing program
  56. void fast_horizontal_line( int x1, int x2, int y, unsigned char colour ) {
  57.     char far *screen_location;
  58.     int xcount;
  59.  
  60.     screen_location = MK_FP( 0xA000, ((int)y*320) + (int)x1 );
  61.     for ( xcount = x1; xcount <= x2; xcount++ ) {
  62.         *screen_location = colour;
  63.         screen_location++;
  64.         }
  65. }
  66.  
  67. // Fast vertical line drawing program
  68. void fast_vertical_line( int x, int y1, int y2, unsigned char colour ) {
  69.     char far *screen_location;
  70.     int ycount;
  71.  
  72.     screen_location = MK_FP( 0xA000, (int)x + ((int)y1*320) );
  73.     for ( ycount = y1; ycount <= y2; ycount++ ) {
  74.         *screen_location = colour;
  75.         screen_location += 320;
  76.         }
  77. }
  78.  
  79.  
  80. // Pixel plotting routine
  81. void plot_pixel( int x, int y, unsigned char colour ) {
  82.     unsigned char far *screen_position;
  83.  
  84.     screen_position = MK_FP( 0xA000, x + (320*y) );
  85.     *screen_position = colour;
  86. }
  87.  
  88.  
  89. // General line-drawing algorithm
  90. void draw_line( int x1, int y1, int x2, int y2, unsigned char colour ) {
  91.     double xstep, ystep, x, y;
  92.     int xlength, ylength, xcount, ycount;
  93.  
  94.     xlength = abs( x2 - x1 );
  95.     ylength = abs( y2 - y1 );
  96.  
  97.     if ( xlength == 0 ) // Vertical Line
  98.         fast_vertical_line( x1, y1, y2, colour );
  99.  
  100.     else if ( ylength == 0 ) // Horizontal Line
  101.         fast_horizontal_line( x1, x2, y1, colour );
  102.  
  103.     else if ( xlength > ylength ) {
  104.         if ( x1 > x2 ) {
  105.             swap( x1, x2 );
  106.             swap( y1, y2 );
  107.             }
  108.  
  109.         ystep = (double)( y2 - y1 ) / (double)( x2 - x1 );
  110.         y = y1;
  111.  
  112.         for ( xcount = x1; xcount <= x2; xcount++ ) {
  113.             plot_pixel( xcount, (int)y, colour );
  114.             y += ystep;
  115.             }
  116.         }
  117.  
  118.     else {
  119.         if ( y1 > y2 ) {
  120.             swap( x1, x2 );
  121.             swap( y1, y2 );
  122.             }
  123.  
  124.         xstep = (double)( x2 - x1 ) / (double)( y2 - y1 );
  125.         x = x1;
  126.  
  127.         for ( ycount = y1; ycount <= y2; ycount++ ) {
  128.             plot_pixel( (int)x, ycount, colour );
  129.             x += xstep;
  130.             }
  131.         }
  132. }
  133.  
  134.  
  135.  
  136. // This is where the program first starts
  137. void main( void ) {
  138.     int x1, x2, y1, y2;
  139.     long lines, number_of_lines;
  140.     unsigned char colour;
  141.     char input[80];
  142.  
  143.     clrscr();
  144.  
  145.     printf( "*** GENERAL LINE DRAWING DEMO ***\n\n" );
  146.  
  147.     printf( "Suggestions for number of lines:\n\n" );
  148.     printf( "486/50:  25000\n" );
  149.     printf( "486/33:  10000\n" );
  150.     printf( "486/25:   5000\n" );
  151.     printf( "386/40:    500\n" );
  152.     printf( "386/33:    200\n" );
  153.     printf( "lower :    100\n\n" );
  154.  
  155.     printf( "Enter number of lines to draw: " );
  156.     gets( input );
  157.  
  158.     number_of_lines = atol(input);
  159.     if ( number_of_lines <= 0 ) {
  160.         printf( "That's not a valid number!" );
  161.         exit(1);
  162.         }
  163.  
  164.     set_mode_13h();
  165.  
  166.     for ( lines = 0; lines < number_of_lines; lines++ ) {
  167.         x1 = rand()%320;        // 0 <= x1 <= 319
  168.         y1 = rand()%200;            // 0 <= y1 <= 199
  169.         x2 = rand()%320;        // 0 <= x2 <= 319
  170.         y2 = rand()%200;            // 0 <= y2 <= 199
  171.         colour = rand()%256;        // 0 <= colour <= 255
  172.         draw_line( x1, y1, x2, y2, colour );
  173.         }
  174.  
  175.     gotoxy( 8, 12 ); puts( "                          " );
  176.     gotoxy( 8, 13 ); puts( " Press <space> to exit... " );
  177.     gotoxy( 8, 14 ); puts( "                          " );
  178.     getch();
  179.  
  180.     set_text_mode();
  181. }
  182.