page%swap@Sun.COM (Bob Page) (05/17/89)
Submitted-by: u211344@hnykun11.bitnet (Olaf 'Rhialto' Seibert)
Posting-number: Volume 89, Issue 144
Archive-name: graphics/mandel180.3
# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
# Main.c
# Makefile
# Mandel.h
# Menu.c
# MinRexx.c
# Misc.c
# This is archive 3 of a 4-part kit.
# This archive created: Wed May 17 20:45:13 1989
echo "extracting Main.c"
sed 's/^X//' << \SHAR_EOF > Main.c
X/*
X * M A N D E L B R O T C O N S T R U C T I O N S E T
X *
X * (C) Copyright 1989 by Olaf Seibert.
X * Mandel may be freely distributed. See file 'doc/Notice' for details.
X *
X * Main Loop, and a lot of Variables.
X */
X
X#include <exec/types.h>
X#include <intuition/intuition.h>
X#ifdef DEBUG
X# include <stdio.h>
X# undef STATIC
X# define STATIC /* EMPTY */
X#endif
X
X#include "mandel.h"
X
Xextern int Enable_Abort;
X
Xstruct IntuitionBase *IntuitionBase;
Xstruct GfxBase *GfxBase;
Xstruct LayersBase *LayersBase;
X
Xstruct TextAttr Topaz80 = {
X (STRPTR) "topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT
X};
X
Xstruct TextAttr Topaz60 = {
X (STRPTR) "topaz.font", TOPAZ_SIXTY, FS_NORMAL, FPF_ROMFONT
X};
X
Xstruct NewScreen MandelNScreen =
X{
X 0, 0, 320, 256, /* LeftEdge, TopEdge, Width, Height */
X 4, /* Depth */
X 2, 1, /* DetailPen, BlockPen */
X NULL, /* viewmode LORES */
X CUSTOMSCREEN, /* type */
X &Topaz80, /* Font (default) */
X#ifdef IEEEDP
X (UBYTE *) "DP Mandelbrot Construction Set 1.3"
X#else
X (UBYTE *) "FFP Mandelbrot Construction Set 1.3"
X#endif
X};
X
Xstruct NewWindow MainNWindow =
X{
X 0, 0, 0, 0, /* LeftEdge, TopEdge, Width, Height */
X 2, 1, /* DetailPen, BlockPen */
X CLOSEWINDOW | MENUPICK | MOUSEBUTTONS | VANILLAKEY |
X SIZEVERIFY /* | MENUVERIFY */ ,
X WINDOWCLOSE | ACTIVATE | WINDOWSIZING | WINDOWDRAG |
X WINDOWDEPTH | NOCAREREFRESH | SMART_REFRESH | GIMMEZEROZERO,
X NULL, /* FirstGadget */
X NULL, /* default CheckMark */
X (UBYTE *) "Mandelbrot Construction Window", /* Title */
X NULL, /* Screen */
X NULL, /* BitMap */
X 60, 25, /* MinWidth, MinHeight */
X -1, -1, /* MaxWidth, MaxHeight */
X CUSTOMSCREEN /* Screen type */
X};
X
Xstruct BorderInfo borderinfo;
X
Xstruct IntuiText PositiveText = {
X AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X AUTOLEFTEDGE, AUTOTOPEDGE, NULL, (UBYTE *) "Continue", NULL
X},
X
X NegativeText = {
X AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X AUTOLEFTEDGE, AUTOTOPEDGE, &Topaz60, (UBYTE *) "Cancel", NULL
X};
X
XSTATIC SHORT XY1[] = {0, 0, 0, 13, 78, 13, 78, 0, 0, 0};
XSTATIC SHORT XY2[] = {0, 0, 0, 17, 82, 17, 82, 0, 0, 0};
XSTATIC struct Border border[] = {
X {0, 0, 2, 0, JAM1, 5, XY1, &border[1]},
X {-2, -2, 3, 0, JAM1, 5, XY2, NULL}
X};
Xstruct Gadget NegativeGadget = {
X NULL, -100, -20, 79, 14, /* next, LTWH */
X GADGHCOMP | GRELBOTTOM | GRELRIGHT,
X RELVERIFY | ENDGADGET,
X BOOLGADGET | REQGADGET,
X (APTR) & border[0], NULL,
X &NegativeText, 0, NULL,
X NEGGADGETID, NULL
X};
Xstruct Gadget PositiveGadget = {
X &NegativeGadget, 20, -20, 79, 14, /* next, LTWH */
X GADGHCOMP | GRELBOTTOM,
X RELVERIFY | ENDGADGET,
X BOOLGADGET | REQGADGET,
X (APTR) & border[0], NULL,
X &PositiveText, 0, NULL,
X POSGADGETID, NULL
X};
X
XUBYTE PenTable[MAXDEPTH];
Xunsigned PenTableMode = MODULO;
Xshort RangeWidth = 2;
X
Xstruct Screen *MandelScreen = NULL; /* Pointer for OpenScreen return
X * value */
Xstruct Window *MainWindow = NULL; /* Idem for OpenWindow */
Xstruct Window *XYwindow; /* The X/Y window */
Xextern struct Window *ColorWindow; /* Palette */
X
X
XUSHORT WBWidth = 0; /* Preferred size of our screen */
XUSHORT WBHeight = 0; /* in Hires/noninterlace values */
X
Xint (*DepthFunc) () = ZQuadMinC;
XUBYTE FunctionNr = 0;
X
Xvoid (*IPlotFunc) () = None;
XUBYTE IPlotNr = 0;
X
Xvoid (*EPlotFunc) () = PlotIterationCount;
XUBYTE EPlotNr = 0;
X
Xdouble LeftEdge = -0.800, /* Left edge of the picture */
X RightEdge = 2.100,
X TopEdge = 1.200,
X BottomEdge = -1.200;
X
Xdouble CXStep, /* Stepsize through the complex plane */
X CYStep;
Xint PixelStep = 1, /* Stepsize on the screen */
X MaxDepth = 100; /* Maximum iteration count */
X
Xint NumColors; /* Number of colors on the screen */
X
Xunsigned short FrameX1,
X FrameX2,
X FrameY1,
X FrameY2;
X
Xshort MouseStatus = NOTFRAMING; /* Where we are in the
X * process of selecting a
X * frame */
X
Xbool finished = FALSE; /* TRUE to stop the program */
Xbool Saved = TRUE; /* Indicates the picture has been SAVEd */
Xbool NameValid = FALSE; /* Indicates the file name is
X * valid */
Xbool StillDrawing = FALSE; /* Are we still drawing ? */
X
XFILE *BatchFILE; /* Current batch file */
Xint DrawSigBit = -1;/* Signal when drawing is finished */
Xlong DrawSigMask;
X
X#ifdef AREXX
X
X/*
X * And here is some AREXX stuff. Not very complicated, thanks to
X * MinRexx by Tomas Rokicki (Radical Eye Software).
X */
X
Xlong RexxMask; /* Wait signal mask */
Xextern short BatchWaiting; /* Halting all Arexx traffic as well */
X
X#endif
X
X/*
X * M A I N E N T R Y P O I N T
X */
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X char *Main();
X extern struct SignalSemaphore DrawSemaphore;
X
X /*
X * Before we do anything, do an operation which requires the floating
X * point library. So if it is not available, we abort before we need
X * to clean up anything. Note that CXStep is not initialized at this
X * moment.
X */
X
X CXStep = 1.0;
X CXStep = CXStep * 2.0;
X
X /*
X * Make sure we aren't interrupted by any user pressing ^C while we
X * are doing I/O.
X */
X Enable_Abort = 0;
X
X /*
X * Open each of the libraries and check for a NULL return, which
X * indicates unavailability.
X */
X
X IntuitionBase = (struct IntuitionBase *)
X OpenLibrary("intuition.library", LIBRARY_VERSION);
X if (IntuitionBase == NULL)
X MyExit("Can't open Intuition V1.2 or newer!");
X
X GfxBase = (struct GfxBase *)
X OpenLibrary("graphics.library", LIBRARY_VERSION);
X if (GfxBase == NULL)
X MyExit("Can't open Gfx V1.2 or newer!");
X
X LayersBase = (struct LayersBase *)
X OpenLibrary("layers.library", LIBRARY_VERSION);
X if (LayersBase == NULL)
X MyExit("Can't open Layers V1.2 or newer!");
X
X DrawSigBit = AllocSignal(-1L);
X if (DrawSigBit == -1)
X MyExit("Can't allocate signal!");
X DrawSigMask = 1L << DrawSigBit;
X InitSemaphore(&DrawSemaphore);
X MandelTask = FindTask(NULL);
X
X#ifdef AREXX
X/*
X * For rexx, we open up a Rexx port, and Batch() will send out
X * the first command, if there was one.
X */
X RexxMask = upRexxPort("MANDEL", NULL, "mand", NULL) ;
X#endif
X if (InitDisplay((bool) FALSE))
X MyExit("Can't initialise the display properly!");
X
X CalcCSteps();
X Options(argc, argv); /* Maybe open the batch */
X Batch(); /* Check the batch */
X
X MyExit(Main());
X}
X
Xchar *
XMain()
X{
X register ULONG Class; /* IntuiMessage class */
X register USHORT Code; /* and Code field */
X struct IntuiMessage *message; /* Expected message pointer */
X struct Window *window; /* window related to message */
X long signalmask;
X long signals;
X
X#ifdef AREXX
X/*
X * If we're working with Rexx, we wait on the Rexx bit as well.
X * Then, we handle any Rexx messages.
X */
X signalmask = RexxMask | DrawSigMask |
X (1L << MainWindow->UserPort->mp_SigBit);
X#else
X signalmask = DrawSigMask | (1L << MainWindow->UserPort->mp_SigBit);
X#endif
X
Xagain:
X finished = FALSE;
X while (!finished) {
X /*
X * Wait for message port to become not empty, and extract the
X * message or, alternatively, for the drawing to finish.
X */
X
X signals = Wait(signalmask);
X#ifdef AREXX
X if ((signals & RexxMask) && !BatchWaiting) {
X dispRexxPort();
X }
X#endif
X if (signals & DrawSigMask) { /* drawing finished */
X Batch(); /* Check the batch */
X#ifdef AREXX
X Signal(MandelTask, RexxMask);/* Wake up Arexx as well */
X#endif
X }
X while (message = (struct IntuiMessage *)
X GetMsg(MainWindow->UserPort)) {
X window = message->IDCMPWindow;
X
X if (window == ColorWindow) {
X HandleColorWindow(message);
X continue;
X }
X
X Class = message->Class;
X Code = message->Code;
X
X if (Class & ~(MOUSEBUTTONS | INTUITICKS)) {
X ReplyMsg(message); /* Pointer is not valid anymore */
X }
X switch (Class) {
X case MENUPICK:
X GotMenu(Code);
X break;
X case MOUSEBUTTONS:
X case INTUITICKS:
X CheckMouse(message);
X ReplyMsg(message);
X break;
X case SIZEVERIFY:
X StopFraming(); /* Fall Through to MenuVerify */
X case MENUVERIFY:
X break; /* Just make sure there is no half-drawn
X * frame */
X case CLOSEWINDOW:
X if (window == MainWindow) {
X finished = TRUE;
X } else {
X CloseXYwindow();
X }
X break;
X case VANILLAKEY:
X if (Code == ('Q' & 0x1F)) { /* Ctrl-Q; don't check to
X * be sure */
X skipto finished;
X }
X break;
X /* default: Ignore strange messages */
X } /* End Switch The Class Of The Message */
X } /* End While There Is A Message */
X } /* End While Not Finished */
X
X /*
X * So we are finished. And, by the way, are we SURE we are finished
X * alltogether ??
X */
X
X if (!Sure()) {
X backto again;
X }
Xfinished:
X CleanupDisplay((bool) TRUE);
X return NULL; /* Indicate Good Exit */
X} /* End of Main */
SHAR_EOF
echo "extracting Makefile"
sed 's/^X//' << \SHAR_EOF > Makefile
X#
X# Makefile for the Mandelbrot Construction Set by Olaf Seibert, KosmoSoft
X#
X
XSPOBJ = Main.o Misc.o GotMenu.o Batch.o \
X Palette.o Draw.o
XDPOBJ = Main.odp Misc.odp GotMenu.odp Batch.odp \
X Palette.odp Draw.odp
XINTOBJ = Display.o Select.o GetFile.o Jiff.o Menu.o Rev.o
XREXXOBJ = MinRexx.o RexxBind.o
XHEADERS = Mandel.h
XLIBS = -lm -lc
XDPLIBS = -lma -lc
XDUMP = ii
XCFLAGS = +I$(DUMP) +x3,5 -DAREXX
XCC = cc
X
X.SUFFIXES:
X
X.SUFFIXES: .odp .o .asm .c .req
X
X.c.odp:
X $(CC) $(CFLAGS) +fi -DIEEEDP $< -o $@
X
X.c.o:
X $(CC) $(CFLAGS) $< -o $@
X
X.c.asm:
X $(CC) $(CFLAGS) -at $< -o $@
X
XDebug: $(SPOBJ) $(INTOBJ) $(REXXOBJ) $(DUMP)
X air
X ln -o Debug -w $(INTOBJ) $(REXXOBJ) $(SPOBJ) $(LIBS)
X
XMandel: $(SPOBJ) $(INTOBJ) $(DUMP)
X air
X ln -o Mandel $(INTOBJ) $(REXXOBJ) $(SPOBJ) $(LIBS)
X
XMandel-dp: $(DPOBJ) $(INTOBJ) $(DUMP)
X# No IncRev so the number is the same as the FFP version
X ln -o Mandel-dp $(INTOBJ) $(REXXOBJ) $(DPOBJ) $(DPLIBS)
X
Xall: Mandel Mandel-dp
X
X$(INTOBJ): $(HEADERS)
X$(SPOBJ): $(HEADERS)
X$(DPOBJ): $(HEADERS)
X
XSelect.o: Select.req
X
XSelect.req: Select.blk
X blk -d $? $@
X
XMinRexx.o: MinRexx.h
X
X$(DUMP): dummy.c
X cc -a +H$(DUMP) dummy.c -o nil:
SHAR_EOF
echo "extracting Mandel.h"
sed 's/^X//' << \SHAR_EOF > Mandel.h
X/*
X * :ts=8 Common DEFINEs and external declarations for the Mandelbrot
X * Construction Set...
X */
X
X#undef LIBRARY_VERSION
X#define LIBRARY_VERSION 33L /* V1.2 */
X
X
X#define MYFRONTPEN 2 /* Black */
X
X/* Menus */
X#define CPRMENU 0 /* Copyright Menu */
X#define PRJMENU 1 /* Poject Menu */
X#define OPTMENU 2 /* Option Menu */
X#define DRWMENU 3 /* Draw functions Menu */
X#define BATMENU 4 /* Batch Menu */
X
X/* Menu items */
X#define PRJNEW 0 /* Project Menu: New */
X#define PRJOPN 1 /* Open */
X#define PRJSVE 2 /* Save */
X#define PRJSVA 3 /* Save As */
X#define PRJSTP 4 /* Stop */
X#define PRJQUI 5 /* Quit */
X
X#define PNABS 0 /* Project New: Absolute */
X#define PNENL 1 /* Enlarge */
X#define PNRED 2 /* Reduce */
X#define PNSHF 3 /* Shift */
X#define PNZI 4 /* Zoom In */
X#define PNZO 5 /* Zoom Out */
X
X#define OPTCOL 0 /* Option Menu: Colors */
X#define OPTRES 1 /* Resolution */
X#define OPTPAR 2 /* Parameters */
X#define OPTPRI 3 /* Priority */
X
X#define OCSEL 0 /* Opt Color: Select */
X#define OCMOD 1 /* Modulo */
X#define OCRAN 2 /* Ranges */
X#define OCPAL 3 /* Palette */
X
X#define ORNRM 0 /* Opt Resl: Normal */
X#define OR12 1 /* 1/2 */
X#define OR13 2 /* 1/3 */
X#define OR14 3 /* 1/4 */
X#define ORFIL 4 /* Fill In */
X#define ORHI 5 /* HiRes */
X#define ORILC 6 /* Interlace */
X#define ORBCK 7 /* Borderless */
X#define OREHB 8 /* Extra Half Brite */
X
X#define OPNOR 0 /* Normal priority */
X#define OPLOW 1 /* Low priority */
X
X#define DRWFUN 0 /* Draw functions */
X#define DRWIPL 1 /* - Iteration plot */
X#define DRWEPL 2 /* - End plot */
X
X#define DF1 0 /* Functions Menu: Z^2-C */
X#define DF2 1 /* ZC1MinZ */
X#define DF3 2 /* Z3PlusZCMin1MinC */
X#define DFUPF 3 /* Not on the menu for now */
X#define DF5 4 /* i:Z^2 - C */
X
X#define DINONE 0 /* draw iplot none */
X#define DIZ 1 /* iplot Z */
X
X#define DEDEPTH 0 /* draw eplot depth */
X#define DEZ 1 /* eplot Z */
X
X#define BATFILE 0 /* Batch Menu: File... */
X#define BATWAIT 1 /* Wait */
X#define BATCONT 2 /* Continue */
X#define BATABORT 3 /* Abort */
X
X
X#define POSGADGETID 10 /* For Positive Gadget */
X#define NEGGADGETID 11 /* For Negative Gadget */
X
X#define FNAME_SIZE 32L /* Filename size */
X#define DNAME_SIZE 66L /* Directoryname size */
X
X#define MAXDEPTH 512 /* Maximum maximum depth */
X#define BMDEPTH 5 /* Depth of our bitmap */
X#define MAXCOL (1<<BMDEPTH) /* Maximum number of colors */
X
X#define NOTFRAMING 0 /* We are not framing */
X#define NOPOINT 1 /* We have no points of a frame */
X#define POINT1 2 /* We have 1 point of a frame */
X#define CENTERFRAMING 3 /* We have a center and are busy with a
X * corner */
X#define FLASHING 4 /* We are still flashing the frame */
X
X#define MODULO 0 /* Pen assignment to the depths */
X#define RANGES 1
X#define SELECT 2
X
X#define MAND ((ULONG)'M'<<24 | (ULONG)'A'<<16 | 'N'<<8 | 'D')
X
X#define MINSCREENHEIGHT 150 /* Minimum required screen sizes */
X#define MINSCREENWIDTH 320
X
X/* Let's try to make `goto' a little more structured... :-) */
X
X#define skipto goto
X#define backto goto
X
X#define OFFSETOF(member, structure) ((long) &((struct structure *)0)->member)
X
X/* Type definitions */
X
Xtypedef short bool;
X
Xstruct BitMapHeader {
X UWORD w,
X h;
X UWORD x,
X y;
X UBYTE nPlanes;
X UBYTE masking;
X UBYTE compression;
X UBYTE pad1;
X UWORD transparentColor;
X UBYTE xAspect,
X yAspect;
X WORD pageWidth,
X pageHeight;
X};
X
X/*
X * ILBM_info is the structure read_iff returns, and is hopefully all you
X * need to deal with out of the iff reader routines below
X */
Xstruct ILBM_info {
X struct BitMapHeader header;
X UBYTE cmap[MAXCOL * 3];
X struct BitMap bitmap;
X struct Mand *mand;
X long mandsize;
X};
X
Xstruct Mand {
X ULONG MandID; /* 'MAND' */
X LONG Size; /* sizeof(struct Mand) */
X WORD MaxDepth; /* Maximum iteration count */
X WORD RangeWidth;
X BYTE RainDist; /* From the palette Rainbow mode */
X BYTE RainRMax; /* From the palette Rainbow mode */
X BYTE RainGMax; /* From the palette Rainbow mode */
X BYTE RainBMax; /* From the palette Rainbow mode */
X BYTE Coords[4 * 18]; /* Ascii representation */
X BYTE FunctionNr; /* Which function was used (1...4) */
X BYTE PenTableMode; /* MODULO, RANGES, SELECT */
X USHORT WBWidth;
X USHORT WBHeight;
X};
X
Xstruct BorderInfo {
X BYTE SizeX,
X SizeY;
X BYTE MoveX,
X MoveY;
X};
X
X/* Some definitions for the User Programmed Functions */
X
Xstruct Program {
X char pr_OpCode;
X char pr_Dest;
X char pr_Op1;
X char pr_Op2;
X long pr__Reserved;
X};
X
Xenum Opcode {
X End, Rassign, Cassign, Ri, Ci, Rplus, Cplus, Rminus, Cminus,
X Rtimes, Ctimes,
X};
X
X#define PROGRAMSIZE 64
X#define PROGRAMREGS 16
X
Xextern struct Program Program[PROGRAMSIZE];
Xextern double PrgReg[2 * PROGRAMREGS];
X
X#define RE(x) (x) /* These RE and IM cannot */
X#define IM(x) ((x) + PROGRAMREGS) /* be exchanged! */
X
X/* Some Other Macros */
X
X#define MENU(menu,item,subitem)\
X (LONG)(SHIFTMENU(menu)|SHIFTITEM(item)|SHIFTSUB(subitem))
X
X/* External declarations */
X
X#include <functions.h>
Xextern long GetScreenData();
X
X/*
X * extern struct Screen *OpenScreen(); extern struct Window *OpenWindow();
X * extern struct IntuiMessage *GetMsg(); extern struct Library
X * *OpenLibrary(); extern struct MenuItem *ItemAddress(); extern long
X * AutoRequest(), DisplayAlert(), Request(), MoveLayer(), SizeLayer();
X * extern void SetAPen(), WritePixel(), WindowLimits(), EndRequest();
X * extern struct Task *FindTask(); extern long Wait();
X */
X
X
X/* Forward POINTER declarations */
X
Xextern struct Screen *MandelScreen;
Xextern struct Window *MainWindow;
Xextern struct IntuiMessage *message;
Xextern int (*DepthFunc) ();
Xextern void (*IPlotFunc) ();
Xextern void (*EPlotFunc) ();
Xextern struct IntuitionBase *IntuitionBase;
Xextern struct LayersBase *LayersBase;
Xextern struct GfxBase *GfxBase;
Xextern FILE *BatchFILE;
Xextern struct Task *MandelTask,
X *DrawTask;
X
X
X/* Forward STRUCT declarations */
X
Xextern struct Menu MandelMenu[];
Xextern struct NewScreen MandelNScreen;
Xextern struct NewWindow MainNWindow;
Xextern struct TextAttr Topaz60,
X Topaz80;
Xextern struct IntuiText PositiveText,
X NegativeText;
Xextern struct Gadget PositiveGadget,
X NegativeGadget;
Xextern struct BorderInfo borderinfo;
X
X
X/* Forward ARRAY declarations */
X
Xextern TEXT FileName[FNAME_SIZE + 1];
Xextern TEXT DirName[DNAME_SIZE + 2];
X
X
X/* Forward `SIMPLE' declarations */
X
Xextern int NumColors,
X MaxDepth,
X PixelStep,
X RangeWidth;
Xextern int DrawPri;
Xextern unsigned PenTableMode;
Xextern unsigned short FrameX1,
X FrameX2,
X FrameY1,
X FrameY2;
Xextern short MouseStatus;
Xextern bool finished,
X StillDrawing,
X Saved,
X NameValid;
Xextern double LeftEdge,
X RightEdge,
X TopEdge,
X BottomEdge,
X CXStep,
X CYStep;
Xextern UBYTE PenTable[MAXDEPTH];
Xextern UBYTE FunctionNr;
X
Xextern SHORT RainbowDistance,
X RainbowRMax,
X RainbowGMax,
X RainbowBMax;
Xextern long DrawSigMask;
Xextern int DrawSigBit;
Xextern USHORT WBWidth,
X WBHeight;
X
X
X/* Forward FUNCTION declarations */
X
Xextern bool InitDisplay();
Xextern bool ReInitDisplay();
Xextern bool Sure();
Xextern bool CleanupDisplay();
Xextern bool InterpretMAND();
Xextern bool DoBorderless();
Xextern bool DrawPicture();
Xextern bool OpenAs();
Xextern bool SaveAs();
Xextern bool OpenBatch();
X
Xextern int WaitMyRequest();
Xextern int write_iff();
Xextern int ZQuadMinC();
Xextern int ZC1MinZ();
Xextern int Z3PlusZCMin1MinC();
Xextern int UserProgFunc();
Xextern int I_ZQuadMinC();
X
Xextern float Ratio();
Xextern char *get_fname();
Xextern char *index();
Xextern struct ILBM_info *win_read_iff();
Xextern struct Window *MyRequest();
X
Xextern void MyExit();
Xextern void GotMenu();
Xextern void UndoBorderless();
Xextern void CprMenu();
Xextern void PrjMenu();
Xextern void EdtMenu();
Xextern void OptMenu();
Xextern void DrwMenu();
Xextern void BatchMenu();
Xextern void UnImpl();
Xextern void EndMyRequest();
Xextern void CloseWindowSafely();
Xextern void get_ea_cmap();
Xextern void put_ea_cmap();
Xextern void free_planes();
Xextern void RectDraw();
Xextern void CrossDraw();
Xextern void CheckMouse();
Xextern void InitPenTable();
Xextern void StopFraming();
Xextern void EnableSystemGadgets();
Xextern void DisableSystemGadgets();
Xextern void Parameters();
Xextern void Palette();
Xextern void MakeMAND();
Xextern void StopDrawing();
Xextern void CalcCSteps();
Xextern void None();
Xextern void PlotZ();
Xextern void PlotIterationCount();
Xextern void SelectMenu();
Xextern void SuspendDrawing();
Xextern void ResumeDrawing();
Xextern void UpdateCheckmarks();
Xextern void UpdateDrwFunCm();
Xextern void UpdateDrwIplotCm();
Xextern void UpdateDrwEplotCm();
Xextern void UpdateOptColorCm();
Xextern void UpdateOptDrawResCm();
Xextern void UpdateOptViewResCm();
Xextern void UpdateOptPriCm();
Xextern void CloseBatch();
X
X#ifdef AREXX
X/*
X * This is the list of functions we can access. (Cheap forward
X * declarations, too.)
X */
Xextern long upRexxPort() ;
Xextern void dnRexxPort() ;
Xextern void dispRexxPort() ;
Xextern struct RexxMsg *sendRexxCmd() ;
Xextern struct RexxMsg *syncRexxCmd() ;
Xextern struct RexxMsg *asyncRexxCmd() ;
Xextern void replyRexxCmd() ;
X
Xextern long RexxMask;
X#endif
X
SHAR_EOF
echo "extracting Menu.c"
sed 's/^X//' << \SHAR_EOF > Menu.c
X/*
X * M A N D E L B R O T C O N S T R U C T I O N S E T
X *
X * (C) Copyright 1989 by Olaf Seibert.
X * Mandel may be freely distributed. See file 'doc/Notice' for details.
X *
X * Menu definitions.
X */
X
X#include <exec/types.h>
X#include <intuition/intuition.h>
X
X#define MENUFRONTPEN 2
X
X/*-
X * (C) project options draw batch
X * ----------------------------------------------------------------
X * About Mandel... new * colors * function file...
X * open... /O resolution * iplot wait
X * save /S parameters eplot continue
X * save as... priority * abort
X * stop
X * quit /Q
X *
X * new colors resolution priority
X * -------------------------------------------------------------
X * absolute pos'n /A select normal /1 normal /0
X * enlarge /E modulo 1/2 /2 low /-
X * reduce /R ranges 1/3 /3
X * shift /T palette /P 1/4 /4
X * zoom in /< fill in /F
X * zoom out /> hi-res /H
X * interlace /I
X * borderless /B
X * halfbrite //
X *
X * functions iplot eplot
X * -------------------------------------------------------------------
X * z^2-c None Depth
X * z*c*(1-z) Z Z
X * z^3+z*(c-1)-c
X * i:user
X * i:z^2-c
X */
X
X/*
X * Define some handy shortcuts.
X */
X
X#define ITEXT(left,text) \
X { MENUFRONTPEN,AUTOBACKPEN,JAM1,left,1,NULL, (UBYTE*)text, NULL }
X
X#define ITEM(num,top,next,text,flags,mutex,cmd) \
X SITEM(num,top,next,text,flags,mutex,cmd,NULL)
X
X#define SITEM(num,top,next,text,flags,mutex,cmd,sub) \
X {next,MLEFT,top,MWIDTH,10,flags,mutex,(APTR)&text[num],NULL,cmd,sub}
X
X#define Ax COMMSEQ
X#define Vx CHECKIT
X#define VV CHECKIT | CHECKED
X#define TG MENUTOGGLE
X#define EN ITEMENABLED
X
X#define DEFMLEFT 40
X
X/*
X * First the menu texts.
X */
X
Xstruct IntuiText c_it[] = {
X ITEXT(1, "About Mandel..."),
X};
X
Xstruct IntuiText project_it[] = {
X ITEXT(1, "New \xBB"), /* 0xBB is the >> character */
X ITEXT(1, "Open..."),
X ITEXT(1, "Save"),
X ITEXT(1, "Save As..."),
X ITEXT(1, "Stop"),
X ITEXT(1, "Quit..."),
X};
X
Xstruct IntuiText opts_it[] = {
X ITEXT(1, "Colors \xBB"),
X ITEXT(1, "Resolution \xBB"),
X ITEXT(1, "Parameters"),
X ITEXT(1, "Priority \xBB"),
X};
X
Xstruct IntuiText draw_it[] = {
X ITEXT(1, "Func \xBB"),
X ITEXT(1, "IPlot \xBB"),
X ITEXT(1, "EPlot \xBB"),
X};
X
Xstruct IntuiText batch_it[] = {
X ITEXT(1, "File..."),
X ITEXT(1, "Wait"),
X ITEXT(1, "Continue"),
X ITEXT(1, "Abort"),
X};
X
Xstruct IntuiText new_it[] = {
X ITEXT(1, "Absolute"),
X ITEXT(1, "Enlarge"),
X ITEXT(1, "Reduce"),
X ITEXT(1, "Shift"),
X ITEXT(1, "Zoom In"),
X ITEXT(1, "Zoom Out"),
X};
X
Xstruct IntuiText color_it[] = {
X ITEXT(CHECKWIDTH, "Select"),
X ITEXT(CHECKWIDTH, "Modulo"),
X ITEXT(CHECKWIDTH, "Ranges"),
X ITEXT(CHECKWIDTH, "Palette"),
X};
X
Xstruct IntuiText pri_it[] = {
X ITEXT(CHECKWIDTH, "Normal"),
X ITEXT(CHECKWIDTH, "Low"),
X};
X
Xstruct IntuiText res_it[] = {
X ITEXT(CHECKWIDTH, "Normal"),
X ITEXT(CHECKWIDTH, "1/2"),
X ITEXT(CHECKWIDTH, "1/3"),
X ITEXT(CHECKWIDTH, "1/4"),
X ITEXT(CHECKWIDTH, "Fill In"),
X ITEXT(CHECKWIDTH, "Hires"),
X ITEXT(CHECKWIDTH, "Interlace"),
X ITEXT(CHECKWIDTH, "BorderLess"),
X ITEXT(CHECKWIDTH, "HalfBrite"),
X};
X
Xstruct IntuiText fun_it[] = {
X ITEXT(CHECKWIDTH, "Z^2-C"),
X ITEXT(CHECKWIDTH, "Z*C*(1-Z)"),
X ITEXT(CHECKWIDTH, "Z^3+Z*(C-1)-C"),
X ITEXT(CHECKWIDTH, "iplot: User"),
X ITEXT(CHECKWIDTH, "iplot: Z^2-C"),
X};
X
Xstruct IntuiText plot_it[] = {
X ITEXT(CHECKWIDTH, "None"),
X ITEXT(CHECKWIDTH, "Depth"),
X ITEXT(CHECKWIDTH, "Z"),
X};
X
X
X#define FLAGS ITEMTEXT | ITEMENABLED | HIGHBOX
X
X/*
X * New submenu
X */
X
X#define MLEFT DEFMLEFT
X#define MWIDTH 8*8+2+COMMWIDTH+8 /* Funny we need 2 more pixels */
X
Xstruct MenuItem new_mi[] = {
X ITEM(0,05,&new_mi[1],new_it,FLAGS|Ax,0,'A'), /* absolute */
X ITEM(1,15,&new_mi[2],new_it,FLAGS|Ax,0,'E'), /* enlarge */
X ITEM(2,25,&new_mi[3],new_it,FLAGS|Ax,0,'R'), /* reduce */
X ITEM(3,35,&new_mi[4],new_it,FLAGS|Ax,0,'T'), /* shift */
X ITEM(4,45,&new_mi[5],new_it,FLAGS|Ax,0,'<'), /* Zoom In */
X ITEM(5,55,NULL, new_it,FLAGS|Ax,0,'>'), /* Zoom Out */
X};
X
X/*
X * Colors submenu
X */
X
X#undef MWIDTH
X#define MWIDTH CHECKWIDTH+7*8+COMMWIDTH+8
X
Xstruct MenuItem color_mi[] = {
X ITEM(0,05,&color_mi[1],color_it,FLAGS|Vx,1<<1|1<<2,0), /* select */
X ITEM(1,15,&color_mi[2],color_it,FLAGS|VV,1<<0|1<<2,0), /* modulo */
X ITEM(2,25,&color_mi[3],color_it,FLAGS|Vx,1<<0|1<<1,0), /* ranges */
X ITEM(3,35,NULL ,color_it,FLAGS|Ax,0, 'P'), /* palette */
X};
X
X#undef MWIDTH
X#define MWIDTH CHECKWIDTH+10*8+COMMWIDTH+8
X
Xstruct MenuItem res_mi[] = {
X ITEM(0,05,&res_mi[1],res_it,FLAGS|Ax|VV,1<<1|1<<2|1<<3,'1'), /* normal */
X ITEM(1,15,&res_mi[2],res_it,FLAGS|Ax|Vx,1<<0|1<<2|1<<3,'2'), /* 1/2 */
X ITEM(2,25,&res_mi[3],res_it,FLAGS|Ax|Vx,1<<0|1<<1|1<<3,'3'), /* 1/3 */
X ITEM(3,35,&res_mi[4],res_it,FLAGS|Ax|Vx,1<<0|1<<1|1<<2,'4'), /* 1/4 */
X ITEM(4,45,&res_mi[5],res_it,FLAGS|Ax ,0 ,'F'), /* fill in */
X
X ITEM(5,60,&res_mi[6],res_it,FLAGS|Ax|Vx|TG,1<<8,'H'), /* hi-res */
X ITEM(6,70,&res_mi[7],res_it,FLAGS|Ax|Vx|TG,0 ,'I'), /* interlace */
X ITEM(7,80,&res_mi[8],res_it,FLAGS|Ax|Vx|TG,0 ,'B'), /* borderless */
X ITEM(8,90,NULL ,res_it,FLAGS|Ax|Vx|TG,1<<4,'/'), /* extra halfbrite */
X};
X
X#undef MWIDTH
X#define MWIDTH CHECKWIDTH+6*8+COMMWIDTH+8
X
Xstruct MenuItem pri_mi[] = {
X ITEM(0,05,&pri_mi[1],pri_it,FLAGS|Ax|VV,1<<1,'0'), /* normal */
X ITEM(1,15,NULL ,pri_it,FLAGS|Ax|Vx,1<<0,'-'), /* low */
X};
X
X/*
X * Functions submenu:
X */
X
X#undef MWIDTH
X#define MWIDTH CHECKWIDTH+104
X#undef MLEFT
X#define MLEFT DEFMLEFT - 8
X
Xstruct MenuItem fun_mi[] = {
X ITEM(0,05,&fun_mi[1],fun_it,FLAGS|VV,0x1F- 1,0), /* Z^2 - C */
X ITEM(1,15,&fun_mi[2],fun_it,FLAGS|Vx,0x1F- 2,0), /* z*c*(1-z) */
X ITEM(2,25,&fun_mi[3],fun_it,FLAGS|Vx,0x1F- 4,0), /* z^3+z*(c-1)-c */
X ITEM(3,35,&fun_mi[4],fun_it,FLAGS|Vx,0x1F- 8,0), /* i: User */
X ITEM(4,45,NULL ,fun_it,FLAGS|Vx,0x1F-16,0), /* i: Z^2 - C */
X};
X
X/*
X * iplot submenu
X */
X
X#undef MWIDTH
X#define MWIDTH CHECKWIDTH + (5*8)
X#undef MLEFT
X#define MLEFT DEFMLEFT
X
Xstruct MenuItem iplot_mi[] = {
X ITEM(0,05,&iplot_mi[1], plot_it, FLAGS|VV,1<<1,0), /* None */
X ITEM(1,15,NULL ,(plot_it+1),FLAGS|Vx,1<<0,0), /* Z */
X};
X
X/*
X * eplot submenu
X */
X
Xstruct MenuItem eplot_mi[] = {
X ITEM(0,05,&eplot_mi[1],(plot_it+1),FLAGS|VV,1<<1,0), /* Depth */
X ITEM(1,15,NULL ,(plot_it+1),FLAGS|Vx,1<<0,0), /* Z */
X};
X
X/*
X * (C) menu
X */
X
X#undef MLEFT
X#define MLEFT 0
X#undef MWIDTH
X#define MWIDTH 15*8
X
Xstruct MenuItem c_mi[] = {
X ITEM(0,00,NULL,c_it,FLAGS,0,0), /* About Mandel... */
X};
X
X/*
X * Project menu
X */
X
X#undef MWIDTH
X#define MWIDTH 9*8+COMMWIDTH
X
Xstruct MenuItem project_mi[] = {
X SITEM(0,00,&project_mi[1],project_it,FLAGS ,0,0,new_mi), /* new */
X ITEM(1,10,&project_mi[2],project_it,FLAGS|Ax,0,'O' ), /* open... */
X ITEM(2,20,&project_mi[3],project_it,FLAGS|Ax,0,'S' ), /* save */
X ITEM(3,30,&project_mi[4],project_it,FLAGS ,0,0 ), /* save as... */
X ITEM(4,45,&project_mi[5],project_it,FLAGS ,0,0 ), /* stop */
X ITEM(5,55,NULL ,project_it,FLAGS|Ax,0,'Q' ), /* quit */
X};
X
X/*
X * Options menu
X */
X
X#undef MWIDTH
X#define MWIDTH 12*8+2
X
Xstruct MenuItem opt_mi[] = {
X SITEM(0,00,&opt_mi[1],opts_it,FLAGS,0,0,color_mi), /* colors */
X SITEM(1,10,&opt_mi[2],opts_it,FLAGS,0,0,res_mi ), /* resolution */
X ITEM(2,20,&opt_mi[3],opts_it,FLAGS,0,0 ), /* parameters */
X SITEM(3,30,NULL ,opts_it,FLAGS,0,0,pri_mi ), /* priority */
X};
X
X
X/*
X * Draw Menu
X */
X
X#undef MWIDTH
X#define MWIDTH (7*8)
X#undef MLEFT
X#define MLEFT -MWIDTH+40
X
Xstruct MenuItem draw_mi[] = {
X SITEM(0,00,&draw_mi[1],draw_it,FLAGS,0,0,fun_mi ), /* func */
X SITEM(1,10,&draw_mi[2],draw_it,FLAGS,0,0,iplot_mi), /* iplot */
X SITEM(2,20,NULL ,draw_it,FLAGS,0,0,eplot_mi), /* eplot */
X};
X
X
X/*
X * Batch Menu
X */
X
X#undef MWIDTH
X#define MWIDTH (8*8)
X#undef MLEFT
X#define MLEFT -MWIDTH+43
X
Xstruct MenuItem batch_mi[] = {
X ITEM(0,00,&batch_mi[1],batch_it,FLAGS, 0,0), /* file */
X ITEM(1,10,&batch_mi[2],batch_it,(FLAGS)-EN,0,0), /* wait */
X ITEM(2,20,&batch_mi[3],batch_it,(FLAGS)-EN,0,0), /* continue */
X ITEM(3,30,NULL ,batch_it,(FLAGS)-EN,0,0), /* abort */
X};
X
X/*
X * Main MenuStrip structure
X */
X
Xstruct Menu MandelMenu[] = {
X { &MandelMenu[1], 2,0,21,10, MENUENABLED, " \xA9", c_mi },
X { &MandelMenu[2], 30,0,59,10, MENUENABLED, "Project", project_mi },
X { &MandelMenu[3], 100,0,59,10, MENUENABLED, "Options", opt_mi },
X { &MandelMenu[4], 170,0,37,10, MENUENABLED, "Draw", draw_mi },
X { NULL, 220,0,43,10, MENUENABLED, "Batch", batch_mi },
X};
SHAR_EOF
echo "extracting MinRexx.c"
sed 's/^X//' << \SHAR_EOF > MinRexx.c
X/*
X * This is an example of how REXX messages might be handled. This is
X * a `minimum' example that both accepts asynchronous REXX messages and
X * can request REXX service.
X *
X * Read this entire file! It's short enough.
X *
X * It is written in such a fashion that it can be attached to a program
X * with a minimum of fuss. The only external symbols it makes available
X * are the seven functions and RexxSysBase.
X *
X * This code is by Radical Eye Software, but it is put in the public
X * domain. I would appreciate it if the following string was left in
X * both as a version check and as thanks from you for the use of this
X * code.
X *
X * If you modify this file for your own use, don't bump the version
X * number; add a suffix, such as 1.0a or 1.0.3 or something, so we
X * don't have fake `versions' floating around.
X *
X * I [Olaf Seibert] changed it a bit for Mandel, that has its own
X * kind of association list and command dispatcher. And I adjusted some
X * comments to match the code.
X */
Xstatic char *blurb = "Radical Eye MinRexx 0.4 for Mandel" ;
X/*
X * We read in our own personal little include.
X */
X#include "minrexx.h"
X/*
X * All of our local globals, hidden from sight.
X */
Xstatic struct MsgPort *rexxPort ; /* this is *our* rexx port */
Xstatic int bringerdown ; /* are we trying to shut down? */
Xstatic struct rexxCommandList *globalrcl ; /* our command association list */
Xstatic long stillNeedReplies ; /* how many replies are pending? */
Xstatic long rexxPortBit ; /* what bit to wait on for Rexx? */
Xstatic char *extension ; /* the extension for macros */
Xstatic int (*userdisp)() ; /* the user's dispatch function */
Xstruct RexxMsg *oRexxMsg ; /* the outstanding Rexx message */
X/*
X * Our library base. Don't you dare close this!
X */
Xstruct RxsLib *RexxSysBase ;
X/*
X * This is the main entry point into this code.
X */
Xlong upRexxPort(s, rcl, exten, uf)
X/*
X * The first argument is the name of your port to be registered;
X * this will be used, for instance, with the `address' command of ARexx.
X */
Xchar *s ;
X/*
X * The second argument is an association list of command-name/user-data
X * pairs. It's an array of struct rexxCommandList, terminated by a
X * structure with a NULL in the name field. The commands are case
X * sensitive. The user-data field can contain anything appropriate,
X * perhaps a function to call or some other data.
X */
Xstruct rexxCommandList *rcl ;
X/*
X * The third argument is the file extension for ARexx macros invoked
X * by this program. If you supply this argument, any `primitive' not
X * in the association list rcl will be sent out to ARexx for
X * interpretation, thus allowing macro programs to work just like
X * primitives. If you do not want this behavior, supply a `NULL'
X * here, and those commands not understood will be replied with an
X * error value of RXERRORNOCMD.
X */
Xchar *exten ;
X/*
X * The fourth argument is the user dispatch function. This function
X * will *only* be called from dispRexxPort(), either from the user calling
X * this function directly, or from dnRexxPort(). Anytime a command
X * match is found in the association list, this user-supplied function
X * will be called with three arguments---the Rexx message that was
X * received, a pointer to the association pair, and a pointer to the
X * command string.
X * Note that the user function should never ReplyMsg() the message;
X * instead he should indicate the return values with replyRexxCmd();
X * otherwise we lose track of the messages that still lack replies.
X */
Xint (*uf)() ;
X/*
X * upRexxPort() returns the signal bit to wait on for Rexx messages.
X * If something goes wrong, it simply returns a `0'. Note that this
X * function is safe to call multiple times because we check to make
X * sure we haven't opened already. It's also a quick way to change
X * the association list or dispatch function.
X */
X{
X struct MsgPort *FindPort() ;
X struct MsgPort *CreatePort() ;
X
X/*
X * Some basic error checking.
X */
X /*
X if (rcl == NULL || uf == NULL)
X return(0L) ;
X */
X/*
X * If we aren't open, we make sure no one else has opened a port with
X * this name already. If that works, and the createport succeeds, we
X * fill rexxPortBit with the value to return.
X *
X * Note that rexxPortBit will be 0 iff rexxPort is NULL, so the check
X * for rexxPort == NULL also insures that our rexxPortBit is 0.
X */
X if (rexxPort == NULL) {
X Forbid() ;
X if (FindPort(s)==NULL)
X rexxPort = CreatePort(s, 0L) ;
X Permit() ;
X if (rexxPort != NULL)
X rexxPortBit = 1L << rexxPort->mp_SigBit ;
X }
X/*
X * Squirrel away these values for our own internal access, and return
X * the wait bit.
X */
X globalrcl = rcl ;
X extension = exten ;
X userdisp = uf ;
X return(rexxPortBit) ;
X}
X/*
X * This function closes the rexx library, but only if it is open
X * and we aren't expecting further replies from REXX. It's
X * *private*, but it doesn't have to be; it's pretty safe to
X * call anytime.
X */
Xstatic void closeRexxLib() {
X if (stillNeedReplies == 0 && RexxSysBase) {
X CloseLibrary(RexxSysBase) ;
X RexxSysBase = NULL ;
X }
X}
X/*
X * This function closes down the Rexx port. It is always safe to
X * call, and should *definitely* be made a part of your cleanup
X * routine. No arguments and no return. It removes the Rexx port,
X * replies to all of the messages and insures that we get replies
X * to all the ones we sent out, closes the Rexx library, deletes the
X * port, clears a few flags, and leaves.
X */
Xvoid dnRexxPort() {
X if (rexxPort) {
X RemPort(rexxPort) ;
X bringerdown = 1 ;
X/*
X * A message still hanging around? We kill it off.
X */
X if (oRexxMsg) {
X oRexxMsg->rm_Result1 = RXERRORIMGONE ;
X ReplyMsg(oRexxMsg) ;
X oRexxMsg = NULL ;
X }
X while (stillNeedReplies) {
X WaitPort(rexxPort) ;
X dispRexxPort() ;
X }
X closeRexxLib() ;
X DeletePort(rexxPort) ;
X rexxPort = NULL ;
X }
X rexxPortBit = 0 ;
X}
X/*
X * Here we dispatch any REXX messages that might be outstanding.
X * This is the main routine for handling Rexx messages.
X * This function is fast if no messages are outstanding, so it's
X * pretty safe to call fairly often.
X *
X * If we are bring the system down and flushing messages, we reply
X * with a pretty serious return code RXERRORIMGONE.
X *
X * No arguments, no returns.
X */
Xvoid dispRexxPort() {
X register struct RexxMsg *GetMsg() ;
X register struct RexxMsg *RexxMsg ;
X register char *p ;
X register int dontreply ;
X
X/*
X * If there's no rexx port, we're out of here.
X */
X if (rexxPort == NULL)
X return ;
X/*
X * Otherwise we have our normal loop on messages.
X */
X while (RexxMsg = (struct RexxMsg *)GetMsg(rexxPort)) {
X/*
X * If we have a reply to a message we sent, we look at the second
X * argument. If it's set, it's a function we are supposed to call
X * so we call it. Then, we kill the argstring and the message
X * itself, decrement the outstanding count, and attempt to close
X * down the Rexx library. Note that this call only succeeds if
X * there are no outstanding messages. Also, it's pretty quick, so
X * don't talk to me about efficiency.
X */
X if (RexxMsg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG) {
X if (RexxMsg->rm_Args[1]) {
X ((int (*)())(RexxMsg->rm_Args[1]))(RexxMsg) ;
X }
X DeleteArgstring(RexxMsg->rm_Args[0]) ;
X DeleteRexxMsg(RexxMsg) ;
X stillNeedReplies-- ;
X closeRexxLib() ;
X/*
X * The default case is we got a message and we need to check it for
X * primitives. We skip past any initial tabs or spaces and initialize
X * the return code fields.
X */
X } else {
X p = (char *)RexxMsg->rm_Args[0] ;
X while (*p > 0 && *p <= ' ')
X p++ ;
X RexxMsg->rm_Result1 = 0 ;
X RexxMsg->rm_Result2 = 0 ;
X/*
X * If somehow the reply is already done or postponed, `dontreply' is
X * set.
X */
X dontreply = 0 ;
X/*
X * If the sky is falling, we just blow up and replymsg.
X */
X if (bringerdown) {
X RexxMsg->rm_Result1 = RXERRORIMGONE ;
X/*
X * Otherwise we call ExecuteBatchCommand() to find and execute
X * the command.
X */
X } else {
X int result;
X
X oRexxMsg = RexxMsg ;
X result = ExecuteBatchCommand(p);
X/*
X * If we did get -1, we didn't understand the command. In
X * this case, if we were supplied an extension in upRexxPort, we know
X * that we should send the command out, so we do so, synchronously.
X * The synchronous send takes care of our reply. If we were given a
X * NULL extension, we bitch that the command didn't make sense to us.
X */
X if (result == -1) {
X if (extension) {
X syncRexxCmd(RexxMsg->rm_Args[0], RexxMsg) ;
X dontreply = 1 ;
X } else {
X RexxMsg->rm_Result1 = RXERRORNOCMD ;
X }
X } else if (result == 0) { /* Command failed */
X RexxMsg->rm_Result1 = 20;
X RexxMsg->rm_Result2 = 10;
X }
X }
X/*
X * Finally, reply if appropriate.
X */
X oRexxMsg = NULL ;
X if (! dontreply)
X ReplyMsg(RexxMsg) ;
X }
X }
X}
X/*
X * Opens the Rexx library if unopened. Returns success (1) or
X * failure (0). This is another function that is *private* but
X * that doesn't have to be.
X */
Xstatic int openRexxLib() {
X struct RxsLib *OpenLibrary() ;
X
X if (RexxSysBase)
X return(1) ;
X return((RexxSysBase = OpenLibrary(RXSNAME, 0L)) != NULL) ;
X}
X/*
X * This is the general ARexx command interface, but is not the one
X * you will use most of the time; ones defined later are easier to
X * understand and use. But they all go through here.
X */
Xstruct RexxMsg *sendRexxCmd(s, f, p1, p2, p3)
Xchar *s ;
X/*
X * The first parameter is the command to send to Rexx.
X */
Xint (*f)() ;
X/*
X * The second parameter is either NULL, indicating that the command
X * should execute asynchronously, or a function to be called when the
X * message we build up and send out here finally returns. Please note
X * that the function supplied here could be called during cleanup after
X * a fatal error, so make sure it is `safe'. This function always is
X * passed one argument, the RexxMsg that is being replied.
X */
XSTRPTR p1, p2, p3 ;
X/*
X * These are up to three arguments to be stuffed into the RexxMsg we
X * are building up, making the values available when the message is
X * finally replied to. The values are stuffed into Args[2]..Args[4].
X */
X{
X struct RexxMsg *CreateRexxMsg() ;
X STRPTR CreateArgstring() ;
X register struct MsgPort *rexxport ;
X register struct RexxMsg *RexxMsg ;
X
X/*
X * If we have too many replies out there, we just return failure.
X * Note that you should check the return code to make sure your
X * message got out! Then, we forbid, and make sure that:
X * - we have a rexx port open
X * - Rexx is out there
X * - the library is open
X * - we can create a message
X * - we can create an argstring
X *
X * If all of these succeed, we stuff a few values and send the
X * message, permit, and return.
X */
X if (rexxPort == NULL || stillNeedReplies > MAXRXOUTSTANDING-1)
X return(NULL) ;
X RexxMsg = NULL ;
X if (openRexxLib() && (RexxMsg =
X CreateRexxMsg(rexxPort, extension, rexxPort->mp_Node.ln_Name)) &&
X (RexxMsg->rm_Args[0] = CreateArgstring(s, (long)strlen(s)))) {
X RexxMsg->rm_Action = RXCOMM ;
X RexxMsg->rm_Args[1] = (STRPTR)f ;
X RexxMsg->rm_Args[2] = p1 ;
X RexxMsg->rm_Args[3] = p2 ;
X RexxMsg->rm_Args[4] = p3 ;
X RexxMsg->rm_Node.mn_Node.ln_Name = RXSDIR ;
X Forbid() ;
X if (rexxport = FindPort(RXSDIR))
X PutMsg(rexxport, RexxMsg) ;
X Permit() ;
X if (rexxport) {
X stillNeedReplies++ ;
X return(RexxMsg) ;
X } else
X DeleteArgstring(RexxMsg->rm_Args[0]) ;
X }
X if (RexxMsg)
X DeleteRexxMsg(RexxMsg) ;
X closeRexxLib() ;
X return(NULL) ;
X}
X/*
X * This function is used to send out an ARexx message and return
X * immediately. Its single parameter is the command to send.
X */
Xstruct RexxMsg *asyncRexxCmd(s)
Xchar *s ;
X{
X return(sendRexxCmd(s, NULL, NULL, NULL, NULL)) ;
X}
X/*
X * This function sets things up to reply to the message that caused
X * it when we get a reply to the message we are sending out here.
X * But first the function we pass in, which actually handles the reply.
X * Note how we get the message from the Args[2]; Args[0] is the command,
X * Args[1] is this function, and Args[2]..Args[4] are any parameters
X * passed to sendRexxCmd() as p1..p3. We pass the result codes right
X * along.
X */
Xstatic void replytoit(msg)
Xregister struct RexxMsg *msg ;
X{
X register struct RexxMsg *omsg ;
X
X omsg = (struct RexxMsg *)(msg->rm_Args[2]) ;
X replyRexxCmd(omsg, msg->rm_Result1, msg->rm_Result2, NULL) ;
X ReplyMsg(omsg) ;
X}
X/*
X * This function makes use of everything we've put together so far,
X * and functions as a synchronous Rexx call; as soon as the macro
X * invoked here returns, we reply to `msg', passing the return codes
X * back.
X */
Xstruct RexxMsg *syncRexxCmd(s, msg)
Xchar *s ;
Xstruct RexxMsg *msg ;
X{
X return(sendRexxCmd(s, (APTR)&replytoit, msg, NULL, NULL)) ;
X}
X/*
X * There are times when you want to pass back return codes or a
X * return string; call this function when you want to do that.
X */
Xvoid replyRexxCmd(msg, primary, secondary, string)
X/*
X * The first parameter is the message we are replying to.
X */
Xregister struct RexxMsg *msg ;
X/*
X * The next two parameters are the primary and secondary return
X * codes.
X */
Xregister long primary, secondary ;
X/*
X * The final parameter is a return string. This string is only
X * returned if the primary return code is 0, and a string was
X * requested.
X */
Xregister char *string ;
X{
X STRPTR CreateArgstring() ;
X
X/*
X * Note how we make sure the Rexx Library is open before calling
X * CreateArgstring . . . and we close it down at the end, if possible.
X */
X if (primary == 0 && (msg->rm_Action & (1L << RXFB_RESULT))) {
X if (string && openRexxLib())
X secondary = (long)CreateArgstring(string, (long)strlen(string)) ;
X else
X secondary = 0L ;
X }
X msg->rm_Result1 = primary ;
X msg->rm_Result2 = secondary ;
X closeRexxLib() ;
X}
SHAR_EOF
echo "extracting Misc.c"
sed 's/^X//' << \SHAR_EOF > Misc.c
X/*
X * M A N D E L B R O T C O N S T R U C T I O N S E T
X *
X * (C) Copyright 1989 by Olaf Seibert.
X * Mandel may be freely distributed. See file 'doc/Notice' for details.
X *
X * Main Program, including some general routines
X */
X
X#include <exec/types.h>
X#include <intuition/intuition.h>
X#ifdef DEBUG
X# include <stdio.h>
X# undef STATIC
X# define STATIC /* EMPTY */
X#endif
X#include "mandel.h"
X
Xextern struct NewWindow XYNWindow;
Xextern struct Window *XYwindow;
X
X#define BORDERLEFT 3
X#define BORDERTOP 11
X#define BORDERBOTTOM 3
X
X#define CHARS 16 /* Change UpdateXYwindow also with this */
X
Xstruct NewWindow XYNWindow =
X{
X 2 * BORDERLEFT, 2 * BORDERTOP,
X CHARS*8+BORDERLEFT*2, 2*8+BORDERTOP+BORDERBOTTOM,
X 2, 1, /* DetailPen, BlockPen */
X 0, /* CLOSEWINDOW */
X WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | NOCAREREFRESH | SIMPLE_REFRESH,
X NULL, /* FirstGadget */
X NULL, /* default CheckMark */
X (UBYTE *) "Re and Im", /* Title */
X NULL, /* Screen */
X NULL, /* BitMap */
X 0, 0, /* MinWidth, MinHeight */
X 0, 0, /* MaxWidth, MaxHeight */
X CUSTOMSCREEN /* Screen type */
X};
X
Xdouble ReMouse, ImMouse;
X
X/*
X * We always ask for INTUITICKS, since this window will only be open
X * as long as we have the flashing lines.
X */
X
Xvoid OpenXYwindow()
X{
X if (XYwindow == NULL) {
X XYNWindow.Screen = MandelScreen;
X
X if (XYwindow = OpenWindow(&XYNWindow)) {
X XYwindow->UserPort = MainWindow->UserPort;
X ModifyIDCMP(XYwindow, (long)CLOSEWINDOW | MOUSEBUTTONS | INTUITICKS);
X SetDrMd(XYwindow->RPort, (long)JAM2);
X SetAPen(XYwindow->RPort, (long)1);
X SetBPen(XYwindow->RPort, (long)0);
X }
X }
X}
X
Xvoid CloseXYwindow()
X{
X if (XYwindow) {
X CloseWindowSafely(XYwindow);
X XYwindow = NULL;
X }
X}
X
Xvoid UpdateXYwindow(x, y) /* corrected: 0..max */
Xint x, y;
X{
X register int chars;
X register struct RastPort *rp;
X register long left, top;
X char buffer[CHARS+2]; /* 1 extra for \0, and 1 for safety */
X static char format[] = "%-16.10g"; /* 16 == CHARS */
X /* -1.234567890e-99 is 16 chars with a precision of 10 digits */
X
X ReMouse = LeftEdge + CXStep * x;
X ImMouse = TopEdge - CYStep * y;
X
X if (XYwindow) {
X rp = XYwindow->RPort;
X left = XYwindow->BorderLeft;
X top = XYwindow->BorderTop;
X
X chars = sprintf(buffer, format, ReMouse);
X Move(rp, left, top+7);
X Text(rp, buffer, (long)chars);
X
X chars = sprintf(buffer, format, ImMouse);
X Move(rp, left, top+15);
X Text(rp, buffer, (long)chars);
X }
X}
X
Xvoid MyExit(status)
Xchar *status;
X{
X static char message[] = "\
X\0\144\25Mandelbrot Construction Set -- By KosmoSoft Productions\0a\
X\0\144\41 \0";
X/* 3^5^ 10^ ^ 20^ ^ 30^ ^ 40^ ^ 50^ 55^58^ */
X register char *c=message+63;
X
X#ifdef AREXX
X dnRexxPort();
X#endif
X
X if (status) {
X /* Center the message. */
X
X {
X register int halfway = 320 - (strlen(status) << 2);
X message[60] = halfway >> 8; /* High byte */
X message[61] = halfway; /* Low byte */
X }
X while ((*(c++) = *(status++)) && c < message + 127);
X *c = 0;
X
X /* Let's be paranoid for a change... */
X if (!IntuitionBase) IntuitionBase = (struct IntuitionBase *)
X OpenLibrary ("intuition.library", 0L);
X if (IntuitionBase)
X DisplayAlert(RECOVERY_ALERT, message, 50L);
X else { /* AT_Recovery | AG_OpenLib | AO_Intuition */
X CPTR AlertParameter = (CPTR) FindTask(NULL);
X Alert(0x00038004L, &AlertParameter);
X }
X
X status=1;
X }
X CleanupDisplay((bool) TRUE);
X if (DrawSigBit != -1) FreeSignal((long)DrawSigBit);
X if (IntuitionBase) CloseLibrary(IntuitionBase);
X if (LayersBase) CloseLibrary(LayersBase);
X if (GfxBase) CloseLibrary(GfxBase);
X exit ((int) (status != NULL));
X}
X
Xvoid _abort()
X{
X MyExit("_abort() called...");
X}
X
Xbool Sure()
X{
X bool Result;
X ULONG OldIDCMP = MainWindow->IDCMPFlags;
X
X static struct IntuiText Body[] =
X {
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X 25, 10, NULL, (UBYTE *) "You are going to", &Body[1] },
X { MYFRONTPEN+1, AUTOBACKPEN, AUTODRAWMODE,
X 57, 25, &Topaz60, (UBYTE *) "destroy", &Body[2] },
X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X 33, 40, NULL, (UBYTE *) "your picture !", NULL }
X };
X
X if (Saved) return TRUE;
X
X ModifyIDCMP(MainWindow, OldIDCMP &~ (MENUVERIFY | SIZEVERIFY | REQVERIFY));
X Result = AutoRequest(MainWindow, &Body[0], &PositiveText, &NegativeText,
X NULL, NULL, 200L, 90L);
X ModifyIDCMP(MainWindow, OldIDCMP);
X
X return Result;
X}
X
X/*
X * Render a requester in a window. If it won't fit, open a new window.
X * This new window will share the IDCMP port with the original
X * window. This is to save memory, signal bits and VERIFY deadlocks.
X * Returns the window in which the requester actually appears.
X */
X
Xstruct Window *MyRequest(request, window)
Xstruct Requester *request;
Xstruct Window *window;
X{
X static struct NewWindow newwindow = {
X 0, 0, 0, 0, 2, 1,
X NULL, /* IDCMP flags -- port shared with main window */
X WINDOWDEPTH | WINDOWDRAG | ACTIVATE | SIMPLE_REFRESH | NOCAREREFRESH,
X NULL, NULL, NULL, NULL,
X NULL, 0, 0, 0, 0, NULL };
X int width, height;
X int borderleft, borderright, bordertop, borderbottom;
X struct Window *oldwindow = window;
X
X borderleft = window->WScreen->WBorLeft;
X borderright = window->BorderRight;
X bordertop = window->WScreen->BarHeight + 1;
X borderbottom = window->BorderBottom;
X
X /* Center the requester in the given window.
X * If impossible, open a new window to the place the requester in.
X */
X
X width = window->GZZWidth;
X height = window->GZZHeight;
X
X if (width < request->Width || height < request-> Height) {
X /* Window too small. Open a new one */
X newwindow.Screen = window->WScreen;
X newwindow.Type = window->WScreen->Flags & SCREENTYPE;
X newwindow.Title = window->Title;
X newwindow.Width = request->Width + 2 * borderleft;
X newwindow.Height = request->Height + bordertop + borderbottom;
X newwindow.LeftEdge = (newwindow.Screen->Width - newwindow.Width) / 2;
X newwindow.TopEdge = (newwindow.Screen->Height - newwindow.Height) / 2;
X
X if (window = OpenWindow(&newwindow)) {
X window->UserPort = oldwindow->UserPort;
X /* Upen up the other port */
X ModifyIDCMP(window, GADGETUP);
X }
X
X request->LeftEdge = borderleft;
X request->TopEdge = bordertop;
X } else { /* The requester fits. Center it! */
X request->LeftEdge = ((width - request->Width) >> 1);
X request->TopEdge = ((height - request->Height) >> 1);
X if (!(window->Flags & GIMMEZEROZERO)) {
X request->LeftEdge += borderleft;
X request->TopEdge += bordertop;
X }
X }
X
X if (window && Request(request, window)) return window;
X
X if (window) CloseWindowSafely(window);
X return NULL;
X}
X
Xvoid EndMyRequest(request, window, original)
Xstruct Requester *request;
Xstruct Window *window, *original;
X{
X EndRequest(request, window);
X if (window != original) CloseWindowSafely(window);
X}
X
X/*
X * Wait on a request posted by MyRequest.
X * Returns when a gadget with GadgetID >= POSGADGETID is released,
X * so Gadgets with an ID < POSGADGETID will be ignored.
X * NEGGADID > POSGADID.
X * Any messages other than GADGETUP will be ignored.
X */
X
Xint WaitMyRequest(window)
Xstruct Window *window;
X{
X int ID = 0;
X struct IntuiMessage *message;
X struct Gadget *Gadget;
X ULONG Class;
X ULONG OldIDCMP = window->IDCMPFlags;
X ULONG SigMask;
X
X if (!window)
X return NEGGADGETID;
X
X ModifyIDCMP(window, GADGETUP);
X
X#ifdef AREXX
X SigMask = RexxMask | (1L << MainWindow->UserPort->mp_SigBit);
X#else
X SigMask = (1L << MainWindow->UserPort->mp_SigBit);
X#endif
X
X while (ID < POSGADGETID) {
X Wait(SigMask);
X#ifdef AREXX
X dispRexxPort();
X#endif
X while (message = (struct IntuiMessage *) GetMsg(window->UserPort) ) {
X Class = message->Class;
X Gadget = (struct Gadget *)message->IAddress;
X ReplyMsg(message);
X if (Class != GADGETUP) continue;
X ID = Gadget->GadgetID;
X if (ID >= POSGADGETID) break; /* Also gets out of outer loop */
X }
X }
X ModifyIDCMP(window, OldIDCMP);
X return ID;
X}
X
Xvoid RectDraw(rp, x1, y1, x2, y2)
Xstruct RastPort *rp;
XSHORT x1, y1, x2,y2;
X{
X Move(rp, (long) x1, (long) y1);
X Draw(rp, (long) x2, (long) y1);
X Draw(rp, (long) x2, (long) y2);
X Draw(rp, (long) x1, (long) y2);
X if (y2 > y1) y1++; else y1--; /* Don't XOR the first pixel twice */
X Draw(rp, (long) x1, (long) y1);
X}
X
Xvoid CrossDraw(rp, x, y, left, right, top, bottom)
Xstruct RastPort *rp;
XSHORT x, y, top, bottom, left, right;
X{
X Move(rp, (long) left, (long) y);
X Draw(rp, (long) right, (long) y);
X Move(rp, (long) x, (long) top);
X Draw(rp, (long) x, (long) bottom);
X}
X
Xvoid DisableSystemGadgets(gadget)
Xstruct Gadget *gadget;
X{
X while (gadget) {
X if (gadget->GadgetType & SYSGADGET) {
X /* Ghost everything except the Title/Dragbar */
X if ((gadget->GadgetType & 0x00F0) != WDRAGGING)
X OffGadget(gadget, MainWindow, NULL);
X gadget->Flags |= GADGDISABLED;
X }
X gadget = gadget->NextGadget;
X }
X}
X
Xvoid EnableSystemGadgets(gadget)
Xstruct Gadget *gadget;
X{
X USHORT Flags = 0;
X
X while (gadget) {
X if (gadget->GadgetType & SYSGADGET) {
X Flags |= gadget->Flags;
X gadget->Flags &= ~GADGDISABLED;
X }
X gadget = gadget->NextGadget;
X }
X /* Unghost everthing if necessary */
X if (Flags & GADGDISABLED) RefreshWindowFrame(MainWindow);
X}
X
Xvoid StopFraming()
X{
X if (MainWindow) {
X EnableSystemGadgets(MainWindow->FirstGadget);
X ModifyIDCMP(MainWindow, MainWindow->IDCMPFlags & ~INTUITICKS);
X }
X MouseStatus = NOTFRAMING;
X CloseXYwindow();
X}
X
Xvoid CheckMouse(Message)
Xregister struct IntuiMessage *Message;
X{
X register SHORT top = MainWindow->BorderTop,
X bottom = MainWindow->Height - MainWindow->BorderBottom - 1,
X left = MainWindow->BorderLeft,
X right = MainWindow->Width - MainWindow->BorderRight - 1;
X static ULONG OldSecs, OldMicros;
X static SHORT MidX, MidY;
X USHORT MouseX, MouseY;
X
X if (Message->IDCMPWindow == MainWindow) {
X MouseX = Message->MouseX;
X MouseY = Message->MouseY;
X } else {
X MouseX = MainWindow->MouseX;
X MouseY = MainWindow->MouseY;
X }
X
X if (StillDrawing || MouseStatus != FLASHING &&
X (MouseX < left || MouseX > right || MouseY < top || MouseY > bottom))
X return;
X
X MouseX -= left;
X MouseY -= top;
X
X if (Message->Class == MOUSEBUTTONS) {
X if (Message->Code == SELECTDOWN) {
X /* We selected a point */
X switch (MouseStatus) {
X case NOTFRAMING:
X case FLASHING:
X MouseStatus = NOPOINT;
X DisableSystemGadgets(MainWindow->FirstGadget);
X ModifyIDCMP(MainWindow, MainWindow->IDCMPFlags | INTUITICKS);
X OpenXYwindow();
X /* Now we can select our first corner */
X break;
X case NOPOINT:
X FrameX1 = FrameX2 = MouseX;
X FrameY1 = FrameY2 = MouseY;
X MouseStatus = POINT1;
X OldMicros = Message->Micros;
X OldSecs = Message->Seconds;
X /* We have the first point. Now go for the second */
X break;
X case POINT1:
X if (DoubleClick(OldSecs, OldMicros,
X Message->Seconds, Message->Micros)) {
X /* Did we double-click? Then we have selected a center */
X MouseStatus = CENTERFRAMING;
X MidX = FrameX1;
X MidY = FrameY1;
X break;
X }
X FrameX2 = MouseX;
X FrameY2 = MouseY;
X /* Fall through to CENTERFRAMING */
X case CENTERFRAMING:
X if (FrameX1 == FrameX2 || FrameY1 == FrameY2) break;
X EnableSystemGadgets(MainWindow->FirstGadget);
X MouseStatus = FLASHING;
X /* Point 1 should be upper left */
X if (FrameX2 < FrameX1) {
X /* I DO know I am reusing a variable here. Sorry! */
X left=FrameX2; FrameX2=FrameX1; FrameX1=left;
X }
X if (FrameY2 < FrameY1) {
X left=FrameY2; FrameY2=FrameY1; FrameY1=left;
X }
X break;
X } /* End switch MouseStatus */
X } /* End if Code == SELECTDOWN */
X return;
X } /* End if Class == MOUSEBUTTONS */
X
X /* We are moving the mouse. Show something! */
X
X UpdateXYwindow(MouseX, MouseY);
X
X SetDrMd(MainWindow->RPort, (ULONG) COMPLEMENT);
X
X switch (MouseStatus) {
X /* case NOTFRAMING: */
X /* return; */
X case NOPOINT:
X FrameX1 = FrameX2 = MouseX;
X FrameY1 = FrameY2 = MouseY;
X WaitTOF();
X CrossDraw(MainWindow->RPort, FrameX1, FrameY1,
X 0, MainWindow->GZZWidth-1, 0, MainWindow->GZZHeight-1);
X WaitTOF();
X CrossDraw(MainWindow->RPort, FrameX1, FrameY1,
X 0, MainWindow->GZZWidth-1, 0, MainWindow->GZZHeight-1);
X break;
X case CENTERFRAMING:
X FrameX1 = MouseX;
X FrameY1 = MouseY;
X FrameX2 = 2*MidX - FrameX1;
X FrameY2 = 2*MidY - FrameY1;
X skipto flashing;
X case POINT1:
X FrameX2 = MouseX;
X FrameY2 = MouseY;
X /* Deliberate Fall-Through to FLASHING */
X case FLASHING:
Xflashing:
X WaitTOF();
X RectDraw(MainWindow->RPort, FrameX1, FrameY1, FrameX2, FrameY2);
X WaitTOF();
X RectDraw(MainWindow->RPort, FrameX1, FrameY1, FrameX2, FrameY2);
X }
X}
X
Xvoid InitPenTable()
X{
X register int i;
X
X switch (PenTableMode) {
X case MODULO:
X PenTable[0] = 0;
X for (i=1; i<MAXDEPTH; i++) PenTable[i] = 1 + i % (NumColors - 1);
X break;
X case RANGES:
X PenTable[0] = 0;
X for (i=1; i<MAXDEPTH; i++)
X PenTable[i] = 1 + (i/RangeWidth) % (NumColors - 1);
X case SELECT:
X /* Don't change the table if it is user-defined */
X break;
X }
X}
X
Xvoid SelectMenu(MenuNum, CheckIt)
XLONG MenuNum;
Xbool CheckIt;
X{
X struct MenuItem *Item = ItemAddress(MandelMenu, MenuNum);
X
X ClearMenuStrip(MainWindow);
X
X if (CheckIt)
X Item->Flags |= CHECKED;
X else
X Item->Flags &= ~CHECKED;
X
X SetMenuStrip(MainWindow, MandelMenu);
X}
X
Xvoid MakeMAND(mand)
Xstruct Mand *mand;
X{
X int i;
X
X mand->MandID = MAND;
X mand->Size = sizeof(struct Mand) - 2 * sizeof(LONG);
X mand->MaxDepth = MaxDepth;
X mand->RangeWidth = RangeWidth;
X
X mand->RainDist = RainbowDistance;
X mand->RainRMax = RainbowRMax;
X mand->RainGMax = RainbowGMax;
X mand->RainBMax = RainbowBMax;
X
X for (i=0; i < sizeof(mand->Coords); i++)
X mand->Coords[i] = '\0';
X sprintf(&mand->Coords[0], "%1.10g %1.10g %1.10g %1.10g",
X LeftEdge, RightEdge, TopEdge, BottomEdge);
X
X mand->FunctionNr = FunctionNr;
X mand->PenTableMode = PenTableMode;
X mand->WBWidth = WBWidth;
X mand->WBHeight = WBHeight;
X
X}
X
Xbool InterpretMAND(mand, ilbminfo)
Xstruct Mand *mand;
Xstruct ILBM_info *ilbminfo;
X{
X double NewLeftEdge, NewRightEdge, NewTopEdge, NewBottomEdge;
X double Ratio;
X
X /* Perform some checks on correctness of the chunk */
X if (mand->MandID != MAND ||
X mand->Size > sizeof(struct Mand) - 2 * sizeof(LONG) ||
X mand->MaxDepth > MAXDEPTH ||
X mand->RangeWidth > MAXDEPTH)
X return FALSE;
X
X if (sscanf(&mand->Coords[0], "%lf %lf %lf %lf",
X &NewLeftEdge, &NewRightEdge, &NewTopEdge, &NewBottomEdge) < 4)
X return FALSE;
X
X MaxDepth = mand->MaxDepth;
X RangeWidth = mand->RangeWidth;
X
X /* Compensate for different sized windows */
X
X Ratio = (double)MainWindow->GZZWidth / (double)ilbminfo->header.w;
X LeftEdge = NewLeftEdge;
X if (Ratio != 1.0)
X RightEdge = NewLeftEdge + Ratio * (NewRightEdge - NewLeftEdge);
X else /* avoid round-off when almost exactly 1.0000 */
X RightEdge = NewRightEdge;
X
X Ratio = (double)MainWindow->GZZHeight / (double)ilbminfo->header.h;
X TopEdge = NewTopEdge;
X if (Ratio != 1.0)
X BottomEdge = NewTopEdge - Ratio * (NewTopEdge - NewBottomEdge);
X else /* avoid round-off when almost exactly 1.0000 */
X BottomEdge = NewBottomEdge;
X
X CalcCSteps();
X
X RainbowDistance = mand->RainDist;
X RainbowRMax = mand->RainRMax;
X RainbowGMax = mand->RainGMax;
X RainbowBMax = mand->RainBMax;
X
X if (mand->Size > OFFSETOF(FunctionNr, Mand) - 2*sizeof(long)) {
X SetDrawingFunction(mand->FunctionNr);
X PenTableMode = mand->PenTableMode;
X WBWidth = mand->WBWidth;
X WBHeight = mand->WBHeight;
X InitPenTable();
X }
X
X UpdateCheckmarks();
X
X return TRUE;
X}
SHAR_EOF
echo "End of archive 3 (of 4)"
# if you want to concatenate archives, remove anything after this line
exit