/***************************************************************************
*  SaveILBM.c --  Save screen as ILBM file
*
*                 Modified version of Carolyn Scheppner's ScreenSave program
*
*     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 bufSize 512

extern struct IntuitionBase *IntuitionBase;
extern struct Screen *screen;
extern struct Window *MandWind;

struct Screen   *frontScreen;

struct ViewPort *picViewPort;
struct BitMap   *picBitMap;
WORD            *picColorTable;
ULONG            picViewModes;

/**************************************************************************
 *
 *  Save the current screen as an ILBM file
 *
 *************************************************************************/
SaveILBM(FileName)
  char *FileName;
{
  LONG            file;
  IFFP            iffp = NO_FILE;

  int l;

  WindowToFront(MandWind);

  if (!(file = Open(FileName, MODE_NEWFILE))) {
    printf("Can't open file %s\n",FileName);
    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);
  Close(file);

  if (iffp == IFF_OKAY) {
    printf("Screen saved\n");
  }
  printf("Done\n");
} /* SaveILBM */


/** PutPicture() ***********************************************************
 *
 * Put a picture into an IFF file.
 * This procedure calls PutAnILBM, passing in an <x, y> 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;

   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 );
   }


