home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: DFÜ und Kommunikation / SOS-DFUE.ISO / programm / dos / utility / pccp076 / viewpcx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-16  |  21.3 KB  |  1,057 lines

  1. /* Copyright 1992, 1993 Peter Edward Cann, all rights reserved */
  2.  
  3. #include<stdio.h>
  4. #include<fcntl.h>
  5. #include<sys\types.h>
  6. #include<sys\stat.h>
  7. #include<bios.h>
  8. #include<dos.h>
  9. #include<graph.h>
  10. #include<stdlib.h>
  11. #include<malloc.h>
  12.  
  13. struct header_s
  14.     {
  15.     unsigned char mfgr;
  16.     unsigned char version;
  17.     unsigned char encoding;
  18.     unsigned char bppix;
  19.     unsigned short xmin;
  20.     unsigned short ymin;
  21.     unsigned short xmax;
  22.     unsigned short ymax;
  23.     unsigned short hdpi;
  24.     unsigned short vdpi;
  25.     unsigned char cmap[48];
  26.     unsigned char reserved;
  27.     unsigned char nplanes;
  28.     unsigned short bypl;
  29.     unsigned short paltinf;
  30.     unsigned short hscrnsz;
  31.     unsigned short vscrnsz;
  32.     unsigned char filler[54];
  33.     };
  34.  
  35. struct header_s header;
  36.  
  37. unsigned long tick;
  38.  
  39. void (interrupt far *oldtick)();
  40.  
  41. void interrupt far tickhndl()
  42.     {
  43.     tick++;
  44.     }
  45.  
  46. struct lrunode
  47.     {
  48.     char prev;
  49.     char which;
  50.     char next;
  51.     }
  52.     lru[20];
  53.  
  54. char lruhead, lrutail, nlru, cachetab[128];
  55.  
  56. unsigned char *buf[20];
  57. char nblocks, swapsize;
  58.  
  59. int swapfd;
  60.  
  61. xseek(which)
  62.     char which;
  63.     {
  64.     if(!swapsize)
  65.         if((swapfd=open("viewpcx.swp", O_RDWR|O_BINARY|O_CREAT|O_TRUNC, S_IWRITE))==-1)
  66.             {
  67.             _setvideomode(_DEFAULTMODE);
  68.             printf("Swap open error.\n");
  69.             exit(43);
  70.             }
  71.     if(which>swapsize)
  72.         {
  73.         if(lseek(swapfd, (long)swapsize<<15, SEEK_SET)==(long)-1)
  74.             {
  75.             _setvideomode(_DEFAULTMODE);
  76.             printf("Swap grow seek error; existing banks %d.\n", (int)swapsize);
  77.             exit(70);
  78.             }
  79.         while(which>swapsize)
  80.             {
  81.             if(write(swapfd, buf[0], 32768)!=(unsigned)32768)
  82.                 {
  83.                 _setvideomode(_DEFAULTMODE);
  84.                 printf("Swap grow write error, existing banks %d.\n", (int)swapsize);
  85.                 exit(44);
  86.                 }
  87.             swapsize++;
  88.             }
  89.         }
  90.     if(which==swapsize)
  91.         swapsize++; /* We trust us to write. */
  92.     if(lseek(swapfd, ((long)which)<<15, SEEK_SET)==(long)-1)
  93.         {
  94.         _setvideomode(_DEFAULTMODE);
  95.         printf("Swap seek error, bank %d.\n", which);
  96.         exit(42);
  97.         }
  98.     }
  99.  
  100. char getcache()
  101.     {
  102.     char tmp;
  103.     if(!nlru)
  104.         {
  105.         lruhead=lrutail=(char)0;
  106.         lru[0].prev=lru[0].next=(char)-1;
  107.         return(nlru++);
  108.         }
  109.     if(nlru<nblocks)
  110.         {
  111.         lru[nlru].prev=(char)-1;
  112.         lru[nlru].next=lruhead;
  113.         lru[lruhead].prev=nlru;
  114.         lruhead=nlru;
  115.         return(nlru++);
  116.         }
  117.     xseek(lru[lrutail].which);
  118.     if(write(swapfd, buf[lrutail], 32768)!=(unsigned)32768)
  119.         {
  120.         _setvideomode(_DEFAULTMODE);
  121.         printf("Swap write error, buf[%d].\n", lrutail);
  122.         exit(41);
  123.         }
  124.     cachetab[lru[lrutail].which]=(char)-1;
  125.     tmp=lrutail;
  126.     lrutail=lru[tmp].prev;
  127.     lru[lrutail].next=(char)-1;
  128.     lru[tmp].prev=(char)-1;
  129.     lru[tmp].next=lruhead;
  130.     lru[lruhead].prev=tmp;
  131.     lruhead=tmp;
  132.     return(tmp);
  133.     }
  134.  
  135. char ntotal;
  136.  
  137. unsigned char *getnew()
  138.     {
  139.     char cachepos;
  140.     if(ntotal>=127)
  141.         {
  142.         _setvideomode(_DEFAULTMODE);
  143.         printf("Too much storage requested.\n");
  144.         exit(45);
  145.         }
  146.     cachepos=getcache();
  147.     cachetab[ntotal]=cachepos;
  148.     lru[cachepos].which=ntotal++;
  149.     return(buf[cachepos]);
  150.     }
  151.  
  152. unsigned char *fetch(which)
  153.     char which;
  154.     {
  155.     char cachepos, prevcp, nextcp;
  156.     if((cachepos=cachetab[which])!=-1)
  157.         {
  158.         if(cachepos==lruhead)
  159.             return(buf[cachepos]);
  160.         if(cachepos==lrutail)
  161.             {
  162.             lrutail=lru[cachepos].prev;
  163.             lru[lrutail].next=(char)-1;
  164.             lru[lruhead].prev=cachepos;
  165.             lru[cachepos].next=lruhead;
  166.             lru[cachepos].prev=(char)-1;
  167.             lruhead=cachepos;
  168.             return(buf[cachepos]);
  169.             }
  170.         prevcp=lru[cachepos].prev;
  171.         nextcp=lru[cachepos].next;
  172.         lru[prevcp].next=nextcp;
  173.         lru[nextcp].prev=prevcp;
  174.         lru[cachepos].next=lruhead;
  175.         lru[cachepos].prev=(char)-1;
  176.         lru[lruhead].prev=cachepos;
  177.         lruhead=cachepos;
  178.         return(buf[cachepos]);
  179.         }
  180.     cachepos=getcache();
  181.     lru[cachepos].which=which;
  182.     xseek(which);
  183.     if(read(swapfd, buf[cachepos], 32768)!=(unsigned)32768)
  184.         {
  185.         _setvideomode(_DEFAULTMODE);
  186.         printf("Swap read error, buf[%d].\n", cachepos);
  187.         exit(46);
  188.         }
  189.     cachetab[which]=cachepos;
  190.     return(buf[cachepos]);
  191.     }
  192.  
  193. #define INS 0x5200
  194. #define DEL 0x5300
  195. #define HOME 0x4700
  196. #define END 0x4f00
  197. #define PGUP 0x4900
  198. #define PGDN 0x5100
  199. #define UP 0x4800
  200. #define DN 0x5000
  201. #define LT 0x4b00
  202. #define RT 0x4d00
  203. #define ESC 0x011b
  204.  
  205. unsigned char barr1[1024], barr2[1024], barr3[1024], bassack[256];
  206. unsigned char bbarr1[1024], bbarr2[1024], bbarr3[1024];
  207.  
  208. /* If you want to get rid of the black-priority feature in the zoom
  209.  * mode, I think you do it here, in the table preparation.
  210.  * If you want to recover some speed by doing that, remove the
  211.  * shifty stuff from the z-whatever-redisplay functions.
  212.  */
  213.  
  214. mkbtab()
  215.     {
  216.     int i, j;
  217.     for(i=0;i<256;++i)
  218.         {
  219.         bassack[i]=0;
  220.         for(j=0;j<8;++j)
  221.             if(i&(1<<j))
  222.                 bassack[i]|=(((unsigned char)0x80)>>j);
  223.         }
  224.     for(i=0;i<1024;i++)
  225.         {
  226.         barr1[i]=barr2[i]=barr3[i]=bbarr1[i]=bbarr2[i]=bbarr3[i]=0;
  227.         /* There's probably a faster way to handle this,
  228.          * but every time I try, I bomb! */
  229.         if((i&0xe0)==0xe0)
  230.             {
  231.             barr1[i]|=0x80;
  232.             bbarr1[i]|=0x01;
  233.             }
  234.         if((i&0x1c)==0x1c)
  235.             {
  236.             barr1[i]|=0x40;
  237.             bbarr1[i]|=0x02;
  238.             }
  239.         if((i&0x380)==0x380)
  240.             {
  241.             barr2[i]|=0x20;
  242.             bbarr2[i]|=0x04;
  243.             }
  244.         if((i&0x70)==0x70)
  245.             {
  246.             barr2[i]|=0x10;
  247.             bbarr2[i]|=0x08;
  248.             }
  249.         if((i&0x0e)==0x0e)
  250.             {
  251.             barr2[i]|=0x08;
  252.             bbarr2[i]|=0x10;
  253.             }
  254.         if((i&0x1c0)==0x1c0)
  255.             {
  256.             barr3[i]|=0x04;
  257.             bbarr3[i]|=0x20;
  258.             }
  259.         if((i&0x38)==0x38)
  260.             {
  261.             barr3[i]|=0x02;
  262.             bbarr3[i]|=0x40;
  263.             }
  264.         if((i&0x07)==0x07)
  265.             {
  266.             barr3[i]|=0x01;
  267.             bbarr3[i]|=0x80;
  268.             }
  269.         }
  270.     }
  271.  
  272. unsigned uibpl, uiheight;
  273. int vheight, vbpl, leftbyte, topline, iheight, ibpl;
  274. long  vidbase;
  275.  
  276. normredisplay()
  277.     {
  278.     long l, l1, lvid, bvid;
  279.     unsigned llocnt;
  280.     int byte, lcnt, bcnt, llo, lhi, ibcnt, ilcnt;
  281.     unsigned char *arr;
  282.     for(l=((long)topline*ibpl), lvid=vidbase, lcnt=vheight, ilcnt=iheight-topline;lcnt--;l+=ibpl, lvid+=vbpl)
  283.         if(ilcnt)
  284.             {
  285.             ilcnt--;
  286.             l1=l+leftbyte;
  287.             lhi=(l1>>15)&0x0f;
  288.             arr=fetch(lhi);
  289.             llo=l1&0x7fff;
  290.             llocnt=32768-llo;
  291.             arr=&arr[llo];
  292.             for(bvid=lvid, bcnt=vbpl, ibcnt=ibpl-leftbyte;bcnt--;++bvid)
  293.                 if(ibcnt--)
  294.                     {
  295.                     (*(unsigned char *)bvid)=*arr++;
  296.                     if(!(--llocnt))
  297.                         {
  298.                         llocnt=32768;
  299.                         arr=fetch(++lhi);
  300.                         }
  301.                     }
  302.                 else
  303.                     {
  304.                     ibcnt++; /* Cancel 0-- */
  305.                     (*(unsigned char *)bvid)=0;
  306.                     }
  307.             }
  308.         else
  309.             for(bvid=lvid,bcnt=vbpl;bcnt--;bvid++)
  310.                 (*(unsigned char *)bvid)=0;
  311.     }
  312.  
  313. normredisplay180()
  314.     {
  315.     long l, l1, lvid, bvid;
  316.     unsigned llocnt;
  317.     int byte, lcnt, bcnt, llo, lhi, ibcnt, ilcnt;
  318.     unsigned char *arr;
  319.     for(l=((long)topline*ibpl), lvid=vidbase+(((long)vbpl)*vheight)-1, lcnt=vheight, ilcnt=iheight-topline;lcnt--;l+=ibpl, lvid-=vbpl)
  320.         if(ilcnt)
  321.             {
  322.             ilcnt--;
  323.             l1=l+leftbyte;
  324.             lhi=(l1>>15)&0x0f;
  325.             arr=fetch(lhi);
  326.             llo=l1&0x7fff;
  327.             llocnt=32768-llo;
  328.             arr=&arr[llo];
  329.             for(bvid=lvid, bcnt=vbpl, ibcnt=ibpl-leftbyte;bcnt--;--bvid)
  330.                 if(ibcnt--)
  331.                     {
  332.                     (*(unsigned char *)bvid)=bassack[*arr++];
  333.                     if(!(--llocnt))
  334.                         {
  335.                         llocnt=32768;
  336.                         arr=fetch(++lhi);
  337.                         }
  338.                     }
  339.                 else
  340.                     {
  341.                     ibcnt++; /* Cancel 0-- */
  342.                     (*(unsigned char *)bvid)=0;
  343.                     }
  344.             }
  345.         else
  346.             for(bvid=lvid,bcnt=vbpl;bcnt--;bvid--)
  347.                 (*(unsigned char *)bvid)=0;
  348.     }
  349.  
  350. hercredisplay()
  351.     {
  352.     long l, l1, lvid, bvid;
  353.     unsigned llocnt;
  354.     int byte, line, lcnt, bcnt, llo, lhi, ibcnt, ilcnt;
  355.     unsigned char *arr;
  356.     for(l=((long)topline*ibpl), line=0, lcnt=vheight, ilcnt=iheight-topline;lcnt--;l+=ibpl, ++line)
  357.         {
  358.         lvid=vidbase+(((line>>2)&0xff)*90)+((line&3)<<13);
  359.         if(ilcnt)
  360.             {
  361.             ilcnt--;
  362.             l1=l+leftbyte;
  363.             lhi=(l1>>15)&0x0f;
  364.             arr=fetch(lhi);
  365.             llo=l1&0x7fff;
  366.             llocnt=32768-llo;
  367.             arr=&arr[llo];
  368.             for(bvid=lvid, bcnt=vbpl, ibcnt=ibpl-leftbyte;bcnt--;++bvid)
  369.                 if(ibcnt--)
  370.                     {
  371.                     (*(unsigned char *)bvid)=*arr++;
  372.                     if(!(--llocnt))
  373.                         {
  374.                         llocnt=32768;
  375.                         arr=fetch(++lhi);
  376.                         }
  377.                     }
  378.                 else
  379.                     {
  380.                     ibcnt++;
  381.                     (*(unsigned char *)bvid)=0;
  382.                     }
  383.             }
  384.         else
  385.             for(bvid=lvid,bcnt=vbpl;bcnt--;bvid++)
  386.                 (*(unsigned char *)bvid)=0;
  387.         }
  388.     }
  389.  
  390. hercredisplay180()
  391.     {
  392.     long l, l1, lvid, bvid;
  393.     unsigned llocnt;
  394.     int byte, line, lcnt, bcnt, llo, lhi, ibcnt, ilcnt;
  395.     unsigned char *arr;
  396.     for(l=((long)topline*ibpl), line=vheight-1, lcnt=vheight, ilcnt=iheight-topline;lcnt--;l+=ibpl, --line)
  397.         {
  398.         lvid=vidbase+(((line>>2)&0xff)*90)+((line&3)<<13);
  399.         if(ilcnt)
  400.             {
  401.             ilcnt--;
  402.             l1=l+leftbyte;
  403.             lhi=(l1>>15)&0x0f;
  404.             arr=fetch(lhi);
  405.             llo=l1&0x7fff;
  406.             llocnt=32768-llo;
  407.             arr=&arr[llo];
  408.             for(bvid=lvid+vbpl-1, bcnt=vbpl, ibcnt=ibpl-leftbyte;bcnt--;--bvid)
  409.                 if(ibcnt--)
  410.                     {
  411.                     (*(unsigned char *)bvid)=bassack[*arr++];
  412.                     if(!(--llocnt))
  413.                         {
  414.                         llocnt=32768;
  415.                         arr=fetch(++lhi);
  416.                         }
  417.                     }
  418.                 else
  419.                     {
  420.                     ibcnt++;
  421.                     (*(unsigned char *)bvid)=0;
  422.                     }
  423.             }
  424.         else
  425.             for(bvid=lvid,bcnt=vbpl;bcnt--;bvid++)
  426.                 (*(unsigned char *)bvid)=0;
  427.         }
  428.     }
  429.  
  430. znormredisplay()
  431.     {
  432.     long l, l1, lvid, bvid;
  433.     unsigned llocnt;
  434.     int byte, lcnt, bcnt, llo, lhi, ibcnt, ilcnt, zibpl, bai;
  435.     unsigned char *arr;
  436.     zibpl=ibpl*3;
  437.     for(l=((long)topline*ibpl), lvid=vidbase, lcnt=vheight, ilcnt=(iheight-topline)/3;lcnt--;l+=zibpl, lvid+=vbpl)
  438.         if(ilcnt)
  439.             {
  440.             ilcnt--;
  441.             l1=l+leftbyte;
  442.             lhi=(l1>>15)&0x0f;
  443.             arr=fetch(lhi);
  444.             llo=l1&0x7fff;
  445.             llocnt=32768-llo;
  446.             arr=&arr[llo];
  447.             for(bai=0xff, bvid=lvid, bcnt=vbpl, ibcnt=ibpl-leftbyte;bcnt--;++bvid)
  448.                 if(ibcnt--)
  449.                     {
  450.                     (*(unsigned char *)bvid)=barr1[bai=(*arr++)];
  451.                     if(!(--llocnt))
  452.                         {
  453.                         llocnt=32768;
  454.                         arr=fetch(++lhi);
  455.                         }
  456.                     if(ibcnt--)
  457.                         {
  458.                         (*(unsigned char *)bvid)|=barr2[bai=(((bai<<8)|(*arr++))&0x3ff)];
  459.                         if(!(--llocnt))
  460.                             {
  461.                             llocnt=32768;
  462.                             arr=fetch(++lhi);
  463.                             }
  464.                         if(ibcnt--)
  465.                             {
  466.                             (*(unsigned char *)bvid)|=barr3[bai=(((bai<<8)|(*arr++))&0x1ff)];
  467.                             if(!(--llocnt))
  468.                                 {
  469.                                 llocnt=32768;
  470.                                 arr=fetch(++lhi);
  471.                                 }
  472.                             }
  473.                         else
  474.                             ibcnt++;
  475.                         }
  476.                     else
  477.                         ibcnt++;
  478.                     }
  479.                 else
  480.                     {
  481.                     ibcnt++;
  482.                     (*(unsigned char *)bvid)=0;
  483.                     }
  484.             }
  485.         else
  486.             for(bvid=lvid,bcnt=vbpl;bcnt--;bvid++)
  487.                 (*(unsigned char *)bvid)=0;
  488.     }
  489.  
  490. znormredisplay180()
  491.     {
  492.     long l, l1, lvid, bvid;
  493.     unsigned llocnt;
  494.     int byte, lcnt, bcnt, llo, lhi, ibcnt, ilcnt, zibpl, bai;
  495.     unsigned char *arr;
  496.     zibpl=ibpl*3;
  497.     for(l=((long)topline*ibpl), lvid=vidbase+(((long)vbpl)*vheight)-1, lcnt=vheight, ilcnt=(iheight-topline)/3;lcnt--;l+=zibpl, lvid-=vbpl)
  498.         if(ilcnt)
  499.             {
  500.             ilcnt--;
  501.             l1=l+leftbyte;
  502.             lhi=(l1>>15)&0x0f;
  503.             arr=fetch(lhi);
  504.             llo=l1&0x7fff;
  505.             llocnt=32768-llo;
  506.             arr=&arr[llo];
  507.             for(bai=0xff, bvid=lvid, bcnt=vbpl, ibcnt=ibpl-leftbyte;bcnt--;--bvid)
  508.                 if(ibcnt--)
  509.                     {
  510.                     (*(unsigned char *)bvid)=bbarr1[bai=(*arr++)];
  511.                     if(!(--llocnt))
  512.                         {
  513.                         llocnt=32768;
  514.                         arr=fetch(++lhi);
  515.                         }
  516.                     if(ibcnt--)
  517.                         {
  518.                         (*(unsigned char *)bvid)|=bbarr2[bai=(((bai<<8)|(*arr++))&0x3ff)];
  519.                         if(!(--llocnt))
  520.                             {
  521.                             llocnt=32768;
  522.                             arr=fetch(++lhi);
  523.                             }
  524.                         if(ibcnt--)
  525.                             {
  526.                             (*(unsigned char *)bvid)|=bbarr3[bai=(((bai<<8)|(*arr++))&0x1ff)];
  527.                             if(!(--llocnt))
  528.                                 {
  529.                                 llocnt=32768;
  530.                                 arr=fetch(++lhi);
  531.                                 }
  532.                             }
  533.                         else
  534.                             ibcnt++;
  535.                         }
  536.                     else
  537.                         ibcnt++;
  538.                     }
  539.                 else
  540.                     {
  541.                     ibcnt++;
  542.                     (*(unsigned char *)bvid)=0;
  543.                     }
  544.             }
  545.         else
  546.             for(bvid=lvid,bcnt=vbpl;bcnt--;bvid--)
  547.                 (*(unsigned char *)bvid)=0;
  548.     }
  549.  
  550. zhercredisplay()
  551.     {
  552.     long l, l1, lvid, bvid;
  553.     unsigned llocnt, bai;
  554.     int byte, line, lcnt, bcnt, llo, lhi, ibcnt, ilcnt, zibpl;
  555.     unsigned char *arr;
  556.     zibpl=ibpl*3;
  557.     for(l=((long)topline*ibpl), line=0, lcnt=vheight, ilcnt=(iheight-topline)/3;lcnt--;l+=zibpl, ++line)
  558.         {
  559.         lvid=vidbase+(((line>>2)&0xff)*90)+((line&3)<<13);
  560.         if(ilcnt)
  561.             {
  562.             ilcnt--;
  563.             l1=l+leftbyte;
  564.             lhi=(l1>>15)&0x0f;
  565.             arr=fetch(lhi);
  566.             llo=l1&0x7fff;
  567.             llocnt=32768-llo;
  568.             arr=&arr[llo];
  569.             for(bai=0xff, bvid=lvid, bcnt=vbpl, ibcnt=ibpl-leftbyte;bcnt--;++bvid)
  570.                 if(ibcnt--)
  571.                     {
  572.                     (*(unsigned char *)bvid)=barr1[bai=(*arr++)];
  573.                     if(!(--llocnt))
  574.                         {
  575.                         llocnt=32768;
  576.                         arr=fetch(++lhi);
  577.                         }
  578.                     if(ibcnt--)
  579.                         {
  580.                         (*(unsigned char *)bvid)|=barr2[bai=(((bai<<8)|(*arr++))&0x3ff)];
  581.                         if(!(--llocnt))
  582.                             {
  583.                             llocnt=32768;
  584.                             arr=fetch(++lhi);
  585.                             }
  586.                         if(ibcnt--)
  587.                             {
  588.                             (*(unsigned char *)bvid)|=barr3[bai=(((bai<<8)|(*arr++))&0x1ff)];
  589.                             if(!(--llocnt))
  590.                                 {
  591.                                 llocnt=32768;
  592.                                 arr=fetch(++lhi);
  593.                                 }
  594.                             }
  595.                         else
  596.                             ibcnt++;
  597.                         }
  598.                     else
  599.                         ibcnt++;
  600.                     }
  601.                 else
  602.                     {
  603.                     ibcnt++;
  604.                     (*(unsigned char *)bvid)=0;
  605.                     }
  606.             }
  607.         else
  608.             for(bvid=lvid,bcnt=vbpl;bcnt--;bvid++)
  609.                 (*(unsigned char *)bvid)=0;
  610.         }
  611.     }
  612.  
  613. zhercredisplay180()
  614.     {
  615.     long l, l1, lvid, bvid;
  616.     unsigned llocnt, bai;
  617.     int byte, line, lcnt, bcnt, llo, lhi, ibcnt, ilcnt, zibpl;
  618.     unsigned char *arr;
  619.     zibpl=ibpl*3;
  620.     for(l=((long)topline*ibpl), line=vheight-1, lcnt=vheight, ilcnt=(iheight-topline)/3;lcnt--;l+=zibpl, --line)
  621.         {
  622.         lvid=vidbase+(((line>>2)&0xff)*90)+((line&3)<<13);
  623.         if(ilcnt)
  624.             {
  625.             ilcnt--;
  626.             l1=l+leftbyte;
  627.             lhi=(l1>>15)&0x0f;
  628.             arr=fetch(lhi);
  629.             llo=l1&0x7fff;
  630.             llocnt=32768-llo;
  631.             arr=&arr[llo];
  632.             for(bai=0xff, bvid=lvid+vbpl-1, bcnt=vbpl, ibcnt=ibpl-leftbyte;bcnt--;--bvid)
  633.                 if(ibcnt--)
  634.                     {
  635.                     (*(unsigned char *)bvid)=bbarr1[bai=(*arr++)];
  636.                     if(!(--llocnt))
  637.                         {
  638.                         llocnt=32768;
  639.                         arr=fetch(++lhi);
  640.                         }
  641.                     if(ibcnt--)
  642.                         {
  643.                         (*(unsigned char *)bvid)|=bbarr2[bai=(((bai<<8)|(*arr++))&0x3ff)];
  644.                         if(!(--llocnt))
  645.                             {
  646.                             llocnt=32768;
  647.                             arr=fetch(++lhi);
  648.                             }
  649.                         if(ibcnt--)
  650.                             {
  651.                             (*(unsigned char *)bvid)|=bbarr3[bai=(((bai<<8)|(*arr++))&0x1ff)];
  652.                             if(!(--llocnt))
  653.                                 {
  654.                                 llocnt=32768;
  655.                                 arr=fetch(++lhi);
  656.                                 }
  657.                             }
  658.                         else
  659.                             ibcnt++;
  660.                         }
  661.                     else
  662.                         ibcnt++;
  663.                     }
  664.                 else
  665.                     {
  666.                     ibcnt++;
  667.                     (*(unsigned char *)bvid)=0;
  668.                     }
  669.             }
  670.         else
  671.             for(bvid=lvid,bcnt=vbpl;bcnt--;bvid--)
  672.                 (*(unsigned char *)bvid)=0;
  673.         }
  674.     }
  675.  
  676. char herc, zoom, rotp;
  677.  
  678. redisplay()
  679.     {
  680.     if(herc)
  681.         if(zoom)
  682.             if(rotp)
  683.                 zhercredisplay180();
  684.             else
  685.                 zhercredisplay();
  686.         else
  687.             if(rotp)
  688.                 hercredisplay180();
  689.             else
  690.                 hercredisplay();
  691.     else
  692.         if(zoom)
  693.             if(rotp)
  694.                 znormredisplay180();
  695.             else
  696.                 znormredisplay();
  697.         else
  698.             if(rotp)
  699.                 normredisplay180();
  700.             else
  701.                 normredisplay();
  702.     }
  703.  
  704. poot() /* A less irritating beep */
  705.     {
  706.     oldtick=_dos_getvect(0x1c);
  707.     _dos_setvect(0x1c, tickhndl);
  708.     outp(0x43, 0xb6); /* Ctl Reg = #3 Lo-Hi Square Wave */
  709.     outp(0x42, 164); /* Divisor LSB (250 Hz) */
  710.     outp(0x42, 18); /* Divisor MSB (250 Hz) */
  711.     tick=0L;
  712.     while(tick==0L); /* Synchronize w/ tick phase; i.e. eliminate slop  */
  713.     outp(0x61, inp(0x61)|0x03); /* PortB; 2^0: timer gate, 2^1: AND/OR? */
  714.     while(1)
  715.         {
  716.         if(tick>1) /* EXACTLY 1 tick */
  717.             break;
  718.         }
  719.     outp(0x61, inp(0x61)&~(unsigned char)0x03);
  720.     _dos_setvect(0x1c, oldtick);
  721.     }
  722.  
  723. #define FBUFSIZ 16384
  724.  
  725. unsigned char fbuf[FBUFSIZ];
  726.  
  727. main(argc, argv)
  728.     int argc;
  729.     char **argv;
  730.     {
  731.     unsigned int k;
  732.     int i, count, vstep, hstep, bbytes, fd;
  733.     unsigned llocnt;
  734.     unsigned char c, *arr, *fbp;
  735.     struct videoconfig *vconf;
  736.     swapfd=-1;
  737.     nlru=0;
  738.     ntotal=0;
  739.     swapsize=0;
  740.     i=0;
  741.     rotp=0;
  742.     if(!strcmp(getenv("REMOTE"), "YES"))
  743.         {
  744.         printf("You appear to be logged in remotely, judging by the environment\n");
  745.         printf("variable REMOTE, so this is probably a very bad idea.\n");
  746.         printf("Are you sure you want to run VIEWPCX? (y or n) --> ");
  747.         if(getchar()!='y') /* Note getchar() and not getch()! */
  748.             {
  749.             printf("n\nI didn't think so!\n");
  750.             exit(99);
  751.             }
  752.         else
  753.             printf("y\nOK, you're the boss!\n");
  754.         }
  755.     while(i<20)
  756.         if((buf[i]=malloc(32768))==NULL)
  757.             break;
  758.         else
  759.             ++i;
  760.     nblocks=i;
  761.     if((argc!=2)&&(argc!=4))
  762.         {
  763.         printf("\nUSAGE: viewpcx <file> [<vertical step> <horizontal step>]\n");
  764.         printf("\nKey Commands:\n\n");
  765.         printf("\t   INSERT - Toggle 3:1 Zoom\n");
  766.         printf("\t   DELETE - Rotate 180\n");
  767.         printf("\t     HOME - Go to Top of Image\n");
  768.         printf("\t      END - Go to Bottom of Image\n");
  769.         printf("\t  PAGE UP - View Screenfull Above\n");
  770.         printf("\tPAGE DOWN - View Screenfull Below\n\n");
  771.         printf("\t <arrows> - Move view by default or specified steps.\n");
  772.         printf("\t      ESC - Exit\n");
  773.         exit(1);
  774.         }
  775.     if(argc==4)
  776.         {
  777.         vstep=atoi(argv[2]);
  778.         hstep=atoi(argv[3])/8;
  779.         }
  780.     else
  781.         vstep=hstep=0;
  782.     mkbtab();
  783.     _getvideoconfig(vconf);
  784.     herc=zoom=0;
  785.     if((vconf->adapter==_HGC)||(vconf->adapter==_MDPA))
  786.         {
  787.         herc=1;
  788.         vidbase=(long)0xb0000000;
  789.         vheight=348;
  790.         vbpl=90;
  791.         if(!vstep)
  792.             {
  793.             vstep=100;
  794.             hstep=30;
  795.             }
  796.         if(!_setvideomode(_HERCMONO))
  797.             {
  798.             printf("Couldn't set Hercules video mode. Did you run MSHERC.COM?\n");
  799.             exit(5);
  800.             }
  801.         }
  802.     else if(vconf->adapter==_CGA)
  803.         {
  804.         vidbase=(long)0xb8000000;
  805.         vheight=200;
  806.         vbpl=40;
  807.         if(!vstep)
  808.             {
  809.             vstep=67;
  810.             hstep=13;
  811.             }
  812.         if(!_setvideomode(_MRESNOCOLOR))
  813.             {
  814.             printf("Couldn't set CGA mono video mode.\n");
  815.             exit(5);
  816.             }
  817.         }
  818.     else if(vconf->adapter==_EGA)
  819.         {
  820.         vidbase=(long)0xb8000000;
  821.         vheight=350;
  822.         vbpl=80;
  823.         if(!vstep)
  824.             {
  825.             vstep=110;
  826.             hstep=26;
  827.             }
  828.         if(!_setvideomode(_ERESNOCOLOR))
  829.             {
  830.             printf("Couldn't set EGA mono video mode.\n");
  831.             exit(5);
  832.             }
  833.         }
  834.     else
  835.         {
  836.         vidbase=0xa0000000;
  837.         vheight=480;
  838.         vbpl=80;
  839.         if(!vstep)
  840.             {
  841.             vstep=160;
  842.             hstep=26;
  843.             }
  844.         if(!_setvideomode(_VRES2COLOR))
  845.             {
  846.             if(vconf->adapter!=_VGA)
  847.                 printf("Couldn't set unrecognized video adapter to VGA mono mode.\n");
  848.             else
  849.                 printf("Couldn't set VGA mono video mode.\n");
  850.             exit(5);
  851.             }
  852.         }
  853.     if((fd=open(argv[1], O_RDONLY|O_BINARY))==-1)
  854.         {
  855.         _setvideomode(_DEFAULTMODE);
  856.         printf("Error opening %s for read.\n", argv[1]);
  857.         exit(6);
  858.         }
  859.     if(read(fd, &header, sizeof(header))!=sizeof(header))
  860.         {
  861.         _setvideomode(_DEFAULTMODE);
  862.         printf("Error reading pcx file header.\n");
  863.         exit(7);
  864.         }
  865.     if(((long)(uibpl=header.bypl)*(uiheight=(header.ymax+1-header.ymin)))>(128*32768))
  866.         {
  867.         _setvideomode(_DEFAULTMODE);
  868.         printf("Sorry, image too big for paging code.\n");
  869.         exit(8);
  870.         }
  871.     if((uiheight>16384)||(uibpl>16384))
  872.         {
  873.         printf("Sorry, image dimension(s) too great for math.\n");
  874.         exit(8);
  875.         }
  876.     iheight=(int)uiheight;
  877.     ibpl=(int)uibpl;
  878.     if(header.nplanes!=1)
  879.         {
  880.         _setvideomode(_DEFAULTMODE);
  881.         printf("Sorry, monochrome only.\n");
  882.         exit(12);
  883.         }
  884.     if(header.bppix!=1)
  885.         {
  886.         _setvideomode(_DEFAULTMODE);
  887.         printf("Sorry, I don't do grayscales.\n");
  888.         exit(50);
  889.         }
  890.     llocnt=32767;
  891.     count=0;
  892.     arr=getnew();
  893.     while((bbytes=read(fd, fbuf, FBUFSIZ))>0)
  894.         for(fbp=fbuf;bbytes--;)
  895.             {
  896.             if(count)
  897.                 {
  898.                 while(count--)
  899.                     {
  900.                     *arr++=*fbp;
  901.                     if(!(llocnt--))
  902.                         {
  903.                         llocnt=32767;
  904.                         arr=getnew();
  905.                         }
  906.                     }
  907.                 fbp++;
  908.                 count=0;
  909.                 }
  910.             else if(((*fbp)&0xc0)!=0xc0)
  911.                 {
  912.                 *arr++=*fbp++;
  913.                 if(!(llocnt--))
  914.                     {
  915.                     llocnt=32767;
  916.                     arr=getnew();
  917.                     }
  918.                 }
  919.             else
  920.                 count=0x3f&*fbp++;
  921.             }
  922.     leftbyte=topline=0;
  923.     redisplay();
  924.     while((k=_bios_keybrd(_KEYBRD_READ))!=ESC)
  925.         {
  926.         if(rotp)
  927.             {
  928.             if(k==HOME)
  929.                 k=END;
  930.             else if(k==END)
  931.                 k=HOME;
  932.             else if(k==PGUP)
  933.                 k=PGDN;
  934.             else if(k==PGDN)
  935.                 k=PGUP;
  936.             else if(k==UP)
  937.                 k=DN;
  938.             else if(k==DN)
  939.                 k=UP;
  940.             else if(k==LT)
  941.                 k=RT;
  942.             else if(k==RT)
  943.                 k=LT;
  944.             }
  945.         switch(k)
  946.             {
  947.             case INS:
  948.                 zoom=!zoom;
  949.                 redisplay();
  950.                 break;
  951.             case LT:
  952.                 if(leftbyte<=0)
  953.                     {
  954.                     poot();
  955.                     break;
  956.                     }
  957.                 if(zoom)
  958.                     leftbyte-=hstep*3;
  959.                 else
  960.                     leftbyte-=hstep;
  961.                 if(leftbyte<0)
  962.                     leftbyte=0;
  963.                 redisplay();
  964.                 break;
  965.             case RT:
  966.                 if(leftbyte>=(ibpl-((zoom?3:1)*vbpl)))
  967.                     {
  968.                     poot();
  969.                     break;
  970.                     }
  971.                 if(zoom)
  972.                     leftbyte+=hstep*3;
  973.                 else
  974.                     leftbyte+=hstep;
  975.                 if(leftbyte>(ibpl-((zoom?3:1)*vbpl)))
  976.                     leftbyte=ibpl-((zoom?3:1)*vbpl);
  977.                 redisplay();
  978.                 break;
  979.             case UP:
  980.                 if(topline<=0)
  981.                     {
  982.                     poot();
  983.                     break;
  984.                     }
  985.                 if(zoom)
  986.                     topline-=vstep*3;
  987.                 else
  988.                     topline-=vstep;
  989.                 if(topline<0)
  990.                     topline=0;
  991.                 redisplay();
  992.                 break;
  993.             case PGUP:
  994.                 if(topline<=0)
  995.                     {
  996.                     poot();
  997.                     break;
  998.                     }
  999.                 if(zoom)
  1000.                     topline-=vheight*3;
  1001.                 else
  1002.                     topline-=vheight;
  1003.                 if(topline<0)
  1004.                     topline=0;
  1005.                 redisplay();
  1006.                 break;
  1007.             case DN:
  1008.                 if(topline>=(iheight-((zoom?3:1)*vheight)))
  1009.                     {
  1010.                     poot();
  1011.                     break;
  1012.                     }
  1013.                 if(zoom)
  1014.                     topline+=vstep*3;
  1015.                 else
  1016.                     topline+=vstep;
  1017.                 if(topline>(iheight-((zoom?3:1)*vheight)))
  1018.                     topline=iheight-((zoom?3:1)*vheight);
  1019.                 redisplay();
  1020.                 break;
  1021.             case PGDN:
  1022.                 if(topline>=(iheight-((zoom?3:1)*vheight)))
  1023.                     {
  1024.                     poot();
  1025.                     break;
  1026.                     }
  1027.                 if(zoom)
  1028.                     topline+=vheight*3;
  1029.                 else
  1030.                     topline+=vheight;
  1031.                 if(topline>(iheight-((zoom?3:1)*vheight)))
  1032.                     topline=iheight-((zoom?3:1)*vheight);
  1033.                 redisplay();
  1034.                 break;
  1035.             case HOME:
  1036.                 topline=0;
  1037.                 redisplay();
  1038.                 break;
  1039.             case END:
  1040.                 topline=iheight-((zoom?3:1)*vheight);
  1041.                 if(topline<0)
  1042.                     topline=0;
  1043.                 redisplay();
  1044.                 break;
  1045.             case DEL:
  1046.                 rotp=!rotp;
  1047.                 redisplay();
  1048.                 break;
  1049.             default:
  1050.                 putch(7);
  1051.             }
  1052.         }
  1053.     _setvideomode(_DEFAULTMODE);
  1054.     if(swapfd!=-1)
  1055.         unlink("viewpcx.swp");
  1056.     }
  1057.