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

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

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

# 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:
#	nav.c
#	orbit.c
#	orbitint.c
#	packer.c
#	palette.c
# This is archive 7 of a 9-part kit.
# This archive created: Tue Jun 20 20:45:31 1989
echo "extracting nav.c"
sed 's/^X//' << \SHAR_EOF > nav.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 handle MandelVroom's
X * Zoom box which is used for navigation around in the complex plane.
X */
X
X#include "mandp.h"
X
XSHORT BoxSizeX = 3, BoxSizeY = 3, DragSize = 3;
X
Xstatic SHORT HotSpotX, HotSpotY;
X
Xstruct Picture *ZoomedPict;
X
X#define MENUCODE(m,i,s) (SHIFTMENU(m)|SHIFTITEM(i)|SHIFTSUB(s))
X
X/*
X * Picture (project) related commands
X */
X
XZoomInCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  struct Picture *Pict;
X
X  Pict = (struct Picture *) Msg->IDCMPWindow->UserData;
X
X  switch( Msg->Class ) {
X
X    case GADGETDOWN:
X         ZoomedPict = Pict;
X
X    case MENUPICK:
X         Pict->ZoomType = ZOOMIN;
X         if ( ! (Pict->Flags & SCROLL_HAPPENED)) {
X           CloseZoomBox(Pict);
X           SetToPointer();
X           State = ZOOMINSTATE;
X         }
X         break;
X
X    case MOUSEBUTTONS:
X         if (Msg->Code == SELECTDOWN) {
X           if (ZoomedPict->pNode.ln_Type == Pict->pNode.ln_Type) {
X             StartZoomBox(ZoomedPict, Pict);
X             ResizeZoomCmd(Msg); /* Pass control off to resize routine */
X           }
X         }
X         break;
X  }
X}
X
X/*
X * StartZoomOut
X */
XZoomOutCmd( Msg )
X  struct IntuiMessage *Msg;
X{
X  register struct Picture *Pict;
X
X  if (Msg->Class == MENUPICK) {
X    Pict = CurPict;
X  } else {
X    Pict = (struct Picture *) Msg->IDCMPWindow->UserData;
X  }
X  Pict->ZoomType = ZOOMOUT;
X
X  AddHead( &Pict->zList, &Pict->zNode );
X
X  Pict->Flags   |= ZOOM_BOX_OPEN;
X  Pict->DrawPict = Pict;
X
X  Pict->NavLeft  = Pict->LeftMarg;
X  Pict->NavRight = Pict->CountX + Pict->NavLeft - 1;
X  Pict->NavTop   = Pict->TopMarg;
X  Pict->NavBot   = Pict->CountY + Pict->NavTop - 1;
X
X  ZoomOnOff( Pict );
X}
X
XResizeZoomCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  struct Window  *Window;
X  struct Picture *Pict;
X
X  Window = Msg->IDCMPWindow;
X  Pict   = (struct Picture *) Window->UserData;
X
X  switch( Msg->Class ) {
X
X    case MOUSEBUTTONS:
X         switch (Msg->Code) {
X
X           case SELECTDOWN:
X
X                if (State != ZOOMINSTATE)
X                  ZoomExtras(ZoomedPict);
X                AllocLensTemp( ZoomedPict );
X                ModifyIDCMP(Window, Window->IDCMPFlags |  MOUSEMOVE);
X                State = RESIZEZOOMSTATE;
X                break;
X
X           case SELECTUP:
X                ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
X                FreeLensTemp();
X                FinishResize(ZoomedPict);
X                State = IDLESTATE;
X                break;
X         }
X         break;
X
X    case MOUSEMOVE:
X         StretchZoomBox( ZoomedPict );
X         break;
X  }
X}
X
XZoomDragCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  struct Window *Window;
X  struct Picture *Pict;
X
X  Window = Msg->IDCMPWindow;
X  Pict = (struct Picture *) Window->UserData;
X
X  switch( Msg->Class ) {
X
X    case MOUSEBUTTONS:
X         ZoomExtras( ZoomedPict );            /* draw/undraw the extras */
X         switch( Msg->Code ) {
X
X           case SELECTDOWN:                   /* start drag */
X                AllocLensTemp( ZoomedPict );
X                ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
X                State = ZOOMDRAGSTATE;
X                break;
X
X           case SELECTUP:                     /* stop slide */
X                FreeLensTemp();
X                ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
X                State = IDLESTATE;
X                break;
X         }
X         break;
X
X    case MOUSEMOVE:
X         DragZoomBox( ZoomedPict );
X         Lens( ZoomedPict );
X         break;
X  }
X}
X
XPropResizeCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  struct Window *Window;
X  struct Picture *Pict;
X
X  Window = Msg->IDCMPWindow;
X  Pict = (struct Picture *) Window->UserData;
X
X  switch( Msg->Class ) {
X
X    case MOUSEBUTTONS:
X         ZoomExtras( ZoomedPict );            /* draw/undraw the extras */
X         switch( Msg->Code ) {
X
X           case SELECTDOWN:                   /* start resize */
X                AllocLensTemp( ZoomedPict );
X                StartPropStrech( ZoomedPict );
X                ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
X                State = PROPRESIZESTATE;
X                break;
X
X           case SELECTUP:                     /* stop resize */
X                FreeLensTemp();
X                ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
X                State = IDLESTATE;
X                break;
X         }
X         break;
X
X    case MOUSEMOVE:
X         PropStretchBox( ZoomedPict );
X         Lens( ZoomedPict );
X         break;
X  }
X}
X
XSetJuliaCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  switch( Msg->Class ) {
X
X    case MENUPICK:
X         SetToPointer();
X         ZoomedPict = CurPict;
X         State = SETJULIASTATE;
X         break;
X
X    case GADGETDOWN:
X         SetToPointer();
X         ZoomedPict = (struct Picture *) Msg->IDCMPWindow->UserData;
X         State = SETJULIASTATE;
X         break;
X
X    case MOUSEBUTTONS:
X         if (Msg->Code == SELECTDOWN) {
X
X           SetJuliaPt(ZoomedPict,
X                      (struct Picture *) Msg->IDCMPWindow->UserData);
X           State = IDLESTATE;
X         }
X         break;
X  }
X}
X
XQueryHeightCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  struct Window *Window;
X  struct Picture *Pict;
X
X  Window = Msg->IDCMPWindow;
X  Pict = (struct Picture *) Window->UserData;
X
X  if (Pict->Flags & SCROLL_HAPPENED)
X    return;
X
X  switch( Msg->Class ) {
X
X    case MOUSEBUTTONS:
X         switch( Msg->Code ) {
X                                              /* start query */
X           case SELECTDOWN:
X                if (Pict->Counts && !(Pict->Flags & NO_RAM_GENERATE)) {
X                  ShowContour( MouseX, MouseY, 1 );
X                  ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
X                  State = QUERYHEIGHTSTATE;
X                }
X                break;
X
X           case SELECTUP:                     /* stop query */
X                ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
X                State = IDLESTATE;
X                break;
X         }
X         break;
X
X    case MOUSEMOVE:
X         ShowContour( MouseX, MouseY, 0);
X         break;
X  }
X}
X
Xstatic int OldHeight; /* used to detect title change */
X
XShowContour(MouseX,MouseY,Flag)
X  register int MouseX,MouseY;
X  register int Flag;
X{
X  register struct Picture *Pict;
X
X  static char ScreenTitle[80];
X
X  int Height;
X  float r, i;
X
X  Pict = (struct Picture *) CurWind->UserData;
X
X  if (Pict == NULL)
X    return;
X
X  if (MouseX >= Pict->LeftMarg &&
X      MouseY >= Pict->TopMarg  &&
X      MouseX <  CurWind->Width  - Pict->RightMarg &&
X      MouseY <  CurWind->Height - Pict->BotMarg) {
X
X    Height = HeightPicked(Pict,MouseX,MouseY);
X    r = Pict->RealLow + (MouseX - Pict->LeftMarg) * Pict->RealGap;
X    i = Pict->ImagLow + (MouseY - Pict->TopMarg) * Pict->ImagGap;
X
X    sprintf(ScreenTitle,"Height %3d r %f i %f",
X                         Height, r, i);
X
X    SetWindowTitles( CurWind, (long) -1, ScreenTitle );
X  }
X}
X
X/*
X * Start Zoom box
X */
XStartZoomBox( NavPict, DrawPict )
X  register struct Picture *NavPict;
X  register struct Picture *DrawPict;
X{
X  register struct Window  *Window = DrawPict->Window;
X
X  CloseZoomBox( NavPict);
X
X  AddHead( &DrawPict->zList, &NavPict->zNode );
X
X  NavPict->Flags    |= ZOOM_BOX_OPEN;
X  NavPict->DrawPict  = DrawPict;
X
X  /* Draw first box */
X  NavPict->NavTop   = NavPict->NavBot   = MouseY;
X  NavPict->NavLeft  = NavPict->NavRight = MouseX;
X
X  ZoomBox( NavPict );
X}
X
XStretchZoomBox( Pict )
X  register struct Picture *Pict;
X{
X  register struct Picture  *DrawPict = Pict->DrawPict;
X  register LONG Left = DrawPict->CountX + DrawPict->LeftMarg;
X  register LONG Top  = DrawPict->CountY + DrawPict->TopMarg;
X
X  ZoomBox( Pict );
X
X  if ( MouseX < Pict->NavLeft )
X    MouseX = Pict->NavLeft;
X
X  if ( MouseY < Pict->NavTop )
X    MouseY = Pict->NavTop;
X
X  if ( MouseX > Left )
X    MouseX = Left-1;
X
X  if ( MouseY > Top )
X    MouseY = Top-1;
X
X  Pict->NavBot   = MouseY;
X  Pict->NavRight = MouseX;
X
X  Lens( Pict );
X
X  ZoomBox( Pict );
X}
X
Xstatic double ZoomAspectRatio;
X
XStartPropStrech( Pict )
X  register struct Picture *Pict;
X{
X  ZoomAspectRatio = (double) (Pict->NavRight - Pict->NavLeft) /
X                   (double) (Pict->NavBot - Pict->NavTop);
X}
X
XPropStretchBox( Pict )
X  register struct Picture *Pict;
X{
X  register LONG Left = Pict->LeftMarg;
X  register LONG Top  = Pict->DrawPict->CountY + Pict->TopMarg;
X
X  register LONG CenterX = Pict->NavRight - Pict->NavLeft;
X  register LONG CenterY = Pict->NavBot - Pict->NavTop;
X
X  LONG NewLeft,NewRight,NewTop;
X
X  ZoomBox( Pict );
X
X  CenterX = Pict->NavLeft + CenterX / 2;
X  CenterY = Pict->NavTop + CenterY / 2;
X
X  if ( MouseX > CenterX-4 )  MouseX = CenterX-4;
X  if ( MouseY < CenterY+4 )  MouseY = CenterY+4;
X
X#if 0
X  if ( MouseX < Left ) MouseX = Left;  /* don't let it flip */
X  if ( MouseY > Top )  MouseY = Top;
X#endif
X
X  Top = MouseY - CenterY;
X  Left = (LONG) ((float) Top * ZoomAspectRatio);
X
X  NewLeft = CenterX - Left;
X  NewRight = CenterX + Left;
X  NewTop = CenterY - Top;
X
X  if (NewLeft  >= Pict->LeftMarg &&
X      NewRight <  Pict->DrawPict->Window->Width - Pict->RightMarg &&
X      NewTop   >= Pict->TopMarg ) {
X
X    Pict->NavBot = MouseY;
X    Pict->NavTop = NewTop;
X    Pict->NavLeft  = NewLeft;
X    Pict->NavRight = NewRight;
X  }
X
X  Lens( Pict );
X
X  ZoomBox( Pict );
X}
X
X#define MINXBOX (8 << XScale)
X#define MINYBOX (7 << YScale)
X
XFinishResize( Pict )
X  struct Picture *Pict;
X{
X  register int t;
X
X  if (Pict->NavBot < Pict->NavTop) {
X    t            = Pict->NavBot;
X    Pict->NavBot = Pict->NavTop;
X    Pict->NavTop = t;
X  }
X  if (Pict->NavRight < Pict->NavLeft) {
X    t              = Pict->NavRight;
X    Pict->NavRight = Pict->NavLeft;
X    Pict->NavLeft  = t;
X  }
X
X  ZoomBox( Pict );
X
X  if (Pict->NavRight - Pict->NavLeft < MINXBOX )
X    Pict->NavRight = Pict->NavLeft + MINXBOX;
X
X  if (Pict->NavBot - Pict->NavTop < MINYBOX )
X    Pict->NavBot = Pict->NavTop + MINYBOX;
X
X  ZoomOnOff( Pict );
X}
X
XDragZoomBox( Pict )
X  register struct Picture *Pict;
X{
X  register struct Picture *DrawPict = Pict->DrawPict;
X  register LONG Width, Height;
X
X  ZoomBox( Pict );
X
X  Width  = Pict->NavRight - Pict->NavLeft - HotSpotX;
X  Height = Pict->NavBot -   Pict->NavTop - HotSpotY;
X
X  if ( MouseY < 1 )
X    MouseY = 1;
X
X  if ( MouseX - HotSpotX < DrawPict->LeftMarg )
X    MouseX = DrawPict->LeftMarg + HotSpotX;
X
X  if ( MouseY - HotSpotY < DrawPict->TopMarg )
X    MouseY = DrawPict->TopMarg + HotSpotY;
X
X  if ( MouseX + Width >= DrawPict->CountX + DrawPict->LeftMarg )
X    MouseX = DrawPict->CountX + DrawPict->LeftMarg - Width;
X
X  if ( MouseY + Height >= DrawPict->CountY + DrawPict->TopMarg )
X    MouseY = DrawPict->CountY + DrawPict->TopMarg - Height;
X
X  Pict->NavLeft  = MouseX - HotSpotX;
X  Pict->NavTop   = MouseY - HotSpotY;
X
X  Pict->NavRight = MouseX + Width;
X  Pict->NavBot   = MouseY + Height;
X
X  Lens( Pict );
X
X  ZoomBox( Pict );
X}
X
XCloseZoomBox( Pict )
X  struct Picture *Pict;
X{
X  if (Pict) {
X    if (Pict->Flags & ZOOM_BOX_OPEN) {
X      ZoomOnOff( Pict );
X      Remove( &Pict->zNode );
X      Pict->Flags &= ~ZOOM_BOX_OPEN;
X    }
X    Pict->DrawPict = NULL;
X  }
X}
X
XClearZoomBox(Pict)
X  struct Picture *Pict;
X{
X  CloseZoomBox( Pict );
X  ZoomedPict = NULL;
X}
X
XZoomBox( Pict )
X  register struct Picture *Pict;
X{
X  if ( Pict && Pict->DrawPict && Pict->DrawPict->Window) {
X
X    ObtainSemaphore( &Pict->WindowSemi );
X    DrawBox( Pict->DrawPict->Window,
X             Pict->NavLeft,  Pict->NavTop,
X             Pict->NavRight, Pict->NavBot );
X    ReleaseSemaphore( &Pict->WindowSemi );
X  }
X}
X
XZoomExtras( Pict )
X  register struct Picture *Pict;
X{
X  if ( Pict && Pict->DrawPict && Pict->DrawPict->Window) {
X
X
X    ObtainSemaphore( &Pict->WindowSemi );
X    DrawExtras( Pict->DrawPict->Window,
X                Pict->NavLeft,  Pict->NavTop,
X                Pict->NavRight, Pict->NavBot );
X    ReleaseSemaphore( &Pict->WindowSemi );
X  }
X}
X
XZoomOnOff( Pict )
X  register struct Picture *Pict;
X{
X  ZoomBox( Pict );
X  ZoomExtras( Pict );
X}
X
XDrawBox( Window, PLeft, PTop, PRight, PBottom)
X  struct Window *Window;
X  SHORT PTop, PLeft, PBottom, PRight;
X{
X  register struct RastPort *Rp;
X  register LONG Top, Left, Right, Bottom;
X
X  Rp = Window->RPort;
X
X  Top = PTop;
X  Left = PLeft;
X  Right = PRight;
X  Bottom = PBottom;
X
X  SetDrMd(Rp, COMPLEMENT);
X  /*
X   * Draw the new box
X   */
X  Move(Rp, Left,  Top   );
X  Draw(Rp, Right, Top   );
X  Draw(Rp, Right, Bottom);
X  Draw(Rp, Left,  Bottom);
X  Draw(Rp, Left,  Top+1 );
X
X  SetDrMd(Rp, JAM1);
X} /* DrawBox */
X
XDrawExtras( Window, Left, Top, Right, Bottom)
X  struct Window *Window;
X  SHORT Top, Left, Bottom, Right;
X{
X  register struct RastPort *Rp = Window->RPort;
X  register LONG ResizeTop  = Bottom - ( BoxSizeY << YScale );
X  register LONG ResizeLeft = Right  - ( BoxSizeX << XScale );
X  register LONG BotDrag = Top + ( DragSize << YScale );
X
X  SetDrMd(Rp, COMPLEMENT);
X  /*
X   * Draw Normal Resize gadget
X   */
X  Move(Rp, (long) Right - 1,  ResizeTop );
X  Draw(Rp, ResizeLeft, ResizeTop );
X  Draw(Rp, ResizeLeft, (long) Bottom - 1);
X
X  /*
X   * Draw Proportional Resize gadget
X   */
X  ResizeLeft = Left + ( BoxSizeX << XScale );
X
X  Move(Rp, (long) Left + 1,  ResizeTop );
X  Draw(Rp, ResizeLeft, ResizeTop );
X  Draw(Rp, ResizeLeft, (long) Bottom - 1);
X
X  /*
X   * Drag bar bar / close gadget separator
X   */
X  Move(Rp, (long) Left  + 1,  BotDrag );
X  Draw(Rp, (long) Right - 1,  BotDrag );
X
X  Move(Rp, (long) Left + (4 << XScale), (long) Top + 1);
X  Draw(Rp, (long) Left + (4 << XScale), BotDrag - 1 );
X
X  SetDrMd(Rp, JAM1);
X} /* DrawExtras */
X
X/*
X * ZoomIn
X */
XZoomIn( NavPict )
X  register struct Picture *NavPict;
X{
X  register struct Picture *DrawPict = NavPict->DrawPict;
X  double left,  top;
X  double right, bot;
X
X  double AspectRatio();
X
X  double Gap;
X
X  if (DrawPict) {
X
X    left  = (double) (NavPict->NavLeft  - DrawPict->LeftMarg);
X    top   = (double) (NavPict->NavTop   - DrawPict->TopMarg);
X    right = (double) (NavPict->NavRight - DrawPict->LeftMarg);
X    bot   = (double) (NavPict->NavBot   - DrawPict->TopMarg);
X
X    switch( NavPict->ZoomType ) {
X      case  ZOOMIN:
X
X            NavPict->RealHigh = DrawPict->RealLow + DrawPict->RealGap*right;
X            NavPict->ImagHigh = DrawPict->ImagLow + DrawPict->ImagGap*bot;
X            NavPict->RealLow  = DrawPict->RealLow + DrawPict->RealGap*left;
X            NavPict->ImagLow  = DrawPict->ImagLow + DrawPict->ImagGap*top;
X
X            NavPict->Real     = DrawPict->Real;
X            NavPict->Imag     = DrawPict->Imag;
X            break;
X
X      case  ZOOMOUT:
X
X            Gap = (DrawPict->ImagHigh - DrawPict->ImagLow) / (bot - top);
X
X            NavPict->ImagLow  -= top * Gap;
X            NavPict->ImagHigh = NavPict->ImagLow +
X                                (double) NavPict->CountY*Gap;
X
X            NavPict->ImagGap = Gap;
X            NavPict->RealGap = Gap *= AspectRatio(NavPict);
X
X            NavPict->RealLow  -= left * Gap;
X            NavPict->RealHigh = NavPict->RealLow +
X                                (double) NavPict->CountX*Gap;
X    }
X
X    CloseZoomBox( NavPict );
X  }
X  CalculateGaps( NavPict );
X} /* ZoomIn */
X
X/*
X * Calculate Gaps
X */
XCalculateGaps( Pict )
X  register struct Picture *Pict;
X{
X  double AspectRatio();
X
X  Pict->ImagGap = (Pict->ImagHigh - Pict->ImagLow) / (double) Pict->CountY;
X  Pict->RealGap = Pict->ImagGap * AspectRatio( Pict );
X}
X
X/*
X * Apsect Ratio - IEEE
X */
Xdouble
XAspectRatio( Pict )
X  register struct Picture *Pict;
X{
X  double aspectratio;
X
X  if (Pict->ViewModes & HIRES)
X    if (Pict->ViewModes & INTERLACE)
X      aspectratio = 0.88;
X    else
X      aspectratio = 0.44;
X  else
X    if (Pict->ViewModes & INTERLACE)
X      aspectratio = 1.76;
X    else
X      aspectratio = 0.88;
X
X  return( aspectratio );
X}
X
X/*
X * Simulate Zoom box gadgets
X */
Xint
XCheckPictZoomBox( NavPict )
X  register struct Picture  *NavPict;
X{
X  register struct Picture *DrawPict = NavPict->DrawPict;
X  register struct Window  *Window = DrawPict->Window;
X
X  register LONG BoxX;
X
X  BoxX = BoxSizeX << XScale;
X
X  /* is it in the window box? */
X  if (MouseX >= NavPict->NavLeft && MouseX <= NavPict->NavRight &&
X      MouseY >= NavPict->NavTop  && MouseY <= NavPict->NavBot) {
X
X    /* is it in the top part? */
X    if (MouseY <= NavPict->NavTop + (DragSize << YScale) ) {
X
X      /* is it the drag bar? */
X      if (MouseX > NavPict->NavLeft + BoxX ) {
X
X        HotSpotX = MouseX - NavPict->NavLeft;
X        HotSpotY = MouseY - NavPict->NavTop;
X        return(ZOOMDRAGHIT);
X
X      } else {                     /* We got the close gadget */
X
X        return(ZOOMCLOSEHIT);
X      }
X    } else {
X
X      /* is it the Resize Gadget? */
X      if (MouseY >= NavPict->NavBot - ((BoxSizeY + 1) << YScale) ) {
X
X        if ( MouseX > NavPict->NavRight - BoxX ) {
X
X          return(ZOOMRESIZEHIT);
X
X        } else
X        if ( MouseX <= NavPict->NavLeft + BoxX ) {
X
X          return(PROPRESIZEHIT);
X        }
X      }
X    }
X  }
X  return(NOTHINGHIT);
X}
X
XSetJuliaPt( ZoomedPict, Pict )
X  register struct Picture *ZoomedPict, *Pict;
X{
X  register LONG x,y;
X
X  if (ZoomedPict && Pict &&
X      ZoomedPict->pNode.ln_Type != Pict->pNode.ln_Type) {
X
X    x = MouseX - Pict->LeftMarg;
X    y = MouseY - Pict->TopMarg;
X
X    ZoomedPict->Real = Pict->RealLow + x * Pict->RealGap;
X    ZoomedPict->Imag = Pict->ImagLow + y * Pict->ImagGap;
X  }
X}
SHAR_EOF
echo "extracting orbit.c"
sed 's/^X//' << \SHAR_EOF > orbit.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 that open, maintain and
X * close the orbit window.
X */
X
X#define PARSEGOOD 0
X#define PARSEBAD  1
X
X#include "mandp.h"
X#include "parms.h"
X
XSHORT MaxOrbit = 32;
XUBYTE OrbitMode = 1;
X
XUBYTE OrbitOpen;
X
Xstruct NewWindow NewOrbit = {
X   100, 12,                  /* start position           */
X   130,80,                   /* width, height            */
X
X   (UBYTE) 0, (UBYTE) NORMALPEN,
X   NULL,                     /* IDCMP flags */
X   /* OrbitWind flags */
X   WINDOWCLOSE | WINDOWDEPTH | WINDOWSIZING | WINDOWDRAG | ACTIVATE |
X   NOCAREREFRESH | SMART_REFRESH,
X   (struct Gadget *) NULL,   /* first gadget             */
X   (struct Image *) NULL,    /* user checkmark           */
X   (UBYTE *) "Orbit",        /* Title                    */
X   (struct Screen *) NULL,   /* pointer to screen        */
X   (struct BitMap *) NULL,   /* pointer to superbitmap   */
X   20,20,-1,-1,              /* sizing                   */
X   CUSTOMSCREEN              /* type of screen           */
X};
X
Xstruct Window *OrbitWind;
X
XConfOrbMode( subnum )
X  int subnum;
X{
X  OrbitMode = subnum;
X}
X
XOrbitCmd( msg )
X  register struct IntuiMessage *msg;
X{
X  static struct Picture *OrbitPict;
X  register struct Window *Window;
X
X  switch( msg->Class ) {
X    case MENUPICK:
X    case GADGETDOWN:
X         OpenOrbitWind();
X         break;
X
X    case MOUSEBUTTONS:
X
X         Window = (struct Window *) msg->IDCMPWindow;
X
X         switch (msg->Code) {
X           case SELECTDOWN:
X
X                OrbitPict = (struct Picture *) Window->UserData;
X
X                if (OrbitPict != NULL &&
X                  !(OrbitPict->Flags & SCROLL_HAPPENED)) {
X
X                  ModifyIDCMP( Window,
X                               (long) Window->IDCMPFlags | MOUSEMOVE );
X                  DrawOrbit(OrbitPict);
X                }
X                break;
X
X           case SELECTUP:
X
X                if (OrbitPict != NULL) {
X
X                  ModifyIDCMP( Window,
X                               (long) Window->IDCMPFlags & ~MOUSEMOVE );
X                  OrbitPict = NULL;
X                }
X                break;
X         }
X         break;
X
X    case MOUSEMOVE:
X
X         if (OrbitPict != NULL) {
X           DrawOrbit( OrbitPict );
X         }
X         break;
X  }
X}
X
XDrawOrbit( Pict )
X  struct Picture *Pict;
X{
X  switch( OrbitMode ) {
X    case 1:   /* ffp       */
X         {    /* 32 bit IEEE float variables */
X
X           float CReal_float, CImag_float, ZReal_float, ZImag_float;
X
X           if (OpenFFPLibs() != 0)
X             return;
X
X           /* convert 64 bit IEEE variables into 32 bit IEEE variables */
X
X           CReal_float =
X             Pict->RealLow + (MouseX-Pict->LeftMarg) * Pict->RealGap;
X           CImag_float =
X             Pict->ImagLow + (MouseY-Pict->TopMarg) * Pict->ImagGap;
X
X           ZReal_float   = Pict->Real;
X           ZImag_float   = Pict->Imag;
X
X           /*
X            * calculate pointers and convert them to pointers to ULONG
X            * so that when we indirect off of these and pass the results
X            * as parameters they are not promoted to doubles.
X            */
X
X           DrawOrbitFFP( Pict,
X                         *((ULONG *) &CReal_float),
X                         *((ULONG *) &CImag_float),
X                         *((ULONG *) &ZReal_float),
X                         *((ULONG *) &ZImag_float));
X         }
X         break;
X
X    case 0:   /* int 16/32 */
X         DrawOrbitInt( Pict );
X         break;
X
X    case 2:   /* ieee      */
X         DrawOrbitIEEE( Pict );
X         break;
X  }
X}
X
Xstruct Gadget *
XMakeOrbitGads()
X{
X  register struct Gadget *Firstgadget;
X  register struct IntuiText  *Intui;
X
X  struct IntuiText *ShadowIntui();
X  struct Border *Border, *MakeShadow();
X
X  Firstgadget = MakeBool(-15,TOPMARG, 12,12, 0,ORBTTYPE<<WINDTYPEBITS,NULL);
X
X  if (Firstgadget == NULL) {
X    return( Firstgadget );
X  }
X
X  Firstgadget->Flags      |= GRELRIGHT;
X  Firstgadget->Activation |= RIGHTBORDER;
X
X  Intui = ShadowIntui( "O", 3, 3);
X
X  if (Intui == NULL) {
X    FreeGadgets( Firstgadget );
X    return( NULL );
X  }
X
X  Firstgadget->GadgetText = Intui;
X
X#define NUMPATCHCORNERS 5
X
X  Border = MakeShadow( NORMALPEN, NUMPATCHCORNERS );
X
X  if ( Border ) {
X    InitPatch( Border );
X
X    Border->NextBorder = (struct Border *) Firstgadget->GadgetRender;
X    Firstgadget->GadgetRender = (APTR) Border;
X  }
X
X  return( Firstgadget );
X}
X
Xstatic struct Gadget *OrbitGadgets;
Xstruct Gadget *OrbitResize;
X
X/*
X * Open the Orbit window
X */
XOpenOrbitWind()
X{
X  extern struct Window *OpenMyWind();
X
X  register struct Window    *Window;
X  register struct NewWindow *NewWind;
X
X  struct Gadget *gadgets;
X
X  if ( OrbitWind == NULL ) {
X
X    OrbitGadgets = gadgets = MakeOrbitGads();
X
X    if (gadgets == NULL) {
X      return( -1 );
X    }
X
X    Window = OpenMyWind(&NewOrbit, screen, gadgets,
X                         NewOrbit.Width, NewOrbit.Height );
X
X    if (Window == NULL) {
X
X      DispErrMsg("Can't open picture window",0);
X      FreeGadgets( OrbitGadgets );
X      return( -1 );
X
X    } else {
X
X      OrbitWind = Window;
X      MoveResize( Window, &OrbitResize );
X      BorderWindow( Window );
X    }
X  }
X
X  OrbitOpen = 1;
X  State = ORBITSTATE;
X  SetToPointer();
X  return( 0 );
X} /* OpenOrbit */
X
X/*
X * Close the Orbit Window
X */
XCloseOrbitWind()
X{
X  register struct Window    *Window;
X  register struct NewWindow *NewWindow;
X
X  Window = OrbitWind;
X
X  if ( Window != NULL) {
X
X    NewOrbit.LeftEdge = Window->LeftEdge;
X    NewOrbit.TopEdge  = Window->TopEdge;
X    NewOrbit.Width    = Window->Width;
X    NewOrbit.Height   = Window->Height;
X
X    CloseMyWind(Window, OrbitGadgets );
X
X    OrbitWind    = NULL;
X    OrbitGadgets = NULL;
X  }
X}
SHAR_EOF
echo "extracting orbitint.c"
sed 's/^X//' << \SHAR_EOF > orbitint.c
X/*
X * MandelVroom 2.0
X *
X * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
X *
X * All rights reserved.
X *
X * Permission is hereby granted to distribute this program's source
X * executable, and documentation for non-comercial purposes, so long as the
X * copyright notices are not removed from the sources, executable or
X * documentation.  This program may not be distributed for a profit without
X * the express written consent of the author Kevin L. Clague.
X *
X * This program is not in the public domain.
X *
X * Fred Fish is expressly granted permission to distribute this program's
X * source and executable as part of the "Fred Fish freely redistributable
X * Amiga software library."
X *
X * Permission is expressly granted for this program and it's source to be
X * distributed as part of the Amicus Amiga software disks, and the
X * First Amiga User Group's Hot Mix disks.
X *
X * contents: this file contains functions to calculate and draw orbits for
X * fixed point (scaled int) math mode.
X */
X
X#include "mandp.h"
X
X#include "parms.h"
X
Xstatic double x_scale,  y_scale;
Xstatic int    x_center, y_center;
Xstatic int    rightedge,botedge;
Xstatic struct RastPort *Rp;
X
Xextern SHORT MaxOrbit;
X
X#define ORBSHIFT 27
X#define ORBINT(f) ((int)((f)*(double)(1<<ORBSHIFT)))
X
XInitIntOrbit()
X{
X  register struct Window *Window;
X  register int    width,  height;
X
X  Window = OrbitWind;
X  Rp = Window->RPort;
X
X  width  = (Window->Width-LEFTMARG-RIGHTMARG);
X  height = (Window->Height-TOPMARG-BOTMARG);
X
X  rightedge = width + LEFTMARG - 1;
X  botedge   = height + TOPMARG - 1;
X
X  x_scale = y_scale = (float) height / (2.0 * (double)(1<<ORBSHIFT));
X
X  x_center = width/2 + LEFTMARG;
X  y_center = height/2 + TOPMARG;
X}
X
Xstatic char first_flag;
X
XDrawOrbitInt( Pict )
X  struct Picture *Pict;
X{
X  struct IntPotParms Parms;
X  LONG creal, cimag;
X  LONG sreal, simag;
X
X  InitIntOrbit();
X
X  creal = ORBINT( Pict->RealLow + (MouseX-Pict->LeftMarg) * Pict->RealGap );
X  cimag = ORBINT( Pict->ImagLow + (MouseY-Pict->TopMarg)  * Pict->ImagGap );
X
X  sreal = ORBINT( Pict->Real );
X  simag = ORBINT( Pict->Imag );
X
X  if ( Pict->pNode.ln_Type == MANDPICT ) {
X
X    Parms.C_Real = creal;
X    Parms.C_Imag = cimag;
X
X    Parms.ScreenReal = sreal;
X    Parms.ScreenImag = simag;
X  } else {
X
X    Parms.C_Real = sreal;
X    Parms.C_Imag = simag;
X
X    Parms.ScreenReal = creal;
X    Parms.ScreenImag = cimag;
X  }
X
X  Parms.MaxIteration = MaxOrbit;
X
X  /* Clear the window for next display plot */
X
X  SetAPen(Rp, 0);
X  RectFill(Rp, LEFTMARG,TOPMARG, rightedge, botedge);
X  SetAPen(Rp, HIGHLIGHTPEN);
X
X  first_flag = 0;
X
X  Orbit3216( &Parms );
X}
X
XPlotIntOrbit( zreal, zimag )
X  LONG zreal, zimag;
X{
X  int x,y;
X
X  x = x_center + (int)((double) zreal * x_scale);
X  y = y_center + (int)((double) zimag * y_scale);
X
X  if (x >= LEFTMARG && x <= rightedge &&
X      y >= TOPMARG  && y <= botedge   &&
X      first_flag == 1                   ) {
X
X    WritePixel( Rp, x, y );
X  }
X  first_flag = 1;
X}
X
X/*
X *  Orbit display for 32 bit math using 16 bit multiplies.
X *  It is written for the 68000 instruction set.
X */
XOrbit3216( Parms )
X
X  struct IntPotParms *Parms;
X{
X  LONG Height;
X
X  register struct IntPotParms *P = Parms;
X
X  register LONG cura, curb, cura2, curb2;
X
X#asm
Xheight  equ -4
XBits2Shift equ  5
X;
X;
X;  d1 - BITS2SHIFT
X;  d2 - k
X;  d4 - a
X;  d5 - b
X;  d6 - a2
X;  d7 - b2
X;
Xscreenr  equ 0
Xscreeni  equ 4
Xcurx     equ 8
Xcury     equ 12
Xmaxi     equ 16
X;
X   move.l   #Bits2Shift,d1
X   move.l   screenr(a2),d4
X   move.l   screeni(a2),d5
X   move.w   maxi(a2),d2
X   bra      Fposa2
X;
XFKLoop
X;
X;  cura = cura2 - curb2 + curx;
X   exg      d6,d4       ; exchange cura and cura2
X   sub.l    d7,d4       ; subtract curb
X   add.l    curx(a2),d4 ; add curx
X;
X;  curb = cura * curb >> 12;
X   move.l   d6,d7      ; get copy of op1 sign bit
X   bpl      Fpos1       ; get absolute value of op1
X   neg.l    d6
XFpos1
X   eor.l    d5,d7      ; calculate result sign
X   tst.l    d5         ; get absolute value of op2
X   bpl      Fpos2
X   neg.l    d5
XFpos2
X   move.l   d6,d0      ; get a copy of op1
X   swap     d0         ; get high half of op1
X   move.w   d0,d7      ; save a copy of high half
X   mulu     d5,d0      ; multiply op2 low by op1 high
X   clr.w    d0         ;  clear least significant part
X   swap     d0         ;  put it in it's place
X   swap     d5         ; get high half of op2
X   mulu     d5,d6      ; multiply op2 high with op1 low
X   clr.w    d6         ;  clear least significant part
X   swap     d6         ;  put it in its place
X   mulu     d7,d5      ; multiply op2 high by op1 high
X   add.l    d0,d5      ; add partial results
X   add.l    d6,d5      ; add partial results
X   tst.l    d7         ; is the result negative?
X   bpl      Fpos3
X   neg.l    d5         ; yes, better negate it.
XFpos3
X   asl.l    d1,d5      ; now, rescale it.
X;
X;  curb += curb + cury;
X   add.l    d5,d5      ; double it and add cury
X   add.l    cury(a2),d5
XFposa2
X;
X;  cura2 = cura * cura;
X   move.l   d4,d0      ; get absolute value of a in d0
X   bpl      Fposa
X   neg.l    d0
XFposa
X   move.l   d0,d6      ; copy absolute value into d6
X   swap     d6         ; get high part in d6
X   mulu     d6,d0      ; multiply high and low destroying low
X   clr.w    d0         ; clear the least significant part
X   swap     d0         ; put most sig. part in low half
X   mulu     d6,d6      ; multiply high and high destroing high
X   add.l    d0,d6      ; add in lower half twice
X   add.l    d0,d6
X   asl.l    d1,d6      ; get radix point back in correct place
X   bvs      Fbailout
X;
X;  curb2 = curb * curb;
X   move.l   d5,d0      ; get absolute value of a in d0
X   bpl      Fposb
X   neg.l    d0
XFposb
X   move.l   d0,d7      ; copy absolute value into d7
X   swap     d7         ; get high part in d7
X   mulu     d7,d0      ; multiply high and low destroying low
X   clr.w    d0         ; clear the least significant part
X   swap     d0         ; put most sig. part in low half
X   mulu     d7,d7      ; multiply high and high destroing high
X   add.l    d0,d7      ; add in lower half twice
X   add.l    d0,d7
X   asl.l    d1,d7      ; get radix point back in correct place
X   bvs      Fbailout
X;
X   movem.l  .saveregs,-(sp)
X;
X#endasm
X   PlotIntOrbit(cura,curb);
X#asm
X;
X   movem.l  (sp)+,.saveregs
X;
X   move.l   d6,d0      ; if (cura2 + curb2 >= 4) goto bailout;
X   add.l    d7,d0
X   bvs      Fbailout
X;
X   dbra     d2,FKLoop
X;  addq     #1,d2
XFbailout
X   move.w   maxi(a2),d0
X   sub.w    d2,d0
X   sub.w    #1,d0
X   ext.l    d0
X#endasm
X   ;;
X}
X
X#asm
X.saveregs   reg     d0-d3/a2
X#endasm
X
X
X
SHAR_EOF
echo "extracting packer.c"
sed 's/^X//' << \SHAR_EOF > packer.c
X/*----------------------------------------------------------------------*
X * packer.c Convert data to "cmpByteRun1" run compression.     11/15/85
X *
X * By Jerry Morrison and Steve Shaw, Electronic Arts.
X * This software is in the public domain.
X *
X *	control bytes:
X *	 [0..127]   : followed by n+1 bytes of data.
X *	 [-1..-127] : followed by byte to be repeated (-n)+1 times.
X *	 -128       : NOOP.
X *
X * This version for the Commodore-Amiga computer.
X *----------------------------------------------------------------------*/
X#include "iff/packer.h"
X
X#define DUMP	0
X#define RUN	1
X
X#define MinRun 3	
X#define MaxRun 128
X#define MaxDat 128
X
XLONG putSize;
X#define GetByte()	(*source++)
X#define PutByte(c)	{ *dest++ = (c);   ++putSize; }
X
Xchar buf[256];	/* [TBD] should be 128?  on stack?*/
X
XBYTE *PutDump(dest, nn)  BYTE *dest;  int nn; {
X	int i;
X
X	PutByte(nn-1);
X	for(i = 0;  i < nn;  i++)   PutByte(buf[i]);
X	return(dest);
X	}
X
XBYTE *PutRun(dest, nn, cc)   BYTE *dest;  int nn, cc; {
X	PutByte(-(nn-1));
X	PutByte(cc);
X	return(dest);
X	}
X
X#define OutDump(nn)   dest = PutDump(dest, nn)
X#define OutRun(nn,cc) dest = PutRun(dest, nn, cc)
X
X/*----------- PackRow --------------------------------------------------*/
X/* Given POINTERS TO POINTERS, packs one row, updating the source and
X   destination pointers.  RETURNs count of packed bytes.*/
XLONG PackRow(pSource, pDest, rowSize)
X    BYTE **pSource, **pDest;   LONG rowSize; {
X    BYTE *source, *dest;
X    char c,lastc = '\0';
X    BOOL mode = DUMP;
X    short nbuf = 0;		/* number of chars in buffer */
X    short rstart = 0;		/* buffer index current run starts */
X
X    source = *pSource;
X    dest = *pDest;
X    putSize = 0;
X    buf[0] = lastc = c = GetByte();  /* so have valid lastc */
X    nbuf = 1;   rowSize--;	/* since one byte eaten.*/
X
X
X    for (;  rowSize;  --rowSize) {
X	buf[nbuf++] = c = GetByte();
X	switch (mode) {
X		case DUMP: 
X			/* If the buffer is full, write the length byte,
X			   then the data */
X			if (nbuf>MaxDat) {
X				OutDump(nbuf-1);  
X				buf[0] = c; 
X				nbuf = 1;   rstart = 0; 
X				break;
X				}
X
X			if (c == lastc) {
X			    if (nbuf-rstart >= MinRun) {
X				if (rstart > 0) OutDump(rstart);
X				mode = RUN;
X				}
X			    else if (rstart == 0)
X				mode = RUN;	/* no dump in progress,
X				so can't lose by making these 2 a run.*/
X			    }
X			else  rstart = nbuf-1;		/* first of run */ 
X			break;
X
X		case RUN: if ( (c != lastc)|| ( nbuf-rstart > MaxRun)) {
X	    		/* output run */
X	   		OutRun(nbuf-1-rstart,lastc);
X	    		buf[0] = c;
X	    		nbuf = 1; rstart = 0;
X	    		mode = DUMP;
X	    		}
X			break;
X		}
X
X	lastc = c;
X	}
X
X    switch (mode) {
X	case DUMP: OutDump(nbuf); break;
X	case RUN: OutRun(nbuf-rstart,lastc); break;
X	}
X    *pSource = source;
X    *pDest = dest;
X    return(putSize);
X    }
X
SHAR_EOF
echo "extracting palette.c"
sed 's/^X//' << \SHAR_EOF > palette.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 that open, maintain, operate
X * and close the color palette.
X */
X
X#include "mandp.h"
X
X#include <ctype.h>
X
X#define PENLEFT 8
X#define PENTOP  15
X
Xextern struct Gadget *ContGadget[], *SelGadget[];
X
XUBYTE PaletteOpen;
X
X/*
X * Holder for Allocated color potentiometer gadgets.
X */
Xstruct ColorGads {
X  struct Gadget *RedPot;
X  struct Gadget *GreenPot;
X  struct Gadget *BluePot;
X};
X
Xstruct Window          *PalWind;
Xstruct ColorGads        PalGads;
X
XLONG CurPen;
X
Xstruct NewWindow NewPal = {
X   128,0,                    /* start position           */
X   70,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 *) "Colors",       /* 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
X/*
X * Color Palette Commands
X */
X
XCopyRGBCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  struct Gadget  *gadget;
X  register LONG rgb, pen;
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 == PALCOPY) { /* Copy command gadget */
X
X      SetToPointer();
X      State = COPYRGBSTATE;
X    } else {
X
X      if (GADG_TYPE(gadget->GadgetID) == PALPEN) {
X
X        /* Copy the RGBs from CurPen to NewPen */
X
X        pen = GADG_NUM(gadget->GadgetID);
X        rgb = GetRGB4(vp->ColorMap, CurPen);
X        SetRGB4(vp, pen, rgb >> 8, rgb >> 4, rgb);
X        SaveRGBs(CurPict);
X
X        State = IDLESTATE;
X      }
X    }
X  }
X}
X
XSpreadRGBCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  struct Gadget *gadget;
X  register LONG  pen;
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 == PALRANGE) { /* Spread command gadget */
X
X      SetToPointer();
X      State = SPREADRGBSTATE;
X    } else {
X
X      if (GADG_TYPE(gadget->GadgetID) == PALPEN) {
X
X        /* Spread the RGBs from CurPen to NewPen */
X
X        pen = GADG_NUM(gadget->GadgetID);
X        ColorRange(CurPen, pen);
X        SaveRGBs(CurPict);
X
X        State = IDLESTATE;
X      }
X    }
X  }
X}
X
XExchangeRGBCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  register LONG rgb, rgb2, pen;
X  struct Gadget *gadget;
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 == PALEXCG) { /* Exchange command gadget */
X
X      SetWithPointer();
X      State = XCHGRGBSTATE;
X    } else {
X
X      if (GADG_TYPE(gadget->GadgetID) == PALPEN) {
X
X        /* exchange the RGBs in CurPen and NewPen */
X
X        pen = GADG_NUM(gadget->GadgetID);
X        rgb  = GetRGB4(vp->ColorMap, CurPen);
X        rgb2 = GetRGB4(vp->ColorMap, pen);
X        SetRGB4(vp, CurPen, rgb2 >> 8, rgb2 >> 4, rgb2 );
X        SetRGB4(vp, pen,    rgb  >> 8, rgb  >> 4, rgb  );
X        SaveRGBs(CurPict);
X
X        State = IDLESTATE;
X      }
X    }
X  }
X}
X
XSlideRGBCmd(Msg)
X  struct IntuiMessage *Msg;
X{
X  struct Gadget *gadget;
X
X  gadget = (struct Gadget *) Msg->IAddress;
X
X  switch( Msg->Class ) {
X
X    case GADGETDOWN:                          /* Start RGB slide    */
X         StartBarDrag();
X         State = SLIDERGBSTATE;
X         break;
X
X    case MOUSEMOVE:
X         ModifyColors();                      /* change RGB colors */
X         break;
X
X    case GADGETUP:                            /* Stop the RGB slide */
X         ModifyColors();
X         SaveRGBs(CurPict);
X         State = IDLESTATE;
X         break;
X  }
X}
X
XSetCurPen( pen )
X  int pen;
X{
X  BoxPen( CurPen, NORMALPEN );
X  CurPen = pen;
X  SetColorProps(pen);
X  BoxPen( CurPen, MEDIUMPEN );
X  SaveRGBs( CurPict );
X}
X
X/*
X * Blend a range of colors between two pens
X */
XColorRange(first, last)
X  LONG first, last;
X{
X    LONG i;
X    register LONG whole, redfraction, greenfraction, bluefraction;
X    register USHORT rgb;
X    LONG firstred, firstgreen, firstblue;
X    LONG lastred, lastgreen, lastblue;
X    LONG workred, workgreen, workblue;
X
X    if (first > last) {
X        i = first;
X        first = last;
X        last = i;
X     }
X
X    /* I need to see a spread of at least two, where there's at least one
X     * spot between the endpoints, else there's no work to do so I
X     * might as well just return now.
X     */
X    if (first >= last - 1) return;
X
X    rgb = GetRGB4(vp->ColorMap, first);
X    firstred = (rgb >> 8) & 0xF;
X    firstgreen = (rgb >> 4) & 0xF;
X    firstblue = (rgb >> 0) & 0xF;
X
X    rgb = GetRGB4(vp->ColorMap, last);
X    lastred = (rgb >> 8) & 0xF;
X    lastgreen = (rgb >> 4) & 0xF;
X    lastblue = (rgb >> 0) & 0xF;
X
X    whole = (lastred - firstred) << 16;
X    redfraction = whole / (last - first);
X    whole = (lastgreen - firstgreen) << 16;
X    greenfraction = whole / (last - first);
X    whole = (lastblue - firstblue) << 16;
X    bluefraction = whole / (last - first);
X
X    for (i = first + 1; i < last; i++)
X        {
X        lastred = (redfraction * (i - first) + 0x8000) >> 16;
X        workred = firstred + lastred;
X        lastgreen = (greenfraction * (i - first) + 0x8000) >> 16;
X        workgreen = firstgreen + lastgreen;
X        lastblue = (bluefraction * (i - first) + 0x8000) >> 16;
X        workblue = firstblue + lastblue;
X        SetRGB4(vp, i, workred, workgreen, workblue);
X        }
X} /* ColorRange */
X
X/*
X * Modify the colors in the current pen
X */
XModifyColors( )
X{
X  register LONG newred, newgreen, newblue;
X
X  newred = ((struct PropInfo *)
X           PalGads.RedPot->SpecialInfo)->VertPot >> 12;
X  newgreen = ((struct PropInfo *)
X           PalGads.GreenPot->SpecialInfo)->VertPot >> 12;
X  newblue = ((struct PropInfo *)
X           PalGads.BluePot->SpecialInfo)->VertPot >> 12;
X
X  newred   = 0xF ^ newred;
X  newgreen = 0xF ^ newgreen;
X  newblue  = 0xF ^ newblue;
X
X  PrintRGB( newred, newgreen, newblue );
X
X  SetRGB4(vp, CurPen, newred, newgreen, newblue);
X} /* ModifyColors */
X
XPrintRGB( r, g, b )
X  LONG r,g,b;
X{
X  PrintGad( PalGads.RedPot,   r );
X  PrintGad( PalGads.GreenPot, g );
X  PrintGad( PalGads.BluePot,  b );
X}
X
XPrintGad( gadget, Color )
X  register struct Gadget *gadget;
X  LONG   Color;
X{
X  register struct IntuiText *SaveIntui, *IntuiText = gadget->GadgetText;
X
X  char d[4];
X
X  SaveIntui = IntuiText;
X
X  Color &= 0xf;
X  sprintf( d, "%x", Color );
X
X  d[0] = toupper(d[0]);
X
X  IntuiText = IntuiText->NextText;
X
X  IntuiText->IText[0] = d[0];
X
X  IntuiText = IntuiText->NextText;
X
X  IntuiText->IText[0] = d[0];
X
X  PrintIText( PalWind->RPort, SaveIntui, gadget->LeftEdge, gadget->TopEdge);
X}
X
X/*
X * Reflect a pen's new color in the proportional gadget
X */
XSetColorProps(pen)
X  LONG pen;
X{
X  register LONG rgb, red, green, blue;
X
X  if (PalWind == NULL)
X    return;
X
X  pen &= Num_vp_Colors - 1;
X
X  rgb = GetRGB4(vp->ColorMap, pen);
X
X  red = 0xF - ((rgb >> 8) & 0xF);
X  green = 0xF - ((rgb >> 4) & 0xF);
X  blue = 0xF - (rgb & 0xF);
X
X  red   |= (red << 4);
X  red   |= (red << 8);
X  green |= (green << 4);
X  green |= (green << 8);
X  blue  |= (blue <<  4);
X  blue  |= (blue <<  8);
X
X  NewModifyProp(PalGads.RedPot,  PalWind,NULL,FREEVERT|PROPBORDERLESS,
X             0L,red,0L,0xfffL,1L);
X  NewModifyProp(PalGads.GreenPot,PalWind,NULL,FREEVERT|PROPBORDERLESS,
X             0L,green,0L,0xfffL,1L);
X  NewModifyProp(PalGads.BluePot, PalWind,NULL,FREEVERT|PROPBORDERLESS,
X             0L,blue,0L,0xfffL,1L);
X} /* SetColorProps */
X
XBoxPen(BoxPen, DrawPen)
X  LONG BoxPen, DrawPen;
X{
X  register LONG  Top, Bot, Left, Right;
X  register ULONG row, column;
X
X#define PALTOP    (PENTOP - 1)
X#define PALLEFT   (PENLEFT - 1)
X#define PENWIDTH  (4 << XScale)
X#define PENHEIGHT (4 << YScale)
X#define PENXPITCH (6 << XScale)
X#define PENYPITCH (6 << YScale)
X
X  if (PalWind == NULL)
X    return;
X
X  column = BoxPen/8;
X
X  row = BoxPen - column*8;
X
X  SetAPen(PalWind->RPort, DrawPen);
X
X  Left  = PALLEFT + PENXPITCH * column;
X  Top   = PALTOP  + PENYPITCH * row;
X  Right = Left    + PENWIDTH  + 2 + XScale;
X  Bot   = Top     + PENHEIGHT + 2 + YScale;
X
X  Move(PalWind->RPort, Left,  Top);
X  Draw(PalWind->RPort, Right, Top);
X
X  if (DrawPen == HIGHLIGHTPEN) SetAPen(PalWind->RPort, SHADOWPEN);
X
X  Draw(PalWind->RPort, Right, Bot);
X  Draw(PalWind->RPort, Left,  Bot);
X
X  SetAPen(PalWind->RPort, DrawPen);
X
X  Draw(PalWind->RPort, Left,  Top + 1);
X
X  if (DrawPen) {
X    row = GetRGB4(vp->ColorMap, BoxPen & (Num_vp_Colors - 1));
X    PrintRGB( (long) row >> 8, (long) row >> 4, (long) row );
X  }
X}
X
Xstatic LONG WindowWidth;
Xstatic LONG WindowHeight;
Xstatic LONG BorderLeft;
X
Xstatic struct Border *PensBorder;
X/*
X * Allocate all the gadgets for the color palette window
X */
Xstruct Gadget *MakePalette()
X{
X           struct Gadget *FirstGadget;
X  register struct Gadget *NextGadget;
X  register LONG i,Left,x,y,c = 0;
X
X  struct IntuiText *Text, *NextText;
X  struct PropInfo  *PropInfo;
X
X  LONG fourx = 4 << XScale;
X  LONG foury = 4 << YScale;
X
X  char *str;
X
X  Left = PENLEFT;
X
X  FirstGadget = NextGadget =
X    MakeBool( Left, PENTOP, fourx, foury, 0, PALPEN, GADGIMAGE );
X
X  if ( FirstGadget == NULL ) goto error;
X
X  i = 1 << (screen->BitMap.Depth);
X
X  for (x = 0; x < 6*8 && i > 0; x += 6) {
X    for (y = 0; y < 6*8 && i > 0; y += 6) {
X      if (c != 0) {
X
X        NextGadget->NextGadget =
X          MakeBool( Left, (y<<YScale)+PENTOP, fourx, foury, c, PALPEN+c,
X                    GADGIMAGE);
X
X        if ((NextGadget = NextGadget->NextGadget) == NULL) goto error;
X      }
X      c++;
X      i--;
X    }
X    Left += 6 << XScale;
X  }
X  WindowHeight = ((6*8) << YScale) + PENTOP + 6;
X
X  c = ((y + 1) << YScale) + 2;
X
X  if ( c > WindowHeight ) {
X    WindowHeight = c + 4;
X  }
X
X  PensBorder = ShadowBorder( BEVELEDUP, 4, 12, Left - 2, c+1);
X
X  if (PensBorder == NULL) goto error;
X
X  Left += 9;
X
X  BorderLeft = Left - 1;
X
X  i = -2 * ( XScale ^ 1 );
X
X  for (x = y = 0; y < 3; x += 10, y++) {
X
X    NextGadget->NextGadget = MakePot( Left + x, 22, fourx,
X                                      WindowHeight - 35, PALPOT, y);
X    NextGadget = NextGadget->NextGadget;
X
X    if ( NextGadget == NULL ) goto error;
X
X    NextGadget->Activation = GADGIMMEDIATE | FOLLOWMOUSE | RELVERIFY;
X    NextGadget->GadgetText = Text =
X                           ShadowIntui("0", i, WindowHeight - 32 );
X    if ( Text == NULL ) goto error;
X
X    PropInfo = (struct PropInfo *) NextGadget->SpecialInfo;
X    PropInfo->VertBody  = 0xfff;
X
X    switch (y) {
X      case 0:  PalGads.RedPot = NextGadget;
X               str = "R";
X               break;
X
X      case 1:  PalGads.GreenPot = NextGadget;
X               str = "G";
X               break;
X
X      case 2:  PalGads.BluePot = NextGadget;
X               str = "B";
X               break;
X    }
X    NextText = Text;
X
X    while ( NextText->NextText ) {
X      NextText = NextText->NextText;
X    }
X
X    NextText->NextText = ShadowIntui( str, i, -11 );
X
X    if ( NextText->NextText == NULL ) goto error;
X  }
X  Left += 32;
X
X  for (c = 0, x = 0; x < 17*3; x += 17) {
X
X    NextGadget->NextGadget =
X      MakeBool( Left, x + 11, 54, 13, 1, PALCNTL+c, NULL);
X
X    NextGadget = NextGadget->NextGadget;
X
X    if ( NextGadget == NULL) goto error;
X
X    switch (c) {
X      case 0:  NextGadget->GadgetText =
X                  ShadowIntui("Copy", 12,3);
X               break;
X
X      case 1:  NextGadget->GadgetText =
X                  ShadowIntui("Spread",4,3);
X               break;
X
X      case 2:  NextGadget->GadgetText =
X                  ShadowIntui("Exchg", 8,3);
X               break;
X    }
X    c++;
X  }
X  WindowWidth = Left + 59;
X
X  return(FirstGadget);
X
Xerror:
X  FreeBorder( PensBorder );
X  FreeGadgets( FirstGadget );
X  return( NULL );
X} /* MakePalette */
X
Xstatic struct Gadget *PalGadgets;
X
X/*
X * Open the Palette window
X */
XOpenPalWind()
X{
X  struct Window *OpenMyWind();
X
X  register struct Gadget *gadget;
X  register struct RastPort *Rp;
X  LONG fourx = 4 << XScale;
X
X  if (CurPict == NULL)
X    return;
X
X  if ( PalWind == NULL ) {
X
X    gadget = MakePalette();
X
X    if ( gadget == NULL ) {
X      DispErrMsg("Couldn't get palette gadgets", 0 );
X      return;
X    }
X
X    PalWind = OpenMyWind( &NewPal, screen, NULL, WindowWidth, WindowHeight);
X
X    if ( PalWind != NULL ) {
X
X      ModifyIDCMP( PalWind,  (long)
X                   PalWind->IDCMPFlags | MOUSEBUTTONS | MOUSEMOVE );
X
X      Rp = PalWind->RPort;
X
X      SetAPen( Rp, NORMALPEN );
X      RectFill( Rp, LEFTMARG, TOPMARG,
X                WindowWidth,WindowHeight);
X
X      BorderWindow( PalWind );
X
X      PalGadgets = gadget;
X
X      AddGList( PalWind, gadget, -1, -1);
X
X      RefreshGadgets( gadget, PalWind, NULL );
X
X      DrawBorder( Rp, PensBorder, 0L, 0L );
X      FreeBorder( PensBorder );
X
X      CurPen &= Num_vp_Colors - 1;
X
X      BoxPen( CurPen, MEDIUMPEN );
X      SetColorProps( CurPen );
X    }
X  } else {
X    WindowToFront( PalWind );
X  }
X  PaletteOpen = 1;
X} /* OpenPalWind */
X
X/*
X * Close the Palette window
X */
XClosePalWind()
X{
X  if (PalWind != NULL) {
X
X    NewPal.LeftEdge = PalWind->LeftEdge;
X    NewPal.TopEdge  = PalWind->TopEdge;
X
X    CloseMyWind(PalWind,PalGadgets);
X    PalGadgets = NULL;
X  }
X  PalWind = NULL;
X} /* ClosePalWind */
X
SHAR_EOF
echo "End of archive 7 (of 9)"
# if you want to concatenate archives, remove anything after this line
exit