home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 305_01 / emdispla.c < prev    next >
Text File  |  1990-02-14  |  12KB  |  552 lines

  1. /*
  2. TITLE:        EMDISPLAY.C;
  3. DATE:        6/21/88;
  4. DESCRIPTION:    "Printer driver and display utility for Mandelbrot pictures.";
  5. VERSION:    1.04;
  6. KEYWORDS:    Mandelbrot;
  7. FILENAME:    EMDISPLAY.C;
  8. WARNINGS:    "Requires HGA. Supports Epson LX-800 only.";
  9. SEE-ALSO:    MANDEL.DOC, EMANDEL.C, EMDISPLAY.EXE, EMANDEL.EXE, EJULIA.EXE;
  10. SYSTEM:        MS-DOS;
  11. COMPILERS:    Aztec;
  12. AUTHORS:    Dan Schechter;
  13.  */
  14.  
  15. #define DATE " 6/21/88 "
  16. #define VERSION "1.04"
  17.  
  18. char *version = "Emdisplay by Kittensoft. Version " VERSION "-c" DATE ;
  19. char *copyright = "\nCopyright (c) 1988, 1989 by Dan Schechter.\n";
  20.  
  21. #include <stdio.h>
  22. #include <fcntl.h>
  23. #include <string.h>
  24. #include <setjmp.h>
  25. #include <signal.h>
  26.  
  27. void    setmode(int), sleep(void), clearscreen(int), sendch(int),
  28.     strUcpy(char *,char *), tellversion(void), printch(int),
  29.     gl_build(int), virtto0(int), eratline(void),
  30.     print(int), g_write(char *,int), g_putch(int,int,int);
  31. int    getreply(char *), tpr(int), inkey(void), displaypict(char *) ;
  32.  
  33. #define NORMAL 0
  34. #define GRAPHICS 1
  35. #define INDEXPORT 0x3B4
  36. #define CONTROLPORT 0x3b8
  37. #define DATAPORT 0x3b5
  38. #define CONFIGPORT 0x3bf
  39. #define SCREEN_ON 8
  40. #define GRAPH 2
  41. #define TEXT 0x20
  42. #define SCREEN0 0xb0000l 
  43.  
  44. #define FONTADDR 0xffa6e
  45.  
  46. #define P_DATA_NUM 672        /* MUST be divisible by 8 */
  47. #define P_DATA_SIZE 504        /* MUST be divisible by 8 */
  48. #define VIRT_SIZE 43680        /* 672/8 * 504+16      */
  49. #define SCR_H 348
  50. #define LEADLINES 6
  51.  
  52. unsigned char *screen0addr;
  53. unsigned char *font;
  54. unsigned char virtscreen[VIRT_SIZE];
  55. FILE *outfile = (void *)0;
  56. void myputs(char *), sendch(int), help(void);
  57. char *index(char *,int);
  58. int look(int,int);
  59. void exitt(int);
  60.  
  61. char *init = "\033@\0333\030\033?Z\005\033l\005"; 
  62.                 /* init, initsquare, set margin. */
  63.  
  64. char *mask[25];
  65. char _mask[250];
  66.  
  67. int gdata[12] = { 
  68.     0x35, 0x2d, 0x2e, 0x7, 0x5b, 
  69.     0x2, 0x57, 0x57, 0x2, 0x3, 0x0, 0x0 };
  70. int tdata[12] = { 
  71.     0x61, 0x50, 0x52, 0xf, 0x19, 
  72.     0x6, 0x19, 0x19, 0x2, 0xd, 0xb, 0xc };
  73.  
  74. char *cat = "\
  75. \040\040\040\040\057\134\137\057\134\n\
  76. \040\040\040\050\376\040\322\040\376\051\n\
  77. \360\360\360\360\040\304\312\304\040\360\360\360\360\n\
  78. \040\040\040\040\040\042\042\042\n";
  79.  
  80. char darkprint=0,titleblank=0,diskout=0,noask=0;
  81. int leadlines=LEADLINES;
  82. struct { int ax,bx,cx,dx,si,di,ds,es; } iregs,oregs;
  83. jmp_buf env;
  84.  
  85. int main(n,arg)
  86. int n;
  87. char **arg;
  88. {
  89.     char *filename,*scdir();
  90.     void *abstoptr(),*malloc();
  91.     int i,namecount,cut;
  92.     int fd,stop=0,lf=030;
  93.     char *wp;
  94.     char *namelist[200];
  95.     
  96.     if ((n==2)&&(arg[1][0]=='?')&&(arg[1][1]==0)){
  97.         help();
  98.         exit(0);
  99.     }
  100.     if ((n>1)&&(arg[n-1][0]=='/')){
  101.         n--;
  102.         for (i=1;arg[n][i];i++) switch(tpr(arg[n][i])){
  103.             case 'D': darkprint=1; break;
  104.             case '^': leadlines=0; break;
  105.             case 'Z': diskout=1; break;
  106.             case 'N': noask=1; break;
  107.             case '2': iregs.dx=1; break;
  108.             case '3': iregs.dx=2; break;
  109.             case '?': help(); exit(0);
  110.             case 'F': 
  111.                 switch(arg[n][++i]){
  112.                     case '+': init[4]++; 
  113.                           if (leadlines>1) leadlines-=2;
  114.                           break;
  115.                     case '-': init[4]--; 
  116.                           if (leadlines) leadlines+=2;
  117.                           break;
  118.                     default: 
  119.                         myputs("\nInvalid F.\n");
  120.                         help();
  121.                         exit(0);
  122.                 }
  123.                 break;
  124.         }
  125.     }
  126.     if (n==1) mask[0]="*.PIC";
  127.     else {
  128.         for (wp=_mask,i=1;i<n;i++){
  129.             mask[i-1]=wp;
  130.             strcpy(wp,arg[i]);
  131.             if (!index(wp,'.')) strcat(wp,".PIC");
  132.             wp+=strlen(wp)+1;
  133.         }
  134.         n--;
  135.     }
  136.     tellversion();
  137.     if (diskout) {
  138.         if ((outfile=fopen("EPT.DAT","w"))==0){
  139.             myputs("Can't open EPT.DAT");
  140.             exit(1);
  141.         }
  142.         else myputs("Disk file output.");
  143.     }
  144.     if (n==1) myputs("\nMask = ");
  145.     else myputs("\nMasks = ");
  146.     for (i=0;i<n;i++){
  147.         myputs(mask[i]);
  148.         putchar(' ');
  149.     }
  150.     putchar('\n');
  151.     if (leadlines) myputs("Auto adv.");
  152.     else myputs("Zero adv.");
  153.     if (darkprint) myputs(" Dark print.");
  154.     else myputs(" Light print.");
  155.     if (titleblank) myputs(" No title.");
  156.     if (!diskout) switch ( iregs.dx ){
  157.         case 0: myputs(" LPT1"); break;
  158.         case 1: myputs(" LPT2"); break;
  159.         case 2: myputs(" LPT3"); break;
  160.     }
  161.     if (init[4]!=lf){
  162.         myputs(" Lf");
  163.         if (init[4]>lf) while ((lf++)<init[4]) putchar('+');
  164.         else while ((lf--)>init[4]) putchar('-');
  165.         putchar('.');
  166.     }
  167.     myputs("\nPress ^C to abort. Any other key to begin. ");
  168.     if (scr_getc()==3) exit(0);
  169.     
  170.     screen0addr=abstoptr(SCREEN0);
  171.     font=abstoptr(FONTADDR);
  172.  
  173.     for (i=namecount=0;i<n;i++){
  174.         while (filename=scdir(mask[i])) {
  175.             if ((namelist[namecount]=malloc(1+strlen(filename)))==0){
  176.                 myputs("malloc error.");
  177.                 exit(1);
  178.             }
  179.             strUcpy(namelist[namecount++],filename);
  180.         }
  181.     }
  182.     if (!namecount) {
  183.         myputs("\n\n   *** No files. ***\n");
  184.         exit(1);
  185.     }
  186.     signal(SIGINT,(void (*)(int))exitt);    
  187.     setmode(GRAPHICS);
  188.     for(i=0;;i++){
  189.         if (i==namecount) {
  190.             if (noask) break;
  191.             i=0;
  192.         }
  193.         if (i==-1) i=namecount-1;
  194.         setjmp(env);
  195.         if (displaypict(namelist[i])<0) {
  196.             if (noask) continue;
  197.             clearscreen(0);
  198.             g_write(namelist[i],162);
  199.             g_write("is not a PIC file.",174);
  200.             g_write("Press ESC to exit. Any other key to continue...",186);
  201.             switch (scr_getc()){
  202.                 case 27: 
  203.                 case 3:  exitt(1);
  204.                 default: continue;
  205.             }
  206.         }
  207.         g_write(namelist[i],319);
  208.         cut=0;
  209.         if (noask) print(darkprint);
  210.         else for(;;){
  211.             g_write("(P)rint e(X)xit (M)ask (\032) (\033)",330);
  212.             switch(getreply(" pbmx\231\313\310\307\317\033\315\320")) {
  213.                 case 'p': print(darkprint); break;
  214.     /* ALT-P */        case 153: print(darkprint^1); break;
  215.     /* La */        case 203:
  216.     /* Ua */        case 200:
  217.                 case 'b': i-=2; break;
  218.     /* Home */        case 199: i= -1; break;
  219.     /* End */        case 207: i= namecount-2; break;
  220.                 case 'm': cut++; 
  221.                       virtto0(cut%3); 
  222.                       g_write(namelist[i],319);
  223.                       continue;
  224.                 case ' ':
  225.     /* Ra */        case 205:
  226.     /* Da */        case 208: break;
  227.                 case 'x':
  228.                 case 27:  
  229.                 case 3:   exitt(0);
  230.             }
  231.             break;
  232.         }
  233.     }
  234.     exitt(0);
  235. }
  236.  
  237. /* v and h are pixel addresses, not col, line */
  238. void g_write(s,v)
  239. char *s;
  240. int v;
  241. {
  242.     int gh=0;
  243.     
  244.     while (*s) g_putch(*s++,v,gh++);
  245.     g_putch(' ',v,gh);
  246. }
  247. void g_putch(c,v,x)
  248. int c,x,v;
  249. {
  250.     int i,j,y;
  251.     unsigned char dat,mask;
  252.     unsigned off;
  253.     
  254.     for (y=v-2;y<v+10;y++){
  255.         off=(unsigned)( 0x2000 * (y%4) + 90*(y/4) + x);
  256.         screen0addr[off]=0;
  257.     }
  258.     for (y=v,i=0;i<8;i++,y++){
  259.         off=(unsigned)( 0x2000 * (y%4) + 90*(y/4) + x);
  260.         dat=font[c*8+i];
  261.         screen0addr[off]=dat;
  262.     }
  263. }
  264.  
  265. void setmode(q)
  266. int q;
  267. {
  268.     unsigned i;
  269.     
  270.     switch (q) {
  271.         case GRAPHICS:
  272.                 putchar(10);
  273.                 outportb(CONFIGPORT,3);
  274.                 outportb(CONTROLPORT,2);
  275.                 for(i=0;i<12;i++){
  276.                     outportb(INDEXPORT,i);
  277.                     outportb(DATAPORT,gdata[i]);
  278.                 }
  279.                 sleep();
  280.                 clearscreen(0);
  281.                 outportb(CONTROLPORT,10);
  282.                 break;
  283.         case NORMAL:
  284.                 clearscreen(0);
  285.                 outportb(CONTROLPORT,0);
  286.                 for(i=0;i<12;i++){
  287.                     outportb(INDEXPORT,i);
  288.                     outportb(DATAPORT,tdata[i]);
  289.                 }
  290.                 sleep();
  291.                 outportb(CONTROLPORT,61);
  292.                 outportb(CONFIGPORT,0);
  293.                 scr_clear();
  294.                 break;
  295.     }
  296. }
  297. void sleep()
  298. {
  299.     long i,clock();
  300.     
  301.     i=clock();
  302.     while ( clock()-i <100 );
  303. }
  304. int displaypict(name)
  305. char *name;
  306. {
  307.     FILE *fp;
  308.     int f;
  309.     unsigned pic_size;
  310.     int i,height,xwidth,topskip,leftskip;
  311.     unsigned char scanline[P_DATA_NUM];
  312.     char trash[160];
  313.     
  314.     clearscreen(1);
  315.     if ((f=open(name,O_RDONLY,0))==(-1)) return(-1);
  316.     
  317.     read(f,&trash,160);
  318.     read(f,(char *)&height,2);
  319.     read(f,(char *)&xwidth,2);
  320.     if ((height>P_DATA_SIZE)||(height<=0)||(xwidth>P_DATA_NUM)||(xwidth<=0))
  321.         return(-2);
  322.     
  323.     topskip= (P_DATA_SIZE - height)/2;    /* scan lines */
  324.     leftskip= (P_DATA_NUM - xwidth)/16;    /* bytes */
  325.     
  326.     pic_size= (long)height*(long)xwidth/8l;
  327.     
  328.     read(f,virtscreen,pic_size);
  329.     for (i=0;i<8;i++)
  330.         read(f,virtscreen+VIRT_SIZE-P_DATA_NUM+(i*(P_DATA_NUM/8)),P_DATA_NUM/8);
  331.     close(f);
  332.     
  333.     for (i=height;i>=0;i--){
  334.         memcpy(scanline,virtscreen+i*(xwidth/8),xwidth/8);
  335.         memset(virtscreen+i*(xwidth/8),0,xwidth/8);
  336.         memcpy(virtscreen+((i+topskip)*(P_DATA_NUM/8))+leftskip,scanline,xwidth/8);
  337.     }
  338.     virtto0(0);
  339.     return(0);
  340. }
  341. void clearscreen(q)
  342. int q;
  343. {
  344.     switch (q){
  345.         case 0:    memset(screen0addr,0,(unsigned)32768); 
  346.         case 1:    memset(virtscreen,0,(unsigned)VIRT_SIZE); 
  347.     }
  348. }
  349. int tpr(c)
  350. int c;
  351. {
  352.     if ((c>='a')&&(c<='z')) c ^= 32;
  353.     return(c);
  354. }
  355. void myputs(s)
  356. char *s;
  357. {
  358.     while (*s) putchar(*s++);
  359. }
  360.  
  361. int look(v,h)
  362. int h,v;
  363. {
  364.     unsigned off;
  365.     
  366.     off = (P_DATA_NUM/8)*v + h/8;
  367.     
  368.     return(virtscreen[off]);
  369. }
  370. void help()
  371. {
  372.     myputs("\
  373. -------------------------------------------\n");
  374.     tellversion();
  375.     myputs("\
  376. View Emandel pictures and print on Epson LX-800 printer.\n\
  377. -------------------------------------------\n\
  378. Usage: EMDISPLAY <filename> [/<options>]\n\
  379. Filename may contain wild cards. Filetype PIC is assumed but may be overridden.\n");
  380.     myputs("\
  381.                                 Options:\n\
  382. F+ Increase line feed by 1/216 in.  |   2  Use LPT2.\n\
  383. F- Decrease line feed by 1/216 in.  |   3  Use LPT3.\n\
  384. ^  Don't advance paper at top.      |   D  Print dark.\n\
  385. Z  Send output to disk file.        |   N  Print without asking.\n"
  386. "?  Help. Show this message.\n\
  387. -------------------------------------------------------------------\n\
  388. See MANDEL.DOC for detailed instructions.");
  389. }
  390.  
  391. void print(darkprint)
  392. int darkprint;
  393. {
  394.     int i,j,line,dat,v,darktoggle=0;
  395.         
  396.     for (i=0;init[i];i++) {
  397.         if (i==4) sendch(init[4]-darkprint);
  398.         else sendch(init[i]);
  399.     }
  400.     i=0;
  401.     for(;i<leadlines;i++) sendch('\n');
  402.     gl_build(-2);
  403.     for (line=0;line<P_DATA_NUM;line+=8){
  404.         if (titleblank) 
  405.             for (i=16;i;i--) gl_build(0);
  406.         for (v=(titleblank)?(P_DATA_SIZE-1):P_DATA_SIZE+15;v>=0;v--){
  407.             dat=look(v,line);
  408.             gl_build(dat);
  409.         }
  410.         gl_build(-1);
  411.  
  412.         if (scr_poll()!=(-1)){
  413.             if (scr_getc()==3){
  414.                 sendch(12);
  415.                 return;
  416.             }
  417.         }
  418.         if (darkprint){
  419.             darktoggle ^= 1;
  420.             if (darktoggle){
  421.                 sendch(13);
  422.                 sendch(27);
  423.                 sendch('J');
  424.                 sendch(1);
  425.                 line-=8;
  426.                 continue;
  427.             }
  428.         }
  429.         sendch(13);
  430.         sendch(10);
  431.     }
  432.     sendch(10);
  433.     sendch(12);    /* Form feed. */
  434. }
  435. void sendch(c)
  436. int c;
  437. {
  438.     if (outfile) putc(c,outfile);
  439.     else printch(c);
  440. }
  441. void printch(c)
  442. int c;
  443. {
  444.     
  445.     iregs.ax= 2<<8;
  446.     sysint(0x17,&iregs,&oregs);
  447.     if ( (oregs.ax>>8) & 32) {
  448.         putchar(7);
  449.         g_write("Printer out of paper. (A)bort e(X)it (R)etry? ",308);
  450.         switch( getreply("xra\003")){
  451.             case 'x': 
  452.             case 3:   exitt(1);
  453.             case 'r': 
  454.                   g_write("                                               ",308);
  455.                   printch(c);
  456.                   return;
  457.             case 'a': longjmp(env,'p');
  458.         }
  459.     }
  460.     if ( (oregs.ax>>8) & 8) {
  461.         putchar(7);
  462.         g_write("Printer I/O error. (A)bort e(X)it (R)etry? ",308);
  463.         switch( getreply("xra\003")){
  464.             case 'x': 
  465.             case 3:   exitt(1);
  466.             case 'r': 
  467.                   g_write("                                               ",308);
  468.                   printch(c);
  469.                   return;
  470.             case 'a': longjmp(env,'e');
  471.         }
  472.     }
  473.     iregs.ax=c;
  474.     sysint(0x17,&iregs,&oregs);
  475. }
  476. int getreply(s)
  477. char *s;
  478. {
  479.     int c;
  480.     unsigned char *p;
  481.     
  482.     for(;;){
  483.         c=scr_getc();
  484.         if ((c>='A')&&(c<='Z')) c ^= 32;
  485.         for (p=(unsigned char *)s;*p;p++) if (*p==c) return c;
  486.     }
  487. }
  488. void exitt(q)
  489. int q;
  490. {
  491.     setmode(NORMAL);
  492.     signal(SIGINT,SIG_DFL);
  493.     myputs(cat);
  494.     tellversion(); 
  495.     exit(q);
  496. }
  497. void strUcpy(s1,s2)
  498. char *s1,*s2;
  499. {
  500.     while (*s2) *(s1++) = tpr( *s2++ );
  501.     *s1=0;
  502. }
  503. void tellversion()
  504. {
  505.     int t,mask;
  506.  
  507.     myputs(version);
  508.     myputs(copyright);
  509. }
  510. void gl_build(c)
  511. int c;
  512. {
  513.     static int pline[P_DATA_SIZE+100],plinecount;
  514.     int i;
  515.     
  516.     if (c==-2) {
  517.         plinecount=0;
  518.         return;
  519.     }
  520.     if (c==-1) {
  521.         if (plinecount==0) return;
  522.         while ( !pline[plinecount-1] ) {
  523.             plinecount--;
  524.             if (plinecount==0) return;
  525.         }
  526.         sendch(27);
  527.         sendch('Z');
  528.         sendch(plinecount%256);
  529.         sendch(plinecount/256);
  530.         for(i=0;i<plinecount;i++) sendch( pline[i] );
  531.         plinecount=0;
  532.         return;
  533.     }
  534.     pline[plinecount++]=c;
  535. }
  536. void virtto0(cut)
  537. int cut;
  538. {
  539.     int line0,linevirt;
  540.     unsigned off0,offvirt;
  541.     
  542.     for (line0=linevirt=0;line0<SCR_H;linevirt++){
  543.         if ((line0<SCR_H-8)&&(linevirt%3==cut)) continue;
  544.         if ((line0==SCR_H-8)&&(linevirt>=P_DATA_SIZE)&&(linevirt<P_DATA_SIZE+8)) 
  545.             continue;
  546.         off0=(unsigned)( 0x2000 * (line0%4) + 90*(line0/4) );
  547.         offvirt= (unsigned)(P_DATA_NUM/8)*linevirt ;
  548.         memcpy(screen0addr+off0,virtscreen+offvirt,P_DATA_NUM/8);
  549.         line0++;
  550.     }
  551. }
  552.