home *** CD-ROM | disk | FTP | other *** search
- /* Copyright © 1991 Lake Forest Logic Inc. */
- /* SHAZAM: Macro Paint picture viewer version 1.1 */
-
- /*
-
- This program is designed to display dynamic hires images created with
- Macro Paint, the 4096 color high-resolution paint program from Lake
- Forest Logic. The source code is provided so that others can support
- Macro Paint images in their viewer programs. There is quite a bit
- of room for improvement in this program but we felt it was important
- to release a usable viewer as soon as possible. 1/31/91
-
- This program is version 1.1: bug reports and suggestions are welcome
- and may be sent to:
-
- Lake Forest Logic Inc.
- 28101 Ballard Road, Unit E
- Lake Forest, IL 60045
- (708)816-6666 FAX: (708)680-0832
- BBS: (708)680-0590 HST, 24 hours
- BIX: equack
- PLink: LFL*ERIK
-
- The program was compiled using SAS/C Version 5.10a. The command
- "LC -rr -L shazam" should suffice to compile and link it.
-
- Permission is granted to distribute this file for non-commercial
- purposes. Portions of the compiled code may be incorporated into your own
- programs (commercial or otherwise), but you may not distribute a modified
- version of this source file without permission.
-
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <libraries/dos.h>
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <graphics/gfx.h>
- #include <graphics/gfxbase.h>
- #include <graphics/view.h>
- #include <graphics/copper.h>
- #include <hardware/custom.h>
- #include <proto/all.h>
- #include <stdio.h>
-
- /* short hand */
-
- #define NL (0)
- #define CINIT(c,n) { UCopperListInit(c,n); }
- #define CWAIT(c,a,b) { CWait(c,a,b);CBump(c); }
- #define CEND(c) { CWAIT(c,10000,255); }
- #define CMOVE(c,a,b) { CMove(c,(long)&a,b);CBump(c); }
-
- #define MakeID(a,b,c,d) ( (LONG)(a)<<24L | (LONG)(b)<<16L | (c)<<8 | (d) )
-
- #define ID_FORM MakeID('F','O','R','M')
- #define ID_MPCT MakeID('M','P','C','T')
- #define ID_DYCP MakeID('D','Y','C','P')
- #define ID_CTBL MakeID('C','T','B','L')
- #define ID_BMHD MakeID('B','M','H','D')
- #define ID_CMAP MakeID('C','M','A','P')
- #define ID_BODY MakeID('B','O','D','Y')
-
- #define BUFSIZE (8192)
- #define UGetByte() (*source++)
- #define UPutByte(c) (*dest++ = (c))
-
- /* some global data */
-
- struct View *vshift;
- struct Screen *screen=0;
- struct NewScreen plane;
- struct GfxBase *GfxBase;
- struct IntuitionBase *IntuitionBase=0;
- struct ViewPort *vp;
-
- int COPHEIGHT;
- char DISPLAY=1,LACEME=0,OSCAN=16;
- UWORD inmap[64],*Coppers;
- UWORD colors[16]={0x000,0x111,0x222,0x333,0x444,0x555,0x666,0x777,
- 0x888,0x999,0xaaa,0xbbb,0xccc,0xddd,0xeee,0xfff};
-
- struct Custom *custom;
- struct UCopList *ucop=0;
-
- struct BMHD
- {
- UWORD w, h;
- WORD x, y;
- UBYTE nPlanes;
- UBYTE masking;
- UBYTE compression;
- UBYTE pad1;
- UWORD transparentColor;
- UBYTE xAspect, yAspect;
- WORD pageWidth, pageHeight;
- };
-
- /* function prototypes */
-
- void Shazam(BPTR);
- void PutCop(void);
- void Chunker(BPTR,ULONG *,int);
- void GetScreen(struct BMHD *header);
- void UnScreen(void);
- char UnpackRLL(BYTE **,BYTE **,int,int);
-
-
- main(int argc,char **argv)
- {
- ULONG handle;
-
- printf("\n\233;1mSHAZAM\233;0m V1.1 © 1991 Lake Forest Logic Inc.\n\n");
-
- if(argc<2)
- {
- printf(" Syntax: SHAZAM <macro paint file>\n");
- }
- else
- {
- handle=Open(argv[1],MODE_OLDFILE);
- if(!handle)
- {
- printf(" Error: unable to open file \233;32m%s\233;0m\n",argv[1]);
- return(1);
- }
- Shazam(handle);
- Close(handle);
- }
- printf("\n");
- return(DISPLAY);
- }
-
- /* get started */
-
- void Shazam(BPTR handle)
- {
- ULONG *buffer;
- int result;
-
- buffer=AllocMem(BUFSIZE,0);
- if(!buffer)
- {
- printf(" Error: not enough memory.\n");
- DISPLAY=1;
- return;
- }
- result=Read(handle,buffer,12);
- if(result!=12)
- {
- printf(" Error: unable to read header.\n");
- DISPLAY=1;
- return;
- }
- if(buffer[0]!=ID_FORM)
- {
- printf(" Error: not an IFF file.\n");
- DISPLAY=1;
- return;
- }
-
- Chunker(handle,buffer,buffer[1]-4);
-
- UnScreen();
-
- FreeMem(buffer,BUFSIZE);
- return;
- }
-
- /* chop up those IFF chunks */
-
- void Chunker(BPTR handle,ULONG *buffer,int total)
- {
- int here,result,size,loop,planes,lines,bites,line,plane;
- struct BMHD *bmhd;
- UBYTE *collar, *source,*dest;
- here=0;
-
- custom=(struct Custom *) 0x00DFF000;
-
- while(here<total)
- {
- if(here==1) return;
- if(here&1) Read(handle,buffer,1);
- result=Read(handle,buffer,8);
- if(result!=8)
- {
- printf(" Error: unable to read chunk header.\n");
- DISPLAY=1;
- return;
- }
- size=buffer[1];
- if(buffer[0]==ID_MPCT)
- {
- DISPLAY=0;
- }
- if(buffer[0]==ID_BODY)
- {
- if(screen)
- {
- collar=AllocMem(size,0);
- if(!collar)
- {
- printf(" Error: unable to allocate BODY.\n");
- DISPLAY=1;
- }
- else
- {
- result=Read(handle,collar,size);
- if(result!=size) printf(" Error: unable to read BODY.\n");
- lines=screen->BitMap.Rows;
- planes=screen->BitMap.Depth;
- bites=screen->BitMap.BytesPerRow;
- source=collar;
-
- for(line=0;line<lines;line++)
- {
- for(plane=0;plane<planes;plane++)
- {
- dest=screen->BitMap.Planes[plane]+line*bites;
- result=UnpackRLL(&source,&dest,size,bites);
-
- if(result)
- {
- printf(" Error %d: unable to unpack BODY L:%d P:%d.\n",
- result,line,plane);
- DISPLAY=1;
- FreeMem(collar,size);
- here+=size+8;
- return;
- }
- }
- }
- FreeMem(collar,size);
- }
- }
- }
- else if(buffer[0]==ID_CMAP)
- {
- result=Read(handle,buffer,size);
- if(screen)
- {
- collar=(BYTE *)buffer;
- for(loop=0;loop<size/3;loop++)
- {
- inmap[loop]=((collar[loop*3]>>4)<<8)+((collar[loop*3+1]>>4)<<4)+(collar[loop*3+2]>>4);
- SetRGB4(&screen->ViewPort,
- loop,collar[loop*3]>>4,collar[loop*3+1]>>4,collar[loop*3+2]>>4);
- }
- }
- }
- else if(buffer[0]==ID_CTBL)
- {
- Coppers=AllocMem(size,0);
- if(!Coppers) DISPLAY=1;
- else
- {
- COPHEIGHT=size/32;
- result=Read(handle,Coppers,size);
- if(!DISPLAY)
- {
- colors[0]=Coppers[0];
- colors[1]=Coppers[1];
- colors[2]=Coppers[2];
- colors[3]=Coppers[3];
- LoadRGB4(&screen->ViewPort,colors,20);
- }
- }
- }
- else if(buffer[0]==ID_BMHD)
- {
- result=Read(handle,buffer,size);
- if(!DISPLAY)
- {
- bmhd=(struct BMHD *)buffer;
- GetScreen(bmhd);
- }
- else
- {
- printf(" Not a Macro Paint picture file.\n");
- DISPLAY=1;
- }
- }
- else
- {
- if(size%BUFSIZE)
- {
- result=Read(handle,buffer,size%BUFSIZE);
- if(result!=size%BUFSIZE)
- {
- printf(" Error: unable to read chunk body.\n");
- DISPLAY=1;
- return;
- }
- }
- if(size/BUFSIZE) for(loop=0;loop<size/BUFSIZE;loop++)
- {
- result=Read(handle,buffer,BUFSIZE);
- if(result!=BUFSIZE)
- {
- printf(" Error: unable to read chunk body.\n");
- DISPLAY=1;
- return;
- }
- }
- }
- here+=size+8;
- }
- }
-
- /* kick in the display and wait for the end */
-
- void UnScreen()
- {
- int preserve;
- if(screen)
- {
- ScreenToFront(screen);
-
- vshift=ViewAddress();
- preserve=vshift->DyOffset;
-
- if(GfxBase->LibNode.lib_Version<36) /* dead reckoning */
- {
- if((COPHEIGHT>>1)>GfxBase->NormalDisplayRows) vshift->DyOffset=14;
- }
- else
- {
- if((COPHEIGHT>>1)>GfxBase->NormalDisplayRows) vshift->DyOffset=22;
- }
-
- PutCop();
- getchar();
- vshift->DyOffset=preserve;
-
- FreeVPortCopLists(&screen->ViewPort);
- RemakeDisplay();
- CloseScreen(screen);
- if(Coppers) FreeMem(Coppers,COPHEIGHT<<5);
- }
-
- if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
- if(GfxBase) CloseLibrary((struct Library *)GfxBase);
- }
-
- /* our copper list 'magic' */
-
- void PutCop()
- {
- int line,creg,top;
-
- ucop=(struct UCopList *)AllocMem(sizeof(struct UCopList),MEMF_CLEAR);
-
- top=COPHEIGHT;
- if(LACEME) top=top/2;
-
- CINIT(ucop,top*13);
-
- for(line=0;line<top;line++)
- {
- if(LACEME)
- {
- CWAIT(ucop,(line-1)<<1,112);
- }
- else
- {
- CWAIT(ucop,(line-1),112);
- }
-
- for(creg=4;creg<OSCAN;creg++)
- {
- if(LACEME)
- {
- CMOVE(ucop,custom->color[creg],Coppers[(line<<5)+creg]);
- }
- else
- {
- CMOVE(ucop,custom->color[creg],Coppers[(line<<4)+creg]);
- }
- }
- }
- CEND(ucop);
-
- printf("Press return.\n");
- Forbid();
- vp->UCopIns=ucop;
- Permit();
- MakeScreen(screen);
- RethinkDisplay();
- }
-
- /* throw up a screen */
-
- void GetScreen(struct BMHD *header)
- {
- IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",33);
- if(!IntuitionBase)
- {
- printf(" Error: unable to open Intuition!\n");
- return;
- }
-
- GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",33);
- if(!GfxBase)
- {
- printf(" Error: unable to open graphics.\n");
- return;
- }
-
- plane.LeftEdge=0;
- plane.TopEdge=0;
- plane.DetailPen=2;
- plane.BlockPen=1;
- plane.Type=CUSTOMSCREEN|SCREENQUIET;
- plane.Font=0;
- plane.DefaultTitle="SHAZAM Screen";
- plane.Gadgets=0;
- plane.CustomBitMap=0;
- plane.ViewModes=0;
-
- plane.Width=header->w;
- plane.Height=header->h;
- plane.Depth=header->nPlanes;
- plane.ViewModes|=HIRES;
-
- if(header->h>300) { plane.ViewModes|=LACE; LACEME=1; }
-
- if(header->w>640) OSCAN=14;
-
- screen=OpenScreen(&plane);
- vp=&screen->ViewPort;
- return;
- }
-
- /* BODY voodoo */
-
- char UnpackRLL(BYTE **pSource,BYTE **pDest,int srcBytes0,int dstBytes0)
- {
- int srcBytes,dstBytes;
- BYTE *source, *dest, c;
- WORD n,minus128=-128;
-
- source=*pSource;
- dest=*pDest;
- srcBytes=srcBytes0;
- dstBytes=dstBytes0;
-
- while(dstBytes>0)
- {
- if((srcBytes-=1)<0) return(1);
- n=UGetByte();
-
- if (n >= 0)
- {
- n += 1;
- if((srcBytes-=n)<0) return(2);
- if((dstBytes-=n)<0) return(3);
- do
- {
- UPutByte(UGetByte());
- }
- while(--n>0);
- }
- else if(n!=minus128)
- {
- n = -n + 1;
- if((srcBytes-=1)<0) return(4);
- if((dstBytes-=n)<0) return(5);
- c = UGetByte();
- do
- {
- UPutByte(c);
- }
- while(--n>0);
- }
- }
-
- *pSource=source; *pDest=dest;
- return(0);
- }
-