/* dwip.c: Daisy Wheel IFF Printer utility.
 *   Placed in the public domain by the author:
 *		Ken Van Camp
 *      Digitized Data Display Systems
 *		P.O. Box 878
 *		Marshalls Creek, PA  18335-0878
 *   Version 1.0 March 12, 1988
 * Based heavily on the public domain jiff and plop programs by Jim Kent
 */

#include	<exec/types.h>
#include 	<exec/nodes.h>
#include	<exec/libraries.h>
#include	<graphics/gfx.h>
#include	<graphics/rastport.h>
#include	<graphics/text.h>
#include	<intuition/intuition.h>
#include 	<stdio.h>
#include 	"jiff.h"

#define PARANOID

/* variables specific to dwip: */

typedef float REAL;

struct dev_info {
	REAL	hpitch, vpitch,		/* horizontal & vertical dot pitch (dpi) */
			hlength, vlength;	/* horiz & vert length of tot pic (inches) */
	int		xstart, ystart,		/* starting position (in dots) */
			xstop, ystop,		/* stopping position (in dots) */
			width, height;		/* area to print (in dots) */
};

struct dev_info scr = {	/* screen device info */
	XMAX/10.25,			/* hpitch */
	YMAX/7.15,			/* vpitch */
	0., 0.,				/* hlength, vlength (computed, not initialized) */
	0, 0,				/* xstart, ystart */
	0, 0,				/* xstop, ystop (computed, not initialized) */
	XMAX, YMAX			/* width, height */
};

struct dev_info ptr = {	/* printer device info */
	10.,				/* hpitch */
	6.,					/* vpitch */
	0., 0.,				/* hlength, vlength (computed, not initialized) */
	0, 0,				/* xstart, ystart (unused on printer) */
	0, 0,				/* xstop, ystop (unused on printer) */
	135,				/* width (135 columns of text) */
	0					/* height (computed, not initialized) */
};

REAL	hreduce,		/* reduction factor (dots per dot) screen to ptr */
		vreduce,		/* same, but vertical */
		r_intens = 1.0,	/* red color intensity */
		g_intens = 0.7,	/* green color intensity */
		b_intens = 1.0;	/* blue color intensity */
int	fileopen=0,			/* is an output file open? */
	sideopt=0,			/* print it sideways? */
	dotopt=0,			/* use dots instead of characters? */
	viewopt=0,			/* view only (don't print)? */
	modopt=0,			/* modify (invert) the image? */
	autopt=1,			/* automatically start up background printing? */
	nplanes,			/* # bitplanes used in this picture */
	ncolors,			/* # colors in the pallette */
	universal=0,		/* "universal" printing option (use backspaces) */
	testpat=0,			/* just print a test pattern? */
	scrn_alloc=0;		/* has a screen been allocated? */

/* these are the RGB components of all the colors in the palette: */
unsigned short rcol[MAXCOL], gcol[MAXCOL], bcol[MAXCOL];

FILE *outfile, *fopen();		/* output file descriptor */


char	*bplane[PLANES],		/* ptrs to each bitplane */
		*filename,				/* output file name */
		init_string[160] = "",	/* initialization string to printer */
		eol_string[20] = "\n";	/* end-of-line string */

/* following is for the line buffers.  Each buffer holds one line of
 * data to be output to the printer, separated by a carriage return
 */
#define NBUFS	6				/* max #chars can be overstruck for 1 dot */
char	buf[NBUFS][XMAX];		/* buffers for line output */
int		buf_used[NBUFS];		/* flag: was buffer used in this line? */

char	*documentation[] = {
"dwip: public domain Daisy Wheel IFF Printer utility v1.0 by Ken Van Camp",
"  usage:  dwip [options] files           --where valid options are:",
"	-lval      set leftmost location on screen (default 0)",
"	-tval      set top location on screen (default 0)",
"	-wval      set width of screen area to print (default 320)",
"	-hval      set height of screen area to print (default 200)",
"	-pval      set printer pitch (default 10)",
"	-cval      set # columns to use across printer (default 135)",
"	-nval      set # lines per inch on printer (default 6)",
"	-istring   set initialization string (default is none)",
"	-estring   set end-of-line string (default is newline)",
"	-ofile     send output to named file (default is RAM:dwXXXX)",
"	-s         toggle to print sideways (default OFF)",
"	-m         toggle to modify (negative) picture (default OFF)",
"	-rval      set red relative intensity (default 1.0)",
"	-gval      set green relative intensity (default 0.7)",
"	-bval      set blue relative intensity (default 1.0)",
"	-vtime     view file for time seconds, instead of printing",
0 };

/* Following are strings to send for each of the 37 character grey scales.
 * This table came from:
 *	"Considerations for Efficient Picture Output via Lineprinter"
 *	by Peter Henderson and Steven Tanimoto, Computer Graphics & Image
 *	Processing, Vol 3. 1974, pp. 327-335.
 */
#define MAXSHADES 37
char *letters[MAXSHADES] = {
/* 0 next */
"MW#O0+",
"MW#O0 ",
"MW#O+ ",
"MW#0  ",
"MW#O  ",
"MW#   ",
"MW0   ",
"MWO   ",
"H#+   ",
"H#-   ",
/* 10 next */
"H#    ",
"H*    ",
"H+    ",
"X+    ",
"H-    ",
"X-    ",
"O-    ",
"Z-    ",
"W     ",
"M     ",
/* 20 next */
"N     ",
"H     ",
"0     ",
"O     ",
"S     ",
"==    ",
"I     ",
"*     ",
"+-    ",
"+     ",
/* 30 next */
"=     ",
":     ",
"--    ",
".     ",
"-     ",
"`     ",
"      " };

struct ILBM_info *s_info;

/*This should be in exec/libraries.h */
extern struct Library *OpenLibrary();

/*This should be in intuition/intuition.h */
extern struct Screen *OpenScreen();

struct Library *GfxBase = NULL;
struct Library *LayersBase = NULL;
struct Library	*IntuitionBase = NULL;

struct Screen *DwipScreen = NULL;

struct TextAttr DwipFont =
    {
	"topaz.font",  /* I think this is the ROM font */
	8,
	0,
	0,
    };

/* a NewScreen - I don't know what half of this means either */
static
struct NewScreen DwipNewScreen =
	{
	0, 0, XMAX, YMAX, PLANES,
	0, 1,
	0,
	CUSTOMSCREEN,
	&DwipFont,
	"dwip dwip dwip",
	NULL,
	NULL,
	};

/* To use clip blit need a RastPort. */
struct RastPort DwipRastPort;

/* help: Give good help */
void help (hp)
char	**hp;
{
	void dwip_cleanup();
	register char	**dp;

	for (dp = hp; *dp; dp++)
		printf ("%s\n", *dp);
	dwip_cleanup();
	exit(1);
} /* help */

/*put_ea_cmap given an ea-type color map:
		an array of unsigned chars of form ea_cmap[] = {r, g, b, r, g, b...}
  turn it into an amiga-type color map:
  		an array of unsigned short of form amiga_cmap = {0xrgb, 0xrgb, ...}
  and then tell Dale these are the colors we want for our viewport */
void put_ea_cmap(cmap, colors)
unsigned char *cmap;
int colors;
{
	unsigned short amy_cmap[MAXCOL];
	int i;
	unsigned char r, g, b;

	if (colors > MAXCOL)	/*color clipping*/
		colors = MAXCOL;
	ncolors = colors;
	for (i=0; i<colors; i++){
		rcol[i] = (cmap[0] & 0xf0) >> 4;
		gcol[i] = (cmap[1] & 0xf0) >> 4;
		bcol[i] = (cmap[2] & 0xf0) >> 4;
		amy_cmap[i] = ((cmap[0] & 0xf0) << 4) + (cmap[1] & 0xf0) + 
			((cmap[2] & 0xf0) >> 4);
		cmap += 3;
	}
	LoadRGB4( &DwipScreen->ViewPort, amy_cmap, (long)colors);
} /* put_ea_cmap */

/* back out backwards */
void dwip_cleanup()
{
	if (DwipScreen != NULL)
		CloseScreen(DwipScreen);
	if (IntuitionBase != NULL)
		CloseLibrary(IntuitionBase);
	if (LayersBase != NULL)
		CloseLibrary(LayersBase);
	if (GfxBase != NULL)
		CloseLibrary(GfxBase);
	if (fileopen){
		fileopen = 0;
		fclose (outfile);
	}
	if (scrn_alloc){
		scrn_alloc = 0;
		free_planes (&s_info->bitmap);
	}
} /* dwip_cleanup */

/* getbit: return value (0 or 1) of specified bit of supplied byte.
 * Why didn't I put this in a macro?
 */
int getbit (b, n)
char b;
int  n;
{
	return (b>>n & 1);
} /* getbit */

/* get_shade: return the shade of the specified pixel */
int get_shade (x, y)
int	x, y;				/* coords of the pixel */
{
	int	color_num,		/* color number of the pixel */
		j,				/* index to bitplanes */
		shade,			/* shade of the pixel */
		byte_num,		/* byte # offset within bitplane */
		bit;			/* bit # within byte */
	char	*b;			/* actual byte address */

	byte_num = y * 40 + x / 8;
	bit = 7 - (x % 8);			/* bits are in reverse order! */

	/* find color # */
	color_num = 0;
	for (j = 0; j < nplanes; j++){
		b = bplane[j] + (char *)byte_num;
		color_num += getbit (*b, bit) << j;
	}
	if (color_num > ncolors){
#ifdef PARANOID
		printf ("Unknown color #%d\n", color_num);
#endif PARANOID
		return(0);
	}else{
		shade = (int) ((REAL)rcol[color_num] * r_intens + 
				(REAL)gcol[color_num] * g_intens +
				(REAL)bcol[color_num] * b_intens);
		if (modopt)
			/* inverse picture */
			return (MAXSHADES - shade);
		else
			/* normal picture */
			return (shade);
	} /* if color_num */
} /* get_shade */

/* charshade: Returns the string of characters to send to produce a given
 * shade of grey.
 */
char *charshade (shade)
int shade;
{
	if (shade < MAXSHADES)
		return (letters[shade]);
	else
		/* This makes more pixels white than really should be. */
		return (letters[MAXSHADES-1]);
}

/* set_values: Set the screen printing parameters.  This routine is called
 * before every picture is printed, in case anything has changed since
 * the last picture.
 */
void set_values ()
{
	if (scr.xstart < 0)
		scr.xstart = 0;
	if (scr.ystart < 0)
		scr.ystart = 0;
	if (scr.width + scr.xstart > XMAX)
		scr.width = XMAX - scr.xstart;
	if (scr.height + scr.ystart > YMAX)
		scr.height = YMAX - scr.ystart;
	ptr.hlength = ptr.width / ptr.hpitch;
	scr.hlength = scr.width / scr.hpitch;
	scr.vlength = scr.height / scr.vpitch;
	if (! sideopt){
		/* normal print */
		hreduce = (REAL) scr.width / ptr.width;
		ptr.vlength = scr.vlength * ptr.hlength / scr.hlength;
	}else{
		/* sideways print */
		hreduce = (REAL) scr.height / ptr.width;
		ptr.vlength = scr.hlength * ptr.hlength / scr.hlength;
	}
	ptr.height = ptr.vlength * ptr.vpitch;
	vreduce = (REAL) scr.height / ptr.height;
	scr.xstop = scr.xstart + scr.width - 1;
	scr.ystop = scr.ystart + scr.height - 1;
#ifdef DEBUG
	printf("Screen : pitches=%lf,%lf lengths=%lf,%lf width=%d height=%d\n",
		scr.hpitch, scr.vpitch, scr.hlength, scr.vlength, scr.width,
		scr.height);
	printf("Printer: pitches=%lf,%lf lengths=%lf,%lf width=%d height=%d\n",
		ptr.hpitch, ptr.vpitch, ptr.hlength, ptr.vlength, ptr.width,
		ptr.height);
	printf("reduce=%lf,%lf start=%d,%d stop=%d,%d\n", hreduce, vreduce,
		scr.xstart, scr.ystart, scr.xstop, scr.ystop);
#endif
} /* set_values */

/* eval_strg: evaluate 3-digit decimal constants within a string */
void eval_strg (s)
char *s;
{
	int	i, j;
	char	t[80], tmp[4];

	tmp[3] = NULL;
	i = j = 0;
	while (s[i] != NULL){
		if (s[i] == '\\'){
			/* decode a decimal constant */
			tmp[0] = s[++i];
			tmp[1] = s[++i];
			tmp[2] = s[++i];
			t[j++] = (char) atoi (tmp);
		}else
			t[j++] = s[i];
		i++;
	}
	t[j] = NULL;
	strcpy (s, t);
} /* eval_strg */

/* eval_arg: Evaluate a command-line argument, and set appropriate global
 * variables.  Returns 1 if just an input filename, 0 if a valid option.
 * Doesn't return at all if an invalid option.
 */
int eval_arg (arg)
char *arg;
{
	void	help(), eval_strg();
	double	atof();
	int	i,			/* char array index */
		optused;	/* flag: was complete option used? */
	char	c;		/* next char to process */

	if (arg[0] == '-'){
		/* cmmd line option: interpret */
		i = 1;
		optused = 0;	/* could be more than one option per minus sign */
		c = arg[i];
		/* do until delimiter between arguments is found: either a space
		 * or null
		 */
		while (c && c != ' ' && !optused){
			i++;
			switch (c){

			case '?':
				help (documentation);
				break;

			case 'a':	/* auto-printing option */
				autopt = !autopt;
				break;

			case 'b':	/* set blue value */
				b_intens = atof (&arg[i]);
				optused++;
				break;

			case 'c':	/* set # columns on printer */
				ptr.width = atoi (&arg[i]);
				optused++;
				break;

			case 'd':	/* dot (dithering) option */
				dotopt = !dotopt;
				printf ("Dot option not implemented yet\n");
				break;

			case 'e':	/* end-of-line string */
				/* sprintf (eol_string, &arg[i]); */
				strcpy (eol_string, &arg[i]);
				eval_strg (eol_string);
				optused++;
				break;

			case 'g':	/* set green value */
				g_intens = atof (&arg[i]);
				optused++;
				break;

			case 'h':	/* set screen height */
				scr.height = atoi (&arg[i]);
				optused++;
				break;

			case 'i':	/* initialization string */
				/* sprintf (init_string, &arg[i]); */
				strcpy (init_string, &arg[i]);
				eval_strg (init_string);
				optused++;
				break;

			case 'l':	/* set left edge of screen to print */
				scr.xstart = atoi (&arg[i]);
				optused++;
				break;

			case 'm':	/* set "modified" flag (inverse image) */
				modopt = !modopt;
				break;

			case 'n':	/* set # lines per inch on printer */
				ptr.vpitch = atoi (&arg[i]);
				optused++;
				break;

			case 'o':	/* output filename */
				/* strcpy (filename, &arg[i]); */
				filename = &arg[i];
				optused++;
				if (fileopen){
					fclose (outfile);
					fileopen = 0;
				}
				break;

			case 'p':	/* set printer pitch */
				ptr.hpitch = atoi (&arg[i]);
				optused++;
				break;

			case 'r':	/* set red value */
				r_intens = atof (&arg[i]);
				optused++;
				break;

			case 's':	/* print sideways option */
				sideopt = !sideopt;
				break;

			case 't':	/* set top edge of screen to print */
				scr.ystart = atoi (&arg[i]);
				optused++;
				break;

			case 'u':	/* universal printing option (use backspaces) */
				universal = 1;
				break;

			case 'v':	/* view file option */
				viewopt = atoi (&arg[i]);
				autopt = 0;		/* turns off auto-printing option */
				optused++;
				break;

			case 'w':	/* set screen width */
				scr.width = atoi (&arg[i]);
				optused++;
				break;

			case 'z':	/* just print test pattern */
				testpat = 1;
				break;

			default:
				printf ("Unknown option %c\n", c);
				help (documentation);
			} /* switch (c) */
			c = arg[i];
		} /* while */
		return (0);
	}else
		/* Just a file name */
		return (1);
} /* eval_arg */

/* init_graph: Initialize Amiga graphics */
int init_graph()
{
	if ((GfxBase =  OpenLibrary("graphics.library", (long)0)) == NULL){
		printf("Can't open Graphics Library\n");
		return(1);
	}

	if ((LayersBase =  OpenLibrary("layers.library", (long)0)) == NULL){
		printf("Can't open Layers Library\n");
		dwip_cleanup();
		return(2);
	}

	if ((IntuitionBase =  OpenLibrary("intuition.library",(long)0)) == NULL){
		printf("Can't open Intuition Library\n");
		dwip_cleanup();
		return(3);
	}

	if ( (DwipScreen = OpenScreen(&DwipNewScreen) ) == NULL){
		printf("OpenScreen failed\n");
		dwip_cleanup();
		return(4);
	}

	InitRastPort(&DwipRastPort);
	DwipRastPort.Mask = (1<<PLANES)-1;  /*just play it safe in case someone
										 * tries to load 6 bit planes...*/
	return(0);
} /* init_graph */

/* outstring: Store a character string in the output buffers.
 * One buffer is used per overstriked character.
 */
void outstring (s, nchar)
char	*s;			/* string of chars to be overlaid */
int		nchar;		/* current position in buffers */
{
	int	i;			/* buffer # */

	for (i = 0; i < NBUFS; i++)
		if ((buf[i][nchar] = s[i]) != ' ')
			buf_used[i] = 1;
} /* outstring */

/* printscreen: This routine sends out the characters to the printer */
void printscreen()
{
	char	*charshade();
	void	dwip_cleanup(), outstring();
	int		get_shade();
	int	j,						/* index to bitplanes */
		i,						/* index to buffers */
		ct,						/* count of #chars outputted on line */
		shade,					/* shade of a pixel */
		x, y;					/* actual screen coord looked at */
	REAL	xskip, yskip;		/* # pixels skipped since last one printed */

	if (! fileopen){
		if ((outfile = fopen (filename, "w")) == NULL){
			printf("Couldn't open file %s for output\n", filename);
			help (documentation);
		}
		fileopen = 1;
	}

	/* initialize the bitplane pointers */
	nplanes = s_info->bitmap.Depth;
	for (j=0; j < s_info->bitmap.Depth; j++)
		bplane[j] = (char *)s_info->bitmap.Planes[j];

	fprintf(outfile,"%s", init_string);
	/* want normal or sideways print? */
	if (! sideopt){
		/* normal printout */
		for (y = scr.ystart, yskip = 0.; y <= scr.ystop; y++){
			yskip += 1.;
			while (yskip > vreduce){
				/* plot this line */
				yskip -= vreduce;
				/* Initialize the line buffers */
				for (i = 0; i < NBUFS; i++)
					buf_used[i] = 0;
				for (x=scr.xstart, xskip=0., ct=0; x <= scr.xstop; x++){
					xskip += 1.;
					while (xskip > hreduce){
						/* plot this pixel */
						xskip -= hreduce;
						shade = get_shade (x, y);
						/* fprintf (outfile, "%s", charshade (shade)); */
						outstring (charshade (shade), ct++);
#ifdef DEBUG
						if (ct > ptr.width)
							printf("Warning: %d chars on line\n", ct);
#endif DEBUG
					} /* while xskip */
				} /* for x */
				/* print out the buffers */
				for (i = 0; i < NBUFS; i++)
					if (buf_used[i]){
						buf[i][ct] = NULL;
						/* first print the buffer */
						fprintf (outfile, "%s", buf[i]);
						/* Now do something to get printhead back to
						 * beginning of line, for overstriking.
						 */
						if (universal)
							/* Universal printer output sends backspaces
							 * instead of a carriage return.
							 */
							for (j = 0; j < ct; j++)
								fprintf (outfile, "\010");
						else
							/* each buffer followed by carriage return */
							fprintf (outfile, "\015");
					}
				/* the end-of-line string */
				fprintf(outfile,"%s", eol_string);
			} /* while yskip */
		} /* for y */
	}else{
		/* sideways print */
		for (x = scr.xstart, xskip = 0.; x <= scr.xstop; x++){
			xskip += 1.;
			while (xskip > vreduce){
				/* plot this line */
				xskip -= vreduce;
				/* Initialize the line buffers */
				for (i = 0; i < NBUFS; i++)
					buf_used[i] = 0;
				for (y=scr.ystop, yskip=0., ct=0; y >= scr.ystart; y--){
					yskip += 1.;
					while (yskip > hreduce){
						/* plot this pixel */
						yskip -= hreduce;
						shade = get_shade (x, y);
						/* fprintf (outfile, "%s", charshade (shade)); */
						outstring (charshade (shade), ct++);
					} /* while yskip */
				} /* for y */
				/* print out the buffers */
				for (i = 0; i < NBUFS; i++)
					if (buf_used[i]){
						buf[i][ct] = NULL;
						/* first print the buffer */
						fprintf (outfile, "%s", buf[i]);
						/* Now do something to get printhead back to
						 * beginning of line, for overstriking.
						 */
						if (universal)
							/* Universal printer output sends backspaces
							 * instead of a carriage return.
							 */
							for (j = 0; j < ct; j++)
								fprintf (outfile, "\010");
						else
							/* each buffer followed by carriage return */
							fprintf (outfile, "\015");
					}
				/* the end-of-line string */
				fprintf(outfile,"%s", eol_string);
			} /* while xskip */
		} /* for x */
	} /* if ! sideopt */
} /* printscreen */

/* eval_env: Evaluate the DWIP environment variable */
void eval_env()
{
	char *getenv(), *index();
	int eval_arg();
	char *opts;

	if (opts = getenv ("DWIP")){
		while (opts){
			if (eval_arg (opts)){
				/* eval_arg thinks it's a filename; probably just an extra
				 * space between arguments, so ignore
				 */
				opts++;
			}else{
				/* advance to next argument */
				opts = index (opts, ' ');
				if (opts)
					opts++;
			}
		} /* while */
	} /* if opts */
} /* eval_env */

/* display_pic: Display an IFF picture on the screen, return 1 if
 * successful, 0 if not. */
int display_pic (flnm)
char *flnm;
{
	void help(), set_values(), free_planes(), put_ea_cmap();
	struct ILBM_info *read_iff();

	set_values();

	if (scrn_alloc){
		free_planes (&s_info->bitmap);
		scrn_alloc = 0;
	}
	if ((s_info = read_iff(flnm, 0)) != NULL){
		scrn_alloc = 1;
		put_ea_cmap(&s_info->cmap, (1 << s_info->bitmap.Depth));
		DwipRastPort.BitMap = &s_info->bitmap;
		ClipBlit( &DwipRastPort, (long)0, (long)0,
			&DwipScreen->RastPort, (long)s_info->header.x, 
			(long)s_info->header.y, (long)s_info->header.w, 
			(long)s_info->header.h, (long)COPY_MINTERM);
		return (1);
	}else
		return (0);
} /* display_pic */

/* print_testpat: Print a simple test pattern across the page (5 lines) */
void print_testpat ()
{
	char *charshade();
	void outstring();
	int	ct,		/* # shades of grey */
		l,		/* line # */
		i,		/* buffer # */
		j;		/* ctr for backspaces */

	if (! fileopen){
		if ((outfile = fopen (filename, "w")) == NULL){
			printf("Couldn't open file %s for output\n", filename);
			help (documentation);
		}
		fileopen = 1;
	}

	for (l = 0; l < 5; l++){
		/* Initialize the line buffers */
		for (i = 0; i < NBUFS; i++)
			buf_used[i] = 0;
		/* Output a continuous line of grey (black to white) */
		for (ct = 0; ct < MAXSHADES; ct++)
			outstring (charshade (ct), ct);
		/* print out the buffers */
		for (i = 0; i < NBUFS; i++){
			if (buf_used[i]){
				buf[i][ct] = NULL;
				/* first print the buffer */
				fprintf (outfile, "%s", buf[i]);
				/* Now do something to get printhead back to
				 * beginning of line, for overstriking.
				 */
				if (universal)
					/* Universal printer output sends backspaces
					 * instead of a carriage return.
					 */
					for (j = 0; j < ct; j++)
						fprintf (outfile, "\010");
				else
					/* each buffer followed by carriage return */
					fprintf (outfile, "\015");
			} /* if buf_used */
		} /* for i */
		/* the end-of-line string */
		fprintf(outfile,"%s", eol_string);
	} /* for l */
} /* print_testpat */

main (argc, argv)
int argc;
char *argv[];
{
	int		eval_arg(), init_graph(), display_pic();
	void	eval_env(), dwip_cleanup(), printscreen(), print_testpat();
	char	*mktemp();
	int	i,						/* index to args */
		nfiles = 0;				/* # input files read */

	filename = mktemp ("RAM:dwXXXX");
	eval_env();

	/* Initialize graphics */
	if (init_graph()){
		dwip_cleanup();
		exit(1);
	}

	/* parse the command line */
	for (i=1; i<argc; i++){
#ifdef DEBUG
		puts(argv[i]);
#endif DEBUG
		if (eval_arg (argv[i])){
			nfiles++;
			if (display_pic (argv[i])){
				if (! viewopt)
					printscreen();
				else
					/* Viewing option: Just pause for specified # seconds */
					Delay ((long)viewopt * 50);

				free_planes (&s_info->bitmap);
				scrn_alloc = 0;
			}else /* if display_pic */
				printf("dwip: Couldn't load %s as an IFF file\n", argv[i]);
		} /* if eval_arg */
	} /* for argv */
	if (nfiles)
		dwip_cleanup();
	else if (testpat){
		print_testpat();
		dwip_cleanup();
	}else{
		printf ("dwip: No files specified.\n");
		help (documentation);
	}
#ifdef NEVER
	/* This didn't work right, so I took it out. Seemed like a nice idea.
	 * If anybody knows what I did wrong, let me know. -kvc
	 */
	if (autopt)
		execlp ("runback", "runback", "c:type", filename, "to", "PRT:",0);
#endif NEVER
} /* main */

