[comp.sources.amiga] v89i155: mandelvroom - mandelbrot explorer v2.0, Part04/09

page%swap@Sun.COM (Bob Page) (06/21/89)

Submitted-by: kevin@uts.amdahl.com (Kevin Clague)
Posting-number: Volume 89, Issue 155
Archive-name: graphics/mandelv20.4

# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
#	ilbmw.c
#	lens.c
#	lists.c
#	main.c
#	makefile
#	mand.c
# This is archive 4 of a 9-part kit.
# This archive created: Tue Jun 20 20:45:28 1989
echo "extracting ilbmw.c"
sed 's/^X//' << \SHAR_EOF > ilbmw.c
X/*----------------------------------------------------------------------*
X * ILBMW.C  Support routines for writing ILBM files.            1/23/86
X * (IFF is Interchange Format File.)
X *
X * By Jerry Morrison and Steve Shaw, Electronic Arts.
X * This software is in the public domain.
X *
X * This version for the Commodore-Amiga computer.
X *----------------------------------------------------------------------*/
X#include "iff/packer.h"
X#include "iff/ilbm.h"
X
X/*---------- InitBMHdr -------------------------------------------------*/
XIFFP InitBMHdr(bmHdr0, bitmap, masking, compression, transparentColor,
X	    pageWidth, pageHeight)
X        BitMapHeader *bmHdr0;  struct BitMap *bitmap;
X        WORD masking;		/* Masking */
X	WORD compression;	/* Compression */
X	WORD transparentColor;	/* UWORD */
X	WORD pageWidth, pageHeight;
X    {
X    register BitMapHeader *bmHdr = bmHdr0;
X    register WORD rowBytes = bitmap->BytesPerRow;
X
X    bmHdr->w = rowBytes << 3;
X    bmHdr->h = bitmap->Rows;
X    bmHdr->x = bmHdr->y = 0;	/* Default position is (0,0).*/
X    bmHdr->nPlanes = bitmap->Depth;
X    bmHdr->masking = masking;
X    bmHdr->compression = compression;
X    bmHdr->pad1 = 0;
X    bmHdr->transparentColor = transparentColor;
X    bmHdr->xAspect = bmHdr->yAspect = 1;
X    bmHdr->pageWidth = pageWidth;
X    bmHdr->pageHeight = pageHeight;
X
X    if (pageWidth = 320)
X	switch (pageHeight) {
X	    case 200: {bmHdr->xAspect = x320x200Aspect;
X		       bmHdr->yAspect = y320x200Aspect; break;}
X	    case 400: {bmHdr->xAspect = x320x400Aspect;
X		       bmHdr->yAspect = y320x400Aspect; break;}
X	    }
X    else if (pageWidth = 640)
X	switch (pageHeight) {
X	    case 200: {bmHdr->xAspect = x640x200Aspect;
X		       bmHdr->yAspect = y640x200Aspect; break;}
X	    case 400: {bmHdr->xAspect = x640x400Aspect;
X		       bmHdr->yAspect = y640x400Aspect; break;}
X	    }
X
X    return( IS_ODD(rowBytes) ? CLIENT_ERROR : IFF_OKAY );
X    }
X
X/*---------- PutCMAP ---------------------------------------------------*/
XIFFP PutCMAP(context, colorMap, depth)   
X      GroupContext *context;  WORD *colorMap;  UBYTE depth;
X   {
X   register LONG nColorRegs;   
X   IFFP iffp;
X   ColorRegister colorReg;
X
X   if (depth > MaxAmDepth)   depth = MaxAmDepth;
X   nColorRegs = 1 << depth;
X
X   iffp = PutCkHdr(context, ID_CMAP, nColorRegs * sizeofColorRegister);
X   CheckIFFP();
X
X   for ( ;  nColorRegs;  --nColorRegs)  {
X      colorReg.red   = ( *colorMap >> 4 ) & 0xf0;
X      colorReg.green = ( *colorMap      ) & 0xf0;
X      colorReg.blue  = ( *colorMap << 4 ) & 0xf0;
X      iffp = IFFWriteBytes(context, (BYTE *)&colorReg, sizeofColorRegister);
X      CheckIFFP();
X      ++colorMap;
X      }
X
X   iffp = PutCkEnd(context);
X   return(iffp);
X   }
X
X/*---------- PutBODY ---------------------------------------------------*/
X/* NOTE: This implementation could be a LOT faster if it used more of the
X * supplied buffer. It would make far fewer calls to IFFWriteBytes (and
X * therefore to DOS Write). */
XIFFP PutBODY(context, bitmap, mask, bmHdr, buffer, bufsize)
X      GroupContext *context;  struct BitMap *bitmap;  BYTE *mask;
X      BitMapHeader *bmHdr;  BYTE *buffer;  LONG bufsize;
X   {         
X   IFFP iffp;
X   LONG rowBytes = bitmap->BytesPerRow;
X   int dstDepth = bmHdr->nPlanes;
X   Compression compression = bmHdr->compression;
X   int planeCnt;		/* number of bit planes including mask */
X   register int iPlane, iRow;
X   register LONG packedRowBytes;
X   BYTE *buf;
X   BYTE *planes[MaxAmDepth + 1]; /* array of ptrs to planes & mask */
X
X   if ( bufsize < MaxPackedSize(rowBytes)  ||	/* Must buffer a comprsd row*/
X        compression > cmpByteRun1  ||		/* bad arg */
X	bitmap->Rows != bmHdr->h   ||		/* inconsistent */
X	rowBytes != RowBytes(bmHdr->w)  ||	/* inconsistent*/
X	bitmap->Depth < dstDepth   ||		/* inconsistent */
X	dstDepth > MaxAmDepth )			/* too many for this routine*/
X      return(CLIENT_ERROR);
X
X   planeCnt = dstDepth + (mask == NULL ? 0 : 1);
X
X   /* Copy the ptrs to bit & mask planes into local array "planes" */
X   for (iPlane = 0; iPlane < dstDepth; iPlane++)
X      planes[iPlane] = (BYTE *)bitmap->Planes[iPlane];
X   if (mask != NULL)
X      planes[dstDepth] = mask;
X
X   /* Write out a BODY chunk header */
X   iffp = PutCkHdr(context, ID_BODY, szNotYetKnown);
X   CheckIFFP();
X
X   /* Write out the BODY contents */
X   for (iRow = bmHdr->h; iRow > 0; iRow--)  {
X      for (iPlane = 0; iPlane < planeCnt; iPlane++)  {
X
X         /* Write next row.*/
X         if (compression == cmpNone) {
X            iffp = IFFWriteBytes(context, planes[iPlane], rowBytes);
X            planes[iPlane] += rowBytes;
X            }
X
X         /* Compress and write next row.*/
X         else {
X            buf = buffer;
X            packedRowBytes = PackRow(&planes[iPlane], &buf, rowBytes);
X            iffp = IFFWriteBytes(context, buffer, packedRowBytes);
X            }
X
X         CheckIFFP();
X         }
X      }
X
X   /* Finish the chunk */
X   iffp = PutCkEnd(context);
X   return(iffp);
X   }
SHAR_EOF
echo "extracting lens.c"
sed 's/^X//' << \SHAR_EOF > lens.c
X/*
X * MandelVroom 2.0
X *
X * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
X *
X * All rights reserved.
X *
X * Permission is hereby granted to distribute this program's source
X * executable, and documentation for non-comercial purposes, so long as the
X * copyright notices are not removed from the sources, executable or
X * documentation.  This program may not be distributed for a profit without
X * the express written consent of the author Kevin L. Clague.
X *
X * This program is not in the public domain.
X *
X * Fred Fish is expressly granted permission to distribute this program's
X * source and executable as part of the "Fred Fish freely redistributable
X * Amiga software library."
X *
X * Permission is expressly granted for this program and it's source to be
X * distributed as part of the Amicus Amiga software disks, and the
X * First Amiga User Group's Hot Mix disks.
X *
X * contents: this file contains the code that implements the lens effect
X * (pixelized expansion) when zooming in.
X *
X */
X
X#include "mandp.h"
X
X/* Lens algorithm:
X *
X *   Initialization - Create RastPort and BitMap as a work area
X *
X *   Lens Expansion -
X *     Phase 1 (Horizontal Expansion)
X *       1.  Working from left side of NavBox to Right
X *       2.  expand one verticle line from NavBox into temp rastport.
X *       3.  duplicate the line in temp rastport to expansion width
X *       4.  Continue for enough lines to fill the temp rastport
X *
X *     Phase 2 (Verticle Expansion)
X *       1.  Working from top of temp rastport to bottom
X *       2.  expand one horizontal line from temp rastport into Lens
X *           window rastport.
X *       3.  duplicate the line in Lens window rastport to expansion height
X *       4.  Continue for enough lines in the temp rastport
X */
X
X/* These structures are used to hold horizontally expanded view of lenz
X   expansion */
X
Xstatic struct RastPort LensRp;
Xstatic struct BitMap   LensBitMap;
Xstatic LONG   LensWidth, LensHeight;
X
XUBYTE LensOK;
XUBYTE LensOn = 1;
X
X#ifdef TEMPWINDOW
X#define SAFEBLIT
X
Xstatic struct NewWindow NewTemp = {
X   0,12,                     /* start position           */
X   80,80,                    /* width, height            */
X   (UBYTE) 0, (UBYTE) NORMALPEN,
X   MOUSEBUTTONS,             /* IDCMP flags              */
X                             /* MandWind flags           */
X   WINDOWDRAG | NOCAREREFRESH | SMART_REFRESH,
X   (struct Gadget *) NULL,   /* first gadget             */
X   (struct Image *) NULL,    /* user checkmark           */
X   (UBYTE *) NULL,           /* Title                    */
X   (struct Screen *) NULL,   /* pointer to screen        */
X   (struct BitMap *) NULL,   /* pointer to superbitmap   */
X   20,20,-1,-1,              /* sizing                   */
X   CUSTOMSCREEN              /* type of screen           */
X   };
X
Xstatic struct Window *TempWind;
X#endif
X
XAllocLensTemp( Pict )
X  register struct Picture *Pict;
X{
X  LONG Plane;
X  PLANEPTR t;
X
X  extern struct MenuItem LensSub[];
X
X  static LensInited;
X
X  extern struct NewScreen NewScreen;
X
X  if ( !LensOn )
X    return;
X
X  if (LensOK == 1)
X    return;
X
X  if (Pict == Pict->DrawPict)
X    return;
X
X#ifdef TEMPWINDOW
X
X  NewTemp.Width    = Pict->Window->Width;
X  NewTemp.Height   = Pict->DrawPict->Window->Height;
X  NewTemp.LeftEdge = NewScreen.Width - NewTemp.Width-2;
X  NewTemp.TopEdge  = 0;
X  NewTemp.Screen   = screen;
X  TempWind         = OpenWindow( &NewTemp );
X/*WindowToBack( TempWind );*/
X  LensOK = TempWind != NULL;
X
X#else
X
X  if ( ! LensInited ) {
X
X    InitRastPort( &LensRp );
X    LensRp.BitMap = &LensBitMap;
X
X    LensInited = 1;
X  }
X
X  LensWidth  = Pict->Window->Width;
X  LensHeight = Pict->DrawPict->Window->Height;
X
X  InitBitMap( &LensBitMap, (long) NewScreen.Depth, LensWidth, LensHeight);
X
X  for (Plane = 0; Plane < NewScreen.Depth; Plane++) {
X
X    t = (PLANEPTR) AllocRaster(LensWidth,LensHeight);
X    LensBitMap.Planes[Plane] = (PLANEPTR) t;
X
X    if (t == NULL) {
X      FreeLensTemp( );
X      return;
X    }
X  }
X  LensOK = 1;
X
X#endif
X}
X
XFreeLensTemp( )
X{
X  LONG Plane;
X
X  if (LensOK) {
X
X#ifdef TEMPWINDOW
X    CloseWindow( TempWind );
X#else
X
X    for (Plane = 0; Plane < LensBitMap.Depth; Plane++) {
X
X      if (LensBitMap.Planes[Plane]) {
X
X        FreeRaster( (char *) LensBitMap.Planes[Plane],
X                    LensWidth, LensHeight);
X        LensBitMap.Planes[Plane] = NULL;
X      }
X    }
X#endif
X    LensOK = 0;
X  }
X}
X
X#ifdef SAFEBLIT
X
XSafeClipBlit( src_Wind, src_x, src_y,
X              dst_Wind, dst_x, dst_y,
X              width, height, min_terms,
X              line_no )
X
X  struct Window *src_Wind, *dst_Wind;
X  LONG   src_x, src_y, dst_x, dst_y, width, height, min_terms;
X  LONG   line_no;
X{
X
X  if (src_x < 0 || src_x > src_Wind->Width) {
X    printf("Line %d Bad blit src_x %d Width %d\n",
X            line_no,src_x,src_Wind->Width);
X    return;
X  }
X
X  if (src_y < 0 || src_y > src_Wind->Height) {
X    printf("Line %d Bad blit src_y %d Height %d\n",
X            line_no, src_y,src_Wind->Height);
X    return;
X  }
X
X  if (width < 1 || width > src_Wind->Width) {
X    printf("Line %d Bad blit width %d\n",line_no, width);
X    return;
X  }
X
X  if (src_x + width > src_Wind->Width) {
X    printf("Line %d Blit outside %d Width %d \n",
X            line_no,src_x+width,src_Wind->Width);
X    return;
X  }
X
X  if (height < 1 || height > src_Wind->Height) {
X    printf("Line %d Bad blit height %d\n",line_no,height);
X    return;
X  }
X
X  if (src_y + height > src_Wind->Height) {
X    printf("Line %d Blit outside %d Height %d \n",
X            line_no,src_y+height,src_Wind->Height);
X    return;
X  }
X
X  ClipBlit( src_Wind->RPort, src_x, src_y,
X            dst_Wind->RPort, dst_x, dst_y,
X            width, height, min_terms);
X}
X#endif
X
X  /* Do Lens effect using temporary rastort, ClipBlit() with exponential
X     expansion */
X
XLens( Pict )
X  register struct Picture *Pict;
X{
X  struct Picture *DrawPict;
X
X  LONG ExpFactor;
X  LONG MaxHeight,MaxWidth;
X  LONG SrcPos, SrcMax;
X
X  LONG DstPos, DstMax;
X
X  LONG EOL;
X
X  LONG NextPos, AccPos;
X  LONG          AccExp;
X
X  LONG FirstSrc,FirstDst,NumOnes;
X
X  static LONG OldLeft,OldTop,OldExp;
X  LONG Top,Left,Bot,t;
X
X  struct Window   *src_Wind,*dst_Wind;
X  struct RastPort *src_Rp,  *dst_Rp,  *tmp_Rp;
X
X  DrawPict = Pict->DrawPict;
X
X  if (DrawPict == NULL)
X    return;
X
X  CloseZoomBoxList( Pict );
X
X  src_Wind = DrawPict->Window;
X  dst_Wind = Pict->Window;
X
X  src_Rp = src_Wind->RPort;
X  dst_Rp = dst_Wind->RPort;
X
X  if (src_Rp == dst_Rp) return;
X
X#ifdef TEMPWINDOW
X  tmp_Rp = TempWind->RPort;
X#else
X  tmp_Rp = &LensRp;
X#endif
X
X  if ( !LensOK )
X    return;
X
X#ifndef TEMPWINDOW
X  SetRast( tmp_Rp, (long) NORMALPEN );
X#endif
X
X  /* turn the Nav Box upside down, so the bit map is not inverted */
X
X  Top   = Pict->NavTop;
X  Bot   = Pict->NavBot;
X  Left  = Pict->NavLeft;
X
X  if (Bot < Top) {
X    t            = Bot;
X    Bot = Top;
X    Top = t;
X  }
X  if (Pict->NavRight < Left) {
X    Left  = Pict->NavRight;
X  }
X
X  /* Do Horizontal Expansion into a temporary bitmap */
X  /* src = DrawPict */
X  /* dst = Pict */
X
X  MaxHeight = Bot - Top + 1;
X
X  if (MaxHeight == 0)
X    return;
X
X  DstPos = 0;
X
X  DstMax = dst_Wind->Width - Pict->LeftMarg - Pict->RightMarg;
X  SrcMax = src_Wind->Width - DrawPict->RightMarg;
X
X#define SHIFT_FACTOR 8
X
X  AccExp = ((dst_Wind->Height - Pict->TopMarg - Pict->BotMarg)
X            << SHIFT_FACTOR) / MaxHeight;
X
X  if (OldLeft == Left && OldTop == Top && OldExp == AccExp)
X    return;
X
X  Pict->Flags |= LENS_DISPLAYED;
X
X  OldLeft = Left;
X  OldTop  = Top;
X  OldExp  = AccExp;
X
X  AccPos = DstPos << SHIFT_FACTOR;
X
X  EOL = 0;
X  NumOnes = 0;
X
X  for (SrcPos = Left; SrcPos < SrcMax && ! EOL; SrcPos++) {
X
X    AccPos += AccExp;
X    NextPos = AccPos >> SHIFT_FACTOR;
X
X    ExpFactor = NextPos - DstPos;
X
X    /* Accumulate adjacent single line blits */
X
X    if (ExpFactor == 1) {
X      if (NumOnes == 0) {
X        FirstSrc = SrcPos;
X        FirstDst = DstPos;
X      }
X      NumOnes++;
X    } else {
X
X      /* Copy accumulated adjcent single line copies */
X
X      if (NumOnes > 0) {
X
X#ifndef SAFEBLIT
X        ClipBlit( src_Rp,  FirstSrc,  (long) Top,
X                  tmp_Rp,  FirstDst,  0,
X                  NumOnes, MaxHeight, (long) 0xc0 );
X#else
X        SafeClipBlit( src_Wind, FirstSrc,  Top,
X                      TempWind, FirstDst,  0,
X                      NumOnes,  MaxHeight, 0xc0, __LINE__ );
X#endif
X        NumOnes = 0;
X      }
X
X      if (ExpFactor > 1) {
X
X        register LONG WrkPos, WrkOff, Last, DstExp;
X
X        /* Expand Pattern exponentially */
X
X        WrkPos = DstPos + 1;
X        WrkOff = 1;
X        Last = 0;
X        DstExp = 1;
X
X        /* Copy First line */
X
X#ifndef SAFEBLIT
X        ClipBlit( src_Rp, SrcPos,    (long) Top,
X                  tmp_Rp, DstPos,    0,
X                  (long) 1, MaxHeight, (long) 0xc0 );
X#else
X        SafeClipBlit( src_Wind,  SrcPos,  Top,
X                      TempWind,  DstPos,  0,
X                      1,         MaxHeight, 0xc0, __LINE__);
X#endif
X
X        /* Now expand it exponentially */
X
X        do {
X
X          if ( WrkOff + DstExp >= ExpFactor ) {
X            Last = 1;
X            DstExp = ExpFactor - WrkOff;
X          }
X
X          if ( WrkPos + DstExp >= DstMax ) {
X            Last = 1;
X            EOL = 1;
X            DstExp = DstMax - WrkPos;
X          }
X
X          if (DstExp) {
X#ifndef SAFEBLIT
X            ClipBlit( tmp_Rp, DstPos,    0,
X                      tmp_Rp, WrkPos,    0,
X                      DstExp, MaxHeight, (long) 0xc0 );
X#else
X            SafeClipBlit( TempWind,  DstPos,  0,
X                          TempWind,  WrkPos,  0,
X                          DstExp,    MaxHeight, 0xc0, __LINE__);
X#endif
X            WrkPos += DstExp;
X            WrkOff += DstExp;
X
X            DstExp <<= 1;
X          }
X        } while ( ! Last );
X      }
X    }
X    if ((DstPos = NextPos) >= DstMax) EOL = 1;
X  }
X
X  if (NumOnes > 0) {
X
X#ifndef SAFEBLIT
X    ClipBlit( src_Rp,  FirstSrc,  (long) Top,
X              tmp_Rp,  FirstDst,  0,
X              NumOnes, MaxHeight, (long) 0xc0 );
X#else
X    SafeClipBlit( src_Wind,  FirstSrc,  Top,
X                  TempWind,  FirstDst,  0,
X                  NumOnes,   MaxHeight, 0xc0, __LINE__);
X#endif
X  }
X  NumOnes = 0;
X
X  ZoomBox( Pict );
X
X  /* src = DrawPict */
X  /* dst = Pict */
X
X  /* Do Verticle Expansion */
X
X  MaxWidth = dst_Wind->Width - Pict->LeftMarg - Pict->RightMarg;
X
X  DstPos = Pict->TopMarg;
X  DstMax = dst_Wind->Height - Pict->BotMarg;
X  SrcMax = src_Wind->Height;
X
X  EOL = 0;
X
X  AccPos = DstPos << SHIFT_FACTOR;
X
X  for (SrcPos = 0; SrcPos < SrcMax && !EOL; SrcPos++) {
X
X    AccPos += AccExp;
X    NextPos = AccPos >> SHIFT_FACTOR;
X
X    ExpFactor = NextPos - DstPos;
X
X    /* Accumulate adjacent single line blits */
X
X    if (ExpFactor == 1) {
X      if (NumOnes == 0) {
X        FirstSrc = SrcPos;
X        FirstDst = DstPos;
X      }
X      NumOnes++;
X    } else {
X
X      /* Copy accumulated adjacent single line copies */
X
X      if (NumOnes > 0) {
X
X#ifndef SAFEBLIT
X        ClipBlit( tmp_Rp,   0,  FirstSrc,
X                  dst_Rp,   Pict->LeftMarg,  FirstDst,
X                  MaxWidth, NumOnes,   (long) 0xc0 );
X#else
X        SafeClipBlit( TempWind,  0,  FirstSrc,
X                      dst_Wind,  Pict->LeftMarg,  FirstDst,
X                      MaxWidth,  NumOnes,  0xc0, __LINE__);
X#endif
X        NumOnes = 0;
X      }
X
X      if ( ExpFactor > 1 ) {
X
X        register LONG WrkPos, WrkOff, Last, DstExp;
X
X        /* Expand Pattern exponentially */
X
X        WrkPos = DstPos + 1;
X        WrkOff = 1;
X        Last = 0;
X        DstExp = 1;
X
X        /* Copy First Horizontal Line */
X
X#ifndef SAFEBLIT
X        ClipBlit( tmp_Rp,   0, SrcPos,
X                  dst_Rp,   Pict->LeftMarg, DstPos,
X                  MaxWidth, (long) 1, (long) 0xc0 );
X#else
X        SafeClipBlit( TempWind, 0, SrcPos,
X                      dst_Wind, Pict->LeftMarg, DstPos,
X                      MaxWidth, 1,        0xc0, __LINE__ );
X#endif
X        do {
X
X          if ( WrkOff + DstExp >= ExpFactor ) {
X            Last = 1;
X            DstExp = ExpFactor - WrkOff;
X          }
X
X          if ( WrkPos + DstExp >= DstMax ) {
X            Last = 1;
X            EOL = 1;
X            DstExp = DstMax - WrkPos;
X          }
X          if (DstExp) {
X#ifndef SAFEBLIT
X            ClipBlit( dst_Rp,   Pict->LeftMarg, DstPos,
X                      dst_Rp,   Pict->LeftMarg, WrkPos,
X                      MaxWidth, DstExp,   (long) 0xc0 );
X#else
X            SafeClipBlit( dst_Wind, Pict->LeftMarg, DstPos,
X                          dst_Wind, Pict->LeftMarg, WrkPos,
X                          MaxWidth, DstExp,   0xc0, __LINE__ );
X#endif
X            WrkPos += DstExp;
X            WrkOff += DstExp;
X
X            DstExp <<= 1;
X          }
X        } while ( ! Last );
X      }
X    }
X    if ((DstPos = NextPos) >= DstMax) EOL = 1;
X  }
X
X  /* Copy accumulated adjacent single line copies */
X
X  if (NumOnes > 0) {
X#ifndef SAFEBLIT
X    ClipBlit( tmp_Rp,  0,  FirstSrc,
X              dst_Rp,  Pict->LeftMarg,  FirstDst,
X              MaxWidth,NumOnes,   (long) 0xc0 );
X#else
X    SafeClipBlit( TempWind, 0,  FirstSrc,
X                  dst_Wind, Pict->LeftMarg,  FirstDst,
X                  MaxWidth, NumOnes,   0xc0, __LINE__ );
X#endif
X  }
X
X  ZoomBox( Pict );
X}
X
XCloseZoomBoxList( Pict )
X  register struct Picture *Pict;
X{
X  register struct Node    *zNode;
X  register struct Picture *ClosePict;
X           struct Picture *PictAddr();
X
X  zNode = Pict->zList.lh_Head;
X
X  while ( zNode->ln_Succ ) {
X
X    ClosePict = PictAddr( zNode );
X
X    if (Pict != ClosePict) {
X      CloseZoomBox(ClosePict);
X    }
X
X    zNode = zNode->ln_Succ;
X  }
X}
X
X
X
SHAR_EOF
echo "extracting lists.c"
sed 's/^X//' << \SHAR_EOF > lists.c
X/*
X * MandelVroom 2.0
X *
X * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
X *
X * All rights reserved.
X *
X * Permission is hereby granted to distribute this program's source
X * executable, and documentation for non-comercial purposes, so long as the
X * copyright notices are not removed from the sources, executable or
X * documentation.  This program may not be distributed for a profit without
X * the express written consent of the author Kevin L. Clague.
X *
X * This program is not in the public domain.
X *
X * Fred Fish is expressly granted permission to distribute this program's
X * source and executable as part of the "Fred Fish freely redistributable
X * Amiga software library."
X *
X * Permission is expressly granted for this program and it's source to be
X * distributed as part of the Amicus Amiga software disks, and the
X * First Amiga User Group's Hot Mix disks.
X *
X * contents: this file contains functions that create, delete, and performs
X * operations on lists of projects.
X */
X
X#include "mandp.h"
X
Xextern LONG MainPri, TaskPri;
X
X#define LT_PICTLIST 0xff
X#define LT_ZOOMLIST 0xfe
X
Xstruct List pList = {
X  (struct Node *) &pList.lh_Tail,
X  (struct Node *) NULL,
X  (struct Node *) &pList.lh_Head,
X  LT_PICTLIST
X};
X
Xunion PictNode {
X  struct Node    *Node;
X  struct Picture *Pict;
X};
X
Xstruct Picture *
XNewPict( Type )
X  UBYTE Type;
X{
X  register union PictNode ln;
X  register struct List *Head;
X
X  extern struct NewWindow NewMand;
X
X  ln.Pict = (struct Picture *)
X            safeAllocMem( (long) sizeof(struct Picture), (long) MEMF_CLEAR);
X
X  if (ln.Pict == NULL)
X    return( ln.Pict );
X
X  ln.Node->ln_Type = Type;
X  ln.Node->ln_Name = ln.Pict->Title;
X
X#if 0
X  strcpy( ln.Pict->Title, "* ");
X#endif
X
X  if ( Type == MANDPICT ) {
X
X    InitMand( ln.Pict );
X  }
X
X  ln.Pict->NewWind = &NewMand;
X
X  ln.Pict->TopEdge = 12;
X
X  if ( pList.lh_Head->ln_Succ == NULL ) {
X
X    ToggleEnableds();
X  }
X
X  AddHead( &pList, ln.Node );
X
X  ln.Pict->gSigBit = -1;
X
X  Head = &ln.Pict->zList;
X
X  Head->lh_Head     = (struct Node *) &Head->lh_Tail;
X  Head->lh_TailPred = (struct Node *) &Head->lh_Head;
X  Head->lh_Type     = LT_ZOOMLIST;
X
X  ln.Pict->WindowSemi.ss_Link.ln_Name = NULL;
X  ln.Pict->WindowSemi.ss_Link.ln_Pri  = 0;
X
X  AddSemaphore( &ln.Pict->WindowSemi );
X
X  return( ln.Pict );
X}
X
X/* Dale Luck's Add Semaphore code */
X
XmyAddSemaphore( ss )
X  struct SignalSempahore *ss;
X{
X  extern struct ExecBase *SysBase;
X
X  InitSemaphore(ss);
X  Forbid();
X  Enqueue(&SysBase->SemaphoreList, ss);
X  Permit();
X}
X
X
XDisposePict( NPict )
X  register struct Picture *NPict;
X{
X  Remove( &NPict->pNode );
X
X  RemSemaphore( &NPict->WindowSemi );
X
X  if (NPict == CurPict)
X    CurPict = NULL;
X
X  FreeMem( (char *) NPict, (long) sizeof( struct Picture ) );
X
X  if ( pList.lh_Head->ln_Succ == NULL ) {
X
X    ToggleEnableds();
X  }
X}
X
XGetCurPict( )
X{
X  register struct Picture *NewPict;
X
X  if ( pList.lh_Head->ln_Succ ) {
X
X    NewPict = (struct Picture *) pList.lh_Head;
X
X    MakeCurProj( NewPict );
X
X  } else {
X
X    CurPict = NULL;
X  }
X}
X
XThrowPicts()
X{
X  register union PictNode ln;
X  register union PictNode lnt;
X
X  ln.Node = pList.lh_Head;
X
X  while ( ln.Node->ln_Succ ) {
X
X    lnt.Node = ln.Node;
X    ln.Node = ln.Node->ln_Succ;
X    ThrowPict( lnt.Pict );
X  }
X}
X
XThrowPict( Pict )
X  register struct Picture *Pict;
X{
X  ThrowTask( Pict );
X
X  KillReColor( Pict );
X
X  FreeCounts( Pict );
X
X  FreeHist( Pict->Hist );
X  Pict->Hist = NULL;
X
X  ClosePicture( Pict );
X  DisposePict( Pict );
X}
X
XReColorPicts()
X{
X  register union PictNode ln;
X
X  ln.Node = pList.lh_Head;
X
X  while ( ln.Node->ln_Succ ) {
X
X    ReColor( ln.Pict );
X    ln.Node = ln.Node->ln_Succ;
X  }
X}
X
XCheckNewScreen( ViewModes )
X  USHORT ViewModes;
X{
X  register union PictNode ln;
X
X  struct NewScreen MaybeScreen;
X  register struct NewScreen *ns;
X
X  ns = &MaybeScreen;
X
X  ns->ViewModes = ViewModes;
X
X  NewScreenSize( ns );
X
X  ln.Node = pList.lh_Head;
X
X  while ( ln.Node->ln_Succ ) {
X
X    if (ln.Pict->Window && ( ln.Pict->Window->Width  > ns->Width  ||
X                             ln.Pict->Window->Height > ns->Height))
X      return( UNSUCCESSFUL );
X
X    ln.Node = ln.Node->ln_Succ;
X  }
X  return( SUCCESSFUL );
X}
X
XReOpenPicts()
X{
X  register union PictNode ln;
X  register union PictNode temp_ln;
X
X  extern struct NewWindow NewMand;
X
X  ln.Node = pList.lh_Head;
X
X  while ( ln.Node->ln_Succ ) {
X
X    ReleaseSemaphore( &ln.Pict->WindowSemi );
X
X    if ( OpenPicture( ln.Pict ) != 0 ) {
X
X      temp_ln.Node = ln.Node;
X
X      ln.Node = ln.Node->ln_Succ;
X
X      ThrowPict( temp_ln.Pict );
X
X    } else {
X      if ( ln.Pict->Counts && ! (ln.Pict->Flags & NO_RAM_GENERATE) ) {
X        ReColor( ln.Pict );
X      }
X
X      AwakenChild( ln.Pict );
X
X      if ( ln.Pict->GenState == GENPENDSTATE ) {
X        Generate( ln.Pict );
X      }
X
X      ln.Node = ln.Node->ln_Succ;
X    }
X  }
X  ServiceTasks();
X}
X
XClosePicts()
X{
X  register union PictNode ln;
X
X  ln.Node = pList.lh_Head;
X
X  while ( ln.Node->ln_Succ ) {
X
X    if ( ln.Pict->cTask ) {
X
X      KillReColor( ln.Pict );
X    }
X
X
X
X    ObtainSemaphore( &ln.Pict->WindowSemi );
X
X    ClosePicture( ln.Pict );
X
X    ln.Node = ln.Node->ln_Succ;
X  }
X}
X
XServiceTasks()
X{
X  register union PictNode ln;
X
X  ln.Node = pList.lh_Head;
X
X  while ( ln.Node->ln_Succ ) {
X
X    switch( ln.Pict->GenChildState ) {
X
X      case NOSIGSTATE:
X      case GENCOMPLETE:
X
X           KillDoneChild( ln.Pict );
X           SetGenGad( ln.Pict );
X           ln.Pict->gTask = NULL;
X           PrintTime( ln.Pict );
X           break;
X    }
X
X    if ( ln.Pict->ColorChildState == RECOLORCOMPLETE ) {
X      KillReColor( ln.Pict );
X      AwakenChild( ln.Pict );
X    }
X
X    ln.Node = ln.Node->ln_Succ;
X  }
X}
X
XPrintTime( Pict )
X register struct Picture *Pict;
X{
X LONG t2[3];
X LONG *t1,t;
X
X if (FromWB)
X   return;
X
X return;
X
X DateStamp(t2);
X
X t1 = Pict->TimeStamp;
X
X t = ((t2[0]-t1[0]) * 1440 + t2[1] - t1[1]) * 3000 + t2[2] - t1[2] ;
X
X printf("time is %ld.%ld seconds\n",t/50,2*(t%50));
X}
X
XReColorLine( Pict )
X  register struct Picture *Pict;
X{
X  register struct RastPort *Rp;
X  register UBYTE *ColorXLate;
X  register SHORT *LinePtr;
X  register LONG   Top;
X  register LONG   Width;
X  register struct Window   *Window;
X
X  LONG i;
X
X  (void) SetTaskPri( Pict->gTask, MainPri );
X
X  ObtainSemaphore( &Pict->WindowSemi );
X
X  Top     = Pict->CurLine;
X  Width   = Pict->CountX;
X  Window  = Pict->Window;
X
X  if ( Window ) {
X
X    ColorXLate = Pict->ClrXlate;
X
X    if ( Pict->Flags & NO_RAM_GENERATE ) {
X
X      LinePtr = Pict->Counts;
X    } else {
X      LinePtr = Pict->Counts + Top * Width;
X    }
X
X    Top   += Pict->TopMarg;
X    Width += Pict->LeftMarg;
X
X    Rp = Window->RPort;
X
X    for (i = Pict->LeftMarg; i < Width; i++) {
X
X      SetAPen( Rp, (long) *(ColorXLate + *LinePtr++) );
X
X      if ( i < Window->Width - Pict->RightMarg )
X        WritePixel( Rp, i, Top );
X    }
X  }
X
X  ReleaseSemaphore( &Pict->WindowSemi );
X
X  (void) SetTaskPri( Pict->gTask, TaskPri );
X}
SHAR_EOF
echo "extracting main.c"
sed 's/^X//' << \SHAR_EOF > main.c
X/*
X * MandelVroom 2.0
X *
X * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
X *
X * All rights reserved.
X *
X * Permission is hereby granted to distribute this program's source
X * executable, and documentation for non-comercial purposes, so long as the
X * copyright notices are not removed from the sources, executable or
X * documentation.  This program may not be distributed for a profit without
X * the express written consent of the author Kevin L. Clague.
X *
X * This program is not in the public domain.
X *
X * Fred Fish is expressly granted permission to distribute this program's
X * source and executable as part of the "Fred Fish freely redistributable
X * Amiga software library."
X *
X * Permission is expressly granted for this program and it's source to be
X * distributed as part of the Amicus Amiga software disks, and the
X * First Amiga User Group's Hot Mix disks.
X *
X * contents: this file contains main(), Workbench support code, and
X * miscellaneous funtions.
X */
X
X#define COLORCYCLE
X
X#include "mandp.h"
X
Xextern struct NewScreen NewScreen;
Xextern struct Picture *ZoomedPict;
X
Xextern UBYTE ContOpen, PaletteOpen, CycleOpen, HistOpen;
X
Xstruct Window  *CurWind;
Xstruct Picture *CurPict;
X
Xstruct Window *ClosedWind;
X
XUBYTE  QuitScreen;
X
XSHORT MouseX,MouseY;
X
XLONG mSigBit, mSigMask; /* Finished Signal */
Xstruct Task *mTask;
X
Xextern int Num_vp_Colors;
X
Xextern LONG MainPri, TaskPri;
X
Xextern struct WBStartup *WBenchMsg;
Xstruct IntuiMessage *ParseMsg;
X
XBYTE FromWB;
X
X/*
X * Do it all
X */
Xmain (argc, argv)
X  int   argc;
X  char *argv[];
X {
X  struct WBArg     *arg;
X  char  *LoadFile;
X  char  *NameFromLock();
X
X  struct Process *Process;
X
X  int i, rc;
X
X  AllocArrows();
X
X  ToggleEnableds();
X
X  Menu[CALCULATEMENU].Flags ^= MENUENABLED;
X
X  MainPri = FindTask(0)->tc_Node.ln_Pri;
X  TaskPri = MainPri - 1;
X
X  FromWB = argc == 0;
X
X  Process = (struct Process *) FindTask(0);
X
X  /* Set up Mandelbrot Pict */
X
X  if (OpenLibs() == 0 && OpenTasks() == 0 && OpenDisp() == 0) {
X
X    DefaultColors();
X
X    if (FromWB) {
X      argc = WBenchMsg->sm_NumArgs;
X      arg = WBenchMsg->sm_ArgList;
X    }
X
X    if (argc == 1) {
X
X      if (SetPreset( 0 ) == UNSUCCESSFUL)
X        AndDie( "Can't open preset 0. No RAM\n" );
X
X    } else {
X
X      rc = SUCCESSFUL;
X
X      /* get all the projects indicated */
X
X      for (i = 1; i < argc && rc == SUCCESSFUL; i++) {
X
X        if (FromWB) {
X
X          arg++;
X          rc = LoadPicture( NameFromLock( (struct Lock *) arg->wa_Lock,
X                                           arg->wa_Name ) );
X        } else {
X
X          rc = LoadPicture( NameFromLock( (struct Lock *)
X                                           Process->pr_CurrentDir), argv[i]);
X
X        }
X
X        if (rc == UNSUCCESSFUL) {
X
X          DispErrMsg("Failure opening project",0);
X        } else {
X
X          if (CurPict->Flags & NO_RAM_GENERATE)
X            rc = UNSUCCESSFUL;
X        }
X      }
X    }
X
X    DoBrot();
X  }
X
X#ifdef CHECK_TASK_STACK
X  PrintStack();
X#endif
X
X  ThrowPicts();
X
X  CloseTasks();
X  CloseDisp();
X  CloseLibs();
X
X  FreeArrows();
X
X#ifdef MEM_DEBUG
X  TERMINATE();
X#endif
X}
X
Xchar *
XNameFromLock(Lock,WBName)
X  struct Lock *Lock;
X  char  *WBName;
X{
X  struct FileInfoBlock *fib;
X  struct Lock *lock,*newlock;
X
X  static char cwd[255];
X
X  int i,len;
X  char *name;
X
X  i = 255;
X  cwd[255] = '\0';
X
X  len = strlen( WBName );
X  i -= len;
X  movmem(WBName, cwd + i, (unsigned) len);
X
X  fib = (struct FileInfoBlock *)
X        safeAllocMem( (long) sizeof(struct FileInfoBlock), MEMF_CLEAR );
X
X  if (fib == NULL) {
X    DispErrMsg("Can't Allocate FileInfoBlock",0);
X    return(NULL);
X  }
X
X  lock = Lock;
X
X  while (lock) {                    /* while the lock is good */
X
X    newlock = (struct Lock *) ParentDir(lock);
X    (void) Examine(lock, fib);
X
X    name = fib->fib_FileName;
X
X    if (*name == '\0')
X       name = "ram";
X    len = strlen(name);
X
X    if (newlock) {
X
X      i -= len + 1;
X      movmem(name, cwd + i, (unsigned) len);
X      cwd[i+len] = '/';
X
X    } else {
X
X      i -= len + 1;
X      movmem(name, cwd + i, (unsigned) len);
X      cwd[i + len] = ':';
X    }
X
X    if (lock != Lock)
X      UnLock(lock);
X    lock = newlock;
X  }
X  movmem(cwd + i, cwd, (unsigned) 256 - i);
X
X  FreeMem( (char *) fib, (long) sizeof(struct FileInfoBlock) );
X
X  return( cwd );
X}
X
X/*
X * Wait and process a message
X */
XDoBrot()
X{
X  LONG bSigMask = 1 << BackWind->UserPort->mp_SigBit;
X  LONG rc;
X
X  while (QuitScreen == FALSE) {
X
X    rc = Wait( bSigMask | mSigMask );
X
X    if (rc & bSigMask) DoMsg();
X    if (rc & mSigMask) ServiceTasks();
X  }
X
X  if (CurPict == NULL) {
X    GetCurPict();
X  }
X}
X
X/*
X * if there is a message, process it
X */
XDoMsg()
X{
X  register SHORT  MouseMoved, Activate;
X  register struct IntuiMessage *message;
X  register struct IntuiMessage *CopyMsg;
X  struct IntuiMessage LocalMsg;
X  struct IntuiMessage MouseMsg;
X  struct IntuiMessage ActiveMsg;
X
X  MouseMoved = FALSE;
X  Activate   = FALSE;
X
X  while (message = (struct IntuiMessage *) GetMsg( BackWind->UserPort)) {
X
X    if (message->Class == MOUSEMOVE) {
X      CopyMsg = &MouseMsg;
X      MouseMoved = TRUE;
X    } else
X    if (message->Class == ACTIVEWINDOW) {
X      CopyMsg  = &ActiveMsg;
X      Activate = TRUE;
X    } else {
X      CopyMsg = &LocalMsg;
X    }
X
X    CopyMsg->Class       = message->Class;
X    CopyMsg->Code        = message->Code;
X    CopyMsg->IAddress    = message->IAddress;
X    CopyMsg->MouseX      = message->MouseX;
X    CopyMsg->MouseY      = message->MouseY;
X             MouseX      = message->MouseX;
X             MouseY      = message->MouseY;
X    CopyMsg->IDCMPWindow = message->IDCMPWindow;
X
X    /* got a message */
X
X    ReplyMsg(message);
X
X    if (CopyMsg->Class != MOUSEMOVE && CopyMsg->Class != ACTIVEWINDOW) {
X      if (CopyMsg->Class == MOUSEBUTTONS && MouseMoved) {
X        ProcessCmd( &MouseMsg );
X        MouseMoved = FALSE;
X      }
X      ProcessCmd( CopyMsg );
X    }
X  }
X
X  /* If the Mouse moved during the loop, respond to it now */
X  if ( MouseMoved ) {
X    ProcessCmd( &MouseMsg );
X  }
X
X  /* If there was one or more WindowActive then service the last one */
X  if ( Activate ) {
X    ProcessCmd( &ActiveMsg );
X  }
X} /* DoMsg */
X
XUBYTE ScreenSizeChanged;
X
XMaybeNewScreen()
X{
X  int rc;
X
X  extern USHORT NewViewModes;
X  extern UBYTE  NewDepth;
X
X#define VIEW_MODE_MASK (HIRES|INTERLACE|EXTRA_HALFBRITE)
X
X  if (screen->BitMap.Depth  != NewDepth ||
X      (screen->ViewPort.Modes & VIEW_MODE_MASK) != NewViewModes ||
X       ScreenSizeChanged ) {
X
X    if (CheckNewScreen( NewViewModes ) == SUCCESSFUL) {
X
X      NewScreen.ViewModes = NewViewModes;
X      NewScreen.Depth = NewDepth;
X
X      CloseDisp();
X      (void) OpenDisp();
X      rc = 1;
X    } else {
X      DispErrMsg("Can't change screen. Projects too big",0);
X      rc = 0;
X    }
X    ScreenSizeChanged = 0;
X  } else {
X    rc = 0;
X  }
X  NewViewModes = NewScreen.ViewModes;
X  NewDepth = NewScreen.Depth;
X  return( rc );
X}
X
XActivatePict( Window )
X  register struct Window *Window;
X{
X  SetMouse( Window );
X
X  CurWind = Window;
X
X  DisplayMsg();
X}
X
XCloseWinds( Window )
X  register struct Window *Window;
X{
X  register struct Picture *NewPict;
X  extern UBYTE ContOpen, OrbitOpen, StatsOpen;
X
X  ForceNormPointer();
X
X  if ( Window == ContWind) {
X
X    CloseContWind();
X    ContOpen = 0;
X
X  } else
X  if ( Window == HistWind) {
X
X    CloseHistWind();
X    HistOpen = 0;
X
X  } else
X  if ( Window == PalWind) {
X
X    ClosePalWind();
X    PaletteOpen = 0;
X
X  } else
X  if ( Window == CycWind) {
X
X    CloseCycWind();
X    CycleOpen = 0;
X
X  } else
X  if ( Window == HelpWind) {
X
X    CloseHelpWind(0,NULL);
X
X  } else
X  if ( Window == StatsWind) {
X
X    CloseStatsWind();
X    StatsOpen = 0;
X
X  } else
X  if ( Window == OrbitWind) {
X
X    CloseOrbitWind();
X    OrbitOpen = 0;
X
X  } else {
X
X    if ( NewPict = (struct Picture *) Window->UserData  ) {
X
X      /* Erase the Zoom box if it is open */
X
X      if (NewPict->DrawPict)
X        ZoomOnOff( NewPict );
X
X      /* Undo any pictures that have zoom boxes open in this window */
X
X      CloseZoomedPicts( NewPict );
X
X      ThrowPict( NewPict );
X
X      /* Figure out who is next */
X
X      GetCurPict();
X
X      if (CurPict == NULL) {
X
X        /* Close the contour window */
X
X        CloseContWind();  ContOpen    = 0;
X        ClosePalWind();   PaletteOpen = 0;
X        CloseCycWind();   CycleOpen   = 0;
X        CloseOrbitWind(); OrbitOpen   = 0;
X        CloseHistWind();  HistOpen    = 0;
X        CloseStatsWind(); StatsOpen   = 0;
X      } else {
X
X        LoadRGB4(vp, CurPict->RGBs, (long) Num_vp_Colors);
X        RefreshContours();
X      }
X    }
X  }
X}
X
XToggleEnableds( )
X{
X  extern struct MenuItem ProjectItems[];
X  extern struct MenuItem DisplayItems[];
X  extern struct MenuItem SpecialItems[];
X  extern struct Menu     Menu[];
X
X  ProjectItems[CURITEM].Flags   ^= ITEMENABLED;
X  ProjectItems[SAVEPROJ].Flags  ^= ITEMENABLED;
X  ProjectItems[CLOSEPROJ].Flags ^= ITEMENABLED;
X  ProjectItems[SAVEILBM].Flags  ^= ITEMENABLED;
X
X  DisplayItems[COLORITEM].Flags     ^= ITEMENABLED;
X  DisplayItems[CYCLEITEM].Flags     ^= ITEMENABLED;
X  DisplayItems[CONTOURITEM].Flags   ^= ITEMENABLED;
X  DisplayItems[AUTOCNTRITEM].Flags  ^= ITEMENABLED;
X  DisplayItems[HISTOGRAMITEM].Flags ^= ITEMENABLED;
X  DisplayItems[BORDERITEM].Flags    ^= ITEMENABLED;
X
X  Menu[CALCULATEMENU].Flags ^= MENUENABLED;
X
X  SpecialItems[ORBITITEM].Flags     ^= ITEMENABLED;
X  SpecialItems[ORBITMATHITEM].Flags ^= ITEMENABLED;
X  SpecialItems[MAXORBITEM].Flags    ^= ITEMENABLED;
X}
X
XBorderWindow( Window )
X  register struct Window *Window;
X{
X  register struct RastPort *Rp;
X  register LONG   Bottom, Right;
X  register struct Picture *Pict;
X  register LONG   Max;
X  struct Gadget *Sizing;
X  int      Top;
X
X  extern struct Gadget *OrbitResize;
X
X  Pict = (struct Picture *) Window->UserData;
X
X  if (Pict && (Pict->Flags & BORDERLESS_PROJ))
X    return;
X
X  Bottom = Window->Height - 1;
X  Right  = Window->Width  - 1;
X
X  Rp = Window->RPort;
X
X  if (Pict || Window == OrbitWind) {
X
X    if (Pict) {
X      ObtainSemaphore( &Pict->WindowSemi );
X      Sizing = Pict->SizingGadget;
X    } else {
X      Sizing = OrbitResize;
X    }
X
X    SetAPen( Rp, NORMALPEN );
X
X    Move( Rp, LEFTMARG,                Bottom - 1);
X    Draw( Rp, Right - RIGHTMARG/2 - 1, Bottom - 1);
X
X    if (Pict) {
X      if (Pict->pNode.ln_Type == MANDPICT) {
X        Max = 10+4*14;
X      } else {
X        Max = 10+5*14;
X      }
X    } else {
X      Max = 10+1*14;
X    }
X
X    if ( Bottom > Max ) {
X
X      RectFill( Rp, Right - RIGHTMARG + 1, Max, Right - 1, Bottom - 1);
X      RefreshGadgets( Window->FirstGadget, Window, NULL);
X    }
X
X    /* Bevel the resize gadget edges */
X
X    Max = Right + Sizing->LeftEdge;
X    Top = Bottom+ Sizing->TopEdge-1+YScale;
X
X    SetAPen( Rp, HIGHLIGHTPEN );
X    Move(Rp, Max,            Bottom-2+YScale);
X    Draw(Rp, Max,            Top);
X    Draw(Rp, Right-2+XScale, Top);
X    SetAPen( Rp, SHADOWPEN );
X    Move(Rp, Right-2+XScale, Top+1);
X    Draw(Rp, Right-2+XScale, Bottom-2+YScale);
X    Draw(Rp, Max,            Bottom-2+YScale);
X  }
X
X  SetAPen( Rp, SHADOWPEN );
X  WritePixel( Rp, (long) 0, TOPMARG );
X
X  Move( Rp, (long) 0,  Bottom );
X  Draw( Rp, Right,     Bottom );
X  Draw( Rp, Right,     TOPMARG);
X
X  SetAPen( Rp, HIGHLIGHTPEN );
X
X  Move( Rp, (long) 0,     TOPMARG + 1);
X  Draw( Rp, (long) 0,     Bottom - 1 );
X
X  if (Pict)
X    ReleaseSemaphore( &Pict->WindowSemi );
X}
X
XMakeCurProj( NewPict )
X  register struct Picture *NewPict;
X{
X  extern USHORT NewViewModes;
X  extern UBYTE  NewDepth;
X
X  if ( NewPict ) {
X
X    if ( NewPict != CurPict ) {
X
X      SetWindowActive( NewPict->Window , '*' );
X
X      if (CurPict) {
X        SetWindowActive( CurPict->Window, ' ' );
X      }
X      SetOnString( NewPict->CycleOn );
X
X      KillCycle();
X
X      CurPict = NewPict;
X
X      NewViewModes = NewPict->ViewModes;
X      NewDepth     = NewPict->Depth;
X
X      InitGenSubs();
X      InitBorderSubs();
X      InitOrbitSubs();
X
X      if (MaybeNewScreen() == 0) {
X
X        LoadRGB4(vp, NewPict->RGBs, (long) Num_vp_Colors);
X        SetColorProps(CurPen);
X
X        ReDoHist(CurPict);
X        ShowStats(CurPict);
X        RefreshContours();
X      }
X
X      ModifySpeedPot();
X      SetDirGadget(CurPict);
X
X      if (CurPict->CycleOn) {
X        CreateCycle();
X      }
X    }
X  }
X}
X
SHAR_EOF
echo "extracting makefile"
sed 's/^X//' << \SHAR_EOF > makefile
XSCR = dev:mand/src/screensave
XREQ = dev:mand/src/req
X
XSCROBJS = $(SCR)/SaveILBM.o $(SCR)/packer.o $(SCR)/ilbmw.o $(SCR)/iffw.o
X
XREQOBJS = $(REQ)/getfile.o $(REQ)/safeclose.o
X
XMANDOBJS = safeAddHead.o orbit.o orbitint.o hist.o help.o showhelp.o\
X cycle.o cycleII.o menu.o disp.o gadgets.o nav.o lens.o contour.o cmd.o\
X recolor.o palette.o savemand.o status.o getint.o menu1.o presets.o\
X main.o tasks.o lists.o mandffp.o mand881.o mandIEEE.o mandInt32.o mand.o\
X scroll.o SaveILBM.o packer.o ilbmw.o iffw.o getfile.o safeclose.o
X
XOBJECTS  = $(MANDOBJS)
X
XDEFINES  = -DMULTI
XCCFLAGS  = +c +l -n +IMand.p $(DEFINES)
X
XMandelVroom: mand.p $(OBJECTS)
X             ln $(OBJECTS) -lma32 -lm32 -lc32 -o MandelVroom -g -w
X
Xmand.p:  mandp.h
X         cc mandp.h +c +l -n +Hmand.p $(DEFINES) +fi
X
Xmain.o:  mand.p main.c
X         cc main.c $(CCFLAGS) +fi
X
Xcmd.o:   mand.p cmd.c
X         cc cmd.c $(CCFLAGS) +fi
X
Xmand.o:  mand.p mand.c
X         cc mand.c $(CCFLAGS) +fi
X
XmandIEEE.o:  mand.p mandIEEE.c
X         cc mandIEEE.c $(CCFLAGS) +fi
X
XmandInt32.o:  mand.p mandInt32.c
X         cc mandInt32.c $(CCFLAGS) +fi
X
Xmandffp.o:  mand.p mandffp.c
X         cc mandffp.c $(CCFLAGS) +ff
X
Xmand881.o:  mand.p mand881.c
X         cc mand881.c $(CCFLAGS) +f8
X
Xdisp.o:  mand.p disp.c
X         cc disp.c $(CCFLAGS) +fi
X
Xlists.o:  mand.p lists.c
X         cc lists.c $(CCFLAGS) +fi
X
Xtasks.o:  mand.p tasks.c
X         cc tasks.c $(CCFLAGS) +fi
X
Xgadgets.o:  mand.p gadgets.c
X         cc gadgets.c $(CCFLAGS) +fi
X
Xnav.o:   mand.p nav.c
X         cc nav.c $(CCFLAGS) +fi
X
Xlens.o:  mand.p lens.c
X         cc lens.c $(CCFLAGS) +fi
X
Xcontour.o:  mand.p contour.c
X         cc contour.c $(CCFLAGS) +fi -E200
X
Xhist.o:  mand.p hist.c
X         cc hist.c $(CCFLAGS) +fi
X
Xrecolor.o:  mand.p recolor.c
X         cc recolor.c $(CCFLAGS) +fi
X
Xpalette.o:  mand.p palette.c
X         cc palette.c $(CCFLAGS) +fi
X
Xsavemand.o:     mand.p savemand.c
X         cc savemand.c $(CCFLAGS) +fi
X
Xmenu.o: mand.p menu.c
X         cc menu.c $(CCFLAGS) +fi
X
Xmenu1.o: mand.p menu1.c
X         cc menu1.c $(CCFLAGS) +fi
X
Xpresets.o: mand.p presets.c
X         cc presets.c $(CCFLAGS) +fi
X
Xscrollit.o: mand.p scrollit.c
X         cc scrollit.c $(CCFLAGS) +fi
X
Xstatus.o: mand.p status.c
X         cc status.c $(CCFLAGS) +fi
X
Xgetint.o: mand.p getint.c
X         cc getint.c $(CCFLAGS) +fi
X
Xhelp.o:  mand.p help.c
X         cc help.c $(CCFLAGS) +fi
X
Xshowhelp.o: mand.p showhelp.c
X         cc showhelp.c $(CCFLAGS) +fi
X
Xcycle.o: mand.p cycle.c
X         cc cycle.c $(CCFLAGS) +fi
X
XcycleII.o: mand.p cycleII.c
X         cc cycleII.c $(CCFLAGS) +fi
X
Xorbit.o: mand.p orbit.c
X         cc orbit.c $(CCFLAGS) +fi
X
Xorbitint.o: mand.p orbitint.c
X         cc orbitint.c $(CCFLAGS) +fi
X
Xscroll.o: mand.p scroll.c
X         cc scroll.c $(CCFLAGS) +fi
X
XsafeAddHead.o: mand.p safeAddHead.c
X         cc safeAddHead.c +l -n
X
XSaveILBM.o :    SaveILBM.c
X         cc +l -n SaveILBM.c
X
Xiffw.o :        iffw.c
X         cc +l -n iffw.c
X
Xilbmw.o :       ilbmw.c
X         cc +l -n ilbmw.c
X
Xpacker.o :      packer.c
X         cc +l -n packer.c
X
Xsafeclose.o: safeclose.c
X  cc safeclose.c +l -n -s
X
Xgetfile.o: getfile.c
X  cc getfile.c +l -n -s
X
SHAR_EOF
echo "extracting mand.c"
sed 's/^X//' << \SHAR_EOF > mand.c
X/*
X * MandelVroom 2.0
X *
X * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
X *
X * All rights reserved.
X *
X * Permission is hereby granted to distribute this program's source
X * executable, and documentation for non-comercial purposes, so long as the
X * copyright notices are not removed from the sources, executable or
X * documentation.  This program may not be distributed for a profit without
X * the express written consent of the author Kevin L. Clague.
X *
X * This program is not in the public domain.
X *
X * Fred Fish is expressly granted permission to distribute this program's
X * source and executable as part of the "Fred Fish freely redistributable
X * Amiga software library."
X *
X * Permission is expressly granted for this program and it's source to be
X * distributed as part of the Amicus Amiga software disks, and the
X * First Amiga User Group's Hot Mix disks.
X *
X * contents: this file contains funtions to create, maintain and delete
X * Mandelbrot and Julia projects (including spawning off child generator
X * tasks.)
X */
X
X#include "mandp.h"
X
Xstruct NewWindow NewMand = {
X   0,12,                     /* start position           */
X   80,80,                    /* width, height            */
X
X   (UBYTE) 0, (UBYTE) NORMALPEN,
X   NULL,                     /* IDCMP flags */
X   /* MandWind flags */
X   WINDOWCLOSE | WINDOWDEPTH | WINDOWSIZING | WINDOWDRAG | ACTIVATE |
X   REPORTMOUSE | NOCAREREFRESH | SMART_REFRESH,
X   (struct Gadget *) NULL,   /* first gadget             */
X   (struct Image *) NULL,    /* user checkmark           */
X   (UBYTE *) NULL,           /* Title                    */
X   (struct Screen *) NULL,   /* pointer to screen        */
X   (struct BitMap *) NULL,   /* pointer to superbitmap   */
X   20,20,-1,-1,              /* sizing                   */
X   CUSTOMSCREEN              /* type of screen           */
X   };
X
XLONG TopMarg   = 10;
XLONG BotMarg   =  2;
XLONG LeftMarg  =  2;
XLONG RightMarg;
X
XULONG CalcTime;
X
Xextern LONG TaskPri, MainPri;
Xextern LONG pSigMask;
X
Xextern struct ExecBase *ExecBase;
X
Xstatic struct Picture *GenNPict;
X
X/* Toggle generation of project */
X
XGenerateCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  switch(Msg->Class) {
X
X    case GADGETDOWN:
X         ToggleGen((struct Picture *) Msg->IDCMPWindow->UserData);
X         break;
X
X    case MENUPICK:
X         switch( SUBNUM(Msg->Code) ) {
X           case STARTGEN:
X
X             CurPict->GenState = GENPENDSTATE;
X             Generate( CurPict );
X             break;
X
X           case STOPGEN:
X
X             ThrowTask(CurPict);
X             break;
X
X           case CONTGEN:
X
X             CurPict->GenState = CONTINUESTATE;
X             Generate( CurPict );
X             break;
X         }
X         break;
X  }
X}
X
XToggleGen( Pict )
X  struct Picture *Pict;
X{
X  if ( Pict->gTask ) {
X
X    ThrowTask( Pict );
X  } else {
X
X    Pict->GenState = GENPENDSTATE;
X    Generate( Pict );
X  }
X  SetGenGad( Pict );
X}
X
X/*
X * Generate It
X */
XGenerate( Pict )
X  register struct Picture *Pict;
X{
X
X  register char *t;
X
X  int GenTask();
X
X  extern struct MenuItem LensSub[];
X
X  if ( Pict->gTask ) {
X    return;
X  }
X
X  if (Pict->Flags & SCROLL_HAPPENED) {
X
X    /* create a new counts array with unclipped data in it */
X    /* adjust the real and imaginary upper left */
X
X    ScrollComplex(Pict);
X
X    if (Pict->Counts == NULL)
X      return;
X
X  } else {
X
X    FreeScrollTemp(Pict);
X
X    if (Pict->GenState == CONTINUESTATE ){
X      if ( Pict->CurLine < Pict->CountY ) {
X        if (Pict->Counts == NULL) return;
X      } else {
X        return;
X      }
X    }
X
X    if (Pict->GenState == GENPENDSTATE) {
X
X      InitNewGen( Pict );
X      if (Pict->Counts == NULL) return;
X    }
X  }
X  ResetScrollRects(Pict);
X
X  Pict->GenState = GENERATESTATE;
X
X  if ( Pict->MathMode == INTIIGENERATOR &&
X      (ExecBase->AttnFlags & (1 << AFB_68020)) == 0 ) {
X
X    Pict->MathMode = INTGENERATOR;
X  }
X
X  if ( Pict->MathMode == _81GENERATOR &&
X       (ExecBase->AttnFlags & (1 << AFB_68881)) == 0 ) {
X
X    Pict->MathMode = IEEEGENERATOR;
X  }
X
X  MakeColorXlate( Pict );
X
X  if (Pict->MathMode == 1) {
X
X    if (OpenFFPLibs() != 0)
X      return;
X  }
X
X  /* Spawn off the generator as a task */
X
X  DateStamp( Pict->TimeStamp );
X
X  /* GenNPict is pointer to Picture that task needs to generate */
X
X  GenNPict = Pict;
X
X#define KAY (1024L)
X
X#ifdef MULTI
X  Pict->gTask = CreateTask( Pict->Title+2, MainPri, GenTask, KAY);
X
X  if ( Pict->gTask == NULL ) {
X    DispErrMsg("Could not create task",0);
X  }
X
X  SetGenGad( Pict );
X
X  /* Do this so we are sure child is done with GenNPict */
X
X  Wait( pSigMask );
X
X#else
X  GenTask();
X#endif
X}
X
XInitNewGen( Pict )
X  register struct Picture *Pict;
X{
X
X  if (Pict->Flags & BORDERLESS_PROJ) {
X
X    Pict->LeftMarg  = 0;
X    Pict->RightMarg = 0;
X    Pict->TopMarg   = 0;
X    Pict->BotMarg   = 0;
X  }
X
X  /* figure out new picture size */
X
X  Pict->CountX = Pict->Window->Width-(Pict->LeftMarg+Pict->RightMarg);
X  Pict->CountY = Pict->Window->Height-(Pict->TopMarg+Pict->BotMarg);
X
X  /* free up old counts memory, get new picture size, get new counts memory
X   */
X
X  GetCountsMemory( Pict );
X
X  if (Pict->Counts == NULL) {
X    DispErrMsg("Can't generate. Out of RAM!!",0);
X    return;
X  }
X
X  if (Pict->Flags & NO_RAM_GENERATE ) {
X    DispErrMsg("Can't save counts. Out of RAM!!",0);
X  }
X
X  /* calculate new picture's coordinates from zoom box */
X
X  ZoomIn( Pict );
X  Pict->CurLine = 0;
X
X  /* clear the picture area */
X
X  if (!(Pict->Flags & LENS_DISPLAYED)) {
X
X    SetAPen(  Pict->Window->RPort, NORMALPEN );
X    RectFill( Pict->Window->RPort, Pict->LeftMarg, Pict->TopMarg,
X              Pict->Window->Width - Pict->RightMarg - 1,
X              Pict->Window->Height - Pict->BotMarg - 1);
X  }
X}
X
XGenTask() {
X
X  register struct Picture *Pict;
X
X  int MandelbrotInt32();
X  int MandelbrotInt32II();
X  int MandelbrotIEEE();
X  int MandelbrotFFP();
X
X  int JuliaInt32();
X  int JuliaIEEE();
X  int JuliaFFP();
X
X  LONG SPFieee();
X
X#ifdef MULTI
X  geta4();
X#endif
X
X  Pict = GenNPict;
X
X  /* Signal Parent that we have accessed GenNPict */
X
X  Signal( mTask, pSigMask );
X
X  /* Lower our priority while we generate */
X
X  SetTaskPri( FindTask(0), TaskPri );
X
X  Pict->GenChildState = GENINCOMPLETE;
X
X  if (GetTaskSig( Pict ) == UNSUCCESSFUL) {
X    Pict->GenChildState = NOSIGSTATE;
X
X  } else {
X    Pict->GenChildState = GENINCOMPLETE;
X
X    if ( Pict->pNode.ln_Type == MANDPICT ) {
X
X      switch ( Pict->MathMode ) {
X        case 0:
X             MandelbrotInt32( Pict );
X             break;
X
X        case 2:
X        case 4:
X             MandelbrotIEEE( Pict );
X             break;
X
X        case 3:
X             MandelbrotInt32II( Pict );
X             break;
X
X        case 1: {
X               /*
X                * Constraints for IEEE to FFP conversion
X                *
X                *  1. SPFieee() expects 32 bit IEEE floats
X                *  2. The C language always promotes floats to doubles for
X                *     parameter passing.
X                *  3. doubles are 64 bits wide
X                *
X                * Therefore I must do the following:
X                *
X                *  1. Convert double parameters to float
X                *  2. Take the address of the floats and cast them to *ULONG
X                *  3. Indirect off the ULONG pointers that are pointing to
X                *     32 IEEE format floats (gross eh?) as parameters to FFP
X                *     Mandelbrot function.
X                */
X
X             /* 32 bit IEEE float variables */
X
X             float StartX_float, StartY_float, GapX_float, GapY_float;
X
X             /* convert 64 bit IEEE variables into 32 bit IEEE variables */
X
X             StartX_float = Pict->RealLow;
X             StartY_float = Pict->ImagLow + Pict->CurLine*Pict->RealGap;
X             GapX_float   = Pict->RealGap;
X             GapY_float   = Pict->ImagGap;
X
X             /*
X              * calculate pointers and convert them to pointers to ULONG
X              * so that when we indirect off of these and pass the results
X              * as parameters they are not promoted to doubles.
X              */
X
X
X             MandelbrotFFP( Pict,
X                            *( (ULONG *) &StartX_float ),
X                            *( (ULONG *) &StartY_float ),
X                            *( (ULONG *) &GapX_float   ),
X                            *( (ULONG *) &GapY_float   ));
X             }
X             break;
X      }
X    } else {
X
X      switch ( Pict->MathMode ) {
X
X        case 0:
X        case 3:
X             JuliaInt32( Pict );
X             break;
X
X        case 2:
X        case 4:
X             JuliaIEEE( Pict );
X             break;
X
X        case 1: {
X             /*
X              * Constraints for IEEE to FFP conversion
X              *
X              *  1. SPFieee() expects 32 bit IEEE float
X              *  2. The C language always promotes floats to doubles for
X              *     parameter passing.
X              *  3. doubles are 64 bits wide
X              *
X              * Therefore I must do the following:
X              *
X              *  1. Convert double parameters to float
X              *  2. Take the address of the floats and cast them to *ULONG
X              *  3. Indirect off the ULONG pointers that are pointing to
X              *     32 IEEE format floats (gross eh?) as parameters to FFP
X              *     Julia function.
X              */
X
X             /* 32 bit IEEE float variables */
X
X             float JuliaX_float, JuliaY_float;
X             float StartX, StartY, GapX, GapY;
X
X             /* convert 64 bit IEEE variables into 32 bit IEEE variables */
X
X             JuliaX_float = Pict->Real;
X             JuliaY_float = Pict->Imag;
X             StartX = Pict->RealLow;
X             StartY = Pict->ImagLow;
X             GapX   = Pict->RealGap;
X             GapY   = Pict->ImagGap;
X
X             /*
X              * calculate pointers and convert them to pointers to ULONG
X              * so that when we indirect off of these and pass the results
X              * as parameters they are not promoted to doubles.
X              */
X
X             JuliaFFP( Pict, *( (ULONG *) &JuliaX_float ),
X                             *( (ULONG *) &JuliaY_float ),
X                             *( (ULONG *) &StartX ),
X                             *( (ULONG *) &StartY ),
X                             *( (ULONG *) &GapX ),
X                             *( (ULONG *) &GapY ) );
X             }
X             break;
X      }
X    }
X    Pict->GenChildState = GENCOMPLETE;
X  }
X
X#ifdef MULTI
X
X  /* Indicate that generation has finished for this task */
X
X  Signal( mTask, mSigMask );               /* signal parent as to change */
X
X  while (Pict->GenState != KILLSTATE) {    /* Wait for task to be removed */
X
X    while (Pict->GenState == GENERATESTATE) {   /* spin 'till parent kills us */
X    }
X
X    /* accept any pauses that the parent may send too late */
X
X    if (Pict->GenState == PAUSESTATE) {
X      ChildSignal(Pict);  /* signal back so parent doesn't hang */
X    }
X  }
X
X  /* We've been informed that we will die, so free up resources */
X
X  FreeSignal( Pict->gSigBit );
X  Signal( mTask, pSigMask );               /* signal death O.K. */
X  Wait( 0L );                              /* stop here forever */
X#endif
X}
X
XInitMand( Pict )
X  register struct Picture *Pict;
X{
X
X  Pict->Real   = 0.0;
X  Pict->Imag   = 0.0;
X}
X
XSetWindowActive( Window, Active )
X  register struct Window *Window;
X  char Active;
X{
X  struct Picture *Pict;
X
X  if ( Window ) {
X
X    Pict = (struct Picture *) Window->UserData;
X
X    if ( ! (Pict->Flags & BORDERLESS_PROJ)) {
X      Window->Title[0] = Active;
X      SetWindowTitles( Window, Window->Title, -1 );
X    }
X  }
X}
X
X/*
X * Free up old memory and get memory for new picture
X */
XGetCountsMemory( Pict )
X  register struct Picture *Pict;
X{
X  /* free up old pictures iteration count pile */
X
X  FreeCounts( Pict );
X
X  /* Allocate memory for new picture */
X
X  Pict->CountsSize = Pict->CountX * Pict->CountY * sizeof(SHORT);
X  Pict->Counts     = (SHORT *) safeAllocMem(Pict->CountsSize, MEMF_CLEAR );
X
X  if (Pict->Counts == NULL) {
X
X    Pict->CountsSize = Pict->CountX * sizeof(SHORT);
X    Pict->Counts     = (SHORT *) safeAllocMem(Pict->CountsSize, MEMF_CLEAR);
X
X    if (Pict->Counts != NULL)
X      Pict->Flags     |= NO_RAM_GENERATE;
X
X  } else {
X
X    Pict->Flags     &= ~NO_RAM_GENERATE;
X  }
X}
X
XFreeCounts( Pict )
X  register struct Picture *Pict;
X{
X  if ( Pict->Counts ) {
X
X    FreeMem( Pict->Counts, Pict->CountsSize );
X    Pict->Counts = NULL;
X  }
X}
X
Xstruct Gadget *
XMakePictGads( Type )
X  register int Type;
X{
X  register struct Gadget    *gadget;
X  register struct Gadget *Newgadget;
X  register struct Gadget *Firstgadget;
X  register struct IntuiText  *Intui;
X  register char *str;
X
X  struct Border *Border, *MakeShadow();
X
X  register int i,j,k;
X
X  struct IntuiText *ShadowIntui();
X
X  j = TOPMARG;
X
X  if ( Type == MANDPICT ) {
X    k = 4;
X  } else {
X    k = 5;
X  }
X
X  Firstgadget = NULL;
X
X  for (i = 0; i < k; i++) {
X
X    Newgadget = MakeBool(-15,j, 12,12, 0,(PICTTYPE<<WINDTYPEBITS)+i,NULL);
X
X    if (Newgadget) {
X
X      if ( i == 0 ) {
X
X        Firstgadget = Newgadget;
X
X      } else {
X
X        gadget->NextGadget = Newgadget;
X      }
X
X      Newgadget->Flags      |= GRELRIGHT;
X      Newgadget->Activation |= RIGHTBORDER;
X
X      gadget = Newgadget;
X
X      j += 14;
X
X      switch( i ) {
X        case  0:  str = "C"; break;
X        case  1:  str = "G"; break;
X        case  2:  str = "I"; break;
X        case  3:  str = "O"; break;
X        case  4:  str = "J"; break;
X      }
X
X      Intui = ShadowIntui( str, 3, 3);
X
X      if (Intui == NULL) {
X        FreeGadgets( Firstgadget );
X      }
X
X      gadget->GadgetText = Intui;
X
X#define NUMPATCHCORNERS 5
X
X      Border = MakeShadow( NORMALPEN, NUMPATCHCORNERS );
X
X      if ( Border ) {
X        InitPatch( Border );
X        Border->NextBorder = (struct Border *) gadget->GadgetRender;
X        gadget->GadgetRender = (APTR) Border;
X      }
X
X    } else {
X
X      if (Firstgadget)
X        FreeGadgets( Firstgadget );
X
X      return( NULL );
X    }
X  }
X  return( Firstgadget );
X}
X
XSetGenGad( Pict )
X  register struct Picture *Pict;
X{
X  register struct Window *Window;
X  register struct Gadget *Gadget;
X  register struct IntuiText *Intui;
X  register char c;
X  register int  place;
X
X  if (Pict == NULL)
X    return;
X
X  if (Pict->Flags & BORDERLESS_PROJ)
X    return;
X
X  Window = Pict->Window;
X
X  if (Window) {
X
X    if ( Pict->gTask )
X      c = 'S';
X    else
X      c = 'G';
X
X    Gadget = Pict->Gadgets->NextGadget;
X
X    place = RemoveGadget( Window, Gadget );
X
X    Intui = Gadget->GadgetText;
X
X    Intui = Intui->NextText;
X    Intui->IText[0] = c;
X
X    Intui = Intui->NextText;
X    Intui->IText[0] = c;
X
X    AddGadget( Window, Gadget, place );
X
X    RefreshGadgets( Pict->Gadgets, Window, NULL );
X  }
X}
X
XInitPatch( Border )
X  register struct Border *Border;
X{
X  register SHORT *NewCounts;
X
X  NewCounts = Border->XY;
X
X  *NewCounts++ = 3;       *NewCounts++ = 11;
X  *NewCounts++ = 2;       *NewCounts++ = 11;
X  *NewCounts++ = 2;       *NewCounts++ = 2;
X  *NewCounts++ = 11;      *NewCounts++ = 2;
X  *NewCounts++ = 11;      *NewCounts++ = 3;
X
X} /* InitPatch */
X
X/*
X * Open the Picture window
X */
XOpenPicture( Pict )
X  struct Picture    *Pict;
X{
X  extern struct Window *OpenMyWind();
X
X  register struct Window    *Window;
X  register struct NewWindow *NewWind;
X
X  register LONG width, height;
X  register LONG extrax,extray;
X
X  struct Gadget *gadgets, *MakePictGads();
X
X  if ( Pict->Window == NULL ) {
X
X    width  = Pict->CountX;
X    height = Pict->CountY;
X
X    NewWind = Pict->NewWind;
X
X    if (Pict->Flags & BORDERLESS_PROJ) {
X
X      NewWind->Flags = ACTIVATE | REPORTMOUSE | NOCAREREFRESH |
X                       SMART_REFRESH | BORDERLESS;
X      NewWind->Title = NULL;
X      Pict->Gadgets  = gadgets = NULL;
X
X      if (Pict->LeftEdge+Pict->CountX+LEFTMARG+RIGHTMARG == screen->Width &&
X          Pict->TopEdge +Pict->CountY+TOPMARG+BOTMARG    == screen->Height) {
X
X        Pict->LeftMarg  = LEFTMARG;
X        Pict->RightMarg = RIGHTMARG;
X        Pict->TopMarg   = TOPMARG;
X        Pict->BotMarg   = BOTMARG;
X      } else {
X
X        Pict->LeftMarg  = 0;
X        Pict->RightMarg = 0;
X        Pict->TopMarg   = 0;
X        Pict->BotMarg   = 0;
X      }
X    } else {
X
X      NewWind->Flags = WINDOWCLOSE | WINDOWDEPTH | WINDOWSIZING |
X                       WINDOWDRAG | ACTIVATE | REPORTMOUSE | NOCAREREFRESH |
X                       SMART_REFRESH;
X      NewWind->Title = (UBYTE *) Pict->Title;
X      Pict->Gadgets  = gadgets = MakePictGads( Pict->pNode.ln_Type );
X
X      Pict->LeftMarg  = LEFTMARG;
X      Pict->RightMarg = RIGHTMARG;
X      Pict->TopMarg   = TOPMARG;
X      Pict->BotMarg   = BOTMARG;
X    }
X
X    width  += Pict->LeftMarg + Pict->RightMarg;
X    height += Pict->TopMarg  + Pict->BotMarg;
X
X    extrax = width - screen->Width;
X    extray = height - screen->Height;
X
X    if ( extrax > 0 || extray > 0 ) {
X
X      ThrowTask(  Pict);
X      FreeCounts( Pict);
X      DispErrMsg("Picture too big. Regenerate",0);
X
X      if ( extrax > 0 ) {
X        Pict->CountX -= extrax;
X        width -= extrax;
X      }
X
X      if ( extray > 0 ) {
X        Pict->CountY -= extray;
X        height -= extray;
X      }
X    }
X
X    NewWind->LeftEdge = Pict->LeftEdge;
X    NewWind->TopEdge  = Pict->TopEdge;
X
X    Window = OpenMyWind(NewWind, screen, gadgets, width, height );
X
X    Pict->Window  = Window;
X
X    if (Window == NULL) {
X
X      DispErrMsg("Can't open picture window",0);
X      FreeGadgets( Pict->Gadgets );
X      ThrowPict(Pict);
X      return( -1 );
X
X    } else {
X
X      CurWind = Window;
X      DisplayMsg();
X
X      SetAPen(  Window->RPort, NORMALPEN );
X
X      if (Pict->Flags & BORDERLESS_PROJ) {
X        RectFill( Window->RPort, Pict->LeftMarg, Pict->TopMarg,
X                  NewWind->Width-Pict->RightMarg-1,
X                  NewWind->Height-Pict->BotMarg-1);
X      } else {
X        RectFill( Window->RPort, Pict->LeftMarg, Pict->TopMarg,
X                  NewWind->Width, NewWind->Height);
X      }
X
X      Window->UserData = (BYTE *) Pict;
X
X      MoveResize( Pict->Window, &Pict->SizingGadget );
X      BorderWindow( Window );
X
X      if (Pict->CycleOn) {
X        CreateCycle();
X      }
X    }
X  }
X  SetGenGad( Pict );
X  return( 0 );
X} /* OpenPicture */
X
XMoveResize( Window, RetGadget )
X  register struct Window *Window;
X  register struct Gadget **RetGadget;
X{
X  register struct Gadget *Gadget;
X  register int place;
X
X  Gadget = Window->FirstGadget;
X
X  while ( Gadget && !(Gadget->GadgetType & SIZING)) {
X    Gadget = Gadget->NextGadget;
X  }
X
X  if (Gadget) {
X
X    *RetGadget = Gadget;
X
X    place = RemoveGadget( Window, Gadget );
X
X    if (XScale == 0)
X      Gadget->LeftEdge -= 2;
X
X    if (YScale == 0)
X      Gadget->TopEdge  -= 3;
X    else
X      Gadget->TopEdge  -= 1;
X
X    AddGadget( Window, Gadget, place );
X
X    RefreshGList( Gadget, Window, NULL, 1);
X  }
X}
X
X/*
X * Close the Mandelbrot Window
X */
XClosePicture( Pict )
X  register struct Picture   *Pict;
X{
X  register struct Window    *Window;
X  register struct NewWindow *NewWindow;
X
X  if ( (Window = Pict->Window) != NULL) {
X
X    KillCycle();
X    FreeScrollTemp(Pict);
X
X    Pict->LeftEdge = Window->LeftEdge;
X    Pict->TopEdge = Window->TopEdge;
X
X    CloseMyWind(Window, Pict->Gadgets );
X
X    Pict->Window = NULL;
X    Pict->Gadgets = NULL;
X    Pict->Flags &= ~LENS_DISPLAYED;
X  }
X}
SHAR_EOF
echo "End of archive 4 (of 9)"
# if you want to concatenate archives, remove anything after this line
exit