/* PlayAnim.c * * Load an ILBM raster image file from C structures in memory * into an existing bitmap (preloaded files from PreLoadAnim). * * Written by Gary Bonham, Sparta, Inc. 15 Aug 1986 * Modified by Olaf `Olsen' Barthel, 16-Sep-1991 * */ #include #include #include "ilbm.h" #include "preloadanim.h" #define UGetByte() (*source++) #define UPutByte(c) (*dest++ = (c)) extern BYTE CheckAbort(); extern VOID FrameSetup(ULONG jiffies); extern VOID FrameSync(VOID); extern VOID SwapBits(VOID); extern VOID CopyBits(VOID); extern VOID LoadPalette(UWORD *Palette); extern VOID __asm decode_vkplane(register __a0 UBYTE *deltabyte,register __a2 PLANEPTR plane,register __d2 UWORD bytesperrow); STATIC VOID __regargs UnPackRow(BYTE **pSource,BYTE **pDest,WORD srcBytes0,WORD dstBytes0); STATIC VOID __regargs SetRIFF(struct BitMap *bm,struct FrameHD *cfr); STATIC VOID __regargs SetBODY(struct BitMap *bm,struct FrameHD *cfr); BYTE PlayAnim(VOID); extern struct IFFfile *IFFfileList; extern struct BitMap *DrawBitMap; STATIC BitMapHeader masterbmhd; STATIC VOID __regargs UnPackRow(BYTE **pSource,BYTE **pDest,WORD srcBytes0,WORD dstBytes0) { BYTE *source = *pSource, *dest = *pDest,c; WORD n, srcBytes = srcBytes0, dstBytes = dstBytes0; while(dstBytes > 0) { if((--srcBytes) < 0) break; if((n = UGetByte()) >= 0) { n++; if((srcBytes -= n) < 0) break; if((dstBytes -= n) < 0) break; do UPutByte(UGetByte()); while(--n); } else { if(n != (WORD)(-128)) /* compiler generates a cmp.w! */ { n = -n + 1; if((--srcBytes) < 0) break; if((dstBytes -= n) < 0) break; c = UGetByte(); do UPutByte(c); while(--n); } } } *pSource = source; *pDest = dest; } STATIC VOID __regargs SetRIFF(struct BitMap *bm,struct FrameHD *cfr) { UBYTE *deltabyte; LONG *deltadata; int i; deltadata = (LONG *)cfr -> body; for(i = 0 ; i < bm -> Depth ; i++) { if(deltadata[i]) { deltabyte = (UBYTE *)deltadata + deltadata[i]; decode_vkplane(deltabyte,bm -> Planes[i],bm -> BytesPerRow); } } } STATIC VOID __regargs SetBODY(struct BitMap *bm,struct FrameHD *cfr) { LONG x,y,deltabyte,i,irow,ip; BYTE *planes[9],*ss,**dd; WORD srcRowBytes,w,h; UBYTE mask; if(cfr -> anhd) { w = cfr -> anhd -> w; h = cfr -> anhd -> h; x = cfr -> anhd -> x; y = cfr -> anhd -> y; mask = cfr -> anhd -> mask; } else { w = cfr -> bmhd -> w; h = cfr -> bmhd -> h; x = cfr -> bmhd -> x; y = cfr -> bmhd -> y; mask = 0xFF; } srcRowBytes = RowBytes(w); deltabyte = (masterbmhd . pageWidth >> 3) - (w >> 3); /* assume cmpByteRun1 data compression */ for(i = 0 ; i < masterbmhd . nPlanes ; i++) { if((mask >> i) & 1) planes[i] = (BYTE *)bm -> Planes[i] + y * bm -> BytesPerRow + (x >> 3); else planes[i] = NULL; } ss = (BYTE *)cfr -> body; for(irow = h ; irow > 0 ; irow--) { for(ip = 0 ; ip < masterbmhd . nPlanes ; ip++) { if(planes[ip]) { dd = &planes[ip]; UnPackRow(&ss,dd,10000,srcRowBytes); planes[ip] += deltabyte; } } } } BYTE PlayAnim() { struct FrameHD *currentframe = IFFfileList -> firstframe; BYTE firstframe = TRUE; ULONG FrameSkip = 0; UBYTE Pop = 0; while(currentframe) { if(firstframe) { if(currentframe -> bmhd) masterbmhd = *currentframe -> bmhd; } else { if(currentframe -> bmhd) masterbmhd = *currentframe -> bmhd; } if(currentframe -> anhd) { Pop = currentframe -> anhd -> operation; FrameSkip = currentframe -> anhd -> reltime; } if(currentframe -> nColorRegs) LoadPalette(currentframe->cmap); if(FrameSkip) { FrameSetup(FrameSkip); FrameSkip = 0; if(Pop >= 2) { if(currentframe -> body) { if(Pop == 5) SetRIFF(DrawBitMap,currentframe); } } else { if(currentframe -> body) SetBODY(DrawBitMap,currentframe); } FrameSync(); } else { if(Pop >= 2) { if(currentframe -> body) { if(Pop == 5) SetRIFF(DrawBitMap,currentframe); } } else { if(currentframe -> body) SetBODY(DrawBitMap,currentframe); } } SwapBits(); if(CheckAbort()) return(FALSE); if(firstframe) { CopyBits(); firstframe = FALSE; } if(currentframe) currentframe = currentframe -> next; } return(TRUE); }