home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
POINT Software Programming
/
PPROG1.ISO
/
misc
/
pcgame
/
linedraw.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-09
|
4KB
|
182 lines
// LINEDRAW.C - General Line Drawing
// Written by Phil Inch for Game Developers Magazine (issue 2).
// Contributed to the public domain.
// This program written and compiled with Borland C++ v3.1
// Compatibility with other compilers is not guaranteed.
// Usage of this program is subject to the disclaimer printed
// in the magazine. You assume all risks associated with the use
// of this program.
// Note to experienced C programmers: I'm deliberately using 'double'
// instead of 'int' to exaggerate the optimisation. I don't know if
// other languages optimise integer calculations as well as C does
// so by doing this I hope to present a more general result.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <dos.h>
// Routine to swap to integers
void swap( int a, int b ) {
int temp;
temp = a;
a = b;
b = temp;
}
// Routine to put screen into mode 13h
void set_mode_13h( void ) {
asm {
mov ax,0x13
int 0x10
}
}
// Routine to put screen into mode 3h (text mode)
void set_text_mode( void ) {
asm {
mov ax,0x03
int 0x10
}
}
// Fast horizontal line drawing program
void fast_horizontal_line( int x1, int x2, int y, unsigned char colour ) {
char far *screen_location;
int xcount;
screen_location = MK_FP( 0xA000, ((int)y*320) + (int)x1 );
for ( xcount = x1; xcount <= x2; xcount++ ) {
*screen_location = colour;
screen_location++;
}
}
// Fast vertical line drawing program
void fast_vertical_line( int x, int y1, int y2, unsigned char colour ) {
char far *screen_location;
int ycount;
screen_location = MK_FP( 0xA000, (int)x + ((int)y1*320) );
for ( ycount = y1; ycount <= y2; ycount++ ) {
*screen_location = colour;
screen_location += 320;
}
}
// Pixel plotting routine
void plot_pixel( int x, int y, unsigned char colour ) {
unsigned char far *screen_position;
screen_position = MK_FP( 0xA000, x + (320*y) );
*screen_position = colour;
}
// General line-drawing algorithm
void draw_line( int x1, int y1, int x2, int y2, unsigned char colour ) {
double xstep, ystep, x, y;
int xlength, ylength, xcount, ycount;
xlength = abs( x2 - x1 );
ylength = abs( y2 - y1 );
if ( xlength == 0 ) // Vertical Line
fast_vertical_line( x1, y1, y2, colour );
else if ( ylength == 0 ) // Horizontal Line
fast_horizontal_line( x1, x2, y1, colour );
else if ( xlength > ylength ) {
if ( x1 > x2 ) {
swap( x1, x2 );
swap( y1, y2 );
}
ystep = (double)( y2 - y1 ) / (double)( x2 - x1 );
y = y1;
for ( xcount = x1; xcount <= x2; xcount++ ) {
plot_pixel( xcount, (int)y, colour );
y += ystep;
}
}
else {
if ( y1 > y2 ) {
swap( x1, x2 );
swap( y1, y2 );
}
xstep = (double)( x2 - x1 ) / (double)( y2 - y1 );
x = x1;
for ( ycount = y1; ycount <= y2; ycount++ ) {
plot_pixel( (int)x, ycount, colour );
x += xstep;
}
}
}
// This is where the program first starts
void main( void ) {
int x1, x2, y1, y2;
long lines, number_of_lines;
unsigned char colour;
char input[80];
clrscr();
printf( "*** GENERAL LINE DRAWING DEMO ***\n\n" );
printf( "Suggestions for number of lines:\n\n" );
printf( "486/50: 25000\n" );
printf( "486/33: 10000\n" );
printf( "486/25: 5000\n" );
printf( "386/40: 500\n" );
printf( "386/33: 200\n" );
printf( "lower : 100\n\n" );
printf( "Enter number of lines to draw: " );
gets( input );
number_of_lines = atol(input);
if ( number_of_lines <= 0 ) {
printf( "That's not a valid number!" );
exit(1);
}
set_mode_13h();
for ( lines = 0; lines < number_of_lines; lines++ ) {
x1 = rand()%320; // 0 <= x1 <= 319
y1 = rand()%200; // 0 <= y1 <= 199
x2 = rand()%320; // 0 <= x2 <= 319
y2 = rand()%200; // 0 <= y2 <= 199
colour = rand()%256; // 0 <= colour <= 255
draw_line( x1, y1, x2, y2, colour );
}
gotoxy( 8, 12 ); puts( " " );
gotoxy( 8, 13 ); puts( " Press <space> to exit... " );
gotoxy( 8, 14 ); puts( " " );
getch();
set_text_mode();
}