home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d588 / mandelsquare.lha / MandelSquare / Source / MandelSquare.c < prev    next >
C/C++ Source or Header  |  1992-01-04  |  98KB  |  4,133 lines

  1. /** Revision Header * Header built automatically - do not edit! *************
  2.  *
  3.  *    (C) Copyright 1991 by Olaf `Olsen' Barthel, all rights reserved
  4.  *
  5.  *    Name .....: MandelSquare
  6.  *    Created ..: Monday 26-Aug-91 11:20
  7.  *    Revision .: 3
  8.  *
  9.  *    Date            Author          Comment
  10.  *    =========       ========        ====================
  11.  *    16-Sep-91    Olsen        Added animation replay feature
  12.  *    12-Sep-91    Olsen        Several enhancements & bug fixes
  13.  *    26-Aug-91    Olsen        Created this file!
  14.  *
  15.  ***************************************************************************/
  16.  
  17. #include "MandelSquare.h"
  18.  
  19. UBYTE VersTag[]    = VERSTAG;
  20.  
  21.     /* Menu IDs */
  22.  
  23. enum    {    MEN_OPEN=17,MEN_SAVE,MEN_SAVEAS,MEN_PRI0,MEN_PRI1,MEN_PRI2,MEN_PLAY,MEN_START,MEN_STOP,MEN_SCROLL,MEN_FRAME,MEN_INCLUDE,MEN_RESOLUTION,MEN_ABOUT,MEN_QUIT,
  24.         MEN_ZOOM,MEN_CLIP,MEN_RERUN,MEN_PRECISE,MEN_COORDS,MEN_PALETTE,MEN_SPEC,MEN_RUN };
  25.  
  26.     /* Screen width & height must be a multiple of 32. */
  27.  
  28. #define PLUS        32
  29.  
  30.     /* Dimensions of the coords control panel. */
  31.  
  32. #define COORDS_WIDTH    256
  33. #define COORDS_HEIGHT    120
  34.  
  35.     /* Dimensions of the palette control panel. */
  36.  
  37. #define PALETTE_WIDTH    245
  38. #define PALETTE_HEIGHT    53
  39.  
  40.     /* Dimensions of the scroll amount control panel. */
  41.  
  42. #define SCROLL_WIDTH    175
  43. #define SCROLL_HEIGHT    45
  44.  
  45.     /* Two handy macros to set the window mouse pointer. */
  46.  
  47. #define            SetWait(Window)        SetPointer((Window),&Stopwatch[0],16,16,-6,0)
  48. #define            SetClear(Window)    SetPointer((Window),&ClearData[0],1,16,0,0)
  49.  
  50.     /* Just to avoid enforcer hits... */
  51.  
  52. #define            BailOut()        if(!Gadget) return(NULL);
  53.  
  54.     /* In Plot.asm, Iterate.asm & WaitLine.asm */
  55.  
  56. extern VOID __asm    Plot(register __a0 struct BitMap *,register __d0 WORD X,register __d1 WORD Y,register __d2 WORD Colour);
  57. extern BYTE __asm    Test(register __a0 struct BitMap *,register __d0 WORD X,register __d1 WORD Y);
  58. extern BYTE __stdargs    Iterate(double RealValue,double ImaginaryValue);
  59. extern VOID __asm    WaitLine(register __d1 Line);
  60.  
  61.     /* In Mandelbrot.c */
  62.  
  63. VOID __regargs        DrawSquare(struct RastPort *RPort,WORD X,WORD Y,WORD Width);
  64. VOID __regargs        DrawLine(struct RastPort *RPort,UWORD FromX,UWORD FromY,UWORD ToX,UWORD ToY);
  65. VOID            IterationSetup(VOID);
  66. VOID            GetScreenPalette(VOID);
  67. LONG __saveds        CycleServer(VOID);
  68. VOID            GfxCleanup(VOID);
  69. LONG            GfxSetup(VOID);
  70. VOID __regargs        CloseAll(LONG ReturnCode);
  71. VOID            OpenAll(VOID);
  72. VOID __regargs        CopyLine(struct BitMap *BitMap,WORD Line);
  73. VOID            GetTime(VOID);
  74. VOID            BlockWindow(VOID);
  75. VOID            ReleaseWindow(VOID);
  76. BYTE            GetFile(UBYTE *Title,UBYTE *Directory,UBYTE *Name,UBYTE *Buffer,UBYTE *Pattern,BYTE SaveFlag);
  77. WORD __stdargs        MyEasyRequest(UBYTE *Gadgets,UBYTE *Text,...);
  78. VOID            FadeTo(struct ViewPort *VPort,UWORD *From,UWORD *To,UBYTE NumColours,UBYTE ToCol,UBYTE FromCol);
  79. ULONG __regargs        Random(LONG MaxValue);
  80. struct Gadget *        CreateAllCoordsGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge);
  81. struct Gadget *        CreateAllPaletteGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge);
  82. struct Gadget *        CreateAllScrollGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge);
  83. VOID            InfoText(VOID);
  84. WORD            CalculateFrames(double MinReal,double MinImaginary,double Size);
  85. VOID            RunAnim(VOID);
  86. VOID            StopAnim(VOID);
  87. VOID            Coords(VOID);
  88. VOID            Palette(VOID);
  89. VOID            MaxScrollPanel(VOID);
  90. VOID            AreaZoom(VOID);
  91. VOID            Zoom(VOID);
  92. VOID            HandleEvent(VOID);
  93. VOID            Mandelbrot(double MinReal,double MinImaginary,double RealStep,double ImaginaryStep,LONG Left,LONG Top,LONG Width,LONG Height);
  94. VOID            RunMandelbrot(double MinReal,double MaxReal,double MinImaginary,double MaxImaginary,LONG Width,LONG Height);
  95. VOID            RunAreaMandelbrot(double RealStep,double ImaginaryStep);
  96. VOID __stdargs        main(VOID);
  97.  
  98.     /* In playanim.lib */
  99.  
  100. VOID            ClosePreLoadIFF(VOID);
  101. BYTE            OpenPreLoadIFF(BPTR file);
  102. VOID            DeleteBuffer(VOID);
  103. BYTE            CreateBuffer(VOID);
  104. VOID            SwapBits(VOID);
  105. BYTE            PlayAnim(VOID);
  106.  
  107.     /* In saveanim.lib */
  108.  
  109. BYTE            AnimOpen(UBYTE *Name,struct ViewPort *VPort,struct RastPort *RPort);
  110. BYTE            AnimAdd(struct RastPort *RPort);
  111. VOID            AnimClose(VOID);
  112.  
  113.     /* In ReadILBM.c */
  114.  
  115. struct IFFHandle * __regargs    OpenImageFile(UBYTE *Name);
  116. VOID __regargs            CloseImageFile(struct IFFHandle *Handle);
  117. BYTE __regargs            ReadImageBody(struct IFFHandle *Handle,struct BitMap *BitMap,struct BitMapHeader *BitMapHeader);
  118. BYTE __regargs            ReadImageHeader(struct IFFHandle *Handle,ULONG *ViewModes,BYTE *NumCols,UWORD *Colours,struct BitMapHeader *BitMapHeader,struct MandelInfo *MandelInfo);
  119. VOID __regargs            DeleteBitMap(struct BitMap *BitMap);
  120. struct BitMap * __regargs    CreateBitMap(BYTE Depth,UWORD Width,UWORD Height);
  121.  
  122.     /* In WriteILBM.c */
  123.  
  124. LONG            SaveBitMap(struct BitMap *BitMap,struct ViewPort *VPort,LONG LeftEdge,LONG TopEdge,LONG Width,LONG Height,LONG ParentWidth,LONG ParentHeight,STRPTR Name,struct MandelInfo *MandelInfo);
  125.  
  126.     /* Shared and global library data. */
  127.  
  128. struct IntuitionBase    *IntuitionBase;
  129. struct GfxBase        *GfxBase;
  130. struct Library        *GadToolsBase;
  131. struct Library        *IFFParseBase;
  132. struct Library        *AslBase;
  133. struct Library        *TimerBase;
  134. struct Library        *IconBase;
  135.  
  136.     /* Timer data. */
  137.  
  138. struct timerequest    *TimeRequest;
  139. struct MsgPort        *TimePort;
  140.  
  141.     /* Window & Screen data. */
  142.  
  143. struct Screen        *Screen;
  144. struct Window        *Window;
  145. struct RastPort        *RPort;
  146. struct ViewPort        *VPort;
  147. APTR             VisualInfo;
  148. struct BitMap        *BackupBitMap;
  149. struct Menu        *Menu;
  150.  
  151.     /* Current process and Window Pointer. */
  152.  
  153. struct Process        *ThisProcess;
  154. APTR             OldPtr;
  155. BYTE             OldPri;
  156.  
  157.     /* Colour cycling data. */
  158.  
  159. struct Interrupt    *CycleInterrupt;
  160. BYTE             DoCycle = FALSE,Forward,Wheel = 0,Add = 0;
  161.  
  162.     /* Some strings. */
  163.  
  164. UBYTE             LastName[256],NameBuffer[256],DummyBuffer[256],AnimSaveName[256],AnimPlayName[256];
  165.  
  166.     /* Table of spectral colours. */
  167.  
  168. UWORD             Table[80];
  169.  
  170.     /* Some more colour tables. */
  171.  
  172. UWORD             ScreenPalette[32],SinPalette[32],WheelPalette[32];
  173.  
  174.     /* Calculation data. */
  175.  
  176. LONG             MaxIteration = 32;
  177. double             RealStep,ImaginaryStep;
  178. double             RealWidth = 4.5,ImaginaryHeight = 4.5;
  179. double             MinReal,MinImaginary;
  180. double             MainMinReal,MainMinImaginary,MainRealWidth,MainImaginaryHeight;
  181. double             MaxScroll = 4;
  182. double             LastSize,LastMinReal,LastMinImaginary;
  183.  
  184.     /* Size and position of the screen. */
  185.  
  186. UWORD             AreaLeft,AreaTop,AreaWidth,AreaHeight;
  187.  
  188.     /* Various flags. */
  189.  
  190. BYTE             Running = FALSE,NewCoords = FALSE,AreaActive = FALSE,GotClip = FALSE,
  191.              NewMode = FALSE,Frame = FALSE,Include = TRUE,Faster = TRUE,UseWheel = FALSE,
  192.              Precise = FALSE,HoldIt = FALSE,AnimRunning = FALSE,FullPicture,AnimOpened = FALSE;
  193.  
  194.     /* A range of colour intensities and the colour transition table. */
  195.  
  196. BYTE             Range[32],*Wave;
  197.  
  198.     /* The levels of the palette colour sliders. */
  199.  
  200. BYTE             RedLevel = 27,GreenLevel = 22,BlueLevel = 17;
  201.  
  202.     /* A global MandelInfo structure to be prepared for the
  203.      * MAND chunk.
  204.      */
  205.  
  206. struct MandelInfo     MandelInfo;
  207.  
  208.     /* Rendering data. */
  209.  
  210. LONG              Mode = LORES_KEY,Depth = 5,Square = 256;
  211.  
  212.     /* The TextFont structure contained in Font.c */
  213.  
  214. extern struct TextFont     DigitFont;
  215.  
  216.     /* A single line bitmap whose planes are to be located
  217.      * in fast ram.
  218.      */
  219.  
  220. struct BitMap         LineBitMap;
  221.  
  222.     /* Global image data. */
  223.  
  224. struct BitMap        *GlobalBitMap;
  225. struct BitMapHeader     GlobalHeader;
  226. ULONG             GlobalMode;
  227.  
  228.     /* The initial colour table the program uses. */
  229.  
  230. UWORD ColourTable[32] =
  231. {
  232.     0x0000,0x0FFF,0x04BE,0x03AE,
  233.     0x019D,0x007D,0x016C,0x034B,
  234.     0x043A,0x0619,0x0707,0x0916,
  235.     0x0A34,0x0B43,0x0C61,0x0D70,
  236.     0x0D91,0x0EA3,0x0EB4,0x0FC6,
  237.     0x0FD7,0x0FD9,0x0EEA,0x0EEB,
  238.     0x0DFC,0x0DFD,0x0CFD,0x0BEE,
  239.     0x0AEE,0x09DF,0x07DF,0x06CF
  240. };
  241.  
  242.     /* The standard font to be use throughout the
  243.      * whole program.
  244.      */
  245.  
  246. struct TextAttr DefaultFont =
  247. {
  248.     (UBYTE *)"topaz.font",
  249.     8,
  250.     FS_NORMAL,
  251.     FPF_ROMFONT
  252. };
  253.  
  254.     /* Definitions for the pull-down menu used by the program. */
  255.  
  256. struct NewMenu MandelbrotMenu[] =
  257. {
  258.     { NM_TITLE, "Project",             0 , 0,            0,    (APTR)0},
  259.     {  NM_ITEM, "Open Picture...",        "O", 0,            0,    (APTR)MEN_OPEN},
  260.     {  NM_ITEM, "Save Picture",         0 , 0,            0,    (APTR)MEN_SAVE},
  261.     {  NM_ITEM, "Save Picture As...",    "S", 0,            0,    (APTR)MEN_SAVEAS},
  262.     {  NM_ITEM, NM_BARLABEL,         0 , 0,            0,    (APTR)0},
  263.     {  NM_ITEM, "Priority",             0 , 0,            0,    (APTR)0},
  264.     {   NM_SUB, "-5",             0 , CHECKIT|MENUTOGGLE,~1,    (APTR)MEN_PRI0},
  265.     {   NM_SUB, " 0",             0 , CHECKIT|CHECKED|MENUTOGGLE,~2,    (APTR)MEN_PRI1},
  266.     {   NM_SUB, "+5",             0 , CHECKIT|MENUTOGGLE,~4,    (APTR)MEN_PRI2},
  267.     {  NM_ITEM, NM_BARLABEL,         0 , 0,            0,    (APTR)0},
  268.     {  NM_ITEM, "Replay Animation...",    "!", 0,            0,    (APTR)MEN_PLAY},
  269.     {  NM_ITEM, NM_BARLABEL,         0 , 0,            0,    (APTR)0},
  270.     {  NM_ITEM, "Begin Animation...",    "B", 0,            0,    (APTR)MEN_START},
  271.     {  NM_ITEM, "End Animation",        "E", 0,            0,    (APTR)MEN_STOP},
  272.     {  NM_ITEM, "Set Scroll Amount...",    "A", 0,            0,    (APTR)MEN_SCROLL},
  273.     {  NM_ITEM, "Include Frame",         0 , CHECKIT|MENUTOGGLE,0,    (APTR)MEN_FRAME},
  274.     {  NM_ITEM, "Include Coordinates",     0 , CHECKIT|CHECKED|MENUTOGGLE,0,    (APTR)MEN_INCLUDE},
  275.     {  NM_ITEM, NM_BARLABEL,         0 , 0,            0,    (APTR)0},
  276.     {  NM_ITEM, "Change Resolution",    "X", 0,            0,    (APTR)MEN_RESOLUTION},
  277.     {  NM_ITEM, NM_BARLABEL,         0 , 0,            0,    (APTR)0},
  278.     {  NM_ITEM, "About...",            "?", 0,            0,    (APTR)MEN_ABOUT},
  279.     {  NM_ITEM, NM_BARLABEL,         0 , 0,            0,    (APTR)0},
  280.     {  NM_ITEM, "Quit...",            "Q", 0,            0,    (APTR)MEN_QUIT},
  281.  
  282.     { NM_TITLE, "Calculation",         0 , 0,            0,    (APTR)0},
  283.     {  NM_ITEM, "Magnify...",        "M", 0,            0,    (APTR)MEN_ZOOM},
  284.     {  NM_ITEM, "Detail...",        "D", 0,            0,    (APTR)MEN_CLIP},
  285.     {  NM_ITEM, "Recalculate...",        "R", 0,            0,    (APTR)MEN_RERUN},
  286.     {  NM_ITEM, "Precise Calculation",     0 , CHECKIT|MENUTOGGLE,0,    (APTR)MEN_PRECISE},
  287.     {  NM_ITEM, NM_BARLABEL,         0 , 0,            0,    (APTR)0},
  288.     {  NM_ITEM, "Coordinates...",        "C", 0,            0,    (APTR)MEN_COORDS},
  289.     {  NM_ITEM, NM_BARLABEL,         0 , 0,            0,    (APTR)0},
  290.     {  NM_ITEM, "Palette...",        "P", 0,            0,    (APTR)MEN_PALETTE},
  291.     {  NM_ITEM, "Spectral Colours",         0 , CHECKIT|MENUTOGGLE,0,    (APTR)MEN_SPEC},
  292.     {  NM_ITEM, NM_BARLABEL,         0 , 0,            0,    (APTR)0},
  293.     {  NM_ITEM, "Toggle Calculation",    ".", 0,            0,    (APTR)MEN_RUN},
  294.  
  295.     { NM_TITLE, "Depth",             0 , 0,            0,    (APTR)0},
  296.     {  NM_ITEM, "   32",            "0", CHECKIT|CHECKED,    ~  1,    (APTR)5},
  297.     {  NM_ITEM, "   64",            "1", CHECKIT,        ~  2,    (APTR)6},
  298.     {  NM_ITEM, "  128",            "2", CHECKIT,        ~  4,    (APTR)7},
  299.     {  NM_ITEM, "  256",            "3", CHECKIT,        ~  8,    (APTR)8},
  300.     {  NM_ITEM, "  512",            "4", CHECKIT,        ~ 16,    (APTR)9},
  301.     {  NM_ITEM, " 1024",            "5", CHECKIT,        ~ 32,    (APTR)10},
  302.     {  NM_ITEM, " 2048",            "6", CHECKIT,        ~ 64,    (APTR)11},
  303.     {  NM_ITEM, " 4096",            "7", CHECKIT,        ~128,    (APTR)12},
  304.     {  NM_ITEM, " 8192",            "8", CHECKIT,        ~256,    (APTR)13},
  305.     {  NM_ITEM, "16384",            "9", CHECKIT,        ~512,    (APTR)14},
  306.     {   NM_END, 0,                 0 , 0,            0,    (APTR)0}
  307. };
  308.  
  309.     /* Run-dump of the stopwatch mouse pointer. */
  310.  
  311. UWORD __chip Stopwatch[(2 + 16) * 2] =
  312. {
  313.     0x0000,0x0000,
  314.  
  315.     0x0400,0x07C0,
  316.     0x0000,0x07C0,
  317.     0x0100,0x0380,
  318.     0x0000,0x07E0,
  319.     0x07C0,0x1FF8,
  320.     0x1FF0,0x3FEC,
  321.     0x3FF8,0x7FDE,
  322.     0x3FF8,0x7FBE,
  323.     0x7FFC,0xFF7F,
  324.     0x7EFC,0xFFFF,
  325.     0x7FFC,0xFFFF,
  326.     0x3FF8,0x7FFE,
  327.     0x3FF8,0x7FFE,
  328.     0x1FF0,0x3FFC,
  329.     0x07C0,0x1FF8,
  330.     0x0000,0x07E0,
  331.  
  332.     0x0000,0x0000
  333. };
  334.  
  335.     /* Definitions for a clear sprite. */
  336.  
  337. UWORD __chip ClearData[(2 + 1) * 2] =
  338. {
  339.     0x0000,0x0000,
  340.  
  341.     0x0000,0x0000,
  342.  
  343.     0x0000,0x0000
  344. };
  345.  
  346.     /* Run-dump of the picture icon image data. */
  347.  
  348. USHORT Picture1Data[700] =
  349. {
  350.     0x0000,0x0000,0x0000,0x0000,0x0010,0x0000,0x0000,0x0000,
  351.     0x0000,0x0030,0x0000,0x0000,0x0000,0x0000,0x0030,0x0000,
  352.     0x0000,0x0000,0x0000,0x0030,0x0000,0x0000,0x0000,0x0000,
  353.     0x0030,0x0000,0x0000,0x0000,0x4000,0x0030,0x0000,0x0000,
  354.     0x0000,0x0000,0x0030,0x0000,0x0000,0x0000,0x0400,0x0030,
  355.     0x0000,0x0000,0x0000,0x1C00,0x0030,0x0000,0x0000,0x0000,
  356.     0x0000,0x0030,0x0000,0x0000,0x0000,0x4800,0x0030,0x0000,
  357.     0x0000,0x0000,0xC000,0x0030,0x0000,0x0000,0x0005,0x8000,
  358.     0x0030,0x0000,0x0000,0x0001,0x0300,0x0030,0x0000,0x0000,
  359.     0x0001,0x0200,0x0030,0x0000,0x0000,0x0001,0x0200,0x0030,
  360.     0x0000,0x0000,0x0100,0x0020,0x0030,0x0000,0x0000,0x002F,
  361.     0x8E80,0x8030,0x0000,0x0000,0x0328,0x0080,0x0030,0x0000,
  362.     0x0000,0x0260,0x002E,0xC030,0x0000,0x0000,0x0200,0x0008,
  363.     0x8030,0x0000,0x0000,0x0200,0x0000,0x8030,0x0000,0x0000,
  364.     0x1600,0x0000,0x0030,0x0000,0x0000,0x1400,0x0000,0x8030,
  365.     0x0000,0x2000,0x1000,0x0000,0x0030,0x0000,0x0040,0x3000,
  366.     0x0000,0x9030,0x0000,0x4000,0x2000,0x0000,0x3030,0x0000,
  367.     0x0080,0x6000,0x0000,0x6030,0x0000,0x0FB0,0x4000,0x0000,
  368.     0x0030,0x0000,0x0800,0xC000,0x0000,0x2030,0x0000,0x0800,
  369.     0x0000,0x0000,0x6030,0x0000,0x1800,0xC000,0x0000,0x4030,
  370.     0x0000,0x3000,0x8000,0x0000,0x4030,0x0001,0x2000,0x8000,
  371.     0x0000,0xC030,0x0003,0x6000,0x0000,0x0000,0x8030,0x0F82,
  372.     0x0000,0x0000,0x0001,0x0030,0x0020,0x0000,0x0000,0x0000,
  373.     0x0030,0x0008,0x0000,0x0000,0x0000,0x0030,0x0000,0x2000,
  374.     0x0000,0x0000,0x0030,0x0003,0x8000,0x8000,0x0000,0x4030,
  375.     0x0006,0x0000,0x8000,0x0000,0x4030,0x0000,0x4800,0x0000,
  376.     0x0000,0x0030,0x0000,0x0802,0x4000,0x0000,0x2030,0x0000,
  377.     0x0006,0x4000,0x0000,0x6030,0x0000,0x060C,0x0000,0x0000,
  378.     0x0030,0x0000,0x3C78,0x0000,0x0000,0x0030,0x0000,0x20C0,
  379.     0x0000,0x0000,0x1030,0x0000,0x2000,0x1800,0x0000,0xF030,
  380.     0x0000,0x4000,0x0000,0x0001,0x8030,0x0000,0x0000,0x2000,
  381.     0x0001,0x0030,0x0000,0x0000,0x0200,0x0000,0x0030,0x0000,
  382.     0x0000,0x0200,0x0000,0x0030,0x0000,0x0000,0x0200,0x0000,
  383.     0x4030,0x0000,0x0000,0x0080,0x003E,0xC030,0x0000,0x0000,
  384.     0x0180,0x0120,0x8030,0x0000,0x0000,0x0D19,0x8360,0x8030,
  385.     0x0000,0x0000,0x0101,0x0200,0x0030,0x0000,0x0000,0x0001,
  386.     0x0200,0x0030,0x0000,0x0000,0x0000,0x0000,0x0030,0x0000,
  387.     0x0000,0x0000,0x0300,0x0030,0x0000,0x0000,0x0005,0x0E00,
  388.     0x0030,0x0000,0x0000,0x0001,0x1800,0x0030,0x0000,0x0000,
  389.     0x0000,0x0000,0x0030,0x0000,0x0000,0x0000,0x2000,0x0030,
  390.     0x0000,0x0000,0x0000,0x2C00,0x0030,0x0000,0x0000,0x0000,
  391.     0x2000,0x0030,0x0000,0x0000,0x0000,0x0000,0x0030,0x0000,
  392.     0x0000,0x0000,0x0000,0x0030,0x0000,0x0000,0x0000,0x0000,
  393.     0x0030,0x7FFF,0xFFFF,0xFFFF,0xFFFF,0xFFF0,
  394.  
  395.     0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFE0,0xD555,0x5555,0x5555,
  396.     0x5555,0x5540,0xD555,0x5555,0x5555,0x5555,0x5540,0xD555,
  397.     0x5555,0x5555,0x5555,0x5540,0xD555,0x5555,0x5555,0x5555,
  398.     0x5540,0xD555,0x5555,0x5555,0x1555,0x5540,0xD555,0x5555,
  399.     0x5555,0x3555,0x5540,0xD555,0x5555,0x5555,0x8155,0x5540,
  400.     0xD555,0x5555,0x5555,0x8155,0x5540,0xD555,0x5555,0x5557,
  401.     0x0555,0x5540,0xD555,0x5555,0x555C,0x0555,0x5540,0xD555,
  402.     0x5555,0x5550,0x0155,0x5540,0xD555,0x5555,0x5558,0x5155,
  403.     0x5540,0xD555,0x5555,0x5558,0x5855,0x5540,0xD555,0x5555,
  404.     0x7558,0x59D5,0x5540,0xD555,0x5555,0x6DF8,0x7197,0x5540,
  405.     0xD555,0x5555,0x6080,0x401E,0x5540,0xD555,0x5555,0x4000,
  406.     0x5010,0x5540,0xD555,0x5555,0x5015,0x5500,0x5540,0xD555,
  407.     0x5555,0x5115,0x5540,0x1540,0xD555,0x5555,0xF155,0x5554,
  408.     0x5540,0xD555,0x5555,0x8155,0x5551,0x5540,0xD555,0xD555,
  409.     0x8155,0x5554,0x5540,0xD555,0x1555,0x8155,0x5556,0x5540,
  410.     0xD555,0x9755,0x8555,0x5554,0x1540,0xD555,0x1E35,0x0555,
  411.     0x5555,0x0540,0xD555,0x0005,0x1555,0x5555,0x0540,0xD555,
  412.     0x4005,0x1555,0x5555,0x1540,0xD555,0xC040,0x1555,0x5555,
  413.     0x1540,0xD555,0x0550,0x1555,0x5555,0x1540,0xD555,0x8554,
  414.     0x5555,0x5555,0x1540,0xD55B,0x8556,0x1555,0x5557,0x1540,
  415.     0xD558,0x0554,0x5555,0x5556,0x1540,0xFFF0,0x1555,0x5555,
  416.     0x5554,0x1540,0xC000,0x1555,0x5555,0x555D,0x5540,0xD001,
  417.     0x5555,0x5555,0x5550,0x5540,0xD541,0xD555,0x5555,0x5555,
  418.     0x5540,0xD550,0x1557,0x5555,0x5554,0x5540,0xD558,0x1556,
  419.     0x5555,0x5555,0x5540,0xD550,0x1556,0x5555,0x5555,0x1540,
  420.     0xD551,0x055C,0x5555,0x5555,0x1540,0xD555,0x05F0,0x5555,
  421.     0x5555,0x9540,0xD555,0x4580,0x1555,0x5555,0x1540,0xD555,
  422.     0xC000,0x1555,0x5555,0x1540,0xD555,0x8001,0x1555,0x5555,
  423.     0x9540,0xD555,0x0005,0x1555,0x5557,0x1540,0xD555,0x1515,
  424.     0x8555,0x5556,0x0540,0xD555,0x5555,0x8555,0x555C,0x0540,
  425.     0xD555,0x1555,0x0555,0x5550,0x5540,0xD555,0x5555,0x4155,
  426.     0x5574,0x5540,0xD555,0x5555,0x5155,0x5564,0x5540,0xD555,
  427.     0x5555,0x7155,0x55C6,0x5540,0xD555,0x5555,0x403D,0x5F80,
  428.     0x1540,0xD555,0x5555,0x7001,0x5800,0x1540,0xD555,0x5555,
  429.     0x4040,0x5014,0x5540,0xD555,0x5555,0x5040,0x5015,0x5540,
  430.     0xD555,0x5555,0x5458,0x5955,0x5540,0xD555,0x5555,0x5558,
  431.     0x5955,0x5540,0xD555,0x5555,0x5558,0x7155,0x5540,0xD555,
  432.     0x5555,0x5550,0x6055,0x5540,0xD555,0x5555,0x5550,0x0155,
  433.     0x5540,0xD555,0x5555,0x5554,0x0555,0x5540,0xD555,0x5555,
  434.     0x5555,0x8555,0x5540,0xD555,0x5555,0x5555,0x8555,0x5540,
  435.     0xD555,0x5555,0x5555,0x1155,0x5540,0xD555,0x5555,0x5555,
  436.     0x5555,0x5540,0xD555,0x5555,0x5555,0x5555,0x5540,0xD555,
  437.     0x5555,0x5555,0x5555,0x5540,0xD555,0x5555,0x5555,0x5555,
  438.     0x5540,0x8000,0x0000,0x0000,0x0000,0x0000
  439. };
  440.  
  441.     /* Definitions for the picture icon image. */
  442.  
  443. struct Image Picture1Image =
  444. {
  445.     0,0,
  446.     76,70,2,
  447.     (USHORT *)&Picture1Data[0],
  448.     0x03,0x00,
  449.     (struct Image *)NULL
  450. };
  451.  
  452.     /* Tool types for the picture project icon. */
  453.  
  454. char *PictureToolTypes[] =
  455. {
  456.     "FILETYPE=ILBM",
  457.     NULL
  458. };
  459.  
  460.     /* The name of the project's default tool (will be filled
  461.      * in later).
  462.      */
  463.  
  464. UBYTE DefaultTool[256];
  465.  
  466.     /* Definitions for the picture project icon. */
  467.  
  468. struct DiskObject PictureIcon =
  469. {
  470.     WB_DISKMAGIC,
  471.     WB_DISKVERSION,
  472.  
  473.     (struct Gadget *)NULL,
  474.     0,0,
  475.     76,70,
  476.     0x0004,
  477.     0x0003,
  478.     0x0001,
  479.     (APTR)&Picture1Image,
  480.     (APTR)NULL,
  481.     (struct IntuiText *)NULL,
  482.     NULL,
  483.     (APTR)NULL,
  484.     NULL,
  485.     (APTR)NULL,
  486.  
  487.     WBPROJECT,
  488.     (char *)NULL,
  489.     PictureToolTypes,
  490.     NO_ICON_POSITION,
  491.     NO_ICON_POSITION,
  492.     (struct DrawerData *)NULL,
  493.     (char *)NULL,
  494.     20000
  495. };
  496.  
  497.     /* Run-dump of the anim icon image data. */
  498.  
  499. UWORD Anim1Data[700] =
  500. {
  501.     0x0000,0x0000,0x0000,0x0000,0x0010,0x0000,0x0000,0x0000,
  502.     0x0000,0x0030,0x0000,0x0000,0x0000,0x0000,0x0030,0x0000,
  503.     0x0000,0x0000,0x0000,0x0030,0x0000,0x0000,0x0000,0x0000,
  504.     0x0030,0x0000,0x0000,0x0000,0x4000,0x0030,0x0000,0x0000,
  505.     0x0000,0x0000,0x0030,0x0000,0x0000,0x0000,0x0400,0x0030,
  506.     0x0000,0x0000,0x0000,0x1C00,0x0030,0x0000,0x0000,0x0000,
  507.     0x0000,0x0030,0x0000,0x0000,0x0000,0x4800,0x0030,0x0000,
  508.     0x0000,0x0000,0xC000,0x0030,0x0000,0x0000,0x0005,0x8000,
  509.     0x0030,0x0000,0x0000,0x0001,0x0300,0x0030,0x0000,0x0000,
  510.     0x0001,0x0200,0x0030,0x0000,0x0000,0x0001,0x0200,0x0030,
  511.     0x0000,0x0000,0x0100,0x0020,0x0030,0x0000,0x0000,0x002F,
  512.     0x8E80,0x8030,0x0000,0x0000,0x0328,0x0080,0x0030,0x0000,
  513.     0x0000,0x0260,0x002E,0xC030,0x0003,0xFFD0,0x0200,0x0008,
  514.     0x8030,0x0002,0x0010,0x0200,0x0000,0x8030,0x0002,0x0010,
  515.     0x1600,0x0000,0x0030,0x0002,0x0010,0x1400,0x0000,0x8030,
  516.     0x0002,0x2010,0x1000,0x0000,0x0030,0x0002,0x0010,0x3000,
  517.     0x0000,0x9030,0x0002,0x4010,0x2000,0x0000,0x3030,0x0002,
  518.     0x0010,0x6000,0x0000,0x6030,0x0002,0x0F10,0x4000,0x0000,
  519.     0x0030,0x0002,0x0810,0xC000,0x0000,0x2030,0x0002,0x0810,
  520.     0x0000,0x0000,0x6030,0x0002,0x0010,0xC000,0x0000,0x4030,
  521.     0x0000,0x0010,0x8000,0x0000,0x4030,0x0003,0xFFF0,0x8000,
  522.     0x0000,0xC030,0x0003,0x6000,0x0000,0x0000,0x8030,0x0F82,
  523.     0x0000,0x0000,0x0001,0x0030,0x0020,0x0000,0x0000,0x0000,
  524.     0x0030,0x0008,0x0000,0x0000,0x0000,0x0030,0x0000,0x2000,
  525.     0x0000,0x0000,0x0030,0x0003,0x8000,0x8000,0x0000,0x4030,
  526.     0x0006,0x0000,0x8000,0x0000,0x4030,0x0000,0x4800,0x0000,
  527.     0x0000,0x0030,0x0000,0x0802,0x4000,0x0000,0x2030,0x0000,
  528.     0x0006,0x4000,0x0000,0x6030,0x0000,0x060C,0x0000,0x0000,
  529.     0x0030,0x0000,0x3C78,0x0000,0x0000,0x0030,0x0000,0x20C0,
  530.     0x0000,0x0000,0x1030,0x0000,0x2000,0x1800,0x0000,0xF030,
  531.     0x0000,0x400C,0x0000,0x0C01,0x8030,0x0000,0x001C,0x2000,
  532.     0x1E01,0x0030,0x0000,0x001C,0x0200,0x0C00,0x0030,0x0000,
  533.     0x001E,0x0200,0x0000,0x0030,0x0000,0x003E,0x0DF0,0x7C1F,
  534.     0xF830,0x0000,0x003E,0x0FF8,0xFC1F,0xFC30,0x0000,0x0037,
  535.     0x0F18,0x0D1D,0xCC30,0x0000,0x0073,0x0E19,0x8D59,0xCC30,
  536.     0x0000,0x0073,0x0E19,0x0C19,0xCC30,0x0000,0x0063,0x8C19,
  537.     0x0C19,0xCC30,0x0000,0x00E1,0x8C18,0x0C19,0xCC30,0x0000,
  538.     0x00FF,0x8C18,0x0D19,0xCC30,0x0000,0x00FF,0xCC19,0x0C19,
  539.     0xCC30,0x0000,0x01C1,0xCC19,0x0C19,0xCC30,0x0000,0x01C0,
  540.     0xCC18,0x0C19,0xCC30,0x0000,0x0180,0xEC18,0x2C19,0xCC30,
  541.     0x0000,0x0180,0xEC18,0x2C19,0xCC30,0x0000,0x0100,0x6C18,
  542.     0x2C18,0x8C30,0x0000,0x0000,0x0000,0x0000,0x0030,0x0000,
  543.     0x0000,0x0000,0x0000,0x0030,0x0000,0x0000,0x0000,0x0000,
  544.     0x0030,0x7FFF,0xFFFF,0xFFFF,0xFFFF,0xFFF0,
  545.  
  546.     0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFE0,0xD555,0x5555,0x5555,
  547.     0x5555,0x5540,0xD555,0x5555,0x5555,0x5555,0x5540,0xD555,
  548.     0x5555,0x5555,0x5555,0x5540,0xD555,0x5555,0x5555,0x5555,
  549.     0x5540,0xD555,0x5555,0x5555,0x1555,0x5540,0xD555,0x5555,
  550.     0x5555,0x3555,0x5540,0xD555,0x5555,0x5555,0x8155,0x5540,
  551.     0xD555,0x5555,0x5555,0x8155,0x5540,0xD555,0x5555,0x5557,
  552.     0x0555,0x5540,0xD555,0x5555,0x555C,0x0555,0x5540,0xD555,
  553.     0x5555,0x5550,0x0155,0x5540,0xD555,0x5555,0x5558,0x5155,
  554.     0x5540,0xD555,0x5555,0x5558,0x5855,0x5540,0xD555,0x5555,
  555.     0x7558,0x59D5,0x5540,0xD555,0x5555,0x6DF8,0x7197,0x5540,
  556.     0xD555,0x5555,0x6080,0x401E,0x5540,0xD555,0x5555,0x4000,
  557.     0x5010,0x5540,0xD55F,0xFFC5,0x5015,0x5500,0x5540,0xD558,
  558.     0x0005,0x5115,0x5540,0x1540,0xD558,0x0005,0xF155,0x5554,
  559.     0x5540,0xD559,0x5545,0x8155,0x5551,0x5540,0xD559,0xD545,
  560.     0x8155,0x5554,0x5540,0xD559,0x1545,0x8155,0x5556,0x5540,
  561.     0xD559,0x9745,0x8555,0x5554,0x1540,0xD559,0x1E45,0x0555,
  562.     0x5555,0x0540,0xD559,0x0045,0x1555,0x5555,0x0540,0xD559,
  563.     0x4045,0x1555,0x5555,0x1540,0xD559,0xC040,0x1555,0x5555,
  564.     0x1540,0xD559,0x0540,0x1555,0x5555,0x1540,0xD559,0x8544,
  565.     0x5555,0x5555,0x1540,0xD559,0xFFC6,0x1555,0x5557,0x1540,
  566.     0xD550,0x0004,0x5555,0x5556,0x1540,0xFFF0,0x0005,0x5555,
  567.     0x5554,0x1540,0xC000,0x1555,0x5555,0x555D,0x5540,0xD001,
  568.     0x5555,0x5555,0x5550,0x5540,0xD541,0xD555,0x5555,0x5555,
  569.     0x5540,0xD550,0x1557,0x5555,0x5554,0x5540,0xD558,0x1556,
  570.     0x5555,0x5555,0x5540,0xD550,0x1556,0x5555,0x5555,0x1540,
  571.     0xD551,0x055C,0x5555,0x5555,0x1540,0xD555,0x05F0,0x5555,
  572.     0x5555,0x9540,0xD555,0x4580,0x1555,0x5555,0x1540,0xD555,
  573.     0xC000,0x1555,0x5555,0x1540,0xD555,0x8001,0x1555,0x5555,
  574.     0x9540,0xD555,0x0005,0x1555,0x5557,0x1540,0xD555,0x1515,
  575.     0x8555,0x5556,0x0540,0xD555,0x5551,0x8555,0x515C,0x0540,
  576.     0xD555,0x1545,0x0555,0x4150,0x5540,0xD555,0x5551,0x4155,
  577.     0x5274,0x5540,0xD555,0x5551,0x5155,0x4D64,0x5540,0xD555,
  578.     0x5542,0x7005,0x01C0,0x0540,0xD555,0x5528,0x4D15,0x7D9C,
  579.     0xC140,0xD555,0x5528,0x6248,0x8002,0x1140,0xD555,0x5505,
  580.     0x4100,0x0005,0x0140,0xD555,0x5550,0x4040,0x4001,0x4140,
  581.     0xD555,0x5550,0x4240,0x4141,0x4140,0xD555,0x5502,0x8140,
  582.     0x4141,0x4140,0xD555,0x54A0,0x0140,0x6141,0x4140,0xD555,
  583.     0x5480,0x0140,0x6041,0x4140,0xD555,0x543F,0x4140,0x0141,
  584.     0x4140,0xD555,0x5501,0x0140,0x0141,0x4140,0xD555,0x5554,
  585.     0x0141,0x8141,0x4140,0xD555,0x5414,0xA141,0x8141,0x4140,
  586.     0xD555,0x5414,0x8141,0x0141,0x4140,0xD555,0x5555,0x6D59,
  587.     0x4D58,0x8D40,0xD555,0x5455,0x1145,0x5145,0x5140,0xD555,
  588.     0x5555,0x5555,0x5555,0x5540,0xD555,0x5555,0x5555,0x5555,
  589.     0x5540,0x8000,0x0000,0x0000,0x0000,0x0000
  590. };
  591.  
  592.     /* Definitions for the anim icon image. */
  593.  
  594. struct Image Anim1Image =
  595. {
  596.     0,0,
  597.     76,70,2,
  598.     (UWORD *)&Anim1Data[0],
  599.     0x03,0x00,
  600.     (struct Image *)NULL
  601. };
  602.  
  603.     /* Tool types for the anim project icon. */
  604.  
  605. char *AnimToolTypes[] =
  606. {
  607.     "FILETYPE=ANIM",
  608.     NULL
  609. };
  610.  
  611.     /* Definitions for the anim project icon. */
  612.  
  613. struct DiskObject AnimIcon =
  614. {
  615.     WB_DISKMAGIC,
  616.     WB_DISKVERSION,
  617.  
  618.     (struct Gadget *)NULL,
  619.     23,15,
  620.     76,70,
  621.     0x0004,
  622.     0x0003,
  623.     0x0001,
  624.     (APTR)&Anim1Image,
  625.     (APTR)NULL,
  626.     (struct IntuiText *)NULL,
  627.     NULL,
  628.     (APTR)NULL,
  629.     NULL,
  630.     (APTR)NULL,
  631.  
  632.     WBPROJECT,
  633.     (char *)NULL,
  634.     AnimToolTypes,
  635.     NO_ICON_POSITION,
  636.     NO_ICON_POSITION,
  637.     (struct DrawerData *)NULL,
  638.     (char *)NULL,
  639.     20000
  640. };
  641.  
  642.     /* DrawSquare():
  643.      *
  644.      *    Draws a square rectangle at a given position.
  645.      */
  646.  
  647. VOID __regargs
  648. DrawSquare(struct RastPort *RPort,WORD X,WORD Y,WORD Width)
  649. {
  650.     Move(RPort,X,Y);
  651.     Draw(RPort,X + Width - 1,Y);
  652.     Draw(RPort,X + Width - 1,Y + Width - 1);
  653.     Draw(RPort,X,Y + Width - 1);
  654.     Draw(RPort,X,Y);
  655. }
  656.  
  657.     /* DrawLine():
  658.      *
  659.      *    Draw a simple line from a to b.
  660.      */
  661.  
  662. VOID __regargs
  663. DrawLine(struct RastPort *RPort,UWORD FromX,UWORD FromY,UWORD ToX,UWORD ToY)
  664. {
  665.     Move(RPort,FromX,FromY);
  666.     Draw(RPort,ToX,ToY);
  667. }
  668.  
  669.     /* IterationSetup():
  670.      *
  671.      *    Sets up the iterations menu, checkmarks the currently
  672.      *    selected number of iterations, uncheckmarks all the
  673.      *    others.
  674.      */
  675.  
  676. VOID
  677. IterationSetup()
  678. {
  679.     struct MenuItem *Item;
  680.  
  681.     Window -> Flags |= WFLG_RMBTRAP;
  682.  
  683.     if(Item = ItemAddress(Menu,FULLMENUNUM(2,0,0)))
  684.     {
  685.         while(Item)
  686.         {
  687.             if((1 << (ULONG)GTMENUITEM_USERDATA(Item)) == MaxIteration)
  688.                 Item -> Flags |= CHECKED;
  689.             else
  690.                 Item -> Flags &= ~CHECKED;
  691.  
  692.             Item = Item -> NextItem;
  693.         }
  694.     }
  695.  
  696.     Window -> Flags &= ~WFLG_RMBTRAP;
  697. }
  698.  
  699.     /* GetScreenPalette():
  700.      *
  701.      *    Copies the current screen palette to a buffer.
  702.      */
  703.  
  704. VOID
  705. GetScreenPalette()
  706. {
  707.     WORD i;
  708.  
  709.     for(i = 0 ; i < 32 ; i++)
  710.         ScreenPalette[i] = GetRGB4(VPort -> ColorMap,i);
  711. }
  712.  
  713.     /* CycleServer():
  714.      *
  715.      *    The interrupt server routine which handles the
  716.      *    colour cycling.
  717.      */
  718.  
  719. LONG __saveds
  720. CycleServer()
  721. {
  722.     STATIC BYTE Count = 0;
  723.  
  724.     if(Count++ == 2)
  725.     {
  726.         if(DoCycle && !HoldIt)
  727.         {
  728.             if(UseWheel)
  729.             {
  730.                 BYTE AltWheel = Wheel,i;
  731.  
  732.                 WheelPalette[0] = 0x000;
  733.                 WheelPalette[1] = 0xFFF;
  734.  
  735.                 if(Forward)
  736.                 {
  737.                     for(i = 2 ; i < 32 ; i++)
  738.                     {
  739.                         WheelPalette[i] = Table[AltWheel];
  740.  
  741.                         AltWheel = (AltWheel + 1) % 75;
  742.                     }
  743.  
  744.                     Wheel = (Wheel + 1) % 75;
  745.                 }
  746.                 else
  747.                 {
  748.                     for(i = 2 ; i < 32 ; i++)
  749.                     {
  750.                         WheelPalette[i] = Table[AltWheel];
  751.  
  752.                         AltWheel = (AltWheel + 1) % 75;
  753.                     }
  754.  
  755.                     if(Wheel)
  756.                         Wheel--;
  757.                     else
  758.                         Wheel = 74;
  759.                 }
  760.  
  761.                 LoadRGB4(VPort,WheelPalette,1 << Depth);
  762.             }
  763.             else
  764.             {
  765.                 UWORD        NewPalette[32];
  766.                 BYTE        i,Wrap = (1 << Depth) - 2,AltAdd = Add;
  767.  
  768.                 NewPalette[0] = 0x000;
  769.                 NewPalette[1] = 0xFFF;
  770.  
  771.                 if(Forward)
  772.                 {
  773.                     for(i = 2 ; i < (1 << Depth) ; i++)
  774.                     {
  775.                         NewPalette[i] = SinPalette[AltAdd + 2];
  776.  
  777.                         AltAdd = (AltAdd + 1) % Wrap;
  778.                     }
  779.  
  780.                     Add = (Add + 1) % Wrap;
  781.                 }
  782.                 else
  783.                 {
  784.                     for(i = 2 ; i < (1 << Depth) ; i++)
  785.                     {
  786.                         NewPalette[i] = SinPalette[AltAdd + 2];
  787.  
  788.                         AltAdd = (AltAdd + 1) % Wrap;
  789.                     }
  790.  
  791.                     if(Add)
  792.                         Add--;
  793.                     else
  794.                         Add = Wrap - 1;
  795.                 }
  796.  
  797.                 LoadRGB4(VPort,NewPalette,1 << Depth);
  798.             }
  799.         }
  800.  
  801.         Count = 0;
  802.     }
  803.  
  804.     return(0);
  805. }
  806.  
  807.     /* GfxCleanup():
  808.      *
  809.      *    Frees the graphics resources allocated by the
  810.      *    program.
  811.      */
  812.  
  813. VOID
  814. GfxCleanup()
  815. {
  816.     ThisProcess -> pr_WindowPtr = OldPtr;
  817.  
  818.     if(LineBitMap . Planes[0])
  819.     {
  820.         FreeVec(LineBitMap . Planes[0]);
  821.  
  822.         LineBitMap . Planes[0] = NULL;
  823.     }
  824.  
  825.     DoCycle = FALSE;
  826.  
  827.     Delay(5);
  828.  
  829.     if(Screen)
  830.         ScreenToBack(Screen);
  831.  
  832.     if(Window)
  833.     {
  834.         ClearMenuStrip(Window);
  835.  
  836.         CloseWindow(Window);
  837.  
  838.         Window = NULL;
  839.     }
  840.  
  841.     if(Menu)
  842.     {
  843.         FreeMenus(Menu);
  844.  
  845.         Menu = NULL;
  846.     }
  847.  
  848.     if(VisualInfo)
  849.     {
  850.         FreeVisualInfo(VisualInfo);
  851.  
  852.         VisualInfo = NULL;
  853.     }
  854.  
  855.     if(Screen)
  856.     {
  857.         CloseScreen(Screen);
  858.  
  859.         Screen = NULL;
  860.     }
  861. }
  862.  
  863.     /* GfxSetup():
  864.      *
  865.      *    Allocates the graphics resources the program requires.
  866.      */
  867.  
  868. LONG
  869. GfxSetup()
  870. {
  871.     struct Rectangle     DisplayClip;
  872.     LONG             Differ;
  873.     WORD             i,c = 0,r = 15,g = 0,b = 0;
  874.     double             a,p;
  875.     BYTE             AltWheel = Wheel,Wrap = (1 << Depth) - 2;
  876.  
  877.     struct ColorSpec    *ColorSpec;
  878.  
  879.     a = PI / (double)((1 << Depth) - 2);
  880.  
  881.         /* Build a range of colour intensities mapped to the
  882.          * sine wave amplitude.
  883.          */
  884.  
  885.     for(p = 0.0, i = 0 ; (p < PI) && (i < (1 << Depth) - 2) ; p += a, i++)
  886.         Range[i] = (BYTE)(sin(p) * 15 - 0.3);
  887.  
  888.     SinPalette[0] = 0x000;
  889.     SinPalette[1] = 0xFFF;
  890.  
  891.         /* Combine all three colour ranges into a single palette. */
  892.  
  893.     for(i = 0 ; i < Wrap ; i++)
  894.     {
  895.         SinPalette[2 + i]  = Range[(RedLevel   + i) % Wrap] << 8;
  896.         SinPalette[2 + i] |= Range[(GreenLevel + i) % Wrap] << 4;
  897.         SinPalette[2 + i] |= Range[(BlueLevel  + i) % Wrap];
  898.     }
  899.  
  900.         /* Create the spectral colour table. */
  901.  
  902.     for(i = 0 ; i < 16 ; i++)
  903.         Table[c++] = (r << 8) | ((g++) << 4) | b;
  904.  
  905.     g = 15;
  906.     r--;
  907.  
  908.     for(i = 0 ; i < 15 ; i++)
  909.         Table[c++] = ((r--) << 8) | (g << 4) | b;
  910.  
  911.     r = 0;
  912.     g--;
  913.     b++;
  914.  
  915.     for(i = 0 ; i < 15 ; i++)
  916.         Table[c++] = (r << 8) | ((g--) << 4) | (b++);
  917.  
  918.     g = 0;
  919.     b = 15;
  920.     r++;
  921.  
  922.     for(i = 0 ; i < 15 ; i++)
  923.         Table[c++] = ((r++) << 8) | (g << 4) | b;
  924.  
  925.     r = 15;
  926.     b--;
  927.  
  928.     for(i = 0 ; i < 14 ; i++)
  929.         Table[c++] = (r << 8) | (g << 4) | (b--);
  930.  
  931.         /* Set up the spectral colour palette. */
  932.  
  933.     WheelPalette[0] = 0x000;
  934.     WheelPalette[1] = 0xFFF;
  935.  
  936.     for(i = 2 ; i < 32 ; i++)
  937.     {
  938.         WheelPalette[i] = Table[AltWheel];
  939.  
  940.         AltWheel = (AltWheel + 1) % 75;
  941.     }
  942.  
  943.         /* Create the colour transition table. */
  944.  
  945.     for(i = 0 ; i < 16384 ; i++)
  946.         Wave[i] = 2 + (i % ((1 << Depth) - 2));
  947.  
  948.         /* Create the main screen, first query how wide the
  949.          * current overscan settings allow a screen to be.
  950.          */
  951.  
  952.     if(!QueryOverscan(Mode,&DisplayClip,OSCAN_TEXT))
  953.         return(RETURN_FAIL + 12);
  954.  
  955.         /* Open a centered screen. */
  956.  
  957.     Differ = ((DisplayClip . MaxX - DisplayClip . MinX + 1) - Square) >> 1;
  958.  
  959.     DisplayClip . MinX += Differ;
  960.     DisplayClip . MaxX -= Differ;
  961.  
  962.         /* Allocate a couple of colour specification structures. */
  963.  
  964.     if(!(ColorSpec = (struct ColorSpec *)AllocVec(sizeof(struct ColorSpec) * ((1 << Depth) + 1),MEMF_PUBLIC|MEMF_CLEAR)))
  965.     {
  966.             /* Open a screen with monochrome system imagery. */
  967.  
  968.         if(!(Screen = OpenScreenTags(NULL,
  969.             SA_Width,    Square,
  970.             SA_Height,    Square,
  971.             SA_DClip,    &DisplayClip,
  972.             SA_Left,    DisplayClip . MinX,
  973.             SA_Depth,    Depth,
  974.             SA_DisplayID,    Mode,
  975.             SA_Font,    &DefaultFont,
  976.             SA_ShowTitle,    FALSE,
  977.             SA_Quiet,    TRUE,
  978.             SA_AutoScroll,    TRUE,
  979.             SA_Behind,    TRUE,
  980.         TAG_END)))
  981.             return(RETURN_FAIL + 13);
  982.     }
  983.     else
  984.     {
  985.             /* Set up the colour specifications to open
  986.              * an entirely black screen.
  987.              */
  988.  
  989.         for(i = 0 ; i < (1 << Depth) ; i++)
  990.             ColorSpec[i] . ColorIndex = i;
  991.  
  992.         ColorSpec[i] . ColorIndex = -1;
  993.  
  994.             /* Open a screen with monochrome system imagery. */
  995.  
  996.         if(!(Screen = OpenScreenTags(NULL,
  997.             SA_Width,    Square,
  998.             SA_Height,    Square,
  999.             SA_DClip,    &DisplayClip,
  1000.             SA_Left,    DisplayClip . MinX,
  1001.             SA_Depth,    Depth,
  1002.             SA_DisplayID,    Mode,
  1003.             SA_Font,    &DefaultFont,
  1004.             SA_ShowTitle,    FALSE,
  1005.             SA_Quiet,    TRUE,
  1006.             SA_AutoScroll,    TRUE,
  1007.             SA_Behind,    TRUE,
  1008.             SA_Colors,    ColorSpec,
  1009.         TAG_END)))
  1010.         {
  1011.             FreeVec(ColorSpec);
  1012.  
  1013.             return(RETURN_FAIL + 13);
  1014.         }
  1015.         else
  1016.             FreeVec(ColorSpec);
  1017.     }
  1018.  
  1019.         /* Set up the remaining data. */
  1020.  
  1021.     if(!(VisualInfo = GetVisualInfo(Screen,TAG_DONE)))
  1022.         return(RETURN_FAIL + 14);
  1023.  
  1024.     if(!(Menu = CreateMenus(MandelbrotMenu,
  1025.         GTMN_FrontPen, 0,
  1026.     TAG_DONE)))
  1027.         return(RETURN_FAIL + 15);
  1028.  
  1029.     if(!LayoutMenus(Menu,    VisualInfo,
  1030.         GTMN_TextAttr,    &DefaultFont,
  1031.     TAG_DONE))
  1032.         return(RETURN_FAIL + 16);
  1033.  
  1034.     if(!(Window = OpenWindowTags(NULL,
  1035.         WA_Width,    Screen -> Width,
  1036.         WA_Height,    Screen -> Height,
  1037.         WA_Borderless,    TRUE,
  1038.         WA_Backdrop,    TRUE,
  1039.         WA_IDCMP,    IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | IDCMP_MENUPICK | IDCMP_RAWKEY | IDCMP_VANILLAKEY | IDCMP_MENUVERIFY,
  1040.         WA_RMBTrap,    TRUE,
  1041.         WA_CustomScreen,Screen,
  1042.     TAG_END)))
  1043.         return(RETURN_FAIL + 17);
  1044.  
  1045.         /* Create a bitmap which is exactly as wide as the
  1046.          * main screen, but only a single line high.
  1047.          */
  1048.  
  1049.     InitBitMap(&LineBitMap,Depth,Square,1);
  1050.  
  1051.         /* Allocate space for the bitmap, note that the
  1052.          * bitplanes are to reside in fast ram.
  1053.          */
  1054.  
  1055.     if(LineBitMap . Planes[0] = AllocVec(LineBitMap . BytesPerRow * LineBitMap . Depth,MEMF_PUBLIC|MEMF_CLEAR|MEMF_FAST))
  1056.     {
  1057.         for(i = 1 ; i < LineBitMap . Depth ; i++)
  1058.             LineBitMap . Planes[i] = &LineBitMap . Planes[i - 1][LineBitMap . BytesPerRow];
  1059.     }
  1060.  
  1061.     SetMenuStrip(Window,Menu);
  1062.  
  1063.     OffMenu(Window,FULLMENUNUM(0,9,0));
  1064.  
  1065.     RPort = &Screen -> RastPort;
  1066.     VPort = &Screen -> ViewPort;
  1067.  
  1068.     SetRast(RPort,0);
  1069.  
  1070.     Window -> Flags &= ~WFLG_RMBTRAP;
  1071.  
  1072.     ThisProcess -> pr_WindowPtr = (APTR)Window;
  1073.  
  1074.     return(0);
  1075. }
  1076.  
  1077.     /* CloseAll(LONG ReturnCode):
  1078.      *
  1079.      *    Close all remaining resources and terminate the program.
  1080.      */
  1081.  
  1082. VOID __regargs
  1083. CloseAll(LONG ReturnCode)
  1084. {
  1085.     SetTaskPri(ThisProcess,OldPri);
  1086.  
  1087.     if(GlobalBitMap)
  1088.     {
  1089.         DeleteBitMap(GlobalBitMap);
  1090.  
  1091.         GlobalBitMap = NULL;
  1092.     }
  1093.  
  1094.     StopAnim();
  1095.  
  1096.     if(CycleInterrupt)
  1097.     {
  1098.         DoCycle = FALSE;
  1099.  
  1100.         if(CycleInterrupt -> is_Code)
  1101.             RemIntServer(INTB_VERTB,CycleInterrupt);
  1102.  
  1103.         FreeVec(CycleInterrupt);
  1104.     }
  1105.  
  1106.     if(Wave)
  1107.         FreeVec(Wave);
  1108.  
  1109.     GfxCleanup();
  1110.  
  1111.     if(BackupBitMap)
  1112.         DeleteBitMap(BackupBitMap);
  1113.  
  1114.     if(TimeRequest)
  1115.     {
  1116.         if(TimeRequest -> tr_node . io_Device)
  1117.             CloseDevice(TimeRequest);
  1118.  
  1119.         DeleteIORequest(TimeRequest);
  1120.     }
  1121.  
  1122.     if(TimePort)
  1123.         DeleteMsgPort(TimePort);
  1124.  
  1125.     if(IconBase)
  1126.         CloseLibrary(IconBase);
  1127.  
  1128.     if(AslBase)
  1129.         CloseLibrary(AslBase);
  1130.  
  1131.     if(IFFParseBase)
  1132.         CloseLibrary(IFFParseBase);
  1133.  
  1134.     if(GadToolsBase)
  1135.         CloseLibrary(GadToolsBase);
  1136.  
  1137.     if(GfxBase)
  1138.         CloseLibrary(GfxBase);
  1139.  
  1140.     if(IntuitionBase)
  1141.         CloseLibrary(IntuitionBase);
  1142.  
  1143.     exit(ReturnCode);
  1144. }
  1145.  
  1146.     /* OpenAll():
  1147.      *
  1148.      *    Open libraries and other data which does not
  1149.      *    require changing when the display modes are
  1150.      *    altered.
  1151.      */
  1152.  
  1153. VOID
  1154. OpenAll()
  1155. {
  1156.     ThisProcess = (struct Process *)FindTask(NULL);
  1157.  
  1158.     OldPri = SetTaskPri(ThisProcess,0);
  1159.  
  1160.     OldPtr = ThisProcess -> pr_WindowPtr;
  1161.  
  1162.     if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37)))
  1163.         CloseAll(RETURN_FAIL + 0);
  1164.  
  1165.     if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",37)))
  1166.         CloseAll(RETURN_FAIL + 1);
  1167.  
  1168.     if(!(GadToolsBase = OpenLibrary("gadtools.library",37)))
  1169.         CloseAll(RETURN_FAIL + 2);
  1170.  
  1171.     if(!(IFFParseBase = OpenLibrary("iffparse.library",37)))
  1172.         CloseAll(RETURN_FAIL + 3);
  1173.  
  1174.     if(!(AslBase = OpenLibrary("asl.library",37)))
  1175.         CloseAll(RETURN_FAIL + 4);
  1176.  
  1177.     if(!(TimePort = (struct MsgPort *)CreateMsgPort()))
  1178.         CloseAll(RETURN_FAIL + 5);
  1179.  
  1180.     if(!(TimeRequest = (struct timerequest *)CreateIORequest(TimePort,sizeof(struct timerequest))))
  1181.         CloseAll(RETURN_FAIL + 6);
  1182.  
  1183.     if(OpenDevice(TIMERNAME,UNIT_VBLANK,TimeRequest,0))
  1184.         CloseAll(RETURN_FAIL + 7);
  1185.  
  1186.     if(!(BackupBitMap = CreateBitMap(5,25 * 8,8)))
  1187.         CloseAll(RETURN_FAIL + 8);
  1188.  
  1189.     if(!(CycleInterrupt = AllocVec(sizeof(struct Interrupt),MEMF_PUBLIC|MEMF_CLEAR)))
  1190.         CloseAll(RETURN_FAIL + 9);
  1191.  
  1192.     if(!(Wave = (BYTE *)AllocVec(16384,MEMF_PUBLIC|MEMF_CLEAR)))
  1193.         CloseAll(RETURN_FAIL + 10);
  1194.  
  1195.     if(!(IconBase = OpenLibrary("icon.library",37)))
  1196.         CloseAll(RETURN_FAIL + 11);
  1197.  
  1198.     TimerBase = &TimeRequest -> tr_node . io_Device -> dd_Library;
  1199.  
  1200.     CycleInterrupt -> is_Node . ln_Name    = "Mandelbrot Cycling";
  1201.     CycleInterrupt -> is_Node . ln_Type    = NT_INTERRUPT;
  1202.     CycleInterrupt -> is_Code        = (APTR)CycleServer;
  1203.  
  1204.     AddIntServer(INTB_VERTB,CycleInterrupt);
  1205. }
  1206.  
  1207.     /* CopyLine(struct BitMap *BitMap,WORD Line):
  1208.      *
  1209.      *    Copies the contents of the single line bitmap to a given
  1210.      *    line on screen.
  1211.      */
  1212.  
  1213. VOID __regargs
  1214. CopyLine(struct BitMap *BitMap,WORD Line)
  1215. {
  1216.     WORD i;
  1217.  
  1218.     Line *= BitMap -> BytesPerRow;
  1219.  
  1220.     for(i = 0 ; i < BitMap -> Depth ; i++)
  1221.         CopyMemQuick(BitMap -> Planes[i],&RPort -> BitMap -> Planes[i][Line],BitMap -> BytesPerRow);
  1222. }
  1223.  
  1224.     /* GetTime():
  1225.      *
  1226.      *    Asks the timer.device for the current system time.
  1227.      */
  1228.  
  1229. VOID
  1230. GetTime()
  1231. {
  1232.     TimeRequest -> tr_node . io_Command = TR_GETSYSTIME;
  1233.  
  1234.     DoIO(TimeRequest);
  1235. }
  1236.  
  1237.     /* BlockWindow():
  1238.      *
  1239.      *    Blocks the menu bar of the window and sets the busy
  1240.      *    mouse pointer.
  1241.      */
  1242.  
  1243. VOID
  1244. BlockWindow()
  1245. {
  1246.     HoldIt = TRUE;
  1247.  
  1248.     SetWait(Window);
  1249.  
  1250.     Window -> Flags |= WFLG_RMBTRAP;
  1251. }
  1252.  
  1253.     /* ReleaseWindow():
  1254.      *
  1255.      *    Reenables the menu bar of the window and resets the
  1256.      *    mouse pointer to the default mouse pointer.
  1257.      */
  1258.  
  1259. VOID
  1260. ReleaseWindow()
  1261. {
  1262.     ClearPointer(Window);
  1263.  
  1264.     Window -> Flags &= ~WFLG_RMBTRAP;
  1265.  
  1266.     HoldIt = FALSE;
  1267. }
  1268.  
  1269.     /* GetFile():
  1270.      *
  1271.      *    Get a file name using the asl.library file requester.
  1272.      */
  1273.  
  1274. BYTE
  1275. GetFile(UBYTE *Title,UBYTE *Directory,UBYTE *Name,UBYTE *Buffer,UBYTE *Pattern,BYTE SaveFlag)
  1276. {
  1277.     struct FileRequester    *AslFileRequest;
  1278.     BYTE             Result = FALSE;
  1279.     LONG             Flags;
  1280.  
  1281.     if(!Directory[0])
  1282.         NameFromLock(ThisProcess -> pr_CurrentDir,Directory,256);
  1283.  
  1284.     if(Pattern)
  1285.     {
  1286.         Flags = FILF_PATGAD;
  1287.  
  1288.         if(!Pattern[0])
  1289.             Pattern = "~(#?.info)";
  1290.     }
  1291.     else
  1292.     {
  1293.         Flags = 0;
  1294.  
  1295.         Pattern = "~(#?.info)";
  1296.     }
  1297.  
  1298.     if(SaveFlag)
  1299.         Flags |= FILF_SAVE;
  1300.  
  1301.     if(AslFileRequest = (struct FileRequester *)AllocAslRequestTags(ASL_FileRequest,
  1302.         ASL_Window,    Window,
  1303.         ASL_File,    Name,
  1304.         ASL_Dir,    Directory,
  1305.         ASL_Hail,    Title,
  1306.         ASL_FuncFlags,    Flags,
  1307.         ASL_Pattern,    Pattern,
  1308.         ASL_OKText,    SaveFlag ? "Save" : "Open",
  1309.         ASL_LeftEdge,    0,
  1310.         ASL_TopEdge,    0,
  1311.         ASL_Width,    Screen -> Width,
  1312.         ASL_Height,    Screen -> Height,
  1313.     TAG_DONE))
  1314.     {
  1315.         if(RequestFile(AslFileRequest))
  1316.         {
  1317.             if(AslFileRequest -> rf_File[0])
  1318.             {
  1319.                 strcpy(Buffer,AslFileRequest -> rf_Dir);
  1320.  
  1321.                 AddPart((UBYTE *)Buffer,(UBYTE *)AslFileRequest -> rf_File,256);
  1322.  
  1323.                 Result = TRUE;
  1324.             }
  1325.         }
  1326.     }
  1327.  
  1328.     FreeFileRequest(AslFileRequest);
  1329.  
  1330.     return(Result);
  1331. }
  1332.  
  1333.     /* MyEasyRequest():
  1334.      *
  1335.      *    EasyRequestArgs stub routine.
  1336.      */
  1337.  
  1338. WORD __stdargs
  1339. MyEasyRequest(UBYTE *Gadgets,UBYTE *Text,...)
  1340. {
  1341.     struct EasyStruct    Easy;
  1342.     WORD            Result;
  1343.     ULONG            IDCMP = NULL;
  1344.     va_list             VarArgs;
  1345.  
  1346.     Easy . es_StructSize    = sizeof(struct EasyStruct);
  1347.     Easy . es_Flags        = NULL;
  1348.     Easy . es_Title        = (UBYTE *)"MandelSquare";
  1349.     Easy . es_TextFormat    = (UBYTE *)Text;
  1350.     Easy . es_GadgetFormat    = (UBYTE *)Gadgets;
  1351.  
  1352.     va_start(VarArgs,Text);
  1353.     Result = EasyRequestArgs(Window,&Easy,&IDCMP,VarArgs);
  1354.     va_end(VarArgs);
  1355.  
  1356.     return(Result);
  1357. }
  1358.  
  1359.     /* FadeTo():
  1360.      *
  1361.      *    Fades from one colour table to another.
  1362.      */
  1363.  
  1364. VOID
  1365. FadeTo(struct ViewPort *VPort,UWORD *From,UWORD *To,UBYTE NumColours,UBYTE ToCol,UBYTE FromCol)
  1366. {
  1367.     UWORD    FromTemp[32];
  1368.     UWORD    ToTemp[32];
  1369.     UBYTE    i,j;
  1370.     BYTE    R1,G1,B1,R2,G2,B2;
  1371.  
  1372.     if(NumColours > 32)
  1373.         NumColours = 32;
  1374.  
  1375.     if(From)
  1376.         CopyMem(&From[0],&FromTemp[0],sizeof(UWORD) * NumColours);
  1377.     else
  1378.         memset(&FromTemp[0],FromCol,sizeof(UWORD) * NumColours);
  1379.  
  1380.     if(To)
  1381.         CopyMem(&To[0],&ToTemp[0],sizeof(UWORD) * NumColours);
  1382.     else
  1383.         memset(&ToTemp[0],ToCol,sizeof(UWORD) * NumColours);
  1384.  
  1385.     for(j = 0 ; j < 16 ; j++)
  1386.     {
  1387.         for(i = 0 ; i < NumColours ; i++)
  1388.         {
  1389.             R1 = (FromTemp[i] >> 8)    & 0xF;
  1390.             G1 = (FromTemp[i] >> 4)    & 0xF;
  1391.             B1 = (FromTemp[i])    & 0xF;
  1392.  
  1393.             R2 = (ToTemp[i] >> 8)    & 0xF;
  1394.             G2 = (ToTemp[i] >> 4)    & 0xF;
  1395.             B2 = (ToTemp[i])    & 0xF;
  1396.  
  1397.             if(R1 > R2)
  1398.                 R1--;
  1399.  
  1400.             if(G1 > G2)
  1401.                 G1--;
  1402.  
  1403.             if(B1 > B2)
  1404.                 B1--;
  1405.  
  1406.             if(R1 < R2)
  1407.                 R1++;
  1408.  
  1409.             if(G1 < G2)
  1410.                 G1++;
  1411.  
  1412.             if(B1 < B2)
  1413.                 B1++;
  1414.  
  1415.             FromTemp[i] = (R1 << 8) | (G1 << 4) | B1;
  1416.         }
  1417.  
  1418.         Delay(2);
  1419.  
  1420.         LoadRGB4(VPort,FromTemp,NumColours);
  1421.     }
  1422. }
  1423.  
  1424.     /* Random(LONG MaxValue)
  1425.      *
  1426.      *    Small random number generator.
  1427.      */
  1428.  
  1429. ULONG __regargs
  1430. Random(LONG MaxValue)
  1431. {
  1432.     STATIC ULONG RandomSeed = 213567657;
  1433.  
  1434.     RandomSeed = RandomSeed * custom . vhposr + 8754331;
  1435.  
  1436.     return(RandomSeed % MaxValue);
  1437. }
  1438.  
  1439.     /* CreateAllCoordsGadgets():
  1440.      *
  1441.      *    Creates all gadgets required by the coordinates control panel.
  1442.      */
  1443.  
  1444. struct Gadget *
  1445. CreateAllCoordsGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge)
  1446. {
  1447.     struct Gadget        *Gadget;
  1448.     struct NewGadget     NewGadget;
  1449.     UWORD             Counter = 0;
  1450.     UBYTE             Buffer[40];
  1451.  
  1452.     if(Gadget = CreateContext(GadgetList))
  1453.     {
  1454.         NewGadget . ng_Width        = COORDS_WIDTH - 20;
  1455.         NewGadget . ng_Height        = 14;
  1456.         NewGadget . ng_GadgetText    = "Real Part (X-Coordinate)";
  1457.         NewGadget . ng_TextAttr        = &DefaultFont;
  1458.         NewGadget . ng_VisualInfo    = VisualInfo;
  1459.         NewGadget . ng_GadgetID        = Counter;
  1460.         NewGadget . ng_Flags        = PLACETEXT_ABOVE;
  1461.         NewGadget . ng_LeftEdge        = 10;
  1462.         NewGadget . ng_TopEdge        = 2 + TopEdge + 14;
  1463.  
  1464.         sprintf(Buffer,"%g",MinReal);
  1465.  
  1466.         GadgetArray[Counter++] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
  1467.             GTST_MaxChars,        40,
  1468.             GTST_String,        Buffer,
  1469.             STRINGA_Justification,    STRINGCENTER,
  1470.         TAG_DONE);
  1471.  
  1472.         BailOut();
  1473.  
  1474.         NewGadget . ng_GadgetText    = "Imaginary Part (Y-Coordinate)";
  1475.         NewGadget . ng_GadgetID        = Counter;
  1476.         NewGadget . ng_TopEdge        = Gadget -> TopEdge + Gadget -> Height + 4 + 15;
  1477.  
  1478.         sprintf(Buffer,"%g",MinImaginary);
  1479.  
  1480.         BailOut();
  1481.  
  1482.         GadgetArray[Counter++] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
  1483.             GTST_MaxChars,        40,
  1484.             GTST_String,        Buffer,
  1485.             STRINGA_Justification,    STRINGCENTER,
  1486.         TAG_DONE);
  1487.  
  1488.         NewGadget . ng_GadgetText    = "Width & Height";
  1489.         NewGadget . ng_GadgetID        = Counter;
  1490.         NewGadget . ng_TopEdge        = Gadget -> TopEdge + Gadget -> Height + 4 + 15;
  1491.  
  1492.         sprintf(Buffer,"%g",RealWidth);
  1493.  
  1494.         BailOut();
  1495.  
  1496.         GadgetArray[Counter++] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
  1497.             GTST_MaxChars,        40,
  1498.             GTST_String,        Buffer,
  1499.             STRINGA_Justification,    STRINGCENTER,
  1500.         TAG_DONE);
  1501.  
  1502.         NewGadget . ng_Width        = 68;
  1503.         NewGadget . ng_Height        = 12;
  1504.         NewGadget . ng_GadgetText    = "Accept";
  1505.         NewGadget . ng_GadgetID        = Counter;
  1506.         NewGadget . ng_Flags        = 0;
  1507.         NewGadget . ng_TopEdge        = COORDS_HEIGHT - 3 - NewGadget . ng_Height;
  1508.  
  1509.         BailOut();
  1510.  
  1511.         GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  1512.             TAG_DONE);
  1513.  
  1514.         NewGadget . ng_GadgetText    = "Cancel";
  1515.         NewGadget . ng_GadgetID        = Counter;
  1516.         NewGadget . ng_LeftEdge        = COORDS_WIDTH - 10 - NewGadget . ng_Width;
  1517.  
  1518.         BailOut();
  1519.  
  1520.         GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  1521.             TAG_DONE);
  1522.     }
  1523.  
  1524.     return(Gadget);
  1525. }
  1526.  
  1527.     /* CreateAllPaletteGadgets():
  1528.      *
  1529.      *    Creates all gadgets required by the palette control panel.
  1530.      */
  1531.  
  1532. struct Gadget *
  1533. CreateAllPaletteGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge)
  1534. {
  1535.     struct Gadget        *Gadget;
  1536.     struct NewGadget     NewGadget;
  1537.     UWORD             Counter = 0;
  1538.  
  1539.     if(Gadget = CreateContext(GadgetList))
  1540.     {
  1541.         NewGadget . ng_Width        = 60;
  1542.         NewGadget . ng_Height        = 12;
  1543.         NewGadget . ng_GadgetText    = "Red  ";
  1544.         NewGadget . ng_TextAttr        = &DefaultFont;
  1545.         NewGadget . ng_VisualInfo    = VisualInfo;
  1546.         NewGadget . ng_GadgetID        = Counter;
  1547.         NewGadget . ng_Flags        = PLACETEXT_LEFT;
  1548.         NewGadget . ng_LeftEdge        = 18 + 8 * strlen(NewGadget . ng_GadgetText);
  1549.         NewGadget . ng_TopEdge        = 1 + TopEdge;
  1550.  
  1551.         GadgetArray[Counter++] = Gadget = CreateGadget(SLIDER_KIND,Gadget,&NewGadget,
  1552.             GTSL_Min,        0,
  1553.             GTSL_Max,        (1 << Depth) - 3,
  1554.             GTSL_Level,        RedLevel,
  1555.         TAG_DONE);
  1556.  
  1557.         NewGadget . ng_GadgetText    = "Green";
  1558.         NewGadget . ng_GadgetID        = Counter;
  1559.         NewGadget . ng_TopEdge        = Gadget -> TopEdge + Gadget -> Height + 3;
  1560.  
  1561.         BailOut();
  1562.  
  1563.         GadgetArray[Counter++] = Gadget = CreateGadget(SLIDER_KIND,Gadget,&NewGadget,
  1564.             GTSL_Min,        0,
  1565.             GTSL_Max,        (1 << Depth) - 3,
  1566.             GTSL_Level,        GreenLevel,
  1567.         TAG_DONE);
  1568.  
  1569.         NewGadget . ng_GadgetText    = "Blue ";
  1570.         NewGadget . ng_GadgetID        = Counter;
  1571.         NewGadget . ng_TopEdge        = Gadget -> TopEdge + Gadget -> Height + 3;
  1572.  
  1573.         BailOut();
  1574.  
  1575.         GadgetArray[Counter++] = Gadget = CreateGadget(SLIDER_KIND,Gadget,&NewGadget,
  1576.             GTSL_Min,        0,
  1577.             GTSL_Max,        (1 << Depth) - 3,
  1578.             GTSL_Level,        BlueLevel,
  1579.         TAG_DONE);
  1580.     }
  1581.  
  1582.     return(Gadget);
  1583. }
  1584.  
  1585.     /* CreateAllScrollGadgets():
  1586.      *
  1587.      *    Creates all the gadgets required by the scroll amount
  1588.      *    control panel.
  1589.      */
  1590.  
  1591. struct Gadget *
  1592. CreateAllScrollGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge)
  1593. {
  1594.     struct Gadget        *Gadget;
  1595.     struct NewGadget     NewGadget;
  1596.     UWORD             Counter = 0;
  1597.  
  1598.     if(Gadget = CreateContext(GadgetList))
  1599.     {
  1600.         NewGadget . ng_Width        = 44;
  1601.         NewGadget . ng_Height        = 14;
  1602.         NewGadget . ng_GadgetText    = "Scroll Amount";
  1603.         NewGadget . ng_TextAttr        = &DefaultFont;
  1604.         NewGadget . ng_VisualInfo    = VisualInfo;
  1605.         NewGadget . ng_GadgetID        = Counter;
  1606.         NewGadget . ng_Flags        = 0;
  1607.         NewGadget . ng_LeftEdge        = (strlen(NewGadget . ng_GadgetText) + 2) * 8 + 1;
  1608.         NewGadget . ng_TopEdge        = 1 + TopEdge;
  1609.  
  1610.         GadgetArray[Counter++] = Gadget = CreateGadget(INTEGER_KIND,Gadget,&NewGadget,
  1611.             GTIN_MaxChars,    3,
  1612.             GTIN_Number,    (LONG)MaxScroll,
  1613.         TAG_DONE);
  1614.  
  1615.         NewGadget . ng_Width        = 52;
  1616.         NewGadget . ng_Height        = 12;
  1617.         NewGadget . ng_GadgetText    = "Accept";
  1618.         NewGadget . ng_GadgetID        = Counter;
  1619.         NewGadget . ng_Flags        = 0;
  1620.         NewGadget . ng_LeftEdge        = 10;
  1621.         NewGadget . ng_TopEdge        = SCROLL_HEIGHT - 3 - NewGadget . ng_Height;
  1622.  
  1623.         BailOut();
  1624.  
  1625.         GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  1626.             TAG_DONE);
  1627.  
  1628.         NewGadget . ng_GadgetText    = "Cancel";
  1629.         NewGadget . ng_GadgetID        = Counter;
  1630.         NewGadget . ng_LeftEdge        = SCROLL_WIDTH - 10 - NewGadget . ng_Width;
  1631.  
  1632.         BailOut();
  1633.  
  1634.         GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  1635.             TAG_DONE);
  1636.     }
  1637.  
  1638.     return(Gadget);
  1639. }
  1640.  
  1641.     /* InfoText():
  1642.      *
  1643.      *    Renders a small position and size information text into
  1644.      *    the left bottom corner of the screen.
  1645.      */
  1646.  
  1647. VOID
  1648. InfoText()
  1649. {
  1650.     struct TextFont    *OldFont;
  1651.     UBYTE         Buffer[80];
  1652.     WORD         i;
  1653.     struct RastPort    *RPort = Window -> RPort;
  1654.  
  1655.     BlockWindow();
  1656.  
  1657.     OldFont = RPort -> Font;
  1658.  
  1659.     SetFont(RPort,&DigitFont);
  1660.     SetAPen(RPort,1);
  1661.  
  1662.     sprintf(Buffer,"(/%1.04e )/%1.04e %1.04e*%1.04e",MinReal,MinImaginary,RealWidth,ImaginaryHeight);
  1663.  
  1664.     for(i = 0 ; i < strlen(Buffer) ; i++)
  1665.     {
  1666.         if(Buffer[i] == 'e')
  1667.             Buffer[i] = '$';
  1668.     }
  1669.  
  1670.     SetDrMd(RPort,JAM1);
  1671.  
  1672.     Move(RPort,1,Window -> Height - 2);
  1673.     Text(RPort,Buffer,strlen(Buffer));
  1674.  
  1675.     SetFont(RPort,OldFont);
  1676.     SetDrMd(RPort,JAM2);
  1677. }
  1678.  
  1679.     /* CalculateFrames():
  1680.      *
  1681.      *    Precalculates the number of pictures to be generated
  1682.      *    when zooming to a specific location in the Mandelbrot
  1683.      *    set.
  1684.      */
  1685.  
  1686. WORD
  1687. CalculateFrames(double MinReal,double MinImaginary,double Size)
  1688. {
  1689.     double    Data[3],Div,Value,FourPixels,GlobalSize,GlobalMinReal,GlobalMinImaginary;
  1690.     BYTE    i,Render;
  1691.     WORD    Count = 0;
  1692.  
  1693.     GlobalSize        = LastSize;
  1694.     GlobalMinReal        = LastMinReal;
  1695.     GlobalMinImaginary    = LastMinImaginary;
  1696.  
  1697.     do
  1698.     {
  1699.         Data[0]    = GlobalSize - Size;
  1700.         Data[1]    = MinReal - GlobalMinReal;
  1701.         Data[2] = MinImaginary - GlobalMinImaginary;
  1702.  
  1703.         Value    = fabs(Data[0]);
  1704.         Render    = FALSE;
  1705.  
  1706.         for(i = 0 ; i < 3 ; i++)
  1707.         {
  1708.             if(Data[i] != 0.0)
  1709.                 Render = TRUE;
  1710.  
  1711.             if(fabs(Data[i]) > Value)
  1712.                 Value = fabs(Data[i]);
  1713.         }
  1714.  
  1715.         if(Render)
  1716.         {
  1717.             FourPixels    = MaxScroll * (GlobalSize / (double)Screen -> Width);
  1718.             Div        = Value;
  1719.  
  1720.             if(Value > FourPixels)
  1721.                 Value = FourPixels;
  1722.  
  1723.             Div /= Value;
  1724.  
  1725.             GlobalSize        -= Data[0] / Div;
  1726.             GlobalMinReal        += Data[1] / Div;
  1727.             GlobalMinImaginary    += Data[2] / Div;
  1728.  
  1729.             Count++;
  1730.         }
  1731.     }
  1732.     while(Render);
  1733.  
  1734.     return(Count);
  1735. }
  1736.  
  1737.     /* CheckAbort():
  1738.      *
  1739.      *    Provides a safe callback routine to allow the anim
  1740.      *    player to check for a user abort.
  1741.      */
  1742.  
  1743. BYTE
  1744. CheckAbort()
  1745. {
  1746.     if(SetSignal(0,0) & (1 << Window -> UserPort -> mp_SigBit))
  1747.     {
  1748.         struct IntuiMessage    *Massage;
  1749.         ULONG             Class,Code;
  1750.  
  1751.         while(Massage = (struct IntuiMessage *)GT_GetIMsg(Window -> UserPort))
  1752.         {
  1753.             Class    = Massage -> Class;
  1754.             Code    = Massage -> Code;
  1755.  
  1756.             GT_ReplyIMsg(Massage);
  1757.  
  1758.             if((Class == IDCMP_MOUSEBUTTONS && !(Code & IECODE_UP_PREFIX)) || Class == IDCMP_VANILLAKEY)
  1759.                 return(TRUE);
  1760.         }
  1761.     }
  1762.     else
  1763.         return(FALSE);
  1764. }
  1765.  
  1766.     /* ReplayAnim():
  1767.      *
  1768.      *    Loads and replays an animation file.
  1769.      */
  1770.  
  1771. BYTE
  1772. ReplayAnim()
  1773. {
  1774.     BYTE     Success = FALSE;
  1775.     UBYTE    *DummyChar;
  1776.  
  1777.     strcpy(DummyBuffer,AnimPlayName);
  1778.  
  1779.     DummyChar = PathPart(DummyBuffer);
  1780.  
  1781.     *DummyChar = 0;
  1782.  
  1783.     if(GetFile("Replay Animation",DummyBuffer,FilePart(AnimPlayName),DummyBuffer,"~(#?.info)",FALSE))
  1784.     {
  1785.         BPTR File;
  1786.  
  1787.         if(File = Open(DummyBuffer,MODE_OLDFILE))
  1788.         {
  1789.             if(CreateBuffer())
  1790.             {
  1791.                 if(OpenPreLoadIFF(File))
  1792.                 {
  1793.                     strcpy(AnimPlayName,DummyBuffer);
  1794.  
  1795.                     SetClear(Window);
  1796.  
  1797.                     SwapBits();
  1798.  
  1799.                     Success = TRUE;
  1800.  
  1801.                     while(PlayAnim());
  1802.  
  1803.                     ClosePreLoadIFF();
  1804.                 }
  1805.                 else
  1806.                     MyEasyRequest("Continue","Could not read file\n%s.",FilePart(DummyBuffer));
  1807.  
  1808.                 SetWait(Window);
  1809.  
  1810.                 DeleteBuffer();
  1811.             }
  1812.             else
  1813.                 MyEasyRequest("Continue","Not enough memory for\ndisplay buffer.");
  1814.  
  1815.             Close(File);
  1816.         }
  1817.         else
  1818.             MyEasyRequest("Continue","Error opening file\n%s.",FilePart(DummyBuffer));
  1819.     }
  1820.  
  1821.     return(Success);
  1822. }
  1823.  
  1824.     /* RunAnim():
  1825.      *
  1826.      *    This routine calculates the single animation frames and
  1827.      *    stores them in the anim file.
  1828.      */
  1829.  
  1830. VOID
  1831. RunAnim()
  1832. {
  1833.     double    Data[3],Value,Div,SomePixels;
  1834.     BYTE    Render,i;
  1835.  
  1836.     LastSize        = RealWidth;
  1837.     LastMinReal        = MinReal;
  1838.     LastMinImaginary    = MinImaginary;
  1839.  
  1840.     NewCoords = FALSE;
  1841.  
  1842.     while(AnimRunning && !NewCoords)
  1843.         Zoom();
  1844.  
  1845. /*    Coords();*/
  1846.  
  1847.     if(NewCoords)
  1848.     {
  1849.         if(!AnimOpened)
  1850.         {
  1851.             UBYTE *DummyChar;
  1852.  
  1853.             AnimRunning = FALSE;
  1854.  
  1855.             strcpy(DummyBuffer,AnimSaveName);
  1856.  
  1857.             DummyChar = PathPart(DummyBuffer);
  1858.  
  1859.             *DummyChar = 0;
  1860.  
  1861.             if(GetFile("Begin Animation",DummyBuffer,FilePart(AnimSaveName),DummyBuffer,"~(#?.info)",FALSE))
  1862.             {
  1863.                 if(Frame)
  1864.                 {
  1865.                     WORD    X,Y,Width;
  1866.                     double    Pixel;
  1867.  
  1868.                     Pixel    = LastSize / (double)Screen -> Width;
  1869.  
  1870.                     X    = (WORD)(fabs(LastMinReal - MainMinReal) / Pixel);
  1871.                     Y    = (WORD)(fabs(LastMinImaginary - MainMinImaginary) / Pixel);
  1872.                     Width    = (WORD)(MainRealWidth / Pixel);
  1873.  
  1874.                     if(X || Y || Width != Screen -> Width)
  1875.                     {
  1876.                         SetAPen(Window -> RPort,1);
  1877.                         DrawSquare(Window -> RPort,X,Y,Width);
  1878.                     }
  1879.                 }
  1880.  
  1881.                 if(Include)
  1882.                     InfoText();
  1883.  
  1884.                 if(AnimOpened = AnimOpen(DummyBuffer,VPort,RPort))
  1885.                 {
  1886.                     if(!ThisProcess -> pr_CLI)
  1887.                         PutDiskObject(DummyBuffer,&AnimIcon);
  1888.  
  1889.                     OffMenu(Window,FULLMENUNUM(0, 0,0));
  1890.                     OffMenu(Window,FULLMENUNUM(0, 1,0));
  1891.                     OffMenu(Window,FULLMENUNUM(0, 2,0));
  1892.                     OffMenu(Window,FULLMENUNUM(0, 8,0));
  1893.                     OnMenu (Window,FULLMENUNUM(0, 9,0));
  1894.                     OffMenu(Window,FULLMENUNUM(0,11,0));
  1895.                     OffMenu(Window,FULLMENUNUM(0,12,0));
  1896.                     OffMenu(Window,FULLMENUNUM(0,14,0));
  1897.  
  1898.                     OffMenu(Window,FULLMENUNUM(1, 0,0));
  1899.                     OffMenu(Window,FULLMENUNUM(1, 1,0));
  1900.                     OffMenu(Window,FULLMENUNUM(1, 2,0));
  1901.                     OffMenu(Window,FULLMENUNUM(1, 5,0));
  1902.                     OffMenu(Window,FULLMENUNUM(1, 7,0));
  1903.                     OffMenu(Window,FULLMENUNUM(1, 8,0));
  1904.                     OffMenu(Window,FULLMENUNUM(1,10,0));
  1905.  
  1906.                     AnimRunning = TRUE;
  1907.  
  1908.                     strcpy(AnimSaveName,DummyBuffer);
  1909.                 }
  1910.             }
  1911.         }
  1912.  
  1913.         if(AnimRunning)
  1914.         {
  1915.             RealWidth        = LastSize;
  1916.             ImaginaryHeight        = LastSize;
  1917.  
  1918.             MinReal            = LastMinReal;
  1919.             MinImaginary        = LastMinImaginary;
  1920.  
  1921.             LastSize        = MainRealWidth;
  1922.             LastMinReal        = MainMinReal;
  1923.             LastMinImaginary    = MainMinImaginary;
  1924.  
  1925.             do
  1926.             {
  1927.                 Data[0]    = RealWidth - LastSize;
  1928.                 Data[1]    = LastMinReal - MinReal;
  1929.                 Data[2] = LastMinImaginary - MinImaginary;
  1930.  
  1931.                 Value    = fabs(Data[0]);
  1932.                 Render    = FALSE;
  1933.  
  1934.                 for(i = 0 ; i < 3 ; i++)
  1935.                 {
  1936.                     if(Data[i] != 0.0)
  1937.                         Render = TRUE;
  1938.  
  1939.                     if(fabs(Data[i]) > Value)
  1940.                         Value = fabs(Data[i]);
  1941.                 }
  1942.  
  1943.                 if(Render)
  1944.                 {
  1945.                     SomePixels    = MaxScroll * (RealWidth / (double)Screen -> Width);
  1946.                     Div        = Value;
  1947.  
  1948.                     if(Value > SomePixels)
  1949.                         Value = SomePixels;
  1950.  
  1951.                     Div /= Value;
  1952.  
  1953.                     RealWidth    -= Data[0] / Div;
  1954.                     ImaginaryHeight    -= Data[0] / Div;
  1955.                     MinReal        += Data[1] / Div;
  1956.                     MinImaginary    += Data[2] / Div;
  1957.  
  1958.                     RealStep    = RealWidth / (double)Window -> Width;
  1959.                     ImaginaryStep    = ImaginaryHeight / (double)Window -> Height;
  1960.  
  1961.                     AreaActive    = FALSE;
  1962.                     Running        = TRUE;
  1963.  
  1964.                     FullPicture    = TRUE;
  1965.  
  1966.                     SetRast(Window -> RPort,0);
  1967.  
  1968.                     Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,0,0,Window -> Width >> 1,Window -> Height >> 1);
  1969.                     Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,Window -> Width >> 1,0,Window -> Width >> 1,Window -> Height >> 1);
  1970.  
  1971.                     Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,0,Window -> Height >> 1,Window -> Width >> 1,Window -> Height >> 1);
  1972.                     Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,Window -> Width >> 1,Window -> Height >> 1,Window -> Width >> 1,Window -> Height >> 1);
  1973.  
  1974.                     if(FullPicture)
  1975.                     {
  1976.                         BlockWindow();
  1977.  
  1978.                         if(Frame)
  1979.                         {
  1980.                             WORD    X,Y,Width;
  1981.                             double    Pixel;
  1982.  
  1983.                             Pixel    = RealWidth / (double)Screen -> Width;
  1984.  
  1985.                             X    = (WORD)(fabs(MinReal - LastMinReal) / Pixel);
  1986.                             Y    = (WORD)(fabs(MinImaginary - LastMinImaginary) / Pixel);
  1987.                             Width    = (WORD)(LastSize / Pixel);
  1988.  
  1989.                             if(X || Y || Width != Screen -> Width)
  1990.                             {
  1991.                                 SetAPen(Window -> RPort,1);
  1992.                                 DrawSquare(Window -> RPort,X,Y,Width);
  1993.                             }
  1994.                         }
  1995.  
  1996.                         if(Include)
  1997.                             InfoText();
  1998.  
  1999.                         AnimAdd(RPort);
  2000.  
  2001.                         ReleaseWindow();
  2002.                     }
  2003.  
  2004.                     if(!AnimRunning)
  2005.                         break;
  2006.                 }
  2007.             }
  2008.             while(Render);
  2009.  
  2010.             if(!Render)
  2011.             {
  2012.                 MoveScreen(Screen,0,-Screen -> TopEdge);
  2013.  
  2014.                 ScreenToFront(Screen);
  2015.  
  2016.                 ActivateWindow(Window);
  2017.  
  2018.                 Delay(10);
  2019.  
  2020.                 DisplayBeep(Screen);
  2021.             }
  2022.         }
  2023.  
  2024.         AreaActive    = FALSE;
  2025.         Running        = FALSE;
  2026.     }
  2027.     else
  2028.         StopAnim();
  2029. }
  2030.  
  2031.     /* StopAnim():
  2032.      *
  2033.      *    Stops the animation generation.
  2034.      */
  2035.  
  2036. VOID
  2037. StopAnim()
  2038. {
  2039.     if(AnimRunning)
  2040.     {
  2041.         AnimRunning = FALSE;
  2042.  
  2043.         OnMenu (Window,FULLMENUNUM(0, 0,0));
  2044.         OnMenu (Window,FULLMENUNUM(0, 1,0));
  2045.         OnMenu (Window,FULLMENUNUM(0, 2,0));
  2046.         OnMenu (Window,FULLMENUNUM(0, 8,0));
  2047.         OffMenu(Window,FULLMENUNUM(0, 9,0));
  2048.         OnMenu (Window,FULLMENUNUM(0,11,0));
  2049.         OnMenu (Window,FULLMENUNUM(0,12,0));
  2050.         OnMenu (Window,FULLMENUNUM(0,14,0));
  2051.  
  2052.         OnMenu (Window,FULLMENUNUM(1, 0,0));
  2053.         OnMenu (Window,FULLMENUNUM(1, 1,0));
  2054.         OnMenu (Window,FULLMENUNUM(1, 2,0));
  2055.         OnMenu (Window,FULLMENUNUM(1, 5,0));
  2056.         OnMenu (Window,FULLMENUNUM(1, 7,0));
  2057.         OnMenu (Window,FULLMENUNUM(1, 8,0));
  2058.         OnMenu (Window,FULLMENUNUM(1,10,0));
  2059.  
  2060.         AnimClose();
  2061.  
  2062.         AnimOpened = FALSE;
  2063.     }
  2064. }
  2065.  
  2066.     /* Coords():
  2067.      *
  2068.      *    This routine implements the coordinates control panel.
  2069.      */
  2070.  
  2071. VOID
  2072. Coords()
  2073. {
  2074.     struct Gadget    *GadgetList = NULL;
  2075.     struct Gadget    *GadgetArray[5];
  2076.     struct Window    *CoordsWindow;
  2077.  
  2078.     double         TempMinReal,TempMinImaginary,
  2079.              TempRealWidth,TempImaginaryHeight;
  2080.  
  2081.     BYTE         MadeChanges = FALSE;
  2082.  
  2083.     TempMinReal        = MinReal;
  2084.     TempMinImaginary    = MinImaginary;
  2085.     TempRealWidth        = RealWidth;
  2086.     TempImaginaryHeight    = ImaginaryHeight;
  2087.  
  2088.     if(CreateAllCoordsGadgets(&GadgetArray[0],&GadgetList,VisualInfo,Screen -> WBorTop + Screen -> Font -> ta_YSize + 1))
  2089.     {
  2090.         if(CoordsWindow = OpenWindowTags(NULL,
  2091.             WA_Width,    COORDS_WIDTH,
  2092.             WA_Height,    COORDS_HEIGHT,
  2093.             WA_Top,        (Screen -> Height - COORDS_HEIGHT) >> 1,
  2094.             WA_Left,    (Screen -> Width - COORDS_WIDTH) >> 1,
  2095.             WA_Activate,    TRUE,
  2096.             WA_DragBar,    FALSE,
  2097.             WA_CloseGadget,    TRUE,
  2098.             WA_RMBTrap,    TRUE,
  2099.             WA_IDCMP,    IDCMP_CLOSEWINDOW | BUTTONIDCMP | STRINGIDCMP,
  2100.             WA_Title,    "Coordinates",
  2101.             WA_CustomScreen,Screen,
  2102.         TAG_DONE))
  2103.         {
  2104.             struct IntuiMessage    *Massage;
  2105.             ULONG             Class;
  2106.             struct Gadget        *Gadget;
  2107.             BYTE             Terminated = FALSE;
  2108.  
  2109.             AddGList(CoordsWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
  2110.             RefreshGList(GadgetList,CoordsWindow,NULL,(UWORD)-1);
  2111.             GT_RefreshWindow(CoordsWindow,NULL);
  2112.  
  2113.             ActivateGadget(GadgetArray[0],CoordsWindow,NULL);
  2114.  
  2115.             while(!Terminated)
  2116.             {
  2117.                 WaitPort(CoordsWindow -> UserPort);
  2118.  
  2119.                 while(!Terminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(CoordsWindow -> UserPort)))
  2120.                 {
  2121.                     Class    = Massage -> Class;
  2122.                     Gadget    = (struct Gadget *)Massage -> IAddress;
  2123.  
  2124.                     GT_ReplyIMsg(Massage);
  2125.  
  2126.                     if(Class == IDCMP_CLOSEWINDOW)
  2127.                         Terminated = TRUE;
  2128.  
  2129.                     if(Class == IDCMP_GADGETUP)
  2130.                     {
  2131.                         double Value;
  2132.  
  2133.                         switch(Gadget -> GadgetID)
  2134.                         {
  2135.                             case 3:    if(MadeChanges)
  2136.                                 {
  2137.                                     MinReal        = TempMinReal;
  2138.                                     MinImaginary    = TempMinImaginary;
  2139.                                     RealWidth    = TempRealWidth;
  2140.                                     ImaginaryHeight    = TempImaginaryHeight;
  2141.  
  2142.                                     RealStep    = RealWidth / (double)Window -> Width;
  2143.                                     ImaginaryStep    = ImaginaryHeight / (double)Window -> Height;
  2144.  
  2145.                                     MainMinReal        = MinReal;
  2146.                                     MainMinImaginary    = MinImaginary;
  2147.                                     MainRealWidth        = RealWidth;
  2148.                                     MainImaginaryHeight    = ImaginaryHeight;
  2149.  
  2150.                                     NewCoords    = TRUE;
  2151.                                     Running        = FALSE;
  2152.                                     AreaActive    = FALSE;
  2153.                                 }
  2154.  
  2155.                                 Terminated = TRUE;
  2156.                                 break;
  2157.  
  2158.                             case 4:    Terminated = TRUE;
  2159.                                 break;
  2160.  
  2161.                             default:Value = atof(((struct StringInfo *)Gadget -> SpecialInfo) -> Buffer);
  2162.  
  2163.                                 MadeChanges = TRUE;
  2164.  
  2165.                                 switch(Gadget -> GadgetID)
  2166.                                 {
  2167.                                     case 0:    TempMinReal        = Value;
  2168.                                         break;
  2169.  
  2170.                                     case 1:    TempMinImaginary    = Value;
  2171.                                         break;
  2172.  
  2173.                                     case 2:    TempRealWidth        = Value;
  2174.                                         TempImaginaryHeight    = Value;
  2175.                                         break;
  2176.                                 }
  2177.  
  2178.                                 break;
  2179.                         }
  2180.                     }
  2181.                 }
  2182.             }
  2183.  
  2184.             CloseWindow(CoordsWindow);
  2185.         }
  2186.     }
  2187.  
  2188.     FreeGadgets(GadgetList);
  2189. }
  2190.  
  2191.     /* Palette():
  2192.      *
  2193.      *    This routine implements the palette control panel.
  2194.      */
  2195.  
  2196. VOID
  2197. Palette()
  2198. {
  2199.     struct Gadget    *GadgetList = NULL;
  2200.     struct Gadget    *GadgetArray[3];
  2201.     struct Window    *Window;
  2202.  
  2203.     if(CreateAllPaletteGadgets(&GadgetArray[0],&GadgetList,VisualInfo,Screen -> WBorTop + Screen -> Font -> ta_YSize + 1))
  2204.     {
  2205.         if(Window = OpenWindowTags(NULL,
  2206.             WA_Width,    PALETTE_WIDTH,
  2207.             WA_Height,    PALETTE_HEIGHT,
  2208.  
  2209.             WA_Top,        (Screen -> Height - PALETTE_HEIGHT) >> 1,
  2210.             WA_Left,    (Screen -> Width - PALETTE_WIDTH) >> 1,
  2211.  
  2212.             WA_Activate,    TRUE,
  2213.             WA_DragBar,    TRUE,
  2214.             WA_CloseGadget, TRUE,
  2215.             WA_RMBTrap,    TRUE,
  2216.  
  2217.             WA_IDCMP,    IDCMP_CLOSEWINDOW | SLIDERIDCMP,
  2218.             WA_CustomScreen,Screen,
  2219.  
  2220.             WA_Title,    "Palette",
  2221.         TAG_DONE))
  2222.         {
  2223.             struct IntuiMessage    *Massage;
  2224.             ULONG             Class,Code;
  2225.             struct Gadget        *Gadget;
  2226.             BYTE             Terminated = FALSE;
  2227.             WORD             i,Width = 120 / ((1 << Depth) - 2),Top = Screen -> WBorTop + Screen -> Font -> ta_YSize + 2;
  2228.  
  2229.             AddGList(Window,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
  2230.             RefreshGList(GadgetList,Window,NULL,(UWORD)-1);
  2231.             GT_RefreshWindow(Window,NULL);
  2232.  
  2233.             for(i = 2 ; i < (1 << Depth) ; i++)
  2234.             {
  2235.                 SetAPen(Window -> RPort,i);
  2236.  
  2237.                 RectFill(Window -> RPort,111 + 8 + (i - 2) * Width,Top,111 + 8 + (i - 1) * Width - 1,Window -> Height - Window -> BorderBottom - 2);
  2238.             }
  2239.  
  2240.             if(DoCycle)
  2241.             {
  2242.                 DoCycle = FALSE;
  2243.  
  2244.                 GetScreenPalette();
  2245.  
  2246.                 FadeTo(&Screen -> ViewPort,ScreenPalette,SinPalette,1 << Depth,0,0);
  2247.             }
  2248.             else
  2249.                 DoCycle = FALSE;
  2250.  
  2251.             UseWheel = FALSE;
  2252.  
  2253.             while(!Terminated)
  2254.             {
  2255.                 WaitPort(Window -> UserPort);
  2256.  
  2257.                 while(!Terminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(Window -> UserPort)))
  2258.                 {
  2259.                     Class    = Massage -> Class;
  2260.                     Code    = Massage -> Code;
  2261.                     Gadget    = (struct Gadget *)Massage -> IAddress;
  2262.  
  2263.                     GT_ReplyIMsg(Massage);
  2264.  
  2265.                     if(Class == IDCMP_CLOSEWINDOW)
  2266.                         Terminated = TRUE;
  2267.  
  2268.                     if(Class == IDCMP_MOUSEMOVE)
  2269.                     {
  2270.                         WORD Wrap = (1 << Depth) - 2;
  2271.  
  2272.                         switch(Gadget -> GadgetID)
  2273.                         {
  2274.                             case 0:    RedLevel = Code;
  2275.                                 break;
  2276.  
  2277.                             case 1:    GreenLevel = Code;
  2278.                                 break;
  2279.  
  2280.                             case 2:    BlueLevel = Code;
  2281.                                 break;
  2282.                         }
  2283.  
  2284.                         SinPalette[0] = 0x000;
  2285.                         SinPalette[1] = 0xFFF;
  2286.  
  2287.                         for(i = 0 ; i < Wrap ; i++)
  2288.                         {
  2289.                             SinPalette[2 + i]  = Range[(RedLevel + i) % Wrap] << 8;
  2290.                             SinPalette[2 + i] |= Range[(GreenLevel + i) % Wrap] << 4;
  2291.                             SinPalette[2 + i] |= Range[(BlueLevel + i) % Wrap];
  2292.                         }
  2293.  
  2294.                         LoadRGB4(&Screen -> ViewPort,SinPalette,1 << Depth);
  2295.                     }
  2296.                 }
  2297.             }
  2298.  
  2299.             CloseWindow(Window);
  2300.         }
  2301.     }
  2302.  
  2303.     FreeGadgets(GadgetList);
  2304. }
  2305.  
  2306.     /* MaxScrollPanel():
  2307.      *
  2308.      *    This routine implements the scroll amount control panel.
  2309.      */
  2310.  
  2311. VOID
  2312. MaxScrollPanel()
  2313. {
  2314.     struct Gadget    *GadgetList = NULL;
  2315.     struct Gadget    *GadgetArray[3];
  2316.     struct Window    *ScrollWindow;
  2317.  
  2318.     if(CreateAllScrollGadgets(&GadgetArray[0],&GadgetList,VisualInfo,Screen -> WBorTop + Screen -> Font -> ta_YSize + 1))
  2319.     {
  2320.         if(ScrollWindow = OpenWindowTags(NULL,
  2321.             WA_Width,    SCROLL_WIDTH,
  2322.             WA_Height,    SCROLL_HEIGHT,
  2323.  
  2324.             WA_Top,        (Screen -> Height - SCROLL_HEIGHT) >> 1,
  2325.             WA_Left,    (Screen -> Width - SCROLL_WIDTH) >> 1,
  2326.  
  2327.             WA_Activate,    TRUE,
  2328.             WA_DragBar,    TRUE,
  2329.             WA_DepthGadget,    TRUE,
  2330.             WA_CloseGadget,    TRUE,
  2331.             WA_RMBTrap,    TRUE,
  2332.             WA_CustomScreen,Screen,
  2333.  
  2334.             WA_IDCMP,    IDCMP_CLOSEWINDOW | IDCMP_ACTIVEWINDOW | BUTTONIDCMP | INTEGERIDCMP,
  2335.  
  2336.             WA_Title,    "Set Scroll Amount",
  2337.         TAG_DONE))
  2338.         {
  2339.             struct IntuiMessage    *Massage;
  2340.             ULONG             Class;
  2341.             struct Gadget        *Gadget;
  2342.             BYTE             Terminated = FALSE;
  2343.  
  2344.             AddGList(ScrollWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
  2345.             RefreshGList(GadgetList,ScrollWindow,NULL,(UWORD)-1);
  2346.             GT_RefreshWindow(ScrollWindow,NULL);
  2347.  
  2348.             ActivateGadget(GadgetArray[0],ScrollWindow,NULL);
  2349.  
  2350.             while(!Terminated)
  2351.             {
  2352.                 WaitPort(ScrollWindow -> UserPort);
  2353.  
  2354.                 while(!Terminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(ScrollWindow -> UserPort)))
  2355.                 {
  2356.                     Class    = Massage -> Class;
  2357.                     Gadget    = (struct Gadget *)Massage -> IAddress;
  2358.  
  2359.                     GT_ReplyIMsg(Massage);
  2360.  
  2361.                     if(Class == IDCMP_CLOSEWINDOW)
  2362.                         Terminated = TRUE;
  2363.  
  2364.                     if(Class == IDCMP_ACTIVEWINDOW)
  2365.                         ActivateGadget(GadgetArray[0],ScrollWindow,NULL);
  2366.  
  2367.                     if(Class == IDCMP_GADGETUP)
  2368.                     {
  2369.                         if(Gadget -> GadgetID == 2)
  2370.                             Terminated = TRUE;
  2371.                         else
  2372.                         {
  2373.                             LONG Value = ((struct StringInfo *)GadgetArray[0] -> SpecialInfo) -> LongInt;
  2374.                             BYTE GoodValue = TRUE;
  2375.  
  2376.                             if(Value < 1)
  2377.                             {
  2378.                                 GoodValue    = FALSE;
  2379.                                 Value        = 1;
  2380.                             }
  2381.  
  2382.                             if(Value >= Screen -> Width)
  2383.                             {
  2384.                                 GoodValue    = FALSE;
  2385.                                 Value        = Screen -> Width - 1;
  2386.                             }
  2387.  
  2388.                             if(GoodValue)
  2389.                             {
  2390.                                 MaxScroll    = (double)Value;
  2391.                                 Terminated    = TRUE;
  2392.                             }
  2393.                             else
  2394.                             {
  2395.                                 GT_SetGadgetAttrs(GadgetArray[0],ScrollWindow,NULL,
  2396.                                     GTIN_Number,Value,
  2397.                                 TAG_DONE);
  2398.  
  2399.                                 DisplayBeep(Screen);
  2400.  
  2401.                                 ActivateGadget(GadgetArray[0],ScrollWindow,NULL);
  2402.                             }
  2403.                         }
  2404.                     }
  2405.                 }
  2406.             }
  2407.  
  2408.             CloseWindow(ScrollWindow);
  2409.         }
  2410.     }
  2411.  
  2412.     FreeGadgets(GadgetList);
  2413. }
  2414.  
  2415.     /* AreaZoom():
  2416.      *
  2417.      *    This routine handles the selection of an area on screen
  2418.      *    to recalculate later.
  2419.      */
  2420.  
  2421. VOID
  2422. AreaZoom()
  2423. {
  2424.     struct IntuiMessage    *Massage;
  2425.     ULONG             Class,Code;
  2426.     UWORD             X,Y,LastX,LastY;
  2427.  
  2428.     SetClear(Window);
  2429.  
  2430.     Code = NULL;
  2431.  
  2432.     Window -> Flags |= WFLG_RMBTRAP;
  2433.  
  2434.     ReportMouse(TRUE,Window);
  2435.  
  2436.     SetAPen(RPort,1);
  2437.     SetDrMd(RPort,COMPLEMENT);
  2438.  
  2439.     LastX    = Window -> MouseX;
  2440.     LastY    = Window -> MouseY;
  2441.  
  2442.     DrawLine(RPort,LastX,0,LastX,Screen -> Height - 1);
  2443.     DrawLine(RPort,0,LastY,Screen -> Width - 1,LastY);
  2444.  
  2445.     while(Code != SELECTUP)
  2446.     {
  2447.         WaitPort(Window -> UserPort);
  2448.  
  2449.         if(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  2450.         {
  2451.             Class    = Massage -> Class;
  2452.             Code    = Massage -> Code;
  2453.  
  2454.             X    = Massage -> MouseX;
  2455.             Y    = Massage -> MouseY;
  2456.  
  2457.             ReplyMsg(&Massage -> ExecMessage);
  2458.  
  2459.             if(Class == IDCMP_MOUSEMOVE)
  2460.             {
  2461.                 if(LastX != X)
  2462.                 {
  2463.                     DrawLine(RPort,LastX,0,LastX,Screen -> Height - 1);
  2464.                     DrawLine(RPort,X,0,X,Screen -> Height - 1);
  2465.                 }
  2466.  
  2467.                 if(LastY != Y)
  2468.                 {
  2469.                     DrawLine(RPort,0,LastY,Screen -> Width - 1,LastY);
  2470.                     DrawLine(RPort,0,Y,Screen -> Width - 1,Y);
  2471.                 }
  2472.  
  2473.                 LastX = X;
  2474.                 LastY = Y;
  2475.             }
  2476.  
  2477.             if(Class == IDCMP_MOUSEBUTTONS)
  2478.             {
  2479.                 if(Code == SELECTDOWN)
  2480.                 {
  2481.                     UWORD    Left,Top,Width = 0,Height = 0;
  2482.                     BYTE    DidBox = FALSE;
  2483.  
  2484.                     Left    = X;
  2485.                     Top    = Y;
  2486.  
  2487.                     DrawLine(RPort,LastX,0,LastX,Screen -> Height - 1);
  2488.                     DrawLine(RPort,0,LastY,Screen -> Width - 1,LastY);
  2489.  
  2490.                     while(Code != SELECTUP)
  2491.                     {
  2492.                         WaitPort(Window -> UserPort);
  2493.  
  2494.                         while(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  2495.                         {
  2496.                             Class    = Massage -> Class;
  2497.                             Code    = Massage -> Code;
  2498.  
  2499.                             Y    = Massage -> MouseY;
  2500.                             X    = Massage -> MouseX;
  2501.  
  2502.                             ReplyMsg(&Massage -> ExecMessage);
  2503.  
  2504.                             if(Class == IDCMP_MOUSEMOVE)
  2505.                             {
  2506.                                 if(Y > Top && X > Left)
  2507.                                 {
  2508.                                     if(DidBox)
  2509.                                     {
  2510.                                         Move(RPort,Left,Top);
  2511.                                         Draw(RPort,Left + Width - 1,Top);
  2512.                                         Draw(RPort,Left + Width - 1,Top + Height - 1);
  2513.                                         Draw(RPort,Left,Top + Height - 1);
  2514.                                         Draw(RPort,Left,Top + 1);
  2515.                                     }
  2516.  
  2517.                                     Width    = X - Left + 1;
  2518.                                     Height    = Y - Top + 1;
  2519.  
  2520.                                     Move(RPort,Left,Top);
  2521.                                     Draw(RPort,Left + Width - 1,Top);
  2522.                                     Draw(RPort,Left + Width - 1,Top + Height - 1);
  2523.                                     Draw(RPort,Left,Top + Height - 1);
  2524.                                     Draw(RPort,Left,Top + 1);
  2525.  
  2526.                                     DidBox = TRUE;
  2527.                                 }
  2528.  
  2529.                                 Code = NULL;
  2530.                             }
  2531.                         }
  2532.                     }
  2533.  
  2534.                     if(DidBox)
  2535.                     {
  2536.                         Move(RPort,Left,Top);
  2537.                         Draw(RPort,Left + Width - 1,Top);
  2538.                         Draw(RPort,Left + Width - 1,Top + Height - 1);
  2539.                         Draw(RPort,Left,Top + Height - 1);
  2540.                         Draw(RPort,Left,Top + 1);
  2541.                     }
  2542.  
  2543.                     SetDrMd(RPort,JAM1);
  2544.  
  2545.                     if(Width >= 2 && Height >= 2)
  2546.                     {
  2547.                         AreaLeft    = Left;
  2548.                         AreaTop        = Top;
  2549.  
  2550.                         AreaWidth    = Width;
  2551.                         AreaHeight    = Height;
  2552.  
  2553.                         NewCoords    = TRUE;
  2554.                         Running        = FALSE;
  2555.                         AreaActive    = TRUE;
  2556.                     }
  2557.                 }
  2558.             }
  2559.         }
  2560.     }
  2561.  
  2562.     ReportMouse(FALSE,Window);
  2563.  
  2564.     Window -> Flags &= ~WFLG_RMBTRAP;
  2565.  
  2566.     ClearPointer(Window);
  2567. }
  2568.  
  2569.     /* Zoom():
  2570.      *
  2571.      *    This routine handles the selection of an area on screen
  2572.      *    to zoom to later. Note that the area will be square.
  2573.      */
  2574.  
  2575. VOID
  2576. Zoom()
  2577. {
  2578.     struct IntuiMessage    *Massage;
  2579.     ULONG             Class,Code;
  2580.     UWORD             X,Y,LastX,LastY;
  2581.  
  2582.     SetClear(Window);
  2583.  
  2584.     Code = NULL;
  2585.  
  2586.     Window -> Flags |= WFLG_RMBTRAP;
  2587.  
  2588.     ReportMouse(TRUE,Window);
  2589.  
  2590.     SetAPen(RPort,1);
  2591.     SetDrMd(RPort,COMPLEMENT);
  2592.  
  2593.     LastX    = Window -> MouseX;
  2594.     LastY    = Window -> MouseY;
  2595.  
  2596.     DrawLine(RPort,LastX,0,LastX,Screen -> Height - 1);
  2597.     DrawLine(RPort,0,LastY,Screen -> Width - 1,LastY);
  2598.  
  2599.     while(Code != SELECTUP)
  2600.     {
  2601.         WaitPort(Window -> UserPort);
  2602.  
  2603.         if(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  2604.         {
  2605.             Class    = Massage -> Class;
  2606.             Code    = Massage -> Code;
  2607.  
  2608.             X    = Massage -> MouseX;
  2609.             Y    = Massage -> MouseY;
  2610.  
  2611.             ReplyMsg(&Massage -> ExecMessage);
  2612.  
  2613.             if(Class == IDCMP_MOUSEMOVE)
  2614.             {
  2615.                 if(LastX != X)
  2616.                 {
  2617.                     DrawLine(RPort,LastX,0,LastX,Screen -> Height - 1);
  2618.                     DrawLine(RPort,X,0,X,Screen -> Height - 1);
  2619.                 }
  2620.  
  2621.                 if(LastY != Y)
  2622.                 {
  2623.                     DrawLine(RPort,0,LastY,Screen -> Width - 1,LastY);
  2624.                     DrawLine(RPort,0,Y,Screen -> Width - 1,Y);
  2625.                 }
  2626.  
  2627.                 LastX = X;
  2628.                 LastY = Y;
  2629.             }
  2630.  
  2631.             if(Class == IDCMP_MOUSEBUTTONS)
  2632.             {
  2633.                 if(Code == SELECTDOWN)
  2634.                 {
  2635.                     UWORD    Left,Top,Width = 0,Height = 0;
  2636.                     BYTE    DidBox = FALSE;
  2637.  
  2638.                     DrawLine(RPort,LastX,0,LastX,Screen -> Height - 1);
  2639.                     DrawLine(RPort,0,LastY,Screen -> Width - 1,LastY);
  2640.  
  2641.                     Left    = X;
  2642.                     Top    = Y;
  2643.  
  2644.                     SetAPen(RPort,1);
  2645.                     SetDrMd(RPort,COMPLEMENT);
  2646.  
  2647.                     while(Code != SELECTUP)
  2648.                     {
  2649.                         WaitPort(Window -> UserPort);
  2650.  
  2651.                         while(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  2652.                         {
  2653.                             Class    = Massage -> Class;
  2654.                             Code    = Massage -> Code;
  2655.  
  2656.                             Y    = Massage -> MouseY;
  2657.  
  2658.                             ReplyMsg(&Massage -> ExecMessage);
  2659.  
  2660.                             if(Class == IDCMP_MOUSEMOVE)
  2661.                             {
  2662.                                 if(Y > Top)
  2663.                                 {
  2664.                                     if(DidBox)
  2665.                                     {
  2666.                                         Move(RPort,Left,Top);
  2667.                                         Draw(RPort,Left + Width - 1,Top);
  2668.                                         Draw(RPort,Left + Width - 1,Top + Height - 1);
  2669.                                         Draw(RPort,Left,Top + Height - 1);
  2670.                                         Draw(RPort,Left,Top + 1);
  2671.                                     }
  2672.  
  2673.                                     Width = Height = Y - Top + 1;
  2674.  
  2675.                                     Move(RPort,Left,Top);
  2676.                                     Draw(RPort,Left + Width - 1,Top);
  2677.                                     Draw(RPort,Left + Width - 1,Top + Height - 1);
  2678.                                     Draw(RPort,Left,Top + Height - 1);
  2679.                                     Draw(RPort,Left,Top + 1);
  2680.  
  2681.                                     DidBox = TRUE;
  2682.                                 }
  2683.  
  2684.                                 Code = NULL;
  2685.                             }
  2686.                         }
  2687.                     }
  2688.  
  2689.                     if(DidBox)
  2690.                     {
  2691.                         Move(RPort,Left,Top);
  2692.                         Draw(RPort,Left + Width - 1,Top);
  2693.                         Draw(RPort,Left + Width - 1,Top + Height - 1);
  2694.                         Draw(RPort,Left,Top + Height - 1);
  2695.                         Draw(RPort,Left,Top + 1);
  2696.                     }
  2697.  
  2698.                     SetDrMd(RPort,JAM1);
  2699.  
  2700.                     if(Width >= 2 && Height >= 2)
  2701.                     {
  2702.                         BYTE Val;
  2703.  
  2704.                         SetWait(Window);
  2705.  
  2706.                         if(AnimRunning)
  2707.                             Val = MyEasyRequest("Yes|Abort|No","Transition will consist\nof %ld images.\n\nDo you wish to use the\ncurrent coordinates?",CalculateFrames(MinReal + (double)Left * RealStep,MinImaginary + (double)Top * ImaginaryStep,(double)Width * RealStep));
  2708.                         else
  2709.                             Val = MyEasyRequest("Yes|No","Do you wish to use the\ncurrent coordinates?");
  2710.  
  2711.                         switch(Val)
  2712.                         {
  2713.                             case 0:    break;
  2714.  
  2715.                             case 1:    MinReal        = MinReal + (double)Left * RealStep;
  2716.                                 MinImaginary    = MinImaginary + (double)Top * ImaginaryStep;
  2717.  
  2718.                                 RealWidth    = (double)Width * RealStep;
  2719.                                 ImaginaryHeight    = (double)Height * ImaginaryStep;
  2720.  
  2721.                                 RealStep    = RealWidth / (double)Window -> Width;
  2722.                                 ImaginaryStep    = ImaginaryHeight / (double)Window -> Height;
  2723.  
  2724.                                 MainMinReal        = MinReal;
  2725.                                 MainMinImaginary    = MinImaginary;
  2726.                                 MainRealWidth        = RealWidth;
  2727.                                 MainImaginaryHeight    = ImaginaryHeight;
  2728.  
  2729.                                 NewCoords    = TRUE;
  2730.                                 Running        = FALSE;
  2731.                                 AreaActive    = FALSE;
  2732.                                 break;
  2733.  
  2734.                             case 2:    Running = FALSE;
  2735.                                 StopAnim();
  2736.                                 break;
  2737.                         }
  2738.                     }
  2739.                 }
  2740.             }
  2741.         }
  2742.     }
  2743.  
  2744.     ReportMouse(FALSE,Window);
  2745.  
  2746.     Window -> Flags &= ~WFLG_RMBTRAP;
  2747.  
  2748.     ClearPointer(Window);
  2749. }
  2750.  
  2751.     /* HandleEvent():
  2752.      *
  2753.      *    The global input event (menus, key, mouse, etc.) handler.
  2754.      */
  2755.  
  2756. VOID
  2757. HandleEvent()
  2758. {
  2759.     struct IntuiMessage    *Massage;
  2760.     struct MenuItem        *Item;
  2761.     ULONG             Class,Code,Qualifier,MenuItem,Selected;
  2762.     UBYTE            *DummyChar;
  2763.     BYTE             Waiting = FALSE;
  2764.  
  2765.     SetSignal(0,1 << Window -> UserPort -> mp_SigBit);
  2766.  
  2767.     do
  2768.     {
  2769.         while(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  2770.         {
  2771.             Class        = Massage -> Class;
  2772.             Code        = Massage -> Code;
  2773.             Qualifier    = Massage -> Qualifier;
  2774.  
  2775.             ReplyMsg(&Massage -> ExecMessage);
  2776.  
  2777.             if(Class == IDCMP_MENUVERIFY)
  2778.                 Waiting = HoldIt = TRUE;
  2779.  
  2780.             if(Class == IDCMP_VANILLAKEY)
  2781.             {
  2782.                 if(Code == '\t')
  2783.                 {
  2784.                     if(!DoCycle)
  2785.                     {
  2786.                         Forward = TRUE;
  2787.  
  2788.                         DoCycle = TRUE;
  2789.                     }
  2790.                     else
  2791.                         DoCycle = FALSE;
  2792.                 }
  2793.             }
  2794.  
  2795.             if(Class == IDCMP_RAWKEY)
  2796.             {
  2797.                 UWORD    Palette[32];
  2798.                 BYTE    AltWheel = Wheel,i;
  2799.  
  2800.                 if(Code == CURSORLEFT)
  2801.                 {
  2802.                     DoCycle = FALSE;
  2803.  
  2804.                     Palette[0] = 0x000;
  2805.                     Palette[1] = 0xFFF;
  2806.  
  2807.                     if(UseWheel)
  2808.                     {
  2809.                         if(Wheel)
  2810.                             Wheel--;
  2811.                         else
  2812.                             Wheel = 74;
  2813.  
  2814.                         for(i = 2 ; i < 32 ; i++)
  2815.                         {
  2816.                             Palette[i] = Table[AltWheel];
  2817.  
  2818.                             AltWheel = (AltWheel + 1) % 75;
  2819.                         }
  2820.                     }
  2821.                     else
  2822.                     {
  2823.                         BYTE AltAdd = Add,Wrap = (1 << Depth) - 2;
  2824.  
  2825.                         if(Add)
  2826.                             Add--;
  2827.                         else
  2828.                             Add = Wrap - 1;
  2829.  
  2830.                         for(i = 2 ; i < (1 << Depth) ; i++)
  2831.                         {
  2832.                             Palette[i] = SinPalette[AltAdd + 2];
  2833.  
  2834.                             AltAdd = (AltAdd + 1) % Wrap;
  2835.                         }
  2836.                     }
  2837.  
  2838.                     LoadRGB4(VPort,Palette,1 << Depth);
  2839.                 }
  2840.  
  2841.                 if(Code == CURSORRIGHT)
  2842.                 {
  2843.                     DoCycle = FALSE;
  2844.  
  2845.                     Palette[0] = 0x000;
  2846.                     Palette[1] = 0xFFF;
  2847.  
  2848.                     if(UseWheel)
  2849.                     {
  2850.                         Wheel = (Wheel + 1) % 75;
  2851.  
  2852.                         for(i = 2 ; i < 32 ; i++)
  2853.                         {
  2854.                             Palette[i] = Table[AltWheel];
  2855.  
  2856.                             AltWheel = (AltWheel + 1) % 75;
  2857.                         }
  2858.                     }
  2859.                     else
  2860.                     {
  2861.                         BYTE AltAdd = Add,Wrap = (1 << Depth) - 2;
  2862.  
  2863.                         Add = (Add + 1) % Wrap;
  2864.  
  2865.                         for(i = 2 ; i < (1 << Depth) ; i++)
  2866.                         {
  2867.                             Palette[i] = SinPalette[AltAdd + 2];
  2868.  
  2869.                             AltAdd = (AltAdd + 1) % Wrap;
  2870.                         }
  2871.                     }
  2872.  
  2873.                     LoadRGB4(VPort,Palette,1 << Depth);
  2874.                 }
  2875.  
  2876.                 if(Code == CURSORUP)
  2877.                 {
  2878.                     Forward = TRUE;
  2879.  
  2880.                     DoCycle = TRUE;
  2881.                 }
  2882.  
  2883.                 if(Code == CURSORDOWN)
  2884.                 {
  2885.                     Forward = FALSE;
  2886.  
  2887.                     DoCycle = TRUE;
  2888.                 }
  2889.             }
  2890.  
  2891.             if(Class == IDCMP_MENUPICK)
  2892.             {
  2893.                 Waiting = HoldIt = FALSE;
  2894.  
  2895.                 if(GotClip)
  2896.                 {
  2897.                     BltBitMap(BackupBitMap,0,0,RPort -> BitMap,(Square - 25 * 8) >> 1,(Square - 8) >> 1,8 * 25,8,0xC0,0xFF,NULL);
  2898.  
  2899.                     GotClip = FALSE;
  2900.                 }
  2901.  
  2902.                 MenuItem = Code;
  2903.  
  2904.                 while(MenuItem != MENUNULL)
  2905.                 {
  2906.                     if(Item = ItemAddress(Menu,MenuItem))
  2907.                     {
  2908.                         Selected = (ULONG)MENU_USERDATA(Item);
  2909.  
  2910.                         switch(Selected)
  2911.                         {
  2912.                             case MEN_OPEN:    BlockWindow();
  2913.  
  2914.                                     strcpy(NameBuffer,LastName);
  2915.  
  2916.                                     DummyChar = PathPart(NameBuffer);
  2917.  
  2918.                                     *DummyChar = 0;
  2919.  
  2920.                                     if(GetFile("Open Picture",NameBuffer,FilePart(LastName),NameBuffer,"~(#?.info)",FALSE))
  2921.                                     {
  2922.                                         struct IFFHandle    *Handle;
  2923.                                         struct BitMap        *BitMap;
  2924.  
  2925.                                         if(Handle = OpenImageFile(NameBuffer))
  2926.                                         {
  2927.                                             struct BitMapHeader    BitMapHeader;
  2928.                                             struct MandelInfo    TempMandelInfo;
  2929.                                             BYTE            Colours = 1 << Depth,GotImage = FALSE;
  2930.  
  2931.                                             if(ReadImageHeader(Handle,&GlobalMode,&Colours,ColourTable,&BitMapHeader,&TempMandelInfo))
  2932.                                             {
  2933.                                                 if(BitMapHeader . w == Window -> Width && BitMapHeader . h == Window -> Height)
  2934.                                                 {
  2935.                                                     if(BitMap = CreateBitMap(BitMapHeader . nPlanes,BitMapHeader . w,BitMapHeader . h))
  2936.                                                     {
  2937.                                                         if(ReadImageBody(Handle,BitMap,&BitMapHeader))
  2938.                                                         {
  2939.                                                             WORD i,Height = Screen -> Height;
  2940.  
  2941.                                                             if(GetVPModeID(&Screen -> ViewPort) & LACE)
  2942.                                                                 Height >>= 1;
  2943.  
  2944.                                                             DoCycle = FALSE;
  2945.  
  2946.                                                             GetScreenPalette();
  2947.  
  2948.                                                             FadeTo(&Screen -> ViewPort,ScreenPalette,ColourTable,1 << Depth,0,0);
  2949.  
  2950.                                                             switch(Random(6))
  2951.                                                             {
  2952.                                                                 case 0:    for(i = 0 ; i < (Square >> 1) ; i++)
  2953.                                                                     {
  2954.                                                                         WaitLine(Height);
  2955.  
  2956.                                                                         BltBitMapRastPort(BitMap,0,2 * i,      RPort,0,2 * i,      Screen -> Width,1,0xC0);
  2957.                                                                         BltBitMapRastPort(BitMap,0,Square - 1 - 2 * i,RPort,0,Square - 1 - 2 * i,Screen -> Width,1,0xC0);
  2958.                                                                     }
  2959.  
  2960.                                                                     break;
  2961.  
  2962.                                                                 case 1:    for(i = 0 ; i < (Square >> 1) ; i++)
  2963.                                                                     {
  2964.                                                                         WaitLine(Height);
  2965.  
  2966.                                                                         BltBitMapRastPort(BitMap,2 * i,0,      RPort,2 * i,0,1,      Screen -> Height,0xC0);
  2967.                                                                         BltBitMapRastPort(BitMap,Square - 1 - 2 * i,0,RPort,Square - 1 - 2 * i,0,1,Screen -> Height,0xC0);
  2968.                                                                     }
  2969.  
  2970.                                                                     break;
  2971.  
  2972.                                                                 case 2:    for(i = 0 ; i < (Square >> 1) ; i++)
  2973.                                                                     {
  2974.                                                                         WaitLine(Height);
  2975.  
  2976.                                                                         BltBitMapRastPort(BitMap,i,i,RPort,i,i,((Square >> 1) - i) * 2,1,0xC0);
  2977.                                                                         BltBitMapRastPort(BitMap,i,Square - 1 - i,RPort,i,Square - 1 - i,((Square >> 1) - i) * 2,1,0xC0);
  2978.  
  2979.                                                                         BltBitMapRastPort(BitMap,i,i,RPort,i,i,1,((Square >> 1) - i) * 2,0xC0);
  2980.                                                                         BltBitMapRastPort(BitMap,Square - 1 - i,i,RPort,Square - 1 - i,i,1,((Square >> 1) - i) * 2,0xC0);
  2981.                                                                     }
  2982.  
  2983.                                                                     break;
  2984.  
  2985.                                                                 case 3:    for(i = (Square >> 1) - 1 ; i >= 0 ; i--)
  2986.                                                                     {
  2987.                                                                         WaitLine(Height);
  2988.  
  2989.                                                                         BltBitMapRastPort(BitMap,i,i,RPort,i,i,((Square >> 1) - i) * 2,1,0xC0);
  2990.                                                                         BltBitMapRastPort(BitMap,i,Square - 1 - i,RPort,i,Square - 1 - i,((Square >> 1) - i) * 2,1,0xC0);
  2991.  
  2992.                                                                         BltBitMapRastPort(BitMap,i,i,RPort,i,i,1,((Square >> 1) - i) * 2,0xC0);
  2993.                                                                         BltBitMapRastPort(BitMap,Square - 1 - i,i,RPort,Square - 1 - i,i,1,((Square >> 1) - i) * 2,0xC0);
  2994.                                                                     }
  2995.  
  2996.                                                                     break;
  2997.  
  2998.                                                                 case 4:    for(i = 0 ; i < Square ; i++)
  2999.                                                                     {
  3000.                                                                         WaitLine(Height);
  3001.  
  3002.                                                                         BltBitMapRastPort(BitMap,      i,  0,RPort,      i,  0,1,(Square >> 1),0xC0);
  3003.                                                                         BltBitMapRastPort(BitMap,Square - 1 - i,(Square >> 1),RPort,Square - 1 - i,(Square >> 1),1,(Square >> 1),0xC0);
  3004.                                                                     }
  3005.  
  3006.                                                                     break;
  3007.  
  3008.                                                                 case 5:    for(i = 0 ; i < Square ; i++)
  3009.                                                                     {
  3010.                                                                         WaitLine(Height);
  3011.  
  3012.                                                                         BltBitMapRastPort(BitMap,  0,      i,RPort,  0,      i,(Square >> 1),1,0xC0);
  3013.                                                                         BltBitMapRastPort(BitMap,(Square >> 1),Square - 1 - i,RPort,(Square >> 1),Square - 1 - i,(Square >> 1),1,0xC0);
  3014.                                                                     }
  3015.  
  3016.                                                                     break;
  3017.                                                             }
  3018.  
  3019.                                                             Wheel = 0;
  3020.  
  3021.                                                             for(i = 0 ; i < 75 ; i++)
  3022.                                                             {
  3023.                                                                 if(ColourTable[2] == Table[i])
  3024.                                                                 {
  3025.                                                                     Wheel = i;
  3026.                                                                     break;
  3027.                                                                 }
  3028.                                                             }
  3029.  
  3030.                                                             if(TempMandelInfo . Iterations)
  3031.                                                             {
  3032.                                                                 MainMinReal        = MinReal        = TempMandelInfo . MinReal;
  3033.                                                                 MainMinImaginary    = MinImaginary        = TempMandelInfo . MinImaginary;
  3034.                                                                 MainRealWidth        = RealWidth        = TempMandelInfo . RealWidth;
  3035.                                                                 MainImaginaryHeight    = ImaginaryHeight    = TempMandelInfo . ImaginaryHeight;
  3036.                                                                 MaxIteration                    = TempMandelInfo . Iterations;
  3037.  
  3038.                                                                 IterationSetup();
  3039.  
  3040.                                                                 RealStep    = RealWidth / (double)Window -> Width;
  3041.                                                                 ImaginaryStep    = ImaginaryHeight / (double)Window -> Height;
  3042.                                                             }
  3043.                                                             else
  3044.                                                                 MyEasyRequest("Continue","Could not read image\ncoordinates, previous values\nremain untouched.");
  3045.  
  3046.                                                             strcpy(LastName,NameBuffer);
  3047.  
  3048.                                                             Running = FALSE;
  3049.  
  3050.                                                             AreaActive = FALSE;
  3051.  
  3052.                                                             GotImage = TRUE;
  3053.                                                         }
  3054.                                                         else
  3055.                                                             MyEasyRequest("Continue","Error reading file\n%s.",FilePart(NameBuffer));
  3056.  
  3057.                                                         DeleteBitMap(BitMap);
  3058.                                                     }
  3059.                                                     else
  3060.                                                         MyEasyRequest("Continue","Not enough memory!");
  3061.                                                 }
  3062.                                                 else
  3063.                                                 {
  3064.                                                     if(BitMapHeader . w == BitMapHeader . h && !(BitMapHeader . h % 4))
  3065.                                                     {
  3066.                                                         if(BitMap = CreateBitMap(BitMapHeader . nPlanes,BitMapHeader . w,BitMapHeader . h))
  3067.                                                         {
  3068.                                                             if(ReadImageBody(Handle,BitMap,&BitMapHeader))
  3069.                                                             {
  3070.                                                                 WORD i;
  3071.  
  3072.                                                                 Wheel = 0;
  3073.  
  3074.                                                                 for(i = 0 ; i < 75 ; i++)
  3075.                                                                 {
  3076.                                                                     if(ColourTable[2] == Table[i])
  3077.                                                                     {
  3078.                                                                         Wheel = i;
  3079.                                                                         break;
  3080.                                                                     }
  3081.                                                                 }
  3082.  
  3083.                                                                 if(TempMandelInfo . Iterations)
  3084.                                                                 {
  3085.                                                                     MainMinReal        = MinReal        = TempMandelInfo . MinReal;
  3086.                                                                     MainMinImaginary    = MinImaginary        = TempMandelInfo . MinImaginary;
  3087.                                                                     MainRealWidth        = RealWidth        = TempMandelInfo . RealWidth;
  3088.                                                                     MainImaginaryHeight    = ImaginaryHeight    = TempMandelInfo . ImaginaryHeight;
  3089.                                                                     MaxIteration                    = TempMandelInfo . Iterations;
  3090.  
  3091.                                                                     RealStep        = RealWidth / (double)Window -> Width;
  3092.                                                                     ImaginaryStep        = ImaginaryHeight / (double)Window -> Height;
  3093.                                                                 }
  3094.                                                                 else
  3095.                                                                     MyEasyRequest("Continue","Could not read image\ncoordinates, previous values\nremain untouched.");
  3096.  
  3097.                                                                 strcpy(LastName,NameBuffer);
  3098.  
  3099.                                                                 Running        = FALSE;
  3100.                                                                 AreaActive    = FALSE;
  3101.                                                                 NewMode        = TRUE;
  3102.                                                                 DoCycle        = FALSE;
  3103.  
  3104.                                                                 GlobalBitMap    = BitMap;
  3105.                                                                 GlobalHeader    = BitMapHeader;
  3106.                                                             }
  3107.                                                             else
  3108.                                                             {
  3109.                                                                 MyEasyRequest("Continue","Error reading file\n%s.",FilePart(NameBuffer));
  3110.  
  3111.                                                                 DeleteBitMap(BitMap);
  3112.                                                             }
  3113.                                                         }
  3114.                                                         else
  3115.                                                             MyEasyRequest("Continue","Not enough memory!");
  3116.                                                     }
  3117.                                                     else
  3118.                                                         MyEasyRequest("Continue","Picture has wrong size!");
  3119.                                                 }
  3120.                                             }
  3121.                                             else
  3122.                                                 MyEasyRequest("Continue","Error reading file\n%s.",FilePart(NameBuffer));
  3123.  
  3124.                                             CloseImageFile(Handle);
  3125.                                         }
  3126.                                         else
  3127.                                             MyEasyRequest("Continue","Could not open file\n%s.",FilePart(NameBuffer));
  3128.                                     }
  3129.  
  3130.                                     ReleaseWindow();
  3131.  
  3132.                                     break;
  3133.  
  3134.                             case MEN_SAVE:    BlockWindow();
  3135.  
  3136.                                     if(NameBuffer[0])
  3137.                                         goto SaveIt;
  3138.  
  3139.                             case MEN_SAVEAS:BlockWindow();
  3140.  
  3141.                                     strcpy(NameBuffer,LastName);
  3142.  
  3143.                                     DummyChar = PathPart(NameBuffer);
  3144.  
  3145.                                     *DummyChar = 0;
  3146.  
  3147.                                     if(GetFile("Save Picture As",NameBuffer,FilePart(LastName),NameBuffer,"~(#?.info)",TRUE))
  3148.                                     {
  3149. SaveIt:                                        MandelInfo . MinReal        = MinReal;
  3150.                                         MandelInfo . MinImaginary    = MinImaginary;
  3151.                                         MandelInfo . RealWidth        = RealWidth;
  3152.                                         MandelInfo . ImaginaryHeight    = ImaginaryHeight;
  3153.                                         MandelInfo . Iterations        = MaxIteration;
  3154.  
  3155.                                         if(!SaveBitMap(RPort -> BitMap,&Screen -> ViewPort,0,0,Window -> Width,Window -> Height,Screen -> Width,Screen -> Height,NameBuffer,&MandelInfo))
  3156.                                             MyEasyRequest("Continue","Could not save file\n%s.",FilePart(NameBuffer));
  3157.                                         else
  3158.                                         {
  3159.                                             if(!ThisProcess -> pr_CLI)
  3160.                                                 PutDiskObject(NameBuffer,&PictureIcon);
  3161.  
  3162.                                             strcpy(LastName,NameBuffer);
  3163.                                         }
  3164.                                     }
  3165.  
  3166.                                     ReleaseWindow();
  3167.                                     break;
  3168.  
  3169.                             case MEN_PRI0:    SetTaskPri(ThisProcess,-5);
  3170.                                     break;
  3171.  
  3172.                             case MEN_PRI1:    SetTaskPri(ThisProcess,0);
  3173.                                     break;
  3174.  
  3175.                             case MEN_PRI2:    SetTaskPri(ThisProcess,5);
  3176.                                     break;
  3177.  
  3178.                             case MEN_PLAY:    BlockWindow();
  3179.  
  3180.                                     ReplayAnim();
  3181.  
  3182.                                     ReleaseWindow();
  3183.  
  3184.                                     break;
  3185.  
  3186.                             case MEN_START:    if(!AnimRunning)
  3187.                                     {
  3188.                                         Running        = FALSE;
  3189.                                         FullPicture    = FALSE;
  3190.                                         AnimRunning    = TRUE;
  3191.                                     }
  3192.  
  3193.                                     break;
  3194.  
  3195.                             case MEN_STOP:    BlockWindow();
  3196.  
  3197.                                     StopAnim();
  3198.  
  3199.                                     Running = FALSE;
  3200.  
  3201.                                     FullPicture = FALSE;
  3202.  
  3203.                                     ReleaseWindow();
  3204.  
  3205.                                     break;
  3206.  
  3207.                             case MEN_SCROLL:BlockWindow();
  3208.  
  3209.                                     MaxScrollPanel();
  3210.  
  3211.                                     ReleaseWindow();
  3212.  
  3213.                                     break;
  3214.  
  3215.                             case MEN_FRAME:    if(Item -> Flags & CHECKED)
  3216.                                         Frame = TRUE;
  3217.                                     else
  3218.                                         Frame = FALSE;
  3219.  
  3220.                                     break;
  3221.  
  3222.                             case MEN_INCLUDE:
  3223.                                     if(Item -> Flags & CHECKED)
  3224.                                         Include = TRUE;
  3225.                                     else
  3226.                                         Include = FALSE;
  3227.  
  3228.                                     break;
  3229.  
  3230.                             case MEN_RESOLUTION:
  3231.                                     NewMode = TRUE;
  3232.                                     Running = FALSE;
  3233.                                     DoCycle = FALSE;
  3234.                                     break;
  3235.  
  3236.                             case MEN_ABOUT:    BlockWindow();
  3237.  
  3238.                                     MyEasyRequest("So what?","       MandelSquare\n\nYet another Mandelbrot set\n   exploration program\n\n        Written by\n   Olaf `Olsen' Barthel\n\n     © Copyright 1991\n");
  3239.  
  3240.                                     ReleaseWindow();
  3241.                                     break;
  3242.  
  3243.                             case MEN_QUIT:    BlockWindow();
  3244.  
  3245.                                     if(MyEasyRequest("Yes|No","Do you really wish to\nleave this program?"))
  3246.                                         CloseAll(RETURN_OK);
  3247.  
  3248.                                     ReleaseWindow();
  3249.                                     break;
  3250.  
  3251.                             case MEN_ZOOM:    Zoom();
  3252.                                     break;
  3253.  
  3254.                             case MEN_CLIP:    AreaZoom();
  3255.                                     Faster = TRUE;
  3256.                                     break;
  3257.  
  3258.                             case MEN_RERUN:    AreaZoom();
  3259.                                     Faster = FALSE;
  3260.                                     break;
  3261.  
  3262.                             case MEN_PRECISE:
  3263.                                     if(Item -> Flags & CHECKED)
  3264.                                         Precise = TRUE;
  3265.                                     else
  3266.                                         Precise = FALSE;
  3267.  
  3268.                                     break;
  3269.  
  3270.                             case MEN_COORDS:BlockWindow();
  3271.                                     Coords();
  3272.                                     ReleaseWindow();
  3273.                                     break;
  3274.  
  3275.                             case MEN_PALETTE:
  3276.                                     BlockWindow();
  3277.                                     Palette();
  3278.                                     ReleaseWindow();
  3279.                                     break;
  3280.  
  3281.                             case MEN_SPEC:    DoCycle = FALSE;
  3282.  
  3283.                                     if(Item -> Flags & CHECKED)
  3284.                                         UseWheel = TRUE;
  3285.                                     else
  3286.                                         UseWheel = FALSE;
  3287.  
  3288.                                     GetScreenPalette();
  3289.  
  3290.                                     if(UseWheel)
  3291.                                         FadeTo(&Screen -> ViewPort,ScreenPalette,WheelPalette,1 << Depth,0,0);
  3292.                                     else
  3293.                                         FadeTo(&Screen -> ViewPort,ScreenPalette,SinPalette,1 << Depth,0,0);
  3294.  
  3295.                                     break;
  3296.  
  3297.                             case MEN_RUN:    Running ^= TRUE;
  3298.  
  3299.                                     if(!Running)
  3300.                                         FullPicture = FALSE;
  3301.  
  3302.                                     break;
  3303.  
  3304.                             default:    if(Selected >= 1 && Selected <= 16)
  3305.                                         MaxIteration = (1 << Selected);
  3306.  
  3307.                                     break;
  3308.                         }
  3309.  
  3310.                         MenuItem = Item -> NextSelect;
  3311.                     }
  3312.                     else
  3313.                         break;
  3314.                 }
  3315.             }
  3316.         }
  3317.  
  3318.         if(Waiting)
  3319.             WaitPort(Window -> UserPort);
  3320.     }
  3321.     while(Waiting);
  3322. }
  3323.  
  3324. #if 0
  3325.  
  3326.     /* Iterate(double RealValue,double ImaginaryValue):
  3327.      *
  3328.      *    This is the `C' version of the Iterate routine
  3329.      *    present in Iterate.asm. I've commented it out
  3330.      *    and included it only for historical reasons.
  3331.      */
  3332.  
  3333. BYTE
  3334. Iterate(double RealValue,double ImaginaryValue)
  3335. {
  3336.     double    Real = 0,Imaginary = 0,RealTemp,ImaginaryTemp;
  3337.     WORD    i = 0;
  3338.  
  3339.     for(;;)
  3340.     {
  3341.         ImaginaryTemp     = Imaginary * Imaginary;
  3342.         RealTemp    = Real * Real;
  3343.  
  3344.         if(fabs(RealTemp + ImaginaryTemp) > 4.0)
  3345.             return(Wave[i]);
  3346.  
  3347.         if(++i >= MaxIteration)
  3348.             return(0);
  3349.  
  3350.         Imaginary    = 2.0 * Real * Imaginary + ImaginaryValue;
  3351.         Real        = RealTemp - ImaginaryTemp + RealValue;
  3352.     }
  3353. }
  3354.  
  3355. #endif
  3356.  
  3357.     /* Mandelbrot():
  3358.      *
  3359.      *    The recursive image generation routine.
  3360.      */
  3361.  
  3362. VOID
  3363. Mandelbrot(double MinReal,double MinImaginary,double RealStep,double ImaginaryStep,LONG Left,LONG Top,LONG Width,LONG Height)
  3364. {
  3365.     if(SetSignal(0,0) & (1 << Window -> UserPort -> mp_SigBit))
  3366.         HandleEvent();
  3367.  
  3368.     if(Running)
  3369.     {
  3370.         BYTE Colours[4],LastColour,Ident = TRUE;
  3371.         WORD Positions[4][2],i;
  3372.  
  3373.             /* Set up pixel positions. */
  3374.  
  3375.         Positions[0][0] = Left;
  3376.         Positions[0][1] = Top;
  3377.  
  3378.         Positions[1][0] = Left + Width - 1;
  3379.         Positions[1][1] = Top;
  3380.  
  3381.         Positions[2][0] = Left + Width - 1;
  3382.         Positions[2][1] = Top + Height - 1;
  3383.  
  3384.         Positions[3][0] = Left;
  3385.         Positions[3][1] = Top + Height - 1;
  3386.  
  3387.         for(i = 0 ; i < 4 ; i++)
  3388.         {
  3389.                 /* Calculate colour values for each pixel. */
  3390.  
  3391.             Colours[i] = Iterate(MinReal + RealStep * (double)Positions[i][0],MinImaginary + ImaginaryStep * (double)Positions[i][1]);
  3392.  
  3393.                 /* Are all colour identical? */
  3394.  
  3395.             if(Ident)
  3396.             {
  3397.                 if(!i)
  3398.                     LastColour = Colours[i];
  3399.                 else
  3400.                 {
  3401.                     if(Colours[i] != LastColour)
  3402.                         Ident = FALSE;
  3403.                     else
  3404.                         LastColour = Colours[i];
  3405.                 }
  3406.             }
  3407.         }
  3408.  
  3409.             /* If all colour happen to be identical, fill the
  3410.              * are in the given colour.
  3411.              */
  3412.  
  3413.         if(Ident)
  3414.         {
  3415.                 /* If extra precision is selected, also check
  3416.                  * if all the pixels on the margin of the
  3417.                  * current square are in the same colour.
  3418.                  */
  3419.  
  3420.             if(Precise)
  3421.             {
  3422.                 WORD j,PositionBackup[4][2];
  3423.  
  3424.                 CopyMem(Positions,PositionBackup,sizeof(PositionBackup));
  3425.  
  3426.                 for(i = 0 ; i < Width - 1 ; i++)
  3427.                 {
  3428.                     PositionBackup[0][0]++;
  3429.                     PositionBackup[1][1]++;
  3430.                     PositionBackup[2][0]--;
  3431.                     PositionBackup[3][1]--;
  3432.  
  3433.                     for(j = 0 ; j < 4 ; j++)
  3434.                     {
  3435.                         if(Iterate(MinReal + RealStep * (double)PositionBackup[j][0],MinImaginary + ImaginaryStep * (double)PositionBackup[j][1]) != Colours[0])
  3436.                             goto Full;
  3437.                     }
  3438.                 }
  3439.             }
  3440.  
  3441.                 /* If necessary fill the square. */
  3442.  
  3443.             if(Colours[0])
  3444.             {
  3445.                 if(RPort -> FgPen != Colours[0])
  3446.                     SetAPen(RPort,Colours[0]);
  3447.  
  3448.                 RectFill(RPort,Left,Top,Left + Width - 1,Top + Height - 1);
  3449.             }
  3450.         }
  3451.         else
  3452.         {
  3453.                 /* If not already down at minimum level,
  3454.                  * split the square again.
  3455.                  */
  3456.  
  3457. Full:            if(Width > 2 && Height > 2)
  3458.             {
  3459.                 Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,Left,Top,Width >> 1,Height >> 1);
  3460.                 Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,Left + (Width >> 1),Top,Width >> 1,Height >> 1);
  3461.  
  3462.                 Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,Left,Top + (Height >> 1),Width >> 1,Height >> 1);
  3463.                 Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,Left + (Width >> 1),Top + (Height >> 1),Width >> 1,Height >> 1);
  3464.             }
  3465.             else
  3466.             {
  3467.                 register struct BitMap *BitMap = RPort -> BitMap;
  3468.  
  3469.                     /* Set the pixels. */
  3470.  
  3471.                 for(i = 0 ; i < 4 ; i++)
  3472.                 {
  3473.                     if(Colours[i])
  3474.                         Plot(BitMap,Positions[i][0],Positions[i][1],Colours[i]);
  3475.                 }
  3476.             }
  3477.         }
  3478.     }
  3479. }
  3480.  
  3481.     /* RunMandelbrot():
  3482.      *
  3483.      *    This is the recursive image generation driver, it
  3484.      *    remembers the time it took to generate the image and
  3485.      *    calls the recursive image generation routine.
  3486.      */
  3487.  
  3488. VOID
  3489. RunMandelbrot(double MinReal,double MaxReal,double MinImaginary,double MaxImaginary,LONG Width,LONG Height)
  3490. {
  3491.     double        RealStep,ImaginaryStep;
  3492.     UBYTE        TimeBuffer[40];
  3493.     struct timeval    TimeVal;
  3494.  
  3495.     GetTime();
  3496.  
  3497.     TimeVal = TimeRequest -> tr_time;
  3498.  
  3499.     RealStep    = (MaxReal - MinReal) / (double)Width;
  3500.     ImaginaryStep    = (MaxImaginary - MinImaginary) / (double)Height;
  3501.  
  3502.     FullPicture = TRUE;
  3503.  
  3504.     Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,0,0,Window -> Width >> 1,Window -> Height >> 1);
  3505.     Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,Window -> Width >> 1,0,Window -> Width >> 1,Window -> Height >> 1);
  3506.  
  3507.     Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,0,Window -> Height >> 1,Window -> Width >> 1,Window -> Height >> 1);
  3508.     Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,Window -> Width >> 1,Window -> Height >> 1,Window -> Width >> 1,Window -> Height >> 1);
  3509.  
  3510.     GetTime();
  3511.  
  3512.     SubTime(&TimeRequest -> tr_time,&TimeVal);
  3513.  
  3514.     BltBitMap(RPort -> BitMap,(Square - 25 * 8) >> 1,(Square - 8) >> 1,BackupBitMap,0,0,8 * 25,8,0xC0,0xFF,NULL);
  3515.  
  3516.     GotClip = TRUE;
  3517.  
  3518.     SetAPen(RPort,1);
  3519.     SetDrMd(RPort,JAM1);
  3520.  
  3521.     TimeVal = TimeRequest -> tr_time;
  3522.  
  3523.     sprintf(TimeBuffer,"Duration %2d:%02d:%02d Minutes",(TimeVal . tv_secs % 86400) / 3600,(TimeVal . tv_secs % 3600) / 60,TimeVal . tv_secs % 60);
  3524.  
  3525.     Move(RPort,(Square - 25 * 8) >> 1,((Square - 8) >> 1) + 6);
  3526.     Text(RPort,TimeBuffer,25);
  3527.  
  3528.     Running = FALSE;
  3529. }
  3530.  
  3531.     /* RunAreaMandelbrot(double RealStep,double ImaginaryStep):
  3532.      *
  3533.      *    This is the iterative image generation routine,
  3534.      *    unlike the routines above it generates the image
  3535.      *    pixel by pixel and is not limited to a square
  3536.      *    drawing area.
  3537.      */
  3538.  
  3539. VOID
  3540. RunAreaMandelbrot(double RealStep,double ImaginaryStep)
  3541. {
  3542.     double         RealValue,ImaginaryValue;
  3543.     WORD         x,y;
  3544.     UBYTE         TimeBuffer[40];
  3545.     struct BitMap    *BitMap = RPort -> BitMap;
  3546.     struct timeval     TimeVal;
  3547.     BYTE         Colour;
  3548.  
  3549.     GetTime();
  3550.  
  3551.     TimeVal = TimeRequest -> tr_time;
  3552.  
  3553.     ImaginaryValue = MinImaginary + ImaginaryStep * (double)AreaTop;
  3554.  
  3555.         /* `Faster' actually only means that before a pixel
  3556.          * is drawn the approriate spot is checked to see
  3557.          * if there is not already a pixel in place.
  3558.          */
  3559.  
  3560.     if(Faster)
  3561.     {
  3562.         for(y = 0 ; (y < AreaHeight) && Running ; y++)
  3563.         {
  3564.             RealValue = MinReal + RealStep * (double)AreaLeft;
  3565.  
  3566.             for(x = 0 ; (x < AreaWidth) && Running ; x++)
  3567.             {
  3568.                 if(!Test(BitMap,AreaLeft + x,AreaTop + y))
  3569.                 {
  3570.                     if((Colour = Iterate(RealValue,ImaginaryValue)))
  3571.                         Plot(BitMap,AreaLeft + x,AreaTop + y,Colour);
  3572.                 }
  3573.  
  3574.                 RealValue += RealStep;
  3575.  
  3576.                 if(SetSignal(0,0) & (1 << Window -> UserPort -> mp_SigBit))
  3577.                     HandleEvent();
  3578.             }
  3579.  
  3580.             ImaginaryValue += ImaginaryStep;
  3581.         }
  3582.     }
  3583.     else
  3584.     {
  3585.             /* These loops will calculate the image pixel
  3586.              * by pixel without skipping already set areas.
  3587.              * The first check insures that the drawing area
  3588.              * is as wide as the screen which means that
  3589.              * we are able to generate the pixels in fast
  3590.              * ram and to copy them to chip ram when done.
  3591.              */
  3592.  
  3593.         if(AreaWidth == Window -> Width && LineBitMap . Planes[0])
  3594.         {
  3595.             BitMap = &LineBitMap;
  3596.  
  3597.             for(y = 0 ; (y < AreaHeight) && Running ; y++)
  3598.             {
  3599.                 RealValue = MinReal + RealStep * (double)AreaLeft;
  3600.  
  3601.                 for(x = 0 ; (x < AreaWidth) && Running ; x++)
  3602.                 {
  3603.                     if((Colour = Iterate(RealValue,ImaginaryValue)))
  3604.                         Plot(BitMap,AreaLeft + x,0,Colour);
  3605.                     else
  3606.                         Plot(BitMap,AreaLeft + x,0,0);
  3607.  
  3608.                     RealValue += RealStep;
  3609.  
  3610.                     if(SetSignal(0,0) & (1 << Window -> UserPort -> mp_SigBit))
  3611.                         HandleEvent();
  3612.                 }
  3613.  
  3614.                 if(Running)
  3615.                     CopyLine(BitMap,AreaTop + y);
  3616.  
  3617.                 ImaginaryValue += ImaginaryStep;
  3618.             }
  3619.         }
  3620.         else
  3621.         {
  3622.             for(y = 0 ; (y < AreaHeight) && Running ; y++)
  3623.             {
  3624.                 RealValue = MinReal + RealStep * (double)AreaLeft;
  3625.  
  3626.                 for(x = 0 ; (x < AreaWidth) && Running ; x++)
  3627.                 {
  3628.                     if((Colour = Iterate(RealValue,ImaginaryValue)))
  3629.                         Plot(BitMap,AreaLeft + x,AreaTop + y,Colour);
  3630.  
  3631.                     RealValue += RealStep;
  3632.  
  3633.                     if(SetSignal(0,0) & (1 << Window -> UserPort -> mp_SigBit))
  3634.                         HandleEvent();
  3635.                 }
  3636.  
  3637.                 ImaginaryValue += ImaginaryStep;
  3638.             }
  3639.         }
  3640.     }
  3641.  
  3642.     GetTime();
  3643.  
  3644.     SubTime(&TimeRequest -> tr_time,&TimeVal);
  3645.  
  3646.     BltBitMap(RPort -> BitMap,(Square - 25 * 8) >> 1,(Square - 8) >> 1,BackupBitMap,0,0,8 * 25,8,0xC0,0xFF,NULL);
  3647.  
  3648.     GotClip = TRUE;
  3649.  
  3650.     SetAPen(RPort,1);
  3651.     SetDrMd(RPort,JAM1);
  3652.  
  3653.     TimeVal = TimeRequest -> tr_time;
  3654.  
  3655.     sprintf(TimeBuffer,"Duration %2d:%02d:%02d Minutes",(TimeVal . tv_secs % 86400) / 3600,(TimeVal . tv_secs % 3600) / 60,TimeVal . tv_secs % 60);
  3656.  
  3657.     Move(RPort,(Square - 25 * 8) >> 1,((Square - 8) >> 1) + 6);
  3658.     Text(RPort,TimeBuffer,25);
  3659.  
  3660.     Running = FALSE;
  3661.  
  3662.     Faster = TRUE;
  3663. }
  3664.  
  3665.     /* main():
  3666.      *
  3667.      *    The notorious main routine.
  3668.      */
  3669.  
  3670. VOID __stdargs
  3671. main()
  3672. {
  3673.     struct IFFHandle    *Handle;
  3674.     struct BitMap        *BitMap;
  3675.     BYTE             GotImage = FALSE,IsAnim = FALSE;
  3676.  
  3677.         /* Open the required resources. */
  3678.  
  3679.     OpenAll();
  3680.  
  3681.     MinReal        = -RealWidth / 2;
  3682.     MinImaginary    = -ImaginaryHeight / 2;
  3683.  
  3684.     DummyBuffer[0] = 0;
  3685.  
  3686.         /* Pick up any selected images if run from Workbench. */
  3687.  
  3688.     if(!ThisProcess -> pr_CLI)
  3689.     {
  3690.         extern struct WBStartup *WBenchMsg;
  3691.  
  3692.         DefaultTool[0] = 0;
  3693.  
  3694.             /* Build new default tool name. */
  3695.  
  3696.         if(NameFromLock(WBenchMsg -> sm_ArgList[0] . wa_Lock,DefaultTool,256))
  3697.         {
  3698.             if(!AddPart(DefaultTool,WBenchMsg -> sm_ArgList[0] . wa_Name,256))
  3699.                 DefaultTool[0] = 0;
  3700.         }
  3701.  
  3702.         if(!DefaultTool[0])
  3703.             strcpy(DefaultTool,"MandelSquare");
  3704.  
  3705.         PictureIcon . do_DefaultTool    = DefaultTool;
  3706.         AnimIcon . do_DefaultTool    = DefaultTool;
  3707.  
  3708.             /* Called with Workbench arguments? */
  3709.  
  3710.         if(WBenchMsg -> sm_NumArgs > 1)
  3711.         {
  3712.                 /* Construct the full name. */
  3713.  
  3714.             if(NameFromLock(WBenchMsg -> sm_ArgList[1] . wa_Lock,DummyBuffer,256))
  3715.             {
  3716.                 if(!AddPart(DummyBuffer,WBenchMsg -> sm_ArgList[1] . wa_Name,256))
  3717.                     DummyBuffer[0] = 0;
  3718.                 else
  3719.                 {
  3720.                     struct DiskObject *Icon;
  3721.  
  3722.                         /* Read the icon and try to figure
  3723.                          * out whether the corresponding
  3724.                          * file is an animation or just
  3725.                          * a plain image.
  3726.                          */
  3727.  
  3728.                     if(Icon = GetDiskObject(DummyBuffer))
  3729.                     {
  3730.                         UBYTE *Value;
  3731.  
  3732.                         if(Value = FindToolType(Icon -> do_ToolTypes,"FILETYPE"))
  3733.                         {
  3734.                             if(!stricmp(Value,"ANIM"))
  3735.                                 IsAnim = TRUE;
  3736.                         }
  3737.  
  3738.                         FreeDiskObject(Icon);
  3739.                     }
  3740.                 }
  3741.             }
  3742.             else
  3743.                 DummyBuffer[0] = 0;
  3744.         }
  3745.     }
  3746.  
  3747.         /* No chance, use the default image. */
  3748.  
  3749.     if(!DummyBuffer[0])
  3750.         strcpy(DummyBuffer,"MandelSquare.Title");
  3751.  
  3752.         /* Try to read the selected image. */
  3753.  
  3754.     if(Handle = OpenImageFile(DummyBuffer))
  3755.     {
  3756.         struct BitMapHeader    BitMapHeader;
  3757.         struct MandelInfo    TempMandelInfo;
  3758.         BYTE            Colours = 1 << Depth;
  3759.         ULONG            MyMode = Mode;
  3760.  
  3761.         if(ReadImageHeader(Handle,&MyMode,&Colours,ColourTable,&BitMapHeader,&TempMandelInfo))
  3762.         {
  3763.             LONG Error;
  3764.  
  3765.             if(TempMandelInfo . Iterations)
  3766.             {
  3767.                 MinReal        = TempMandelInfo . MinReal;
  3768.                 MinImaginary    = TempMandelInfo . MinImaginary;
  3769.                 RealWidth    = TempMandelInfo . RealWidth;
  3770.                 ImaginaryHeight    = TempMandelInfo . ImaginaryHeight;
  3771.  
  3772.                 MaxIteration    = TempMandelInfo . Iterations;
  3773.             }
  3774.  
  3775.             if(BitMapHeader . w == BitMapHeader . h && !(BitMapHeader . h % 4))
  3776.             {
  3777.                 Square    = BitMapHeader . w;
  3778.                 Mode    = MyMode;
  3779.                 Depth    = BitMapHeader . nPlanes;
  3780.             }
  3781.  
  3782.             if(BitMap = CreateBitMap(BitMapHeader . nPlanes,BitMapHeader . w,BitMapHeader . h))
  3783.             {
  3784.                 if(ReadImageBody(Handle,BitMap,&BitMapHeader))
  3785.                     GotImage = TRUE;
  3786.                 else
  3787.                     DeleteBitMap(BitMap);
  3788.             }
  3789.  
  3790.             if(Error = GfxSetup())
  3791.             {
  3792.                 if(GotImage)
  3793.                     DeleteBitMap(BitMap);
  3794.  
  3795.                 CloseImageFile(Handle);
  3796.  
  3797.                 CloseAll(Error);
  3798.             }
  3799.             else
  3800.             {
  3801.                 if(GotImage)
  3802.                 {
  3803.                     BltBitMapRastPort(BitMap,0,0,RPort,0,0,Screen -> Width,Screen -> Height,0xC0);
  3804.  
  3805.                     DeleteBitMap(BitMap);
  3806.                 }
  3807.             }
  3808.  
  3809.             IterationSetup();
  3810.         }
  3811.  
  3812.         CloseImageFile(Handle);
  3813.     }
  3814.     else
  3815.     {
  3816.         struct Rectangle    DisplayClip;
  3817.         LONG            Error,Height;
  3818.  
  3819.             /* No title image, so let's produce one.
  3820.              * At first determine the maximum screen
  3821.              * size.
  3822.              */
  3823.  
  3824.         if(QueryOverscan(Mode,&DisplayClip,OSCAN_TEXT))
  3825.         {
  3826.             WORD p = 0;
  3827.  
  3828.             Height    = (((DisplayClip . MaxY - DisplayClip . MinY + 1) + 3) >> 2) << 2;
  3829.             Square    = 0;
  3830.  
  3831.             while(Square < Height)
  3832.             {
  3833.                 p++;
  3834.  
  3835.                 Square += PLUS;
  3836.             }
  3837.  
  3838.             if(Square > Height)
  3839.             {
  3840.                 p--;
  3841.  
  3842.                 Square -= PLUS;
  3843.             }
  3844.  
  3845.             if(p & 1)
  3846.                 Square -= PLUS;
  3847.         }
  3848.         else
  3849.         {
  3850.             if(Mode == LORES_KEY)
  3851.                 Square = 256;
  3852.             else
  3853.                 Square = 512;
  3854.         }
  3855.  
  3856.         if(Error = GfxSetup())
  3857.             CloseAll(Error);
  3858.     }
  3859.  
  3860.         /* Are we supposed to load and replay an animation file? */
  3861.  
  3862.     if(IsAnim)
  3863.     {
  3864.         BPTR File;
  3865.  
  3866.         SetWait(Window);
  3867.  
  3868.         Window -> Flags |= WFLG_RMBTRAP;
  3869.  
  3870.         if(File = Open(DummyBuffer,MODE_OLDFILE))
  3871.         {
  3872.             if(CreateBuffer())
  3873.             {
  3874.                 if(OpenPreLoadIFF(File))
  3875.                 {
  3876.                     strcpy(AnimPlayName,DummyBuffer);
  3877.  
  3878.                     SetClear(Window);
  3879.  
  3880.                     SwapBits();
  3881.  
  3882.                     ActivateWindow(Window);
  3883.  
  3884.                     ScreenToFront(Screen);
  3885.  
  3886.                     while(PlayAnim());
  3887.  
  3888.                     ClosePreLoadIFF();
  3889.                 }
  3890.  
  3891.                 DeleteBuffer();
  3892.  
  3893.                 LoadRGB4(&Screen -> ViewPort,ColourTable,1 << Depth);
  3894.             }
  3895.  
  3896.             Close(File);
  3897.         }
  3898.  
  3899.         Window -> Flags &= ~WFLG_RMBTRAP;
  3900.  
  3901.         ClearPointer(Window);
  3902.     }
  3903.     else
  3904.     {
  3905.         if(!GotImage)
  3906.         {
  3907.                 /* Set up working data. */
  3908.  
  3909.             MainMinReal        = MinReal;
  3910.             MainMinImaginary    = MinImaginary;
  3911.             MainRealWidth        = RealWidth;
  3912.             MainImaginaryHeight    = ImaginaryHeight;
  3913.  
  3914.                 /* Present the screen. */
  3915.  
  3916.             LoadRGB4(&Screen -> ViewPort,ColourTable,1 << Depth);
  3917.  
  3918.             ScreenToFront(Screen);
  3919.  
  3920.             ActivateWindow(Window);
  3921.  
  3922.             Running        = TRUE;
  3923.             NewCoords    = FALSE;
  3924.  
  3925.                 /* Generate the image. */
  3926.  
  3927.             RunMandelbrot(MinReal,MinReal + RealWidth,MinImaginary,MinImaginary + ImaginaryHeight,Window -> Width,Window -> Height);
  3928.         }
  3929.         else
  3930.         {
  3931.             strcpy(LastName,DummyBuffer);
  3932.  
  3933.                 /* Present the screen. */
  3934.  
  3935.             ScreenToFront(Screen);
  3936.  
  3937.             BlockWindow();
  3938.  
  3939.             ActivateWindow(Window);
  3940.  
  3941.                 /* Fade in the image. */
  3942.  
  3943.             FadeTo(&Screen -> ViewPort,NULL,ColourTable,1 << Depth,0,0);
  3944.  
  3945.             ReleaseWindow();
  3946.         }
  3947.  
  3948.         RealStep    = (RealWidth) / (double)Window -> Width;
  3949.         ImaginaryStep    = (ImaginaryHeight) / (double)Window -> Height;
  3950.     }
  3951.  
  3952.         /* The main input loop. */
  3953.  
  3954.     FOREVER
  3955.     {
  3956.         WaitPort(Window -> UserPort);
  3957.  
  3958.         HandleEvent();
  3959.  
  3960.             /* New display mode? */
  3961.  
  3962.         if(NewMode)
  3963.         {
  3964.             struct Rectangle    DisplayClip;
  3965.             LONG            Error,Height;
  3966.  
  3967.                 /* Remember colour table. */
  3968.  
  3969.             CopyMem(ColourTable,SinPalette,sizeof(UWORD) * 32);
  3970.  
  3971.                 /* We have a bitmap to copy to the
  3972.                  * screen.
  3973.                  */
  3974.  
  3975.             if(GlobalBitMap)
  3976.             {
  3977.                 GfxCleanup();
  3978.  
  3979.                 Mode    = GlobalMode;
  3980.                 Depth    = GlobalHeader . nPlanes;
  3981.                 Square    = GlobalHeader . w;
  3982.  
  3983.                 NewMode    = FALSE;
  3984.  
  3985.                 if(Error = GfxSetup())
  3986.                     CloseAll(Error);
  3987.                 else
  3988.                 {
  3989.                     BltBitMapRastPort(GlobalBitMap,0,0,RPort,0,0,Screen -> Width,Screen -> Height,0xC0);
  3990.  
  3991.                     DeleteBitMap(GlobalBitMap);
  3992.  
  3993.                     GlobalBitMap = NULL;
  3994.  
  3995.                     ScreenToFront(Screen);
  3996.  
  3997.                     BlockWindow();
  3998.  
  3999.                     ActivateWindow(Window);
  4000.  
  4001.                     if(UseWheel)
  4002.                         FadeTo(&Screen -> ViewPort,NULL,WheelPalette,1 << Depth,0,0);
  4003.                     else
  4004.                         FadeTo(&Screen -> ViewPort,NULL,SinPalette,1 << Depth,0,0);
  4005.  
  4006.                     NewCoords    = FALSE;
  4007.                     Running        = FALSE;
  4008.                     AreaActive    = FALSE;
  4009.  
  4010.                     IterationSetup();
  4011.  
  4012.                     ReleaseWindow();
  4013.                 }
  4014.             }
  4015.             else
  4016.             {
  4017.                     /* Open new screen with maximum
  4018.                      * available text overscan dimensions.
  4019.                      */
  4020.  
  4021.                 if(Mode == LORES_KEY)
  4022.                 {
  4023.                     Mode    = HIRESLACE_KEY;
  4024.                     Depth    = 4;
  4025.                 }
  4026.                 else
  4027.                 {
  4028.                     Mode    = LORES_KEY;
  4029.                     Depth    = 5;
  4030.                 }
  4031.  
  4032.                 if(QueryOverscan(Mode,&DisplayClip,OSCAN_TEXT))
  4033.                 {
  4034.                     WORD p = 0;
  4035.  
  4036.                     Height    = (((DisplayClip . MaxY - DisplayClip . MinY + 1) + 3) >> 2) << 2;
  4037.                     Square    = 0;
  4038.  
  4039.                     while(Square < Height)
  4040.                     {
  4041.                         p++;
  4042.  
  4043.                         Square += PLUS;
  4044.                     }
  4045.  
  4046.                     if(Square > Height)
  4047.                     {
  4048.                         p--;
  4049.  
  4050.                         Square -= PLUS;
  4051.                     }
  4052.  
  4053.                     if(p & 1)
  4054.                         Square -= PLUS;
  4055.                 }
  4056.                 else
  4057.                 {
  4058.                     if(Mode == LORES_KEY)
  4059.                         Square = 256;
  4060.                     else
  4061.                         Square = 512;
  4062.                 }
  4063.  
  4064.                 NewMode    = FALSE;
  4065.  
  4066.                 GfxCleanup();
  4067.  
  4068.                 if(Error = GfxSetup())
  4069.                     CloseAll(Error);
  4070.                 else
  4071.                 {
  4072.                     if(UseWheel)
  4073.                         LoadRGB4(&Screen -> ViewPort,WheelPalette,1 << Depth);
  4074.                     else
  4075.                         LoadRGB4(&Screen -> ViewPort,SinPalette,1 << Depth);
  4076.  
  4077.                     ScreenToFront(Screen);
  4078.  
  4079.                     ActivateWindow(Window);
  4080.  
  4081.                     MinReal        = MainMinReal;
  4082.                     MinImaginary    = MainMinImaginary;
  4083.                     RealWidth    = MainRealWidth;
  4084.                     ImaginaryHeight    = MainImaginaryHeight;
  4085.  
  4086.                     RealStep    = (RealWidth) / (double)Window -> Width;
  4087.                     ImaginaryStep    = (ImaginaryHeight) / (double)Window -> Height;
  4088.  
  4089.                     NewCoords    = TRUE;
  4090.                     AreaActive    = FALSE;
  4091.  
  4092.                     IterationSetup();
  4093.                 }
  4094.             }
  4095.         }
  4096.  
  4097.             /* Run the animation routine? */
  4098.  
  4099.         while(AnimRunning)
  4100.         {
  4101.             RunAnim();
  4102.  
  4103.             if(!AnimRunning)
  4104.             {
  4105.                 Running        = FALSE;
  4106.                 NewCoords    = FALSE;
  4107.             }
  4108.         }
  4109.  
  4110.             /* Restart with new coordinates. */
  4111.  
  4112.         if(NewCoords)
  4113.         {
  4114.             Running        = TRUE;
  4115.             NewCoords    = FALSE;
  4116.         }
  4117.  
  4118.             /* Run the image generation routines. */
  4119.  
  4120.         if(Running)
  4121.         {
  4122.             if(AreaActive)
  4123.                 RunAreaMandelbrot(RealStep,ImaginaryStep);
  4124.             else
  4125.             {
  4126.                 SetRast(RPort,0);
  4127.  
  4128.                 RunMandelbrot(MinReal,MinReal + RealWidth,MinImaginary,MinImaginary + ImaginaryHeight,Window -> Width,Window -> Height);
  4129.             }
  4130.         }
  4131.     }
  4132. }
  4133.