/*************************************************************************** * SaveILBM.c -- Save front screen as ILBM file * Saves a CAMG chunk for Amiga ViewModes * by Carolyn Scheppner CBM 10/86 * * modified by Kevin L. Clague for use in Mandelbrot * * Using IFF rtns by J.Morrison and S.Shaw of Electronic Arts * ***************************************************************************/ #include "SaveILBM.h" /* CAMG Stuff */ typedef struct { ULONG ViewModes; } CamgChunk; #define PutCAMG(context, camg) \ PutCk(context, ID_CAMG, sizeof(CamgChunk), (BYTE *)camg) #define ID_CRNG MakeID('C','R','N','G') #define PutCRNG(context, crng) \ PutCk(context, ID_CRNG, sizeof(CrngChunk), (BYTE *)crng) #define bufSize 512 extern struct IntuitionBase *IntuitionBase; extern struct Screen *screen; struct Screen *frontScreen; struct ViewPort *picViewPort; struct BitMap *picBitMap; WORD *picColorTable; ULONG picViewModes; /* ILBM Icon Image */ USHORT ILBMimagedata[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x7FFF, 0xFFFF, 0xFFFF, 0xFF80, 0x6000, 0x0000, 0x0000, 0x0180, 0x6000, 0x07FF, 0xFFFF, 0x8180, 0x6000, 0x401F, 0xFFC0, 0x0180, 0x6002, 0xE000, 0x0000, 0x0180, 0x6003, 0x6002, 0x0008, 0x0180, 0x600B, 0xF807, 0x005E, 0x0180, 0x6001, 0xFC03, 0x809F, 0x8180, 0x6000, 0x0E07, 0xC2FF, 0xE180, 0x600D, 0xAF05, 0xE017, 0xF980, 0x6021, 0x2F83, 0xC057, 0xF980, 0x6025, 0xFF1F, 0x24C7, 0xF980, 0x6097, 0xFA6E, 0x881F, 0xF980, 0x601E, 0xFCEC, 0x3B5B, 0xF980, 0x6055, 0xFFBA, 0x559F, 0xF980, 0x60EF, 0xFFFF, 0xFFFF, 0xF980, 0x6000, 0x0000, 0x0000, 0x0180, 0x7FFF, 0xFFFF, 0xFFFF, 0xFF80, 0x0000, 0x0000, 0x0000, 0x0000, /**/ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFC0, 0x8000, 0x0000, 0x0000, 0x0040, 0x9FFF, 0xFFFF, 0xFFFF, 0xFE40, 0x9800, 0x0000, 0x0000, 0x0640, 0x9800, 0x0000, 0x0000, 0x0640, 0x9801, 0x0000, 0x0000, 0x0640, 0x9804, 0x8004, 0x0000, 0x0640, 0x9804, 0x8008, 0x0020, 0x0640, 0x981F, 0x0C0C, 0x0160, 0x0640, 0x983F, 0xFE1F, 0x8D00, 0x0640, 0x98FF, 0xFF7F, 0xDFE8, 0x0640, 0x9BFF, 0xFFFF, 0xFFFF, 0x0640, 0x9FFF, 0xFFFF, 0xFFFF, 0x8640, 0x9FFF, 0xFFFF, 0xFFFF, 0xFE40, 0x9FFF, 0xFFFF, 0xFFFF, 0xFE40, 0x9FFF, 0xFFFF, 0xFFFF, 0xFE40, 0x9FFF, 0xFFFF, 0xFFFF, 0xFE40, 0x9FFF, 0xFFFF, 0xFFFF, 0xFE40, 0x8000, 0x0000, 0x0000, 0x0040, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFC0 /**/ }; struct Image ILBMimage[] = { 0, /* LeftEdge */ 0, /* TopEdge */ 58, /* Width */ 20, /* Height */ 2, /* Depth */ (USHORT *)&ILBMimagedata, /* ImageData */ 0x3, /* PlanePick */ 0x0, /* PlaneOnOff */ 0 /* [NextImage] */ }; struct DiskObject ILBMIcon = { WB_DISKMAGIC, /* do_Magic */ WB_DISKVERSION, /* do_Version */ /* Embedded Gadget Structure */ 0, /* [NextGadget] */ 147, /* LeftEdge */ 23, /* TopEdge */ 58, /* Width */ 20, /* Height */ 0x4, /* Flags */ 0x3, /* Activation */ 0x1, /* GadgetType */ (APTR)&ILBMimage, /* GadgetRender */ NULL, /* SelectRender */ NULL, /* GadgetText */ 0x0, /* MutualExclude */ 0x0, /* [SpecialInfo] */ 0, /* GadgetID */ 0x0, /* [UserData] */ /* Rest of DiskObject structure */ 0x4, /* do_Type */ ":ViewILBM", /* do_Default Tool */ 0xC06508, /* [do_ToolTypes] */ NO_ICON_POSITION, /* do_CurrentX */ NO_ICON_POSITION, /* do_CurrentY */ 0x0, /* [do_DrawerData] */ 0x0, /* [do_ToolWindow] */ 0x0 /* do_StackSize */ }; /************************************************************************** * * Save the current screen as an ILBM file * **************************************************************************/ SaveILBM(FileName, Crng, numCrng) char *FileName; CrngChunk *Crng; int numCrng; { LONG file; IFFP iffp = NO_FILE; int l; if (!(file = Open(FileName, MODE_NEWFILE))) { char Msg[80]; sprintf(Msg,"Can't open file %s\n",FileName); DispErrMsg(Msg,0); return(0); } Write(file,"x",1); /* 1.1 so Seek to beginning works ? */ frontScreen = screen; picViewPort = &( frontScreen->ViewPort ); picBitMap = (struct BitMap*)picViewPort->RasInfo->BitMap; picColorTable = (WORD *)picViewPort->ColorMap->ColorTable; picViewModes = (ULONG)picViewPort->Modes; iffp = PutPicture(file, picBitMap, picColorTable, picViewModes, Crng, numCrng); Close(file); if (iffp == IFF_OKAY && FromWB ) { /* This line outputs the icon */ PutDiskObject(FileName,&ILBMIcon); } } /* SaveILBM */ /** PutPicture() *********************************************************** * * Put a picture into an IFF file. * This procedure calls PutAnILBM, passing in an location of <0, 0>, * a NULL mask, and a locally-allocated buffer. It also assumes you want to * write out all the bitplanes in the BitMap. * ***************************************************************************/ Point2D nullPoint = {0, 0}; IFFP PutPicture(file, bitmap, colorMap, viewmodes, crng, numcrng) LONG file; struct BitMap *bitmap; WORD *colorMap; ULONG viewmodes; CrngChunk *crng; int numcrng; { BYTE buffer[bufSize]; return( PutAnILBM(file, bitmap, NULL, colorMap, bitmap->Depth, viewmodes, &nullPoint, crng, numcrng, buffer, bufSize) ); } /** PutAnILBM() ************************************************************ * * Write an entire BitMap as a FORM ILBM in an IFF file. * This version works for any display mode (C. Scheppner). * * Normal return result is IFF_OKAY. * * The utility program IFFCheck would print the following outline of the * resulting file: * * FORM ILBM * BMHD * CAMG * CMAP * CRNG * CRNG * CRNG * CRNG * BODY (compressed) * ***************************************************************************/ #define CkErr(expression) {if (ifferr == IFF_OKAY) ifferr = (expression);} IFFP PutAnILBM(file, bitmap, mask, colorMap, depth, viewmodes, xy, crng, numcrng, buffer, bufsize) LONG file; struct BitMap *bitmap; BYTE *mask; WORD *colorMap; UBYTE depth; ULONG viewmodes; Point2D *xy; BYTE *buffer; LONG bufsize; CrngChunk *crng; int numcrng; { BitMapHeader bmHdr; CamgChunk camgChunk; GroupContext fileContext, formContext; IFFP ifferr; WORD pageWidth, pageHeight; int i; pageWidth = (bitmap->BytesPerRow) << 3; pageHeight = bitmap->Rows; ifferr = InitBMHdr(&bmHdr, bitmap, mskNone, cmpByteRun1, 0, pageWidth, pageHeight); /* You could write an uncompressed image by passing cmpNone instead * of cmpByteRun1 to InitBMHdr. */ bmHdr.nPlanes = depth; /* This must be <= bitmap->Depth */ if (mask != NULL) bmHdr.masking = mskHasMask; bmHdr.x = xy->x; bmHdr.y = xy->y; camgChunk.ViewModes = viewmodes; CkErr( OpenWIFF(file, &fileContext, szNotYetKnown) ); CkErr(StartWGroup(&fileContext, FORM, szNotYetKnown, ID_ILBM, &formContext)); CkErr( PutBMHD(&formContext, &bmHdr) ); CkErr( PutCAMG(&formContext, &camgChunk) ); CkErr( PutCMAP(&formContext, colorMap, depth) ); for (i = 0; i < numcrng; i++) { CkErr( PutCRNG(&formContext, &crng[i])); } CkErr( PutBODY(&formContext, bitmap, mask, &bmHdr, buffer, bufsize) ); CkErr( EndWGroup(&formContext) ); CkErr( CloseWGroup(&fileContext) ); return( ifferr ); }