25 Years of Programming
An open source source for C, C++, OWL, BASIC, MDB, XLS, DOT, and more...
Home   Projects   Up   Sitemap   Search   Blog   Forum+Chat   About Us   Privacy   Terms of Use   Feedback   FAQ   Images   Services   Payments   Humor   Music

Heathkit H-100 color graphics functions to draw basic shapes in DeSmet C

These are DeSmet C functions for the Heathkit H-100 computer that use my pset function to draw basic graphic shapes: line, rectangle (box), circle, oval.  

/* -------------------------------------------------------------- */
/* H100 COLOR GRAPHICS DRAWING FUNCTIONS */
/* Copyright (C)1993 Steven Whitney. Published under the */
/* GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY. */
/* Initially published by http://25yearsofprogramming.com. */
/* -------------------------------------------------------------- */
/*	LINE()	10-12-93  */
/*	Copyright (C)1993 Steven Whitney. Published under the */
/*	GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY. */
/*	Initially published by http://25yearsofprogramming.com. */
/*	DRAWS A LINE IN COLOR */
/*	USES PSET(), WHICH WILL IGNORE OUT-OF-BOUNDS REQUESTS */
/*	12-5-93 TOOK DOUBLES & DOUBLE MATH OUT OF LOOP: 77% SPEED IMPROVEMENT, */
/*			EVEN THOUGH LONGS ARE USED */
/*	12-7-93	SUPPORTS NEW PSET() */
/* -------------------------------------------------------------- */
#define	MAX(a,b)	((a) < (b)? (b) : (a))
#define MIN(a,b)	((a) < (b)? (a) : (b))
int line(x1,y1,x2,y2,psetmode,color)
int x1, y1, x2, y2, color;
char psetmode;					
{
int x, y, lastx, lasty, i;
double angle, xrange, yrange, sin(), cos(), atan();
long sine, cosine, dx, dy, longx1, longy1;

				/* COULD BE SPED UP BY POKING ENTIRE BYTES FOR MIDDLE OF LINE */
if(y1 == y2)	/* HORIZONTAL LINE, ALWAYS DRAWS LEFT TO RIGHT */
{	
	if(x1 > x2)				/* LINE MUST START WITH THE LEFTMOST POINT */
	{
		i = x2; x2 = x1; x1 = i;					/* SWAP X1 & X2 */
	}
							/* DRAWING OFF SCREEN WASTES TIME */
	x1 = MAX(x1,-1);		/* MUST BE -1 & 640 BECAUSE IF YOU USE */
	x1 = MIN(x1,640);		/* 0,639, A LINE ENTIRELY OFF THE SCREEN */
	x2 = MIN(x2,640);		/* WILL RESULT IN A POINT BEING SET */
	x2 = MAX(x2,-1);		/* AT THE EDGE OF THE SCREEN */
	while(x1 <= x2)
		pset(x1++,y1,psetmode,color);
	return 1;
}
if(x1 == x2)	/* VERTICAL LINE, ALWAYS DRAWS TOP TO BOTTOM */
{
	if(y1 > y2)
	{
		i = y2; y2 = y1; y1 = i;					/* SWAP Y1 & Y2 */
	}
	y1 = MAX(y1,-1);
	y1 = MIN(y1,225);
	y2 = MIN(y2,225);
	y2 = MAX(y2,-1);
	while(y1 <= y2)
		pset(x1,y1++,psetmode,color);
	return 1;
}
				/* (ALLOW SLANTED LINE TO DRAW OFF SCREEN SO ANGLE IS CORRECT) */
if(x1 > x2)		/* START WITH THE LEFTMOST POINT */
{
	i = x2 ; x2 = x1 ; x1 = i ;					/* SWAP X1 & X2 */
	i = y2 ; y2 = y1 ; y1 = i ;					/* SWAP Y1 & Y2 */
}
xrange = (double)(x2 - x1);
yrange = (double)(y2 - y1);
angle = atan(yrange / xrange);
cosine = (long)(cos(angle) * 10000. + .5);  	 /* +.5 IS FOR ROUNDING */
sine = (long)(sin(angle) * 10000. + .5);

longx1 = (long)x1;
longy1 = (long)y1;
dx = dy = 0L;
x = x1;
lastx = lasty = -1;		/* SET TO IMPOSSIBLE VALUE, OR AT LEAST OFF SCREEN */
while(x < x2)			/* WHEN X == X2, POINT HAS ALREADY BEEN SET */
{
	x = (int)(longx1 + (dx / 10000L));
	y = (int)(longy1 + (dy / 10000L));	
	if((x != lastx) || (y != lasty))		/* DISALLOW DUPLICATE POINTS */
	{										/* SO XPSET WORKS PROPERLY */
		pset(x,y,psetmode,color);				
		lastx = x;
		lasty = y;	
	}
	dx += cosine;
	dy += sine;	
}												
return 1;
}

/* -------------------------------------------------------------- */
/*	BOX()	5-9-93 10-12-93 */
/*	Copyright (C)1993 Steven Whitney. Published under the */
/*	GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY. */
/*	Initially published by http://25yearsofprogramming.com. */
/*	DRAWS A BOX AND OPTIONALLY FILLS IT */
/*	12-5-93 SUPPORTS NEW LINE(), NEW PSET() */
/*	12-7-93 DRAWS CLOCKWISE FROM UPPER LEFT */
/*			(ALTHOUGH LINE DRAWS LEFT TO RIGHT AND TOP TO BOTTOM) */
/*			DOESN'T SET CORNERS TWICE, SO XPSET WORKS PROPERLY */
/* -------------------------------------------------------------- */
#define	MAX(a,b)	((a) < (b)? (b) : (a))
#define MIN(a,b)	((a) < (b)? (a) : (b))
int box(x1,y1,x2,y2,psetmode,color,fill)
int x1, y1, x2, y2;
char psetmode;
int color;
int fill;					/* TRUE OR FALSE */
{
	int i, j, k, m;
	char csts(), ci();

	x1 = MAX(x1,-1);	/* DRAWING OFF SCREEN WASTES TIME - SEE LINE.C */
	x1 = MIN(x1,640);		
	y1 = MAX(y1,-1);
	y1 = MIN(y1,225);

	x2 = MAX(x2,-1);
	x2 = MIN(x2,640);		
	y2 = MAX(y2,-1);
	y2 = MIN(y2,225);

	if(x1 > x2)								/* MAKE SURE X1 IS LEFTMOST */
	{
		i = x2; x2 = x1; x1 = i;			/* SWAP */
	}
	if(y1 > y2)								/* MAKE SURE Y1 IS TOPMOST */
	{
		i = y2; y2 = y1; y1 = i;		
	}
	

	if(fill)
	{
		for(j = y1 ; j <= y2 ; j++)
		{
			if(csts())						/* ^C aborts */
				if(ci() == 3)
					return 1;
			for(i = x1 ; i <= x2 ; i++)
				pset(i,j,psetmode,color);
		}
	}
	else
	{
		line(x1,y1,x2-1,y1,psetmode,color);	/* UPPER LEFT TO UPPER RIGHT */
		line(x2,y1,x2,y2-1,psetmode,color);	/* UPPER RIGHT TO LOWER RIGHT */
		line(x1+1,y2,x2,y2,psetmode,color);	/* LOWER LEFT TO LOWER RIGHT */
		line(x1,y1+1,x1,y2,psetmode,color);	/* UPPER LEFT TO LOWER LEFT */
	}
	return 1;
}

/* -------------------------------------------------------------- */
/*	CIRCLE()	5-1-93 	DRAWS A CIRCLE */
/*	Copyright (C)1993 Steven Whitney. Published under the */
/*	GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY. */
/*	Initially published by http://25yearsofprogramming.com. */
/*	5-24-93 PLOT 8 POINTS AT ONCE INSTEAD OF 4: 3 TIMES FASTER! */
/*			CAN DRAW OVALS */
/*	IF ASPECT == 1., RADIUS IS MEASURED IN X UNITS */
/*	IF ASPECT < 1., OVAL WILL BE HORIZONTAL, AND */
/*		RADIUS WILL BE MEASURED IN X-AXIS POINTS, */
/*		WITH Y AXIS SCALED SMALLER (& SCALED AGAIN TO BE PROPORTIONAL) */
/*	IF ASPECT > 1., OVAL WILL BE VERTICAL, AND */
/*		RADIUS WILL BE MEASURED IN TRUE Y-AXIS UNITS, */
/*		WITH X AXIS SCALED SMALLER */
/*	RETURNS TRUE IF SUCCEED, FALSE IF FAIL */
/*	12-5-93 SUPPORTS NEW PSET() */
/*	12-7-93 DUPLICATE POINTS DISALLOWED, SO XPSET WORKS REASONABLY WELL, */
/*			BUT AXIS INTERCEPTS STILL GET SET TWICE & LEAVE HOLES, AND */
/*			WITH SOME CIRCLE SIZES, PLOTTED POINTS FROM DIFFERENT SEGMENTS */
/*			OVERLAP AND CAN'T BE TESTED WITH LASTX/Y */
/*			NOT WORTH WORKING ON ANY MORE, BUT LEFT IN SOME OF THE CODE */
/*	5-9-94	READJUSTED ADJUSTMENT FACTOR FOR X/Y SCREEN DOTS PER INCH */
/*			ADDED ^C TEST */
/* -------------------------------------------------------------- */
#define TRUE	1
#define FALSE	0
#define	MAX(a,b)	((a) < (b)? (b) : (a))
int circle(x0,y0,radius,psetmode,color,aspect)
int x0, y0, radius, color;
double aspect;					/* MUST HAVE A DECIMAL WHEN CALLED! */
char psetmode;
{
double i, step, angle, xradius, yradius, sine, cosine, sin(), cos();
char csts(), ci();
int dx, dy, ex, ey;
int x1, x2, x3, x4, lastx1, lastx2, lastx3, lastx4;
int y1, y2, y3, y4, lasty1, lasty2, lasty3, lasty4;
/*
INT FIRSTPASS = TRUE;
*/

if((aspect == 0.) || (color < 0) || (color > 7))
	return(FALSE);

xradius = yradius = (double)(abs(radius));

/* X AXIS = 640 DOTS / 10.25" DISPLAY AREA = 62.439 DPI */
/* Y AXIS = 225 DOTS / 7.5" DISPLAY AREA = 30.0 DPI */
	

if(aspect == 1.)					 
	yradius *= 0.48046875;		 /* RATIO DOTS/INCH IN X & Y AXES */

if(aspect < 1.)									/* HORIZ. OVAL */
	yradius = aspect * xradius * 0.48046875;	/* MEASURED IN X UNITS */

if(aspect > 1.)										/* VERT. OVAL */
	xradius = (1./aspect) * yradius / 0.48046875;	/* MEASURED IN Y */

lastx1 = lastx2 = lastx3 = lastx4 = -1;		/* SET TO IMPOSSIBLE, */
lasty1 = lasty2 = lasty3 = lasty4 = -1;		/* OR AT LEAST OFF SCREEN */

											/* THE 80. CAN BE ADJUSTED */
step = 50./(MAX(xradius,yradius));			/* < FOR RESOLUTION */
for(i = 0. ; i <= 45. ; i += step )			/* OR > FOR GREATER SPEED */
{										
	if(csts())								/* ^C ABORTS */
		if(ci() == 3)						/* USEFUL FOR PARTIAL CIRCLES */
			return 1;

	angle = i * .0174532925;				/* .0174 = 180/PI */	
	sine = sin(angle);
	cosine = cos(angle);

	dx = (int)(xradius * cosine + .5);
	ex = (int)(yradius * cosine + .5);

	dy = (int)(yradius * sine + .5);
	ey = (int)(xradius * sine + .5);

	x1 = x0 + dx;
	x2 = x0 - dx;
	x3 = x0 + ey;
	x4 = x0 - ey;

	y1 = y0 + dy;
	y2 = y0 - dy;
	y3 = y0 + ex;
	y4 = y0 - ex;
										/* INTENTIONALLY SET 4 AXIS POINTS */
										/* SO WHEN THEY'RE SET AGAIN, */
										/* THEY'LL COME OUT RIGHT */
/*
	IF(FIRSTPASS)			
	{							
		PSET(X1,Y0,PSETMODE,COLOR);		 2 OF THESE WORKED,
		PSET(X2,Y0,PSETMODE,COLOR);		 DON'T KNOW WHICH
		PSET(X0,Y1,PSETMODE,COLOR);
		PSET(X0,Y2,PSETMODE,COLOR);
		FIRSTPASS = FALSE;
	}
*/
										/* DISALLOW DUPLICATE POINT SETTING, */
										/* SO XPSET WILL WORK PROPERLY */
										/* PLOT POINTS USING */
										/* COS FOR X, SIN FOR Y */
	if((x1 != lastx1) || (y1 != lasty1))
		pset(x1,y1,psetmode,color);	
	if((x2 != lastx2) || (y2 != lasty2))
		pset(x2,y2,psetmode,color);	
	if((x1 != lastx1) || (y2 != lasty2))
		pset(x1,y2,psetmode,color);
	if((x2 != lastx2) || (y1 != lasty1))
		pset(x2,y1,psetmode,color);

	lastx1 = x1;
	lastx2 = x2;
	lasty1 = y1;
	lasty2 = y2;
												/* DERIVE EXTRA SET OF */
												/* POINTS, USING SIN */
												/* FOR X, COS FOR Y */
	if((x3 != lastx3) || (y3 != lasty3))
		pset(x3,y3,psetmode,color);
	if((x4 != lastx4) || (y4 != lasty4))
		pset(x4,y4,psetmode,color);		
	if((x3 != lastx3) || (y4 != lasty4))
		pset(x3,y4,psetmode,color);
	if((x4 != lastx4) || (y3 != lasty3))
		pset(x4,y3,psetmode,color);

	lastx3 = x3;
	lastx4 = x4;
	lasty3 = y3;
	lasty4 = y4;
}
return(TRUE);
}

 

 

Valid HTML 4.01 Transitional Valid CSS
Yahoo! Search
Search the web Search this site
View content labeling at ICRA.