/* ILBM picture reader etc. for PUZZ M.J.Round January 1990 Largely copied from 'view.c' by D. John Hodgson. */ #define SR(a,b,c) if (Read(a,(char *)b,c)==-1L) return(NULL); #define MAXWIDTH 376 /* max non-HIRES width */ #define MAXHEIGHT 242 /* max non-interlaced height (NTSC) */ #define MAXCOLORS 32 /* max # colors supported */ #define MakeID(a,b,c,d) ((a)<<24L | (b)<<16L | (c)<<8 | (d)) #define ID_FORM MakeID('F','O','R','M') #define ID_ILBM MakeID('I','L','B','M') #define ID_BMHD MakeID('B','M','H','D') #define ID_CAMG MakeID('C','A','M','G') #define ID_CMAP MakeID('C','M','A','P') #define ID_BODY MakeID('B','O','D','Y') typedef struct { long ckID,ckSize; } Chunk; Chunk header; char *bufstart; struct BitMap b; struct RastPort rp; struct RastPort dbuffrastport; struct BitMap dbuffbitmap; extern struct IntuitionBase *IntuitionBase; extern struct GfxBase *GfxBase; extern BitMapHeader bmhd; extern struct TextAttr MyFont; struct Screen *ReadILBM(BPTR fp) { struct NewScreen NewScreen; struct Screen *screen; char colormap[MAXCOLORS][3],*sourcebuf; short colorcount; long id,ViewModes=0; SR(fp,&header,(long)sizeof(header)); if (header.ckID!=ID_FORM) return(NULL); SR(fp,&id,(long)sizeof(id)); if (id!=ID_ILBM) return(NULL); for (;;) { SR(fp,&header,(long)sizeof(header)); if (header.ckID==ID_BODY) break; switch(header.ckID) { case ID_BMHD: SR(fp,&bmhd,(long)sizeof(bmhd)); break; case ID_CMAP: SR(fp,&colormap[0][0],(long)header.ckSize); colorcount=header.ckSize/3; break; case ID_CAMG: SR(fp,&ViewModes,(long)header.ckSize); break; default: Seek(fp,(((header.ckSize)+1)&(~1L)),OFFSET_CURRENT); } } /* Read planes into RAM for ease of decompression */ sourcebuf=bufstart=AllocMem((long)header.ckSize,MEMF_PUBLIC); if (sourcebuf==0L) return (NULL); SR(fp,sourcebuf,(long)header.ckSize); NewScreen.LeftEdge=0; NewScreen.TopEdge=0; NewScreen.Width=bmhd.w; NewScreen.Height=bmhd.h; NewScreen.Depth=bmhd.nPlanes; /* make some forced assumptions if CAMG chunk unavailable */ if (!(NewScreen.ViewModes=ViewModes)) { if (bmhd.w>MAXWIDTH) NewScreen.ViewModes|=HIRES; if (bmhd.h>MAXHEIGHT) NewScreen.ViewModes|=LACE; } NewScreen.Type=CUSTOMSCREEN; NewScreen.Font=&MyFont; NewScreen.Gadgets=0L; screen=OpenScreen(&NewScreen); while (colorcount--) SetRGB4 ( &screen->ViewPort, (long)colorcount, colormap[colorcount][0]>>4L,colormap[colorcount][1]>>4L, colormap[colorcount][2]>>4L ); return(screen); } void Expand(screen,bmhd) /* Fast line decompress/deinterleave */ struct Screen *screen; BitMapHeader *bmhd; { register char *sourcebuf; register char n,*destbuf; /* in order of preferred allocation */ register short plane,linelen,rowbytes,i; sourcebuf = bufstart; linelen=bmhd->w/8; for (i=0;ih;i++) /* process n lines/screen */ { for (plane=0;planenPlanes;plane++) { /* process n planes/line */ destbuf=(char *)(screen->BitMap.Planes[plane])+linelen*i; if (bmhd->compression== 1) { /* compressed screen? */ rowbytes=linelen; while (rowbytes) { /* unpack until 1 scan-line complete */ n=*sourcebuf++; /* fetch block run marker */ /* uncompressed block? copy n bytes verbatim */ if (n>=0) { movmem ( sourcebuf, destbuf, (unsigned int)++n ); rowbytes-=n; destbuf+=n; sourcebuf+=n; } else { /* compr. block? expand n duplicate bytes */ n=-n+1; rowbytes-=n; setmem ( destbuf, (unsigned int)n, (unsigned int)*sourcebuf++ ); destbuf+=n; } } /* finish unpacking line */ } else { /* uncompressed? just copy */ movmem(sourcebuf,destbuf,(unsigned int)linelen); sourcebuf+=linelen; } } /* finish interleaved planes, lines */ } } struct RastPort *getbuffs(int width,int height) { int i; InitBitMap(&b,bmhd.nPlanes,bmhd.w,11); for (i=0; i= 0) FreeRaster(b.Planes[i],bmhd.w,11); return (NULL); } } InitRastPort(&rp); rp.BitMap = &b; InitBitMap(&dbuffbitmap,bmhd.nPlanes,width,height); for (i=0; i= 0) FreeRaster(dbuffbitmap.Planes[i],width,height); return (NULL); } } InitRastPort(&dbuffrastport); dbuffrastport.BitMap = &dbuffbitmap; return (&dbuffrastport); } void saveundermenu(struct RastPort *rast) { ClipBlit ( rast,0,0 /* source posn */ ,&rp,0,0 /* dest posn */ ,bmhd.w,11 /* size */ ,0xc0 /* direct copy */ ); } void drawovermenu(struct RastPort *rast) { ClipBlit ( &rp,0,0 /* source posn */ ,rast,0,0 /* dest posn */ ,bmhd.w,11 /* size */ ,0xc0 /* direct copy */ ); } void freebuffs(int width,int height) { int i; for (i=0; i