File:  [OS/2 SDKs] / os2sdk / demos / apps / mandel / mandel.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 12:25:58 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: os2sdk-1988, HEAD
Microsoft OS/2 SDK 03-01-1988

/***	Mandel.c - compute and display Mandelbrot set
 *
 *  Created by Microsoft Corp. 1986
 */



/**	Mandel compute the elements of the Mandelbrot set
 *
 *		z = z**2 + c
 *
 *	where z and c are in the complex plane and z = 0 + 0i for the first
 *	iteration.  The elements of the set along with the description of the
 *	computation are written to the .cnt file.
 */




/**	Call
 *
 *	mandel -v {-u a+bi} {-l c+di} {-r num} {-c num} {-i itr} {-a f} {-f name}
 *		{-d display}
 *
 *	where
 *
 *		a	compute each point with an aspect ratio of f where
 *			f is :
 *				f.ffff	floating point number describing the
 *					ratio of width vs height of each pixel
 *
 *		c	number of points across the real coordinate.  This
 *			value cannot exceed 2000 and is defaulted to 640.
 *
 *		d	set display to device.	The default display is EGA.
 *				CGA	Color Graphics Adapter
 *					columns = 350
 *					rows	= 200
 *					aspect	= 2.4
 *
 *				EGA	Extended Graphics Adapter
 *					columns = 640
 *					rows	= 350
 *					aspect	= 2.4
 *
 *				PGA	Professional Graphics Adapter
 *					columns = 640
 *					rows	= 480
 *					aspect	= 1.0
 *
 *		f	name for the .cnt file
 *			If name is not specified, "mandel" is used.
 *
 *		i	iteration limit.  This value cannot exceed 1000 and
 *			the default is 256
 *
 *		l	lower right corner as c+di
 *
 *
 *		r	number of points down the imaginary coordinate.  This
 *			value is defaulted to 350.
 *
 *		u	upper left corner as a+bi
 *
 *		v	display information about each scan line as processed
 *
 *	The .cnt file has the format
 *		int	number of points along the real axis
 *		int	number of points along the imaginary axis
 *		int	maximum iteration point for each point
 *		double	real coordinate of upper left
 *		double	imaginary coordinate of upper left
 *		double	real coordinate of lower right
 *		double	imaginary coordinate lower rightft
 *		long	(loop + 1) counters for histogram values
 */

#define  INCL_DOSDEVICES

#include <os2def.h>
#include <stdio.h>
#include <bsedos.h>

int mandinter ();

#define MAXREAL 2000		/* maximum number of points in line */
#define MAXLOOP 1000		/* maximum number of iterations */

#define CGA_DEV 0		/* Color Graphics Adapter */
#define CGA_COL 350		/* number of display columns for CGA */
#define CGA_ROW 200		/* number of display rows for CGA */
#define CGA_ASP 12/5		/* aspect ratio (width/height) for CGA */

#define EGA_DEV 1		/* Extended Graphics Adapter */
#define EGA_COL 640		/* number of display columns for EGA */
#define EGA_ROW 350		/* number of display rows for EGA */
#define EGA_ASP 1.33		/* aspect ratio (width/height) for EGA */

#define PGA_DEV 2		/* Professional Graphics Adapter */
#define PGA_COL 640		/* number of display columns for PGA */
#define PGA_ROW 480		/* number of display rows for PGA */
#define PGA_ASP 1.0		/* aspect ratio (width/height) for PGA */


struct cmplx {
	double	 realp; 	/* real part of number */
	double	 imagp; 	/* imaginary part of number */
};



char	fp287;			/* 287 processor status from DosDevConfig */
char	 pmand[60] = "mandel.cnt"; /* file name for loop counts */
FILE	*fmand;

double	rinc;			/* increment in real coordinate */
double	iinc;			/* increment in imaginary coordinate */

int	device = EGA_DEV;	/* default device type */
int	arg_device = -1;	/* device type from arguments */
int	mcount[MAXREAL];	/* array holding interation counters */
int	rlcount[MAXREAL + 2];	/* run length encoded interation counters */
int	nreal = EGA_COL;	/* number of points on real coordinate */
int	arg_nreal = 0;		/* number real coordinate from arguments */
int	nimag = EGA_ROW;	/* number of points on imaginary coordinate */
int	arg_nimag = 0;		/* number imaginary coordinate from arguments */
int	loop = 256;		/* maximum loop count for each point */
int	verbose = FALSE;	/* display scan line information if true */
double	aspect = EGA_ASP;	/* default screen aspect ratio */
double	arg_aspect = 0.0;	/* aspect from arguments */

long	hist[MAXLOOP + 1] = {0}; /* histogram counters */

struct	cmplx c;		/* value of mandelbrot seed */
struct	cmplx ul;		/* coordinates of upper left corner */
struct	cmplx lr;		/* coordinates of lower right corner */


main (argc, argv)
int	argc;
char	**argv;
{
	int	nr;
	int	ni;
	int	i;
	int	temp;
	int    *rl;
	long	position;

	if (DosDevConfig (&fp287, 3, 0) != 0) {
		printf ("Unable to get fp processor presence flag\n");
		exit (1);
	}
	if (fp287 != 1) {
		printf ("There is not a 287 fp processor present\n");
		exit (1);
	}
	nextarg (argc, argv);
	if ((fmand = fopen (pmand, "wb")) == NULL) {
		printf ("Unable to open count file %s\n", pmand);
		exit (3);
	}
	if (ul.realp == lr.realp && ul.imagp == lr.imagp) {
		printf ("%15.13lf+%15.13lfi, %15.13lf+%15.13lfi\n",ul.realp,ul.imagp,lr.realp,lr.imagp);
		printf ("Upper left real = lower right real\n");
		exit (3);
	}

	/* reset nreal, nimag, aspect from command line device type */

	switch (arg_device) {
		case CGA_DEV:
			nreal = CGA_COL;
			nimag = CGA_ROW;
			aspect = CGA_ASP;
			break;

		case EGA_DEV:
			nreal = EGA_COL;
			nimag = EGA_ROW;
			aspect = EGA_ASP;
			break;

		case PGA_DEV:
			nreal = PGA_COL;
			nimag = PGA_ROW;
			aspect = PGA_ASP;
			break;
	}

	/* reset individual parameters */

	if (arg_nreal != 0)
		nreal = arg_nreal;
	if (arg_nimag != 0)
		nimag = arg_nimag;
	if (arg_aspect != 0)
		aspect = arg_aspect;

	/* compute the step increments for the specifed aspect */

	rinc = (lr.realp - ul.realp) / (double)nreal;
	iinc = rinc * aspect;

	lr.imagp = ul.imagp - iinc * nimag;

	fwrite ((char *)&nreal, sizeof (int), 1, fmand);
	fwrite ((char *)&nimag, sizeof (int), 1, fmand);
	fwrite ((char *)&loop, sizeof (int), 1, fmand);
	fwrite ((char *)&ul, sizeof (ul), 1, fmand);
	fwrite ((char *)&lr, sizeof (lr), 1, fmand);
	fwrite ((char *)&rinc, sizeof (rinc), 1, fmand);
	fwrite ((char *)&iinc, sizeof (iinc), 1, fmand);
	fwrite ((char *)&aspect, sizeof (aspect), 1, fmand);
	position = ftell (fmand);
	fwrite ((char *)hist, sizeof (long), loop + 1, fmand);

	c.imagp = ul.imagp;
	for (ni = 0; ni < nimag; ni++) {
		c.realp = ul.realp;
		if (verbose)
			printf ("%4d, %15.13lf + %15.13lfi", ni, c.realp, c.imagp);
		manditer (c.realp, c.imagp, loop, nreal, mcount, rinc);
		for (nr = 0; nr < nreal; nr++) {
			i = mcount[nr];
			hist[i]++;
		}

		/* run length encode counts for this scan line */

		temp = *mcount;
		nr = 1;
		rl = rlcount + 1;
		i = -1;
		for (; nr < nreal; nr++) {
			i++;
			if (mcount[nr] != temp) {
				/* process change in value */
				if (i != 0)
					/* output count of duplicate values */
					*rl++ = -(i + 1);
				/* output value */
				*rl++ = temp;
				/* reset compression values */
				temp = mcount[nr];
				i = -1;
			}
		}
		if (i != -1) {
			if (i != 0)
				/* output count of duplicate values */
				*rl++ = -(i + 2);
			/* output value */
			*rl++ = temp;
		}
		*rlcount = rl - rlcount -1;
		if (verbose)
			printf ("%4d\n", *rlcount);
		if (fwrite ((char *)rlcount, sizeof (int), *rlcount + 1, fmand) !=
		    *rlcount + 1)  {
			printf ("error writing count file %s\n", pmand);
			exit (4);
		}
		c.imagp -= iinc;
	}
	fseek (fmand, position, 0);
	if (fwrite ((char *)hist, sizeof (long), loop + 1, fmand) != loop + 1) {
		printf ("error writing histogram to file %s\n", pmand);
		exit (4);
	}
}



/**	nextarg - process arguments
 *
 */


nextarg (argc, argv)
int	argc;
char	**argv;
{

	argv++;
	while ((argc-- > 0) && (**argv == '-')) {
		switch (*(*argv+1)) {
			case 'a':
				/* specify aspect ratio */
				argv++;
				if ((argc < 1) ||
				    (sscanf (*argv++, "%lf", &arg_aspect) != 1)) {
					printf ("Error specifing aspect\n");
					exit (1);
				}
				argc--;
				break;

			case 'c':
				/* specify number of columns and limit to maximum value */
				argv++;
				if ((argc < 1) ||
				    (sscanf (*argv++, " %d", &arg_nreal) != 1)) {
					printf ("Error specifying number of real points\n");
					exit (1);
				}
				argc--;
				if (arg_nreal > MAXREAL) {
					arg_nreal = MAXREAL;
					printf ("Number of columns limited to %d\n", MAXREAL);
				}
				break;

			case 'd':
				/* specify default device parameters */
				argv++;
				if (strcmp (*argv, "CGA") == 0)
					arg_device = CGA_DEV;
				else if (strcmp (*argv, "EGA") == 0)
					arg_device = EGA_DEV;
				else if (strcmp (*argv, "PGA") == 0)
					arg_device = PGA_DEV;
				else {
					printf ("Error specifing device\n");
					exit (1);
				}
				argv++;
				argc--;
				break;

			case 'f':
				/* specify output file name */
				argv++;
				/* set file name */
				strcpy (pmand, *argv);
				strcat (pmand, ".cnt");
				break;

			case 'i':
				/* specify iteration count and limit to maximum */
				argv++;
				if ((argc < 1) ||
				    (sscanf (*argv++, " %d", &loop) != 1)) {
					printf ("Error specifying iteration limit\n");
					exit (1);
				}
				argc--;
				if (loop > MAXLOOP) {
					loop = MAXREAL;
					printf ("Iteration count limited to %d\n", MAXLOOP);
				}
				break;

			case 'l':
				/* specify lower right corner as c+di */
				argv++;
				if ((argc < 1) || (sscanf (*argv++, "%lf%lfi",
				    &lr.realp, &lr.imagp) != 2)) {
					printf ("Error specifying lower right\n");
					exit (1);
				}
				argc--;
				break;


			case 'r':
				/* specify number of rows */
				argv++;
				if ((argc < 1) ||
				    (sscanf (*argv++, " %d", &arg_nimag) != 1)) {
					printf ("Error specifying number of imaginary points\n");
					exit (1);
				}
				argc--;
				break;

			case 'u':
				/* specify upper right corner as a+bi */
				argv++;
				if ((argc < 1) || (sscanf (*argv++, "%lf%lfi",
				    &ul.realp, &ul.imagp) != 2)) {
					printf ("Error specifying upper left\n");
					exit (1);
				}
				argc--;
				break;

			case 'v':
				/* specify verbose output */
				argv++;
				verbose = TRUE;
				break;

			default:
				printf ("Unknown argument %s\n", *argv);
				exit (1);

		}
	}
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.