home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d566 / apfelkiste.lha / Apfelkiste / Apfelkiste1.3 / Source / Apfelkiste1.3src.lzh / Apfelkiste.c < prev    next >
C/C++ Source or Header  |  1991-10-30  |  24KB  |  880 lines

  1. /************************************************************************/
  2. /* Apfel.c --- Generates an image of the Mandelbrot-set            */
  3. /*                                    */
  4. /* Author:    M. Böhnisch (BillySoft)                    */
  5. /*        Löher Str. 2                        */
  6. /*        D-4790 Paderborn                    */
  7. /*                                    */
  8. /*        billy@uni-paderborn.de.pbinfo                */
  9. /*======================================================================*/
  10. /* 06.11.89    iterative version with fixed box sizes (10 by 10),    */
  11. /*        adapted a GFA-BASIC program from a german magazine    */
  12. /*                                    */
  13. /* 08.11.89    complete own version with recursive algorithm        */
  14. /*        (divide & conquer)                    */
  15. /*                                    */
  16. /* 10.11.89    added user input of picture size and borders        */
  17. /*                                    */
  18. /* 11.11.89    minor bug fixing                    */
  19. /*                                    */
  20. /* 20.11.89    added fix-point arithmetik written in assembler        */
  21. /*        format:                            */
  22. /*                                    */
  23. /*            [sgn|xxx xxxx xxxx xxxx.xxxx xxxx xxxx xxxx]    */
  24. /*                                    */
  25. /*        not accurate enough.                    */
  26. /*                                    */
  27. /* 21.11.89    rewrote fix-point format to:                */
  28. /*                                    */
  29. /*            [sgn|xxx xxxx.xxxx xxxx xxxx xxxx xxxx xxxx]    */
  30. /*                                    */
  31. /*        nice! (I'll try to use 26 bit after the point sometime) */
  32. /*                                    */
  33. /* 28.11.89    found IFF-Library on Fish #173. save picture option    */
  34. /*        added.                            */
  35. /*                                    */
  36. /* 04.12.89    improved assembly program                */
  37. /*                                    */
  38. /* 07.12.89    slight optimization in recursion scheme            */
  39. /*                                    */
  40. /* 09.12.89    added input requester                    */
  41. /*                                    */
  42. /* 21.07.90    review for Aztek-C5.0a                    */
  43. /*                                    */
  44. /* 23.09.90    print option added (color printers)            */
  45. /*                                    */
  46. /* 25.09.90    added color requester                    */
  47. /*                                                                      */
  48. /* 27.09.90     optimization of assembly program                        */
  49. /*                                    */
  50. /* 15.11.90    review for Lattice-C5.10                */
  51. /*                                    */
  52. /* 19.11.90    added a little retrying in case of an error by closing    */
  53. /*        screens. Might recover some problems with Amigas short    */
  54. /*        on memory or when really *BIG* screens are requested.    */
  55. /*                                    */
  56. /* 25.11.90    added s'more source code comments and translated all    */
  57. /*        strings from german to english                */
  58. /*                                    */
  59. /* 30.01.91    removed a bug causing to save no colormap along with a    */
  60. /*        picture                            */
  61. /*                                    */
  62. /* 01.02.91    removed a bug making strange things while colorcycling    */
  63. /*        pictures with more than 5 BitPlanes            */
  64. /*                                    */
  65. /* 01.02.91    added configuration facilities                */
  66. /*                                    */
  67. /* 17.04.91    removed a bug preventing the "Multitasking OFF" to work    */
  68. /*                                    */
  69. /* 18.04.91    some cast - operators added in "printersupport.h" to    */
  70. /*        compile without warnings for Kick 2.0            */
  71. /*                                    */
  72. /* 08.05.91    added 68030/68881 support                */
  73. /*                                    */
  74. /* 09.05.91    replaced lattice fp by fast floating point functions    */
  75. /************************************************************************/
  76.  
  77. /* -------------------------------------------------------------------- */
  78. /* Some defininitions to take advantage of Lattice's LSR-code:        */
  79. /* -------------------------------------------------------------------- */
  80. long     _stack        = 20000;    /* Stack space for this task     */
  81. char    *_procname    = "Apfelkiste";    /* Name of process created    */
  82. long     _priority    = 0;        /* Process priority        */
  83. long     _BackgroundIO    = 0;        /* No stdio required        */
  84. /* -------------------------------------------------------------------- */
  85.  
  86. #define APFEL_VERSION    "27"
  87.  
  88. #include <exec/types.h>
  89. #include <exec/memory.h>
  90. #include <intuition/intuition.h>
  91. #include <graphics/gfx.h>
  92. #include <graphics/gfxmacros.h>
  93. #include <proto/exec.h>
  94. #include <proto/dos.h>
  95. #include <proto/graphics.h>
  96. #include <proto/intuition.h>
  97. #include <libraries/iff.h>
  98. #include <libraries/arpbase.h>
  99. #include <libraries/color.h>
  100. #include <printersupport.h>
  101. #include <clib/macros.h>
  102. #include <string.h>
  103. #include <stdlib.h>
  104. #include <stdio.h>
  105. #include <dos.h>
  106. #include <mffp.h>
  107. #include <math.h>
  108. #include "Apf0.h"
  109. #include "Apf1.h"
  110. #include "Apf2.h"
  111.  
  112. /* -------------------------------------------------------------------- */
  113. /* Prototypes for the functions in the other modules            */
  114. /* -------------------------------------------------------------------- */
  115.  
  116. void FixPoint(double rmin, double rmax, double imin, double imax, double dx, double dy,
  117.         int maxiter, double divergenz, int gx, int gy, int depth);
  118. void __regargs    Apfel_Alert(long number);
  119. void __regargs    Activate_Gadget(struct Window *w, USHORT ID);
  120. void __regargs    Apfel_FLOAT(int x1, int y1, int x2, int y2);
  121. long         Iter_FLOAT(double r, double i);
  122.  
  123. /* --------------------------------------------------------------------- */
  124.  
  125. struct IntuitionBase    *IntuitionBase;
  126. struct GfxBase        *GfxBase;
  127. struct IFFBase        *IFFBase;
  128. struct ArpBase        *ArpBase;
  129. struct ColorBase    *ColorBase;
  130. struct Screen        *s;
  131. struct Window        *w, *u, *v;
  132. struct RastPort        *rp, *up;
  133. struct ViewPort        *vp;
  134. short             cycle, task = TRUE;
  135. APTR             IFFfile = NULL;
  136. struct FileRequester    *FReq;
  137. union printerIO        *request;
  138. struct MsgPort        *printerPort;
  139.  
  140. int             gx, gy, xsize, ysize, depth, hide;
  141. short             maxcol;
  142. int             maxiter;
  143. double             divergenz, rmin, rmax, imin, imax, dx, dy;
  144.  
  145. /* -------------------------------------------------------------------- */
  146. /* All the stuff needed to comfortably get IntuitionMessages        */
  147. /* -------------------------------------------------------------------- */
  148.  
  149. #define GAD_ID (((struct Gadget *)ADDR)->GadgetID)
  150.  
  151. ULONG             CLASS, CODE;
  152. APTR             ADDR;
  153. struct IntuiMessage    *Message    = NULL;
  154.  
  155. ULONG GetMessage(struct Window *MW)
  156. {
  157.     CLASS = CODE = 0;
  158.     ADDR = NULL;
  159.     if ( Message = (struct IntuiMessage *) GetMsg(MW->UserPort) ) {
  160.         CLASS    = Message->Class;
  161.         CODE    = Message->Code;
  162.         ADDR    = Message->IAddress;
  163.         ReplyMsg((struct Message *) Message);
  164.     }
  165.     return(CLASS);
  166. }
  167.  
  168. /* -------------------------------------------------------------------- */
  169. /* Simple routine to draw a rectangular shape. Used for the Mouse Opt    */
  170. /* -------------------------------------------------------------------- */
  171.  
  172. void DrawRect(struct RastPort *rp, short x1, short y1, short x2, short y2)
  173. {
  174.     Move(rp, x1, y1);
  175.     Draw(rp, x2, y1);
  176.     Draw(rp, x2, y2);
  177.     Draw(rp, x1, y2);
  178.     Draw(rp, x1, y1);
  179. }
  180.  
  181. /* -------------------------------------------------------------------- */
  182. /* Pre-initialized structures for main screen and window        */
  183. /* -------------------------------------------------------------------- */
  184.  
  185. struct NewScreen NS = {
  186.     0, 0,                /* screen XY origin relative to View */
  187.     0, 0,                /* screen width and height */
  188.     0,                /* screen depth (number of bitplanes) */
  189.     0, 1,                /* detail and block pens */
  190.     NULL,                /* display modes for this screen */
  191.     CUSTOMSCREEN | SCREENQUIET,    /* screen type */
  192.     NULL,                /* pointer to default screen font */
  193.     NULL,                /* screen title */
  194.     NULL,                /* first in list of custom screen gadgets */
  195.     NULL                /* pointer to custom BitMap structure */
  196. };
  197.  
  198. struct NewWindow NW = {
  199.     0, 0,        /* window XY origin relative to TopLeft of screen */
  200.     0, 0,        /* window width and height */
  201.     0, 1,        /* detail and block pens */
  202.     NULL,        /* IDCMP flags */
  203.     SMART_REFRESH |
  204.     ACTIVATE      |
  205.     BORDERLESS,    /* other window flags */
  206.     NULL,        /* first gadget in gadget list */
  207.     NULL,        /* custom CHECKMARK imagery */
  208.     NULL,        /* window title */
  209.     NULL,        /* custom screen pointer */
  210.     NULL,        /* custom bitmap */
  211.     5, 5,        /* minimum width and height */
  212.     -1, -1,        /* maximum width and height */
  213.     CUSTOMSCREEN    /* destination screen type */
  214. };
  215.  
  216. /* -------------------------------------------------------------------- */
  217. /* Default palette. Change this if you don't like the colors provided    */
  218. /* by me. Versions 25 and higher are supporting a custom default file.    */
  219. /* -------------------------------------------------------------------- */
  220.  
  221. USHORT Palette[128] = {
  222.     0x0000,    /* color #0 */
  223.     0x0F90,    /* color #1 */
  224.     0x0F20,    /* color #2 */
  225.     0x0840,    /* color #3 */
  226.     0x0580,    /* color #4 */
  227.     0x0589,    /* color #5 */
  228.     0x055F,    /* color #6 */
  229.     0x0A0F,    /* color #7 */
  230.     0x0F08,    /* color #8 */
  231.     0x0777,    /* color #9 */
  232.     0x0080,    /* color #10 */
  233.     0x00A0,    /* color #11 */
  234.     0x00C0,    /* color #12 */
  235.     0x00E0,    /* color #13 */
  236.     0x08E0,    /* color #14 */
  237.     0x0FF0,    /* color #15 */
  238.     0x0000,    /* color #16 */
  239.     0x0F90,    /* color #17 */
  240.     0x0F20,    /* color #18 */
  241.     0x0840,    /* color #19 */
  242.     0x0580,    /* color #20 */
  243.     0x0589,    /* color #21 */
  244.     0x055F,    /* color #22 */
  245.     0x0A0F,    /* color #23 */
  246.     0x0F08,    /* color #24 */
  247.     0x0777,    /* color #25 */
  248.     0x0080,    /* color #26 */
  249.     0x00A0,    /* color #27 */
  250.     0x00C0,    /* color #28 */
  251.     0x00E0,    /* color #29 */
  252.     0x08E0,    /* color #30 */
  253.     0x0FF0    /* color #31 */
  254. #define PaletteColorCount 32
  255. };
  256.  
  257. /* -------------------------------------------------------------------- */
  258. /* Close everything opened at runtime                    */
  259. /* -------------------------------------------------------------------- */
  260.  
  261. void CleanUp(void)
  262. {
  263.     if ( request )        DeleteExtIO((struct IORequest *) request);
  264.     if ( printerPort )    DeletePort(printerPort);
  265.     if ( IFFfile )        CloseIFF(IFFfile);
  266.     if ( w )        CloseWindow(w);
  267.     if ( u )        CloseWindow(u);
  268.     if ( s )        CloseScreen(s);
  269.     if ( ColorBase )    CloseLibrary(ColorBase);
  270.     if ( ArpBase )        CloseLibrary((struct Library *) ArpBase);
  271.     if ( IFFBase )        CloseLibrary(IFFBase);
  272.     if ( GfxBase )        CloseLibrary(GfxBase);
  273.     if ( IntuitionBase )    CloseLibrary(IntuitionBase);
  274.     exit(0);
  275. }
  276.  
  277. /* -------------------------------------------------------------------- */
  278. /* Open all used libraries, ports, etc. If this routine fails you are    */
  279. /* probably not up-to-date with one or several of the shared libraries    */
  280. /* used by me. Copy the provided libraries to your LIBS: directory,    */
  281. /* reboot (!) and try again.                        */
  282. /* -------------------------------------------------------------------- */
  283.  
  284. void OpenLibs(void)
  285. {
  286.     IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0L);
  287.     if ( ! IntuitionBase ) {
  288.         Apfel_Alert(1);
  289.         CleanUp();
  290.     }
  291.  
  292.     GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0L);
  293.     if ( ! GfxBase ) {
  294.         Apfel_Alert(2);
  295.         CleanUp();
  296.     }
  297.  
  298.     IFFBase = (struct IFFBase *) OpenLibrary(IFFNAME, IFFVERSION);
  299.     if ( ! IFFBase ) {
  300.         Apfel_Alert(3);
  301.         CleanUp();
  302.     }
  303.  
  304.     ArpBase = (struct ArpBase *) OpenLibrary(ArpName, ArpVersion);
  305.     if ( ! ArpBase ) {
  306.         Apfel_Alert(4);
  307.         CleanUp();
  308.     }
  309.  
  310.     ColorBase = (struct ColorBase *) OpenLibrary(COLORNAME, COLORVERSION);
  311.     if ( ! ColorBase ) {
  312.         Apfel_Alert(5);
  313.         CleanUp();
  314.     }
  315.  
  316.     FReq = ArpAllocFreq();    /* Wird durch CloseLibrary(ArpBase) freigegeben */
  317.     if ( ! FReq ) {
  318.         Apfel_Alert(6);
  319.         CleanUp();
  320.     }
  321.  
  322.     printerPort = CreatePort("Apfel-01.port",0L);
  323.     if ( ! printerPort ) {
  324.         Apfel_Alert(7);
  325.         CleanUp();
  326.     }
  327.  
  328.     request = (union printerIO *) CreateExtIO(printerPort, sizeof(union printerIO));
  329.     if ( ! request ) {
  330.         Apfel_Alert(8);
  331.         CleanUp();
  332.     }
  333. }
  334.  
  335. /* -------------------------------------------------------------------- */
  336. /* Open the control window and set gadget texts to appropriate values    */
  337. /* -------------------------------------------------------------------- */
  338.  
  339. void OpenRW(void)
  340. {
  341.     NW2.Screen = s;
  342.     if ( ! s ) {
  343.         NW2.Type = WBENCHSCREEN;
  344.     }
  345.     else {
  346.         NW2.Type = CUSTOMSCREEN;
  347.     }
  348.  
  349.     if ( task ) {
  350.         strcpy((char *) IText4.IText, " ON ");
  351.         IText4.LeftEdge = 6;
  352.     }
  353.     else {
  354.         strcpy((char *) IText4.IText, "OFF");
  355.         IText4.LeftEdge = 10;
  356.     }
  357.  
  358.     if ( cycle ) {
  359.         strcpy((char *) IText3.IText, " ON ");
  360.         IText3.LeftEdge = 6;
  361.     }
  362.     else {
  363.         strcpy((char *) IText3.IText, "OFF");
  364.         IText3.LeftEdge = 10;
  365.     }
  366.  
  367.     u = OpenWindow(&NW2);        /* open control window         */
  368.     if ( ! u ) {            /* if something goes wrong...    */
  369.         Apfel_Alert(9);        /* give message.        */
  370.         if ( s ) {        /* is the screen open, then ?    */
  371.             CloseScreen(s);    /* close it...            */
  372.             s = NULL;
  373.             OpenRW();    /* and retry on WB Screen...    */
  374.         }
  375.         else {            /* No screen, no hope...    */
  376.             CleanUp();    /* exiting...            */
  377.         }
  378.     }
  379.  
  380.     up = u->RPort;
  381.     PrintIText(up, &IntuiTextList1, 0L, 0L);
  382. }
  383.  
  384. /* -------------------------------------------------------------------- */
  385. /* Open screen & window for graphics rendition trying to evaluate a    */
  386. /* "best match" for the view modes for both PAL and NTSC. Maybe this    */
  387. /* needs a little work for optimal results on NTSC machines.        */
  388. /* I plan to rework this completely after CBM pops out Kick 2.0 for    */
  389. /* the A2000 in an official version.                    */
  390. /* -------------------------------------------------------------------- */
  391.  
  392. void OpenAll(void)
  393. {
  394.     USHORT Modes = 0;
  395.  
  396.     NS.Width    = xsize;
  397.     NS.Height    = ysize;
  398.     NS.Depth    = depth;
  399.     maxcol        = 1 << depth;
  400.  
  401.     if ( xsize > 368 )        Modes  = HIRES;
  402.     if ( ! Modes && depth == 6 )    Modes  = EXTRA_HALFBRITE;
  403.     if ( ysize > 282 )        Modes |= LACE;
  404.  
  405.     NS.ViewModes = Modes;
  406.  
  407.     s = OpenScreen(&NS);
  408.     if ( ! s ) {
  409.         Apfel_Alert(10);
  410.     }
  411.     else {
  412.         NW.Screen    = s;
  413.         NW.Width    = gx;
  414.         NW.Height    = gy;
  415.         NW.LeftEdge    = (xsize - gx) / 2;
  416.         NW.TopEdge    = (ysize - gy) / 2;
  417.         w = OpenWindow(&NW);
  418.         if ( ! w ) {
  419.             Apfel_Alert(9);
  420.         }
  421.         else {
  422.             rp = w->RPort;
  423.             vp = &(s->ViewPort);
  424.             LoadRGB4(vp, Palette, PaletteColorCount);
  425.         }
  426.     }
  427. }
  428.  
  429. /* -------------------------------------------------------------------- */
  430. /* Load an IFF ILBM file and get it displayed on the graphics screen.    */
  431. /* I have not put too much work into this, e.g. there is no chunk for    */
  432. /* the data needed to re-calculate the loaded Mandelbrot image.        */
  433. /* Comments and help are welcome, just send me a message to my E-Mail    */
  434. /* adress.                                */
  435. /* -------------------------------------------------------------------- */
  436.  
  437. BOOL LoadFile(char *Name)
  438. {
  439.     struct BitMapHeader *bmhd;
  440.     ULONG cnt;
  441.  
  442.     IFFfile = OpenIFF(Name);
  443.     if ( ! IFFfile ) {
  444.         Apfel_Alert(12);
  445.     }
  446.     else {
  447.         bmhd = GetBMHD(IFFfile);
  448.         if ( ! bmhd ) {
  449.             Apfel_Alert(13);
  450.         }
  451.         else {
  452.             NS.Width    = gx    = xsize    = bmhd->w;
  453.             NS.Height    = gy    = ysize    = bmhd->h;
  454.             NS.Depth    = depth    = bmhd->nPlanes;
  455.             maxcol        = 1 << depth;
  456.             NS.ViewModes    = GetViewModes(IFFfile);
  457.             s        = OpenScreen(&NS);
  458.             if ( ! s ) {
  459.                 Apfel_Alert(10);
  460.             }
  461.             else {
  462.                 vp        = &(s->ViewPort);
  463.                 cnt        = GetColorTab(IFFfile, (WORD *) Palette);
  464.                 NW.Screen    = s;
  465.                 NW.Width    = gx;
  466.                 NW.Height    = gy;
  467.                 w        = OpenWindow(&NW);
  468.                 if ( ! w ) {
  469.                     Apfel_Alert(9);
  470.                     CloseScreen(s);
  471.                     s = NULL;
  472.                 }
  473.                 else {
  474.                     rp        = w->RPort;
  475.                     LoadRGB4(vp, Palette, cnt);
  476.                     if ( ! DecodePic(IFFfile, rp->BitMap) ) {
  477.                         Apfel_Alert(14);
  478.                         CloseWindow(w);
  479.                         w = NULL;
  480.                         CloseScreen(s);
  481.                         s = NULL;
  482.                     }
  483.                 }
  484.             }
  485.         }
  486.         CloseIFF(IFFfile);
  487.         IFFfile        = NULL;
  488.     }
  489.     return ( w != NULL );        /* All OK if window still open */
  490. }
  491.  
  492. /* -------------------------------------------------------------------- */
  493. /* Set default values for the control window. Load the default image to    */
  494. /* comfortably get zoomed into this wonderful world of chaos.        */
  495. /* -------------------------------------------------------------------- */
  496.  
  497. void SetDefault(void)
  498. {
  499.     FILE    *fp;
  500.     char     defpic[FMSIZE];
  501.     int     i;
  502.     int     omt;
  503.  
  504.     omt = task;
  505.  
  506.     fp = fopen("Apfelkiste.config", "r");
  507.     if ( ! fp ) fopen("DEVS:Apfelkiste.config", "r");
  508.     if ( ! fp ) fopen("S:Apfelkiste.config", "r");
  509.     if ( ! fp ) {
  510.         Apfel_Alert(11);
  511.         strcpy(defpic, "Apfel0.IFF");
  512.         rmin        = -2.3;
  513.         imin        = -1.25;
  514.         rmax        =  0.825;
  515.         imax        =  1.25;
  516.         maxiter        = 30;
  517.         divergenz    =  6.0;
  518.         cycle        = FALSE;
  519.         task        = TRUE;
  520.     }
  521.     else {
  522.         fscanf(fp, "FNAME=%s", defpic);
  523.         fscanf(fp, "RMIN=%lf", &rmin);
  524.         fscanf(fp, "RMAX=%lf", &rmax);
  525.         fscanf(fp, "IMIN=%lf", &imin);
  526.         fscanf(fp, "IMAX=%lf", &imax);
  527.         fscanf(fp, "MAXITER=%d", &maxiter);
  528.         fscanf(fp, "DIVERGENZ=%lf", &divergenz);
  529.         fscanf(fp, "TASK=%hd", &task);
  530.         fscanf(fp, "CYCLE=%hd", &cycle);
  531.         for ( i = 0; i < PaletteColorCount; i++ ) {
  532.             fscanf(fp, "COLOR=%hx", &(Palette[i]));
  533.         }
  534.         fclose(fp);
  535.     }
  536.  
  537.     if ( ! LoadFile("Apfel0.IFF") ) {
  538.         xsize    = gx    = 320;
  539.         ysize    = gy    = 200;
  540.         depth    = 2;
  541.         maxcol    = 1 << depth;
  542.     }
  543.  
  544.     dx = (rmax - rmin) / (double) gx;
  545.     dy = (imax - imin) / (double) gy;
  546.  
  547.     sprintf((char *) Gadget1SIBuff, "%lf", rmin);
  548.     sprintf((char *) Gadget2SIBuff, "%lf", rmax);
  549.     sprintf((char *) Gadget3SIBuff, "%lf", imin);
  550.     sprintf((char *) Gadget4SIBuff, "%lf", imax);
  551.     sprintf((char *) Gadget5SIBuff, "%d",  maxiter);
  552.     sprintf((char *) Gadget6SIBuff, "%lf", divergenz);
  553.     sprintf((char *) Gadget7SIBuff, "%d",  gx);
  554.     sprintf((char *) Gadget8SIBuff, "%d",  gy);
  555.     sprintf((char *) Gadget9SIBuff, "%d",  depth);
  556.  
  557.     if ( omt != task ) {
  558.         if ( task ) {
  559.             Permit();
  560.         }
  561.         else {
  562.             Forbid();
  563.         }
  564.     }
  565. }
  566.  
  567. /* -------------------------------------------------------------------- */
  568. /* Used by load/save routines to get filenames.    Thanks to all the guys    */
  569. /* who put sweat and blood into the creation of ARP.            */
  570. /* -------------------------------------------------------------------- */
  571.  
  572. BOOL GetFileName(char *Name, char *Hail)
  573. {
  574.     FReq->fr_Hail        = Hail;
  575.     FReq->fr_Window        = w;
  576.     FReq->fr_LeftEdge    = 1;
  577.     FReq->fr_TopEdge    = 1;
  578.  
  579.     if ( FileRequest(FReq) ) {
  580.         strcpy(Name, FReq->fr_Dir);
  581.         TackOn(Name, FReq->fr_File);
  582.         return TRUE;
  583.     }
  584.     else {
  585.         return FALSE;
  586.     }
  587. }
  588.  
  589. /************************************************************************/
  590. /* The main() function, at last...                    */
  591. /* Contains the handling to react on gadget activation and manage the    */
  592. /* call of the diverse subroutines.                    */
  593. /* Not commented at all, but shouldn't be too difficult to read anyway.    */
  594. /************************************************************************/
  595.  
  596. void main(int argc, char *argv[])
  597. {
  598.     char    fname[80];
  599.     int    i, x, y;
  600.     double    help;
  601.     int    mx1, my1, mx2, my2;
  602.     UWORD    c_palette[128];
  603.  
  604.     OpenLibs();
  605.     SetDefault();
  606.     OpenRW();
  607.  
  608.     do {
  609.         Wait(1L << u -> UserPort -> mp_SigBit);
  610.         GetMessage(u);
  611.         switch ( CLASS ) {
  612.         case GADGETUP:
  613.             switch ( GAD_ID ) {
  614.             case GAD_FLOAT:
  615.             case GAD_FXP:
  616.                 sscanf((char *) Gadget1SIBuff, "%lf", &rmin);
  617.                 sscanf((char *) Gadget2SIBuff, "%lf", &rmax);
  618.                 sscanf((char *) Gadget3SIBuff, "%lf", &imin);
  619.                 sscanf((char *) Gadget4SIBuff, "%lf", &imax);
  620.                 sscanf((char *) Gadget5SIBuff, "%d",  &maxiter);
  621.                 sscanf((char *) Gadget6SIBuff, "%lf", &divergenz);
  622.                 sscanf((char *) Gadget7SIBuff, "%d",  &gx);
  623.                 sscanf((char *) Gadget8SIBuff, "%d",  &gy);
  624.                 sscanf((char *) Gadget9SIBuff, "%d",  &depth);
  625.  
  626.                 xsize = gx;
  627.                 if ( gx <= 736 ) xsize = 736;    /* Max. Overscan Hires    */
  628.                 if ( gx <= 640 ) xsize = 640;    /* Nor. Size Hires    */
  629.                 if ( gx <= 368 ) xsize = 368;    /* Max. Overscan Lores    */
  630.                 if ( gx <= 320 ) xsize = 320;    /* Nor. Size Lores    */
  631.  
  632.                 ysize = gy;
  633.                 if ( gy <= 564 ) ysize = 564;    /* Max. Overscan Lace   PAL    */
  634.                 if ( gy <= 512 ) ysize = 512;    /* Nor. Size Lace       PAL    */
  635.                 if ( gy <= 400 ) ysize = 400;    /* Nor. Size Lace       NTSC    */
  636.                 if ( gy <= 282 ) ysize = 282;    /* Max. Overscan NoLace PAL    */
  637.                 if ( gy <= 256 ) ysize = 256;    /* Nor. Size NoLace    PAL    */ 
  638.                 if ( gy <= 200 ) ysize = 200;    /* Nor. Size NoLace     NTSC    */
  639.                 if ( w ) CloseWindow(w);
  640.                 w = NULL;
  641.                 if ( u ) CloseWindow(u);
  642.                 u = NULL;
  643.                 if ( s ) CloseScreen(s);
  644.                 s = NULL;
  645.                 OpenAll();
  646.                 if (  w && s ) {
  647.                     dx   = (rmax - rmin) / (double) gx;
  648.                     dy   = (imax - imin) / (double) gy;
  649.  
  650.                     switch ( GAD_ID ) {
  651.                     case GAD_FLOAT:
  652.                         help = rmin;
  653.                         for ( x = 0; x < gx; x++ ) {
  654.                             SetAPen(rp, Iter_FLOAT(help, imin));
  655.                             WritePixel(rp, x, 0);
  656.                             SetAPen(rp, Iter_FLOAT(help, imax));
  657.                             WritePixel(rp, x, gy-1);
  658.                             help += dx;
  659.                         }
  660.  
  661.                         help = imin;
  662.                         for ( y = 0; y < gy; y++ ) {
  663.                             SetAPen(rp, Iter_FLOAT(rmin, help));
  664.                             WritePixel(rp, 0, y);
  665.                             SetAPen(rp, Iter_FLOAT(rmax, help));
  666.                             WritePixel(rp, gx-1, y);
  667.                             help += dy;
  668.                         }
  669.  
  670.                         Apfel_FLOAT(0, 0, gx - 1, gy - 1);
  671.                         break;
  672.                     case GAD_FXP:
  673.                          FixPoint(rmin, rmax, imin, imax, dx, dy,
  674.                              maxiter, divergenz,
  675.                              gx, gy, depth);
  676.                         break;
  677.                     }
  678.                 }
  679.                 else {
  680.                     if ( s ) {
  681.                         CloseScreen(s);
  682.                     }
  683.                 }
  684.                 OpenRW();
  685.                 break;
  686.             case GAD_QUIT:
  687.                 CleanUp();
  688.                 break;
  689.             case GAD_SAVE:
  690.                 if ( u ) CloseWindow(u);
  691.                 u = NULL;
  692.                 if ( GetFileName(fname, "Save Picture") ) {
  693.                     SaveBitMap(fname, &(s->BitMap), Palette, 0x1L);
  694.                 }
  695.                 OpenRW();
  696.                 break;
  697.             case GAD_LOAD:
  698.                 if ( u ) CloseWindow(u);
  699.                 u = NULL;
  700.                 if ( GetFileName(fname, "Load Picture") ) {
  701.                     if ( w ) CloseWindow(w);
  702.                     w = NULL;
  703.                     if ( s ) CloseScreen(s);
  704.                     s = NULL;
  705.                     if ( ! LoadFile(fname) ) {;}
  706.                 }
  707.                 OpenRW();
  708.                 break;
  709.             case GAD_REAL0:
  710.                 Activate_Gadget(u, GAD_REAL1);
  711.                 break;
  712.             case GAD_REAL1:
  713.                 Activate_Gadget(u, GAD_IMAG0);
  714.                 break;
  715.             case GAD_IMAG0:
  716.                 Activate_Gadget(u, GAD_IMAG1);
  717.                 break;
  718.             case GAD_IMAG1:
  719.                 Activate_Gadget(u, GAD_MAXITER);
  720.                 break;
  721.             case GAD_MAXITER:
  722.                 Activate_Gadget(u, GAD_DIV);
  723.                 break;
  724.             case GAD_DIV:
  725.                 Activate_Gadget(u, GAD_XSIZE);
  726.                 break;
  727.             case GAD_XSIZE:
  728.                 Activate_Gadget(u, GAD_YSIZE);
  729.                 break;
  730.             case GAD_YSIZE:
  731.                 Activate_Gadget(u, GAD_DEPTH);
  732.                 break;
  733.             case GAD_DEPTH:
  734.                 Activate_Gadget(u, GAD_REAL0);
  735.                 break;
  736.             case GAD_MOUSE:
  737.                 if ( s && w ) {
  738.                     if ( u ) CloseWindow(u);
  739.                     u = NULL;
  740.                     ModifyIDCMP(w, MOUSEBUTTONS | INTUITICKS);
  741.                     do {
  742.                         Wait(1L << w->UserPort->mp_SigBit);
  743.                         GetMessage(w);
  744.                     } while ( CLASS != MOUSEBUTTONS || CODE != SELECTDOWN );
  745.  
  746.                     mx2 = mx1 = w->MouseX;
  747.                     my2 = my1 = w->MouseY;
  748.                     SetDrMd(rp, JAM2 | COMPLEMENT);
  749.                     SetAPen(rp, 1L);
  750.                     DrawRect(rp, mx1, my1, mx2, my2);
  751.  
  752.                     do {
  753.                         if ( mx2 != w->MouseX || my2 != w->MouseY ) {
  754.                             DrawRect(rp, mx1, my1, mx2, my2);
  755.                             mx2 = w->MouseX;
  756.                             my2 = w->MouseY;
  757.                             DrawRect(rp, mx1, my1, mx2, my2);
  758.                         }
  759.                         Wait(1L << w->UserPort->mp_SigBit);
  760.                         GetMessage(w);
  761.                     } while ( CLASS != MOUSEBUTTONS || CODE != SELECTUP );
  762.  
  763.                     DrawRect(rp, mx1, my1, mx2, my2);
  764.                     if ( mx1 > mx2 ) {
  765.                         i    = mx1;
  766.                         mx1    = mx2;
  767.                         mx2    = i;
  768.                     }
  769.                     if ( my1 > my2 ) {
  770.                         i    = my1;
  771.                         my1    = my2;
  772.                         my2    = i;
  773.                     }
  774.                     ModifyIDCMP(w, NULL);
  775.  
  776.                     sprintf((char *) Gadget1SIBuff, "%lf", mx1*dx+rmin);
  777.                     sprintf((char *) Gadget2SIBuff, "%lf", mx2*dx+rmin);
  778.                     sprintf((char *) Gadget3SIBuff, "%lf", my1*dy+imin);
  779.                     sprintf((char *) Gadget4SIBuff, "%lf", my2*dy+imin);
  780.                     OpenRW();
  781.                 }
  782.                 break;
  783.             case GAD_VIEW:
  784.                 if ( s && w ) {
  785.                     if ( u ) CloseWindow(u);
  786.                     u = NULL;
  787.                     memcpy(c_palette, Palette, sizeof(UWORD) * MIN(32, maxcol));
  788.                     ModifyIDCMP(w, MOUSEBUTTONS | INTUITICKS);
  789.                     while ( GetMessage(w) != MOUSEBUTTONS ) {
  790.                         if ( cycle ) {
  791.                             i = c_palette[MIN(31, maxcol-1)];
  792.                             movmem(c_palette, c_palette+1, sizeof(UWORD) * MIN(31, maxcol-1 ));
  793.                             c_palette[0] = i;
  794.                             LoadRGB4(vp, c_palette, MIN(32, maxcol));
  795.                             Delay(10L);
  796.                         }
  797.                         Wait(1L << w->UserPort->mp_SigBit);
  798.                     }
  799.                     ModifyIDCMP(w, NULL);
  800.                     LoadRGB4(vp, Palette, MIN(32,maxcol));
  801.                     OpenRW();
  802.                 }
  803.                 break;
  804.             case GAD_PRINT:
  805.                 if ( s && w ) {
  806.                     if ( ! OpenPrinter(request) ) {
  807.                         DumpRPort(request, rp, vp->ColorMap,
  808.                         vp->Modes, 0, 0, s->Width, s->Height, 0, 0,
  809.                         SPECIAL_FULLCOLS | SPECIAL_ASPECT);
  810.                         ClosePrinter(request);
  811.                     }
  812.                 }
  813.                 break;
  814.             case GAD_CYCLE:
  815.                 cycle = ! cycle;
  816.                 if ( cycle ) {
  817.                     strcpy((char *) IText3.IText, " ON ");
  818.                     IText3.LeftEdge = 6;
  819.                 }
  820.                 else {
  821.                     strcpy((char *) IText3.IText, "OFF");
  822.                     IText3.LeftEdge = 10;
  823.                 }
  824.                 RefreshGadgets(u->FirstGadget, u, NULL);
  825.                 break;
  826.             case GAD_DEFAULT:
  827.                 if ( w ) CloseWindow(w);
  828.                 w = NULL;
  829.                 if ( u ) CloseWindow(u);
  830.                 u = NULL;
  831.                 if ( s ) CloseScreen(s);
  832.                 s = NULL;
  833.                 SetDefault();
  834.                 OpenRW();
  835.                 break;
  836.             case GAD_TASK:
  837.                 task = ! task;
  838.                 if ( task ) {
  839.                     strcpy((char *) IText4.IText, " ON ");
  840.                     IText4.LeftEdge = 6;
  841.                     Permit();
  842.                 }
  843.                 else {
  844.                     strcpy((char *) IText4.IText, "OFF");
  845.                     IText4.LeftEdge = 10;
  846.                     Forbid();
  847.                 }
  848.                 RefreshGadgets(u->FirstGadget, u, NULL);
  849.                 break;
  850.             case GAD_ABOUT:
  851.                 if ( u ) CloseWindow(u);
  852.                 u = NULL;
  853.                 NW3.Screen = s;
  854.                 if ( ! s )    NW3.Type = WBENCHSCREEN;
  855.                 else        NW3.Type = CUSTOMSCREEN;
  856.                 if ( v = OpenWindow(&NW3) ) {
  857.                     PrintIText(v->RPort, &IntuiTextList2, 0L, 0L);
  858.                     Wait(1L << v->UserPort->mp_SigBit);
  859.                     CloseWindow(v);
  860.                     v = NULL;
  861.                 }
  862.                 OpenRW();
  863.                 break;
  864.             case GAD_COLOR:
  865.                 if ( s ) {
  866.                     if ( u ) CloseWindow(u);
  867.                     u = NULL;
  868.                     if ( ! DoColor(Palette, s) ) {
  869.                         for ( i = 0; i < MIN(32, maxcol); i++ ) {
  870.                             Palette[i] = GetRGB4(vp->ColorMap, i);
  871.                         }
  872.                     }
  873.                     OpenRW();
  874.                 }
  875.                 break;
  876.             }
  877.         }
  878.     } while ( TRUE );
  879. }
  880.