home *** CD-ROM | disk | FTP | other *** search
- /*
- **
- ** $Id: GrabScreen.c,v 21.2 92/05/18 02:27:41 chris Exp $
- ** $Revision: 21.2 $
- **
- ** $Filename: Examples/GrabScreen.c $
- ** $Author: chris $
- ** $Release: 21.1 $
- ** $Date: 92/05/18 02:27:41 $
- **
- ** IFF library example program. Compile with Lattice C 5.x.
- ** This program saves the contents of the frontmost screen as an IFF file
- ** with filename 'RAM:grabscreen.pic'.
- ** This example makes use of the IFFL_PushChunk() / IFFL_WriteChunkBytes() /
- ** IFFL_PopChunk() functions, it does not use IFFL_SaveBitMap().
- **
- ** COPYRIGHT (C) 1987-1992 BY CHRISTIAN A. WEBER, BRUGGERWEG 2,
- ** CH-8037 ZUERICH, SWITZERLAND.
- ** THIS FILE MAY BE FREELY DISTRIBUTED. USE AT YOUR OWN RISK.
- **
- */
-
- #include <proto/exec.h>
- #include <exec/memory.h>
- #include <proto/graphics.h>
- #include <graphics/gfxbase.h>
- #include <proto/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <dos/dos.h>
-
- #include <stdio.h>
-
- #include <libraries/iff.h> /* IFF library include file */
-
- /*
- ** Flags that should be masked out of old 16-bit CAMG before save or use.
- ** Note that 32-bit mode id (non-zero high word) bits should not be twiddled
- */
- #define OLDCAMGMASK (~(SPRITES|VP_HIDE|GENLOCK_AUDIO|GENLOCK_VIDEO))
-
- #define MAXSAVEDEPTH 24
- #define BODYBUFSIZE 10000
- #define MAXPACKEDSIZE(s) ((s)*2)
-
- /*
- ** Masking techniques
- */
- #define mskNone 0
- #define mskHasMask 1
- #define mskHasTransparentColor 2
- #define mskLasso 3
-
- /*
- ** Compression techniques
- */
- #define cmpNone 0
- #define cmpByteRun1 1
-
-
- /****************************************************************************
- ** Globals
- */
-
- struct Library *IFFBase;
- char version[] = "\0$VER: GrabScreen 21.2 by Christian A. Weber";
-
-
- /****************************************************************************
- ** This is an example implementation of an IFF writer. It writes the
- ** contents of a screen to an IFF ILBM file.
- ** Basically, this routine does the same as IFFL_SaveBitMap(), but it is
- ** here anyway to show you how to write an IFF file using iff.library's
- ** generic write functions.
- */
-
- BOOL MySaveScreen(struct Screen *screen,char *filename)
- {
- IFFL_HANDLE iff;
- struct BitMap *bitmap = &screen->BitMap;
- BOOL result = FALSE;
-
- /*
- ** Open the file for writing
- */
- if(iff = IFFL_OpenIFF(filename,IFFL_MODE_WRITE))
- {
- struct IFFL_BMHD bmhd;
- ULONG modeid;
- UBYTE *colortable;
- int count;
-
- /*
- ** Prepare the BMHD structure
- */
- bmhd.w = screen->Width;
- bmhd.h = screen->Height;
- bmhd.x = screen->LeftEdge; /* Not very useful :-) */
- bmhd.y = screen->TopEdge;
- bmhd.nPlanes = bitmap->Depth;
- bmhd.masking = mskNone;
- bmhd.compression = cmpByteRun1;
- bmhd.pad1 = 0;
- bmhd.transparentColor = 0;
- bmhd.xAspect = screen->Width;
- bmhd.yAspect = screen->Height;
- bmhd.pageWidth = screen->Width;
- bmhd.pageHeight = screen->Height;
-
- /*
- ** Create the BMHD chunk. (goto considered useful :-))
- */
- if(IFFL_PushChunk(iff,ID_ILBM,ID_BMHD))
- {
- if(!IFFL_WriteChunkBytes(iff,&bmhd,sizeof(bmhd)))
- {
- printf("Error writing BMHD data.\n");
- goto error;
- }
-
- if(!IFFL_PopChunk(iff))
- {
- printf("Error closing BMHD chunk.\n");
- goto error;
- }
- }
- else
- {
- printf("Error creating BMHD chunk.\n");
- goto error;
- }
-
- /*
- ** Create the CMAP chunk.
- */
- count = screen->ViewPort.ColorMap->Count;
- if(colortable = AllocMem(count * 3, MEMF_ANY))
- {
- int i;
-
- for(i=0; i<count; ++i)
- {
- UWORD rgb4 = GetRGB4(screen->ViewPort.ColorMap,i);
-
- colortable[i*3+0] = (rgb4 >> 4) & 0xF0;
- colortable[i*3+0] |= colortable[i*3+0] >> 4;
-
- colortable[i*3+1] = (rgb4 ) & 0xF0;
- colortable[i*3+1] |= colortable[i*3+1] >> 4;
-
- colortable[i*3+2] = (rgb4 << 4) & 0xF0;
- colortable[i*3+2] |= colortable[i*3+2] >> 4;
- }
-
- if(IFFL_PushChunk(iff,ID_ILBM,ID_CMAP))
- {
- if(!IFFL_WriteChunkBytes(iff,colortable,count * 3))
- {
- printf("Error writing CMAP data.\n");
- goto error;
- }
-
- if(!IFFL_PopChunk(iff))
- {
- printf("Error closing CMAP chunk.\n");
- goto error;
- }
- }
- else
- {
- printf("Error creating CMAP chunk.\n");
- goto error;
- }
-
- FreeMem(colortable,count * 3);
- }
-
- /*
- ** Get the viewport's modes for the CAMG chunk.
- */
- modeid = (GfxBase->LibNode.lib_Version >= 36) ?
- GetVPModeID(&screen->ViewPort) : (screen->ViewPort.Modes&OLDCAMGMASK);
-
- if(IFFL_PushChunk(iff,ID_ILBM,ID_CAMG))
- {
- if(!IFFL_WriteChunkBytes(iff,&modeid,sizeof(modeid)))
- {
- printf("Error writing CAMG data.\n");
- goto error;
- }
-
- if(!IFFL_PopChunk(iff))
- {
- printf("Error closing CAMG chunk.\n");
- goto error;
- }
- }
- else
- {
- printf("Error creating CAMG chunk.\n");
- goto error;
- }
-
- /*
- ** Generate BODY
- */
- if(IFFL_PushChunk(iff,ID_ILBM,ID_BODY))
- {
- UBYTE *bodybuf;
-
- if(bodybuf = AllocMem(BODYBUFSIZE,MEMF_ANY))
- {
- UBYTE *planes[MAXSAVEDEPTH];
- int row,rowbytes,iplane,bodysize=0;
-
- rowbytes = bitmap->BytesPerRow;
-
- /*
- ** Copy the plane pointers into the local array "planes"
- */
- for(iplane=0; iplane < bmhd.nPlanes; ++iplane)
- {
- planes[iplane] = bitmap->Planes[iplane];
- }
-
- for(row=0; row < bmhd.h; ++row)
- {
- for(iplane=0; iplane < bmhd.nPlanes; ++iplane)
- {
- int comprsize;
-
- /*
- ** To speed up things, we collect as much data
- ** as possible in bodybuf before we write it out.
- */
- if(bodysize > (BODYBUFSIZE-MAXPACKEDSIZE(rowbytes)))
- {
- if(!IFFL_WriteChunkBytes(iff,bodybuf,bodysize))
- {
- printf("Error writing BODY data.\n");
- goto error;
- }
- bodysize = 0;
- }
-
- /*
- ** Compress the next row
- */
- if(!(comprsize = IFFL_CompressBlock(planes[iplane],
- bodybuf+bodysize,rowbytes,IFFL_COMPR_BYTERUN1)))
- {
- printf("Error compressing BODY data.\n");
- goto error;
- }
- bodysize += comprsize;
- planes[iplane] += rowbytes;
- }
- }
-
- /*
- ** Now we're done, so flush the body data buffer
- */
- if(bodysize)
- {
- if(!IFFL_WriteChunkBytes(iff,bodybuf,bodysize))
- {
- printf("Error writing BODY data.\n");
- goto error;
- }
- }
-
- FreeMem(bodybuf,BODYBUFSIZE);
- }
- else
- {
- printf("No memory for BODY buffer.\n");
- goto error;
- }
-
- if(!IFFL_PopChunk(iff))
- {
- printf("Error closing BODY chunk.\n");
- goto error;
- }
-
- /*
- ** If we get here, everything was fine.
- */
- result = TRUE;
- }
- else
- {
- printf("Error creating BODY chunk.\n");
- goto error;
- }
- error:
- IFFL_CloseIFF(iff);
- }
-
- return result;
- }
-
- /****************************************************************************
- ** Main program
- */
-
- int main(int argc, char **argv)
- {
- int result = RETURN_FAIL;
-
- if(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0))
- {
- if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
- {
- /*
- ** For the new functions we need at least version 21 of iff.library.
- */
- if(IFFBase = OpenLibrary(IFFNAME,21))
- {
- /*
- ** Note that we don't lock the screen, so it might go away while
- ** we're writing its contents to the file, and the picture may
- ** then contain garbage.
- */
- MySaveScreen(IntuitionBase->FirstScreen,"RAM:grabscreen.pic");
- result = RETURN_OK;
-
- CloseLibrary(IFFBase);
- }
- else printf("Can't open iff.library V21+\n");
-
- CloseLibrary(IntuitionBase);
- }
- else printf("Can't open intuition.library!\n");
-
- CloseLibrary(GfxBase);
- }
- else printf("Can't open graphics.library!\n");
-
- return result;
- }
-