home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD2.img
/
d4xx
/
d449
/
shazam
/
old
/
shazam.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-02
|
12KB
|
475 lines
/* Copyright © 1991 Lake Forest Logic Inc. */
/* SHAZAM: Macro Paint picture viewer version 1.0 */
/*
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 support
Macro Paint images in their viewer programs. The 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/30/91
This program is version 1.0: 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 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 <proto/all.h>
#include <stdio.h>
#include <ctype.h>
#include <hardware/custom.h>
#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); }
struct View *vshift;
struct Screen *screen=0;
struct NewScreen plane;
struct GfxBase *GfxBase;
struct IntuitionBase *IntuitionBase=0;
struct ViewPort *vp;
UWORD inmap[64],*Coppers;
char DISPLAY=1,LACEME=0,OSCAN=16,OSTART=4,TRUNK=1;
int COPHEIGHT;
#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))
struct Custom *custom;
struct UCopList *ucop=0;
struct QBMHD
{
UWORD w, h; /* raster width & height in pixels */
WORD x, y; /* position for this image */
UBYTE nPlanes; /* # source bitplanes */
UBYTE masking; /* masking technique */
UBYTE compression; /* compression algoithm */
UBYTE pad1; /* UNUSED. For consistency, put 0 here.*/
UWORD transparentColor; /* transparent "color number" */
UBYTE xAspect, yAspect; /* aspect ratio, a rational number x/y */
WORD pageWidth, pageHeight; /* source "page" size in pixels */
};
void QDV(BPTR);
void PutCop(void);
void Chunker(BPTR,ULONG *,int);
void GetScreen(struct QBMHD *header);
void UnScreen(void);
char UnpackRLL(BYTE **,BYTE **,int,int);
main(int argc,char **argv)
{
ULONG handle;
printf("\n\233;1mSHAZAM\233;0m V1.0 © 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);
}
QDV(handle);
Close(handle);
}
printf("\n");
return(DISPLAY);
}
void QDV(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;
}
void Chunker(BPTR handle,ULONG *buffer,int total)
{
int here,result,size,loop,planes,lines,bites,line,plane;
struct QBMHD *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)
{
SetRGB4(&screen->ViewPort, 0,(Coppers[0]>>8)&15,(Coppers[0]>>4)&15,Coppers[0]&15);
SetRGB4(&screen->ViewPort, 1,(Coppers[1]>>8)&15,(Coppers[1]>>4)&15,Coppers[1]&15);
SetRGB4(&screen->ViewPort, 2,(Coppers[2]>>8)&15,(Coppers[2]>>4)&15,Coppers[2]&15);
SetRGB4(&screen->ViewPort, 3,(Coppers[3]>>8)&15,(Coppers[3]>>4)&15,Coppers[3]&15);
SetRGB4(&screen->ViewPort, 4,4,4,4);
SetRGB4(&screen->ViewPort, 5,5,5,5);
SetRGB4(&screen->ViewPort, 6,6,6,6);
SetRGB4(&screen->ViewPort, 7,7,7,7);
SetRGB4(&screen->ViewPort, 8,8,8,8);
SetRGB4(&screen->ViewPort, 9,9,9,9);
SetRGB4(&screen->ViewPort,10,10,10,10);
SetRGB4(&screen->ViewPort,11,11,11,11);
SetRGB4(&screen->ViewPort,12,12,12,12);
SetRGB4(&screen->ViewPort,13,13,13,13);
SetRGB4(&screen->ViewPort,14,14,14,14);
SetRGB4(&screen->ViewPort,15,15,15,15);
}
}
}
else if(buffer[0]==ID_BMHD)
{
result=Read(handle,buffer,size);
if(!DISPLAY)
{
bmhd=(struct QBMHD *)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;
}
}
void UnScreen()
{
int shifted;
if(screen)
{
ScreenToFront(screen);
vshift=ViewAddress();
if(!TRUNK)
if((COPHEIGHT>>1)>GfxBase->NormalDisplayRows)
{
shifted=((COPHEIGHT>>1)-GfxBase->NormalDisplayRows)>>1;
vshift->DyOffset-=shifted;
}
PutCop();
getchar();
if(!TRUNK) vshift->DyOffset+=shifted;
FreeVPortCopLists(&screen->ViewPort);
RemakeDisplay();
CloseScreen(screen);
if(Coppers) FreeMem(Coppers,COPHEIGHT<<5);
}
if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
if(GfxBase) CloseLibrary((struct Library *)GfxBase);
}
void PutCop()
{
int line,creg,top;
ucop=(struct UCopList *)AllocMem(sizeof(struct UCopList),MEMF_CLEAR);
top=COPHEIGHT;
if(LACEME) top=top/2;
if(TRUNK)
if(top>GfxBase->NormalDisplayRows) top=GfxBase->NormalDisplayRows;
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=OSTART;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();
}
void GetScreen(struct QBMHD *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;
}
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);
}