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

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

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

# 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:
#	safeclose.h
#	saveilbm.c
#	saveilbm.h
#	savemand.c
#	scroll.c
#	showhelp.c
#	standard.h
#	status.c
#	tasks.c
# This is archive 9 of a 9-part kit.
# This archive created: Tue Jun 20 20:45:33 1989
echo "extracting safeclose.h"
sed 's/^X//' << \SHAR_EOF > safeclose.h
X/* CloseWindowSafely()
X*       This module should be used whenever you are sharing an IDCMP
X* message port with more than one window.  Rather than calling CloseWindow(),
X* you should use CloseWindowSafely().  This will keep Intuition from
X* Guru Meditation, and thus is considered a good thing.  You should still
X* use CloseWindow for the very last window you close.
X*       The reason this is needed, is because Intuition will re-claim
X* any outstanding messages for a window when the window is closed. But...
X* it can't take them out of your message port. Thus, you will receive
X* invalid messages and bad things will happen.  Very bad things.
X*       This code is a slightly condensed version of the same routine
X* written by Neil Katin of Amiga for the April '86 Commodore Developers
X* Newsletter, Amiga Mail (tm).
X*/
X
X#ifndef SAFECLOSE
X
X#define SAFECLOSE
X
X
X/* CloseWindowSafely(window), window is pointer to struct Window */
X
Xextern void CloseWindowSafely();
X
X#endif
X
SHAR_EOF
echo "extracting saveilbm.c"
sed 's/^X//' << \SHAR_EOF > saveilbm.c
X/***************************************************************************
X*  SaveILBM.c --  Save front screen as ILBM file
X*                 Saves a CAMG chunk for Amiga ViewModes
X*                   by Carolyn Scheppner  CBM  10/86
X*
X*                   modified by Kevin L. Clague for use in Mandelbrot
X*
X*     Using IFF rtns by J.Morrison and S.Shaw of Electronic Arts
X*
X***************************************************************************/
X
X#include "SaveILBM.h"
X
X/* CAMG Stuff */
Xtypedef struct {
X   ULONG ViewModes;
X   } CamgChunk;
X
X#define PutCAMG(context, camg)  \
X    PutCk(context, ID_CAMG, sizeof(CamgChunk), (BYTE *)camg)
X
X#define ID_CRNG  MakeID('C','R','N','G')
X#define PutCRNG(context, crng)  \
X    PutCk(context, ID_CRNG, sizeof(CrngChunk), (BYTE *)crng)
X
X#define bufSize 512
X
Xextern struct IntuitionBase *IntuitionBase;
Xextern struct Screen *screen;
X
Xstruct Screen   *frontScreen;
X
Xstruct ViewPort *picViewPort;
Xstruct BitMap   *picBitMap;
XWORD            *picColorTable;
XULONG            picViewModes;
X
X/* ILBM Icon Image */
X
XUSHORT  ILBMimagedata[] = {
X 0x0000, 0x0000, 0x0000, 0x0000,
X 0x7FFF, 0xFFFF, 0xFFFF, 0xFF80,
X 0x6000, 0x0000, 0x0000, 0x0180,
X 0x6000, 0x07FF, 0xFFFF, 0x8180,
X 0x6000, 0x401F, 0xFFC0, 0x0180,
X 0x6002, 0xE000, 0x0000, 0x0180,
X 0x6003, 0x6002, 0x0008, 0x0180,
X 0x600B, 0xF807, 0x005E, 0x0180,
X 0x6001, 0xFC03, 0x809F, 0x8180,
X 0x6000, 0x0E07, 0xC2FF, 0xE180,
X 0x600D, 0xAF05, 0xE017, 0xF980,
X 0x6021, 0x2F83, 0xC057, 0xF980,
X 0x6025, 0xFF1F, 0x24C7, 0xF980,
X 0x6097, 0xFA6E, 0x881F, 0xF980,
X 0x601E, 0xFCEC, 0x3B5B, 0xF980,
X 0x6055, 0xFFBA, 0x559F, 0xF980,
X 0x60EF, 0xFFFF, 0xFFFF, 0xF980,
X 0x6000, 0x0000, 0x0000, 0x0180,
X 0x7FFF, 0xFFFF, 0xFFFF, 0xFF80,
X 0x0000, 0x0000, 0x0000, 0x0000,
X/**/
X 0xFFFF, 0xFFFF, 0xFFFF, 0xFFC0,
X 0x8000, 0x0000, 0x0000, 0x0040,
X 0x9FFF, 0xFFFF, 0xFFFF, 0xFE40,
X 0x9800, 0x0000, 0x0000, 0x0640,
X 0x9800, 0x0000, 0x0000, 0x0640,
X 0x9801, 0x0000, 0x0000, 0x0640,
X 0x9804, 0x8004, 0x0000, 0x0640,
X 0x9804, 0x8008, 0x0020, 0x0640,
X 0x981F, 0x0C0C, 0x0160, 0x0640,
X 0x983F, 0xFE1F, 0x8D00, 0x0640,
X 0x98FF, 0xFF7F, 0xDFE8, 0x0640,
X 0x9BFF, 0xFFFF, 0xFFFF, 0x0640,
X 0x9FFF, 0xFFFF, 0xFFFF, 0x8640,
X 0x9FFF, 0xFFFF, 0xFFFF, 0xFE40,
X 0x9FFF, 0xFFFF, 0xFFFF, 0xFE40,
X 0x9FFF, 0xFFFF, 0xFFFF, 0xFE40,
X 0x9FFF, 0xFFFF, 0xFFFF, 0xFE40,
X 0x9FFF, 0xFFFF, 0xFFFF, 0xFE40,
X 0x8000, 0x0000, 0x0000, 0x0040,
X 0xFFFF, 0xFFFF, 0xFFFF, 0xFFC0
X/**/
X };
X
Xstruct Image  ILBMimage[] = {
X 0,  /* LeftEdge */
X 0,  /* TopEdge */
X 58,  /* Width */
X 20,  /* Height */
X 2,  /* Depth */
X (USHORT *)&ILBMimagedata,  /* ImageData */
X 0x3,  /* PlanePick */
X 0x0,  /* PlaneOnOff */
X 0  /* [NextImage] */
X };
X
Xstruct DiskObject ILBMIcon = {
X WB_DISKMAGIC,   /* do_Magic */
X WB_DISKVERSION, /* do_Version */
X
X/* Embedded Gadget Structure */
X 0,  /* [NextGadget] */
X 147,  /* LeftEdge */
X 23,  /* TopEdge */
X 58,  /* Width */
X 20,  /* Height */
X 0x4,  /* Flags */
X 0x3,  /* Activation */
X 0x1,  /* GadgetType */
X (APTR)&ILBMimage, /* GadgetRender */
X NULL,     /* SelectRender */
X NULL,     /* GadgetText */
X 0x0,  /* MutualExclude */
X 0x0,  /* [SpecialInfo] */
X 0,  /* GadgetID */
X 0x0,  /* [UserData] */
X
X/* Rest of DiskObject structure */
X 0x4,  /* do_Type */
X ":ViewILBM",   /* do_Default Tool */
X 0xC06508,  /* [do_ToolTypes] */
X NO_ICON_POSITION,  /* do_CurrentX */
X NO_ICON_POSITION,  /* do_CurrentY */
X 0x0,  /* [do_DrawerData] */
X 0x0,  /* [do_ToolWindow] */
X 0x0  /* do_StackSize */
X };
X
X/**************************************************************************
X *
X *  Save the current screen as an ILBM file
X *
X **************************************************************************/
X
XSaveILBM(FileName, Crng, numCrng)
X  char *FileName;
X  CrngChunk *Crng;
X  int numCrng;
X{
X  LONG            file;
X  IFFP            iffp = NO_FILE;
X
X  int l;
X
X  if (!(file = Open(FileName, MODE_NEWFILE))) {
X
X    char Msg[80];
X    sprintf(Msg,"Can't open file %s\n",FileName);
X    DispErrMsg(Msg,0);
X    return(0);
X  }
X
X  Write(file,"x",1);  /* 1.1 so Seek to beginning works ? */
X
X  frontScreen  = screen;
X
X  picViewPort =  &( frontScreen->ViewPort );
X  picBitMap =     (struct BitMap*)picViewPort->RasInfo->BitMap;
X  picColorTable = (WORD *)picViewPort->ColorMap->ColorTable;
X  picViewModes =  (ULONG)picViewPort->Modes;
X
X  iffp = PutPicture(file, picBitMap, picColorTable, picViewModes,
X    Crng, numCrng);
X  Close(file);
X
X  if (iffp == IFF_OKAY && FromWB ) {
X
X    /* This line outputs the icon */
X    PutDiskObject(FileName,&ILBMIcon);
X  }
X} /* SaveILBM */
X
X
X/** PutPicture() ***********************************************************
X *
X * Put a picture into an IFF file.
X * This procedure calls PutAnILBM, passing in an <x, y> location of <0, 0>,
X * a NULL mask, and a locally-allocated buffer. It also assumes you want to
X * write out all the bitplanes in the BitMap.
X *
X ***************************************************************************/
XPoint2D nullPoint = {0, 0};
X
XIFFP PutPicture(file, bitmap, colorMap, viewmodes, crng, numcrng)
X      LONG file;  struct BitMap *bitmap;
X      WORD *colorMap;  ULONG viewmodes;
X      CrngChunk *crng;
X      int numcrng;
X   {
X   BYTE buffer[bufSize];
X   return( PutAnILBM(file, bitmap, NULL,
X           colorMap, bitmap->Depth, viewmodes,
X           &nullPoint, crng, numcrng, buffer, bufSize) );
X   }
X
X
X/** PutAnILBM() ************************************************************
X *
X * Write an entire BitMap as a FORM ILBM in an IFF file.
X * This version works for any display mode (C. Scheppner).
X *
X * Normal return result is IFF_OKAY.
X *
X * The utility program IFFCheck would print the following outline of the
X * resulting file:
X *
X *   FORM ILBM
X *     BMHD
X *     CAMG
X *     CMAP
X *     CRNG
X *     CRNG
X *     CRNG
X *     CRNG
X *     BODY       (compressed)
X *
X ***************************************************************************/
X#define CkErr(expression)  {if (ifferr == IFF_OKAY) ifferr = (expression);}
X
XIFFP PutAnILBM(file, bitmap, mask, colorMap, depth,
X                                viewmodes, xy, crng, numcrng,
X                                buffer, bufsize)
X      LONG file;
X      struct BitMap *bitmap;
X      BYTE *mask;  WORD *colorMap; UBYTE depth;
X      ULONG viewmodes;
X      Point2D *xy; BYTE *buffer;  LONG bufsize;
X      CrngChunk *crng;
X      int numcrng;
X   {
X   BitMapHeader bmHdr;
X   CamgChunk    camgChunk;
X   GroupContext fileContext, formContext;
X   IFFP ifferr;
X   WORD pageWidth, pageHeight;
X   int i;
X
X   pageWidth  = (bitmap->BytesPerRow) << 3;
X   pageHeight = bitmap->Rows;
X
X   ifferr = InitBMHdr(&bmHdr, bitmap, mskNone,
X                      cmpByteRun1, 0, pageWidth, pageHeight);
X   /* You could write an uncompressed image by passing cmpNone instead
X    * of cmpByteRun1 to InitBMHdr. */
X   bmHdr.nPlanes = depth;   /* This must be  <= bitmap->Depth */
X   if (mask != NULL) bmHdr.masking = mskHasMask;
X   bmHdr.x = xy->x;   bmHdr.y = xy->y;
X
X   camgChunk.ViewModes = viewmodes;
X
X   CkErr( OpenWIFF(file, &fileContext, szNotYetKnown) );
X   CkErr(StartWGroup(&fileContext, FORM, szNotYetKnown, ID_ILBM, &formContext));
X
X   CkErr( PutBMHD(&formContext, &bmHdr) );
X   CkErr( PutCAMG(&formContext, &camgChunk) );
X   CkErr( PutCMAP(&formContext, colorMap, depth) );
X
X   for (i = 0; i < numcrng; i++) {
X     CkErr( PutCRNG(&formContext, &crng[i]));
X   }
X   CkErr( PutBODY(&formContext, bitmap, mask, &bmHdr, buffer, bufsize) );
X
X   CkErr( EndWGroup(&formContext) );
X   CkErr( CloseWGroup(&fileContext) );
X   return( ifferr );
X   }
X
X
SHAR_EOF
echo "extracting saveilbm.h"
sed 's/^X//' << \SHAR_EOF > saveilbm.h
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: includes required by SaveILBM.c
X */
X
X#include "mandp.h"
X#include <libraries/dos.h>
X#include <graphics/rastport.h>
X#include <graphics/view.h>
SHAR_EOF
echo "extracting savemand.c"
sed 's/^X//' << \SHAR_EOF > savemand.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 functions to save projects to disk,
X * load projects from disk, and save icon files (if the program was started
X * from the WorkBench.)
X */
X
X#include "mandp.h"
X
Xextern struct NewScreen NewScreen;
X
Xextern ULONG CalcTime;
X
Xextern BYTE FromWB;
X
X       ULONG BorderType;
X
XUSHORT  MandimageData1[] = {
X 0xFFFF, 0xFFFF, 0xFFFF, 0xFFC0,
X 0xFFFF, 0xFFFF, 0xFFFF, 0xFFC0,
X 0xFFFF, 0xFFE3, 0xFFFF, 0xFFC0,
X 0xFFFF, 0xF101, 0x67FF, 0xFFC0,
X 0xFFF8, 0x7040, 0xC0F7, 0xFFC0,
X 0xF9D4, 0x4441, 0x414B, 0xFFC0,
X 0xF80F, 0x0F79, 0x8403, 0xFFC0,
X 0xDA0F, 0xFFFF, 0xEC01, 0xFFC0,
X 0x9743, 0xFFFF, 0xFE46, 0x0FC0,
X 0x8FFF, 0xFFFF, 0xFF80, 0x3FC0,
X 0xF03F, 0xFFEF, 0xFFC0, 0x7FC0,
X 0xB7FF, 0xFE00, 0x3F91, 0xDFC0,
X 0xFFFF, 0xF878, 0x3FC0, 0x07C0,
X 0x8FFF, 0xF8F0, 0x7F80, 0x17C0,
X 0xB7FF, 0xF0FF, 0xFFC0, 0x3FC0,
X 0xFFFF, 0xF83F, 0xFC03, 0x7FC0,
X 0xFFFF, 0xF70F, 0xD801, 0xFFC0,
X 0xFFFF, 0xFE00, 0x0000, 0xFFC0,
X 0xBFFF, 0xFE50, 0x415C, 0xFFC0,
X 0xBFFF, 0xFFFC, 0x90FF, 0xFFC0,
X 0xFFFF, 0xFFFD, 0xFEFF, 0xFFC0,
X 0xFFFF, 0xFFFF, 0xFFFF, 0xFFC0,
X/**/
X 0x01E0, 0xE1F0, 0xFC03, 0xFE00,
X 0x41E1, 0xC78F, 0xC03F, 0xF800,
X 0x61C7, 0x2BDD, 0xE1FF, 0x0000,
X 0x4394, 0x7FFF, 0xFD80, 0x0000,
X 0x4C57, 0xFFBF, 0x7FFD, 0xFFC0,
X 0x1FBB, 0xFFFF, 0xBFB4, 0x3FC0,
X 0x6FF0, 0xFCCF, 0xFFFC, 0xC1C0,
X 0x65F3, 0xF9C4, 0xB7FF, 0x9C00,
X 0x79FF, 0x8F33, 0x6BBD, 0xFB00,
X 0x70E7, 0xF136, 0x667F, 0xF9C0,
X 0x4FE0, 0x19D4, 0x0D3F, 0xD8C0,
X 0x4E9F, 0xC9FF, 0xC3EE, 0x3440,
X 0x6580, 0x67D7, 0xECBF, 0xFB00,
X 0x7A3E, 0x2FBF, 0x9EFF, 0xFF80,
X 0x69FF, 0xCF2A, 0xA3FF, 0xF580,
X 0x6700, 0x67E6, 0xC7FD, 0xB1C0,
X 0x583F, 0x1AF4, 0xA7FF, 0xF3C0,
X 0x31FF, 0xF5FF, 0xFFFF, 0x73C0,
X 0x53E0, 0x1DAF, 0xFEA7, 0x23C0,
X 0x4700, 0x00E7, 0xEF58, 0xE1C0,
X 0x4E07, 0xFFE3, 0x77E3, 0xC1C0,
X 0x383F, 0xFC00, 0x078F, 0x81C0,
X/**/
X };
X
Xstruct Image Mandimage1 = {
X 0,  /* LeftEdge */
X 0,  /* TopEdge */
X 58,  /* Width */
X 22,  /* Height */
X 2,  /* Depth */
X (USHORT *)MandimageData1,  /* ImageData */
X 0xFF,  /* PlanePick */
X 0x0,  /* PlaneOnOff */
X 0,  /* [NextImage] */
X };
X
Xstruct DiskObject MandIcon = {
X WB_DISKMAGIC,   /* do_Magic */
X WB_DISKVERSION, /* do_Version */
X
X/* Embedded Gadget Structure */
X 0,  /* [NextGadget] */
X 23,  /* LeftEdge */
X 14,  /* TopEdge */
X 58,  /* Width */
X 23,  /* Height */
X 0x5,  /* Flags */
X 0x3,  /* Activation */
X 0x1,  /* GadgetType */
X (APTR)&Mandimage1, /* GadgetRender */
X NULL,     /* SelectRender */
X NULL,     /* GadgetText */
X 0x0,  /* MutualExclude */
X 0x0,  /* [SpecialInfo] */
X 0,  /* GadgetID */
X 0x0,  /* [UserData] */
X
X/* Rest of DiskObject structure */
X 0x4,  /* do_Type */
X "MandelBrot:MandelVroom",   /* do_Default Tool */
X 0x0,  /* [do_ToolTypes] */
X 0x80000000,  /* do_CurrentX */
X 0x80000000,  /* do_CurrentY */
X 0x0,  /* [do_DrawerData] */
X 0x0,  /* [do_ToolWindow] */
X 10240 /* do_StackSize */
X };
X
XUSHORT  JuliaimageData1[] = {
X 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
X 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
X 0x0000, 0x0000, 0x0F80, 0x0000, 0x0000,
X 0x0000, 0x0000, 0x7F60, 0x0000, 0x0000,
X 0x0000, 0x000F, 0xF07E, 0x0000, 0x0000,
X 0x0000, 0x0079, 0xC071, 0xC000, 0x0000,
X 0x0004, 0xFFDB, 0xFFFE, 0xFC00, 0x0000,
X 0x001C, 0x6FDF, 0xFFFF, 0xFF7D, 0x0000,
X 0x00FF, 0xF183, 0xFFE0, 0x73C3, 0xC000,
X 0x05FF, 0xF100, 0x7FE0, 0xC3FF, 0xFC00,
X 0x33C3, 0xFC00, 0x7FFE, 0x007C, 0x6D80,
X 0x1F85, 0xF800, 0xFFF8, 0x007F, 0x0670,
X 0x03F1, 0xFC06, 0x3FF0, 0x01FE, 0x03E0,
X 0x003B, 0xFF98, 0x0FF0, 0x021F, 0xDF80,
X 0x000F, 0x187C, 0x3FFF, 0xE6FE, 0xB000,
X 0x0003, 0xFFFD, 0xFFFF, 0xDFC1, 0xC000,
X 0x0000, 0x003E, 0x7FDF, 0x7FFF, 0x0000,
X 0x0000, 0x0006, 0x785B, 0x6000, 0x0000,
X 0x0000, 0x0000, 0xFC7E, 0x0000, 0x0000,
X 0x0000, 0x0000, 0x1BF0, 0x0000, 0x0000,
X 0x0000, 0x0000, 0x0380, 0x0000, 0x0000,
X 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
X/**/
X 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
X 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
X 0x0000, 0x0000, 0x0D80, 0x0000, 0x0000,
X 0x0000, 0x0000, 0x70E0, 0x0000, 0x0000,
X 0x0000, 0x000F, 0xFFFE, 0x0000, 0x0000,
X 0x0000, 0x007E, 0x3F8F, 0xC000, 0x0000,
X 0x0007, 0xFFF4, 0x0001, 0xFC00, 0x0000,
X 0x001F, 0x93E0, 0x0000, 0xFFF3, 0x0000,
X 0x00F0, 0x0FFC, 0x001F, 0xFC3D, 0xC000,
X 0x0660, 0x0FFF, 0x801F, 0xFC00, 0x7C00,
X 0x2C7C, 0x1FFF, 0x9FFF, 0xFF83, 0xF380,
X 0x1C7E, 0x07FF, 0xFFFF, 0xFF83, 0xF990,
X 0x03FE, 0x03FF, 0xFF8F, 0xFFC1, 0xFC60,
X 0x003C, 0x007F, 0xF00F, 0xFFE0, 0x3F80,
X 0x000F, 0xE7FB, 0xC000, 0x1F03, 0x7000,
X 0x0002, 0xFFFE, 0x0000, 0x3FFE, 0xC000,
X 0x0000, 0x003F, 0x80A1, 0xFFFF, 0x0000,
X 0x0000, 0x0007, 0xC7E6, 0xE000, 0x0000,
X 0x0000, 0x0000, 0xFFBE, 0x0000, 0x0000,
X 0x0000, 0x0000, 0x1C70, 0x0000, 0x0000,
X 0x0000, 0x0000, 0x0280, 0x0000, 0x0000,
X 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
X/**/
X };
X
Xstruct Image Juliaimage1 = {
X 0,  /* LeftEdge */
X 0,  /* TopEdge */
X 78,  /* Width */
X 22,  /* Height */
X 2,  /* Depth */
X (USHORT *)JuliaimageData1,  /* ImageData */
X 0xFF,  /* PlanePick */
X 0x0,  /* PlaneOnOff */
X 0,  /* [NextImage] */
X };
X
Xstruct DiskObject JuliaIcon = {
X WB_DISKMAGIC,   /* do_Magic */
X WB_DISKVERSION, /* do_Version */
X
X/* Embedded Gadget Structure */
X 0,  /* [NextGadget] */
X 23,  /* LeftEdge */
X 14,  /* TopEdge */
X 78,  /* Width */
X 23,  /* Height */
X 0x5,  /* Flags */
X 0x3,  /* Activation */
X 0x1,  /* GadgetType */
X (APTR)&Juliaimage1, /* GadgetRender */
X NULL,     /* SelectRender */
X NULL,     /* GadgetText */
X 0x0,  /* MutualExclude */
X 0x0,  /* [SpecialInfo] */
X 0,  /* GadgetID */
X 0x0,  /* [UserData] */
X
X/* Rest of DiskObject structure */
X 0x4,  /* do_Type */
X "MandelBrot:MandelVroom",   /* do_Default Tool */
X 0x0,  /* [do_ToolTypes] */
X 0x80000000,  /* do_CurrentX */
X 0x80000000,  /* do_CurrentY */
X 0x0,  /* [do_DrawerData] */
X 0x0,  /* [do_ToolWindow] */
X 10240 /* do_StackSize */
X };
X
X/*
X * Save all the data needed to restore the system to current state.
X */
Xint
XSaveCounts(SaveName, Pict)
X  register char *SaveName;
X  register struct Picture *Pict;
X{
X  register FILE  *SaveFile;
X
X  USHORT ViewModes;
X  UBYTE  Depth;
X  ULONG  Version = VERSION;
X  char   ErrMsg[80];
X
X  /*
X   * Change the mouse pointer to Sleepy pointer
X   */
X  SetSleepyPointer();
X
X  /*
X   * open the desired file for writing
X   */
X  SaveFile = fopen(SaveName,"w");
X
X  if (SaveFile == (FILE *) NULL) {
X    sprintf(ErrMsg, "Can't open file %s", SaveName);
X    DispErrMsg(ErrMsg, 0);
X    return(UNSUCCESSFUL);
X  }
X
X  Pict->LeftEdge = Pict->Window->LeftEdge;
X  Pict->TopEdge  = Pict->Window->TopEdge;
X
X  /*
X   * if there is data to save, save it
X   */
X  if (Pict->Counts && ! (Pict->Flags & NO_RAM_GENERATE) ) {
X
X    if (Pict->pNode.ln_Type == MANDPICT) {
X
X      /*
X       * Put out the file header
X       */
X      fwrite((char *) "MAN4",    4,  1, SaveFile);
X    } else {
X
X      /*
X       * Put out the file header
X       */
X      fwrite((char *) "JUL4",    4,  1, SaveFile);
X    }
X
X    /*
X     * Put out the revision number
X     */
X    fwrite((char *) Version,   sizeof(Version), 1, SaveFile);
X
X    if (Pict->pNode.ln_Type == JULIAPICT) {
X
X      /*
X       * Put out the Julia point
X       */
X      fwrite((char *) &Pict->Real,   sizeof(double),   1, SaveFile);
X      fwrite((char *) &Pict->Imag,   sizeof(double),   1, SaveFile);
X    }
X
X    /*
X     * Put out the location on the complex plane
X     */
X    fwrite((char *) &Pict->RealLow,   sizeof(double),   1, SaveFile);
X    fwrite((char *) &Pict->ImagLow,   sizeof(double),   1, SaveFile);
X    fwrite((char *) &Pict->RealHigh,  sizeof(double),   1, SaveFile);
X    fwrite((char *) &Pict->ImagHigh,  sizeof(double),   1, SaveFile);
X
X    /*
X     * Put out the Maximum iteration count for a given point
X     */
X    fwrite((char *) &Pict->MaxIteration, sizeof(SHORT),    1, SaveFile);
X
X    /*
X     * Put out the generator type
X     */
X    fwrite((char *) &Pict->MathMode, sizeof(Pict->MathMode), 1, SaveFile);
X
X    /*
X     * Put out the time it took to generate
X     */
X    fwrite((char *) &CalcTime, sizeof(CalcTime), 1, SaveFile);
X
X    /*
X     * Put out the screen's viewmodes
X     */
X    ViewModes = NewScreen.ViewModes;
X    fwrite((char *) &ViewModes, sizeof(ViewModes), 1, SaveFile);
X
X    /*
X     * Put out the number of bit planes
X     */
X    Depth = NewScreen.Depth;
X    fwrite((char *) &Depth, sizeof(Depth), 1, SaveFile);
X
X    /*
X     * Put some window flags
X     */
X    fwrite((char *) &BorderType, sizeof(BorderType), 1, SaveFile);
X
X    /*
X     * Save the Color Palette
X     */
X    fwrite((char *) &Pict->RGBs, sizeof(Pict->RGBs), 1, SaveFile);
X
X    /*
X     * Save the number of contours
X     */
X    fwrite((char *) &NumContours, sizeof(NumContours), 1, SaveFile);
X
X    /*
X     * Save the contour's heights
X     */
X    fwrite((char *) Pict->Heights, sizeof(SHORT), (int) NumContours, SaveFile);
X
X    /*
X     * Save the contour's pen numbers (Color is a misnomer)
X     */
X    fwrite((char *) Pict->Pens, sizeof(UBYTE), (int) NumContours, SaveFile);
X
X    /*
X     * Put out the image dimensions
X     */
X    fwrite((char *) &Pict->CountX,   sizeof(SHORT),   1, SaveFile);
X    fwrite((char *) &Pict->CountY,   sizeof(SHORT),   1, SaveFile);
X
X    /*
X     * Put out project's position
X     */
X    fwrite((char *) &Pict->LeftEdge, sizeof(Pict->LeftEdge), 1, SaveFile);
X    fwrite((char *) &Pict->TopEdge,  sizeof(Pict->TopEdge),  1, SaveFile);
X    fwrite((char *) &Pict->CurLine,  sizeof(Pict->CurLine),  1, SaveFile);
X
X    (void) WriteRLLTwo( SaveFile, Pict );
X
X  } else {
X    DispErrMsg("No Picture to save",0);
X    fclose(SaveFile);
X    return(UNSUCCESSFUL);
X  }
X
X  fclose(SaveFile);
X
X  if (FromWB) {
X
X    FILE *IconFile;
X    char IconName[80];
X
X    strcpy( IconName, SaveName );
X    strcat( IconName, ".info" );
X
X    if ((IconFile = fopen( IconName, "r" )) == NULL) {
X
X      /*
X       * OutPut an icon for the saved picture
X       */
X      if (Pict->pNode.ln_Type == MANDPICT)
X        (void) PutDiskObject(SaveName,&MandIcon);
X      else
X        (void) PutDiskObject(SaveName,&JuliaIcon);
X
X    } else {
X      fclose( IconFile );
X    }
X  }
X
X  return(SUCCESSFUL);
X} /* SaveCounts */
X
Xint
XWriteRLLTwo( SaveFile, Pict )
X  register FILE *SaveFile;
X  register struct Picture *Pict;
X{
X
X  LONG Words;
X
X  Words = Compress( Pict );
X
X  fwrite( (char *) &Words, sizeof(LONG), 1, SaveFile);
X
X  /* in case I ever recompile into 16 bit ints */
X
X  if (sizeof(int) == 2 && sizeof(int)*Words > 65535) {
X    DispErrMsg("Programming error in Savemand\n", 0);
X    return(UNSUCCESSFUL);
X  }
X
X  fwrite( (char *) Pict->Counts, (int) (sizeof(SHORT) * Words), 1, SaveFile);
X
X  Decompress( Words, Pict );
X  return( SUCCESSFUL );
X}
X
X/* Compress the data.  Count up how many words in a row have the same value.
X * If the count is only one, then just put the data in the compressed array.
X * Otherwise, turn on the most significant bit in the Count, and put it
X * in the compressed array, then put the potential in the array.
X *
X * Advantages:
X * -  Compressed data guaranteed to be as small or smaller than uncompressed
X *    data.
X * -  Compression can be done in place in memory, so it is fast without
X *    requiring extra memory.
X * -  Once compressed, the data can be written to disk with one fwrite,
X *    therefore it should be quicker than previously used method that
X *    compressed and wrote to disk at the same time.
X * -  Maximum iteration count for Mandelbrot potential is 32767. The
X *    previous method only allowed 1023.
X */
Xint
XCompress( Pict )
X  register struct Picture *Pict;
X{
X  register SHORT *CountPtr,*CompressPtr;
X  register SHORT  Count;
X  register USHORT Cur;
X  register ULONG  i;
X  register ULONG  Word = 0;
X
X  i = Pict->CountsSize/sizeof(SHORT);
X
X  CountPtr = CompressPtr = Pict->Counts;
X  Cur = *CountPtr;
X  Count = 1;
X
X  while (--i) {
X    CountPtr++;
X
X    /*
X     * Count up how many in a row have same height
X     */
X    if (Cur == *CountPtr) {
X      Count++;
X    } else {
X      if ( Count > 1 ) {
X        *CompressPtr++ = Count | 0x8000;
X      }
X      *CompressPtr++ = Cur;
X      Count = 1;
X      Cur = *CountPtr;
X    }
X  }
X
X  if ( Count > 1 ) {
X    *CompressPtr++ = Count | 0x8000;
X  }
X  *CompressPtr++ = Cur;
X
X  Word = CompressPtr - Pict->Counts;
X
X  return( Word );
X}
X
X/*
X * Load the state of the program from file
X */
Xint
XLoadCounts(LoadName, Pict )
X  register char *LoadName;
X  register struct Picture *Pict;
X{
X  register FILE  *LoadFile;
X  USHORT ViewModes;
X  UBYTE  Depth;
X  char   Header[5];
X  ULONG  Version;
X  char   ErrMsg[80];
X  int    rc;
X  char  *File, *ExtractName();
X
X  extern int Num_vp_Colors;
X  extern USHORT NewViewModes;
X  extern UBYTE  NewDepth;
X
X  extern struct MathTransBase *MathTransBase;
X  extern LONG   SPTIEEE;
X
X  /*
X   * Change the mouse pointer to Sleepy pointer
X   */
X
X  SetSleepyPointer();
X
X  LoadFile = fopen(LoadName,"r");
X
X  Pict->GenState = FINISHEDSTATE;
X
X  if (LoadFile == (FILE *) NULL) {
X
X    /*
X     * can't read a non-existant file
X     */
X    sprintf(ErrMsg, "File %s not found", LoadName);
X    DispErrMsg(ErrMsg, 0);
X    return( UNSUCCESSFUL );
X  }
X
X  /*
X   * Read and check the file header
X   */
X  (void) fread((char *) &Header[0], 4, 1, LoadFile);
X  Header[4] = '\0';
X
X  if (strcmp(&Header[0], "MAND") != 0 &&
X      strcmp(&Header[0], "MAN1") != 0 &&
X      strcmp(&Header[0], "MAN2") != 0 &&
X      strcmp(&Header[0], "MAN3") != 0 &&
X      strcmp(&Header[0], "MAN4") != 0 &&
X      strcmp(&Header[0], "JUL3") != 0 &&
X      strcmp(&Header[0], "JUL4") != 0    ) {
X
X    /*
X     * File of improper format
X     */
X    sprintf(ErrMsg, "File %s is not a MAND file",LoadName);
X    DispErrMsg(ErrMsg, 0);
X    fclose(LoadFile);
X    return( UNSUCCESSFUL );
X  }
X
X  /*
X   * Read in the version
X   */
X  (void) fread((char *) &Version, sizeof(Version), 1, LoadFile);
X
X  if ( strcmp( &Header[0], "MAN2") == 0 ||
X       strcmp( &Header[0], "MAN3") == 0 ||
X       strcmp( &Header[0], "MAN4") == 0 ||
X       strcmp( &Header[0], "JUL3") == 0 ||
X       strcmp( &Header[0], "JUL4") == 0 ) {
X
X    if ( strcmp( &Header[0], "JUL3") == 0 ||
X         strcmp( &Header[0], "JUL4") == 0 ) {
X
X      Pict->pNode.ln_Type = JULIAPICT;
X      (void) fread((char *) &Pict->Real, sizeof(double), 1, LoadFile);
X      (void) fread((char *) &Pict->Imag, sizeof(double), 1, LoadFile);
X    } else {
X      Pict->pNode.ln_Type = MANDPICT;
X    }
X
X    /*
X     * Read in the location in the complex plane
X     */
X    (void) fread((char *) &Pict->RealLow,  sizeof(double), 1, LoadFile);
X    (void) fread((char *) &Pict->ImagLow,  sizeof(double), 1, LoadFile);
X    (void) fread((char *) &Pict->RealHigh, sizeof(double), 1, LoadFile);
X    (void) fread((char *) &Pict->ImagHigh, sizeof(double), 1, LoadFile);
X  } else {
X
X    /* Must be old FFP code */
X
X    LONG startx, starty, endx, endy;
X
X    LONG SPTieee();
X
X    /*
X     * Read in the FFP form of location in the complex plane
X     */
X    (void) fread((char *) &startx, sizeof(LONG), 1, LoadFile);
X    (void) fread((char *) &starty, sizeof(LONG), 1, LoadFile);
X    (void) fread((char *) &endx,   sizeof(LONG), 1, LoadFile);
X    (void) fread((char *) &endy,   sizeof(LONG), 1, LoadFile);
X
X    /*
X     * Convert it to IEEE format
X     */
X    if (OpenFFPLibs() != 0)
X      return(UNSUCCESSFUL);
X
X    startx = SPTieee( startx );
X    starty = SPTieee( starty );
X    endx   = SPTieee( endx );
X    endy   = SPTieee( endy );
X
X    /*
X     * promote them to doubles
X     */
X    Pict->RealLow  = (double) *( (float *) &startx );
X    Pict->ImagLow  = (double) *( (float *) &starty );
X    Pict->RealHigh = (double) *( (float *) &endx );
X    Pict->ImagHigh = (double) *( (float *) &endy );
X  }
X
X  /*
X   * Read in the maximum iteration count for a given point
X   */
X  (void) fread((char *) &Pict->MaxIteration, sizeof(SHORT), 1, LoadFile);
X
X  /*
X   * Read in the generator type
X   */
X  (void) fread((char *) &Pict->MathMode, sizeof(Pict->MathMode), 1, LoadFile);
X
X  /*
X   * Read in the calculation time
X   */
X  (void) fread((char *) &CalcTime, sizeof(CalcTime), 1, LoadFile);
X
X  /*
X   * Read in the screen's viewmodes
X   */
X  (void) fread((char *) &ViewModes, sizeof(ViewModes), 1, LoadFile);
X
X  ViewModes &= HIRES | INTERLACE | EXTRA_HALFBRITE;
X  Pict->ViewModes = ViewModes;
X
X  /*
X   * Read in the number of bit planes
X   */
X  (void) fread((char *) &Depth, sizeof(Depth), 1, LoadFile);
X  Pict->Depth = Depth;
X
X  /*
X   * Read in the window flags
X   */
X  (void) fread((char *) &BorderType, sizeof(BorderType), 1, LoadFile);
X
X  /*
X   * Read in the color palette information
X   */
X  (void) fread((char *) &Pict->RGBs[0], sizeof(Pict->RGBs), 1, LoadFile);
X
X  /*
X   * Read in the number of contours
X   */
X  (void) fread((char *) &NumContours, sizeof(NumContours), 1, LoadFile);
X
X  /*
X   * Read in the heights
X   */
X  (void) fread((char *) Pict->Heights, sizeof(SHORT), NumContours, LoadFile);
X
X  /*
X   * Read in the pen numbers (Color is a misnomer)
X   */
X  (void) fread((char *) Pict->Pens, sizeof(UBYTE), NumContours, LoadFile);
X
X  for ( ; NumContours < NUMCONTS; NumContours++ ) {
X    *(Pict->Heights + NumContours) = 0;
X    *(Pict->Pens + NumContours) = 0;
X  }
X
X  /*
X   * Read in the image dimensions
X   */
X  (void) fread((char *) &Pict->CountX,   sizeof(SHORT),  1, LoadFile);
X  (void) fread((char *) &Pict->CountY,   sizeof(SHORT),  1, LoadFile);
X
X  if ( strcmp( &Header[0], "MAN4") == 0 ||
X       strcmp( &Header[0], "JUL4") == 0 ) {
X
X    /*
X     * Read in the image dimensions
X     */
X    (void) fread((char *) &Pict->LeftEdge, sizeof(Pict->LeftEdge),
X                                           1, LoadFile);
X    (void) fread((char *) &Pict->TopEdge,  sizeof(Pict->TopEdge),
X                                           1, LoadFile);
X    (void) fread((char *) &Pict->CurLine,  sizeof(Pict->CurLine),
X                                           1, LoadFile);
X    if (Pict->CurLine > Pict->CountY)
X      Pict->CurLine -= TOPMARG;
X
X  } else {
X    Pict->CurLine = Pict->CountY;
X  }
X
X  GetCountsMemory( Pict );
X
X  if (Pict->Counts == (SHORT *) NULL || (Pict->Flags & NO_RAM_GENERATE)) {
X    DispErrMsg("Can't load counts. Out of RAM!!",0);
X    fclose(LoadFile);
X    return( UNSUCCESSFUL );
X  }
X
X  if ( strcmp( &Header[0], "MAN3") == 0 ||
X       strcmp( &Header[0], "MAN4") == 0 ||
X       strcmp( &Header[0], "JUL3") == 0 ||
X       strcmp( &Header[0], "JUL4") == 0 ) {
X
X    rc = ReadRLLTwo( LoadFile, Pict );
X  } else {
X    rc = ReadRLLOne( LoadFile, Pict );
X  }
X  fclose(LoadFile);
X
X  if (rc != SUCCESSFUL) {
X    return( rc );
X  }
X
X  File = ExtractName( LoadName );
X  strncpy( Pict->Title, "  ", 2);
X  strncat( Pict->Title, File, sizeof(Pict->Title)-3);
X
X  CalculateGaps( Pict );
X
X  NewViewModes = Pict->ViewModes;
X  NewDepth     = Pict->Depth;
X
X  if ( MaybeNewScreen() == 0 ) {
X
X    /*
X     * Let's show it to them
X     */
X    if (OpenPicture( Pict ) != 0) {
X
X      return( UNSUCCESSFUL );
X
X    } else {
X      LoadRGB4( vp, Pict->RGBs, Num_vp_Colors );
X      ReColor( Pict );
X    }
X  }
X
X  GetCurPict();
X
X  if (CurPict) {
X    LoadRGB4( vp, CurPict->RGBs, Num_vp_Colors );
X  }
X  InitBorderSubs();
X
X  return( SUCCESSFUL );
X} /* LoadCounts */
X
X/* Load count information in pseudo RLL format */
X/* Bits 9-0 are iteration count.               */
X/* Bits 15-10 are how many iteration count of same height in a row */
X
Xint
XReadRLLOne( LoadFile, Pict )
X  register FILE *LoadFile;
X  register struct Picture *Pict;
X{
X  register SHORT *CountPtr;
X  register LONG   i;
X  register ULONG  Count = 0;
X
X  USHORT t;
X
X  CountPtr = Pict->Counts;
X
X  i = Pict->CountsSize / sizeof( SHORT );
X
X  while (i > 0) {
X    if ( fread((char *) &t, sizeof(t), 1, LoadFile) == 0) {
X      DispErrMsg("Premature EOF on source file",0);
X      fclose(LoadFile);
X      return( UNSUCCESSFUL);
X    }
X    Count = t >> 10;
X    t = t & 0x3ff;
X
X    for (; Count > 0; Count--) {
X     *(CountPtr++) = t;
X      i--;
X    }
X  }
X  return( SUCCESSFUL );
X}
X
Xint
XReadRLLTwo( LoadFile, Pict )
X  register FILE *LoadFile;
X  register struct Picture *Pict;
X{
X  LONG Words;
X
X  if (fread((char *) &Words, sizeof(Words), 1, LoadFile) == 0) {
X    DispErrMsg("Premature EOF on source file",0);
X    fclose(LoadFile);
X    return(UNSUCCESSFUL);
X  }
X  if (fread((char *) Pict->Counts,(int)(sizeof(SHORT)*Words),1,LoadFile) == 0){
X    DispErrMsg("Premature EOF on source file",0);
X    fclose(LoadFile);
X    return(UNSUCCESSFUL);
X  }
X  Decompress( Words, Pict );
X  return( SUCCESSFUL );
X}
X
X/* This algorithm decompresses the data.  The data array has
X * been malloced large enough to hold the decompressed data.  The data
X * is read from the disk into the array in compressed format.  This
X * decompresses the data in place.  The data must be decompressed from the
X * back to the front.
X */
XDecompress( Word, Pict )
X  LONG  Word;
X  struct Picture *Pict;
X{
X  register SHORT *CountPtr, *CompressPtr;
X  register SHORT  Count,Cur;
X  register LONG   i;
X  register SHORT  j;
X
X  /* Point to the last word of compressed data */
X
X  CompressPtr = Pict->Counts + Word - 1;
X
X  i = Pict->CountsSize/sizeof(SHORT);
X
X  /* Point to the last word of uncompressed data */
X
X  CountPtr = Pict->Counts + i - 1;
X
X  /* While there is data to uncompress.... */
X
X  while (i > 1 && CountPtr >= Pict->Counts && CompressPtr >= Pict->Counts) {
X
X    /* Pick up the last two words */
X
X    Cur   = *CompressPtr--;
X    Count = *CompressPtr;
X
X    if (Count & 0x8000) {        /* is it compressed? */
X
X      Count &= 0x7fff;           /* extract count */
X
X      for ( j = 0; j < Count; j++) {  /* Decompress it */
X        *CountPtr-- = Cur;
X        i--;
X      }
X      CompressPtr--;
X
X    } else {
X
X      *CountPtr-- = Cur;         /* just move it */
X      i--;
X    }
X  }
X}
SHAR_EOF
echo "extracting scroll.c"
sed 's/^X//' << \SHAR_EOF > scroll.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 functions used to implement MandelVroom's
X * pan command.  It seems to have a bug when resizing pictures slightly
X * smaller.
X */
X
X#include "mandp.h"
X
Xstatic int ScrollHotX, ScrollHotY;
X
XUBYTE ScrollOn = 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
XScrollPictCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  struct Window *Window;
X  static struct Picture *Pict;
X
X  Window = Msg->IDCMPWindow;
X  Pict = (struct Picture *) Window->UserData;
X
X  switch( Msg->Class ) {
X    case NEWSIZE:
X         if (CurPict && (CurPict->Flags & SCROLL_HAPPENED)) {
X           MoveClipImage(CurPict);
X         }
X         break;
X
X    case MENUPICK:
X         switch( SUBNUM(Msg->Code) ) {
X           case SETSCROLL:
X                State = SCROLLPICTSTATE;
X                ThrowTask(CurPict);
X                if ( ! (CurPict->Flags & SCROLL_HAPPENED)) {
X
X                  if ( AllocScrollTemp(CurPict) == UNSUCCESSFUL ) {
X                    return;
X                  }
X                  SaveInitialImage(CurPict);
X                }
X                CurPict->Flags |= SCROLL_HAPPENED;
X                SetToPointer();
X                break;
X
X           case GENSCROLL:
X                if (CurPict && CurPict->Flags & SCROLL_HAPPENED) {
X                  Generate(CurPict);
X                }
X                break;
X
X           case CANCELSCROLL:
X                ReColor(CurPict);
X                break;
X         }
X         break;
X
X    case MOUSEBUTTONS:
X         switch( Msg->Code ) {
X
X           case SELECTDOWN:                   /* start drag */
X                if (Pict == NULL || Pict != CurPict) {
X                  return;
X                }
X                ScrollHotX = MouseX - CurPict->ImageLoc.Left;
X                ScrollHotY = MouseY - CurPict->ImageLoc.Top;
X                Scroll( CurPict);
X                ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
X                break;
X
X           case SELECTUP:                     /* stop slide */
X                ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
X                break;
X         }
X         break;
X
X    case MOUSEMOVE:
X         Scroll( CurPict);
X         break;
X  }
X}
X
XSaveInitialImage(Pict)
X  struct Picture *Pict;
X{
X#ifdef SAFEBLIT
X  SafeClipBlit(Pict->Window,  Pict->LeftMarg, Pict->TopMarg,
X               TempWind,      0,            0,
X                              Pict->CountX, Pict->CountY,
X                              0xc0, __LINE__);
X#else
X  ClipBlit(Pict->Window->RPort, Pict->LeftMarg, Pict->TopMarg,
X           &Pict->ScrollRp,           0,            0,
X                                Pict->CountX, Pict->CountY,
X                                0xc0);
X#endif
X}
X
XScroll( Pict )
X  struct Picture *Pict;
X{
X  CalcNewLoc(Pict,MouseX,MouseY); /* figure out location of new image */
X  MoveClipImage(Pict);
X}
X
XCalcNewLoc(Pict, MouseX, MouseY)
X  register struct Picture *Pict;
X  int MouseX, MouseY;
X{
X  /* set new ImageLoc */
X
X  Pict->ImageLoc.Top    = MouseY - ScrollHotY;
X  Pict->ImageLoc.Left   = MouseX - ScrollHotX;
X  Pict->ImageLoc.Bot    = Pict->ImageLoc.Top  + Pict->CountY;
X  Pict->ImageLoc.Right  = Pict->ImageLoc.Left + Pict->CountX;
X}
X
XMoveClipImage(Pict)
X  register struct Picture  *Pict;
X{
X  struct Window   *Window;
X  struct RastPort *wind_Rp, *tmp_Rp;
X
X  register int POLeft, PORight, POTop, POBot;
X
X  struct Rect  SaveRect;
X  struct Rect  DispRect;
X
X  Window = Pict->Window;
X
X  SaveRect = Pict->ClipImage; /* struct assign */
X
X  DispRect.Left  = Pict->LeftMarg;
X  DispRect.Top   = Pict->TopMarg;
X  DispRect.Right = Window->Width - Pict->RightMarg - 1;
X  DispRect.Bot   = Window->Height - Pict->BotMarg - 1;
X
X  if (Pict->ImageLoc.Left  > DispRect.Right ||
X      Pict->ImageLoc.Top   > DispRect.Bot   ||
X      Pict->ImageLoc.Right < DispRect.Left  ||
X      Pict->ImageLoc.Bot   < DispRect.Top   ) {
X
X    return;
X  }
X
X  if (Pict->ImageLoc.Left < DispRect.Left) {
X    Pict->ClipImage.Left =  DispRect.Left;
X    POLeft = -Pict->ImageLoc.Left + Pict->LeftMarg;
X  } else {
X    Pict->ClipImage.Left =  Pict->ImageLoc.Left;
X    POLeft =  0;
X  }
X
X  if (Pict->ImageLoc.Top < DispRect.Top) {
X    Pict->ClipImage.Top = DispRect.Top;
X    POTop = -Pict->ImageLoc.Top + Pict->TopMarg;
X  } else {
X    Pict->ClipImage.Top = Pict->ImageLoc.Top;
X    POTop = 0;
X  }
X
X  if (Pict->ImageLoc.Right <= DispRect.Right) {
X    Pict->ClipImage.Right = Pict->ImageLoc.Right;
X    PORight = Pict->CountX-1;
X  } else {
X    Pict->ClipImage.Right = DispRect.Right;
X    PORight = DispRect.Right - Pict->ImageLoc.Left;
X  }
X
X  if (Pict->ImageLoc.Bot <= DispRect.Bot) {
X    Pict->ClipImage.Bot = Pict->ImageLoc.Bot;
X    POBot = Pict->CountY - 1;
X  } else {
X    Pict->ClipImage.Bot = DispRect.Bot;
X    POBot = DispRect.Bot - Pict->ImageLoc.Top;
X  }
X
X  wind_Rp = Window->RPort;
X
X#ifdef TEMPWINDOW
X  tmp_Rp = TempWind->RPort;
X#else
X  tmp_Rp = &Pict->ScrollRp;
X#endif
X
X  if (POLeft < PORight && POTop < POBot) {
X
X  /* Now copy temp rastport data to window */
X
X#ifdef SAFEBLIT
X    SafeClipBlit(TempWind, POLeft, POTop, Window,
X                       Pict->ClipImage.Left, Pict->ClipImage.Top,
X                       PORight - POLeft + 1, POBot - POTop + 1, 0xc0,
X                       __LINE__);
X#else
X    ClipBlit(tmp_Rp,   POLeft, POTop, wind_Rp,
X                       Pict->ClipImage.Left, Pict->ClipImage.Top,
X                       PORight - POLeft + 1, POBot - POTop + 1, 0xc0);
X#endif
X
X#if 0
X    printf("l %d t %d r %d b %d\n",POLeft, POTop, PORight, POBot);
X    printf("width %d height %d\n",
X            PORight - POLeft + 1, POBot - POTop + 1);
X#endif
X  }
X
X  Pict->DataClip.Left  = POLeft;
X  Pict->DataClip.Right = PORight;
X  Pict->DataClip.Top   = POTop;
X  Pict->DataClip.Bot   = POBot;
X
X  /* Undraw the old picture */
X
X  SetAPen(wind_Rp, 0);
X
X  if (Pict->ClipImage.Left > SaveRect.Left) {
X
X    FillCheck(Window, SaveRect.Left, SaveRect.Top,
X                      Pict->ClipImage.Left, SaveRect.Bot);
X  } else
X  if (Pict->ClipImage.Right < SaveRect.Right) {
X
X    FillCheck(Window, Pict->ClipImage.Right, Pict->ClipImage.Top,
X                      SaveRect.Right, SaveRect.Bot);
X  }
X
X  if (Pict->ClipImage.Top > SaveRect.Top) {
X
X    FillCheck(Window, SaveRect.Left, SaveRect.Top,
X                      SaveRect.Right, Pict->ClipImage.Top);
X  } else
X  if (Pict->ClipImage.Bot < SaveRect.Bot) {
X
X    FillCheck(Window, SaveRect.Left,  Pict->ClipImage.Bot,
X                      SaveRect.Right, SaveRect.Bot);
X  }
X}
X
XFillCheck(Window,src_x,src_y,dst_x,dst_y)
X  struct Window *Window;
X  int src_x,src_y,dst_x,dst_y;
X{
X  if (src_x < 0 || src_x > Window->Width) {
X#ifdef DEBUG
X    printf("Bad Fill src_x %d Width %d\n",
X            src_x,Window->Width);
X#endif
X    return;
X  }
X
X  if (src_y < 0 || src_y > Window->Height) {
X#ifdef DEBUG
X    printf("Bad Fill src_y %d Height %d\n",
X            src_y,Window->Height);
X#endif
X    return;
X  }
X
X  if (dst_x < 0 || dst_x > Window->Width) {
X#ifdef DEBUG
X    printf("Bad Fill dst_x %d Width %d\n",
X            dst_x,Window->Width);
X#endif
X    return;
X  }
X
X  if (dst_y < 0 || dst_y > Window->Height) {
X#ifdef DEBUG
X    printf("Bad Fill dst_y %d Height %d\n",
X            dst_y,Window->Height);
X#endif
X    return;
X  }
X  if (src_x > dst_x) {
X#ifdef DEBUG
X    printf("inverted rect fill\n");
X#endif
X    return;
X  }
X  if (src_y > dst_y) {
X#ifdef DEBUG
X    printf("end for end flipped rect fill\n");
X#endif
X    return;
X  }
X  RectFill(Window->RPort, src_x,src_y,dst_x,dst_y);
X}
X
XAllocScrollTemp( Pict )
X  register struct Picture *Pict;
X{
X  LONG Plane;
X  PLANEPTR t;
X
X  extern struct MenuItem ScrollSub[];
X
X  static ScrollInited;
X
X  extern struct NewScreen NewScreen;
X
X  if ( !ScrollOn )
X    return;
X
X#ifdef TEMPWINDOW
X
X  NewTemp.Width    = Pict->Window->Width;
X  NewTemp.Height   = Pict->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  return( SUCCESSFUL );
X
X#else
X
X  if ( Pict->ScrollRp.BitMap == NULL ) {
X
X    InitRastPort( &Pict->ScrollRp );
X    Pict->ScrollRp.BitMap = &Pict->ScrollBitMap;
X  }
X
X  InitBitMap( &Pict->ScrollBitMap, (long) NewScreen.Depth,
X               Pict->CountX, Pict->CountY);
X
X  for (Plane = 0; Plane < NewScreen.Depth; Plane++) {
X
X    t = (PLANEPTR) AllocRaster(Pict->CountX, Pict->CountY);
X    Pict->ScrollBitMap.Planes[Plane] = (PLANEPTR) t;
X
X    if (t == NULL) {
X      FreeScrollTemp( Pict );
X      return(UNSUCCESSFUL);
X    }
X  }
X  return(SUCCESSFUL);
X#endif
X}
X
XFreeScrollTemp( Pict )
X  struct Picture *Pict;
X{
X  LONG Plane;
X
X  if (Pict->Flags & SCROLL_HAPPENED) {
X
X#ifdef TEMPWINDOW
X    CloseWindow( TempWind );
X#else
X
X    for (Plane = 0; Plane < Pict->ScrollBitMap.Depth; Plane++) {
X
X      if (Pict->ScrollBitMap.Planes[Plane]) {
X
X        FreeRaster( (char *) Pict->ScrollBitMap.Planes[Plane],
X                    Pict->CountX,Pict->CountY);
X        Pict->ScrollBitMap.Planes[Plane] = NULL;
X      }
X    }
X#endif
X  }
X  ResetScrollRects(Pict);
X}
X
XResetScrollRects(Pict)
X  struct Picture *Pict;
X{
X  Pict->Flags &= ~SCROLL_HAPPENED;
X
X  Pict->ImageLoc.Left   = Pict->LeftMarg;
X  Pict->ImageLoc.Top    = Pict->TopMarg;
X  Pict->ImageLoc.Right  = Pict->LeftMarg + Pict->CountX - 1;
X  Pict->ImageLoc.Bot    = Pict->TopMarg  + Pict->CountY - 1;
X
X  Pict->ClipImage = Pict->ImageLoc; /* struct assignment */
X}
X
X#ifdef SAFEBLIT
Xstatic
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
XScrollComplex(Pict)
X  struct Picture *Pict;
X{
X  int left, top;
X  int count_x, count_y;
X  SHORT *NewCounts;
X
X  count_x = Pict->Window->Width  - Pict->LeftMarg - Pict->RightMarg;
X  count_y = Pict->Window->Height - Pict->BotMarg  - Pict->TopMarg;
X
X  NewCounts = (SHORT *) safeAllocMem(count_x*count_y*sizeof(SHORT),MEMF_CLEAR);
X
X  if (NewCounts == NULL) {
X    DispErrMsg("Can't scroll. Out of RAM.",0);
X    return;
X  }
X
X  ScrollData(Pict, NewCounts, count_x, count_y);
X
X  FreeCounts( Pict );
X
X  left  = Pict->ImageLoc.Left  - Pict->LeftMarg;
X  top   = Pict->ImageLoc.Top   - Pict->TopMarg;
X
X  Pict->RealLow  -= Pict->RealGap * left;
X  Pict->ImagLow  -= Pict->ImagGap * top;
X  Pict->RealHigh  = Pict->RealLow + Pict->RealGap * count_x;
X  Pict->ImagHigh  = Pict->ImagLow + Pict->ImagGap * count_y;
X
X  FreeScrollTemp(Pict);
X
X  Pict->Counts = NewCounts;
X  Pict->CountX = count_x;
X  Pict->CountY = count_y;
X  Pict->CountsSize = count_x * count_y * sizeof(*Pict->Counts);
X  Pict->CurLine = 0;
X}
X
XScrollData(Pict, NewCounts, width, height)
X  register struct Picture *Pict;
X  SHORT *NewCounts;
X  int width, height;
X{
X  int sr,sc;
X  register SHORT *s_rowp, *d_rowp, *sp, *dp;
X
X  s_rowp = Pict->Counts +  Pict->DataClip.Top * Pict->CountX;
X  d_rowp = NewCounts    + (Pict->ClipImage.Top-Pict->TopMarg) * width;
X
X  for (sr = Pict->DataClip.Top; sr < Pict->DataClip.Bot; sr++) {
X
X    dp = d_rowp + Pict->ClipImage.Left - Pict->LeftMarg;
X    sp = s_rowp + Pict->DataClip.Left;
X
X    for (sc = Pict->DataClip.Left; sc < Pict->DataClip.Right; sc++) {
X
X      *dp++ = *sp++;
X    }
X    s_rowp += Pict->CountX;
X    d_rowp += width;
X  }
X}
X
SHAR_EOF
echo "extracting showhelp.c"
sed 's/^X//' << \SHAR_EOF > showhelp.c
X/*
X * browser - Rummage around on disks.
X *
X *      copyright (c) 1986, Mike Meyer
X *
X * Permission is hereby granted to distribute this program, so long as this
X * source file is distributed with it, and this copyright notice is not
X * removed from the file.
X *
X * Hacked up to be used as file displayer within MandelVroom.  By Kevin
X * Clague
X */
X
X#include "mandp.h"
X
X#define INTUITION_REV           1L
X#define GRAPHICS_REV            1L
X
X#define LONGEST_NAME            80      /* Longest file name we can deal with */
X#define LONGEST_LINE            256     /* Longest line we will deal with */
X#define AVG_LINE_LENGTH         40      /* A guess, tune it if you need to */
X
X#define UP_GADGET               ((unsigned short) 0)
X#define DOWN_GADGET             ((unsigned short) 1)
X#define SCROLL_GADGET           ((unsigned short) 2)
X#define GWIDTH                  16      /* Width of my two gadgets */
X#define GHEIGHT                 9       /* and their heights */
X
X#define FIRST 18L
X
X/*
X * Pictures for the up and down arrows
X */
XUSHORT arrows[2][GHEIGHT] = {
X        {0xFE7F,
X         0xFC3F,
X         0xF81F,
X         0xF00F,        /* Up */
X         0xFE7F,
X         0xFE7F,
X         0xFE7F,
X         0xFE7F,
X         0xFE7F
X        },{
X         0xFE7F,
X         0xFE7F,
X         0xFE7F,
X         0xFE7F,        /* Down */
X         0xFE7F,
X         0xF00F,
X         0xF81F,
X         0xFC3F,
X         0xFE7F}
X        } ;
X
X/*
X * Now, the Image structures that use the arrows
X */
Xstruct Image Arrow_Image[2] = {
X        {0, 0, GWIDTH, GHEIGHT, 1, NULL, 1, 0, NULL}, /* Up */
X        {0, 0, GWIDTH, GHEIGHT, 1, NULL, 1, 0, NULL} /* Down */
X        };
X/*
X * Now, my Gadget structures
X */
Xstatic struct PropInfo prop;
Xstatic struct Image prop_img;
X
Xstatic struct Gadget Scroll_Gadget = {
X        /*(struct Gadget *)*/ NULL,          /* End of Gadgets */
X        0,10+GHEIGHT,                        /* Left, Top */
X        GWIDTH, -((GHEIGHT*2)+11),
X        GRELHEIGHT | GADGHCOMP,
X        GADGIMMEDIATE|FOLLOWMOUSE|RELVERIFY, /* Messages when released */
X        PROPGADGET,
X        (APTR) &prop_img,
X        (APTR) NULL,                        /* No rendering image, using HCOMP */
X        /*(struct IntuiText *)*/ NULL,
X        0L,                                 /* No mutex */
X        (APTR) &prop,
X        HELPSCROLL,                         /* Yes, this is the scroll gadget */
X        (APTR) NULL                         /* And nothing of mine */
X};
X
Xstatic struct Gadget Up_Gadget = {
X        &Scroll_Gadget,                     /* next gadget is scroll */
X        0,10,                               /* Left, Top */
X        GWIDTH, GHEIGHT,
X        GADGIMAGE | GADGHCOMP,
X        GADGIMMEDIATE,                      /* Messages when released */
X        BOOLGADGET,                         /* These be boolean gadgets */
X        (APTR) &(Arrow_Image[UP_GADGET]),
X        (APTR) NULL,                        /* No rendering image, using HCOMP */
X        /*(struct IntuiText *)*/ NULL,
X        0L,                                 /* No mutex */
X        (APTR) NULL,                        /* Nothing special */
X        HELPUP,                             /* Yes, this is the up gadget */
X        (APTR) NULL                         /* And nothing of mine */
X};
X
Xstatic struct Gadget Down_Gadget = {
X        &Up_Gadget,                         /* Next gadget is Up_Gadget */
X        0,  -GHEIGHT,                       /* Left, Top */
X        GWIDTH, GHEIGHT,
X        GRELBOTTOM | GADGIMAGE |            /* Standard bottom border gadget */
X        GADGHCOMP,
X        GADGIMMEDIATE | BOTTOMBORDER,       /* Messages when released */
X        BOOLGADGET,                         /* These be boolean gadgets */
X        (APTR) &(Arrow_Image[DOWN_GADGET]),
X        (APTR) NULL,                        /* No rendering image, using HCOMP */
X        /*(struct IntuiText *)*/ NULL,
X        0L,                                 /* No mutex */
X        (APTR) NULL,                        /* Nothing special */
X        HELPDOWN,                           /* Yes, this is the up gadget */
X        (APTR) NULL                         /* And nothing of mine */
X        };
X
X/*
X * Now, the window for it all
X */
Xstatic struct NewWindow New_Window = {
X#ifdef DEBUG
X        0, 0, 320, 150,                 /* smaller window to left printf's show up */
X#else
X        0, 1, 320, 199,                 /* Full screen */
X#endif
X        -1L, -1L,                               /* Default pens */
X        NULL,                           /* Window closes and gadgets */
X        ACTIVATE                        /* Standard window */
X        | SMART_REFRESH | NOCAREREFRESH | SIZEBBOTTOM
X        | WINDOWSIZING | WINDOWDEPTH | WINDOWCLOSE | WINDOWDRAG,
X        &Down_Gadget,                   /* Add my gadgets */
X        /*(struct Image *)*/ NULL,
X        (UBYTE *) "MandelVroom Help Window",  /* Title */
X        /*(struct Screen *)*/NULL,
X        /*(struct BitMap *)*/NULL,
X        100, 40,                        /* Minimum sizes */
X        -1, -1,                         /* Maximum sizes */
X        CUSTOMSCREEN
X        } ;
X
X/*
X * My very own variables (mostly for done)
X */
X       struct Window    *HelpWind = NULL ;
Xstatic FILE             *infile = NULL ;        /* Current input file */
Xstatic void             Page_File();
X       char             HelpOpen;
X
X/*
X * Finally, declare the string twiddling functions as voids
X */
Xvoid    strcat(), strcpy(), strncat();
X
XAllocArrows()
X{
X  extern USHORT *MakeChipSprite();
X
X  Arrow_Image[0].ImageData = MakeChipSprite( arrows[0], GHEIGHT );
X  Arrow_Image[1].ImageData = MakeChipSprite( arrows[1], GHEIGHT );
X}
X
XFreeArrows()
X{
X  USHORT *Temp;
X
X  Temp = Arrow_Image[0].ImageData;
X
X  if (Temp)
X    FreeMem( (char *) Temp, (long) sizeof(arrows[0]));
X  Arrow_Image[0].ImageData = NULL;
X
X  Temp = Arrow_Image[1].ImageData;
X
X  if (Temp)
X    FreeMem( (char *) Temp, (long) sizeof(arrows[0]));
X  Arrow_Image[1].ImageData = NULL;
X}
X
X/*
X * Display_File - given a directory path and file name, put the first page of
X *      the file in the window.
X */
X
Xlong aprox_lines, file_size;
Xlong Page_Length = 22L;
X
Xstatic int old_off, new_off;
X
Xstatic
XDisplay_File(dir, name)
Xchar *dir, *name;
X{
X  static char     File_Name[LONGEST_NAME];
X  FILE *fopen();
X  long ftell();
X  long i;
X
X  if (HelpWind == NULL)
X    return;
X
X  old_off = -1;
X
X  /* Get the file name */
X  strcpy(File_Name, dir);
X  strcat(File_Name, name);
X
X  if (infile != NULL)
X    fclose(infile);
X
X  if ((infile = fopen(File_Name, "r")) == NULL) {
X    CloseHelpWind(20, "can't open file") ;
X    return;
X  }
X
X  /* set up the prop gadget for scrolling */
X  fseek(infile, 0L, 2);
X  file_size = ftell(infile);
X  aprox_lines = file_size / AVG_LINE_LENGTH;
X  prop.Flags = FREEVERT | AUTOKNOB;
X  if (Page_Length >= aprox_lines)
X    i = 0xAAAA; /* guess 66% for small files */
X  else
X    i = (Page_Length * 0x10000) / aprox_lines; /* FFFF=100% - 0000=0% */
X
X  prop.VertBody = i;
X  prop.VertPot = 0;       /* always start at begin of file */
X  fseek(infile, 0L, 0);
X
X  Page_File(HELPUP);         /* Down from page 0 */
X}
X
X/*
X * Page_File - move the file up or down one "page"
X */
Xvoid
XPage_File(direction)
Xint direction;
X{
X  register long where;
X  static char     buffer[LONGEST_LINE];
X  static char edited[84]; /* allow room for a tab at end */
X  int end_flag = 0;
X  long tabs, size, Line_Length;
X  int i,j;
X  long new_pos;
X  char *p;
X
X  register struct Window *Window;
X
X  Window = HelpWind;
X
X  if (infile == NULL) return ;
X
X  Page_Length = (Window -> Height - 20) / 8 ;
X  Line_Length = (Window -> Width - (3+FIRST)) / 8;
X
X  switch (direction) {
X
X   case HELPUP:         /* Seek back one page */
X        if (ftell(infile) < AVG_LINE_LENGTH * (Page_Length + 2))
X          fseek(infile, 0L, 0);
X        else {
X          fseek(infile, (long) -Page_Length * AVG_LINE_LENGTH, 1) ;
X          fgets(buffer, LONGEST_LINE, infile) ;
X        }
X        break;
X
X   case HELPDOWN:
X        break;
X
X   case HELPSCROLL:
X        /* compute new position based on the users scroll bar pot */
X        new_pos = (file_size * prop.VertPot) / 0x10000;
X
X        /* if at end of file, back up 1/2 page */
X        if (new_pos >= file_size)
X          new_pos = file_size - ((Page_Length / 2) * AVG_LINE_LENGTH);
X          fseek(infile, new_pos, 0);
X
X          /* discard a partial line */
X          if (new_pos)
X            fgets(buffer, LONGEST_LINE, infile);
X        new_off = ftell(infile);
X
X        if (new_off == old_off)
X          return;
X
X        old_off = new_off;
X        break;
X
X   default:
X        CloseHelpWind(20, "Illegal argument to Page_File");
X        return;
X  }
X
X  SetAPen(Window->RPort, NORMALPEN);
X  SetDrMd(Window->RPort, JAM1);
X  RectFill(Window->RPort, GWIDTH, 10,
X                          Window->Width-2, Window->Height-10);
X  RectFill(Window->RPort, GWIDTH, Window->Height-10,
X                          Window->Width-12-(YScale*4),
X                          Window->Height);
X  BorderWindow( Window );
X
X  /* now put out one page's worth of the file's data */
X  for (where = 17, j = Page_Length; j--; where += 8) {
X
X    /* blank the buffer first */
X    for (i = 0; i < 80; i++)
X      edited[i] = ' ';
X
X    if (!end_flag) {
X
X      if (fgets(buffer, LONGEST_LINE, infile) == NULL)
X        end_flag = TRUE;
X      else {
X        size = strlen(buffer);
X
X        /* remove the newline */
X        buffer[size-1] = '\0';
X        size--;
X
X        p = buffer;
X        size = 0;
X
X        /* edit the buffer for tabs and non-printables */
X        while(*p) {
X
X          if (*p == '\t') {
X            do {
X              edited[size++] = ' ';
X            } while(size&3);
X          } else
X
X          if (*p < ' ') {
X            edited[size++] = '^';
X            edited[size++] = *p + '@';
X
X          } else
X            edited[size++] = *p;
X
X          p++;
X
X          /* mark the line as longer than the window */
X          if (size >= Line_Length) {
X            edited[size-1] = '>';
X            break;
X          }
X        }
X      }
X    }
X
X    SetAPen(Window->RPort, SHADOWPEN);
X    Move(Window -> RPort, FIRST+1, where+1) ;
X    Text(Window -> RPort, edited, Line_Length);
X
X    SetAPen(Window->RPort, HIGHLIGHTPEN);
X    Move(Window -> RPort, FIRST, where) ;
X    Text(Window -> RPort, edited, Line_Length);
X
X  } /* for 1 to size of window */
X}
X
XShowHelp( DirName, FileName )
X  char *DirName, *FileName;
X{
X  register struct IntuiMessage    *message;
X  register unsigned short         class, code ;
X
X  if (HelpWind == NULL) {
X
X    /* set up the scroll bar */
X    prop.Flags = FREEVERT | AUTOKNOB;
X    prop.VertBody = 0x1000;
X
X    New_Window.Screen = screen;
X
X    HelpWind = OpenMyWind(&New_Window,screen, NULL, 320, 200);
X
X    if (HelpWind == NULL){
X      CloseHelpWind(20, "can't open the window") ;
X      return;
X    }
X
X    if (HelpWind == NULL) return;
X
X    AddGList( HelpWind, &Down_Gadget, -1, -1);
X
X    RefreshGadgets( &Down_Gadget, HelpWind, NULL );
X  }
X
X  SetAPen(HelpWind->RPort, NORMALPEN);
X  SetDrMd(HelpWind->RPort, JAM1);
X  RectFill(HelpWind->RPort, GWIDTH, 10,
X                          HelpWind->Width-2, HelpWind->Height-10);
X  RectFill(HelpWind->RPort, GWIDTH, HelpWind->Height-10,
X                          HelpWind->Width-12-(YScale*4),
X                          HelpWind->Height);
X  BorderWindow( HelpWind );
X
X  Display_File(DirName, FileName) ;
X}
X
X/*
X * done - just close everything that's open, and exit.
X */
XCloseHelpWind(how, why)
Xint how;
Xchar *why;
X{
X  if (HelpWind) {
X    CloseMyWind(HelpWind, NULL) ;
X    HelpWind = NULL;
X
X    if (infile) {
X      fclose(infile) ;
X      infile = NULL;
X    }
X    if (why)
X      DispErrMsg(why,0);
X  }
X}
X
SHAR_EOF
echo "extracting standard.h"
sed 's/^X//' << \SHAR_EOF > standard.h
X#include <exec/types.h>
X#include <exec/devices.h>
X#include <intuition/intuition.h>
X
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#ifdef MANX
X#include <functions.h>
X#endif
SHAR_EOF
echo "extracting status.c"
sed 's/^X//' << \SHAR_EOF > status.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 to open, display and close the
X * statistics window.
X */
X
X#include "mandp.h"
X
Xstruct Window *StatsWind;
X
XUBYTE StatsOpen;
X
Xstatic
Xstruct NewWindow NewStats = {
X   0,200-100,                /* start position           */
X   90,120,                   /* width, height            */
X   (UBYTE) 0, (UBYTE) 1,     /* detail pen, block pen    */
X   NULL,                     /* IDCMP flags */
X                             /* MandWind flags */
X   WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | SMART_REFRESH,
X   (struct Gadget *) NULL,   /* first gadget             */
X   (struct Image *) NULL,    /* user checkmark           */
X   (UBYTE *) "Statistics",   /* window title             */
X   (struct Screen *) NULL,   /* pointer to screen        */
X   (struct BitMap *) NULL,   /* pointer to superbitmap   */
X   80,80,80,80,              /* sizing                   */
X   CUSTOMSCREEN              /* type of screen           */
X};
X
Xstatic
XUBYTE StartString[80], EndString[80], GapString[80], SizeString[80];
Xstatic
XUBYTE MagString[30];
X
Xstatic
Xstruct IntuiText MagIntui = {
X  1, 0, JAM1, 8, 52, NULL,
X  (UBYTE *) MagString, NULL
X};
X
Xstatic
Xstruct IntuiText SizeIntui = {
X  1, 0, JAM1, 8, 44, NULL,
X  (UBYTE *) SizeString, &MagIntui
X};
X
Xstatic
Xstruct IntuiText GapIntui = {
X  1, 0, JAM1, 8, 36, NULL,
X  (UBYTE *) GapString, &SizeIntui
X};
X
Xstatic
Xstruct IntuiText EndIntui = {
X  1, 0, JAM1, 8, 28, NULL,
X  (UBYTE *) EndString, &GapIntui
X};
X
Xstatic
Xstruct IntuiText StartIntui = {
X  1, 0, JAM1, 8, 20, NULL,
X  (UBYTE *) StartString, &EndIntui
X};
X
Xstatic
Xstruct IntuiText RealIntui = {
X  1, 0, JAM1, 8, 12, NULL,
X  (UBYTE *) "      Real            Imag", &StartIntui
X};
X
X/*
X * Open the statistics window
X */
XOpenStatsWind( Pict )
X  struct Picture *Pict;
X{
X  struct Window *OpenMyWind();
X
X  if (StatsWind == (struct Window *) NULL) {
X
X    StatsWind = OpenMyWind( &NewStats, screen, NULL, 320, 80);
X
X  } else {
X    WindowToFront( StatsWind );
X  }
X  ShowStats( Pict );
X  StatsOpen = 1;
X} /* OpenStatsWind */
X
X/*
X * Close the statistics window
X */
XCloseStatsWind()
X{
X  if (StatsWind != (struct Window *) NULL) {
X    CloseMyWind( StatsWind, NULL);
X    StatsWind = (struct Window *) NULL;
X  }
X} /* CloseStatsWind */
X
XShowStats( Pict )
X  register struct Picture *Pict;
X{
X  register LONG  Mag;
X
X  if (StatsWind) {
X
X    ClearWindow( StatsWind, 0);
X
X    Mag = (LONG) 4.0 / (Pict->ImagHigh - Pict->ImagLow);
X
X    sprintf( StartString, "Start %15.12f %15.12f", Pict->RealLow,  Pict->ImagLow );
X    sprintf( EndString,   "End   %15.12f %15.12f", Pict->RealHigh, Pict->ImagHigh );
X    sprintf( GapString,   "Gap   %15.12f %15.12f", Pict->RealGap,  Pict->ImagGap );
X    sprintf( SizeString,  "Size  %15d %15d", Pict->CountX,   Pict->CountY );
X    sprintf( MagString,   "Mag   %15d", Mag );
X
X    PrintIText( StatsWind->RPort, &RealIntui, 0, 0 );
X  }
X}
X
XClearWindow( Window, pen )
X  register struct Window *Window;
X  int pen;
X{
X  register struct RastPort *RPort;
X  register LONG bot, right;
X
X  RPort = Window->RPort;
X
X  SetAPen( RPort, (long) pen);
X
X  bot   = Window->Height - Window->BorderBottom;
X  right = Window->Width - Window->BorderRight;
X
X  RectFill( RPort, Window->BorderLeft-1, Window->BorderTop-1, right, bot );
X}
X
X
SHAR_EOF
echo "extracting tasks.c"
sed 's/^X//' << \SHAR_EOF > tasks.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 used to manage tasks used by
X * MandelVroom for picture generation and picture recoloring.
X */
X
X#include "mandp.h"
X
XLONG MainPri =  0;
XLONG TaskPri = -1;
X
XLONG pSigMask, pSigBit;
X
XPauseChild( Pict )
X  register struct Picture *Pict;
X{
X  if (Pict->gTask) {
X
X    if (Pict->GenState == GENERATESTATE) {
X
X      SetTaskPri( Pict->gTask, MainPri );
X
X      Pict->GenState = PAUSESTATE;
X
X      Wait( pSigMask );
X
X      SetTaskPri( Pict->gTask, TaskPri );
X    }
X  }
X}
X
XChildSignal( Pict )
X  register struct Picture *Pict;
X{
X#ifdef MULTI
X  if ( Pict->GenState == PAUSESTATE ) {
X    Signal( mTask, pSigMask );
X    Wait( Pict->gSigMask );
X  }
X#endif
X}
X
XAwakenChild( Pict )
X  register struct Picture *Pict;
X{
X  if (Pict->gTask) {
X    if (Pict->GenState == PAUSESTATE) {
X
X      Pict->GenState = GENERATESTATE;
X
X      Signal( Pict->gTask, Pict->gSigMask );
X
X      if (Pict->gTask->tc_State == TS_WAIT) {
X        printf("Child still waiting\n");
X      }
X    }
X  }
X}
X
XCheckEOL( Pict )
X  register struct Picture *Pict;
X{
X  ChildPause( Pict );
X
X  ReColorLine( Pict );
X
X  Pict->CurLine++;
X}
X
XKillDoneChild( Pict )
X  register struct Picture *Pict;
X{
X  if (Pict->gTask) {
X
X    SetTaskPri( Pict->gTask, MainPri );
X
X    Pict->GenState = KILLSTATE;   /* Child is spinning waiting for this */
X    Wait( pSigMask );      /* wait till child says it notices this */
X
X    DeleteTask(Pict->gTask);
X    Pict->gTask = NULL;
X  }
X}
X
XGetTaskSig( Pict )
X  register struct Picture *Pict;
X{
X  register LONG bit;
X
X  Pict->gSigBit = bit = AllocSignal( (long) -1 );
X
X  if ( bit == -1 )
X    return( UNSUCCESSFUL );
X
X  Pict->gSigMask = 1 << bit;
X
X  return( SUCCESSFUL );
X}
X
Xint
XOpenTasks()
X{
X  mTask = FindTask( NULL );
X
X  mSigBit = AllocSignal( (long) -1 );
X
X  if ( mSigBit == -1 ) {
X    return (-1);
X  }
X
X  mSigMask = 1 << mSigBit;
X
X  pSigBit = AllocSignal( (long) -1 );
X
X  if ( pSigBit == -1 ) {
X
X    FreeSignal( mSigBit );
X    return (-1);
X  }
X
X  pSigMask = 1 << pSigBit;
X
X  return( 0 );
X}
X
XCloseTasks()
X{
X  FreeSignal( mSigBit );
X  FreeSignal( pSigBit );
X}
X
X/* This is called by main task */
X
XThrowTask( Pict )
X  register struct Picture *Pict;
X{
X  register struct Task *gTask = Pict->gTask;
X
X  if (gTask) {
X
X    PauseChild( Pict );
X    DeleteTask( gTask );
X    Pict->gTask = NULL;
X
X    SetGenGad( Pict );
X  }
X}
X
XCloseZoomedPicts( Pict )
X  register struct Picture *Pict;
X{
X  register struct Node    *zNode;
X  register struct Picture *ZoomPict;
X
X  struct Picture *PictAddr();
X
X  zNode = Pict->zList.lh_Head;
X
X  while ( zNode = RemHead( &Pict->zList ) ) {
X
X    ZoomPict = PictAddr( zNode );
X
X    CloseZoomBox(ZoomPict);
X  }
X}
X
X/* Calculate pointer to the beginning of Picture struct */
X
Xstruct Picture *
XPictAddr( zNodeAddr )
X  register struct Node *zNodeAddr;
X{
X  register char *ZoomPict;
X
X  ZoomPict = (char *) zNodeAddr;
X
X  ZoomPict -= ((char *) &CurPict->zNode - (char *) &CurPict->pNode);
X
X  return( (struct Picture *) ZoomPict );
X}
X
XPauseReColor( Pict )
X  register struct Picture *Pict;
X{
X  if (Pict->gTask) {
X
X    if (Pict->ColorState == GENERATESTATE) {
X
X      Pict->ColorState = PAUSESTATE;
X
X      (void) Wait( pSigMask );
X    }
X  }
X}
X
XReColorPause( Pict )
X  register struct Picture *Pict;
X{
X  if ( Pict->ColorState == PAUSESTATE ) {
X
X    Signal( mTask, pSigMask );
X    (void) Wait( 0L );
X  }
X}
SHAR_EOF
echo "End of archive 9 (of 9)"
# if you want to concatenate archives, remove anything after this line
exit