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

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

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

# 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:
#	mand881.c
#	mandffp.c
#	mandieee.c
#	mandint32.c
#	mandp.h
# This is archive 5 of a 9-part kit.
# This archive created: Tue Jun 20 20:45:29 1989
echo "extracting mand881.c"
sed 's/^X//' << \SHAR_EOF > mand881.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 function that calculates the
X * Mandelbrot/Julia caluclation in 68881 assembly.  This funtion needs
X * work, so that it is all assembly instead of C and assembly.
X */
X
X#include "mandp.h"
X#include "parms.h"
X
XHeight_68881( p )
X  struct PotentialParms *p;
X{
X  register LONG k;
X  register double *P;
X
X  k = p->MaxIteration;
X
X  P = (double *) p;
X
X#asm
X;       mc68881
X;
X;four     equ   fp1
X;curx     equ   fp2
X;cury     equ   fp3
X;cura     equ   fp4
X;curb     equ   fp5
X;cura2    equ   fp6
X;curb2    equ   fp7
X;
X;
X;  set up modulus
X        fmove.d #"$4010000000000000",fp1
X;
X;  move posx and posy into fp4 and fp5
X;  move curx and cury into fp2 and fp3
X;
X        fmove.d (a2)+,fp4
X        fmove.d (a2)+,fp5
X        fmove.d (a2)+,fp2
X        fmove.d (a2),fp3
X;
X        fmove.x fp4,fp6
X        fmove.x fp5,fp7
X        fmul.x  fp6,fp6
X        fmul.x  fp7,fp7
XLoop
X;
X;    curb *= cura;
X;    curb += curb + cury;
X        fmul.x  fp4,fp5
X        fadd.x  fp5,fp5
X        fadd.x  fp3,fp5
X;
X;    cura = cura2 - curb2 + curx
X        fsub.x  fp7,fp6
X        fadd.x  fp2,fp6
X;
X;    curb2 = curb * curb;
X        fmove.x fp5,fp7
X        fmul.x  fp5,fp7
X;
X;    cura2 = cura * cura;
X        fmove.x fp6,fp4
X        fmul.x  fp6,fp6
X;
X;    if (cura2+curb2 > 4.0)
X;      return( k );
X        fmove.x fp6,fp0
X        fadd.x  fp7,fp0
X        fcmp.x  fp1,fp0
X        fdbgt   d4,Loop
X;       addq.l  #2,d4
X;
X#endasm
X     ;
X     return( p->MaxIteration - k );
X}
SHAR_EOF
echo "extracting mandffp.c"
sed 's/^X//' << \SHAR_EOF > mandffp.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 routines to calculate Mandelbrot and
X * Julia pictures in Amiga Fast Floating Point.
X */
X
X#include "mandp.h"
X
Xextern SHORT MaxOrbit;
X
Xstatic LONG MaxIter;
X
X/*
X * Fast Floating Point Mandelbrot Generator
X */
XMandelbrotFFP( Pict, StartX, StartY, GapX, GapY )
X  /*
X   * These parameters are IEEE 32 bit floating point numbers
X   */
X
X  struct Picture *Pict;
X
X  LONG  StartX, StartY, GapX, GapY;
X{
X  register int i, j, k;
X  register SHORT *CountPtr;
X
X  register float curx, cury;
X
X  float startx, starty, gapx, gapy;
X  float SPFieee();
X
X  UBYTE MandFlag;
X
X  /* Here we convert the IEEE parameters into FFP format */
X
X  startx = SPFieee( StartX );
X  starty = SPFieee( StartY );
X  gapx   = SPFieee( GapX );
X  gapy   = SPFieee( GapY );
X
X  MaxIter = Pict->MaxIteration;
X
X  if (Pict->Flags & NO_RAM_GENERATE)
X    CountPtr = Pict->Counts;
X  else
X    CountPtr = Pict->Counts + Pict->CurLine*Pict->CountX;
X
X  /* start in the upper left hand corner */
X
X  cury = starty;
X
X  /*
X   * for each row
X   */
X  for (i = Pict->CurLine; i < Pict->CountY; i++) {
X
X    curx = startx;
X
X    MandFlag = 0;
X
X    if ( Pict->Flags & NO_RAM_GENERATE )
X      CountPtr = Pict->Counts;
X
X    /*
X     * for each collumn
X     */
X
X    for (j = 0; j < Pict->CountX; j++) {
X
X     /* if we've hit a Mandelbrot point, then use the convergence detector,
X      *  to reduce compute time
X      */
X
X      if (*CountPtr == 0) {
X
X        if ( MandFlag ) {
X
X          k = FFP_Trace_Height( 0.0, 0.0, curx, cury );
X
X        } else {
X
X          k = FFP_Height( 0.0, 0.0, curx, cury ); /* Normal calculator */
X        }
X
X        MandFlag = k == Pict->MaxIteration;
X
X        *CountPtr = k;        /* save it in ram for recoloring */
X      }
X      CountPtr++;
X
X      curx += gapx;
X
X      ChildPause( Pict );
X    }
X    cury += gapy;
X
X    CheckEOL( Pict );
X  }
X} /* Mandelbrot */
X
X/***************************************************************************
X *
X *           Julia Curve Generator that uses Amiga Fast Floating Point
X *
X **************************************************************************/
X
X/*
X * Fast Floating Point Julia Generator
X */
XJuliaFFP( Pict, JuliaX, JuliaY, StartX, StartY, GapX, GapY )
X
X  /*
X   * These parameters are IEEE 32 bit floating point numbers
X   */
X
X  register struct Picture *Pict;
X  LONG  JuliaX, JuliaY;
X  LONG  StartX, StartY;
X  LONG  GapX,   GapY;
X{
X  register int i, j, k;
X  register float curx, cury;
X
X  register SHORT *CountPtr;
X
X  float juliax, juliay, gapx, gapy,startx;
X  float SPFieee();
X
X  UBYTE ConvFlag;
X
X  MaxIter = Pict->MaxIteration;
X
X  if (Pict->Flags & NO_RAM_GENERATE)
X    CountPtr = Pict->Counts;
X  else
X    CountPtr = Pict->Counts + Pict->CurLine*Pict->CountX;
X
X  /* Here we convert the IEEE parameters into FFP format */
X
X  juliax = SPFieee( JuliaX );
X  juliay = SPFieee( JuliaY );
X
X  gapx = SPFieee( GapX );
X  gapy = SPFieee( GapY );
X
X  /* start in the upper left hand corner */
X
X  startx = SPFieee(StartX);
X  cury   = SPFieee(StartY);
X
X  /* move down to next not generated line */
X
X  cury += Pict->CurLine*gapy;
X
X  /*
X   * for each row
X   */
X  for (i = Pict->CurLine; i < Pict->CountY; i++) {
X
X    curx = startx;
X    ConvFlag = 0;
X
X    if ( Pict->Flags & NO_RAM_GENERATE )
X      CountPtr = Pict->Counts;
X
X    /*
X     * for each collumn
X     */
X
X    for (j = 0; j < Pict->CountX; j++) {
X
X     /* if we've hit a Mandelbrot point, then use the convergence detector,
X      *  to reduce compute time
X      */
X
X      if (*CountPtr == 0) {
X
X        if (ConvFlag) {
X                                           /* try the convergence method */
X          k = FFP_Trace_Height( curx, cury, juliax, juliay);
X        } else {
X          k = FFP_Height( curx, cury, juliax, juliay);      /* Normal calc */
X        }
X
X        ConvFlag = k == Pict->MaxIteration;
X
X        *CountPtr = k;        /* save it in ram for recoloring */
X      }
X      CountPtr++;
X
X      curx += gapx;
X
X      ChildPause( Pict );
X    }
X    cury += gapy;
X
X    CheckEOL( Pict );
X  }
X} /* JuliaFFP */
X
X/*
X * This function calculated the 'potential' of a given location
X * in the complex plane.
X */
Xint
XFFP_Height( posx, posy, juliax, juliay )
X  float posx;    /* Location in screen coordinate space         */
X  float posy;    /* Location in screen coordinate space         */
X  float juliax;  /* Real part of location on complex plane      */
X  float juliay;  /* Imaginary part of location on complex plane */
X{
X  register float cura, curb;
X  register float cura2, curb2;
X  register LONG k;
X
X#ifdef CHECK_TASK_STACK
X
X  CheckStack();
X
X#endif
X
X  cura = cura2 = posx;
X  curb = curb2 = posy;
X
X  cura2 *= cura2;
X  curb2 *= curb2;
X
X  for (k = 0; k < MaxIter; k ++ ) {
X
X    curb *= cura;                     /* b = 2 * a * b  + juliay    */
X    curb += curb + juliay;
X
X    cura = cura2 - curb2 + juliax;    /* a = a2 - b2 + juliax       */
X
X    cura2 = cura * cura;              /* a2 = a * a                 */
X    curb2 = curb * curb;              /* b2 = b * b                 */
X
X    if (cura2+curb2 >= 16.0)          /* quit if a2+b2 is too big   */
X      return( k );
X  }
X  return( k );
X}
X
X/*
X * this is also a Mandelbrot potential calculator, that is tailored to
X * identify points that are 'in' the Mandelbrot set.  Points outside the
X * Mandelbrot set diverge.  Points inside converge.
X * This code uses a trace table mechanism to detect convergence.
X */
Xint
XFFP_Trace_Height( posx, posy, curx, cury )
X
X  float posx;    /* Real part of location on complex plane      */
X  float posy;    /* Imaginary part of location on complex plane */
X
X  float curx;    /* Real part of location on complex plane      */
X  float cury;    /* Imaginary part of location on complex plane */
X{
X  LONG  k, l;
X
X  LONG TraceSize = 32;
X
X  float olda[32], oldb[32]; /* Convergence trace table */
X
X  register float cura, curb, cura2, curb2;
X  register float *RealTrace, *ImagTrace;
X
X#ifdef CHECK_TASK_STACK
X
X  CheckStack();
X
X#endif
X
X  cura = cura2 = posx;
X  curb = curb2 = posy;
X
X  cura2 *= cura2;
X  curb2 *= curb2;
X
X  for (k = 0; k < MaxIter; k += TraceSize) {
X
X    RealTrace = olda;
X    ImagTrace = oldb;
X
X    for (l = 0; l < TraceSize; l++) {
X
X      *(RealTrace++) = cura;
X      *(ImagTrace++) = curb;
X
X      curb *= cura;
X      curb += curb + cury;
X
X      cura = cura2 - curb2 + curx;
X
X      cura2 = cura * cura;
X      curb2 = curb * curb;
X
X      if (cura2+curb2 >= 16.0)
X        return( k + l );
X    }
X
X    /* Scope out trace table for convergence */
X
X    RealTrace = olda;
X    ImagTrace = oldb;
X
X    for (l = 0; l < TraceSize; l++)
X
X      if (cura == *(RealTrace++) && curb == *(ImagTrace++)) {
X        k += MaxIter;
X        return( MaxIter );
X      }
X  }
X  return( MaxIter );
X}
X
XDrawOrbitFFP( Pict, creal, cimag, zreal, zimag )
X  register struct Picture *Pict;
X  LONG zreal, zimag, creal, cimag;
X{
X  register struct RastPort *Rp;
X  register float cura,  curb;
X           float cura2, curb2;
X           float Creal, Cimag;
X
X  float x_scale, y_scale;
X  int x_center, y_center;
X  int width, height;
X  int x, y;
X  register int k;
X
X  struct Window *Window;
X
X  Window = OrbitWind;
X
X  Rp = Window->RPort;
X
X  width  = (Window->Width-Pict->LeftMarg-Pict->RightMarg);
X  height = (Window->Height-Pict->TopMarg-Pict->BotMarg);
X
X  x_center = width/2 + Pict->LeftMarg;
X  y_center = height/2 + Pict->TopMarg;
X
X  y_scale = x_scale = (float) height / 2.0;
X/*x_scale *= AspectRatio( Pict );*/
X
X  if ( Pict->pNode.ln_Type == MANDPICT ) {
X
X    Creal = SPFieee(creal);
X    Cimag = SPFieee(cimag);
X
X    cura = cura2 = SPFieee(zreal);
X    curb = curb2 = SPFieee(zimag);
X
X  } else {
X
X    Creal = SPFieee(zreal);
X    Cimag = SPFieee(zimag);
X
X    cura = cura2 = SPFieee(creal);
X    curb = curb2 = SPFieee(cimag);
X
X  }
X
X  cura2 *= cura2;
X  curb2 *= curb2;
X
X  SetAPen( Rp, 0 );
X  RectFill( Rp, Pict->LeftMarg, Pict->TopMarg, width+Pict->LeftMarg-1, height+Pict->TopMarg-1);
X
X  SetAPen( Rp, HIGHLIGHTPEN);
X
X  for (k = 0; k < MaxOrbit; k++ ) {
X
X    curb *= cura;
X    curb += curb + Cimag;
X
X    cura  = cura2 - curb2 + Creal;
X
X    cura2 = cura * cura;
X    curb2 = curb * curb;
X
X    if (cura2+curb2 >= 16.0)
X      return( k );
X
X    /* map real and imaginary parts into window coordinates */
X
X    x = x_center + (int)(x_scale*cura);
X    y = y_center + (int)(y_scale*curb);
X
X    if ( x >= Pict->LeftMarg && x < Window->Width-Pict->RightMarg &&
X         y >= Pict->TopMarg  && y < Window->Height-Pict->BotMarg ) {
X
X      /* plot pixel location */
X      WritePixel( Rp, x, y);
X    }
X
X  }
X  return( k );
X}
X
X
X
SHAR_EOF
echo "extracting mandieee.c"
sed 's/^X//' << \SHAR_EOF > mandieee.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 Mandelbrot and Julia picture generators
X * in IEEE floating point format.
X */
X
X#include "mandp.h"
X#include "parms.h"
X
Xextern SHORT MaxOrbit;
X
Xextern char *IEEELib;
X
X/*
X * IEEE Floating Point Mandelbrot Generator
X */
Xint
XMandelbrotIEEE( Pict )
X  register struct Picture *Pict;
X{
X  register int i, j, k;
X  register SHORT *CountPtr;
X  register int  MathMode;
X
X  struct PotentialParms Parms;
X  struct RastPort *Rp;
X
X  struct MathIeeeDoubBasBase *LocalMathBase;
X
X  LocalMathBase = (struct MathIeeeDoubBasBase *) OpenLibrary( IEEELib, 0L );
X
X  if (LocalMathBase == NULL)
X    return;
X
X  MathMode = Pict->MathMode;
X
X  if (Pict->Flags & NO_RAM_GENERATE)
X    CountPtr = Pict->Counts;
X  else
X    CountPtr = Pict->Counts + (Pict->CurLine*Pict->CountX);
X
X  Parms.ScreenReal = Pict->Real;
X  Parms.ScreenImag = Pict->Imag;
X
X  /* start in the upper left hand corner */
X
X  Parms.C_Imag = Pict->ImagLow;
X  Parms.C_Imag += Pict->CurLine*Pict->ImagGap;
X
X  Parms.MaxIteration = Pict->MaxIteration;
X
X  /*
X   * for each pixel, calculate mandelbrot
X   */
X  for (i = Pict->CurLine; i < Pict->CountY; i++) {
X
X    Parms.C_Real = Pict->RealLow;
X
X    if ( Pict->Flags & NO_RAM_GENERATE )
X      CountPtr = Pict->Counts;
X
X    for (j = 0; j < Pict->CountX; j++) {
X
X      if (*CountPtr == 0) {
X        if (MathMode == 4) {
X          k = Height_68881( &Parms );
X        } else {
X          k = IEEE_Height( &Parms );
X        }
X
X        *CountPtr = k;
X      }
X      CountPtr++;
X
X      Parms.C_Real += Pict->RealGap;
X
X      ChildPause( Pict );
X    }
X    Parms.C_Imag += Pict->ImagGap;
X
X    CheckEOL( Pict );
X  }
X  CloseLibrary( LocalMathBase );
X} /* MandelbrotIEEE */
X
X/*
X * IEEE Floating Point Juliaelbrot Generator
X */
XJuliaIEEE( Pict )
X  register struct Picture *Pict;
X{
X  register int i, j, k;
X  register SHORT *CountPtr;
X
X  struct PotentialParms Parms;
X
X  struct MathIeeeDoubBasBase *LocalMathBase;
X
X  LocalMathBase = (struct MathIeeeDoubBasBase *) OpenLibrary( IEEELib, 0L );
X
X  if (Pict->Flags & NO_RAM_GENERATE)
X    CountPtr = Pict->Counts;
X  else
X    CountPtr = Pict->Counts + (Pict->CurLine*Pict->CountX);
X
X  Parms.C_Real = Pict->Real;
X  Parms.C_Imag = Pict->Imag;
X  Parms.C_Imag += Pict->CurLine*Pict->ImagGap;
X
X  /* start in the upper left hand corner */
X  Parms.ScreenImag = Pict->ImagLow;
X
X  Parms.MaxIteration = Pict->MaxIteration;
X
X  /*
X   * for each pixel, calculate mandelbrot
X   */
X  for (i = Pict->CurLine; i < Pict->CountY; i++) {
X
X    Parms.ScreenReal = Pict->RealLow;
X
X    if ( Pict->Flags & NO_RAM_GENERATE )
X      CountPtr = Pict->Counts;
X
X    for (j = 0; j < Pict->CountX; j++) {
X
X      if (*CountPtr == 0) {
X        if (Pict->MathMode == 2) {
X          k = IEEE_Height( &Parms );
X        } else {
X          k = Height_68881( &Parms );
X        }
X
X        *CountPtr = k;
X      }
X      CountPtr++;
X
X      Parms.ScreenReal += Pict->RealGap;
X
X      ChildPause( Pict );
X    }
X    Parms.ScreenImag += Pict->ImagGap;
X
X    CheckEOL( Pict );
X  }
X  CloseLibrary( LocalMathBase );
X} /* JuliaIEEE */
X
XIEEE_Height( Parms )
X  register struct PotentialParms *Parms;
X{
X  register double cura,  curb;
X           double cura2, curb2;
X
X  int k;
X
X#ifdef CHECK_TASK_STACK
X
X  CheckStack();
X
X#endif
X
X  cura = cura2 = Parms->ScreenReal;
X  curb = curb2 = Parms->ScreenImag;
X
X  cura2 *= cura2;
X  curb2 *= curb2;
X
X  for (k = 0; k < Parms->MaxIteration; k++ ) {
X
X    curb *= cura;
X    curb += curb + Parms->C_Imag;
X
X    cura = cura2 - curb2 + Parms->C_Real;
X
X    cura2 = cura * cura;
X    curb2 = curb * curb;
X
X    if (cura2+curb2 >= 16.0)
X      return( k );
X  }
X  return( k );
X}
X
XDrawOrbitIEEE( Pict )
X  register struct Picture *Pict;
X{
X  register struct RastPort *Rp;
X  register double cura,  curb;
X           double cura2, curb2;
X           double realc, imagc;
X  register int k;
X  double x_scale, y_scale;
X  int x_center, y_center;
X  int width, height;
X  int x, y;
X
X  struct Window *Window;
X
X  Window = OrbitWind;
X
X  Rp = Window->RPort;
X
X  width  = (Window->Width-Pict->LeftMarg-Pict->RightMarg);
X  height = (Window->Height-Pict->TopMarg-Pict->BotMarg);
X
X  x_center = width/2 + Pict->LeftMarg;
X  y_center = height/2 + Pict->TopMarg;
X
X  y_scale = x_scale = (float) height / 2.0;
X/*x_scale *= AspectRatio( Pict );*/
X
X  realc = Pict->RealLow + (float) (MouseX-Pict->LeftMarg) * Pict->RealGap;
X  imagc = Pict->ImagLow + (float) (MouseY-Pict->TopMarg)  * Pict->ImagGap;
X
X  if ( Pict->pNode.ln_Type == MANDPICT ) {
X
X    cura = cura2 = Pict->Real;
X    curb = curb2 = Pict->Imag;
X
X  } else {
X
X    cura = cura2 = realc;
X    curb = curb2 = imagc;
X    realc = Pict->Real;
X    imagc = Pict->Imag;
X  }
X
X  cura2 *= cura2;
X  curb2 *= curb2;
X
X  SetAPen( Rp, 0 );
X  RectFill( Rp, Pict->LeftMarg, Pict->TopMarg, width+Pict->LeftMarg-1, height+Pict->TopMarg-1);
X
X  SetAPen( Rp, HIGHLIGHTPEN);
X
X  for (k = 0; k < MaxOrbit; k++ ) {
X
X    curb *= cura;
X    curb += curb + imagc;
X
X    cura  = cura2 - curb2 + realc;
X
X    cura2 = cura * cura;
X    curb2 = curb * curb;
X
X    if (cura2+curb2 >= 16.0)
X      return( k );
X
X    /* map real and imaginary parts into window coordinates */
X
X    x = x_center + (int)(x_scale*cura);
X    y = y_center + (int)(y_scale*curb);
X
X    if ( x >= Pict->LeftMarg && x < Window->Width-Pict->RightMarg &&
X         y >= Pict->TopMarg  && y < Window->Height-Pict->BotMarg ) {
X
X      /* plot pixel location */
X
X      WritePixel( Rp, x, y);
X    }
X
X  }
X  return( k );
X}
X
X
X
SHAR_EOF
echo "extracting mandint32.c"
sed 's/^X//' << \SHAR_EOF > mandint32.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 calculate Mandelbrot and
X * Julia pictures using a special and fast fixed point (scaled ints) format.
X * It has generators for 68000 and 68020 in assembly.
X */
X
X#include "mandp.h"
X
X#include "parms.h"
X
X#define BITS2SHIFT 27
X
X/*
X * 32 bit fixed point generator
X */
XMandelbrotInt32( Pict )
X  register struct Picture *Pict;
X{
X  register LONG   i, j, k;
X  register SHORT *CountPtr;
X
X  double gap;
X
X  UBYTE ConvFlag;
X  LONG  gapx, gapy, startx;
X
X  struct IntPotParms Parms;
X  struct RastPort   *Rp;
X
X  if (Pict->Flags & NO_RAM_GENERATE)
X    CountPtr = Pict->Counts;
X  else
X    CountPtr = Pict->Counts + Pict->CurLine*Pict->CountX;
X
X  /* figure out horizontal and verticle distances between points in plane.
X   * convert them to fixed point format                                    */
X
X  gapy = (int) (Pict->ImagGap*((double)(1<<BITS2SHIFT)));
X  gapx = (int) (Pict->RealGap*((double)(1<<BITS2SHIFT)));
X
X  startx = (int)(Pict->RealLow*((double)(1<<BITS2SHIFT)));
X
X  /*
X   * for each point in the image, calculate Mandelbrot
X   */
X  Parms.C_Imag = (int)(Pict->ImagLow*((double)(1<<BITS2SHIFT)));
X
X  Parms.C_Imag += Pict->CurLine*gapy;
X
X  Parms.ScreenReal = 0;
X  Parms.ScreenImag = 0;
X
X  Parms.MaxIteration = Pict->MaxIteration;
X
X  for (i = Pict->CurLine; i < Pict->CountY; i++) {
X
X    Parms.C_Real = startx;
X
X    ConvFlag = 0;
X
X    if ( Pict->Flags & NO_RAM_GENERATE )
X      CountPtr = Pict->Counts;
X
X    for (j = 0; j < Pict->CountX; j++) {
X
X      if (*CountPtr == 0) {
X
X        /*
X         * if the last pixel was mandelbrot, then use trace table
X         */
X        if (ConvFlag) {
X
X          k = Int32_Trace_Height( &Parms );
X        } else {
X
X          k = Int32_Height( &Parms );
X        }
X
X        ConvFlag = k == Pict->MaxIteration;
X        *CountPtr = k;
X      }
X      CountPtr++;
X
X      Parms.C_Real += gapx;
X
X      ChildPause( Pict );
X    }
X    Parms.C_Imag += gapy;
X
X    CheckEOL( Pict );
X  }
X} /* Mandelbrot32Int */
X
X#ifdef CHECK_TASK_STACK
X
Xint stackerr;
XLONG stacklow;
XLONG stackhi;
XLONG stackovfl;
XLONG stackmax;
X
XCheckStack() {
X  register struct Task *Task;
X  register LONG hi,reg,low;
X  register LONG size;
X
X  Task = FindTask(0L);
X
X  hi = Task->tc_SPUpper;
X  reg = Task->tc_SPReg;
X  low = Task->tc_SPLower;
X
X  size = hi - reg;
X
X  if (reg < low) {
X
X    if (size > stackmax) {
X      stackerr  = 1;
X
X      stacklow   = low;
X      stackhi    = hi;
X      stackovfl  = reg;
X      stackmax   = size;
X    }
X  } else {
X
X    if (stackerr == 0 && size > stackmax) {
X      stacklow   = low;
X      stackhi    = hi;
X      stackovfl  = reg;
X      stackmax   = size;
X    }
X  }
X}
X
XPrintStack()
X{
X  if (stackerr != 0)
X    printf("********* STACK ERR ***********\n");
X
X  printf("Low   %08x\nHigh  %08x\nSP     %08x\n",
X          stacklow, stackhi, stackovfl );
X
X  printf("MinStack %d\n",stackmax);
X}
X
X#endif
X
X/*
X * 32 bit fixed point generator
X */
XJuliaInt32( Pict )
X  register struct Picture *Pict;
X{
X  register LONG   i, j, k;
X  register SHORT *CountPtr;
X
X  LONG  gapx, gapy, startx;
X  UBYTE ConvFlag;
X
X  struct IntPotParms Parms;
X
X  if (Pict->Flags & NO_RAM_GENERATE)
X    CountPtr = Pict->Counts;
X  else
X    CountPtr = Pict->Counts + (Pict->CurLine*Pict->CountX);
X
X  /* figure out horizontal and verticle distances between points in plane.
X   * convert them to fixed point format                                    */
X
X  gapx = (int) ( Pict->RealGap * (double) (1 << BITS2SHIFT) );
X  gapy = (int) ( Pict->ImagGap * (double) (1 << BITS2SHIFT) );
X
X  /*
X   * for each point in the image, calculate Julia
X   */
X  Parms.ScreenImag  = (int) ( Pict->ImagLow * (double) (1 << BITS2SHIFT) );
X  Parms.ScreenImag += Pict->CurLine*gapy;
X
X  startx = (int) ( Pict->RealLow * (double) (1 << BITS2SHIFT) );
X
X  Parms.C_Real = (int) ( Pict->Real * (double) (1 << BITS2SHIFT) );
X  Parms.C_Imag = (int) ( Pict->Imag * (double) (1 << BITS2SHIFT) );
X
X  Parms.MaxIteration = Pict->MaxIteration;
X
X  for (i = Pict->CurLine; i < Pict->CountY; i++) {
X
X    Parms.ScreenReal = startx;
X    ConvFlag = 0;
X
X    if ( Pict->Flags & NO_RAM_GENERATE )
X      CountPtr = Pict->Counts;
X
X    for (j = 0; j < Pict->CountX; j++) {
X
X      if (*CountPtr == 0) {
X
X        /*
X         * if the last pixel was mandelbrot, then use trace table
X         */
X
X        if ( ConvFlag ) {
X          k = Int32_Trace_Height( &Parms );
X        } else {
X          k = Int32_Height( &Parms );
X        }
X
X        ConvFlag = k == Pict->MaxIteration;
X        *CountPtr = k;
X      }
X      CountPtr++;
X
X      Parms.ScreenReal += gapx;
X
X      ChildPause( Pict );
X    }
X    Parms.ScreenImag += gapy;
X
X    CheckEOL( Pict );
X  }
X} /* Julia32Int */
X
X/*
X * 32 bit fixed point generator
X */
XMandelbrotInt32II( Pict )
X  register struct Picture *Pict;
X{
X  register LONG   i, j, k;
X  register struct RastPort *Rp;
X
X  double gap;
X
X  SHORT *CountPtr;
X  LONG  gapx, gapy, startx;
X
X  struct IntPotParms Parms;
X
X  if (Pict->Flags & NO_RAM_GENERATE)
X    CountPtr = Pict->Counts;
X  else
X    CountPtr = Pict->Counts + Pict->CurLine*Pict->CountX;
X
X  /* figure out horizontal and verticle distances between points in plane.
X   * convert them to fixed point format                                    */
X
X  gapy = (int) (Pict->ImagGap*((double)(1<<BITS2SHIFT)));
X  gapx = (int) (Pict->RealGap*((double)(1<<BITS2SHIFT)));
X
X  startx = (int)(Pict->RealLow*((double)(1<<BITS2SHIFT)));
X
X  /*
X   * for each point in the image, calculate Mandelbrot
X   */
X  Parms.C_Imag = (int)(Pict->ImagLow*((double)(1<<BITS2SHIFT)));
X  Parms.C_Imag += Pict->CurLine*gapy;
X
X  Parms.ScreenReal = 0;
X  Parms.ScreenImag = 0;
X
X  Parms.MaxIteration = Pict->MaxIteration;
X
X  for (i = Pict->CurLine; i < Pict->CountY; i++) {
X
X    Parms.C_Real = startx;
X
X    if ( Pict->Flags & NO_RAM_GENERATE )
X      CountPtr = Pict->Counts;
X
X    for (j = 0; j < Pict->CountX; j++) {
X
X      /*
X       * if the last pixel was mandelbrot, then use trace table
X       */
X
X      k = Int32_Height_Fast( &Parms );
X
X      *CountPtr++ = k;
X
X      Parms.C_Real += gapx;
X
X      ChildPause( Pict );
X    }
X    Parms.C_Imag += gapy;
X
X    CheckEOL( Pict );
X  }
X} /* MandelbrotInt32II */
X
X/*
X *  This code does mandelbrot without any trace lookup.
X *  It is the fastest 68000 generator in the house.
X */
XInt32_Height( 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   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
XInt32_Trace_Height( Parms )
X
X  register struct IntPotParms *Parms;
X{
X  SHORT  k,TLen;
X  LONG  OldA[17];
X
X  register LONG cura, curb, cura2, curb2;
X
X#asm
X;
X;
X;  d1 - BITS2SHIFT
X;  d2 - k
X;  d4 - a
X;  d5 - b
X;  d6 - a2
X;  d7 - b2
X;  a0 - Trace Table pointer
X;
XTrace equ 16
XOldA  equ -132
Xk     equ -2
XTLen  equ -4
X
X   move.l   #Bits2Shift,d1
X   move.l   screenr(a2),d4
X   move.l   screeni(a2),d5
X;
X   lea      OldA(a5),a0          ; Set up Trace table pointer
X   move.w   #Trace,d2            ; Set up Trace table len
X;
X   move.w   #-1,k(a5)
X   bra      TPosa2               ; branch in to middle to get a2 = a * a
X;
XTLoop
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      TPos1       ; get absolute value of op1
X   neg.l    d6
XTPos1
X   eor.l    d5,d7      ; calculate result sign
X   tst.l    d5         ; get absolute value of op2
X   bpl      TPos2
X   neg.l    d5
XTPos2
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      TPos3
X   neg.l    d5         ; yes, better negate it.
XTPos3
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
XTPosa2
X;
X;  cura2 = cura * cura;
X   move.l   d4,d0      ; get absolute value of a in d0
X   bpl      TPosa
X   neg.l    d0
XTPosa
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      bailout
X;
X;  curb2 = curb * curb;
X   move.l   d5,d0      ; get absolute value of a in d0
X   bpl      TPosb
X   neg.l    d0
XTPosb
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      bailout
X
X   move.l   d6,d0      ; if (cura2 + curb2 >= 4) goto bailout;
X   add.l    d7,d0
X   bvs      bailout
X
X   move     d0,(a0)+   ; save magnitude in trace table
X
X   addq.w   #1,k(a5)   ; are we out of iterations?
X   move.w   maxi(a2),d0
X   cmp.w    k(a5),d0
X   ble      GotIt
X   dbra     d2,TLoop   ; nope, so try again till trace table full
X
X   move.w   -(a0),d0   ; get last entry in the trace
X
X   move.w   #Trace-1,d2  ; set up length and address for comparison loop
X   lea      OldA(a5),a0
X
XTCLoop
X   cmp      (a0)+,d0
X   beq      GotIt       ; did we find it?
X   dbra     d2,TCLoop
X
X   lea      OldA(a5),a0 ; no match, so prepare for the next round
X   move     d0,(a0)+    ; move last entry of the table
X
X   move.w   #Trace,d2
X   bra      TLoop
X
XGotIt
X   move.w   maxi(a2),k(a5)
Xbailout
X   move.w   k(a5),d0
X   ext.l    d0
X#endasm
X   ;;
X}
X
X/*
X * 32 bit fixed point generator
X */
XInt32_Height_Fast( Parms )
X  struct IntPotParms *Parms;
X{
X  register struct IntPotParms *P = Parms;
X  register LONG cura,curb,cura2,curb2;
X  /*
X   *  This is the fastest generator in the house.
X   */
X#asm
X   machine mc68020
Xfscreenr  equ 0
Xfscreeni  equ 4
Xfcurx     equ 8
Xfcury     equ 12
Xfmaxi     equ 16
X
XZcurx      equ   8
XZcury      equ  12
X;
X;  d1 - BITS2SHIFT
X;  d2 - k
X;  d4 - a
X;  d5 - b
X;  d6 - a2
X;  d7 - b2
X;
X;  cura = curb = curc = curd = 0;
X   move.w   maxi(a2),d1
X   move.l   #27,d2
X   move.l   fscreenr(a2),d4
X   move.l   fscreeni(a2),d5
X   move.l   fcurx(a2),a0
X   move.l   fcury(a2),a1
X   bra      Zpos2
X
XZLoop
X;
X;  cura = cura2 - curb2 + curx;
X;
X   exg      d6,d4
X   sub.l    d7,d4
X;   move.l   a0,d0
X   add.l    a0,d4
X;
X;  curb = cura * curb
X;
X   muls.l   d6,d0:d5
X   asl.l    #5,d0
X   lsr.l    d2,d5
X   or.l     d0,d5
X;
X;  curb += curb + cury;
X;
X   add.l    d5,d5
X;   move.l   a1,d0
X   add.l    a1,d5
XZpos2
X;
X;  cura2 = cura * cura;
X;
X   move.l   d4,d6
X   muls.l   d6,d0:d6
X   asl.l    #5,d0
X   bvs      Zbailout
X   lsr.l    d2,d6
X   or.l     d0,d6
X;
X;  curb2 = curb * curb;
X;
X   move.l   d5,d7
X   muls.l   d7,d0:d7
X   asl.l    #5,d0
X   bvs      Zbailout
X   lsr.l    d2,d7
X   or.l     d0,d7
X;
X   move.l   d6,d0
X   add.l    d7,d0
X   bvs      Zbailout
X;
X;  cmp.l    #536870912,d0
X;   bge      Zbailout
X;
X   dbra     d1,ZLoop
X;
X;  addq     #1,d1
XZbailout
X   move.w   fmaxi(a2),d0
X   sub.w    d1,d0
X   sub.w    #1,d0
X   ext.l    d0
X#endasm
X   ;
X}
SHAR_EOF
echo "extracting mandp.h"
sed 's/^X//' << \SHAR_EOF > mandp.h
X/*
X * MandelVroom 2.0
X *
X * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
X *
X * All rights reserved.
X *
X * Permission is hereby granted to distribute this program's source
X * executable, and documentation for non-comercial purposes, so long as the
X * copyright notices are not removed from the sources, executable or
X * documentation.  This program may not be distributed for a profit without
X * the express written consent of the author Kevin L. Clague.
X *
X * This program is not in the public domain.
X *
X * Fred Fish is expressly granted permission to distribute this program's
X * source and executable as part of the "Fred Fish freely redistributable
X * Amiga software library."
X *
X * Permission is expressly granted for this program and it's source to be
X * distributed as part of the Amicus Amiga software disks, and the
X * First Amiga User Group's Hot Mix disks.
X *
X * contents: this is the include file for MandelVroom standard includes.
X */
X
X#include <exec/types.h>
X#include <exec/lists.h>
X#include <exec/nodes.h>
X#include <exec/memory.h>
X#include <exec/execbase.h>
X#include <exec/semaphores.h>
X
X#include <graphics/display.h>
X#include <graphics/gfxbase.h>
X#include <graphics/gfx.h>
X#include <graphics/gfxmacros.h>
X
X#include <intuition/intuition.h>
X#include <intuition/intuitionbase.h>
X
X#include <workbench/startup.h>
X#include <workbench/workbench.h>
X
X#include <libraries/dosextens.h>
X
X#include <iff/ilbm.h>
X
X#include <stdio.h>
X#include <functions.h>
X
X/**************************************************************************
X *
X * color cycling stuff
X *
X *************************************************************************/
X
X#define EXDepth 6        /* Maximum depth (6=HAM) */
X#define maxColorReg 32
X#define maxCycles   4
X#define RNG_NORATE  36   /* Dpaint uses this rate to mean non-active */
X
X#define REVERSE 0x2
X
Xtypedef struct {
X   WORD  pad1;   /* future exp - store 0 here */
X   WORD  rate;   /* 60/sec=16384, 30/sec=8192, 1/sec=16384/60=273 */
X   WORD  active; /* lo bit 0=no cycle, 1=yes; next bit 1=rvs */
X   UBYTE low;    /* range lower */
X   UBYTE high;   /* range upper */
X   } CrngChunk;
X
X/*
X * Mandelvroom uses the gadget ID's to decode the meaning of
X * gadget related messages.  It uses a special encoding to indicate
X * what window, and function this gadget is associated with.
X *
X * I split the gadget id into three fields:
X *
X *    window type - indicates how the window is being used (e.g.
X *      contour or palette)
X *
X *    gadget type - general classification of gadget within the window
X *
X *    gadget number - in the case of an array of gadgets (like the pens
X *      in the color palette) this is the array index.
X */
X
X/*
X * This defines the bit positions of the fields within the gadget ID
X */
X
X#define WINDTYPEBITS 11
X#define TYPEBITS  6
X
X/*
X * These masks are used for extracting the fields from gadgetIDs
X * when messages are received.
X */
X
X#define WINDMASK 0xffff
X#define TYPEMASK 0xf
X#define NUMMASK 0x3f
X
X#define WIND_TYPE(g) ((g) >> WINDTYPEBITS & WINDMASK)
X#define GADG_TYPE(g) ((g) >> TYPEBITS & TYPEMASK)
X#define GADG_NUM(g)  ((g) & NUMMASK)
X#define CNT_NUM(a)   ((a)==CONTLAST ? NUMCONTS-1 : (a)+FirstContour)
X
X/*
X * These are the window types
X */
X
X#define PALTYPE   0 /* gadgetID indicates palette gadget */
X#define CONTYPE   1 /* gadgetID indicates contour gadget */
X#define PICTTYPE  2 /* gadgetID indicates picture gadget */
X#define HELPTYPE  3 /* gadgetID indicates help gadget */
X#define CYCTYPE   4 /* gadgetID indicates color cycling gadget */
X#define ORBTTYPE  5 /* gadgetID indicates orbit gadget */
X
X/*
X * These are the general classifications for palette gadgets
X */
X
X#define PALPENS  0   /* pen gadget in the palette */
X#define PALPOTS  1   /* Red, Green, Blue potentiometer gadgets */
X#define PALCNTLS 2   /* Controls (commands like copy, blend, exchange) */
X
X/*
X * Basis for individual ID expansion
X */
X
X#define PALPEN   (PALTYPE << WINDTYPEBITS | PALPENS  << TYPEBITS)
X#define PALPOT   (PALTYPE << WINDTYPEBITS | PALPOTS  << TYPEBITS)
X#define PALCNTL  (PALTYPE << WINDTYPEBITS | PALCNTLS << TYPEBITS)
X
X/*
X * These are the IDs for the command gadgets
X */
X
X#define PALCOPY  (PALCNTL | 0)
X#define PALRANGE (PALCNTL | 1)
X#define PALEXCG  (PALCNTL | 2)
X
X/*
X * Now we define the contour gadget IDs
X *
X * Start with the gadget types
X */
X
X#define CONTSELS  0  /* Contour window Pens */
X#define CONTUPS   1  /* Contour window increment gadget */
X#define CONTDOWNS 2  /* Contour window decrement gadget */
X#define CONTPOTS  3  /* Contour window potentiometer gadget */
X#define CONTCNTLS 4  /* Contour window controls */
X
X/*
X * Shift everything over so we can or in the specifics
X */
X
X#define CONTSEL  (CONTYPE << WINDTYPEBITS | CONTSELS  << TYPEBITS)
X#define CONTUP   (CONTYPE << WINDTYPEBITS | CONTUPS   << TYPEBITS)
X#define CONTDOWN (CONTYPE << WINDTYPEBITS | CONTDOWNS << TYPEBITS)
X#define CONTPOT  (CONTYPE << WINDTYPEBITS | CONTPOTS  << TYPEBITS)
X#define CONTCNTL (CONTYPE << WINDTYPEBITS | CONTCNTLS << TYPEBITS)
X
X#define CONTLAST  (CONTSEL | 32)
X
X/*
X * Make up the command gadgets IDs for the contour window
X */
X
X#define CONTRECOL (CONTCNTL | 0)
X#define CONTSET   (CONTCNTL | 1)
X#define CONTSMTH  (CONTCNTL | 2)
X#define CONTCUT   (CONTCNTL | 3)
X#define CONTCOPY  (CONTCNTL | 4)
X#define CONTPASTE (CONTCNTL | 5)
X#define CONTCEIL  (CONTCNTL | 9)
X#define CONTBAR   (CONTCNTL | 10)
X
X/*
X * Shift everything over so we can or in the specifics
X */
X
X#define PICTCUR   (PICTTYPE << WINDTYPEBITS | 0)
X#define PICTGEN   (PICTTYPE << WINDTYPEBITS | 1)
X#define PICTIN    (PICTTYPE << WINDTYPEBITS | 2)
X#define PICTOUT   (PICTTYPE << WINDTYPEBITS | 3)
X#define PICTJULIA (PICTTYPE << WINDTYPEBITS | 4)
X
X#define HELPUP     (HELPTYPE << WINDTYPEBITS | 0)
X#define HELPDOWN   (HELPTYPE << WINDTYPEBITS | 1)
X#define HELPSCROLL (HELPTYPE << WINDTYPEBITS | 2)
X
X/*
X * These are the general classifications for cycle gadgets
X */
X
X#define CYCRNUMS 0   /* cycle range indicators */
X#define CYCCNTLS 1   /* Controls (Range changer, direction, and speed) */
X
X/*
X * Basis for individual ID expansion
X */
X
X#define CYCRNUM  (CYCTYPE << WINDTYPEBITS | CYCRNUMS << TYPEBITS)
X#define CYCCNTL  (CYCTYPE << WINDTYPEBITS | CYCCNTLS << TYPEBITS)
X
X/*
X * These are the IDs for the command gadgets
X */
X
X#define CYCRANGE (CYCCNTL | 0)
X#define CYCDIR   (CYCCNTL | 1)
X#define CYCSPEED (CYCCNTL | 2)
X#define CYCON    (CYCCNTL | 3)
X
X#define ORBTCNTLS 0 /* controls (go into orbit mode) */
X#define ORBTMODE  (ORBTCNTLS | 0)
X
X/*
X * Now for some miscelaneous definitions
X *
X * Define the number of contours the system allows.
X */
X
X#define NUMCONTS    256  /* This is total number of contours */
X#define DISPCONTS    32  /* This is how many are displayable */
X
X#define VERSION 200
X
X/*
X * These definitions help us identify menu item selections.
X */
X
X/* Menu Project's, Items */
X#define NEWITEM      0
X#define CURITEM      1
X#define LOADITEM     2
X#define SAVEPROJ     3
X#define CLOSEPROJ    4
X#define SAVEILBM     5
X#define HELPITEM     6
X#define CANCELITEM   7
X#define QUITITEM     8
X
X/* Display Menu's Items */
X#define COLORITEM     0
X#define CYCLEITEM     1
X#define CONTOURITEM   2
X#define AUTOCNTRITEM  3
X#define HISTOGRAMITEM 4
X#define BORDERITEM    5
X#define DEPTHITEM     6
X#define VIEWMODEITEM  7
X#define SCREENITEM    8
X
X/* Menu: Edit, Item: ViewMode's, SubItems */
X#define HIRESSUB 0
X#define INTERLACESUB 1
X#define HALFBRITESUB 2
X
X/* Menu: Edit, Item: Depth's, SubItems */
X#define BITPLANE1SUB  0
X#define BITPLANES2SUB 1
X#define BITPLANES3SUB 2
X#define BITPLANES4SUB 3
X#define BITPLANES5SUB 4
X#define BITPLANES6SUB 5
X
X/* Menu: Edit, Item: Screen's SubItem */
X
X#define WBENCHSUB  0
X#define STANDARD   1
X
X/* Calculate Menu's Items */
X#define GENERATEITEM   0
X#define ZOOMITEM       1
X#define SCROLLITEM     2
X#define LENSITEM       3
X#define GENERATORITEM  4
X#define COUNTITEM      5
X#define STATSITEM      6
X
X/* Menu: Edit, Item: ZoomIn's, SubItems */
X#define ZOOMIN    0
X#define ZOOMOUT   1
X#define ZOOMOFF   2
X#define ZOOMJULIA 3
X
X/* Menu: Project, Item: Generate SubItems */
X#define STARTGEN     0
X#define STOPGEN      1
X#define CONTGEN      2
X
X/* Menu: Project, Item: Scroll SubItems */
X#define SETSCROLL    0
X#define GENSCROLL    1
X#define CANCELSCROLL 2
X
X/* Menu: Edit, Item: Generator, SubItems */
X#define INTGENERATOR   0
X#define FLOATGENERATOR 1
X#define IEEEGENERATOR  2
X#define INTIIGENERATOR 3
X#define _81GENERATOR   4
X
X/* Special Menu's Items */
X#define PRESETITEM     0
X#define ORBITITEM      1
X#define ORBITMATHITEM  2
X#define MAXORBITEM     3
X
X/* Menu: Special, Item: OrbitMode, subitems */
X#define INTORBIT  0
X#define FFPORBIT  1
X#define IEEEORBIT 2
X
X/* Menu Entries */
X#define PROJECTMENU    0
X#define DISPLAYMENU    1
X#define CALCULATEMENU  2
X#define SPECIALMENU    3
X
X#define TOGGLED11 0x0200
X
X/* State definitions */
X
X#define COPYRIGHTSTATE    0
X#define IDLESTATE         1
X#define COPYRGBSTATE      2
X#define SPREADRGBSTATE    3
X#define XCHGRGBSTATE      4
X#define SLIDERGBSTATE     5
X#define SETHEIGHTSTATE    6
X#define SETCONTSTATE      7
X#define SMOOTHCONTSTATE   8
X#define CUTCONTSTATE      9
X#define COPYCONTSTATE    10
X#define PASTECONTSTATE   11
X#define CEILINGSTATE     12
X#define SLIDEBARSTATE    13
X#define ORBITSTATE       14
X#define ZOOMINSTATE      15
X#define RESIZEZOOMSTATE  16
X#define PROPRESIZESTATE  17
X#define ZOOMDRAGSTATE    18
X#define QUERYHEIGHTSTATE 19
X#define SETJULIASTATE    20
X#define SLIDESPEEDSTATE  21
X#define CYCLERANGESTATE  22
X#define HELPSTATE        23
X#define SCROLLHELPSTATE  24
X#define SCROLLPICTSTATE  25
X
X#define PARSEOK      0
X#define PARSEBAD     1
X
X#define ZOOMCLOSEHIT  0
X#define ZOOMDRAGHIT   1
X#define ZOOMRESIZEHIT 2
X#define PROPRESIZEHIT 3
X#define NOTHINGHIT    4
X
X/***************************************************************************
X *
X *  Structure for Mandelbrot and Julia Pictures
X *
X **************************************************************************/
X
Xstruct Rect {
X  int Left, Top, Right, Bot;
X};
X
Xstruct Picture {
X  struct Node pNode;          /* for a linked list of pictures */
X
X  struct List    zList;       /* Pictures that have zoom     */
X                              /* open in this picture        */
X  struct Node    zNode;       /* Used to maintain the above  */
X
X  struct Picture *DrawPict;   /* Picture that zoom box is in */
X
X  UBYTE  ZoomType;            /* Zoom In or Out              */
X  int    NavTop,  NavBot;     /* Zoom box location and size  */
X  int    NavLeft, NavRight;
X
X
X  struct NewWindow *NewWind;  /* NewWindow structure         */
X  struct Window    *Window;   /* Open Intuition window       */
X
X  struct RastPort ScrollRp;   /* rastport for saved image during scroll */
X  struct BitMap   ScrollBitMap; /* bitmap for saved image */
X
X                              /* Window origin for scroll*/
X  struct Rect ImageLoc;       /* Scroll's image location in Pict->Window*/
X  struct Rect ClipImage;      /* location after clipping to Window */
X  struct Rect DataClip;       /* clipping also reflected in data */
X
X  struct Gadget    *SizingGadget; /* sizing place            */
X                              /* Sempahore for window        */
X  struct SignalSemaphore WindowSemi;
X
X  struct Gadget    *Gadgets;
X
X  char   Title[40];           /* Window Title                */
X
X  SHORT *Counts;              /* Pointer to data area. One   */
X  LONG   CountsSize;          /* SHORT per pixel.            */
X                              /* CountX * CountY * sizeof( SHORT ) */
X
X  ULONG  Flags;               /* Flags regarding Picture specifics */
X
X  int    LeftMarg,  TopMarg;
X  int    RightMarg, BotMarg;
X
X  struct Task     *gTask;     /* Task that generates this    */
X  LONG   gSigBit, gSigMask;   /* Signal to free up paused tasks */
X  UBYTE  GenState;            /* Task state                  */
X  UBYTE  GenChildState;       /* Task state                  */
X  int    CurLine;             /* Index of Line generator is on */
X
X  struct Task     *cTask;     /* Task for Recolor Slow       */
X  UBYTE  ColorState;          /* Task state                  */
X  UBYTE  ColorChildState;          /* Task state                  */
X
X  struct Histogram *Hist;     /* Projects Histogram structure */
X
X  SHORT OldMaxIter;           /* used for recalc */
X  LONG   TimeStamp[3];        /* Time stamp for calculation */
X
X  /***********************************************************/
X
X  double Real,     Imag;      /* For Julia only (Julia Seed) */
X                              /* Set it to 0.0 for Mand      */
X  double RealLow,  ImagLow;   /* Screen Boundaries for Julia */
X  double RealHigh, ImagHigh;  /* Complex Plane Origin for Mand */
X  double RealGap,  ImagGap;   /* Real and Imaginary parts of */
X
X  SHORT  LeftEdge, TopEdge;   /* Window position on screen   */
X  SHORT  CountX, CountY;      /* Picture dimensions          */
X
X  SHORT  MaxIteration;
X  UBYTE  MathMode;            /* Int32, FFP, IEEE            */
X
X  SHORT  Heights[256];        /* Contours' heights and pens  */
X  UBYTE  Pens[256];
X
X  UBYTE  ClrXlate[1024];      /* There are MaxIteration entries */
X
X  SHORT  RGBs[32];            /* Red, Green, Blue values     */
X  USHORT ViewModes;
X  SHORT  Depth;
X
X  SHORT  CycleOn;             /* Color Cycling stuff */
X  CrngChunk Crngs[maxCycles];
X};
X
X/* Picture.Types */
X
X#define JULIAPICT 1
X#define MANDPICT  2
X
X/* Picture Flags */
X
X#define NO_RAM_GENERATE 0x00000001
X#define LENS_DISPLAYED  0x00000002
X#define ZOOM_BOX_OPEN   0x00000004
X#define SCROLL_HAPPENED 0x00000008
X#define PROJECT_CHANGED 0x00000010
X#define BORDERLESS_PROJ 0x00000020
X
X#define GENPENDSTATE    1
X#define CONTINUESTATE   2
X#define GENERATESTATE   3
X#define PAUSESTATE      4
X#define FINISHEDSTATE   5
X#define KILLSTATE       6
X
X#define RECOLORINCOMPLETE 0
X#define RECOLORCOMPLETE   1
X
X#define GENINCOMPLETE 0
X#define GENCOMPLETE   1
X#define NOSIGSTATE    2
X
X#define INT1632MATH 0
X#define FFPMATH     1
X#define IEEEMATH    2
X#define INT3232MATH 3
X#define M68881MATH  4
X
X#define INTORBMATH  0
X#define FFPORBMATH  1
X#define IEEEORBMATH 2
X
X/***************************************************************************
X *
X *  External variables
X *
X **************************************************************************/
X
X/* These are global system variables */
X
Xextern struct Picture *CurPict;
X
Xextern int CurContour;
Xextern SHORT  NumContours;
X
Xextern LONG   TopMarg, BotMarg, LeftMarg, RightMarg;
X
Xextern struct Screen *screen;
Xextern struct ViewPort *vp;
Xextern int Num_vp_Colors;
X
Xextern struct Window *PalWind, *ContWind, *StatsWind, *HelpWind;
Xextern struct Window *HistWind,*CycWind, *OrbitWind;
Xextern struct Window *CurWind, *CurPlot, *ClosedWind, *BackWind;
X
Xextern struct Menu Menu[];
X
Xextern SHORT  XScale, YScale;
Xextern SHORT  MouseX, MouseY;
X
Xextern LONG CurPen;
X
Xextern UBYTE  ClosePlot;
Xextern UBYTE  QuitScreen;
X
Xextern LONG   mSigBit,mSigMask;
Xextern struct Task *mTask;
X
Xextern BYTE FromWB;
X
Xextern BYTE State, SubState, Parse_rc;
X
Xstruct Window *OpenMyWind();
X
Xstruct Gadget *MakeBool(), *MakePot(), *MakeString();
Xstruct IntuiText *MakeIntui(), *ShadowIntui();
Xstruct Border *ShadowBorder();
X
X#define AddSemaphore myAddSemaphore
X
X/*
X * Picture window ( Julia and Mandlebrot windows ) margins
X */
X
X#define TOPMARG   TopMarg
X#define BOTMARG   BotMarg
X#define LEFTMARG  LeftMarg
X#define RIGHTMARG RightMarg
X
X#define SUCCESSFUL   0
X#define UNSUCCESSFUL -1
X
X#define ChildPause(Pict) {if(Pict->GenState==PAUSESTATE)ChildSignal(Pict);}
X
X/**************************************************************************
X *
X * Histogram stuff
X *
X *************************************************************************/
X
Xstruct Histogram {
X  int *Table;
X  int  TableSize;
X};
X
X#define AllocHistStruct() (struct Histogram *)safeAllocMem(sizeof(struct Histogram), MEMF_CLEAR)
X#define FreeHistStruct(p) FreeMem(p,sizeof(struct Histogram))
X
X#define AllocHistTable(s) (int *)safeAllocMem(s*sizeof(int), MEMF_CLEAR)
X#define FreeHistTable(p)  FreeMem(p->Table,p->TableSize*sizeof(int))
X
X#define AddHead(List,Node) safeAddHead(List,Node,__FILE__,__LINE__,__FUNC__)
X#define Remove(Node)       safeRemove(Node,__FILE__,__LINE__,__FUNC__)
X
X/**************************************************************************
X *
X * standard stuff
X *
X *************************************************************************/
X
X#define BEVELEDUP    0
X#define BEVELEDDOWN  1
X
X#define NORMALPEN    1
X#define SHADOWPEN    3
X#define MEDIUMPEN    2
X#define HIGHLIGHTPEN 2
X#define POTPEN       3
X
X#ifdef MEM_DEBUG
X
X#include "safeallocmem.h"
X
X#else
X
XAPTR safeAllocMem();
X
X#endif
X
SHAR_EOF
echo "End of archive 5 (of 9)"
# if you want to concatenate archives, remove anything after this line
exit