DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T m

⟦1a56d0751⟧ TextFile

    Length: 7628 (0x1dcc)
    Types: TextFile
    Names: »mandisp.c«

Derivation

└─⟦87ddcff64⟧ Bits:30001253 CPHDIST85 Tape, 1985 Autumn Conference Copenhagen
    └─ ⟦this⟧ »cph85dist/mandelbrot/mandisp.c« 

TextFile

/*
 * Display Mandelbrot set pixels.  (Gidis format)
 *
 * This version uses the Gidis display protocol (for DEC PRO/350)
 * It should be "fairly" easy to adapt it for other displays.
 */

#include		<stdio.h>
#include		<ctype.h>
#ifdef vms
#include		errno
#define	IO_ERROR	errno
#endif
#define FALSE	0
#define TRUE	1
#define	EOS	'\0'
#ifdef decus
int		$$narg = 1;		/* Don't prompt for commands	*/
#define R_BIN_MODE	"rn"		/* Read binary file in Decus C	*/
#else
#define R_BIN_MODE	"r"
#endif
#define	MAX_NITER	1000		/* Max. number of iterations	*/
#define MAX_NPIXEL	 400
#define DEF_FILENAME	"mandel"

/*
 * Screen coordinates (set by mangidis.c, manregis.c)
 */
extern int	max_npixel;
extern int	smaxx;
extern int	smaxy;
extern int	xorigin;
extern int	yorigin;
extern int	gray_scale;
extern int	tick;
extern int	cxsize;
extern int	cysize;

/*
 * These values are read from the .his file
 */
int		niter;			/* Number of iterations		*/
int		npixel;			/* Number of pixels/side	*/
double		orig_real;
double		orig_imag;
double		side;

int		pixel[MAX_NPIXEL];	/* Holds one row		*/
int		factor;			/* Scan lines per pixel		*/
double		hist[MAX_NITER];	/* Pixel density histogram	*/
int		density[MAX_NITER];	/* Initialization fills this in	*/
double		hist_sum;		/* Sum of histogram values	*/
char		line[81];
char		filename[81];
extern double	atof();
extern char	*strchr();
FILE		*pixfd;
FILE		*hisfd;
\f


main(argc, argv)
int		argc;
char		*argv[];
{
	register int		i;

/*	show_gray();			-- no longer needed		*/
	if (argc <= 1) {
	    while (interactive()) {
		doit();
	    }
	}
	else {
	    for (i = 1; i < argc; i++) {
		strcpy(filename, argv[i]);
		doit();
	    }
	}
	dsp_finis();
	scr_clear();
}

doit()
{
	if (setup()) {
	    dsp_init();
	    boarder();
	    process();
	    finish();
	}
}
\f


process()
{
	register int		i, j;
	int			value;
	int			new_density, old_density;
	int			oldx, newx;

	set_gray_scale();
	factor = max_npixel / npixel;		/* Scan lines/pixel	*/
	for (i = 0; i < npixel; i++) {
	    j = fread(pixel, npixel * sizeof (pixel[0]), 1, pixfd);
	    if (feof(pixfd)) {
		perror("pixel file");
		dsp_done();
		scr_move(5, 1);
		printf("read error at scan row %d, expected %d, read %d\n",
		    i, npixel, j);
		sleep(2);
		return;
	    }
	    /*
	     * Position to Left edge of this scan line
	     */
	    dsp_move(xorigin, yorigin - (i * factor));
	    old_density = -1;
	    oldx = xorigin;;
	    for (j = 0; j < npixel; j++) {
		value = pixel[j];
		new_density = density[value];
		if (new_density != old_density) {
		    newx = xorigin + (j * factor);
		    /*
		     * If the luminance has just changed,
		     * write the vector from "old" to "new"
		     */
		    if (old_density >= 0) {
			dsp_draw(old_density, newx - oldx);
		    }
		    old_density = new_density;
		    oldx = newx;
		}
	    }
	    /*
	     * Write the last vector and reset display.
	     */
	    dsp_draw(old_density, xorigin + ((npixel - 1) * factor) - oldx);
	    dsp_endline();
	}
	stall();
}
\f


show_gray()
/*
 * Used to debug the gray scale, this routine prints each gray scale
 * value in turn.
 */
{
	register int		i;
	register int		j;
	register int		y;
	int			lines_per_gray;

	y = yorigin;
	lines_per_gray = max_npixel / gray_scale;
	scr_clear();
	dsp_init();
	for (i = 0; i < gray_scale; i++) {
	    sprintf(line, "%2d", i);
	    dsp_text(xorigin - (cxsize * 3), y - cysize, line);
	    for (j = 0; j < lines_per_gray; j++, y--) {
		dsp_move(xorigin, y);
		dsp_draw(i, max_npixel);
		dsp_endline();
	    }
	    y -= 2;			/* Spacing		*/
	}
	stall();
}
\f


/*
 * This is crude and should be replaced by something suitable to
 * your (hopefully) color display.
 */
static int gray_select[] = {
	0, 1, 2, 3, 4, 5, 6, 7
};
#define	NGRAY	(sizeof gray_select / sizeof (gray_select[0]))

set_gray_scale()
/*
 * Take the density histogram and turn it into a gray scale.
 * (should this be interactive or make better use of the
 * histogram prepared by mancomp?)
 */
{
	register int		i;

	for (i = niter; i >= 0; --i) {
	    density[i] = gray_select[i % NGRAY];
	}
}
\f


boarder()
/*
 * Draw a pretty boarder
 */
{
	register int	i;
	int		xleft, xright, ytop, ybottom;
	int		tick_gap;
	int		do_value;
	double		temp;
	double		offset;
	double		gap;

	xleft = xorigin - 2;
	xright = xorigin + max_npixel + 2;
	ytop = yorigin - max_npixel - 2;
	ybottom = yorigin + 2;
	tick_gap = max_npixel / 10;
	gap = side / ((double) max_npixel);
	dsp_draw(gray_scale - 1, 0);			/* White line	*/
	dsp_line(xleft, ytop, xright, ytop);
	dsp_line(xright, ytop, xright, ybottom);
	dsp_line(xright, ybottom, xleft, ybottom);
	dsp_line(xleft, ybottom, xleft, ytop);
	do_value = TRUE;
	offset = 0.0;
	for (i = xorigin; i < xright; i += tick_gap) {
	    dsp_line(i, ybottom, i, ybottom + tick);
	    dsp_line(i, ytop,    i, ytop    - tick);
	    if (do_value) {
		temp = orig_real + (offset * gap);
		sprintf(line, "%7.4f", temp);
		dsp_text(i - (3 * cxsize), ybottom + (tick * 2), line);
	    }
	    do_value = !do_value;
	    offset += ((double) tick_gap);
	}
	do_value = TRUE;
	offset = 0.0;
	for (i = yorigin; i > ytop; i -= tick_gap) {
	    dsp_line(xleft,  i, xleft  - tick, i);
	    dsp_line(xright, i, xright + tick, i);
	    if (do_value) {
		temp = orig_imag + (offset * gap);
		sprintf(line, "%7.4f", temp);
		dsp_text(xleft - (10 * cxsize), i - (cysize / 2), line);
	    }
	    do_value = !do_value;
	    offset += ((double) tick_gap);
	}
}

int
setup()
/*
 * Open the .pix and .his files.  Zero the vectors.
 */
{
	register int		i;
	auto int		bottom, top;

	sprintf(line, "%s.pix", filename);
	if ((pixfd = fopen(line, R_BIN_MODE)) == NULL) {
	    perror(line);
	    goto nogood;
	}
	sprintf(line, "%s.his", filename);
	if ((hisfd = fopen(line, "r")) == NULL) {
	    perror(line);
	    goto close_pix;
	}
	if (fgets(line, sizeof line, hisfd) == NULL) {
	    perror("histogram file -- first line");
	    goto close_both;
	}
	if (sscanf(line,
#ifdef decus
		"%lf %lf %lf %d %d",
#else
		"%f %f %f %d %d",
#endif
		&orig_real, &orig_imag, &side, &npixel, &niter) != 5) {
	    printf("First hist line didn't scan\n\"%s\"\n",
		line);
	    goto close_both;
	}
	scr_clear();
	scr_move(2, 1);
	printf("Origin %f", orig_real); printf(", %f\n", orig_imag);
	printf("side   %f\n", side);
	printf("npixel %d\n", npixel);
	printf("niter  %d\n", niter);
	for (i = 0; i < MAX_NITER; i++)
	    hist[i] = 0.0;
	if (fgets(line, sizeof line, hisfd) == NULL) {
	    perror("histogram file -- second line");
	    goto close_both;
	}
	if (sscanf(line,
#ifdef decus
		"%d %d %lf",
#else
		"%d %d %f",
#endif
		&bottom, &top, &hist_sum) != 3) {
	    printf("Second line didn't scan\n\"%s\"\n", line);
	    goto close_both;
	}
	for (i = bottom; i <= top; i++) {
	    if (fgets(line, sizeof line, hisfd) == NULL) {
		perror("histogram file -- data");
		goto close_both;
	    }
	    if (sscanf(line,
#ifdef decus
			"%lf",
#else
			"%f",
#endif
			&hist[i]) != 1) {
		printf("Histogram[%d] didn't scan\n\"%s\"",
		    i, line);
		goto close_both;
	    }
	}
	fclose(hisfd);	   
	return (TRUE);

/*
 * Error exits
 */
close_both:
	fclose(hisfd);
close_pix:
	fclose(pixfd);
nogood:
	if (isatty(fileno(stdin))) {
	    printf("Press return to continue.\n");
	    gets(line);
	}
	return (FALSE);
}
\f


finish()
{
	fclose(hisfd);
	fclose(pixfd);
	hisfd = NULL;
	pixfd = NULL;
}

int
interactive()
{
	if (isatty(fileno(stdin)))
	    scr_clear();
	if (!getstring(1, "Input filename", filename, DEF_FILENAME))
	    return (FALSE);
	return (TRUE);
}

stall()
{
	dsp_draw(gray_scale - 1, 0);			/* Force white */
	dsp_text(0, 0, "Press return to continue");
	dsp_done();
	gets(line);
	dsp_finis();
}