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

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

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

[The latest and greatest version of Mandelvroom.  If you liked the old
version, you'll be crazy about this one.  Docs and projects are in the
binaries group.  ..bob]

# 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:
#	cmd.c
#	contour.c
# This is archive 1 of a 9-part kit.
# This archive created: Tue Jun 20 20:45:26 1989
echo "extracting cmd.c"
sed 's/^X//' << \SHAR_EOF > cmd.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 IntuiMessage handler (also referred to
X * as the command handler.)  This code implements a command-state state
X * machine.
X */
X
X#include "mandp.h"
X
Xextern struct Picture *ZoomedPict;
X
XBYTE State;
XBYTE Parse_rc;
X
XProcessCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  DecodeClass(Msg);         /* decode input by class */
X  PostProcessMsg(Msg);      /* set current pen, contour, or range */
X  DisplayMsg();             /* Display a message in the title bar */
X
X  if (State == IDLESTATE) {
X    SetNormPointer();
X  }
X}
X
X/*
X * This function serves the following purposes:
X *    1. Reacts to menu items and command gadgets (overriding whatever
X *       the outstanding state is.)
X *    2. Filters of messages that do not affect the state of
X *       user interaction (NEWSIZE, REFRESHWINDOW, CLOSEWINDOW...)
X *    3. It only allows MOUSEBUTTON messages to get past this
X *       routine if they are desired.
X */
X
XDecodeClass(Msg)
X  struct IntuiMessage *Msg;
X{
X  register struct Window  *Window = Msg->IDCMPWindow;
X  struct Picture *Pict;
X
X  switch( Msg->Class ) {
X
X         /* These Classes can cause State to be set */
X
X    case MENUPICK:
X         HandleMenuPick( Msg );
X         break;
X
X    case GADGETDOWN:
X         HandleGadgetCmd(Msg);
X         break;
X
X    case MOUSEBUTTONS:
X         /* filter unwanted SELECTDOWNS and SELECTUPS */
X         /* So that each of cmd routines below don't  */
X         /* have to ignore them                       */
X
X         if (Msg->IDCMPWindow == ContWind) {
X
X           SlideBarCmd(Msg);
X         } else {
X
X           Pict = (struct Picture *) Window->UserData;
X
X           if (Pict != NULL) {
X
X             /* ignore Project buttons outside the picture area */
X
X             if (Msg->Code == SELECTUP || Msg->Code == SELECTDOWN  &&
X                 MouseX >= Pict->LeftMarg &&
X                 MouseY >= Pict->TopMarg  &&
X                 MouseX <  Window->Width  - Pict->RightMarg &&
X                 MouseY <  Window->Height - Pict->BotMarg ) {
X
X               DecodeState(Msg);
X             }
X           }
X         }
X         break;
X
X         /* this message class cancels any command (i.e. clear state ) */
X
X    case CLOSEWINDOW:
X         CloseWinds( Window );
X         State = IDLESTATE;
X         break;
X
X         /* The response to these message classes depends on what we're
X          * doing.
X          */
X
X    case MOUSEMOVE:
X         DecodeState(Msg);
X         break;
X
X    case GADGETUP:
X         HandleGadgetCmd(Msg);
X      /* DecodeState(Msg); */
X         break;
X
X         /* these message classes do not modify state */
X
X    case ACTIVEWINDOW:
X         ActivatePict( Window );
X         break;
X
X    case NEWSIZE:
X         if (Window != BackWind) {
X           BorderWindow( Window );
X
X           if (Window->UserData) {
X             ScrollPictCmd(Msg);
X           }
X         }
X         break;
X
X    default:
X         printf("Unexpected msg class %04x\n",Msg->Class);
X         break;
X  }
X}
X
XDisplayMsg()
X{
X  char *c;
X  c = NULL;
X
X  switch(State) {
X  case COPYRIGHTSTATE:  c = "Copyright 1987,1989 Kevin Clague";        break;
X  case IDLESTATE:       c = "MandelVroom V2.0 by Kevin Clague";        break;
X  case SETCONTSTATE:    c = "You can set color or height";             break;
X  case ORBITSTATE:      c = "Press left mouse button in Project";      break;
X  case SETJULIASTATE:   c = "Press left mouse button in Mand Project"; break;
X  case ZOOMINSTATE:     c = "Place the Zoom box in a Project";         break;
X  case COPYRGBSTATE:    c = "Select a color pen to copy RGBs";         break;
X  case SPREADRGBSTATE:  c = "Select a color pen to spread RGBs";       break;
X  case XCHGRGBSTATE:    c = "Select a color pen to exchange RGBs";     break;
X  case CYCLERANGESTATE: c = "Select a color pen to complete range";    break;
X  case SMOOTHCONTSTATE: c = "Select a contour pen to smooth heights";  break;
X  case CUTCONTSTATE:    c = "Select a contour pen to cut a pattern";   break;
X  case COPYCONTSTATE:   c = "Select a contour pen to copy a pattern";  break;
X  case PASTECONTSTATE:  c = "Select a contour pen to paste a pattern"; break;
X  case HELPSTATE:       c = "Select a menu or gadget for help";        break;
X  case SCROLLPICTSTATE: c = "Use the mouse to pan the current project";break;
X  case SETHEIGHTSTATE:  c = "Mouse changes contour's lower bound";     break;
X  case SLIDERGBSTATE:   c = "Move the mouse to change RGB values";     break;
X  case SLIDEBARSTATE:   c = "Move the mouse to scroll contours";       break;
X  case RESIZEZOOMSTATE: c = "Move the mouse to size the Zoom box";     break;
X  case ZOOMDRAGSTATE:   c = "Move the mouse to drag the Zoom box";     break;
X  case PROPRESIZESTATE: c = "Move the mouse to size the Zoom box";     break;
X  case SCROLLHELPSTATE: c = "Move the mouse to scroll help info.";     break;
X  case SLIDESPEEDSTATE: c = "Move the mouse to change speed";          break;
X  }
X
X  /* only display the message if it is a new one */
X
X  if (c && screen->Title != c) {
X    SetWindowTitles( CurWind, (char *) -1, c );
X  }
X}
X
XDecodeState(Msg)
X  struct IntuiMessage *Msg;
X{
X  switch(State) {
X    case COPYRIGHTSTATE:
X    case IDLESTATE:        DecodeMsg(Msg);      break;
X    case COPYRGBSTATE:     CopyRGBCmd(Msg);     break;
X    case SPREADRGBSTATE:   SpreadRGBCmd(Msg);   break;
X    case XCHGRGBSTATE:     ExchangeRGBCmd(Msg); break;
X    case SLIDERGBSTATE:    SlideRGBCmd(Msg);    break;
X    case SETHEIGHTSTATE:   SetHeightCmd(Msg);   break;
X    case SETCONTSTATE:     SetContCmd(Msg);     break;
X    case SMOOTHCONTSTATE:  SmoothContCmd(Msg);  break;
X    case CUTCONTSTATE:     CutContCmd(Msg);     break;
X    case COPYCONTSTATE:    CopyContCmd(Msg);    break;
X    case PASTECONTSTATE:   PasteContCmd(Msg);   break;
X    case SLIDEBARSTATE:    SlideBarCmd(Msg);    break;
X    case ORBITSTATE:       OrbitCmd(Msg);       break;
X    case ZOOMINSTATE:      ZoomInCmd(Msg);      break;
X    case RESIZEZOOMSTATE:  ResizeZoomCmd(Msg);  break;
X    case QUERYHEIGHTSTATE: QueryHeightCmd(Msg); break;
X    case ZOOMDRAGSTATE:    ZoomDragCmd(Msg);    break;
X    case PROPRESIZESTATE:  PropResizeCmd(Msg);  break;
X    case SETJULIASTATE:    SetJuliaCmd(Msg);    break;
X    case SLIDESPEEDSTATE:  SlideSpeedCmd(Msg);  break;
X    case CYCLERANGESTATE:  CycleRangeCmd(Msg);  break;
X    case SCROLLHELPSTATE:  ScrollHelpCmd(Msg);  break;
X    case SCROLLPICTSTATE:  ScrollPictCmd(Msg);  break;
X  }
X}
X
X/*
X * Set Current pen or current contour.
X */
X
XPostProcessMsg(Msg)
X  struct IntuiMessage *Msg;
X{
X  register struct Window  *Window = Msg->IDCMPWindow;
X  struct Gadget *gadget;
X  int    id;
X
X  if (Msg->Class == GADGETDOWN) {
X
X    gadget = (struct Gadget *) Msg->IAddress;
X    id = gadget->GadgetID;
X    switch (WIND_TYPE(id)) {
X
X      case PALTYPE:
X           if (GADG_TYPE(id) == PALPENS) {
X             SetCurPen(GADG_NUM(id));
X           }
X           break;
X
X      case CONTYPE:
X           if ((GADG_TYPE(id) == CONTSELS || GADG_TYPE(id) == CONTPOTS) &&
X             id != CONTLAST) {
X
X             SelContCmd(Msg);
X           }
X    }
X  }
X}
X
X/*
X * This is mostly for MOUSEBUTTON related commands (where the MOUSEBUTTONS
X * are commands like drag, close or resize zoom box.)
X */
X
XDecodeMsg(Msg)
X  struct IntuiMessage *Msg;
X{
X  switch( Msg->Class ) {
X
X    case MOUSEBUTTONS:
X         /* query height */
X         DecodePictMouseButtons( Msg );
X         break;
X  }
X}
X
XHandleGadgetCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  struct Gadget *gadget;
X  int id, type, num;
X
X  if (State == HELPSTATE) {
X    HelpGadgetCmd(Msg);
X    State = IDLESTATE;
X    return;
X  }
X
X  gadget = (struct Gadget *) Msg->IAddress;
X
X  id   = gadget->GadgetID;
X  type = GADG_TYPE(id);
X
X  switch( WIND_TYPE(id)) {
X
X    case PICTTYPE:
X         State = IDLESTATE;
X         switch (id) {
X           case PICTGEN:   GenerateCmd(Msg); break;
X           case PICTIN:    ZoomInCmd(Msg);   break;
X           case PICTOUT:   ZoomOutCmd(Msg);  break;
X           case PICTJULIA: SetJuliaCmd(Msg); break;
X         }
X         MakeCurProj((struct Picture *) Msg->IDCMPWindow->UserData);
X         break;
X
X    case PALTYPE:
X         StopCycle();
X         switch (type) {
X           case PALPENS:          DecodeState(Msg);    break;
X           case PALPOTS:          SlideRGBCmd(Msg);    break;
X           case PALCNTLS:
X                switch (id) {
X                  case PALCOPY:   CopyRGBCmd(Msg);     break;
X                  case PALRANGE:  SpreadRGBCmd(Msg);   break;
X                  case PALEXCG:   ExchangeRGBCmd(Msg); break;
X                }
X                break;
X         }
X         break;
X
X    case CYCTYPE:
X         switch (type) {
X           case CYCRNUMS:         SelRangeCmd(Msg);   break;
X           case CYCCNTLS:
X                switch (id) {
X                  case CYCSPEED:  SlideSpeedCmd(Msg); break;
X                  case CYCRANGE:  CycleRangeCmd(Msg); break;
X                  case CYCDIR:    ToggleDirCmd(Msg);  break;
X                  case CYCON:     CycleOnOffCmd(Msg); break;
X                }
X                break;
X
X         }
X         break;
X
X    case CONTYPE:
X         StopCycle();
X         switch (type) {
X           case CONTSELS:         DecodeState(Msg);   break;
X           case CONTPOTS:         SetHeightCmd(Msg);  break;
X           case CONTCNTLS:
X                switch (id) {
X                  case CONTRECOL: PaintCmd(Msg);      break;
X                  case CONTSET:   SetContCmd(Msg);    break;
X                  case CONTSMTH:  SmoothContCmd(Msg); break;
X                  case CONTCUT:   CutContCmd(Msg);    break;
X                  case CONTCOPY:  CopyContCmd(Msg);   break;
X                  case CONTPASTE: PasteContCmd(Msg);  break;
X                  case CONTCEIL:  CeilingCmd(Msg);    break;
X                }
X                break;
X         }
X         break;
X
X    case ORBTTYPE:
X         OrbitCmd(Msg);
X         break;
X
X    case HELPTYPE:
X         switch (id) {
X
X           case HELPUP:
X           case HELPDOWN:
X                Page_File(id);
X                break;
X
X           case HELPSCROLL:
X                ScrollHelpCmd(Msg);
X                break;
X         }
X  }
X}
X
XDecodePictMouseButtons( Msg )
X  struct IntuiMessage *Msg;
X{
X  register struct Node    *zNode;
X  register struct Picture *ZoomPict;
X  register struct Picture *Pict;
X           struct Picture *PictAddr();
X  int rc;
X
X  Pict = (struct Picture *) Msg->IDCMPWindow->UserData;
X
X  zNode = Pict->zList.lh_Head;
X
X  rc = NOTHINGHIT;
X
X  while ( rc == NOTHINGHIT && zNode->ln_Succ ) {
X
X    ZoomPict = PictAddr( zNode );
X
X    switch( rc = CheckPictZoomBox( ZoomPict ) ) {
X
X      case ZOOMCLOSEHIT: /* User closed the zoom box */
X           ClearZoomBox( ZoomPict );
X           break;
X
X      case ZOOMDRAGHIT:
X           ZoomedPict = ZoomPict;
X           ZoomDragCmd(Msg);
X           break;
X
X      case ZOOMRESIZEHIT:
X           ZoomedPict = ZoomPict;
X           ResizeZoomCmd(Msg);
X           break;
X
X      case PROPRESIZEHIT:
X           ZoomedPict = ZoomPict;
X           PropResizeCmd(Msg);
X           break;
X    }
X
X    zNode = zNode->ln_Succ;
X  }
X
X  if (rc == NOTHINGHIT) {
X    QueryHeightCmd(Msg);
X  }
X}
SHAR_EOF
echo "extracting contour.c"
sed 's/^X//' << \SHAR_EOF > contour.c
X/*
X * MandelVroom 2.0
X *
X * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
X *
X * All rights reserved.
X *
X * Permission is hereby granted to distribute this program's source
X * executable, and documentation for non-comercial purposes, so long as the
X * copyright notices are not removed from the sources, executable or
X * documentation.  This program may not be distributed for a profit without
X * the express written consent of the author Kevin L. Clague.
X *
X * This program is not in the public domain.
X *
X * Fred Fish is expressly granted permission to distribute this program's
X * source and executable as part of the "Fred Fish freely redistributable
X * Amiga software library."
X *
X * Permission is expressly granted for this program and it's source to be
X * distributed as part of the Amicus Amiga software disks, and the
X * First Amiga User Group's Hot Mix disks.
X *
X * contents: this file contains the code to open and close the contour
X * palette tool.  It also contains the code that implements the contour
X * commands.
X */
X
X#include "mandp.h"
X
XUBYTE ContOpen;
X
Xstruct Window *ContWind;
X
XBYTE ContTitle[80];
X
Xstruct NewWindow NewCont = {
X   0,200-80,                 /* start position           */
X   320,200,                  /* 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   REPORTMOUSE,
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,320,200,            /* sizing                   */
X   CUSTOMSCREEN              /* type of screen           */
X   };
X
X
XSHORT Ceiling = 1023;
X
XSHORT  NumContours = NUMCONTS;
XSHORT  FirstContour = 0;
XSHORT  SaveFirstCont = 0;
X
Xint    CurContour;
X
Xstruct Gadget *ContGadget[DISPCONTS];
Xstruct Gadget *SelGadget[DISPCONTS];
X
XUBYTE  Pattern[NUMCONTS+4];
XSHORT  PattSize;
X
Xstatic struct Gadget *ModGadget;
X
Xint    BarHotSpot;
X
XLONG BarTop;
XLONG BarBot;
XLONG BarLeft;
XLONG BarRight;
XLONG BarWidth;
XLONG BarBoxTop;
XLONG BarBoxBot;
X
Xint ScaledFirst;
X
Xstruct ContHoriz {
X  int CmdLeft;
X  int BarLeft;
X  int BarWidth;
X  int PenLeft;
X  int PenWidth;
X};
X
Xstruct ContVert {
X  int CmdTop;
X  int BarTop;
X  int BarHeight;
X  int PenTop;
X  int PenHeight;
X};
X
Xstatic struct ContHoriz  Horiz_I     = {  3,   8,  262,   8, 6*33 };
Xstatic struct ContHoriz  Horiz_II    = {  3,   8,  524,   8,12*32 + 4};
Xstatic struct ContVert   Verticle_I  = { 11,   31,  10,  47, 42   };
Xstatic struct ContVert   Verticle_II = { 11,   31,  14,  52, 82  };
X
Xstatic struct ContHoriz *CurH = &Horiz_I;
Xstatic struct ContVert  *CurV = &Verticle_I;
X
X
X/*
X * Contour related commands
X */
X
X/* Paint Command */
X
XPaintCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  ReColor( CurPict );
X  DisplayBeep(screen);
X
X  if ( CurPict->DrawPict ) {
X    ZoomBox( CurPict );
X  }
X}
X
XSelContCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  struct Gadget *gadget;
X
X  gadget = (struct Gadget *) Msg->IAddress;
X
X  SetCurCont(GADG_NUM(gadget->GadgetID));
X}
X
XSetHeightCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  struct Window *Window;
X  static struct Gadget *gadget;
X  struct PropInfo *propinfo;
X  static int knobhit;
X
X  Window = Msg->IDCMPWindow;
X
X  switch( Msg->Class ) {
X
X    case GADGETDOWN:
X         gadget = (struct Gadget *) Msg->IAddress;
X         propinfo = (struct PropInfo *) gadget->SpecialInfo;
X
X         if (knobhit = propinfo->Flags & KNOBHIT) {
X           ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
X           State  = SETHEIGHTSTATE;
X         } else {
X           SetContourHeight(gadget);
X         }
X         break;
X
X    case MOUSEMOVE:
X         SetContourHeight(gadget);                         /* potentio */
X         break;
X
X    case GADGETUP:
X         if (knobhit) {
X           ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
X           ModAll();
X         } else {
X           SetContourHeight(gadget);                         /* potentio */
X           ShowValid();
X         }
X         State = IDLESTATE;
X         break;
X  }
X}
X
XSetContCmd(Msg)  /* user can set height or pen */
X  struct IntuiMessage *Msg;
X{
X  struct Window  *Window;
X  struct Gadget  *gadget;
X  struct Picture *Pict;
X
X  Window = Msg->IDCMPWindow;
X  gadget = (struct Gadget *) Msg->IAddress;
X
X  switch( Msg->Class ) {
X
X    case GADGETDOWN:
X         switch( WIND_TYPE(gadget->GadgetID) ) {
X
X           case CONTYPE:
X                if (gadget->GadgetID == CONTSET) {
X
X                  SetToPointer();
X                  State = SETCONTSTATE;
X                }
X                break;
X
X           case PALTYPE:
X                if (GADG_TYPE(gadget->GadgetID) == PALPENS) {
X
X                  State = IDLESTATE;
X                  SetContourPen( GADG_NUM(gadget->GadgetID) );
X                }
X                break;
X         }
X         break;
X
X    case MOUSEBUTTONS:             /* selecting height from the picture */
X
X         if (Msg->Code == SELECTDOWN) {
X           Pict = (struct Picture *) Window->UserData;
X           if ( Pict ) {
X             State = IDLESTATE;
X             DoWindowPick(Pict,MouseX,MouseY);
X           }
X         }
X         break;
X  }
X}
X
XSmoothContCmd(Msg)  /* Smooth heights between two pens */
X  struct IntuiMessage *Msg;
X{
X  struct Gadget  *gadget;
X  int    t;
X
X  /* Need contour selection to complete */
X
X  gadget = (struct Gadget *) Msg->IAddress;
X
X  if (Msg->Class == GADGETDOWN) {
X
X    if (gadget->GadgetID == CONTSMTH) { /* Smooth command gadget */
X
X      SetToPointer();
X      State = SMOOTHCONTSTATE;
X    } else {
X
X      t = GADG_TYPE(gadget->GadgetID);
X
X      if (t == CONTSELS || t == CONTPOTS) {
X
X        t = GADG_NUM(gadget->GadgetID);
X
X        /* smooth to last does decrement by one */
X
X        if (t == CONTLAST)
X          *(CurPict->Heights + t) = 0x7fff;
X
X        SmoothContours(CurContour, t);
X        State = IDLESTATE;
X      }
X    }
X  }
X}
X
XCutContCmd(Msg)  /* Cut Pens between two contours */
X  struct IntuiMessage *Msg;
X{
X  struct Gadget  *gadget;
X  int    t;
X
X  /* Need contour selection to complete */
X
X  gadget = (struct Gadget *) Msg->IAddress;
X
X  if (Msg->Class == GADGETDOWN) {
X
X    if (gadget->GadgetID == CONTCUT) { /* Cut command gadget */
X
X      SetToPointer();
X      State = CUTCONTSTATE;
X    } else {
X
X      t = GADG_TYPE(gadget->GadgetID);
X
X      if (t == CONTSELS || t == CONTPOTS) {
X
X        t = GADG_NUM(gadget->GadgetID);
X
X        CopyPattern(   CurContour, t);
X        DeleteContours(CurContour, t);
X        State = IDLESTATE;
X      }
X    }
X  }
X}
X
XCopyContCmd(Msg)  /* Copy Pens between two contours */
X  struct IntuiMessage *Msg;
X{
X  struct Gadget  *gadget;
X  int    t;
X
X  /* Need contour selection to complete */
X
X  gadget = (struct Gadget *) Msg->IAddress;
X
X  if (Msg->Class == GADGETDOWN)  {
X    if (WIND_TYPE(gadget->GadgetID) == CONTYPE) {
X
X      if (gadget->GadgetID == CONTCOPY) { /* Copy command gadget */
X
X        SetToPointer();
X        State = COPYCONTSTATE;
X      } else {
X
X        t = GADG_TYPE(gadget->GadgetID);
X
X        if (t == CONTSELS || t == CONTPOTS) {
X
X          CopyPattern( CurContour, GADG_NUM(gadget->GadgetID));
X          State = IDLESTATE;
X        }
X      }
X    } else
X    if (WIND_TYPE(gadget->GadgetID) == PALTYPE) {
X      SetPenPattern(CurPen, GADG_NUM(gadget->GadgetID));
X      State = IDLESTATE;
X    }
X  }
X}
X
XPasteContCmd(Msg)  /* Paste pens into contours */
X  struct IntuiMessage *Msg;
X{
X  struct Gadget  *gadget;
X  int    t;
X
X  /* Need contour selection to complete */
X
X  gadget = (struct Gadget *) Msg->IAddress;
X
X  if (Msg->Class == GADGETDOWN) {
X
X    if (gadget->GadgetID == CONTPASTE) { /* Paste command gadget */
X
X      SetToPointer();
X      State = PASTECONTSTATE;
X    } else {
X
X      t = GADG_TYPE(gadget->GadgetID);
X
X      if (t == CONTSELS || t == CONTPOTS) {
X
X        PastePattern( CurContour, GADG_NUM(gadget->GadgetID));
X        State = IDLESTATE;
X      }
X    }
X  }
X}
X
XCeilingCmd(Msg)  /* Respond to ceiling gadget */
X  struct IntuiMessage *Msg;
X{
X  struct Gadget  *gadget;
X  struct PropInfo *PropInfo;
X  ULONG  VertPot;
X
X  extern SHORT    Ceiling;
X
X  if ( Msg->Class == GADGETUP ) {
X
X    /* Need gadget up to complete */
X
X    gadget = (struct Gadget *) Msg->IAddress;
X    PropInfo = (struct PropInfo *) gadget->SpecialInfo;
X
X    VertPot  = PropInfo->VertPot;
X    VertPot ^= 0xffff;
X    VertPot += 1;
X    Ceiling = VertPot * CurPict->MaxIteration >> 16;
X
X    ModAll();
X    State = IDLESTATE;
X  }
X}
X
XSlideBarCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  struct Window *Window;
X  static SavedState;
X
X  Window = Msg->IDCMPWindow;                  /* had better be ContWind */
X
X  switch( Msg->Class ) {
X
X    case MOUSEBUTTONS:                        /* slide is starting */
X         switch( Msg->Code ) {
X
X           case SELECTDOWN:                   /* ImmediateCmd() filters */
X                if (InBarBox()) {
X                  StartBarDrag();
X                  ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
X                  SavedState = State;
X                  State = SLIDEBARSTATE;
X                }
X                break;
X
X           case SELECTUP:                     /* slide is stoping */
X                if (State == SLIDEBARSTATE) {
X                  ModAll();
X                  ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
X                  State = SavedState;
X                }
X                break;
X         }
X         break;
X
X    case MOUSEMOVE:
X         DragBarBox();                        /* slide the bar */
X         break;
X  }
X}
X
XContNum(num)
X  int num;
X{
X  if (num == 32)
X    return(255);
X  else
X    return(num+FirstContour);
X}
X
XRefreshContours()
X{
X  if ( ContWind ) {
X
X    Ceiling = CurPict->MaxIteration;
X    DrawColorBox( ScaledFirst );
X    DrawColorBar();
X    ReDispPens();
X    ModAll();
X  }
X}
X
XInBarBox()
X{
X  return(MouseX >= BarLeft + ScaledFirst             &&
X         MouseX <= BarLeft + BarWidth  + ScaledFirst &&
X         MouseY >= BarBoxTop                         &&
X         MouseY <= BarBoxBot                             );
X}
X
XStartBarDrag()
X{
X  BarHotSpot = MouseX - BarLeft - ScaledFirst;
X}
X
XDrawColorBar()
X{
X  register LONG x,s,sx;
X  register LONG dx  = XScale + 1;
X
X  register struct RastPort *Rp = ContWind->RPort;
X
X  register UBYTE *ColorPtr = CurPict->Pens;
X
X  sx = BarLeft;
X
X  for (x = 0; x < NumContours; x++ ) {
X
X    SetAPen( Rp, (long) *ColorPtr++ );
X
X    for (s = 0; s < dx; s++) {
X
X      Move(Rp, sx,   BarTop );
X      Draw(Rp, sx++, BarBot );
X    }
X  }
X  DrawColorBox( ScaledFirst );
X}
X
XDrawColorBox( Contour )
X  int Contour;
X{
X  register LONG Left = BarLeft + Contour;
X
X  DrawBox( ContWind, Left, BarBoxTop, Left + BarWidth, BarBoxBot);
X}
X
XDragBarBox()
X{
X  register int CurX;
X  static int OldCurX;
X
X  CurX = MouseX;
X
X  if (CurX == OldCurX)
X    return;
X
X  OldCurX = CurX;
X
X  if ( CurX < BarLeft + BarHotSpot )
X    CurX = BarLeft + BarHotSpot;
X  else
X  if ( CurX > BarRight - BarWidth + BarHotSpot )
X    CurX = BarRight - BarWidth + BarHotSpot;
X
X  DrawColorBox( ScaledFirst );
X  DrawContBox( CurContour, NORMALPEN );
X
X  ScaledFirst = (CurX - BarLeft - BarHotSpot);
X  FirstContour = ScaledFirst >> XScale;
X
X  DrawColorBox( ScaledFirst );
X  DrawContBox( CurContour, HIGHLIGHTPEN );
X
X  ReDispPens();
X}
X
XSetContourPen( Pen )
X  USHORT Pen;
X{
X  register struct Image *Image;
X
X  Image = (struct Image *) SelGadget[ CurContour ]->GadgetRender;
X
X  Image = Image->NextImage;
X  Image->PlaneOnOff = Pen;
X
X  RefreshGList( SelGadget[ CurContour ], ContWind, NULL, 1);
X
X  *(CurPict->Pens + CurContour + FirstContour) = Pen;
X
X  UpdateColorBar( Pen );
X}
X
XUpdateColorBar( Pen )
X  USHORT Pen;
X{
X  register LONG ContourPos;
X  register UBYTE Overlap;
X  register LONG  x, sx;
X
X  register struct RastPort *Rp = ContWind->RPort;
X
X  ContourPos = ((CurContour + FirstContour) << XScale);
X
X  Overlap =
X      ContourPos == ScaledFirst || ContourPos == ScaledFirst + BarWidth;
X
X  if ( Overlap )
X    DrawColorBox( ScaledFirst );
X
X  sx = BarLeft + ((CurContour + FirstContour) << XScale);
X
X  SetAPen( Rp, (long) Pen );
X
X  for (x = 0; x < XScale + 1; x++) {
X
X    Move(Rp, sx,   BarTop );
X    Draw(Rp, sx++, BarBot );
X  }
X
X  if ( Overlap )
X    DrawColorBox( ScaledFirst );
X}
X
XSetCurCont(ContNum)
X  int ContNum;  /* relative to FirstCont */
X{
X  if (ContNum == CONTLAST)
X    return;
X
X  SaveFirstCont = FirstContour;
X
X  DrawContBox(CurContour, NORMALPEN );
X  DrawContBox(ContNum, HIGHLIGHTPEN );
X
X  CurContour = ContNum;
X  SetContTitle(ContNum);
X}
X
XSetContourHeight(gadget)
X  struct Gadget *gadget;
X{
X  struct  PropInfo *PropInfo;
X  ULONG   VertPot;
X  SHORT  *Contour;
X  int     ContNum;
X
X  PropInfo = (struct PropInfo *) gadget->SpecialInfo;
X
X  VertPot  = PropInfo->VertPot;
X
X  VertPot ^= 0xffff;
X  VertPot += 1;
X
X  ContNum = GADG_NUM(gadget->GadgetID);
X  Contour = CurPict->Heights + FirstContour + ContNum;
X
X  if (*Contour <= Ceiling)
X    *Contour = VertPot * Ceiling >> 16;
X
X  SetCurCont(ContNum);
X}
X
X/*
X * Set the contour window's new title
X */
XSetContTitle(ContNum)
X  int ContNum;
X{
X  register SHORT Low, High;
X  register SHORT *Contour;
X  register UBYTE *Color;
X
X  register char *fmt1 = "C: %-3d  P: %-2d  H: %3d-%d";
X  register char *fmt2 = "C: %-3d  P: %-2d  H: %3d";
X
X  ContNum += FirstContour;
X
X  Contour = CurPict->Heights + ContNum;
X
X  Color = CurPict->Pens + ContNum;
X
X  High = *Contour;
X
X  if (ContNum != 0) {
X    Low  = *(Contour - 1);
X
X    if (Low == High || Low - High == 1) {
X      sprintf(ContTitle, fmt2, ContNum, *Color, High);
X    } else {
X      if (Low < High)
X        sprintf(ContTitle, fmt2, ContNum, *Color, High);
X      else
X        sprintf(ContTitle, fmt1, ContNum, *Color, Low - 1, High);
X    }
X  } else {
X
X    sprintf(ContTitle, fmt2, ContNum, *Color, High);
X  }
X  SetWindowTitles(ContWind, ContTitle, NULL);
X}
X
X/*
X * Set Selection's pen
X */
XDrawContBox(Contour, pen)
X  int  Contour;
X  LONG pen;
X{
X  register LONG Left, Right, Top, Bottom;
X  register struct RastPort *Rp = ContWind->RPort;
X
X  static LONG LastCont;
X
X  int Cont;
X
X  if ( pen == NORMALPEN ) {
X
X    Cont = LastCont;
X  } else {
X
X    LastCont = Cont = Contour + SaveFirstCont - FirstContour;
X  }
X
X  if (Cont >= 0 && Cont < DISPCONTS) {
X
X    Left = (6 << XScale) * Cont + CurH->PenLeft - 1;
X    Right = Left + (4 << XScale) + 2 + XScale;
X
X    Top = CurV->PenTop - 1;
X    Bottom = Top + (4 << YScale) + 2 + YScale;
X
X    SetDrMd(Rp, (LONG) JAM1);
X    SetAPen(Rp, pen);
X    /*
X     * Draw the new box
X     */
X    Move(Rp, Left,  Top   );
X    Draw(Rp, Right, Top   );
X
X    if (pen == HIGHLIGHTPEN) SetAPen( Rp, SHADOWPEN );
X
X    Draw(Rp, Right, Bottom);
X    Draw(Rp, Left,  Bottom);
X
X    SetAPen( Rp, (long) pen );
X
X    Draw(Rp, Left,  Top+1 );
X  }
X} /* DrawContBox */
X
X/*
X *  There was a window pick. Do what we need to do to service it
X */
XDoWindowPick(Pict,MouseX,MouseY)
X  register struct Picture *Pict;
X  register SHORT MouseX,MouseY;
X{
X  register struct Window *Window = CurPict->Window;
X  register USHORT Height;
X
X  if (Pict->Flags & NO_RAM_GENERATE)
X    return;
X
X  Height = HeightPicked( Pict, MouseX, MouseY );
X  *(CurPict->Heights + CurContour + FirstContour) = Height;
X  ModAll();
X}
X
Xint
XHeightPicked( Pict, MouseX, MouseY )
X  register struct Picture *Pict;
X  register SHORT MouseX,MouseY;
X{
X  return( *(Pict->Counts + (MouseY - Pict->TopMarg) * Pict->CountX +
X                            MouseX - Pict->LeftMarg));
X}
X
X/*
X *  Smooth the heights over a subrange of contours
X */
XSmoothContours(First,Second)
X  int First;
X  int Second;
X{
X  register USHORT Temp;
X  register SHORT *StartP,*EndP;
X  register float Diff,Start;
X
X  First += SaveFirstCont;
X  Second = ContNum(Second);
X
X  if (Second-First != 0) {
X
X    if (Second < First) {
X      Temp = First;
X      First = Second;
X      Second = Temp;
X    }
X
X    StartP = CurPict->Heights + First;
X    EndP   = CurPict->Heights + Second;
X
X    Start =  (float) *StartP;
X    Diff  = ((float) *EndP - Start) / (float) (Second-First);
X
X    if (Diff > -1.0) {
X      Diff = -1.0;
X    }
X
X    for ( ; First < Second && Start > 0; First++)
X      *(StartP++ + 1) = (SHORT) (Start += Diff);
X
X    if (Start == 0) {
X      for ( ; First < NumContours; First++) {
X        *StartP++ = 0;
X      }
X    }
X
X    ModAll();
X  }
X} /* SmoothContours */
X
X/*
X *  Copy the pattern from the palette into pattern area
X */
XCopyPattern(First,Second)
X  int First, Second;
X{
X  register int i, spacing;
X  register UBYTE *ColorPatt = CurPict->Pens;
X  register struct StringInfo *String =
X                  (struct StringInfo *) ModGadget->SpecialInfo;
X
X  LONG Spacing;
X
X  UBYTE *Last = ColorPatt + NUMCONTS;
X
X  sscanf( String->Buffer, "%d", &Spacing );
X  spacing = Spacing;
X
X  if ( spacing <= 0 ) {
X    return;
X  }
X
X  First += SaveFirstCont;
X  Second = ContNum(Second);
X
X  ColorPatt += First;
X
X  if (First < Second) {
X
X    PattSize = Second - First + 1;
X  } else {
X
X    PattSize = First - Second + 1;
X    spacing = -spacing;
X  }
X
X  for ( i = 0; i < PattSize && ColorPatt >= CurPict->Pens && ColorPatt < Last;
X        i++ ) {
X
X    Pattern[ i ] = *ColorPatt;
X    ColorPatt += spacing;
X  }
X  PattSize = i;
X} /* CopyPattern */
X
X/*
X *  Set the pattern register to a list of consecutive pens
X */
XSetPenPattern(First,Second)
X  register int First, Second;
X{
X  register LONG i, spacing;
X
X  PattSize = Second - First;
X
X  if ( PattSize < 0 ) {
X    PattSize = - PattSize;
X    spacing = -1;
X  } else {
X    spacing =  1;
X  }
X  PattSize += 1;
X
X  for ( i = 0; i < PattSize; i++) {
X    Pattern[ i ] = First;
X    First += spacing;
X  }
X} /* SetPenPattern */
X
X/*
X *  Paste the pattern from the palette
X */
XPastePattern(First,Second)
X  register int First, Second;
X{
X  register int i, Spacing;
X  register UBYTE *ColorPatt = CurPict->Pens;
X  register struct StringInfo *String =
X              (struct StringInfo *) ModGadget->SpecialInfo;
X
X  LONG spacing;
X
X  register UBYTE *Last = ColorPatt + NUMCONTS;
X
X  if ( PattSize == 0 )
X    return;
X
X  sscanf( String->Buffer, "%d", &spacing );
X
X  Spacing = spacing;
X
X  if ( Spacing < 1 )
X    return;
X
X  First  += SaveFirstCont;
X  ColorPatt += First;
X  Second = ContNum(Second);
X
X  if (First < Second ) {
X
X    for ( i = 0; First <= Second && ColorPatt < Last;
X                 First += Spacing, i++ ) {
X
X      if ( i == PattSize )
X        i = 0;
X
X      *ColorPatt = Pattern[ i ];
X
X      ColorPatt += Spacing;
X    }
X  } else {
X
X    if (Second == 0) Second = 1;
X
X    for ( i = 0; Second < First && ColorPatt >= CurPict->Pens;
X                 First -= Spacing, i++ ) {
X
X      if ( i == PattSize )
X        i = 0;
X
X      *ColorPatt = Pattern[ i ];
X
X      ColorPatt -= Spacing;
X    }
X  }
X  DrawColorBox( ScaledFirst );
X  DrawColorBar();
X  ReDispPens();
X} /* PastePattern */
X
X/*
X *  Delete some contours from the contour list
X */
XDeleteContours(First,Second)
X  register int First, Second;
X{
X  register USHORT Temp;
X  register UBYTE *StartCP, *EndCP;
X  register int    Size,i;
X
X  struct StringInfo *String =
X         (struct StringInfo *) ModGadget->SpecialInfo;
X
X  LONG spacing;
X
X  sscanf( String->Buffer, "%d", &spacing );
X
X  if ( spacing < 1 )
X    return;
X
X  First  += SaveFirstCont;
X  Second = ContNum(Second);
X  Size = Second - First;
X
X  if (Size) {
X
X    if (Size < 0) {
X      Temp = First;
X      First = Second;
X      Second = Temp;
X
X      Size = -Size;
X      Temp = Size % spacing;
X      First += Temp;
X    }
X
X    StartCP = CurPict->Pens + First;
X
X    if (spacing == 1) {
X      EndCP = CurPict->Pens + Second;
X
X      Second = NUMCONTS - Second;
X
X      for (i = 0; i < Second; i++) {
X        *StartCP++ = *EndCP++;
X      }
X    } else {
X      EndCP   = StartCP + 1;
X
X      for ( ; First < Second; First += spacing ) {
X        for ( i = 0; i < spacing - 1; i++) {
X          *StartCP++ = *EndCP++;
X        }
X        EndCP++;
X      }
X    }
X
X    while ( StartCP < CurPict->Pens + NUMCONTS ) {
X      *StartCP++ = NORMALPEN;
X    }
X
X    DrawColorBox( ScaledFirst );
X    DrawColorBar();
X    ReDispPens();
X    ModAll();
X  }
X} /* DeleteContours */
X
X/*
X * ReDisplay all the contour potentiometer gadgets
X */
XModAll()
X{
X  register SHORT i;
X  register USHORT VertPot;
X  register USHORT Height;
X  register USHORT PrevHeight;
X
X  register struct Gadget *PropGad = (struct Gadget *) ContGadget[0];
X  register struct Picture *Pict = CurPict;
X
X  if (Ceiling > 0) {
X
X    if (FirstContour == 0) {
X
X      PrevHeight = Pict->Heights[ 0 ] + 1;
X
X    } else {
X
X      for (i = 0; i < FirstContour - 1; i++) {
X
X        Height = Pict->Heights[ i ];
X
X        if (Height < PrevHeight) {
X          PrevHeight = Height;
X        }
X      }
X    }
X
X    for (i = 0; i < DISPCONTS; i++) {
X
X      Height = CurPict->Heights[ i + FirstContour ];
X
X      SetPotPen( PropGad, PrevHeight, Height );
X
X      if (Height < PrevHeight)
X        PrevHeight = Height;
X
X      if ( Height < Ceiling) {
X
X        VertPot  = (Height<<16)/Ceiling;
X        if (VertPot > 0)
X          VertPot--;
X        VertPot ^= 0xffff;
X      } else
X
X        VertPot = (USHORT) 0;
X
X      NewModifyProp( PropGad, ContWind, NULL, FREEVERT|PROPBORDERLESS, 0L,
X               (long) VertPot, 0L, 0xffff/Ceiling, 1L);
X
X      PropGad = PropGad->NextGadget;
X    }
X  }
X} /* ModAll */
X
X/*
X * ReDisplay all the contour potentiometer gadgets
X */
XShowValid()
X{
X  register SHORT i;
X  register USHORT Height;
X  register USHORT PrevHeight;
X
X  register struct Gadget *PropGad = (struct Gadget *) ContGadget[0];
X  register struct Picture *Pict = CurPict;
X
X  if (Ceiling > 0) {
X
X    if (FirstContour == 0)
X      PrevHeight = Pict->Heights[ 0 ] + 1;
X    else
X      PrevHeight = Pict->Heights[ FirstContour - 1 ];
X
X    for (i = 0; i < DISPCONTS; i++) {
X
X      Height = CurPict->Heights[ i + FirstContour ];
X
X      if (SetPotPen( PropGad, PrevHeight, Height )) {
X        RefreshGList( PropGad, ContWind, NULL, 1);
X      }
X
X      if (Height < PrevHeight)
X        PrevHeight = Height;
X
X      PropGad = PropGad->NextGadget;
X    }
X  }
X} /* ShowValid */
X
XSetPotPen( PropGad, PrevHeight, Height )
X  register struct Gadget *PropGad;
X  register USHORT PrevHeight;
X  register USHORT Height;
X{
X  register int place,color;
X  register struct Image *Image;
X  extern int Num_vp_Colors;
X
X  Image = (struct Image *) PropGad->GadgetRender;
X
X  if (Height >= PrevHeight || Num_vp_Colors == 2)
X    color = SHADOWPEN;
X  else
X    color = HIGHLIGHTPEN;
X
X  if (Image->PlaneOnOff != color) {
X    place = RemoveGadget( ContWind, PropGad );
X    Image->PlaneOnOff = color;
X    AddGadget( ContWind, PropGad, place );
X    return(1);
X  }
X  return(0);
X}
X
X/*
X * ReDisplay all the pens gadgets
X */
XReDispPens()
X{
X  struct Gadget **Gadget = SelGadget;
X
X  register LONG Left = (*Gadget)->LeftEdge;
X  register LONG Top = (*Gadget)->TopEdge;
X  register LONG Bot = Top + (4 << YScale) - 1;
X
X  register LONG sixx  = 6 << XScale;
X  register LONG fourx = (4 << XScale) - 1;
X
X  register struct Image *Image;
X
X  LONG i;
X  struct RastPort *Rp = ContWind->RPort;
X  UBYTE *Pen = CurPict->Pens + FirstContour;
X
X  for (i = 0; i < DISPCONTS; i++) {
X
X    Image = (struct Image *) (*Gadget)->GadgetRender;
X
X    Image = Image->NextImage;
X
X    SetAPen( Rp, (long) (Image->PlaneOnOff = *Pen++) );
X
X    RectFill( Rp, Left, Top, Left + fourx, Bot);
X
X    Left += sixx;
X
X    Gadget++;
X  }
X
X  SetContTitle( 0 );
X}
X
Xstatic LONG WindowWidth;
Xstatic LONG WindowHeight;
X
Xstatic struct Border *BarBorder;
Xstatic struct Border *PenBorder;
Xstatic struct Border *ClnBorder;
X
X/*
X * Allocate all the gadgets and things for the contour window
X */
Xstruct Gadget *MakeContours()
X{
X  struct Gadget   *FirstGadget;
X  struct PropInfo *PropInfo;
X
X  register struct Gadget *NextGadget;
X  register struct IntuiText *Intui;
X
X  register ULONG i,x,y;
X  register ULONG c = 0;
X
X  int fourx = 4 << XScale;
X  int foury = 4 << YScale;
X  LONG sixx = 6 << XScale;
X  LONG sixy = 6 << YScale;
X
X  int Left,Top,Width;
X
X  char *str;
X
X  if ( XScale )
X    CurH = &Horiz_II;
X  else
X    CurH = &Horiz_I;
X
X  if ( YScale )
X    CurV = &Verticle_II;
X  else
X    CurV = &Verticle_I;
X
X  FirstContour = 0;
X  SaveFirstCont = 0;
X
X  PenBorder = ClnBorder = BarBorder = NULL;
X
X  BarBorder = ShadowBorder( BEVELEDUP, CurH->BarLeft - 4, CurV->BarTop - 2,
X                                       CurH->BarWidth,    CurV->BarHeight);
X  if (BarBorder == NULL) goto error;
X
X  PenBorder = ShadowBorder( BEVELEDUP, CurH->PenLeft - 4, CurV->PenTop - 3,
X                                       CurH->PenWidth,    CurV->PenHeight);
X  if (PenBorder == NULL) goto error;
X
X  Left = CurH->PenLeft + CurH->PenWidth + 2;
X
X  ClnBorder = ShadowBorder( BEVELEDUP, Left,      CurV->PenTop-3,
X                                       fourx + 5, CurV->PenHeight);
X  if (ClnBorder == NULL) goto error;
X
X  FirstGadget = NextGadget = MakePot( Left + 3, 30 << YScale,
X                                     fourx, 32 << YScale, CONTCEIL, 0);
X  if (NextGadget == NULL) goto error;
X
X  NextGadget->Activation = GADGIMMEDIATE | FOLLOWMOUSE | RELVERIFY;
X
X  Left = CurH->CmdLeft;
X  Top = CurV->CmdTop;
X
X  for (x = 0; x < 6; x++) {
X
X    switch (x) {
X      case 0: str = "Paint";  break;
X      case 1: str = "Set";    break;
X      case 2: str = "Smooth"; break;
X      case 3: str = "Cut";    break;
X      case 4: str = "Copy";   break;
X      case 5: str = "Paste";  break;
X    }
X
X    Width = 8 * strlen( str ) + 6;
X
X    NextGadget = NextGadget->NextGadget =
X      MakeBool( Left, Top, Width, 13, NORMALPEN, CONTCNTL+x, NULL);
X
X    if (NextGadget == NULL) goto error;
X
X    Intui = NextGadget->GadgetText = ShadowIntui( str, 4, 3);
X
X    if (Intui == NULL) goto error;
X
X    Left += 4 + Width;
X  }
X
X  /* Set up color bar below command gadgets */
X
X  BarBoxTop = CurV->BarTop;
X  BarTop = BarBot = BarBoxTop + 1;
X  BarBot += 4 << YScale;
X  BarBoxBot = BarBot + 1;
X
X  BarLeft = BarRight = CurH->BarLeft;
X  BarRight += 256 << XScale;
X  BarWidth = (DISPCONTS) << XScale;
X
X  Width = 8 * strlen("Last") + 4;
X
X  Top = CurV->PenTop;
X
X  NextGadget = NextGadget->NextGadget =
X    MakeBool( BarRight - Width + (2 << XScale), CurV->PenTop - 4, Width, 13,
X              NORMALPEN, CONTLAST, NULL);
X
X  if (NextGadget == NULL) goto error;
X
X  Intui = NextGadget->GadgetText = ShadowIntui( "Last", 3, 3);
X
X  if (Intui == NULL) goto error;
X
X  NextGadget->GadgetText = Intui;
X
X  i = CurH->PenLeft;
X
X  /* Make Set of Gadgets */
X
X  for (x = i, y = 0; y < DISPCONTS; x += sixx, y++) {
X
X    SelGadget[y] = NextGadget = NextGadget->NextGadget =
X      MakeBool(x, Top, fourx, foury, CurPict->Pens[ y + FirstContour ],
X               CONTSEL+y, GADGIMAGE );
X
X    if (NextGadget == NULL) goto error;
X  }
X
X  Top += sixy;
X
X  FirstGadget->TopEdge = Top;
X
X  Ceiling = CurPict->MaxIteration;
X
X  /*
X   * Allocate the potentiometer gadgets for contour window
X   */
X  for (x = i, y = 0; y < DISPCONTS; x += sixx, y++) {
X
X    ContGadget[y] = NextGadget = NextGadget->NextGadget =
X        MakePot(x, Top, 4 << XScale, 32 << YScale, CONTPOT+y, y);
X
X    if (NextGadget == NULL) goto error;
X
X    NextGadget->Activation = GADGIMMEDIATE | FOLLOWMOUSE | RELVERIFY;
X
X    c = CurPict->Heights[ y ];
X
X    if ( c < Ceiling )
X      c = (ULONG) ((((Ceiling - ( c + 1 ))<<16)/(Ceiling)) & 0xffff);
X    else
X      c = (ULONG) 0;
X
X    PropInfo = (struct PropInfo *) NextGadget->SpecialInfo;
X
X    PropInfo->VertPot = c;
X    PropInfo->VertBody = (USHORT) 0xffff/1024;
X  }
X
X  Top += 34 << YScale;
X
X  ModGadget = NextGadget = NextGadget->NextGadget =
X     MakeString( -28, -12 , 3, 0, "1" );
X
X  if ( NextGadget == NULL ) goto error;
X
X  NextGadget->Flags |= GRELBOTTOM | GRELRIGHT;
X  NextGadget->GadgetText = Intui = ShadowIntui( "Mod", 0, -11 );
X
X  if ( Intui == NULL ) goto error;
X
X  WindowHeight = CurV->PenTop + CurV->PenHeight + (2 << YScale);
X
X  if (XScale) {
X    WindowWidth = 534;
X  } else {
X    WindowWidth = 271;
X  }
X  return( FirstGadget );
X
Xerror:
X  FreeBorder( BarBorder );
X  FreeBorder( PenBorder );
X  FreeBorder( ClnBorder );
X  FreeGadgets( FirstGadget );
X  return( NULL );
X
X} /* MakeContours */
X
Xstatic struct Gadget *ContGadgets;
X
X/*
X * Open the Contour window
X */
Xint
XOpenContWind()
X{
X  register struct Gadget *gadgets;
X  register struct RastPort *Rp;
X
X  if (CurPict == NULL)
X    return;
X
X  if (ContWind == NULL) {
X
X    gadgets = MakeContours();
X
X    if (gadgets == NULL) {
X      DispErrMsg("Can't allocate contour gadget chain",0);
X      return(0);
X    }
X    ContWind = OpenMyWind(&NewCont, screen, NULL, WindowWidth,
X                          WindowHeight);
X
X    if (ContWind == NULL) {
X      FreeGadgets(gadgets);
X      return(0);
X    }
X    Rp = ContWind->RPort;
X
X    SetAPen( Rp, NORMALPEN );
X    RectFill( Rp, LEFTMARG, TOPMARG, WindowWidth, WindowHeight);
X
X    ContGadgets = gadgets;
X
X    BorderWindow( ContWind );
X
X    DrawBorder( Rp, BarBorder, 0L, 0L );
X    DrawBorder( Rp, PenBorder, 0L, 0L );
X    DrawBorder( Rp, ClnBorder, 0L, 0L );
X
X    FreeBorder( BarBorder );
X    FreeBorder( PenBorder );
X    FreeBorder( ClnBorder );
X
X    AddGList( ContWind, gadgets, -1L, -1L);
X
X    SetContTitle(0);
X
X    DrawColorBar();
X    DrawContBox( CurContour, HIGHLIGHTPEN );
X
X    RefreshGadgets( ContWind->FirstGadget, ContWind, NULL );
X    ModAll();
X  } else {
X
X    WindowToFront( ContWind );
X  }
X  ContOpen = 1;
X  return( 1 );
X} /* OpenContWind */
X
X/*
X * Close the Mand window
X */
XCloseContWind()
X{
X  if (ContWind != NULL) {
X
X    NewCont.LeftEdge = ContWind->LeftEdge;
X    NewCont.TopEdge = ContWind->TopEdge;
X
X    CloseMyWind(ContWind,ContGadgets);
X  }
X  ContWind = NULL;
X} /* ClosePalWind */
X
SHAR_EOF
echo "End of archive 1 (of 9)"
# if you want to concatenate archives, remove anything after this line
exit