home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / disks / disk449.lzh / Shazam / old / shazam.c < prev    next >
C/C++ Source or Header  |  1991-02-02  |  12KB  |  475 lines

  1. /* Copyright © 1991 Lake Forest Logic Inc. */
  2. /* SHAZAM: Macro Paint picture viewer version 1.0 */
  3.  
  4. /*
  5.  
  6. This program is designed to display dynamic hires images created with
  7. Macro Paint, the 4096 color high-resolution paint program from Lake
  8. Forest Logic. The source code is provided so that others support
  9. Macro Paint images in their viewer programs. The is quite a bit
  10. of room for improvement in this program but we felt it was important
  11. to release a usable viewer as soon as possible. 1/30/91
  12.  
  13. This program is version 1.0: bug reports and suggestions are welcome
  14. and may be sent to:
  15.  
  16.     Lake Forest Logic Inc.
  17.     28101 Ballard Road, Unit E
  18.     Lake Forest, IL 60045
  19.     (708)816-6666 FAX: (708)680-0832
  20.     BBS: (708)680-0590 HST, 24 hours
  21.     BIX: equack
  22.     PLink: LFL*ERIK
  23.  
  24. The program was compiled using SAS/C Version 5.10a. The command
  25. "LC -rr -L shazam" should suffice to compile and link it.
  26.  
  27. Permission is granted to distribute this file for non-commercial
  28. purposes. Portions of the compiled code may be incorporated into your own
  29. programs (commercial or otherwise), but you may not distribute a modified
  30. version of this file without permission.
  31.  
  32.  
  33. */
  34.  
  35. #include <exec/types.h>
  36. #include <exec/memory.h>
  37. #include <libraries/dos.h>
  38. #include <intuition/intuition.h>
  39. #include <intuition/intuitionbase.h>
  40. #include <graphics/gfx.h>
  41. #include <graphics/gfxbase.h>
  42. #include <graphics/view.h>
  43. #include <graphics/copper.h>
  44. #include <proto/all.h>
  45. #include <stdio.h>
  46. #include <ctype.h>
  47. #include <hardware/custom.h>
  48.  
  49. #define NL (0)
  50. #define CINIT(c,n)    { UCopperListInit(c,n); }
  51. #define CWAIT(c,a,b)    { CWait(c,a,b);CBump(c); }
  52. #define CEND(c)        { CWAIT(c,10000,255); }
  53. #define CMOVE(c,a,b)    { CMove(c,(long)&a,b);CBump(c); }
  54.  
  55. struct View *vshift;
  56. struct Screen *screen=0;
  57. struct NewScreen plane;
  58. struct GfxBase *GfxBase;
  59. struct IntuitionBase *IntuitionBase=0;
  60. struct ViewPort *vp;
  61.  
  62. UWORD inmap[64],*Coppers;
  63. char DISPLAY=1,LACEME=0,OSCAN=16,OSTART=4,TRUNK=1;
  64. int COPHEIGHT;
  65.  
  66. #define MakeID(a,b,c,d)  ( (LONG)(a)<<24L | (LONG)(b)<<16L | (c)<<8 | (d) )
  67.  
  68. #define ID_FORM MakeID('F','O','R','M')
  69. #define ID_MPCT MakeID('M','P','C','T')
  70. #define ID_DYCP MakeID('D','Y','C','P')
  71. #define ID_CTBL MakeID('C','T','B','L')
  72. #define ID_BMHD MakeID('B','M','H','D')
  73. #define ID_CMAP MakeID('C','M','A','P')
  74. #define ID_BODY MakeID('B','O','D','Y')
  75.  
  76. #define BUFSIZE (8192)
  77. #define UGetByte()    (*source++)
  78. #define UPutByte(c)    (*dest++ = (c))
  79.  
  80. struct Custom *custom;
  81. struct UCopList *ucop=0;
  82.  
  83. struct QBMHD
  84.   {
  85.     UWORD w, h;         /* raster width & height in pixels */
  86.     WORD  x, y;         /* position for this image */
  87.     UBYTE nPlanes;      /* # source bitplanes */
  88.     UBYTE masking;      /* masking technique */
  89.     UBYTE compression;   /* compression algoithm */
  90.     UBYTE pad1;         /* UNUSED.  For consistency, put 0 here.*/
  91.     UWORD transparentColor;   /* transparent "color number" */
  92.     UBYTE xAspect, yAspect;   /* aspect ratio, a rational number x/y */
  93.     WORD  pageWidth, pageHeight;  /* source "page" size in pixels */
  94.   };
  95.  
  96. void QDV(BPTR);
  97. void PutCop(void);
  98. void Chunker(BPTR,ULONG *,int);
  99. void GetScreen(struct QBMHD *header);
  100. void UnScreen(void);
  101. char UnpackRLL(BYTE **,BYTE **,int,int);
  102.  
  103. main(int argc,char **argv)
  104.   {
  105.    ULONG handle;
  106.  
  107.    printf("\n\233;1mSHAZAM\233;0m V1.0 © 1991 Lake Forest Logic Inc.\n\n");
  108.    
  109.    if(argc<2)
  110.     {
  111.      printf(" Syntax: SHAZAM <macro paint file>\n");
  112.     }
  113.    else
  114.     {
  115.      handle=Open(argv[1],MODE_OLDFILE);
  116.      if(!handle)
  117.       {
  118.        printf(" Error: unable to open file \233;32m%s\233;0m\n",argv[1]);
  119.        return(1);
  120.       }
  121.      QDV(handle);
  122.      Close(handle);
  123.     }
  124.    printf("\n");
  125.    return(DISPLAY);
  126.   }
  127.  
  128. void QDV(BPTR handle)
  129.   {
  130.    ULONG *buffer;
  131.    int result;
  132.  
  133.    buffer=AllocMem(BUFSIZE,0);
  134.    if(!buffer)
  135.     {
  136.      printf(" Error: not enough memory.\n");
  137.      DISPLAY=1;
  138.      return;
  139.     }
  140.    result=Read(handle,buffer,12);
  141.    if(result!=12)
  142.     {
  143.      printf(" Error: unable to read header.\n");
  144.      DISPLAY=1;
  145.      return;
  146.     }
  147.    if(buffer[0]!=ID_FORM)
  148.     {
  149.      printf(" Error: not an IFF file.\n");
  150.      DISPLAY=1;
  151.      return;
  152.     }
  153.  
  154.    Chunker(handle,buffer,buffer[1]-4);
  155.  
  156.    UnScreen();
  157.  
  158.    FreeMem(buffer,BUFSIZE);
  159.    return;
  160.   }
  161.  
  162. void Chunker(BPTR handle,ULONG *buffer,int total)
  163.   {
  164.    int here,result,size,loop,planes,lines,bites,line,plane;
  165.    struct QBMHD *bmhd;
  166.    UBYTE *collar, *source,*dest;
  167.    here=0;
  168.  
  169.    custom=(struct Custom *) 0x00DFF000;
  170.  
  171.    while(here<total)
  172.     {
  173.      if(here==1) return;
  174.      if(here&1) Read(handle,buffer,1);
  175.      result=Read(handle,buffer,8);
  176.      if(result!=8)
  177.       {
  178.        printf(" Error: unable to read chunk header.\n");
  179.        DISPLAY=1;
  180.        return;
  181.       }
  182.     size=buffer[1];
  183.     if(buffer[0]==ID_MPCT)
  184.      {
  185.       DISPLAY=0;
  186.      }
  187.     if(buffer[0]==ID_BODY)
  188.      {
  189.       if(screen)
  190.        {
  191.         collar=AllocMem(size,0);
  192.         if(!collar)
  193.          {
  194.           printf(" Error: unable to allocate BODY.\n");
  195.           DISPLAY=1;
  196.          }
  197.         else
  198.          {
  199.           result=Read(handle,collar,size);
  200.           if(result!=size) printf(" Error: unable to read BODY.\n");
  201.           lines=screen->BitMap.Rows;
  202.           planes=screen->BitMap.Depth;
  203.           bites=screen->BitMap.BytesPerRow;
  204.           source=collar;
  205.  
  206.           for(line=0;line<lines;line++)
  207.            {
  208.             for(plane=0;plane<planes;plane++)
  209.              {
  210.               dest=screen->BitMap.Planes[plane]+line*bites;
  211.               result=UnpackRLL(&source,&dest,size,bites);
  212.  
  213.               if(result)
  214.                {
  215.                 printf(" Error %d: unable to unpack BODY L:%d P:%d.\n",
  216.                  result,line,plane);
  217.                 DISPLAY=1;
  218.                 FreeMem(collar,size);
  219.                 here+=size+8;
  220.                 return;
  221.                }
  222.              }
  223.            }
  224.           FreeMem(collar,size);
  225.          }
  226.        }
  227.      }
  228.     else if(buffer[0]==ID_CMAP)
  229.      {
  230.       result=Read(handle,buffer,size);
  231.       if(screen)
  232.        {
  233.         collar=(BYTE *)buffer;
  234.         for(loop=0;loop<size/3;loop++)
  235.          {
  236.           inmap[loop]=((collar[loop*3]>>4)<<8)+((collar[loop*3+1]>>4)<<4)+(collar[loop*3+2]>>4);
  237.           SetRGB4(&screen->ViewPort,
  238.            loop,collar[loop*3]>>4,collar[loop*3+1]>>4,collar[loop*3+2]>>4);
  239.          }
  240.        }
  241.      }
  242.     else if(buffer[0]==ID_CTBL)
  243.      {
  244.       Coppers=AllocMem(size,0);
  245.       if(!Coppers) DISPLAY=1;
  246.       else
  247.        {
  248.         COPHEIGHT=size/32;
  249.         result=Read(handle,Coppers,size);
  250.         if(!DISPLAY)
  251.          {
  252.           SetRGB4(&screen->ViewPort, 0,(Coppers[0]>>8)&15,(Coppers[0]>>4)&15,Coppers[0]&15);
  253.           SetRGB4(&screen->ViewPort, 1,(Coppers[1]>>8)&15,(Coppers[1]>>4)&15,Coppers[1]&15);
  254.           SetRGB4(&screen->ViewPort, 2,(Coppers[2]>>8)&15,(Coppers[2]>>4)&15,Coppers[2]&15);
  255.           SetRGB4(&screen->ViewPort, 3,(Coppers[3]>>8)&15,(Coppers[3]>>4)&15,Coppers[3]&15);
  256.           SetRGB4(&screen->ViewPort, 4,4,4,4);
  257.           SetRGB4(&screen->ViewPort, 5,5,5,5);
  258.           SetRGB4(&screen->ViewPort, 6,6,6,6);
  259.           SetRGB4(&screen->ViewPort, 7,7,7,7);
  260.           SetRGB4(&screen->ViewPort, 8,8,8,8);
  261.           SetRGB4(&screen->ViewPort, 9,9,9,9);
  262.           SetRGB4(&screen->ViewPort,10,10,10,10);
  263.           SetRGB4(&screen->ViewPort,11,11,11,11);
  264.           SetRGB4(&screen->ViewPort,12,12,12,12);
  265.           SetRGB4(&screen->ViewPort,13,13,13,13);
  266.           SetRGB4(&screen->ViewPort,14,14,14,14);
  267.           SetRGB4(&screen->ViewPort,15,15,15,15);
  268.          }
  269.        }
  270.      }
  271.     else if(buffer[0]==ID_BMHD)
  272.      {
  273.       result=Read(handle,buffer,size);
  274.       if(!DISPLAY)
  275.        {
  276.         bmhd=(struct QBMHD *)buffer;
  277.         GetScreen(bmhd);
  278.        }
  279.       else
  280.        {
  281.         printf(" Not a Macro Paint picture file.\n");
  282.         DISPLAY=1;
  283.        }
  284.      }
  285.     else
  286.      {
  287.       if(size%BUFSIZE)
  288.         {
  289.          result=Read(handle,buffer,size%BUFSIZE);
  290.          if(result!=size%BUFSIZE)
  291.           {
  292.            printf(" Error: unable to read chunk body.\n");
  293.            DISPLAY=1;
  294.            return;
  295.           }
  296.         }
  297.        if(size/BUFSIZE) for(loop=0;loop<size/BUFSIZE;loop++)
  298.         {
  299.          result=Read(handle,buffer,BUFSIZE);
  300.          if(result!=BUFSIZE)
  301.           {
  302.            printf(" Error: unable to read chunk body.\n");
  303.            DISPLAY=1;
  304.            return;
  305.           }
  306.         }
  307.       }
  308.      here+=size+8;
  309.     }
  310.   }
  311.  
  312. void UnScreen()
  313.  {
  314.   int shifted;
  315.  
  316.   if(screen)
  317.    {
  318.     ScreenToFront(screen);
  319.  
  320.     vshift=ViewAddress();
  321.  
  322.     if(!TRUNK)
  323.     if((COPHEIGHT>>1)>GfxBase->NormalDisplayRows)
  324.      {
  325.       shifted=((COPHEIGHT>>1)-GfxBase->NormalDisplayRows)>>1;
  326.       vshift->DyOffset-=shifted;
  327.      }
  328.  
  329.     PutCop();
  330.     getchar();
  331.     if(!TRUNK) vshift->DyOffset+=shifted;
  332.  
  333.     FreeVPortCopLists(&screen->ViewPort);
  334.     RemakeDisplay();
  335.     CloseScreen(screen);
  336.     if(Coppers) FreeMem(Coppers,COPHEIGHT<<5);
  337.    }
  338.  
  339.   if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  340.   if(GfxBase) CloseLibrary((struct Library *)GfxBase);
  341.  }
  342.  
  343. void PutCop()
  344.   {
  345.    int line,creg,top;
  346.  
  347.    ucop=(struct UCopList *)AllocMem(sizeof(struct UCopList),MEMF_CLEAR);
  348.  
  349.    top=COPHEIGHT;
  350.    if(LACEME) top=top/2;
  351.  
  352.    if(TRUNK)
  353.     if(top>GfxBase->NormalDisplayRows) top=GfxBase->NormalDisplayRows;
  354.  
  355.    CINIT(ucop,top*13);
  356.  
  357.    for(line=0;line<top;line++)
  358.     {
  359.      if(LACEME) 
  360.       {
  361.        CWAIT(ucop,(line-1)<<1,112);
  362.       }
  363.      else
  364.       {
  365.        CWAIT(ucop,(line-1),112);
  366.       }
  367.  
  368.      for(creg=OSTART;creg<OSCAN;creg++)
  369.       {
  370.        if(LACEME)
  371.         {
  372.          CMOVE(ucop,custom->color[creg],Coppers[(line<<5)+creg]);
  373.         }
  374.        else
  375.         {
  376.          CMOVE(ucop,custom->color[creg],Coppers[(line<<4)+creg]);
  377.         }
  378.       }
  379.     }
  380.    CEND(ucop);
  381.  
  382.   printf("Press return.\n");
  383.   Forbid();
  384.   vp->UCopIns=ucop;
  385.   Permit();
  386.   MakeScreen(screen);
  387.   RethinkDisplay();
  388.  }
  389.  
  390. void GetScreen(struct QBMHD *header)
  391.  {
  392.   IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",33);
  393.   if(!IntuitionBase) 
  394.    {
  395.     printf(" Error: unable to open Intuition!\n");
  396.     return;
  397.    }
  398.  
  399.    GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",33);
  400.    if(!GfxBase)
  401.     {
  402.      printf(" Error: unable to open graphics.\n");
  403.      return;
  404.     }
  405.  
  406.    plane.LeftEdge=0;
  407.    plane.TopEdge=0;
  408.    plane.DetailPen=2;
  409.    plane.BlockPen=1;
  410.    plane.Type=CUSTOMSCREEN|SCREENQUIET;
  411.    plane.Font=0;
  412.    plane.DefaultTitle="SHAZAM Screen";
  413.    plane.Gadgets=0;
  414.    plane.CustomBitMap=0;
  415.    plane.ViewModes=0;
  416.  
  417.    plane.Width=header->w;
  418.    plane.Height=header->h;
  419.    plane.Depth=header->nPlanes;
  420.    plane.ViewModes|=HIRES;
  421.   
  422.    if(header->h>300) { plane.ViewModes|=LACE; LACEME=1; }
  423.  
  424.    if(header->w>640) OSCAN=14;
  425.  
  426.    screen=OpenScreen(&plane);
  427.    vp=&screen->ViewPort;
  428.    return;
  429.   }
  430.  
  431. char UnpackRLL(BYTE **pSource,BYTE **pDest,int srcBytes0,int dstBytes0)
  432.   {
  433.    int srcBytes,dstBytes;
  434.    BYTE *source, *dest, c;
  435.    WORD n,minus128=-128;
  436.  
  437.    source=*pSource;
  438.    dest=*pDest;
  439.    srcBytes=srcBytes0;
  440.    dstBytes=dstBytes0;
  441.  
  442.    while(dstBytes>0) 
  443.     {
  444.      if((srcBytes-=1)<0) return(1);
  445.      n=UGetByte();
  446.  
  447.      if (n >= 0)
  448.       {
  449.        n += 1;
  450.        if((srcBytes-=n)<0) return(2);
  451.        if((dstBytes-=n)<0) return(3);
  452.        do
  453.         {
  454.          UPutByte(UGetByte());
  455.         }
  456.        while(--n>0);
  457.       }
  458.      else if(n!=minus128)
  459.       {
  460.        n = -n + 1;
  461.        if((srcBytes-=1)<0) return(4);
  462.        if((dstBytes-=n)<0) return(5);
  463.        c = UGetByte();
  464.        do
  465.         {
  466.          UPutByte(c);
  467.         }
  468.        while(--n>0);
  469.       }
  470.     }
  471.  
  472.    *pSource=source;  *pDest=dest;
  473.    return(0);
  474.   }
  475.