home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD2.img
/
d4xx
/
d449
/
shazam
/
shazam.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-02
|
11KB
|
482 lines
/* 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);
}