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

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

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

# 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:
#	gadgets.c
#	getfile.c
#	getfile.h
#	getint.c
#	help.c
#	hist.c
#	iffw.c
# This is archive 3 of a 9-part kit.
# This archive created: Tue Jun 20 20:45:27 1989
echo "extracting gadgets.c"
sed 's/^X//' << \SHAR_EOF > gadgets.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 tools to allocate and free gadgets and
X * gadget imagery for MandelVroom.
X */
X
X#include "mandp.h"
X
X#define TOP 1
X#define BOT 2
X
X/*************************************************************************
X *
X * Allocate and ititialize gadget tools
X *
X ************************************************************************/
X
X/*
X * Make a generic boolean gadget
X */
Xstruct Gadget *MakeBool(x,y,xd,yd,c,id, flags)
X  SHORT  x,y,xd,yd;
X  UBYTE  c;
X  USHORT id;
X  USHORT flags;
X{
X  register struct Gadget *NewGadget;
X  register struct Image  *NewImage,*ShadowImage;
X
X  NewGadget = (struct Gadget *)
X    safeAllocMem( (ULONG) sizeof(struct Gadget), (LONG) MEMF_CLEAR );
X
X  if (NewGadget == NULL) return( NewGadget );
X
X  if ( flags & GADGIMAGE ) {
X
X    NewImage = (struct Image *)
X      safeAllocMem( (ULONG) sizeof(struct Image), (LONG) MEMF_CLEAR );
X
X    if ( NewImage == NULL ) {
X      FreeMem( (char *) NewGadget, (LONG) sizeof(struct Gadget));
X      return( NULL );
X    }
X
X    ShadowImage = (struct Image *)
X      safeAllocMem( (ULONG) sizeof(struct Image), (LONG) MEMF_CLEAR );
X
X    if ( ShadowImage == NULL ) {
X      FreeImage( NewImage );
X      FreeMem( (char *) NewGadget, (LONG) sizeof(struct Gadget));
X      return( NULL );
X    }
X
X    NewImage->Width = xd;
X    NewImage->Height = yd;
X    NewImage->PlaneOnOff = c;
X
X    ShadowImage->LeftEdge = 1 + XScale;
X    ShadowImage->TopEdge = 1 + YScale;
X    ShadowImage->Width = xd;
X    ShadowImage->Height = yd;
X    ShadowImage->PlaneOnOff = SHADOWPEN;
X    ShadowImage->NextImage = NewImage;
X
X    NewGadget->GadgetRender = (APTR) ShadowImage;
X
X  } else {
X
X    NewGadget->GadgetRender = (APTR)
X                              ShadowBorder( BEVELEDUP, 1, 1, xd-1, yd-1 );
X  }
X
X  NewGadget->LeftEdge = x;
X  NewGadget->TopEdge  = y;
X  NewGadget->Width    = xd;
X  NewGadget->Height   = yd;
X  NewGadget->Flags    = GADGHCOMP | flags;
X  NewGadget->Activation = GADGIMMEDIATE;
X  NewGadget->GadgetType = BOOLGADGET;
X  NewGadget->GadgetID = id;
X
X  return(NewGadget);
X} /* MakeBool */
X
X/*
X * Make a generic potentiometer gadget
X */
Xstruct Gadget *MakePot(x, y, xd, yd, id, cnt)
X  SHORT  x,y,xd,yd;
X  USHORT id;
X  USHORT cnt;
X{
X  register struct Gadget   *NewGadget;
X  register struct Image    *NewImage;
X  register struct PropInfo *NewInfo;
X
X  NewGadget = (struct Gadget *)
X    safeAllocMem( (ULONG) sizeof(struct Gadget), MEMF_CLEAR );
X
X  if (NewGadget == NULL) goto nogadget;
X
X  NewImage = (struct Image *)
X    safeAllocMem( (ULONG) sizeof(struct Image), MEMF_CLEAR );
X
X  if (NewImage == NULL) goto noimage;
X
X  NewInfo = (struct PropInfo *)
X    safeAllocMem( (ULONG) sizeof(struct PropInfo), MEMF_CLEAR );
X
X  if (NewInfo == NULL) goto noinfo;
X
X  NewGadget->LeftEdge = x;
X  NewGadget->TopEdge  = y;
X  NewGadget->Width    = xd;
X  NewGadget->Height   = yd;
X  NewGadget->Flags    = GADGHIMAGE | GADGIMAGE;
X  NewGadget->Activation   = RELVERIFY;
X  NewGadget->GadgetType   = PROPGADGET;
X  NewGadget->GadgetRender = (APTR) NewImage;
X  NewGadget->SpecialInfo  = (APTR) NewInfo;
X  NewGadget->GadgetID     = id;
X
X  NewImage->PlaneOnOff = SHADOWPEN;
X  NewImage->Width  = 4 << XScale;
X  NewImage->Height = 3 << YScale;
X
X  NewInfo->Flags = PROPBORDERLESS | FREEVERT;
X  NewInfo->VertBody = 1;
X
X  return(NewGadget);
X
Xnoinfo:
X  FreeMem( (char *) NewImage,  (LONG) sizeof(struct Image));
X
Xnoimage:
X  FreeMem( (char *) NewGadget, (LONG) sizeof(struct Gadget));
X
Xnogadget:
X  return( NULL );
X} /* MakePot */
X
X/*
X * Make a generic string gadget
X */
Xstruct Gadget *MakeString( x, y, length, id, String )
X  SHORT  x,y,length;
X  USHORT id;
X  char *String;
X{
X  register struct Gadget     *NewGadget;
X  register struct StringInfo *NewString;
X  register struct Border     *Border;
X
X  register char *NewBuffer;
X
X  NewGadget = (struct Gadget *)
X    safeAllocMem( (ULONG) sizeof(struct Gadget), (LONG) MEMF_CLEAR );
X
X  if ( NewGadget == NULL ) goto nogadget;
X
X  NewString = (struct StringInfo *)
X    safeAllocMem( (ULONG) sizeof(struct StringInfo), (LONG) MEMF_CLEAR );
X
X  if (NewString == NULL) goto nostring;
X
X  NewBuffer = (char *) safeAllocMem( (ULONG) length + 1, (LONG) MEMF_CLEAR );
X
X  if (NewBuffer == NULL) goto nobuffer;
X
X  Border = ShadowBorder( BEVELEDDOWN, -1, -1, length * 8 + 1, 9 );
X
X  NewGadget->LeftEdge = x;
X  NewGadget->TopEdge  = y;
X  NewGadget->Width    = length * 8;
X  NewGadget->Height   = 8;
X  NewGadget->Flags    = GADGHCOMP;
X  NewGadget->Activation = STRINGRIGHT;
X  NewGadget->GadgetType = STRGADGET;
X  NewGadget->GadgetID = id;
X  NewGadget->GadgetRender = (APTR) Border;
X  NewGadget->SpecialInfo  = (APTR) NewString;
X
X  NewString->MaxChars = length + 1;
X  NewString->BufferPos = 0;
X  NewString->DispPos = 0;
X  NewString->Buffer = (UBYTE *) NewBuffer;
X
X  strcpy( NewBuffer, String );
X
X  return(NewGadget);
X
Xnobuffer:
X
X  FreeMem( (char *) NewString, (long) sizeof( struct StringInfo ) );
X
Xnostring:
X
X  FreeMem( (char *) NewGadget, (long) sizeof( struct Gadget ) );
X
Xnogadget:
X
X  return( NULL );
X
X} /* MakeString */
X
X/*
X * Free a string of gadgets
X */
XFreeGadgets(FirstGadget)
X  struct Gadget *FirstGadget;
X{
X  register struct Gadget *NextGadget;
X  register struct StringInfo *String;
X  register struct Border *Render;
X
X  while (FirstGadget) {
X
X    Render = (struct Border *) FirstGadget->GadgetRender;
X
X    if ( Render ) {
X      if (FirstGadget->Flags & GADGIMAGE) {
X
X        FreeImage( (struct Inage *) Render );
X      } else {
X
X        FreeBorder( Render );
X      }
X    }
X
X    Render = (struct Border *) FirstGadget->SelectRender;
X
X    if ( Render ) {
X      if (FirstGadget->Flags & GADGIMAGE) {
X
X        FreeImage( (struct Inage *) Render );
X      } else {
X
X        FreeBorder( Render );
X      }
X    }
X
X    if (FirstGadget->SpecialInfo) {
X
X      switch( FirstGadget->GadgetType ) {
X
X        case PROPGADGET:
X             FreeMem( (char *) FirstGadget->SpecialInfo,
X                      (LONG) sizeof(struct PropInfo));
X             break;
X
X        case STRGADGET:
X             String = (struct StringInfo *) FirstGadget->SpecialInfo;
X             FreeMem( (char *) String->Buffer, (LONG) String->MaxChars );
X             FreeMem( (char *) String, (LONG) sizeof(struct StringInfo));
X
X             break;
X      }
X    }
X
X    FreeIntui( FirstGadget->GadgetText );
X
X    NextGadget = FirstGadget->NextGadget;
X
X    FreeMem( (char *) FirstGadget, (LONG) sizeof(struct Gadget));
X
X    FirstGadget = NextGadget;
X  }
X} /* FreeGadgets */
X
XFreeImage( Image )
X  struct Image *Image;
X{
X  register struct Image *image, *next;
X
X  next = Image;
X
X  while ( image = next ) {
X
X    next = image->NextImage;
X
X    FreeMem( (char *) image, (LONG) sizeof(struct Image));
X  }
X}
X
Xstruct Border *
XMakeShadow( pen, numverts )
X  LONG pen;
X  int numverts;
X{
X  register struct Border *NewBorder;
X  register SHORT *NewCounts;
X
X  NewBorder = (struct Border *)
X    safeAllocMem( (ULONG) sizeof(struct Border), (LONG) MEMF_CLEAR );
X
X  if (NewBorder == NULL) return( NULL );
X
X  NewCounts = (SHORT *)
X    safeAllocMem( (ULONG) sizeof(SHORT) * 2 * numverts, (LONG) MEMF_CLEAR );
X
X  if (NewCounts == NULL) {
X    FreeMem( (char *) NewBorder, (LONG) sizeof(struct Border) );
X    return( NULL );
X  }
X
X  NewBorder->FrontPen = pen;
X  NewBorder->DrawMode = JAM1;
X  NewBorder->XY       = NewCounts;
X  NewBorder->Count    = numverts;
X
X  return( NewBorder );
X}
X
X/*
X * Make an Border structure
X */
Xstatic struct Border *
XMakeCornerShadow( Type, left, top, Width, Height, pen )
X
X           LONG Type;
X  register LONG left,  top;
X           LONG Width, Height;
X           LONG pen;
X{
X  register struct Border *NewBorder;
X  register SHORT *NewCounts;
X
X  register LONG right = left + Width;
X  register LONG bot   = top + Height;
X           LONG cornerx;
X           LONG cornery;
X           LONG direction;
X
X#define NUMVERTS 6
X
X  NewBorder = MakeShadow( pen, NUMVERTS );
X
X  if (NewBorder == NULL) return( NewBorder );
X
X  if ( Type == TOP ) {
X    cornerx = left;  cornery = top; direction = -1;
X  } else {
X    cornerx = right; cornery = bot; direction =  1;
X  }
X
X  NewCounts = NewBorder->XY;
X
X  *NewCounts++ = left;    *NewCounts++ = bot;
X  *NewCounts++ = cornerx; *NewCounts++ = cornery;
X  *NewCounts++ = right;   *NewCounts++ = top;
X
X  left--; top--; bot++; right++;
X  cornerx += direction; cornery += direction;
X
X  *NewCounts++ = right;   *NewCounts++ = top;
X  *NewCounts++ = cornerx; *NewCounts++ = cornery;
X  *NewCounts++ = left;    *NewCounts++ = bot;
X
X  return( NewBorder );
X} /* MakeCornerShadow */
X
Xstruct Border *
XShadowBorder( Type, left, top, xdim, ydim )
X  int Type;
X  int left, top;
X  int xdim, ydim;
X{
X  register struct Border *Border1, *Border2;
X  register int            Pen1,     Pen2;
X
X  if (Type == BEVELEDUP) {
X    Pen1 = HIGHLIGHTPEN; Pen2 = SHADOWPEN;
X  } else {
X    Pen2 = HIGHLIGHTPEN; Pen1 = SHADOWPEN;
X  }
X
X  Border1 = MakeCornerShadow( (long) TOP,  (long) left, (long) top,
X                              (long) xdim, (long) ydim, (long) Pen1 );
X
X  if ( Border1 ) {
X
X    Border2 = MakeCornerShadow( (long) BOT,  (long) left, (long) top,
X                                (long) xdim, (long) ydim, (long) Pen2 );
X    Border1->NextBorder = Border2;
X  }
X
X  return( Border1 );
X}
X
XFreeBorder( Border )
X  struct Border *Border;
X{
X  register struct Border *border, *next;
X
X  next = Border;
X
X  while ( border = next ) {
X
X    next = border->NextBorder;
X
X    FreeMem( (char *) border->XY, (LONG) sizeof(SHORT) * border->Count * 2);
X    FreeMem( (char *) border,     (LONG) sizeof(struct Border));
X  }
X}
X
X
X
X/*
X * Make an IntuiText structure
X */
Xstruct IntuiText *MakeIntui(str, x, y, frontpen, backpen, drawmode )
X  char *str;
X  LONG  x, y;
X  LONG  frontpen, backpen;
X  LONG  drawmode;
X{
X  register struct IntuiText *NewIntui;
X  register char  *NewString;
X
X  NewIntui = (struct IntuiText *)
X    safeAllocMem( (ULONG) sizeof(struct IntuiText), (LONG) MEMF_CLEAR );
X
X  if ( NewIntui == NULL ) return( NULL );
X
X  NewString = (char *)
X    safeAllocMem( (ULONG) strlen( str ) + 1, (LONG) MEMF_CLEAR );
X
X  if ( NewString == NULL ) {
X    FreeMem( (char *) NewIntui, (long) sizeof(struct IntuiText) );
X    return( NULL );
X  }
X
X  NewIntui->FrontPen = frontpen;
X  NewIntui->BackPen  = backpen;
X  NewIntui->DrawMode = drawmode;
X  NewIntui->LeftEdge = x;
X  NewIntui->TopEdge  = y;
X  NewIntui->IText = (UBYTE *) NewString;
X
X  strcpy( NewString, str );
X
X  return(NewIntui);
X} /* MakeIntui */
X
Xstruct IntuiText *
XShadowIntui( str, x, y )
X  char *str;
X  LONG x,y;
X{
X  register struct IntuiText *Intui1, *Intui2, *Intui3;
X
X  Intui1 = MakeIntui( str,  x,     y,     NORMALPEN, NORMALPEN, JAM2 );
X  Intui2 = MakeIntui( str,  x + 1, y + 1, SHADOWPEN, NORMALPEN, JAM2 );
X  Intui3 = MakeIntui( str,  x,     y,     MEDIUMPEN, (long) 0,  JAM1 );
X
X  Intui1->NextText = Intui2;
X  Intui2->NextText = Intui3;
X
X  return( Intui1 );
X}
X
XFreeIntui( Intui )
X  struct IntuiText *Intui;
X{
X  register struct IntuiText *intui, *next;
X
X  next = Intui;
X
X  while ( intui = next ) {
X
X    next = intui->NextText;
X
X    FreeMem( (char *) intui->IText, (long) strlen((char *)intui->IText) + 1);
X    FreeMem( (char *) intui, (LONG) sizeof(struct IntuiText));
X  }
X}
X
X#if 0
Xstruct Border *
XMakeWindowBorder( NewWindow )
X  register struct NewWindow *NewWindow;
X{
X  register struct Border *Border1,*Border2;
X  register SHORT  *Verts;
X  register SHORT  Bottom, Right;
X
X  Border1 = MakeShadow( HIGHLIGHTPEN, 2 );
X
X  if (Border1 == NULL)
X    return NULL;
X
X  Border2 = MakeShadow( SHADOWPEN, 3 );
X
X  if (Border2 == NULL) {
X    FreeBorder( Border1 );
X    return NULL;
X  }
X
X  Bottom = NewWindow->Height - 1;
X  Right  = NewWindow->Width  - 1;
X
X  Verts = Border1->XY;
X
X  /* Vertex.X        Vertext.Y */
X
X  *Verts++ = 0;     *Verts++ = TOPMARG;
X  *Verts++ = 0;     *Verts++ = Bottom;
X
X  Verts = Border2->XY;
X
X  /* Vertex.X        Vertext.Y */
X
X  *Verts++ = 0;     *Verts++ = Bottom;
X  *Verts++ = Right; *Verts++ = Bottom;
X  *Verts++ = Right; *Verts++ = TOPMARG - 1;
X
X  Border1->NextBorder = Border2;
X
X  return( Border1 );
X}
X#endif
SHAR_EOF
echo "extracting getfile.c"
sed 's/^X//' << \SHAR_EOF > getfile.c
X/************************************************************************
Xreq.c
X        This file contains a general-purpose <requester> that
Xwill prompt the user for a filename input.
X        The program actually uses a window instead of a 'Requester'
Xfor greater flexibility. It will take control of your window's
XIDCMP Port when called.
X
X***     This material is copyright (c) 1986 by C. Heath of Microsmiths, Inc.
XPermission is granted to use these files in any way with the following
Xexceptions:
X
X1) The files shall not be posted on any telecommunications service, public
Xor private, except for BIX until January 15, 1987.
X
X2) The files may only be distributed in archive format, with no modifications.
XIf you make any improvements on the file requester and would like to
Xgenerally distribute them, please contact "cheath" on BIX, or write to:
X        Microsmiths Inc, PO Box 561, Cambridge, MA 02140
X
X3) The requester may be used in any commercial product, but must be in
Xobject code format.  You are free to make modifications for use in your
Xproduct.  Permission is granted to Lattice, Inc, and to Manx, Inc, to
Xinclude the source files in archive format.
X
X        Thank you, and enjoy.
X                ...cheath
X
X************************************************************************/
X
X#include "standard.h"
X#include "safeclose.h"
X
X#define FAST register
X#define NL NULL
X
Xextern char *dmore(), *dinit();
X
Xstatic struct FileLock      *pdir = NL;
Xstatic struct FileInfoBlock *dir_info;
X
Xstatic struct Window   *eW;             /* Parent Window. Uck   */
X
Xstatic struct TextAttr MyFont = {"topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT };
X
X/* FGAD requires a few unique gadget-ids, origined at FGAD      */
X/* In the unlikely event this conflicts with any of your gadgets, */
X/* change this equate to allow 16 contiguous unique ID's        */
X
X#define FGAD    0x76c0L
X
X#define FCHARS  32L     /* Number of chars allowed in file name */
X
X#define DIR_SIZ 50L     /* Number of chars in a dir name...     */
X#define MAX_STR DIR_SIZ+2L
X
X#define DENTS   5L              /* Number of entries on screen   */
X/* It's not as simple as changing 'DENTS'...      */
X
X#define DSIZE   FCHARS+1L       /* Size of a directory entry   */
X
X#define DBUFSIZ 3000L   /* Number of bytes to allocate for all ents */
X
X#define BCOL    1L      /* Background color     */
X#define FCOL    2L      /* Foreground color     */
X
X#define RHGHT   120L
X#define RWDTH   320L
X
X#define ZWDTH   270L
X
Xstatic char     ubuf[MAX_STR];          /* Undo buffer  */
X
Xstatic struct dirent { struct dirent *next; BOOL isfile; char dE[DSIZE+2]; };
Xstatic struct dirent *FirstEntry;
Xstatic struct dirent *NextEntry;
X
Xstatic struct dirhead { struct dirent *next; };
Xstatic struct dirhead ListHead;
X
Xstatic long   curent,maxent;
Xstatic BOOL   more;
X
Xstatic struct Window    *wRq = NL;              /* Requester window   */
Xstatic struct RastPort  *wRp;
X
X/* Requester "Hailing" prompt */
Xstatic struct IntuiText oTxt = {2,2,JAM1,10,11,NL, NL ,NL};
X
Xstatic struct IntuiText saydir = {0,1,JAM2,0,1,&MyFont,(UBYTE *)"(dir) ",NL};
X
Xstatic struct IntuiText rname[DENTS] = { /* File name list */
X   {2,1,JAM2,48,1,NL,NL, NL},
X   {2,1,JAM2,48,1,NL,NL, NL},
X   {2,1,JAM2,48,1,NL,NL, NL},
X   {2,1,JAM2,48,1,NL,NL, NL},
X   {2,1,JAM2,48,1,NL,NL, NL} };
X
X/* Display for file name ... */
X
Xstatic SHORT oXY2[] = {-2,-2, RWDTH-78,-2, RWDTH-78,9, -2,9, -2,-2};
Xstatic struct Border thebd = {0,0, 2,3,JAM1, 5,oXY2, NL};
X
Xstatic struct IntuiText otxt = {2,2,JAM1,-40,0,&MyFont,(UBYTE *)"file",NL};
Xstatic struct StringInfo osx = { NL ,ubuf, NL,DSIZE,NL,NL,NL,NL,NL,NL,NL,NL,NL};
Xstatic struct Gadget ogx = { NL, 60,RHGHT-35,RWDTH-80 ,10,     /* File name gadget */
X   GADGHCOMP, RELVERIFY , STRGADGET,
X   (APTR)&thebd,NL,&otxt,NL,(APTR)&osx, FGAD+11,NL };
X
Xstatic struct Gadget oga = { &ogx, 10,70, ZWDTH,10,   /* Gadgets For   */
X   GADGHCOMP, RELVERIFY, BOOLGADGET,     /* Directory entries   */
X   NL,NL, &rname[4] ,NL,NL, FGAD+10,NL };
Xstatic struct Gadget og9 = {&oga, 10,60, ZWDTH,10,
X   GADGHCOMP, RELVERIFY, BOOLGADGET,
X   NL,NL, &rname[3] ,NL,NL, FGAD+9,NL };
Xstruct Gadget og8 = {&og9, 10,50, ZWDTH,10,
X   GADGHCOMP, RELVERIFY, BOOLGADGET,
X   NL,NL, &rname[2] ,NL,NL, FGAD+8,NL };
Xstatic struct Gadget og7 = {&og8, 10,40, ZWDTH,10,
X   GADGHCOMP, RELVERIFY, BOOLGADGET,
X   NL,NL, &rname[1] ,NL,NL, FGAD+7,NL };
Xstatic struct Gadget og6 = {&og7, 10,30, ZWDTH,10,
X   GADGHCOMP, RELVERIFY, BOOLGADGET,
X   NL,NL, &rname[0] ,NL,NL, FGAD+6,NL };
X
X
X/* Gadjets for requester  */
X
Xstatic SHORT oXY3[] = {0,0, 50,0, 50,9, 0,9, 0,0};
Xstatic SHORT oXY4[] = {2,-2, 48,-2, 52,2, 52,7, 48,11, 2,11, -2,7, -2,2, 2,-2};
Xstatic struct Border obd2 = {0,0, 2,3,JAM1, 9,oXY4, NL};
Xstatic struct Border obd1 = {0,0, 3,2,JAM1, 5,oXY3, &obd2};  /* OTAY / CANCEL box */
X
Xstatic struct IntuiText ot1  = {0,0,JAM1,1,1,&MyFont,(UBYTE *)"  OK  ",NL};
Xstatic struct IntuiText ot2  = {0,0,JAM1,1,1,&MyFont,(UBYTE *)"Cancel",NL};
Xstatic struct IntuiText ot25 = {0,0,JAM1,1,1,&MyFont,(UBYTE *)"Device",NL};
X
Xstatic struct IntuiText dtxt = {2,2,JAM1,-60,0,NL,(UBYTE *)"drawer",NL};
Xstatic struct StringInfo os5 = { NL ,ubuf, NL,DIR_SIZ,NL,NL,NL,NL,NL,NL,NL,NL,NL};
Xstatic struct Gadget og5 = { &og6, RWDTH/2-80,19,190,10,     /* Directory */
X   GADGHCOMP, RELVERIFY, STRGADGET,
X   NL,NL,&dtxt,NL,(APTR)&os5, FGAD+5,NL };
X
Xstatic struct Image   cc_img;
Xstatic struct PropInfo   cc_prop = {AUTOKNOB | FREEVERT, 0,0, 0,0x1000,0,0,0,0,0,0 };
Xstatic struct Gadget og3 = { &og5,RWDTH-39,20,20,60,      /* Scroll Bar   */
X    GADGHCOMP,GADGIMMEDIATE | FOLLOWMOUSE, PROPGADGET,
X    (APTR)&cc_img,NL,NL,NL,(APTR)&cc_prop,FGAD+3,NL };
X
Xstatic struct Gadget og25 = { &og3, RWDTH-70,RHGHT-20, 50,10,  /* CANCEL */
X   GADGHCOMP,  RELVERIFY, BOOLGADGET,
X   (APTR)&obd1,NL, &ot2,NL,NL, FGAD+2,NL };
X
Xstatic struct Gadget og2 = { &og25, 136,RHGHT-20, 50,10,  /* DEVS */
X   GADGHCOMP,  RELVERIFY, BOOLGADGET,
X   (APTR)&obd1,NL, &ot25,NL,NL, FGAD+20,NL };
X
Xstatic struct Gadget og1 = { &og2, 20,RHGHT-20, 50,10,      /* OTAY   */
X   GADGHCOMP,           /* Flags        */
X   RELVERIFY,           /* Activation   */
X   BOOLGADGET,
X   (APTR)&obd1,NL,      /* GadgetRender, SelectRender   */
X   &ot1,NL,NL,          /* IntuiText, MutualExclude,SpecialInfo   */
X   FGAD+1,NL };         /* Gadget Id, UserData  */
X
X/* Open a requester "Window" */
X
Xstatic struct NewWindow NewFiles = {
X   0, 0, RWDTH,RHGHT, BCOL,FCOL, NL, /* Fill in AFTER opening ... */
X   SMART_REFRESH | ACTIVATE | RMBTRAP | WINDOWDRAG,
X   &og1,NL,NL, NL,
X   NL, RWDTH,RHGHT,RWDTH,RHGHT, CUSTOMSCREEN };
X
XIMPORT struct Library   *IntuitionBase;
X
X/***************************************************
X*  get_fname(window,screen,hail,ddef,ddir);
X*
X*   Displays a window/requester that
X* gets a file name for device,directory,default file, extension
X*
X*   Calling args:
X* window:   Window making the request
X* screen:   Screen, if NULL assummed workbench
X* hail:   Text prompt at top of requester
X* ddef:   Input default file-name. Has NO DIRECTORY OR EXTENSION.
X* ddir:   Directory of file, may be null
X
X/* Set a file-requester with prompt 'hail'   */
X
Xchar *get_fname(cW,screen,hail,ddef,ddir)
X   struct Window *cW;           /* Calling Window   */
X   struct Screen *screen;       /* screen .... if null assumed workbench */
X   UBYTE        *hail;          /* Hailing prompt   */
X   char         *ddef;          /* Proable file-name   */
X   char         *ddir;          /* Directory in which to search   */
X   {
X   FAST struct IntuiMessage *imes;   /* Wait for message in HERE   */
X   FAST struct Gadget   *igad;   /* Get Gadjet Mumbo Jumbo   */
X   FAST long    i,class;
X   FAST TEXT    *pnam;
X
X   FAST char    *retval;
X   FAST BOOL    dir_flag;
X   FAST BOOL    keepon;
X
X   if ( ! (eW = cW) )   return(NL);
X
X   osx.Buffer = ddef;   /* Set default file name   */
X   os5.Buffer = ddir;   /* Set default device name   */
X
X   for ( i=0; i<DENTS; i++)
X      {
X      rname[i].IText = "";
X      rname[i].NextText = NL;
X      };
X
X   NewFiles.Title = eW->Title;
X   if ((dir_info = AllocMem((long)sizeof(struct FileInfoBlock),0L)) == NULL)
X      return(NL);
X
X   if (screen)          /* User supplied a screen */
X      {
X      NewFiles.Type = CUSTOMSCREEN;
X      NewFiles.Screen = screen;
X      }
X
X   if ( ! (FirstEntry = (struct dirent *)AllocMem((long)DBUFSIZ,0L)) ||
X        ! (wRq = (struct Window *)OpenWindow( &NewFiles )) )
X      {
X      if (!FirstEntry)
X        notify("Can't Open first entry");
X      if (!wRq)
X        notify("Can't Open new window");
X      if ( FirstEntry )   FreeMem(FirstEntry,(long)DBUFSIZ);
X      /* notify("Can't Open Requester..."); */
X      FreeMem(dir_info,(long)sizeof(struct FileInfoBlock));
X      return(NL);
X      }
X   /* Set up directory, notify any errors...   */
X   if ( pnam = (char *)dinit(ddir) )   notify(pnam);
X
X
X   /* This optional line will activate a string gadget  */
X   if ( IntuitionBase->lib_Version > 32 )
X        {
X        ActivateGadget(&ogx,wRq,0L);
X        }
X
X   wRp = wRq->RPort;
X
X   wRq->UserPort = eW->UserPort;
X   ModifyIDCMP(wRq,(long)(MOUSEBUTTONS | GADGETDOWN | GADGETUP | MOUSEMOVE));
X
X   SetAPen(wRp,1L);
X   RectFill(wRp,4L,10L,(long)(RWDTH-5),(long)(RHGHT-4));
X
X   oTxt.IText = hail;   /* Set calling arg   */
X   oTxt.LeftEdge = (RWDTH - IntuiTextLength(&oTxt)) >> 1L;
X   PrintIText(wRp,&oTxt,0L,0L);
X
X   RefreshGadgets(&og1,wRq,(long)NL);
X   for ( retval= NL, keepon=TRUE; keepon ; )
X      {
X      while ( ! (imes=(struct IntuiMessage *)GetMsg(wRq->UserPort)) )
X      {
X         if ( dir_flag )
X            {
X            i = (maxent-DENTS) * cc_prop.VertPot / MAXBODY;
X            if ( i > (maxent-DENTS) )
X            i = maxent-DENTS;
X            if ( i <0 )   i = 0;
X            curent = i;
X            cxxx();
X            dir_flag = FALSE;
X            }
X         if ( more )
X            {
X            if (pnam = (char *)dmore())   /* Continue to read the directory */
X               notify(pnam);      /* Yucko error   */
X            if ( maxent <= DENTS ) dir_flag = TRUE;
X            }
X         else    WaitPort(wRq->UserPort);
X         }
X      igad = (struct Gadget *)imes->IAddress;
X      class = imes->Class;
X      ReplyMsg(imes);
X
X      switch (class)
X         {
X         case MOUSEMOVE:      dir_flag = TRUE;   break;
X
X         case GADGETUP:
X         case GADGETDOWN:
X            switch ( i = igad->GadgetID)
X            {
X
X            case FGAD+20:       /* Get device list                  */
X               RemoveGadget(wRq,&og5);  /* File name gadget */
X               ddir[0] = '\0';
X               AddGadget(wRq,&og5,-1L);
X               RefreshGadgets(&og5,wRq,(long)NL);
X               getdisks();
X               break;
X
X            case FGAD+6:
X            case FGAD+7:
X            case FGAD+8:
X            case FGAD+9:
X            case FGAD+10:       /* Replace file or directory name   */
X               pnam = rname[i - (FGAD+6)].IText;
X               if ( rname[igad->GadgetID - (FGAD+6)].NextText == NL )
X                  {
X                  RemoveGadget(wRq,&ogx);  /* File name gadget */
X                  for (i=0; i<DSIZE; i++)      ddef[i] = *pnam++;
X                  AddGadget(wRq,&ogx,-1L);
X                  RefreshGadgets(&ogx,wRq,(long)NL);
X                  break;
X                  }
X                  else
X                  {
X                  RemoveGadget(wRq,&og5);  /* Scroll bar */
X                  rfnam(ddir,pnam);
X                  AddGadget(wRq,&og5,-1L);
X                  RefreshGadgets(&og5,wRq,(long)NL);
X                  }
X            case FGAD+5:
X               if ( pnam = (char *)dinit(ddir) )
X                  notify(pnam);
X            case FGAD+3:
X               dir_flag = TRUE;
X               break;
X
X            case FGAD+11:      /* Name gadget, OTAY gadget   */
X            case FGAD+1:
X               retval = ddef;
X            case FGAD+2:      /* Cancel gadget   */
X               keepon = FALSE;
X            }
X         }
X      }
X
X      FreeMem(FirstEntry,(long)DBUFSIZ );
X      FreeMem(dir_info,(long)sizeof(struct FileInfoBlock));
X      free_pdir();
X
X      CloseWindowSafely(wRq);
X      return(retval);
X   }
X
Xstatic free_pdir()
X   {
X   if ( pdir )
X      {
X      UnLock(pdir);
X      pdir = NL;
X      }
X   }
X
X/*****************************************************************
X* dvinit()
X*   Initialize the fib for directory muck.  Null return
X* is good, else return is a pointer to an error string      */
X
Xstatic char *dvinit(subdir)
X   char *subdir;
X   {
X   more = FALSE;
X   curent = maxent = 0;
X
X   NextEntry = FirstEntry;      /* Allocate from here   */
X   ListHead.next = NL;          /* Clear the boogie     */
X
X   free_pdir();   /* Unlock any old lock... */
X
X   more = TRUE;
X   }
X
X
Xstatic char *dvmore(device)
X  char *device;
X   {
X   FAST struct dirent   *p_D = NextEntry;
X   FAST struct dirent   *ptr = (struct dirent *)&ListHead;
X   FAST struct dirent   *plink;
X
X   FAST   TEXT   *p_mung;
X
X   FAST long    i;
X
X   if ( ! more )   return(NL);
X
X      if ( (ULONG)p_D >=
X         ((ULONG)FirstEntry + (ULONG)DBUFSIZ - (ULONG)sizeof(struct dirent)) )
X         {
X         more = FALSE;
X         return("Directory Truncated!");
X         }
X
X
X      /* Here you can add a file/directory filter   */
X      /* filename text string is at &p_D->dE[0   */
X      p_D->isfile = 0;
X      p_mung = &p_D->dE[0];
X
X      for ( i=0; i<FCHARS; i++)
X         if ( ! (*p_mung++ = *device++) )   break;
X
X      i = (long)p_mung;
X      NextEntry = (struct dirent *)( (i+5L) & ~3L );
X
X      for ( i=maxent++; i>=0; i--)
X         {
X         if ( ! (plink = ptr->next)  )   break;
X         if ( alpha_lower(p_D,plink) )   break;
X         ptr = plink;
X         }
X
X      p_D->next = plink;
X      ptr->next = p_D;
X
X      return(NL);
X}
X
X#include <exec/types.h>
X#include <exec/memory.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#include <libraries/filehandler.h>
X
X#include <stdio.h>
X
X/* btoc() takes a pointer to a string in BCPL format and converts it to a
X * C string.
X */
Xvoid *btoc(bstring)
Xchar *bstring;
X{
X register UBYTE len,count,*cstring;
X
X cstring = (UBYTE *) bstring;
X len = cstring[0];
X for(count=0;count < len;count++)
X  cstring[count] = cstring[count+1];
X cstring[count] = '\0';
X}
X
X/* getdisks() will grab all disk device names in the system device list and
X *  append an exec node to a given list. The node being named in respect to the
X *  device.
X */
Xgetdisks()
X{
X extern struct DosLibrary         *DOSBase;
X struct RootNode                  *rnode;
X struct DosInfo                   *dinfo;
X register struct DeviceNode       *dnode;
X register struct Node             *adisk;
X char     *bname,name[32];
X
X rnode   = (struct RootNode *)  DOSBase->dl_Root;
X dinfo   = (struct DosInfo  *)  BADDR(rnode->rn_Info);
X
X dvinit();
X
X Forbid();
X for(dnode = (struct DeviceNode *) BADDR(dinfo->di_DevInfo);BADDR(dnode);
X        dnode = (struct DeviceNode *) BADDR(dnode->dn_Next))
X  {
X   if(!dnode->dn_Type && dnode->dn_Task && BADDR(dnode->dn_Name))
X
X/* if(dnode->dn_Task && BADDR(dnode->dn_Name))                      */
X    {
X     bname = (char *) BADDR(dnode->dn_Name);
X     movmem(bname,name,(ULONG)bname[0]+1L);
X     btoc(name); strcat(name,":");
X     dvmore(name);
X    }
X  }
X Permit();
X
X more = FALSE;
X cxxx();
X}
X
Xstatic char *dinit(subdir)
X   char *subdir;
X   {
X   more = FALSE;
X   curent = maxent = 0;
X
X   NextEntry = FirstEntry;      /* Allocate from here   */
X   ListHead.next = NL;          /* Clear the boogie     */
X
X   free_pdir();   /* Unlock any old lock... */
X
X   if (! (pdir=(struct FileLock *)Lock(subdir,(ULONG)ACCESS_READ)) )
X      return("Wrong Diskette?");
X   if ( ! Examine(pdir, dir_info) )   return("Wierd Disk Error");
X   if ( dir_info->fib_DirEntryType < 0L )   return("Bizzare Alert!!");
X
X   more = TRUE;
X   return(dmore());
X   }
X
X
Xstatic char *dmore()
X   {
X   FAST struct dirent   *p_D = NextEntry;
X   FAST struct dirent   *ptr = (struct dirent *)&ListHead;
X   FAST struct dirent   *plink;
X
X   FAST   TEXT   *p_mung;
X
X   FAST long    i;
X
X   if ( ! more )   return(NL);
X
X   if ( ExNext( pdir, dir_info ) )
X      {
X
X
X      if ( (ULONG)p_D >=
X         ((ULONG)FirstEntry + (ULONG)DBUFSIZ - (ULONG)sizeof(struct dirent)) )
X         {
X         more = FALSE;
X         return("Directory Truncated!");
X         }
X
X
X      /* Here you can add a file/directory filter   */
X      /* filename text string is at &p_D->dE[0   */
X      p_D->isfile = ( dir_info->fib_DirEntryType < 0L );
X      p_mung = &p_D->dE[0];
X
X      if ( IsInfo( dir_info->fib_FileName ) ) return(NL);
X
X      for ( i=0; i<FCHARS; i++)
X         if ( ! (*p_mung++ = dir_info->fib_FileName[i]) )   break;
X
X      i = (long)p_mung;
X      NextEntry = (struct dirent *)( (i+5L) & ~3L );
X
X      for ( i=maxent++; i>=0; i--)
X         {
X         if ( ! (plink = ptr->next)  )   break;
X         if ( alpha_lower(p_D,plink) )   break;
X         ptr = plink;
X         }
X      p_D->next = plink;
X      ptr->next = p_D;
X
X      return(NL);
X      }
X   else return ( IoErr() == ERROR_NO_MORE_ENTRIES) ?
X       (char *)(more = (long)NL) : "Error Reading Directory!!!";
X   }
X
XIsInfo( str )
X  char *str;
X{
X  int len;
X
X  len = strlen(str);
X
X  if (len > 5) {
X    return( strcmp( str + len - 5, ".info" ) == 0 );
X  }
X
X  return( 0 );
X}
X
X/* dedicated alphabetizing function for dmore()   */
X
Xstatic alpha_lower(snew,sold)
X   struct dirent *snew,*sold;
X   {
X   FAST struct dirent *pnew = snew;
X   FAST TEXT *ps1,*ps2, c,d;
X
X   if ( pnew->isfile == sold->isfile)
X      {
X      ps1 = &pnew->dE[0];
X      ps2 = &sold->dE[0];
X      while ( (c=*ps1++) )
X         {
X         if ( c > (d=*ps2++) )   return(FALSE);
X         else if ( c < d )      break;
X         }
X      return(TRUE);
X      }
X   return(pnew->isfile);
X   }
X
X
X
X/* Display directory stuff   */
X
Xstatic cxxx()
X   {
X   FAST long   i,new;
X   FAST long   x,y;
X   FAST struct dirent *ohboy = (struct dirent *)&ListHead;
X
X   new = curent;
X   for ( i=0; i<new; i++)   ohboy = ohboy->next;
X
X   y = 20L;
X   for (i=0; i<DENTS; i++)
X      {
X      y += (x=10);
X      rname[i].NextText = NL;
X      rname[i].IText = "";
X      rname[i].LeftEdge = 0;
X      if ( (new+i) < maxent )
X         {
X         ohboy = ohboy->next;
X         rname[i].IText = &ohboy->dE[0];
X         if ( ohboy->isfile )   PrintIText(wRp,&rname[i],10L,y);
X         else
X            {
X            rname[i].LeftEdge = 48;
X            PrintIText(wRp,&saydir,10L,y);
X            PrintIText(wRp,&rname[i],10L,y);
X            rname[i].NextText = &saydir;
X            }
X         x = wRp->cp_x;
X         }
X      if ( x < ZWDTH+10 )   RectFill(wRp,x,y,(long)(ZWDTH+10),(long)(y+8L));
X      }
X   }
X
X
X/**************************************************
X* rfnam()
X*   Combines dir, plus name into dir   */
X
Xstatic rfnam(dir,fil_nam)
X   char *dir,*fil_nam;
X   {
X   FAST char   *pdst = dir;
X   FAST char   *psrc = fil_nam;
X   FAST char   c = ':';
X
X   while ( *pdst )
X      c = *pdst++;
X   if ( c != ':')   *pdst++ = '/';
X
X   while ( *pdst++ = *psrc++ )
X      ;
X   }
X
Xstatic struct IntuiText b_txt = {0,1,JAM2, 5,20,NL,NL,    NL};
Xstatic struct IntuiText p_txt = {0,1,JAM2, 5,3,NL,"OK", NL};
X
X/****************************************************************/
X/* notify(txt)                     */
X/*   Prompts for Yes/No response            */
X
Xstatic notify(txt)
X   char *txt;
X   {
X   b_txt.IText = txt;
X   AutoRequest(wRq,&b_txt,0L,&p_txt,0L,0L,
X      (long)(IntuiTextLength(&b_txt)+50L),70L);
X   }
SHAR_EOF
echo "extracting getfile.h"
sed 's/^X//' << \SHAR_EOF > getfile.h
X/***************************************************
X*  get_fname(window,screen,hail,ddef,ddir);
X*
X*   Displays a window/requester that
X* gets a file name for device,directory,default file, extension
X*
X*   Calling args:
X* window:   Window making the request
X* screen:   Screen, if NULL assummed workbench
X* hail:   Text prompt at top of requester
X* ddef:   Input default file-name. Has NO DIRECTORY OR EXTENSION.
X* ddir:   Directory of file, may be null
X*
X*  The basic call is:
X*
X*   getfile(Window,Screen,Hailing_string,file_name,directory_name);
X*
X* Where:
X*   Window is a pointer to your window
X*   Screen is a pointer to your screen ... or (long)NULL if workbench
X*   Hailing_string is a prompt displayed in the requester
X*   file_name is a text array which will be altered by getfile,
X*   it returns the file name.
X*   directory_name is a text array altered by getfile, it
X*   is the directory.
X*
X*   The return value is either a pointer to your buffer, file_name,
X*   or NULL if the user selected CANCEL.
X*
X*   You must reserve two text areas for file and directory like so:
X*
X* #define FNAME_SIZE 33
X* TEXT   file_name[FNAME_SIZE + 1];
X* TEXT   dir_name[FNAME_SIZE + 2]
X**********************************************************************/
X
X#ifndef GET_FNAME
X
X#define GET_FNAME
X
X#define FNAME_SIZE 33
X
Xextern char *get_fname();
X
X#endif
X
SHAR_EOF
echo "extracting getint.c"
sed 's/^X//' << \SHAR_EOF > getint.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 implements a requester like window to get an integer
X * value from the user.
X */
X
X#include "mandp.h"
X
Xstruct Window *GetIWind;
X
X#define GIWIDTH  190
X#define GIHEIGHT 50
X
Xstatic
Xstruct NewWindow NewGetI = {
X   (320-GIWIDTH)/2,(200-GIHEIGHT)/2, /* start position           */
X   GIWIDTH,GIHEIGHT,                 /* width, height            */
X   (UBYTE) 0, (UBYTE) 1,     /* detail pen, block pen    */
X   NULL,                     /* IDCMP flags */
X   SMART_REFRESH,            /* MandWind flags */
X   (struct Gadget *) NULL,   /* first gadget             */
X   (struct Image *) NULL,    /* user checkmark           */
X   (UBYTE *) NULL,           /* 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#define GETINOTDONE 0
X#define GETIDONEOK  1
X#define GETICANCEL  2
X
XUBYTE IDone;
X
Xchar *IString;
X
X/*
X * Allocate all the gadgets and things for the get int window
X */
Xstruct Gadget *MakeGetInt( Title, IVal )
X  char *Title;
X  LONG IVal;
X{
X
X  register struct Gadget *NextGadget;
X  register SHORT *Height;
X  register struct StringInfo *StringInfo;
X  register struct Gadget *FirstGadget, *OldGadget;
X
X  char string[80];
X
X  extern struct Gadget *MakeBool();
X  extern struct Gadget *MakeString();
X  extern struct IntuiText *MakeIntui();
X
X  LONG i;
X
X#define GETICANID  0xffff
X#define GETIOKID   0xfffe
X#define GETISTRID  0xfffd
X
X  FirstGadget = MakeBool(127, 32, 54, 12, 1, GETICANID, NULL);
X  if (FirstGadget == NULL) {
X    goto error;
X  }
X  FirstGadget->GadgetText = ShadowIntui("Cancel", 4, 3);
X
X  if ( FirstGadget->GadgetText == NULL ) goto error;
X
X  NextGadget = OldGadget = MakeBool(6, 32, 54, 12, 1, GETIOKID, NULL);
X
X  if (NextGadget == NULL) goto error;
X
X  NextGadget->GadgetText = ShadowIntui("  OK", 4, 3);
X
X  if ( NextGadget->GadgetText == NULL ) goto error;
X
X  FirstGadget->NextGadget = NextGadget;
X
X  sprintf( string,"%d",IVal );
X  NextGadget = MakeString( 55, 16, 10, GETISTRID, string );
X
X  if (NextGadget == NULL) goto error;
X
X  NextGadget->GadgetText = ShadowIntui(Title,-10,-11);
X
X  if ( NextGadget->GadgetText == NULL ) goto error;
X
X/*i = IntuiTextLength(NextGadget->GadgetText);
X  NextGadget->GadgetText->LeftEdge = (GIWIDTH-i)/2;  */
X
X  OldGadget->NextGadget = NextGadget;
X
X  StringInfo = (struct StringInfo *) NextGadget->SpecialInfo;
X  IString = (char *) StringInfo->Buffer;
X
X  return( FirstGadget );
X
Xerror:
X  FreeGadgets(FirstGadget);
X  return((struct Gadget *) NULL);
X
X} /* MakeGetInt */
X
Xstatic struct Gadget *GetGadgets;
X
X/*
X * Get an Integr from the user
X */
XGetInt( Title, IVal)
X  char *Title;
X  LONG *IVal;
X{
X  register struct Gadget *Gadgets;
X  register struct Window *Window;
X  register LONG   i;
X  register struct RastPort *Rp;
X
X  struct Window *OpenMyWind();
X
X  IDone = GETINOTDONE;
X
X  if (GetIWind == NULL ) {
X
X    Gadgets = MakeGetInt( Title, *IVal );
X
X    if (Gadgets == NULL) {
X      DispErrMsg("Panic. No Gadgets\n",0);
X      return( 0 );
X    } else {
X      Window = OpenMyWind( &NewGetI, screen, NULL, GIWIDTH, GIHEIGHT);
X
X      GetIWind = Window;
X
X      if (Window) {
X
X        Rp = Window->RPort;
X
X        CurWind = Window;
X
X        SetAPen( Rp, NORMALPEN );
X        RectFill( Rp,0,0,Window->Width,Window->Height);
X
X        GetGadgets = Gadgets;
X
X        AddGList( Window, Gadgets, -1, -1);
X
X        RefreshGadgets( Gadgets, Window, NULL );
X
X        SetAPen( Rp, HIGHLIGHTPEN );
X        Move( Rp, 0,               Window->Height-1 );
X        Draw( Rp, 0,               0 );
X        Draw( Rp, Window->Width-1, 0 );
X
X        SetAPen( Rp, SHADOWPEN );
X        Draw( Rp, Window->Width-1, Window->Height-1 );
X        Draw( Rp, 0,               Window->Height-1 );
X
X        DoIGet();
X        if (IDone == GETIDONEOK) {
X          sscanf( IString,"%d", IVal);
X        }
X        CloseGetIWind();
X      } else {
X        return( 0 );
X      }
X    }
X  }
X  return( IDone == GETIDONEOK );
X} /* OpenGetIWind */
X
X/*
X * Close the get integer window
X */
XCloseGetIWind()
X{
X  if (GetIWind != NULL) {
X    CloseMyWind( GetIWind, GetGadgets );
X    GetIWind = NULL;
X  }
X} /* CloseGetIWind */
X
X/*
X * Wait and process a message
X */
XDoIGet()
X{
X  while (IDone == GETINOTDONE) {
X
X    Wait( 1 << BackWind->UserPort->mp_SigBit );
X
X    DoIMsg();
X  }
X}
X
X/*
X * if there is a message, process it
X */
XDoIMsg()
X{
X  register ULONG Class;
X  register struct IntuiMessage *message;
X  register struct Gadget *gadget;
X
X  while (message = (struct IntuiMessage *) GetMsg( BackWind->UserPort)) {
X
X    Class = message->Class;
X    gadget = (struct Gadget *) message->IAddress;
X
X    /* got a message */
X
X    ReplyMsg(message);
X
X    CheckButtons( gadget, Class );
X  }
X} /* DoIMsg */
X
XCheckButtons( gadget, class )
X  struct Gadget *gadget;
X  ULONG class;
X{
X  if (class == GADGETDOWN) {
X
X    switch( gadget->GadgetID ) {
X
X      case GETICANID:
X           IDone = GETICANCEL;
X           break;
X
X      case GETIOKID:
X           IDone = GETIDONEOK;
X           break;
X    }
X  }
X} /* CheckButtons */
SHAR_EOF
echo "extracting help.c"
sed 's/^X//' << \SHAR_EOF > help.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 decodes gadget or menu types to determine what help
X * file should be displayed in the help window.
X */
X
X#include "mandp.h"
X
Xstatic char *HelpFile;
X
XScrollHelpCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  struct Window *window;
X  struct Gadget *gadget;
X
X  window = Msg->IDCMPWindow;
X  gadget = (struct Gadget *) Msg->IAddress;
X
X  switch (Msg->Class) {
X
X    case GADGETDOWN:
X         ModifyIDCMP(window, window->IDCMPFlags | MOUSEMOVE);
X         State = SCROLLHELPSTATE;
X         break;
X
X    case MOUSEMOVE:
X         Page_File(HELPSCROLL);
X         break;
X
X    case GADGETUP:
X         if (gadget->GadgetID == HELPSCROLL) {
X           ModifyIDCMP(window, window->IDCMPFlags & ~MOUSEMOVE);
X         }
X         Page_File(HELPSCROLL);
X         break;
X  }
X}
X
XHelpMenuCmd( Msg )
X  struct IntuiMessage *Msg;
X{
X  register USHORT code;
X
X  code = Msg->Code;
X
X  HelpFile = NULL;
X
X  if (code == MENUNULL)
X    return;
X
X  switch ( MENUNUM( code ) ) {
X
X    case PROJECTMENU:
X         HelpProjectMenu(code);
X         break;
X
X    case DISPLAYMENU:
X         HelpDisplayMenu(code);
X         break;
X
X    case CALCULATEMENU:
X         HelpCalculateMenu(code);
X         break;
X
X    case SPECIALMENU:
X         HelpSpecialMenu(code);
X         break;
X  }
X
X  if (HelpFile == NULL)
X    DispErrMsg("No Help for that object",0);
X  else
X    ShowHelp("Mandelbrot:Help/",HelpFile);
X
X}
X
X/*
X * Decide what to do for Project menu's Items
X */
XHelpProjectMenu(code)
X  USHORT code;
X{
X  switch (ITEMNUM(code)) {
X
X    case NEWITEM:
X
X         switch( SUBNUM(code) ) {
X           case 0:
X                HelpFile = "NewMand";
X                break;
X
X           case 1:
X                HelpFile = "NewJulia";
X                break;
X         }
X         break;
X
X    case HELPITEM:
X         HelpFile = "Help";
X         break;
X
X    case CURITEM:
X         HelpFile = "Current";
X         break;
X
X    case CLOSEPROJ:
X         HelpFile = "CloseProj";
X         break;
X
X    case SAVEPROJ:
X    case LOADITEM:
X         HelpFile = "Load.Save";
X         break;
X
X    case SAVEILBM:
X         HelpFile = "SaveILBM";
X         break;
X
X    case CANCELITEM:
X         HelpFile = "CancelCmd";
X         break;
X
X    case QUITITEM:
X         HelpFile = "Quit";
X         break;
X    }
X} /* HelpProjectMenu */
X
X/*
X * Decide what to do for Edit menu's Items
X */
XHelpDisplayMenu(code)
X  USHORT code;
X{
X  switch (ITEMNUM(code)) {
X
X    case COLORITEM:
X         HelpFile = "ColorPalette";
X         break;
X
X    case CYCLEITEM:
X         HelpFile = "CycleControl";
X         break;
X
X    case CONTOURITEM:
X         HelpFile = "ContourGen";
X         break;
X
X    case AUTOCNTRITEM:
X         HelpFile = "AutoContour";
X         break;
X
X    case HISTOGRAMITEM:
X         HelpFile = "Histogram";
X         break;
X
X    case DEPTHITEM:
X         InitDepthSubs();
X         HelpFile = "NumColors";
X         break;
X
X    case VIEWMODEITEM:
X         InitViewModesSubs();
X         HelpFile = "ScreenType";
X         break;
X
X    case SCREENITEM:
X         InitSizeSubs();
X         HelpFile = "ScreenSize";
X         break;
X
X    case BORDERITEM:
X         InitBorderSubs();
X         HelpFile = "Border";
X         break;
X    }
X} /* HelpDisplayMenu */
X
X/*
X * Decide what to do for Special Menu's Items
X */
XHelpCalculateMenu(code)
X  USHORT code;
X{
X  switch (ITEMNUM(code)) {
X
X    case ZOOMITEM:
X
X         switch(SUBNUM(code)) {
X           case ZOOMIN:
X                HelpFile = "ZoomIn";
X                break;
X           case ZOOMOUT:
X                HelpFile = "ZoomOut";
X                break;
X           case ZOOMOFF:
X                HelpFile = "ZoomClose";
X                break;
X           case ZOOMJULIA:
X                HelpFile = "ZoomJulia";
X                break;
X         }
X         break;
X
X    case SCROLLITEM:
X         HelpFile = "Pan";
X         break;
X
X    case LENSITEM:
X         InitLensSubs();
X         HelpFile = "Lens";
X         break;
X
X    case GENERATEITEM:
X         HelpFile = "Generate";
X         break;
X
X    case GENERATORITEM:   /* generator type */
X         InitGenSubs();
X         HelpFile = "Generator";
X         break;
X
X    case STATSITEM:
X         HelpFile = "Statistics";
X         break;
X
X    case COUNTITEM:
X         HelpFile = "MaxIteration";
X         break;
X  }
X} /* HelpCalcualteMenu */
X
X/*
X * Decide what to do for Special Menu's Items
X */
XHelpSpecialMenu(code)
X  USHORT code;
X{
X  switch (ITEMNUM(code)) {
X
X    case PRESETITEM:
X         HelpFile = "Presets";
X         break;
X
X    case ORBITITEM:
X         HelpFile = "Orbit";
X         break;
X
X    case ORBITMATHITEM:
X         HelpFile = "MathOrbit";
X         break;
X
X    case MAXORBITEM:
X         HelpFile = "MaxOrbit";
X         break;
X  }
X} /* HelpCalculateMenu */
X
X/*
X * Perform functions for Gadget down messages
X */
XHelpGadgetCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  struct Gadget *gadget;
X
X  gadget = (struct Gadget *) Msg->IAddress;
X
X  HelpFile = NULL;
X
X  switch (gadget->GadgetID >> WINDTYPEBITS & WINDMASK) {
X
X  case PALTYPE:
X       HelpPalGadget(gadget);
X       break;
X
X  case CONTYPE:
X       HelpContGadget(gadget);
X       break;
X
X  case PICTTYPE:
X       HelpPictGadget(gadget);
X       break;
X
X  case CYCTYPE:
X       HelpCycGadget(gadget);
X       break;
X
X  case ORBTTYPE:
X       HelpFile = "Orbit";
X       break;
X  }
X
X  if (HelpFile != NULL)
X    ShowHelp("Mandelbrot:Help/",HelpFile);
X  else
X    DispErrMsg("No Help for that object",0);
X}
X
X/*
X * Interpret the gadgets and do the right thing
X */
XHelpPalGadget(gadget)
X  register struct Gadget *gadget;
X{
X  switch (gadget->GadgetID >> TYPEBITS & TYPEMASK) {
X
X  case PALPENS:
X       HelpFile = "PalPens";
X       break;
X
X  case PALCNTLS:
X       HelpPalCntl(gadget);
X       break;
X
X  case PALPOTS:
X       HelpFile = "PalPots";
X       break;
X  }
X} /* HelpPalGadget */
X
X/*
X * We got a color palette command gadget
X */
XHelpPalCntl(gadget)
X  register struct Gadget *gadget;
X{
X  switch (gadget->GadgetID) {
X
X  case PALCOPY:
X       HelpFile = "PalCopy";
X       break;
X
X  case PALRANGE:
X       HelpFile = "PalRange";
X       break;
X
X  case PALEXCG:
X       HelpFile = "PalExchg";
X       break;
X  }
X} /* HelpPalCntl */
X
XHelpPictGadget(gadget)
X  register struct Gadget *gadget;
X{
X  switch (gadget->GadgetID) {
X
X    case PICTCUR:
X         HelpFile = "PictCur";
X         break;
X
X    case PICTGEN:
X         HelpFile = "Generate";
X         break;
X
X    case PICTIN:
X         HelpFile = "ZoomIn";
X         break;
X
X    case PICTOUT:
X         HelpFile = "ZoomOut";
X         break;
X
X    case PICTJULIA:
X         HelpFile = "ZoomJulia";
X         break;
X  }
X}
X
X/*
X * Figure out what to do for this contour gadget
X */
XHelpContGadget(gadget)
X  struct Gadget *gadget;
X{
X  switch (gadget->GadgetID >> TYPEBITS & TYPEMASK) {
X
X    case CONTCNTLS:
X         switch (gadget->GadgetID) {
X           case CONTRECOL:
X                HelpFile = "Paint";
X                break;
X
X           case CONTSET:
X                HelpFile = "ContSet";
X                break;
X
X           case CONTSMTH:
X                HelpFile = "ContSmooth";
X                break;
X
X           case CONTCUT:
X                HelpFile = "ContCut";
X                break;
X
X           case CONTCOPY:
X                HelpFile = "ContCopy";
X                break;
X
X           case CONTPASTE:
X                HelpFile = "ContPaste";
X                break;
X
X           case CONTLAST:
X                HelpFile = "ContLast";
X                break;
X
X           case CONTCEIL:
X                HelpFile = "ContCeil";
X                break;
X         }
X         break;
X
X    case CONTSELS:
X         HelpFile = "ContPens";
X         break;
X
X    case CONTPOTS:
X         HelpFile = "ContPots";
X         break;
X  }
X}
X
X/*
X * Figure out what to do for this color cycle gadget
X */
XHelpCycGadget(gadget)
X  struct Gadget *gadget;
X{
X  switch (gadget->GadgetID >> TYPEBITS & TYPEMASK) {
X
X    case CYCCNTLS:
X         switch (gadget->GadgetID) {
X           case CYCRANGE:
X                HelpFile = "CycRange";
X                break;
X
X           case CYCDIR:
X                HelpFile = "CycDir";
X                break;
X
X           case CYCSPEED:
X                HelpFile = "CycSpeed";
X                break;
X
X           case CYCON:
X                HelpFile = "CycOn";
X                break;
X         }
X         break;
X
X    case CYCRNUMS:
X         HelpFile = "CycRNums";
X         break;
X  }
X}
X
X
X
SHAR_EOF
echo "extracting hist.c"
sed 's/^X//' << \SHAR_EOF > hist.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 open, draw and close the
X * histogram window.
X */
X
X#include "mandp.h"
X
XUBYTE HistOpen;
X
Xstruct Window          *HistWind;
X
Xstruct NewWindow NewHist = {
X   0,200-80,                 /* start position           */
X   280,80,                   /* width, height            */
X   (UBYTE) 0, (UBYTE) -1,    /* detail pen, block pen    */
X   NULL,                     /* IDCMP flags */
X                             /* MandWind flags */
X   WINDOWCLOSE|WINDOWDRAG|WINDOWDEPTH|NOCAREREFRESH|SMART_REFRESH,
X   (struct Gadget *) NULL,   /* first gadget             */
X   (struct Image *) NULL,    /* user checkmark           */
X   (UBYTE *) "Histogram",     /* window title             */
X   (struct Screen *) NULL,   /* pointer to screen        */
X   (struct BitMap *) NULL,   /* pointer to superbitmap   */
X   80,80,-1,-1,              /* sizing                   */
X   CUSTOMSCREEN              /* type of screen           */
X   };
X
Xstruct Histogram *
XAllocHist( size )
X  int size;
X{
X  struct Histogram *Hist;
X
X  Hist = AllocHistStruct();
X
X  if (Hist != NULL) {
X
X    if (Hist->Table == NULL) {
X
X      Hist->Table = AllocHistTable(size);
X
X      if (Hist->Table == NULL) {
X
X        FreeHistStruct(Hist);
X        return( NULL );
X      }
X
X      Hist->TableSize = size;
X    }
X  }
X  return( Hist );
X}
X
XFreeHist( Hist )
X  struct Histogram *Hist;
X{
X  if (Hist) {
X
X    if (Hist->Table) {
X      FreeHistTable( Hist );
X    }
X    FreeHistStruct( Hist );
X  }
X}
X
XReDoHist( Pict )
X  register struct Picture *Pict;
X{
X  if (Pict == NULL || Pict->Counts == NULL ||
X      Pict->Flags & NO_RAM_GENERATE || HistWind == NULL) {
X
X    return(UNSUCCESSFUL );
X  }
X  CalcHist(Pict);
X  PlotHist(Pict);
X}
X
X/*
X *
X */
XCalcHist(Pict)
X  register struct Picture *Pict;
X{
X  register int i, n, size, *Table;
X  register SHORT *Counts;
X
X  /* make sure the histogram is available */
X
X  if (Pict->Hist) {
X    FreeHist( Pict->Hist );
X    Pict->Hist = NULL;
X  }
X
X  if (Pict == NULL || Pict->Flags & NO_RAM_GENERATE ||
X      Pict->Counts == NULL) {
X
X    return;
X  }
X
X  Pict->Hist = AllocHist( Pict->MaxIteration );
X
X  if (Pict->Hist == NULL) {
X    return;
X  }
X
X  Table = Pict->Hist->Table;
X  size  = Pict->Hist->TableSize;
X
X  for (i = 0; i < size; i++) {
X    Table[i] = 0;
X  }
X
X  Counts = Pict->Counts;
X  size   = Pict->CountX*Pict->CountY;
X
X  for (i = 0; i < size; i++) {
X
X    if ( (n = *Counts++) > 0 && n < Pict->Hist->TableSize) {
X
X      Table[ n ]++;
X    }
X  }
X}
X
XPlotHist( Pict )
X  struct Picture *Pict;
X{
X  register struct Histogram *Hist;
X  int *Table; int  Size;
X  int  max, locmax, maxnum;
X
X  struct IntuiText *intui;
X
X  BorderWindow( HistWind );
X
X  Hist = Pict->Hist;
X
X  if (Hist == NULL) {
X    return;
X  }
X
X  Table = (int *) Hist->Table;
X  Size  = Hist->TableSize;
X
X  /* Find Max of all iteration counts */
X
X  { int i,n;
X
X    max = 0;
X
X    for (i = 0; i < Size; i++) {
X      if ((n = *Table++) > max) {
X        max = n;
X      }
X    }
X  }
X
X#define BOX_BOT  24
X#define BOX_LEFT 17
X#define BOX_TOP  22
X
X  Table = (int *) Hist->Table;
X
X  /* Plot scaled versions of this histogram */
X
X  { int bot,right,half;
X    int i, j, k, n, height,width;
X    int num_entries;
X    float scale;
X    register struct RastPort *Rp = HistWind->RPort;
X
X    if (XScale) {
X      k = 2;
X    } else {
X      k = 4;
X    }
X
X    num_entries = 1024/k;
X    right = BOX_LEFT + num_entries;
X    half = num_entries/2 + BOX_LEFT;
X    bot  = HistWind->Height - BOX_BOT;
X    scale = (float)(bot-BOX_TOP)/(float)max;
X
X    Rp = HistWind->RPort;
X
X    SetAPen(  Rp, NORMALPEN );
X    RectFill( Rp, LEFTMARG, TOPMARG, HistWind->Width-2, HistWind->Height-2);
X
X    /* Draw plot border */
X
X    SetAPen(Rp,SHADOWPEN);
X    Move(Rp,right+1,  bot+1);     /* Lower right */
X    Draw(Rp,right+1,  BOX_TOP);   /* Upper right */
X    Draw(Rp,BOX_LEFT,BOX_TOP);   /* Upper left  */
X    Draw(Rp,BOX_LEFT,bot+1);     /* Lower left  */
X    Draw(Rp,right+1,  bot+1);     /* Lower right */
X
X    Move(Rp,BOX_LEFT,bot+2);     /* Lower left tic */
X    Draw(Rp,BOX_LEFT,bot+3);
X
X    /* Do altitude tick marks */
X
X    for (i = 0; i < num_entries; i += 16<<XScale) {
X      Move(Rp, right - i + 1, bot+2);
X      Draw(Rp, right - i + 1, bot+3);
X    }
X
X    intui = ShadowIntui("1023", BOX_LEFT-16, bot + 5);
X    PrintIText( Rp, intui, 0, 0);
X    FreeIntui(intui);
X
X    intui = ShadowIntui("512", half-12, bot + 5);
X    PrintIText( Rp, intui, 0, 0);
X    FreeIntui(intui);
X
X    intui = ShadowIntui("0", right-4, bot + 5);
X    PrintIText( Rp, intui, 0, 0);
X    FreeIntui(intui);
X
X    intui = ShadowIntui("Height", half-24, bot + 13);
X    PrintIText( Rp, intui, 0, 0);
X    FreeIntui(intui);
X
X    intui = ShadowIntui("Percentage (10%/Tick)", half-84, BOX_TOP-11);
X    PrintIText( Rp, intui, 0, 0);
X    FreeIntui(intui);
X
X    /* Do percentage tick marks */
X
X    SetAPen(Rp,HIGHLIGHTPEN);
X    Move(Rp,right+1,  BOX_TOP-1); /* right */
X    Draw(Rp,right+1,  BOX_TOP-2);
X    Move(Rp,BOX_LEFT,BOX_TOP-1); /* left  */
X    Draw(Rp,BOX_LEFT,BOX_TOP-2);
X
X    { int tick = Pict->CountX*Pict->CountY/10;
X      int thresh, cur;
X
X      cur = 0;
X      thresh = tick;
X
X      for (i = Size-1; i >= 0; i--) {
X        cur += Table[i];
X        if (cur > thresh) {
X          Move(Rp, right - (i/(4>>XScale)) + 1, BOX_TOP-1);
X          Draw(Rp, right - (i/(4>>XScale)) + 1, BOX_TOP-2);
X          thresh += tick;
X        }
X      }
X    }
X
X    for (i = 0; i < Size; i += k) {
X
X      n = Table[i];
X      locmax = n;
X      maxnum = i;
X
X      for (j = 0; j < 4; j++) {
X
X        n = Table[i+j];
X
X        if (n > locmax) {
X          locmax = n;
X          maxnum = i+j;
X        }
X      }
X
X      if ( locmax > 0 ) {
X
X        height = bot - (int) (scale * locmax);
X
X        if (right   < HistWind->Width && height >= 0 &&
X            height < HistWind->Height) {
X
X          SetAPen( Rp, Pict->ClrXlate[maxnum] );
X
X          Move(Rp, right, bot);
X          Draw(Rp, right, height);
X        }
X      }
X      right -= 1;
X    }
X  }
X}
X
XAutoContour( Pict, Mode )
X  struct Picture *Pict;
X{
X  int num_conts,i,j,prev_i;
X
X  float tick;
X  float thresh, cur;
X
X  if (Pict == NULL || Pict->Flags & NO_RAM_GENERATE ||
X      Pict->Counts == NULL) {
X    return;
X  }
X
X  CalcHist(Pict);
X
X  if (Pict->Hist == NULL)
X    return;
X
X  /* find pattern range length */
X
X  for (num_conts = 255; num_conts >= 0 && Pict->Pens[num_conts] == 1;
X       num_conts--);
X
X  if (num_conts == 0)
X    return;
X
X  /* Set up contours */
X
X  j = 0;
X
X  for (i = 0 ; i < Pict->Hist->TableSize - 1; i++) {
X     j += Pict->Hist->Table[i];
X  }
X
X  thresh = tick = (float) (j) / (float) num_conts;
X  cur = 0.0;
X
X  Pict->Heights[0] = Pict->MaxIteration;
X  j = 1;
X  prev_i = 0;
X
X  for (i = Pict->Hist->TableSize - 2; i >= 0 && j < num_conts-1; i--) {
X
X    cur += Pict->Hist->Table[i];
X
X    if (cur > thresh) {
X
X      Pict->Heights[j++] = i;
X
X      if (Mode == 1 && i+1 == prev_i) {
X        break;   /* out of the loop */
X      }
X      prev_i = i;
X
X      while ( cur > thresh )
X        thresh += tick;
X    }
X  }
X  if (i < 0)
X    i = 0;
X
X  for (; j < num_conts-1; j++) {
X
X    if (i > 0) i--;
X
X    Pict->Heights[j] = i;
X  }
X  Pict->Heights[j] = 0;
X  if (ContWind) {
X    ModAll();
X  }
X  ReColor( Pict );
X}
X
X/*
X * Open the Hist window
X */
XOpenHistWind()
X{
X
X  if (CurPict == NULL)
X    return;
X
X  if ( HistWind == NULL ) {
X
X    HistWind = OpenMyWind( &NewHist, screen, NULL,280<<XScale,96+32*YScale);
X
X    if ( HistWind == NULL ) {
X      return;
X    }
X  } else {
X    WindowToFront( HistWind );
X  }
X  ReDoHist(CurPict);
X  HistOpen = 1;
X} /* OpenHistWind */
X
X/*
X * Close the Hist window
X */
XCloseHistWind()
X{
X  if (HistWind != NULL) {
X
X    NewHist.LeftEdge = HistWind->LeftEdge;
X    NewHist.TopEdge  = HistWind->TopEdge;
X
X    CloseMyWind(HistWind,NULL);
X  }
X  HistWind = NULL;
X} /* CloseHistWind */
X
SHAR_EOF
echo "extracting iffw.c"
sed 's/^X//' << \SHAR_EOF > iffw.c
X/*----------------------------------------------------------------------*
X * IFFW.C  Support routines for writing IFF-85 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/iff.h"
X#include "iff/gio.h"
X
X/* ---------- IFF Writer -----------------------------------------------*/
X
X/* A macro to test if a chunk size is definite, i.e. not szNotYetKnown.*/
X#define Known(size)   ( (size) != szNotYetKnown )
X
X/* Yet another weird macro to make the source code simpler...*/
X#define IfIffp(expr)  {if (iffp == IFF_OKAY)  iffp = (expr);}
X
X/* ---------- OpenWIFF -------------------------------------------------*/
X
XIFFP OpenWIFF(file, new0, limit)  BPTR file; GroupContext *new0; LONG limit; {
X    register GroupContext *new = new0;
X    register IFFP iffp = IFF_OKAY;
X
X    new->parent       = NULL;
X    new->clientFrame  = NULL;
X    new->file         = file;
X    new->position     = 0;
X    new->bound        = limit;
X    new->ckHdr.ckID   = NULL_CHUNK;  /* indicates no current chunk */
X    new->ckHdr.ckSize = new->bytesSoFar = 0;
X
X    if (0 > Seek(file, 0, OFFSET_BEGINNING))    /* Go to start of the file.*/
X        iffp = DOS_ERROR;
X    else if ( Known(limit) && IS_ODD(limit) )
X        iffp = CLIENT_ERROR;
X    return(iffp);
X    }
X
X/* ---------- StartWGroup ----------------------------------------------*/
XIFFP StartWGroup(parent, groupType, groupSize, subtype, new)
X      GroupContext *parent, *new; ID groupType, subtype; LONG groupSize;  {
X    register IFFP iffp;
X
X    iffp = PutCkHdr(parent, groupType, groupSize);
X    IfIffp( IFFWriteBytes(parent, (BYTE *)&subtype, sizeof(ID)) );
X    IfIffp( OpenWGroup(parent, new) );
X    return(iffp);
X    }
X
X/* ---------- OpenWGroup -----------------------------------------------*/
XIFFP OpenWGroup(parent0, new0)  GroupContext *parent0, *new0; {
X    register GroupContext *parent = parent0;
X    register GroupContext *new    = new0;
X    register LONG ckEnd;
X    register IFFP iffp = IFF_OKAY;
X
X    new->parent       = parent;
X    new->clientFrame  = parent->clientFrame;
X    new->file         = parent->file;
X    new->position     = parent->position;
X    new->bound        = parent->bound;
X    new->ckHdr.ckID   = NULL_CHUNK;
X    new->ckHdr.ckSize = new->bytesSoFar = 0;
X
X    if ( Known(parent->ckHdr.ckSize) ) {
X        ckEnd = new->position + ChunkMoreBytes(parent);
X        if ( new->bound == szNotYetKnown || new->bound > ckEnd )
X            new->bound = ckEnd;
X        };
X
X    if ( parent->ckHdr.ckID == NULL_CHUNK || /* not currently writing a chunk*/
X         IS_ODD(new->position) ||
X         (Known(new->bound) && IS_ODD(new->bound)) )
X        iffp = CLIENT_ERROR;
X    return(iffp);
X    }
X
X/* ---------- CloseWGroup ----------------------------------------------*/
XIFFP CloseWGroup(old0)  GroupContext *old0; {
X    register GroupContext *old = old0;
X    IFFP iffp = IFF_OKAY;
X
X    if ( old->ckHdr.ckID != NULL_CHUNK )  /* didn't close the last chunk */
X        iffp = CLIENT_ERROR;
X    else if ( old->parent == NULL ) {     /* top level file context */
X        if (GWriteFlush(old->file) < 0)  iffp = DOS_ERROR;
X        }
X    else {                                /* update parent context */
X        old->parent->bytesSoFar += old->position - old->parent->position;
X        old->parent->position = old->position;
X        };
X    return(iffp);
X    }
X
X/* ---------- EndWGroup ------------------------------------------------*/
XIFFP EndWGroup(old)  GroupContext *old;  {
X    register GroupContext *parent = old->parent;
X    register IFFP iffp;
X
X    iffp = CloseWGroup(old);
X    IfIffp( PutCkEnd(parent) );
X    return(iffp);
X    }
X
X/* ---------- PutCk ----------------------------------------------------*/
XIFFP PutCk(context, ckID, ckSize, data)
X      GroupContext *context; ID ckID; LONG ckSize; BYTE *data; {
X    register IFFP iffp = IFF_OKAY;
X
X    if ( ckSize == szNotYetKnown )
X        iffp = CLIENT_ERROR;
X    IfIffp( PutCkHdr(context, ckID, ckSize) );
X    IfIffp( IFFWriteBytes(context, data, ckSize) );
X    IfIffp( PutCkEnd(context) );
X    return(iffp);
X    }
X
X/* ---------- PutCkHdr -------------------------------------------------*/
XIFFP PutCkHdr(context0, ckID, ckSize)
X      GroupContext *context0;  ID ckID;  LONG ckSize; {
X    register GroupContext *context = context0;
X    LONG minPSize = sizeof(ChunkHeader); /* physical chunk >= minPSize bytes*/
X
X    /* CLIENT_ERROR if we're already inside a chunk or asked to write
X     * other than one FORM, LIST, or CAT at the top level of a file */
X    /* Also, non-positive ID values are illegal and used for error codes.*/
X    /* (We could check for other illegal IDs...)*/
X    if ( context->ckHdr.ckID != NULL_CHUNK  ||  ckID <= 0 )
X        return(CLIENT_ERROR);
X    else if (context->parent == NULL)  {
X        switch (ckID)  {
X            case FORM:  case LIST:  case CAT:  break;
X            default: return(CLIENT_ERROR);
X            }
X        if (context->position != 0)
X            return(CLIENT_ERROR);
X        }
X
X    if ( Known(ckSize) ) {
X        if ( ckSize < 0 )
X            return(CLIENT_ERROR);
X        minPSize += ckSize;
X        };
X    if ( Known(context->bound)  &&
X         context->position + minPSize > context->bound )
X        return(CLIENT_ERROR);
X
X    context->ckHdr.ckID   = ckID;
X    context->ckHdr.ckSize = ckSize;
X    context->bytesSoFar   = 0;
X    if (0 >
X        GWrite(context->file, (BYTE *)&context->ckHdr, sizeof(ChunkHeader))
X        )
X        return(DOS_ERROR);
X    context->position += sizeof(ChunkHeader);
X    return(IFF_OKAY);
X    }
X
X/* ---------- IFFWriteBytes ---------------------------------------------*/
XIFFP IFFWriteBytes(context0, data, nBytes)
X      GroupContext *context0;  BYTE *data;  LONG nBytes; {
X    register GroupContext *context = context0;
X
X    if ( context->ckHdr.ckID == NULL_CHUNK  ||  /* not in a chunk */
X         nBytes < 0  ||                         /* negative nBytes */
X         (Known(context->bound)  &&             /* overflow context */
X            context->position + nBytes > context->bound)  ||
X         (Known(context->ckHdr.ckSize)  &&      /* overflow chunk */
X            context->bytesSoFar + nBytes > context->ckHdr.ckSize) )
X        return(CLIENT_ERROR);
X
X    if (0 > GWrite(context->file, data, nBytes))
X        return(DOS_ERROR);
X
X    context->bytesSoFar += nBytes;
X    context->position   += nBytes;
X    return(IFF_OKAY);
X    }
X
X/* ---------- PutCkEnd -------------------------------------------------*/
XIFFP PutCkEnd(context0)  GroupContext *context0; {
X    register GroupContext *context = context0;
X    WORD zero = 0;      /* padding source */
X
X    if ( context->ckHdr.ckID == NULL_CHUNK )  /* not in a chunk */
X        return(CLIENT_ERROR);
X
X    if ( context->ckHdr.ckSize == szNotYetKnown ) {
X        /* go back and set the chunk size to bytesSoFar */
X        if ( 0 >
XGSeek(context->file, -(context->bytesSoFar + sizeof(LONG)), OFFSET_CURRENT) ||
X             0 >
XGWrite(context->file, (BYTE *)&context->bytesSoFar, sizeof(LONG))  ||
X             0 >
XGSeek(context->file, context->bytesSoFar, OFFSET_CURRENT)  )
X            return(DOS_ERROR);
X        }
X    else {  /* make sure the client wrote as many bytes as planned */
X        if ( context->ckHdr.ckSize != context->bytesSoFar )
X            return(CLIENT_ERROR);
X        };
X
X    /* Write a pad byte if needed to bring us up to an even boundary.
X     * Since the context end must be even, and since we haven't
X     * overwritten the context, if we're on an odd position there must
X     * be room for a pad byte. */
X    if ( IS_ODD(context->bytesSoFar) ) {
X        if ( 0 > GWrite(context->file, (BYTE *)&zero, 1) )
X            return(DOS_ERROR);
X        context->position += 1;
X        };
X
X    context->ckHdr.ckID   = NULL_CHUNK;
X    context->ckHdr.ckSize = context->bytesSoFar = 0;
X    return(IFF_OKAY);
X    }
X
SHAR_EOF
echo "End of archive 3 (of 9)"
# if you want to concatenate archives, remove anything after this line
exit