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

  1. /* Copyright © 1991 Lake Forest Logic Inc. */
  2. /* SHAZAM: Macro Paint picture viewer version 1.1 */
  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 can support
  9. Macro Paint images in their viewer programs. There 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/31/91
  12.  
  13. This program is version 1.1: 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 source file without permission.
  31.  
  32. */
  33.  
  34. #include <exec/types.h>
  35. #include <exec/memory.h>
  36. #include <libraries/dos.h>
  37. #include <intuition/intuition.h>
  38. #include <intuition/intuitionbase.h>
  39. #include <graphics/gfx.h>
  40. #include <graphics/gfxbase.h>
  41. #include <graphics/view.h>
  42. #include <graphics/copper.h>
  43. #include <hardware/custom.h>
  44. #include <proto/all.h>
  45. #include <stdio.h>
  46.  
  47. /* short hand */
  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. #define MakeID(a,b,c,d)  ( (LONG)(a)<<24L | (LONG)(b)<<16L | (c)<<8 | (d) )
  56.  
  57. #define ID_FORM MakeID('F','O','R','M')
  58. #define ID_MPCT MakeID('M','P','C','T')
  59. #define ID_DYCP MakeID('D','Y','C','P')
  60. #define ID_CTBL MakeID('C','T','B','L')
  61. #define ID_BMHD MakeID('B','M','H','D')
  62. #define ID_CMAP MakeID('C','M','A','P')
  63. #define ID_BODY MakeID('B','O','D','Y')
  64.  
  65. #define BUFSIZE (8192)
  66. #define UGetByte()    (*source++)
  67. #define UPutByte(c)    (*dest++ = (c))
  68.  
  69. /* some global data */
  70.  
  71. struct View *vshift;
  72. struct Screen *screen=0;
  73. struct NewScreen plane;
  74. struct GfxBase *GfxBase;
  75. struct IntuitionBase *IntuitionBase=0;
  76. struct ViewPort *vp;
  77.  
  78. int COPHEIGHT;
  79. char DISPLAY=1,LACEME=0,OSCAN=16;
  80. UWORD inmap[64],*Coppers;
  81. UWORD colors[16]={0x000,0x111,0x222,0x333,0x444,0x555,0x666,0x777,
  82.                   0x888,0x999,0xaaa,0xbbb,0xccc,0xddd,0xeee,0xfff};
  83.  
  84. struct Custom *custom;
  85. struct UCopList *ucop=0;
  86.  
  87. struct BMHD
  88.   {
  89.     UWORD w, h;
  90.     WORD  x, y;
  91.     UBYTE nPlanes;
  92.     UBYTE masking;
  93.     UBYTE compression;
  94.     UBYTE pad1;
  95.     UWORD transparentColor;
  96.     UBYTE xAspect, yAspect;
  97.     WORD  pageWidth, pageHeight;
  98.   };
  99.  
  100. /* function prototypes */
  101.  
  102. void Shazam(BPTR);
  103. void PutCop(void);
  104. void Chunker(BPTR,ULONG *,int);
  105. void GetScreen(struct BMHD *header);
  106. void UnScreen(void);
  107. char UnpackRLL(BYTE **,BYTE **,int,int);
  108.  
  109.  
  110. main(int argc,char **argv)
  111.   {
  112.    ULONG handle;
  113.  
  114.    printf("\n\233;1mSHAZAM\233;0m V1.1 © 1991 Lake Forest Logic Inc.\n\n");
  115.    
  116.    if(argc<2)
  117.     {
  118.      printf(" Syntax: SHAZAM <macro paint file>\n");
  119.     }
  120.    else
  121.     {
  122.      handle=Open(argv[1],MODE_OLDFILE);
  123.      if(!handle)
  124.       {
  125.        printf(" Error: unable to open file \233;32m%s\233;0m\n",argv[1]);
  126.        return(1);
  127.       }
  128.      Shazam(handle);
  129.      Close(handle);
  130.     }
  131.    printf("\n");
  132.    return(DISPLAY);
  133.   }
  134.  
  135. /* get started */
  136.  
  137. void Shazam(BPTR handle)
  138.   {
  139.    ULONG *buffer;
  140.    int result;
  141.  
  142.    buffer=AllocMem(BUFSIZE,0);
  143.    if(!buffer)
  144.     {
  145.      printf(" Error: not enough memory.\n");
  146.      DISPLAY=1;
  147.      return;
  148.     }
  149.    result=Read(handle,buffer,12);
  150.    if(result!=12)
  151.     {
  152.      printf(" Error: unable to read header.\n");
  153.      DISPLAY=1;
  154.      return;
  155.     }
  156.    if(buffer[0]!=ID_FORM)
  157.     {
  158.      printf(" Error: not an IFF file.\n");
  159.      DISPLAY=1;
  160.      return;
  161.     }
  162.  
  163.    Chunker(handle,buffer,buffer[1]-4);
  164.  
  165.    UnScreen();
  166.  
  167.    FreeMem(buffer,BUFSIZE);
  168.    return;
  169.   }
  170.  
  171. /* chop up those IFF chunks */
  172.  
  173. void Chunker(BPTR handle,ULONG *buffer,int total)
  174.   {
  175.    int here,result,size,loop,planes,lines,bites,line,plane;
  176.    struct BMHD *bmhd;
  177.    UBYTE *collar, *source,*dest;
  178.    here=0;
  179.  
  180.    custom=(struct Custom *) 0x00DFF000;
  181.  
  182.    while(here<total)
  183.     {
  184.      if(here==1) return;
  185.      if(here&1) Read(handle,buffer,1);
  186.      result=Read(handle,buffer,8);
  187.      if(result!=8)
  188.       {
  189.        printf(" Error: unable to read chunk header.\n");
  190.        DISPLAY=1;
  191.        return;
  192.       }
  193.     size=buffer[1];
  194.     if(buffer[0]==ID_MPCT)
  195.      {
  196.       DISPLAY=0;
  197.      }
  198.     if(buffer[0]==ID_BODY)
  199.      {
  200.       if(screen)
  201.        {
  202.         collar=AllocMem(size,0);
  203.         if(!collar)
  204.          {
  205.           printf(" Error: unable to allocate BODY.\n");
  206.           DISPLAY=1;
  207.          }
  208.         else
  209.          {
  210.           result=Read(handle,collar,size);
  211.           if(result!=size) printf(" Error: unable to read BODY.\n");
  212.           lines=screen->BitMap.Rows;
  213.           planes=screen->BitMap.Depth;
  214.           bites=screen->BitMap.BytesPerRow;
  215.           source=collar;
  216.  
  217.           for(line=0;line<lines;line++)
  218.            {
  219.             for(plane=0;plane<planes;plane++)
  220.              {
  221.               dest=screen->BitMap.Planes[plane]+line*bites;
  222.               result=UnpackRLL(&source,&dest,size,bites);
  223.  
  224.               if(result)
  225.                {
  226.                 printf(" Error %d: unable to unpack BODY L:%d P:%d.\n",
  227.                  result,line,plane);
  228.                 DISPLAY=1;
  229.                 FreeMem(collar,size);
  230.                 here+=size+8;
  231.                 return;
  232.                }
  233.              }
  234.            }
  235.           FreeMem(collar,size);
  236.          }
  237.        }
  238.      }
  239.     else if(buffer[0]==ID_CMAP)
  240.      {
  241.       result=Read(handle,buffer,size);
  242.       if(screen)
  243.        {
  244.         collar=(BYTE *)buffer;
  245.         for(loop=0;loop<size/3;loop++)
  246.          {
  247.           inmap[loop]=((collar[loop*3]>>4)<<8)+((collar[loop*3+1]>>4)<<4)+(collar[loop*3+2]>>4);
  248.           SetRGB4(&screen->ViewPort,
  249.            loop,collar[loop*3]>>4,collar[loop*3+1]>>4,collar[loop*3+2]>>4);
  250.          }
  251.        }
  252.      }
  253.     else if(buffer[0]==ID_CTBL)
  254.      {
  255.       Coppers=AllocMem(size,0);
  256.       if(!Coppers) DISPLAY=1;
  257.       else
  258.        {
  259.         COPHEIGHT=size/32;
  260.         result=Read(handle,Coppers,size);
  261.         if(!DISPLAY)
  262.          {
  263.           colors[0]=Coppers[0];
  264.           colors[1]=Coppers[1];
  265.           colors[2]=Coppers[2];
  266.           colors[3]=Coppers[3];
  267.           LoadRGB4(&screen->ViewPort,colors,20);
  268.          }
  269.        }
  270.      }
  271.     else if(buffer[0]==ID_BMHD)
  272.      {
  273.       result=Read(handle,buffer,size);
  274.       if(!DISPLAY)
  275.        {
  276.         bmhd=(struct BMHD *)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. /* kick in the display and wait for the end */
  313.  
  314. void UnScreen()
  315.  {
  316.   int preserve;
  317.   if(screen)
  318.    {
  319.     ScreenToFront(screen);
  320.  
  321.     vshift=ViewAddress();
  322.     preserve=vshift->DyOffset;
  323.  
  324.     if(GfxBase->LibNode.lib_Version<36) /* dead reckoning */
  325.      {
  326.       if((COPHEIGHT>>1)>GfxBase->NormalDisplayRows) vshift->DyOffset=14;
  327.      }
  328.     else
  329.      {
  330.       if((COPHEIGHT>>1)>GfxBase->NormalDisplayRows) vshift->DyOffset=22;
  331.      }
  332.  
  333.     PutCop();
  334.     getchar();
  335.     vshift->DyOffset=preserve;
  336.  
  337.     FreeVPortCopLists(&screen->ViewPort);
  338.     RemakeDisplay();
  339.     CloseScreen(screen);
  340.     if(Coppers) FreeMem(Coppers,COPHEIGHT<<5);
  341.    }
  342.  
  343.   if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  344.   if(GfxBase) CloseLibrary((struct Library *)GfxBase);
  345.  }
  346.  
  347. /* our copper list 'magic' */
  348.  
  349. void PutCop()
  350.   {
  351.    int line,creg,top;
  352.  
  353.    ucop=(struct UCopList *)AllocMem(sizeof(struct UCopList),MEMF_CLEAR);
  354.  
  355.    top=COPHEIGHT;
  356.    if(LACEME) top=top/2;
  357.  
  358.    CINIT(ucop,top*13);
  359.  
  360.    for(line=0;line<top;line++)
  361.     {
  362.      if(LACEME) 
  363.       {
  364.        CWAIT(ucop,(line-1)<<1,112);
  365.       }
  366.      else
  367.       {
  368.        CWAIT(ucop,(line-1),112);
  369.       }
  370.  
  371.      for(creg=4;creg<OSCAN;creg++)
  372.       {
  373.        if(LACEME)
  374.         {
  375.          CMOVE(ucop,custom->color[creg],Coppers[(line<<5)+creg]);
  376.         }
  377.        else
  378.         {
  379.          CMOVE(ucop,custom->color[creg],Coppers[(line<<4)+creg]);
  380.         }
  381.       }
  382.     }
  383.    CEND(ucop);
  384.  
  385.   printf("Press return.\n");
  386.   Forbid();
  387.   vp->UCopIns=ucop;
  388.   Permit();
  389.   MakeScreen(screen);
  390.   RethinkDisplay();
  391.  }
  392.  
  393. /* throw up a screen */
  394.  
  395. void GetScreen(struct BMHD *header)
  396.  {
  397.   IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",33);
  398.   if(!IntuitionBase) 
  399.    {
  400.     printf(" Error: unable to open Intuition!\n");
  401.     return;
  402.    }
  403.  
  404.    GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",33);
  405.    if(!GfxBase)
  406.     {
  407.      printf(" Error: unable to open graphics.\n");
  408.      return;
  409.     }
  410.  
  411.    plane.LeftEdge=0;
  412.    plane.TopEdge=0;
  413.    plane.DetailPen=2;
  414.    plane.BlockPen=1;
  415.    plane.Type=CUSTOMSCREEN|SCREENQUIET;
  416.    plane.Font=0;
  417.    plane.DefaultTitle="SHAZAM Screen";
  418.    plane.Gadgets=0;
  419.    plane.CustomBitMap=0;
  420.    plane.ViewModes=0;
  421.  
  422.    plane.Width=header->w;
  423.    plane.Height=header->h;
  424.    plane.Depth=header->nPlanes;
  425.    plane.ViewModes|=HIRES;
  426.   
  427.    if(header->h>300) { plane.ViewModes|=LACE; LACEME=1; }
  428.  
  429.    if(header->w>640) OSCAN=14;
  430.  
  431.    screen=OpenScreen(&plane);
  432.    vp=&screen->ViewPort;
  433.    return;
  434.   }
  435.  
  436. /* BODY voodoo */
  437.  
  438. char UnpackRLL(BYTE **pSource,BYTE **pDest,int srcBytes0,int dstBytes0)
  439.   {
  440.    int srcBytes,dstBytes;
  441.    BYTE *source, *dest, c;
  442.    WORD n,minus128=-128;
  443.  
  444.    source=*pSource;
  445.    dest=*pDest;
  446.    srcBytes=srcBytes0;
  447.    dstBytes=dstBytes0;
  448.  
  449.    while(dstBytes>0) 
  450.     {
  451.      if((srcBytes-=1)<0) return(1);
  452.      n=UGetByte();
  453.  
  454.      if (n >= 0)
  455.       {
  456.        n += 1;
  457.        if((srcBytes-=n)<0) return(2);
  458.        if((dstBytes-=n)<0) return(3);
  459.        do
  460.         {
  461.          UPutByte(UGetByte());
  462.         }
  463.        while(--n>0);
  464.       }
  465.      else if(n!=minus128)
  466.       {
  467.        n = -n + 1;
  468.        if((srcBytes-=1)<0) return(4);
  469.        if((dstBytes-=n)<0) return(5);
  470.        c = UGetByte();
  471.        do
  472.         {
  473.          UPutByte(c);
  474.         }
  475.        while(--n>0);
  476.       }
  477.     }
  478.  
  479.    *pSource=source;  *pDest=dest;
  480.    return(0);
  481.   }
  482.