summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Examples/GrabScreen.c337
1 files changed, 337 insertions, 0 deletions
diff --git a/Examples/GrabScreen.c b/Examples/GrabScreen.c
new file mode 100644
index 0000000..2575d1c
--- /dev/null
+++ b/Examples/GrabScreen.c
@@ -0,0 +1,337 @@
+/*
+**
+** $Id: $
+** $Revision: $
+**
+** $Filename: Examples/GrabScreen.c $
+** $Author: Christian A. Weber $
+** $Release: 21.1 $
+** $Date: 92/05/18 15:29:18 $
+**
+** 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.1 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.
+*/
+
+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;
+}