home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d160 / dwip.lha / DWIP / DWIP.c < prev    next >
C/C++ Source or Header  |  1988-10-02  |  22KB  |  858 lines

  1. /* dwip.c: Daisy Wheel IFF Printer utility.
  2.  *   Placed in the public domain by the author:
  3.  *        Ken Van Camp
  4.  *      Digitized Data Display Systems
  5.  *        P.O. Box 878
  6.  *        Marshalls Creek, PA  18335-0878
  7.  *   Version 1.0 March 12, 1988
  8.  * Based heavily on the public domain jiff and plop programs by Jim Kent
  9.  */
  10.  
  11. #include    <exec/types.h>
  12. #include     <exec/nodes.h>
  13. #include    <exec/libraries.h>
  14. #include    <graphics/gfx.h>
  15. #include    <graphics/rastport.h>
  16. #include    <graphics/text.h>
  17. #include    <intuition/intuition.h>
  18. #include     <stdio.h>
  19. #include     "jiff.h"
  20.  
  21. #define PARANOID
  22.  
  23. /* variables specific to dwip: */
  24.  
  25. typedef float REAL;
  26.  
  27. struct dev_info {
  28.     REAL    hpitch, vpitch,        /* horizontal & vertical dot pitch (dpi) */
  29.             hlength, vlength;    /* horiz & vert length of tot pic (inches) */
  30.     int        xstart, ystart,        /* starting position (in dots) */
  31.             xstop, ystop,        /* stopping position (in dots) */
  32.             width, height;        /* area to print (in dots) */
  33. };
  34.  
  35. struct dev_info scr = {    /* screen device info */
  36.     XMAX/10.25,            /* hpitch */
  37.     YMAX/7.15,            /* vpitch */
  38.     0., 0.,                /* hlength, vlength (computed, not initialized) */
  39.     0, 0,                /* xstart, ystart */
  40.     0, 0,                /* xstop, ystop (computed, not initialized) */
  41.     XMAX, YMAX            /* width, height */
  42. };
  43.  
  44. struct dev_info ptr = {    /* printer device info */
  45.     10.,                /* hpitch */
  46.     6.,                    /* vpitch */
  47.     0., 0.,                /* hlength, vlength (computed, not initialized) */
  48.     0, 0,                /* xstart, ystart (unused on printer) */
  49.     0, 0,                /* xstop, ystop (unused on printer) */
  50.     135,                /* width (135 columns of text) */
  51.     0                    /* height (computed, not initialized) */
  52. };
  53.  
  54. REAL    hreduce,        /* reduction factor (dots per dot) screen to ptr */
  55.         vreduce,        /* same, but vertical */
  56.         r_intens = 1.0,    /* red color intensity */
  57.         g_intens = 0.7,    /* green color intensity */
  58.         b_intens = 1.0;    /* blue color intensity */
  59. int    fileopen=0,            /* is an output file open? */
  60.     sideopt=0,            /* print it sideways? */
  61.     dotopt=0,            /* use dots instead of characters? */
  62.     viewopt=0,            /* view only (don't print)? */
  63.     modopt=0,            /* modify (invert) the image? */
  64.     autopt=1,            /* automatically start up background printing? */
  65.     nplanes,            /* # bitplanes used in this picture */
  66.     ncolors,            /* # colors in the pallette */
  67.     universal=0,        /* "universal" printing option (use backspaces) */
  68.     testpat=0,            /* just print a test pattern? */
  69.     scrn_alloc=0;        /* has a screen been allocated? */
  70.  
  71. /* these are the RGB components of all the colors in the palette: */
  72. unsigned short rcol[MAXCOL], gcol[MAXCOL], bcol[MAXCOL];
  73.  
  74. FILE *outfile, *fopen();        /* output file descriptor */
  75.  
  76.  
  77. char    *bplane[PLANES],        /* ptrs to each bitplane */
  78.         *filename,                /* output file name */
  79.         init_string[160] = "",    /* initialization string to printer */
  80.         eol_string[20] = "\n";    /* end-of-line string */
  81.  
  82. /* following is for the line buffers.  Each buffer holds one line of
  83.  * data to be output to the printer, separated by a carriage return
  84.  */
  85. #define NBUFS    6                /* max #chars can be overstruck for 1 dot */
  86. char    buf[NBUFS][XMAX];        /* buffers for line output */
  87. int        buf_used[NBUFS];        /* flag: was buffer used in this line? */
  88.  
  89. char    *documentation[] = {
  90. "dwip: public domain Daisy Wheel IFF Printer utility v1.0 by Ken Van Camp",
  91. "  usage:  dwip [options] files           --where valid options are:",
  92. "    -lval      set leftmost location on screen (default 0)",
  93. "    -tval      set top location on screen (default 0)",
  94. "    -wval      set width of screen area to print (default 320)",
  95. "    -hval      set height of screen area to print (default 200)",
  96. "    -pval      set printer pitch (default 10)",
  97. "    -cval      set # columns to use across printer (default 135)",
  98. "    -nval      set # lines per inch on printer (default 6)",
  99. "    -istring   set initialization string (default is none)",
  100. "    -estring   set end-of-line string (default is newline)",
  101. "    -ofile     send output to named file (default is RAM:dwXXXX)",
  102. "    -s         toggle to print sideways (default OFF)",
  103. "    -m         toggle to modify (negative) picture (default OFF)",
  104. "    -rval      set red relative intensity (default 1.0)",
  105. "    -gval      set green relative intensity (default 0.7)",
  106. "    -bval      set blue relative intensity (default 1.0)",
  107. "    -vtime     view file for time seconds, instead of printing",
  108. 0 };
  109.  
  110. /* Following are strings to send for each of the 37 character grey scales.
  111.  * This table came from:
  112.  *    "Considerations for Efficient Picture Output via Lineprinter"
  113.  *    by Peter Henderson and Steven Tanimoto, Computer Graphics & Image
  114.  *    Processing, Vol 3. 1974, pp. 327-335.
  115.  */
  116. #define MAXSHADES 37
  117. char *letters[MAXSHADES] = {
  118. /* 0 next */
  119. "MW#O0+",
  120. "MW#O0 ",
  121. "MW#O+ ",
  122. "MW#0  ",
  123. "MW#O  ",
  124. "MW#   ",
  125. "MW0   ",
  126. "MWO   ",
  127. "H#+   ",
  128. "H#-   ",
  129. /* 10 next */
  130. "H#    ",
  131. "H*    ",
  132. "H+    ",
  133. "X+    ",
  134. "H-    ",
  135. "X-    ",
  136. "O-    ",
  137. "Z-    ",
  138. "W     ",
  139. "M     ",
  140. /* 20 next */
  141. "N     ",
  142. "H     ",
  143. "0     ",
  144. "O     ",
  145. "S     ",
  146. "==    ",
  147. "I     ",
  148. "*     ",
  149. "+-    ",
  150. "+     ",
  151. /* 30 next */
  152. "=     ",
  153. ":     ",
  154. "--    ",
  155. ".     ",
  156. "-     ",
  157. "`     ",
  158. "      " };
  159.  
  160. struct ILBM_info *s_info;
  161.  
  162. /*This should be in exec/libraries.h */
  163. extern struct Library *OpenLibrary();
  164.  
  165. /*This should be in intuition/intuition.h */
  166. extern struct Screen *OpenScreen();
  167.  
  168. struct Library *GfxBase = NULL;
  169. struct Library *LayersBase = NULL;
  170. struct Library    *IntuitionBase = NULL;
  171.  
  172. struct Screen *DwipScreen = NULL;
  173.  
  174. struct TextAttr DwipFont =
  175.     {
  176.     "topaz.font",  /* I think this is the ROM font */
  177.     8,
  178.     0,
  179.     0,
  180.     };
  181.  
  182. /* a NewScreen - I don't know what half of this means either */
  183. static
  184. struct NewScreen DwipNewScreen =
  185.     {
  186.     0, 0, XMAX, YMAX, PLANES,
  187.     0, 1,
  188.     0,
  189.     CUSTOMSCREEN,
  190.     &DwipFont,
  191.     "dwip dwip dwip",
  192.     NULL,
  193.     NULL,
  194.     };
  195.  
  196. /* To use clip blit need a RastPort. */
  197. struct RastPort DwipRastPort;
  198.  
  199. /* help: Give good help */
  200. void help (hp)
  201. char    **hp;
  202. {
  203.     void dwip_cleanup();
  204.     register char    **dp;
  205.  
  206.     for (dp = hp; *dp; dp++)
  207.         printf ("%s\n", *dp);
  208.     dwip_cleanup();
  209.     exit(1);
  210. } /* help */
  211.  
  212. /*put_ea_cmap given an ea-type color map:
  213.         an array of unsigned chars of form ea_cmap[] = {r, g, b, r, g, b...}
  214.   turn it into an amiga-type color map:
  215.           an array of unsigned short of form amiga_cmap = {0xrgb, 0xrgb, ...}
  216.   and then tell Dale these are the colors we want for our viewport */
  217. void put_ea_cmap(cmap, colors)
  218. unsigned char *cmap;
  219. int colors;
  220. {
  221.     unsigned short amy_cmap[MAXCOL];
  222.     int i;
  223.     unsigned char r, g, b;
  224.  
  225.     if (colors > MAXCOL)    /*color clipping*/
  226.         colors = MAXCOL;
  227.     ncolors = colors;
  228.     for (i=0; i<colors; i++){
  229.         rcol[i] = (cmap[0] & 0xf0) >> 4;
  230.         gcol[i] = (cmap[1] & 0xf0) >> 4;
  231.         bcol[i] = (cmap[2] & 0xf0) >> 4;
  232.         amy_cmap[i] = ((cmap[0] & 0xf0) << 4) + (cmap[1] & 0xf0) + 
  233.             ((cmap[2] & 0xf0) >> 4);
  234.         cmap += 3;
  235.     }
  236.     LoadRGB4( &DwipScreen->ViewPort, amy_cmap, (long)colors);
  237. } /* put_ea_cmap */
  238.  
  239. /* back out backwards */
  240. void dwip_cleanup()
  241. {
  242.     if (DwipScreen != NULL)
  243.         CloseScreen(DwipScreen);
  244.     if (IntuitionBase != NULL)
  245.         CloseLibrary(IntuitionBase);
  246.     if (LayersBase != NULL)
  247.         CloseLibrary(LayersBase);
  248.     if (GfxBase != NULL)
  249.         CloseLibrary(GfxBase);
  250.     if (fileopen){
  251.         fileopen = 0;
  252.         fclose (outfile);
  253.     }
  254.     if (scrn_alloc){
  255.         scrn_alloc = 0;
  256.         free_planes (&s_info->bitmap);
  257.     }
  258. } /* dwip_cleanup */
  259.  
  260. /* getbit: return value (0 or 1) of specified bit of supplied byte.
  261.  * Why didn't I put this in a macro?
  262.  */
  263. int getbit (b, n)
  264. char b;
  265. int  n;
  266. {
  267.     return (b>>n & 1);
  268. } /* getbit */
  269.  
  270. /* get_shade: return the shade of the specified pixel */
  271. int get_shade (x, y)
  272. int    x, y;                /* coords of the pixel */
  273. {
  274.     int    color_num,        /* color number of the pixel */
  275.         j,                /* index to bitplanes */
  276.         shade,            /* shade of the pixel */
  277.         byte_num,        /* byte # offset within bitplane */
  278.         bit;            /* bit # within byte */
  279.     char    *b;            /* actual byte address */
  280.  
  281.     byte_num = y * 40 + x / 8;
  282.     bit = 7 - (x % 8);            /* bits are in reverse order! */
  283.  
  284.     /* find color # */
  285.     color_num = 0;
  286.     for (j = 0; j < nplanes; j++){
  287.         b = bplane[j] + (char *)byte_num;
  288.         color_num += getbit (*b, bit) << j;
  289.     }
  290.     if (color_num > ncolors){
  291. #ifdef PARANOID
  292.         printf ("Unknown color #%d\n", color_num);
  293. #endif PARANOID
  294.         return(0);
  295.     }else{
  296.         shade = (int) ((REAL)rcol[color_num] * r_intens + 
  297.                 (REAL)gcol[color_num] * g_intens +
  298.                 (REAL)bcol[color_num] * b_intens);
  299.         if (modopt)
  300.             /* inverse picture */
  301.             return (MAXSHADES - shade);
  302.         else
  303.             /* normal picture */
  304.             return (shade);
  305.     } /* if color_num */
  306. } /* get_shade */
  307.  
  308. /* charshade: Returns the string of characters to send to produce a given
  309.  * shade of grey.
  310.  */
  311. char *charshade (shade)
  312. int shade;
  313. {
  314.     if (shade < MAXSHADES)
  315.         return (letters[shade]);
  316.     else
  317.         /* This makes more pixels white than really should be. */
  318.         return (letters[MAXSHADES-1]);
  319. }
  320.  
  321. /* set_values: Set the screen printing parameters.  This routine is called
  322.  * before every picture is printed, in case anything has changed since
  323.  * the last picture.
  324.  */
  325. void set_values ()
  326. {
  327.     if (scr.xstart < 0)
  328.         scr.xstart = 0;
  329.     if (scr.ystart < 0)
  330.         scr.ystart = 0;
  331.     if (scr.width + scr.xstart > XMAX)
  332.         scr.width = XMAX - scr.xstart;
  333.     if (scr.height + scr.ystart > YMAX)
  334.         scr.height = YMAX - scr.ystart;
  335.     ptr.hlength = ptr.width / ptr.hpitch;
  336.     scr.hlength = scr.width / scr.hpitch;
  337.     scr.vlength = scr.height / scr.vpitch;
  338.     if (! sideopt){
  339.         /* normal print */
  340.         hreduce = (REAL) scr.width / ptr.width;
  341.         ptr.vlength = scr.vlength * ptr.hlength / scr.hlength;
  342.     }else{
  343.         /* sideways print */
  344.         hreduce = (REAL) scr.height / ptr.width;
  345.         ptr.vlength = scr.hlength * ptr.hlength / scr.hlength;
  346.     }
  347.     ptr.height = ptr.vlength * ptr.vpitch;
  348.     vreduce = (REAL) scr.height / ptr.height;
  349.     scr.xstop = scr.xstart + scr.width - 1;
  350.     scr.ystop = scr.ystart + scr.height - 1;
  351. #ifdef DEBUG
  352.     printf("Screen : pitches=%lf,%lf lengths=%lf,%lf width=%d height=%d\n",
  353.         scr.hpitch, scr.vpitch, scr.hlength, scr.vlength, scr.width,
  354.         scr.height);
  355.     printf("Printer: pitches=%lf,%lf lengths=%lf,%lf width=%d height=%d\n",
  356.         ptr.hpitch, ptr.vpitch, ptr.hlength, ptr.vlength, ptr.width,
  357.         ptr.height);
  358.     printf("reduce=%lf,%lf start=%d,%d stop=%d,%d\n", hreduce, vreduce,
  359.         scr.xstart, scr.ystart, scr.xstop, scr.ystop);
  360. #endif
  361. } /* set_values */
  362.  
  363. /* eval_strg: evaluate 3-digit decimal constants within a string */
  364. void eval_strg (s)
  365. char *s;
  366. {
  367.     int    i, j;
  368.     char    t[80], tmp[4];
  369.  
  370.     tmp[3] = NULL;
  371.     i = j = 0;
  372.     while (s[i] != NULL){
  373.         if (s[i] == '\\'){
  374.             /* decode a decimal constant */
  375.             tmp[0] = s[++i];
  376.             tmp[1] = s[++i];
  377.             tmp[2] = s[++i];
  378.             t[j++] = (char) atoi (tmp);
  379.         }else
  380.             t[j++] = s[i];
  381.         i++;
  382.     }
  383.     t[j] = NULL;
  384.     strcpy (s, t);
  385. } /* eval_strg */
  386.  
  387. /* eval_arg: Evaluate a command-line argument, and set appropriate global
  388.  * variables.  Returns 1 if just an input filename, 0 if a valid option.
  389.  * Doesn't return at all if an invalid option.
  390.  */
  391. int eval_arg (arg)
  392. char *arg;
  393. {
  394.     void    help(), eval_strg();
  395.     double    atof();
  396.     int    i,            /* char array index */
  397.         optused;    /* flag: was complete option used? */
  398.     char    c;        /* next char to process */
  399.  
  400.     if (arg[0] == '-'){
  401.         /* cmmd line option: interpret */
  402.         i = 1;
  403.         optused = 0;    /* could be more than one option per minus sign */
  404.         c = arg[i];
  405.         /* do until delimiter between arguments is found: either a space
  406.          * or null
  407.          */
  408.         while (c && c != ' ' && !optused){
  409.             i++;
  410.             switch (c){
  411.  
  412.             case '?':
  413.                 help (documentation);
  414.                 break;
  415.  
  416.             case 'a':    /* auto-printing option */
  417.                 autopt = !autopt;
  418.                 break;
  419.  
  420.             case 'b':    /* set blue value */
  421.                 b_intens = atof (&arg[i]);
  422.                 optused++;
  423.                 break;
  424.  
  425.             case 'c':    /* set # columns on printer */
  426.                 ptr.width = atoi (&arg[i]);
  427.                 optused++;
  428.                 break;
  429.  
  430.             case 'd':    /* dot (dithering) option */
  431.                 dotopt = !dotopt;
  432.                 printf ("Dot option not implemented yet\n");
  433.                 break;
  434.  
  435.             case 'e':    /* end-of-line string */
  436.                 /* sprintf (eol_string, &arg[i]); */
  437.                 strcpy (eol_string, &arg[i]);
  438.                 eval_strg (eol_string);
  439.                 optused++;
  440.                 break;
  441.  
  442.             case 'g':    /* set green value */
  443.                 g_intens = atof (&arg[i]);
  444.                 optused++;
  445.                 break;
  446.  
  447.             case 'h':    /* set screen height */
  448.                 scr.height = atoi (&arg[i]);
  449.                 optused++;
  450.                 break;
  451.  
  452.             case 'i':    /* initialization string */
  453.                 /* sprintf (init_string, &arg[i]); */
  454.                 strcpy (init_string, &arg[i]);
  455.                 eval_strg (init_string);
  456.                 optused++;
  457.                 break;
  458.  
  459.             case 'l':    /* set left edge of screen to print */
  460.                 scr.xstart = atoi (&arg[i]);
  461.                 optused++;
  462.                 break;
  463.  
  464.             case 'm':    /* set "modified" flag (inverse image) */
  465.                 modopt = !modopt;
  466.                 break;
  467.  
  468.             case 'n':    /* set # lines per inch on printer */
  469.                 ptr.vpitch = atoi (&arg[i]);
  470.                 optused++;
  471.                 break;
  472.  
  473.             case 'o':    /* output filename */
  474.                 /* strcpy (filename, &arg[i]); */
  475.                 filename = &arg[i];
  476.                 optused++;
  477.                 if (fileopen){
  478.                     fclose (outfile);
  479.                     fileopen = 0;
  480.                 }
  481.                 break;
  482.  
  483.             case 'p':    /* set printer pitch */
  484.                 ptr.hpitch = atoi (&arg[i]);
  485.                 optused++;
  486.                 break;
  487.  
  488.             case 'r':    /* set red value */
  489.                 r_intens = atof (&arg[i]);
  490.                 optused++;
  491.                 break;
  492.  
  493.             case 's':    /* print sideways option */
  494.                 sideopt = !sideopt;
  495.                 break;
  496.  
  497.             case 't':    /* set top edge of screen to print */
  498.                 scr.ystart = atoi (&arg[i]);
  499.                 optused++;
  500.                 break;
  501.  
  502.             case 'u':    /* universal printing option (use backspaces) */
  503.                 universal = 1;
  504.                 break;
  505.  
  506.             case 'v':    /* view file option */
  507.                 viewopt = atoi (&arg[i]);
  508.                 autopt = 0;        /* turns off auto-printing option */
  509.                 optused++;
  510.                 break;
  511.  
  512.             case 'w':    /* set screen width */
  513.                 scr.width = atoi (&arg[i]);
  514.                 optused++;
  515.                 break;
  516.  
  517.             case 'z':    /* just print test pattern */
  518.                 testpat = 1;
  519.                 break;
  520.  
  521.             default:
  522.                 printf ("Unknown option %c\n", c);
  523.                 help (documentation);
  524.             } /* switch (c) */
  525.             c = arg[i];
  526.         } /* while */
  527.         return (0);
  528.     }else
  529.         /* Just a file name */
  530.         return (1);
  531. } /* eval_arg */
  532.  
  533. /* init_graph: Initialize Amiga graphics */
  534. int init_graph()
  535. {
  536.     if ((GfxBase =  OpenLibrary("graphics.library", (long)0)) == NULL){
  537.         printf("Can't open Graphics Library\n");
  538.         return(1);
  539.     }
  540.  
  541.     if ((LayersBase =  OpenLibrary("layers.library", (long)0)) == NULL){
  542.         printf("Can't open Layers Library\n");
  543.         dwip_cleanup();
  544.         return(2);
  545.     }
  546.  
  547.     if ((IntuitionBase =  OpenLibrary("intuition.library",(long)0)) == NULL){
  548.         printf("Can't open Intuition Library\n");
  549.         dwip_cleanup();
  550.         return(3);
  551.     }
  552.  
  553.     if ( (DwipScreen = OpenScreen(&DwipNewScreen) ) == NULL){
  554.         printf("OpenScreen failed\n");
  555.         dwip_cleanup();
  556.         return(4);
  557.     }
  558.  
  559.     InitRastPort(&DwipRastPort);
  560.     DwipRastPort.Mask = (1<<PLANES)-1;  /*just play it safe in case someone
  561.                                          * tries to load 6 bit planes...*/
  562.     return(0);
  563. } /* init_graph */
  564.  
  565. /* outstring: Store a character string in the output buffers.
  566.  * One buffer is used per overstriked character.
  567.  */
  568. void outstring (s, nchar)
  569. char    *s;            /* string of chars to be overlaid */
  570. int        nchar;        /* current position in buffers */
  571. {
  572.     int    i;            /* buffer # */
  573.  
  574.     for (i = 0; i < NBUFS; i++)
  575.         if ((buf[i][nchar] = s[i]) != ' ')
  576.             buf_used[i] = 1;
  577. } /* outstring */
  578.  
  579. /* printscreen: This routine sends out the characters to the printer */
  580. void printscreen()
  581. {
  582.     char    *charshade();
  583.     void    dwip_cleanup(), outstring();
  584.     int        get_shade();
  585.     int    j,                        /* index to bitplanes */
  586.         i,                        /* index to buffers */
  587.         ct,                        /* count of #chars outputted on line */
  588.         shade,                    /* shade of a pixel */
  589.         x, y;                    /* actual screen coord looked at */
  590.     REAL    xskip, yskip;        /* # pixels skipped since last one printed */
  591.  
  592.     if (! fileopen){
  593.         if ((outfile = fopen (filename, "w")) == NULL){
  594.             printf("Couldn't open file %s for output\n", filename);
  595.             help (documentation);
  596.         }
  597.         fileopen = 1;
  598.     }
  599.  
  600.     /* initialize the bitplane pointers */
  601.     nplanes = s_info->bitmap.Depth;
  602.     for (j=0; j < s_info->bitmap.Depth; j++)
  603.         bplane[j] = (char *)s_info->bitmap.Planes[j];
  604.  
  605.     fprintf(outfile,"%s", init_string);
  606.     /* want normal or sideways print? */
  607.     if (! sideopt){
  608.         /* normal printout */
  609.         for (y = scr.ystart, yskip = 0.; y <= scr.ystop; y++){
  610.             yskip += 1.;
  611.             while (yskip > vreduce){
  612.                 /* plot this line */
  613.                 yskip -= vreduce;
  614.                 /* Initialize the line buffers */
  615.                 for (i = 0; i < NBUFS; i++)
  616.                     buf_used[i] = 0;
  617.                 for (x=scr.xstart, xskip=0., ct=0; x <= scr.xstop; x++){
  618.                     xskip += 1.;
  619.                     while (xskip > hreduce){
  620.                         /* plot this pixel */
  621.                         xskip -= hreduce;
  622.                         shade = get_shade (x, y);
  623.                         /* fprintf (outfile, "%s", charshade (shade)); */
  624.                         outstring (charshade (shade), ct++);
  625. #ifdef DEBUG
  626.                         if (ct > ptr.width)
  627.                             printf("Warning: %d chars on line\n", ct);
  628. #endif DEBUG
  629.                     } /* while xskip */
  630.                 } /* for x */
  631.                 /* print out the buffers */
  632.                 for (i = 0; i < NBUFS; i++)
  633.                     if (buf_used[i]){
  634.                         buf[i][ct] = NULL;
  635.                         /* first print the buffer */
  636.                         fprintf (outfile, "%s", buf[i]);
  637.                         /* Now do something to get printhead back to
  638.                          * beginning of line, for overstriking.
  639.                          */
  640.                         if (universal)
  641.                             /* Universal printer output sends backspaces
  642.                              * instead of a carriage return.
  643.                              */
  644.                             for (j = 0; j < ct; j++)
  645.                                 fprintf (outfile, "\010");
  646.                         else
  647.                             /* each buffer followed by carriage return */
  648.                             fprintf (outfile, "\015");
  649.                     }
  650.                 /* the end-of-line string */
  651.                 fprintf(outfile,"%s", eol_string);
  652.             } /* while yskip */
  653.         } /* for y */
  654.     }else{
  655.         /* sideways print */
  656.         for (x = scr.xstart, xskip = 0.; x <= scr.xstop; x++){
  657.             xskip += 1.;
  658.             while (xskip > vreduce){
  659.                 /* plot this line */
  660.                 xskip -= vreduce;
  661.                 /* Initialize the line buffers */
  662.                 for (i = 0; i < NBUFS; i++)
  663.                     buf_used[i] = 0;
  664.                 for (y=scr.ystop, yskip=0., ct=0; y >= scr.ystart; y--){
  665.                     yskip += 1.;
  666.                     while (yskip > hreduce){
  667.                         /* plot this pixel */
  668.                         yskip -= hreduce;
  669.                         shade = get_shade (x, y);
  670.                         /* fprintf (outfile, "%s", charshade (shade)); */
  671.                         outstring (charshade (shade), ct++);
  672.                     } /* while yskip */
  673.                 } /* for y */
  674.                 /* print out the buffers */
  675.                 for (i = 0; i < NBUFS; i++)
  676.                     if (buf_used[i]){
  677.                         buf[i][ct] = NULL;
  678.                         /* first print the buffer */
  679.                         fprintf (outfile, "%s", buf[i]);
  680.                         /* Now do something to get printhead back to
  681.                          * beginning of line, for overstriking.
  682.                          */
  683.                         if (universal)
  684.                             /* Universal printer output sends backspaces
  685.                              * instead of a carriage return.
  686.                              */
  687.                             for (j = 0; j < ct; j++)
  688.                                 fprintf (outfile, "\010");
  689.                         else
  690.                             /* each buffer followed by carriage return */
  691.                             fprintf (outfile, "\015");
  692.                     }
  693.                 /* the end-of-line string */
  694.                 fprintf(outfile,"%s", eol_string);
  695.             } /* while xskip */
  696.         } /* for x */
  697.     } /* if ! sideopt */
  698. } /* printscreen */
  699.  
  700. /* eval_env: Evaluate the DWIP environment variable */
  701. void eval_env()
  702. {
  703.     char *getenv(), *index();
  704.     int eval_arg();
  705.     char *opts;
  706.  
  707.     if (opts = getenv ("DWIP")){
  708.         while (opts){
  709.             if (eval_arg (opts)){
  710.                 /* eval_arg thinks it's a filename; probably just an extra
  711.                  * space between arguments, so ignore
  712.                  */
  713.                 opts++;
  714.             }else{
  715.                 /* advance to next argument */
  716.                 opts = index (opts, ' ');
  717.                 if (opts)
  718.                     opts++;
  719.             }
  720.         } /* while */
  721.     } /* if opts */
  722. } /* eval_env */
  723.  
  724. /* display_pic: Display an IFF picture on the screen, return 1 if
  725.  * successful, 0 if not. */
  726. int display_pic (flnm)
  727. char *flnm;
  728. {
  729.     void help(), set_values(), free_planes(), put_ea_cmap();
  730.     struct ILBM_info *read_iff();
  731.  
  732.     set_values();
  733.  
  734.     if (scrn_alloc){
  735.         free_planes (&s_info->bitmap);
  736.         scrn_alloc = 0;
  737.     }
  738.     if ((s_info = read_iff(flnm, 0)) != NULL){
  739.         scrn_alloc = 1;
  740.         put_ea_cmap(&s_info->cmap, (1 << s_info->bitmap.Depth));
  741.         DwipRastPort.BitMap = &s_info->bitmap;
  742.         ClipBlit( &DwipRastPort, (long)0, (long)0,
  743.             &DwipScreen->RastPort, (long)s_info->header.x, 
  744.             (long)s_info->header.y, (long)s_info->header.w, 
  745.             (long)s_info->header.h, (long)COPY_MINTERM);
  746.         return (1);
  747.     }else
  748.         return (0);
  749. } /* display_pic */
  750.  
  751. /* print_testpat: Print a simple test pattern across the page (5 lines) */
  752. void print_testpat ()
  753. {
  754.     char *charshade();
  755.     void outstring();
  756.     int    ct,        /* # shades of grey */
  757.         l,        /* line # */
  758.         i,        /* buffer # */
  759.         j;        /* ctr for backspaces */
  760.  
  761.     if (! fileopen){
  762.         if ((outfile = fopen (filename, "w")) == NULL){
  763.             printf("Couldn't open file %s for output\n", filename);
  764.             help (documentation);
  765.         }
  766.         fileopen = 1;
  767.     }
  768.  
  769.     for (l = 0; l < 5; l++){
  770.         /* Initialize the line buffers */
  771.         for (i = 0; i < NBUFS; i++)
  772.             buf_used[i] = 0;
  773.         /* Output a continuous line of grey (black to white) */
  774.         for (ct = 0; ct < MAXSHADES; ct++)
  775.             outstring (charshade (ct), ct);
  776.         /* print out the buffers */
  777.         for (i = 0; i < NBUFS; i++){
  778.             if (buf_used[i]){
  779.                 buf[i][ct] = NULL;
  780.                 /* first print the buffer */
  781.                 fprintf (outfile, "%s", buf[i]);
  782.                 /* Now do something to get printhead back to
  783.                  * beginning of line, for overstriking.
  784.                  */
  785.                 if (universal)
  786.                     /* Universal printer output sends backspaces
  787.                      * instead of a carriage return.
  788.                      */
  789.                     for (j = 0; j < ct; j++)
  790.                         fprintf (outfile, "\010");
  791.                 else
  792.                     /* each buffer followed by carriage return */
  793.                     fprintf (outfile, "\015");
  794.             } /* if buf_used */
  795.         } /* for i */
  796.         /* the end-of-line string */
  797.         fprintf(outfile,"%s", eol_string);
  798.     } /* for l */
  799. } /* print_testpat */
  800.  
  801. main (argc, argv)
  802. int argc;
  803. char *argv[];
  804. {
  805.     int        eval_arg(), init_graph(), display_pic();
  806.     void    eval_env(), dwip_cleanup(), printscreen(), print_testpat();
  807.     char    *mktemp();
  808.     int    i,                        /* index to args */
  809.         nfiles = 0;                /* # input files read */
  810.  
  811.     filename = mktemp ("RAM:dwXXXX");
  812.     eval_env();
  813.  
  814.     /* Initialize graphics */
  815.     if (init_graph()){
  816.         dwip_cleanup();
  817.         exit(1);
  818.     }
  819.  
  820.     /* parse the command line */
  821.     for (i=1; i<argc; i++){
  822. #ifdef DEBUG
  823.         puts(argv[i]);
  824. #endif DEBUG
  825.         if (eval_arg (argv[i])){
  826.             nfiles++;
  827.             if (display_pic (argv[i])){
  828.                 if (! viewopt)
  829.                     printscreen();
  830.                 else
  831.                     /* Viewing option: Just pause for specified # seconds */
  832.                     Delay ((long)viewopt * 50);
  833.  
  834.                 free_planes (&s_info->bitmap);
  835.                 scrn_alloc = 0;
  836.             }else /* if display_pic */
  837.                 printf("dwip: Couldn't load %s as an IFF file\n", argv[i]);
  838.         } /* if eval_arg */
  839.     } /* for argv */
  840.     if (nfiles)
  841.         dwip_cleanup();
  842.     else if (testpat){
  843.         print_testpat();
  844.         dwip_cleanup();
  845.     }else{
  846.         printf ("dwip: No files specified.\n");
  847.         help (documentation);
  848.     }
  849. #ifdef NEVER
  850.     /* This didn't work right, so I took it out. Seemed like a nice idea.
  851.      * If anybody knows what I did wrong, let me know. -kvc
  852.      */
  853.     if (autopt)
  854.         execlp ("runback", "runback", "c:type", filename, "to", "PRT:",0);
  855. #endif NEVER
  856. } /* main */
  857.  
  858.