/* * ScreenSave.c -- v1.06 Carolyn Scheppner CBM * Saves front screen as ILBM file * Saves a CAMG chunk for HAM, etc. * Creates icon for ILBM file * Original 10/86 * Modified 9/88 - To mask out unwanted ViewMode bits in CAMG * and use CAMG defs in new ilbm.h * * Uses IFF rtns by J.Morrison and S.Shaw of Electronic Arts * * (all C code including IFF modules compiled with -v on LC2) * Linkage information: * FROM AStartup.obj, ScreenSave.o, iffw.o, ilbmw.o, packer.o * TO ScreenSave * LIBRARY Amiga.lib, LC.lib * */ #include #include #include #include #include #include #include #include #include #include #include #include #include "ilbm.h" extern struct IntuitionBase *IntuitionBase; /* Pointer aus exec */ /* For masking unwanted Viewmodes bits */ #define BADFLAGS (SPRITES|VP_HIDE|GENLOCK_AUDIO|GENLOCK_VIDEO) #define FLAGMASK (~BADFLAGS) #define CAMGMASK (FLAGMASK & 0x0000FFFFL) /* Other Stuff */ #define bufSize 512 struct Screen *frontScreen; struct ViewPort *picViewPort; struct BitMap *picBitMap; WORD *picColorTable; ULONG picViewModes; #define INBUFSZ 40 char sbuf[INBUFSZ]; char nbuf[INBUFSZ]; /* Definitions for ILBM Icon */ USHORT ILBMimagedata[] = { 0xFFFF, 0xFFFC, 0xC000, 0x000C, 0xC000, 0x000C, 0xC1E7, 0x9E0C, 0xC1F8, 0x7E0C, 0xC078, 0x780C, 0xC187, 0x860C, 0xC078, 0x780C, 0xC1F8, 0x7E0C, 0xC1E7, 0x9E0C, 0xC000, 0x000C, 0xC000, 0x000C, 0xFFFF, 0xFFFC, 0x0000, 0x0000, 0x0000, 0x0000, /**/ 0xFFFF, 0xFFFC, 0xFFFF, 0xFFFC, 0xF800, 0x007C, 0xF9E0, 0x1E7C, 0xF980, 0x067C, 0xF807, 0x807C, 0xF81F, 0xE07C, 0xF807, 0x807C, 0xF980, 0x067C, 0xF9E0, 0x1E7C, 0xF800, 0x007C, 0xFFFF, 0xFFFC, 0xFFFF, 0xFFFC, 0x0000, 0x0000, 0x0000, 0x0000, /**/ }; struct Image ILBMimage = { 0,0, /* Leftedge, Topedge */ 30,15, /* Width Height */ 2, /* Depth */ &ILBMimagedata[0], /* Data for image */ 3,0 /* PlanePick, PlaneOnOff */ }; struct DiskObject ILBMobject = { WB_DISKMAGIC, WB_DISKVERSION, /* Gadget Structure */ NULL, /* Ptr to next gadget */ 0,0, /* Leftedge, Topedge */ 30,15, /* Width, Height */ GADGHBOX|GADGIMAGE, /* Flags */ RELVERIFY|GADGIMMEDIATE, /* Activation */ BOOLGADGET, /* Type */ (APTR)&ILBMimage, /* Render */ NULL, /* Select Render */ NULL, /* Text */ NULL,NULL,NULL,NULL, /* Exclude, Special, ID, UserData */ 4, /* WBObject type */ ":Display", /* Default tool */ NULL, /* Tool Types */ NO_ICON_POSITION, /* Current X */ NO_ICON_POSITION, /* Current Y */ NULL,NULL,NULL, /* Drawer, ToolWindow, Stack */ }; extern char filename[150]; extern struct Screen *screen; extern struct Window *window; screensave() { IFFP iffp = NO_FILE; struct Process *OurTask; struct Window *old_pr_WindowPtr; LONG fp; static char plotname[150], def_drive[150], def_path[100], def_node[30],def_extn[20]; strcpy(plotname,filename); strsfn(plotname,def_drive,def_path,def_node,def_extn); strcat(def_drive,def_path); strcat(def_node,".pic"); OurTask = (struct Process *)FindTask(0L); old_pr_WindowPtr = (struct Window *)OurTask->pr_WindowPtr; OurTask->pr_WindowPtr = (APTR)window; if (get_fname(window,screen,"Save File As...",def_node,def_drive)==NULL) { OurTask->pr_WindowPtr = (APTR)old_pr_WindowPtr; return(TRUE); } OurTask->pr_WindowPtr = (APTR)old_pr_WindowPtr; strmfp(plotname,def_drive,def_node); if (!(fp = Open(plotname,MODE_NEWFILE) )) {Message(" Can't open file "); return(FALSE);} Write(fp,"x",1); /* 1.1 so Seek to beginning works ? */ Forbid(); frontScreen = IntuitionBase->FirstScreen; Permit(); picViewPort = &( frontScreen->ViewPort ); picBitMap = (struct BitMap*)picViewPort->RasInfo->BitMap; picColorTable = (WORD *)picViewPort->ColorMap->ColorTable; picViewModes = (ULONG)picViewPort->Modes; iffp = PutPicture(fp, picBitMap, picColorTable, picViewModes); Close(fp); if (iffp == IFF_OKAY) { if(!(PutDiskObject(plotname,&ILBMobject))) {Message(" Can't open .info file "); return(FALSE);} } return(1); } /** 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) LONG file; struct BitMap *bitmap; WORD *colorMap; ULONG viewmodes; { BYTE buffer[bufSize]; return( PutAnILBM(file, bitmap, NULL, colorMap, bitmap->Depth, viewmodes, &nullPoint, 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 * BODY (compressed) * ***************************************************************************/ #define CkErr(expression) {if (ifferr == IFF_OKAY) ifferr = (expression);} IFFP PutAnILBM(file, bitmap, mask, colorMap, depth, viewmodes, xy, buffer, bufsize) LONG file; struct BitMap *bitmap; BYTE *mask; WORD *colorMap; UBYTE depth; ULONG viewmodes; Point2D *xy; BYTE *buffer; LONG bufsize; { BitMapHeader bmHdr; CamgChunk camgChunk; GroupContext fileContext, formContext; IFFP ifferr; WORD pageWidth, pageHeight; 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 & CAMGMASK; /* Mask out unwanted bits! */ 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) ); CkErr( PutBODY(&formContext, bitmap, mask, &bmHdr, buffer, bufsize) ); CkErr( EndWGroup(&formContext) ); CkErr( CloseWGroup(&fileContext) ); return( ifferr ); }