home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d566 / apfelkiste.lha / Apfelkiste / Apfelkiste2.0 / Source / Apfelkiste2.0src.lzh / Apfelkiste.c < prev    next >
C/C++ Source or Header  |  1991-10-23  |  28KB  |  1,041 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 SAS 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 doing 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.                */
  71. /*                                    */
  72. /* 08.06.91    added 68030/68881 support                */
  73. /*                                    */
  74. /* 09.06.91    replaced lattice fp by fast floating point functions    */
  75. /*        (faster only if FLOAT is used. shorter object, though)    */
  76. /************************************************************************/
  77. /*                         W A R N I N G  ! ! !                */
  78. /*                                    */
  79. /* From now on ALL versions of Apfelkiste will need KS 2.0 and the new    */
  80. /* set of include files. This applies to version 28 and above.        */
  81. /************************************************************************/
  82. /*                                    */
  83. /* 12.06.91    switched to 2.0 at last. removed ARP routines, not    */
  84. /*        because they're bad (THEY AREN'T!), but because of    */
  85. /*        naming conflicts of arp.h to 2.0 include files.        */
  86. /*                                    */
  87. /* 12.06.91    added some all *new* facilities:            */
  88. /*            o automatic overscan adaption            */
  89. /*            o autoscrolling screen                */
  90. /*                                    */
  91. /* 22.07.91    2.0 style gadgets provided                */
  92. /*                                    */
  93. /* 23.07.91    located a bug in SAS's fscanf() (!!!), %hx does NOT     */
  94. /*        read 16 Bit integers but 32 Bit longs. Thus lead into    */
  95. /*        a strange error that occurred with pictures >3        */
  96. /*        bitplanes only: all colors above #8 are set to 0(black) */
  97. /*        Fixed by scanning into a temporary long first.        */
  98. /*                                    */
  99. /* 23.10.91    changed names of OpenIFF() and CloseIFF() to xOpenIFF()    */
  100. /*        and xCloseIFF() for KS 2.0 include file compatibility    */
  101. /*                                    */
  102. /*        updated docs for inclusion in AmigaLibDisk pool        */
  103. /*                                    */
  104. /*        last-minute review for SAS C5.10b            */
  105. /************************************************************************/
  106.  
  107. /* -------------------------------------------------------------------- */
  108. /* Some defininitions to take advantage of Lattice's LSR-code:        */
  109. /* -------------------------------------------------------------------- */
  110. long     _stack        = 20000;    /* Stack space for this task     */
  111. char    *_procname    = "Apfelkiste";    /* Name of process created    */
  112. long     _priority    = 0;        /* Process priority        */
  113. long     _BackgroundIO    = 0;        /* No stdio required        */
  114. /* -------------------------------------------------------------------- */
  115.  
  116. #define APFEL_VERSION    "30"
  117.  
  118. #include <exec/types.h>
  119. #include <exec/memory.h>
  120.  
  121. #include <intuition/intuition.h>
  122.  
  123. #include <graphics/gfx.h>
  124. #include <graphics/gfxmacros.h>
  125.  
  126. #include <libraries/iff.h>
  127. #include <libraries/asl.h>
  128. #include <libraries/color.h>
  129.  
  130. #include <proto/exec.h>
  131. #include <proto/dos.h>
  132. #include <proto/graphics.h>
  133. #include <proto/intuition.h>
  134. #include <proto/asl.h>
  135. #include <proto/gadtools.h>
  136.  
  137. #include <printersupport.h>
  138. #include <clib/macros.h>
  139. #include <string.h>
  140. #include <stdlib.h>
  141. #include <stdio.h>
  142. #include <dos.h>
  143. #include <mffp.h>
  144. #include <math.h>
  145. #include "Apf0.h"
  146. #include "Apf2.h"
  147.  
  148. /* -------------------------------------------------------------------- */
  149. /* Prototypes for the functions in the other modules            */
  150. /* -------------------------------------------------------------------- */
  151.  
  152. void FixPoint(    double rmin, double rmax, double imin, double imax,
  153.         double dx, double dy,
  154.         int maxiter, double divergenz, int gx, int gy, int depth);
  155. void __regargs    Apfel_Alert(long number);
  156. void __regargs    Activate_Gadget(struct Window *w, USHORT ID);
  157. void __regargs    Apfel_FLOAT(int x1, int y1, int x2, int y2);
  158. long         Iter_FLOAT(double r, double i);
  159. void        FreeGads(void);
  160. struct Gadget    *InitGads(struct Screen *scr);
  161.  
  162. /* --------------------------------------------------------------------- */
  163.  
  164. struct IntuitionBase    *IntuitionBase;
  165. struct GfxBase        *GfxBase;
  166. struct IFFBase        *IFFBase;
  167. struct Library        *AslBase;
  168. struct ColorBase    *ColorBase;
  169. struct Library        *GadToolsBase;
  170.  
  171. struct Screen        *s;
  172. struct Window        *w, *u;
  173. struct RastPort        *rp, *up;
  174. struct ViewPort        *vp;
  175. struct Gadget        *glist;
  176.  
  177. char             DefBuf_REAL0[40];
  178. char             DefBuf_REAL1[40];
  179. char             DefBuf_IMAG0[40];
  180. char             DefBuf_IMAG1[40];
  181. char             DefBuf_MAXITER[40];
  182. char             DefBuf_DIV[40];
  183. char             DefBuf_XSIZE[40];
  184. char             DefBuf_YSIZE[40];
  185. char             DefBuf_DEPTH[40]; 
  186.  
  187. extern long         SelNo_TASK;
  188. extern long         SelNo_CYCLE;
  189. extern char        *Buf_REAL0;
  190. extern char        *Buf_REAL1;
  191. extern char        *Buf_IMAG0;
  192. extern char        *Buf_IMAG1;
  193. extern char        *Buf_MAXITER;
  194. extern char        *Buf_DIV;
  195. extern char        *Buf_XSIZE;
  196. extern char        *Buf_YSIZE;
  197. extern char        *Buf_DEPTH;
  198. extern char        *DefText_REAL0;
  199. extern char        *DefText_REAL1;
  200. extern char        *DefText_IMAG0;
  201. extern char        *DefText_IMAG1;
  202. extern char        *DefText_MAXITER;
  203. extern char        *DefText_DIV;
  204. extern char        *DefText_XSIZE;
  205. extern char        *DefText_YSIZE;
  206. extern char        *DefText_DEPTH;  
  207.  
  208. int             cycle, task = TRUE;
  209. APTR             IFFfile = NULL;
  210. struct FileRequester    *FReq;
  211. union printerIO        *request;
  212. struct MsgPort        *printerPort;
  213.  
  214. int             gx, gy, xsize, ysize, depth, hide;
  215. short             maxcol;
  216. int             maxiter;
  217. double             divergenz, rmin, rmax, imin, imax, dx, dy;
  218.  
  219. /* -------------------------------------------------------------------- */
  220. /* All the stuff needed to comfortably get IntuitionMessages        */
  221. /* -------------------------------------------------------------------- */
  222.  
  223. ULONG             CLASS, CODE, GAD_ID;
  224. APTR             ADDR;
  225. struct IntuiMessage    *Message    = NULL;
  226.  
  227. ULONG GetMessage(struct Window *MW)
  228. {
  229.     CLASS = CODE = 0;
  230.     ADDR = NULL;
  231.     if ( Message = (struct IntuiMessage *) GetMsg(MW->UserPort) ) {
  232.         CLASS    = Message->Class;
  233.         CODE    = Message->Code;
  234.         ADDR    = Message->IAddress;
  235.         ReplyMsg((struct Message *) Message);
  236.     }
  237.     return CLASS;
  238. }
  239.  
  240. ULONG GT_GetMessage(struct Window *MW)
  241. {
  242.     CLASS = CODE = GAD_ID = 0;
  243.     ADDR = NULL;
  244.     if ( Message = GT_GetIMsg(MW->UserPort) ) {
  245.         CLASS    = Message->Class;
  246.         CODE    = Message->Code;        
  247.         ADDR    = Message->IAddress;
  248.         if ( CLASS == IDCMP_GADGETUP ) {
  249.             GAD_ID = ((struct Gadget *) ADDR)->GadgetID;
  250.         }
  251.         GT_ReplyIMsg(Message);
  252.     }
  253.     return CLASS;
  254. }
  255.  
  256. /* -------------------------------------------------------------------- */
  257. /* Simple routine to draw a rectangular shape. Used for the Mouse Opt    */
  258. /* -------------------------------------------------------------------- */
  259.  
  260. void DrawRect(struct RastPort *rp, short x1, short y1, short x2, short y2)
  261. {
  262.     Move(rp, x1, y1);
  263.     Draw(rp, x2, y1);
  264.     Draw(rp, x2, y2);
  265.     Draw(rp, x1, y2);
  266.     Draw(rp, x1, y1);
  267. }
  268.  
  269. /* -------------------------------------------------------------------- */
  270. /* Pre-initialized structures for main screen and window        */
  271. /* -------------------------------------------------------------------- */
  272.  
  273. UWORD PenSpec[] = { ~0 };        /* Minimal pen specifikation array */
  274.  
  275. struct TextAttr TOPAZ80 = { (STRPTR) "topaz.font", TOPAZ_EIGHTY, 0, 0 };
  276.  
  277. struct NewScreen NS = {
  278.     0, 0,                /* screen XY origin relative to View */
  279.     0, 0,                /* screen width and height */
  280.     0,                /* screen depth (number of bitplanes) */
  281.     0, 1,                /* detail and block pens */
  282.     NULL,                /* display modes for this screen */
  283.     CUSTOMSCREEN | SCREENQUIET,    /* screen type */
  284.     &TOPAZ80,            /* pointer to default screen font */
  285.     NULL,                /* screen title */
  286.     NULL,                /* first in list of custom screen gadgets */
  287.     NULL                /* pointer to custom BitMap structure */
  288. };
  289.  
  290. struct NewWindow NW = {
  291.     0, 0,        /* window XY origin relative to TopLeft of screen */
  292.     0, 0,        /* window width and height */
  293.     0, 1,        /* detail and block pens */
  294.     NULL,        /* IDCMP flags */
  295.     SMART_REFRESH |
  296.     ACTIVATE      |
  297.     BORDERLESS,    /* other window flags */
  298.     NULL,        /* first gadget in gadget list */
  299.     NULL,        /* custom CHECKMARK imagery */
  300.     NULL,        /* window title */
  301.     NULL,        /* custom screen pointer */
  302.     NULL,        /* custom bitmap */
  303.     5, 5,        /* minimum width and height */
  304.     -1, -1,        /* maximum width and height */
  305.     CUSTOMSCREEN    /* destination screen type */                          
  306. };
  307.  
  308. struct NewWindow NW2 = {
  309.       0,   0,    /* window XY origin relative to TopLeft of screen */
  310.     320, 196,    /* window width and height */
  311.       0,   1,    /* detail and block pens */
  312.     GADGETUP,    /* IDCMP flags */
  313.     WINDOWDRAG |
  314.     ACTIVATE   |
  315.     NOCAREREFRESH,    /* other window flags */
  316.     NULL,        /* first gadget in gadget list */
  317.     NULL,        /* custom CHECKMARK imagery */
  318.     NULL,        /* window title */
  319.     NULL,        /* custom screen pointer */
  320.     NULL,        /* custom bitmap */
  321.       5,   5,    /* minimum width and height */
  322.          -1,  -1,    /* maximum width and height */
  323.     CUSTOMSCREEN    /* destination screen type */                        
  324. };
  325.  
  326. /* -------------------------------------------------------------------- */
  327. /* Default palette. Change this if you don't like the colors provided    */
  328. /* by me. Versions 25 and higher are supporting a custom default file.    */
  329. /* -------------------------------------------------------------------- */
  330.  
  331. USHORT Palette[128] = {
  332.     0x0000,    /* color #0 */
  333.     0x0F90,    /* color #1 */
  334.     0x0F20,    /* color #2 */
  335.     0x0840,    /* color #3 */
  336.     0x0580,    /* color #4 */
  337.     0x0589,    /* color #5 */
  338.     0x055F,    /* color #6 */
  339.     0x0A0F,    /* color #7 */
  340.     0x0F08,    /* color #8 */
  341.     0x0777,    /* color #9 */
  342.     0x0080,    /* color #10 */
  343.     0x00A0,    /* color #11 */
  344.     0x00C0,    /* color #12 */
  345.     0x00E0,    /* color #13 */
  346.     0x08E0,    /* color #14 */
  347.     0x0FF0,    /* color #15 */
  348.     0x0000,    /* color #16 */
  349.     0x0F90,    /* color #17 */
  350.     0x0F20,    /* color #18 */
  351.     0x0840,    /* color #19 */
  352.     0x0580,    /* color #20 */
  353.     0x0589,    /* color #21 */
  354.     0x055F,    /* color #22 */
  355.     0x0A0F,    /* color #23 */
  356.     0x0F08,    /* color #24 */
  357.     0x0777,    /* color #25 */
  358.     0x0080,    /* color #26 */
  359.     0x00A0,    /* color #27 */
  360.     0x00C0,    /* color #28 */
  361.     0x00E0,    /* color #29 */
  362.     0x08E0,    /* color #30 */
  363.     0x0FF0    /* color #31 */
  364. #define PaletteColorCount 32
  365. };
  366.  
  367. /* -------------------------------------------------------------------- */
  368. /* Close everything opened at runtime                    */
  369. /* -------------------------------------------------------------------- */
  370.  
  371. void CleanUp(void)
  372. {
  373.     if ( FReq )        FreeAslRequest(FReq);
  374.     if ( request )        DeleteExtIO((struct IORequest *) request);
  375.     if ( printerPort )    DeletePort(printerPort);
  376.     if ( IFFfile )        xCloseIFF(IFFfile);
  377.     if ( w )        CloseWindow(w);
  378.     if ( u )        CloseWindow(u);
  379.     if ( glist )        FreeGads();
  380.     if ( s )        CloseScreen(s);
  381.     if ( GadToolsBase )    CloseLibrary(GadToolsBase);
  382.     if ( ColorBase )    CloseLibrary(ColorBase);
  383.     if ( AslBase )        CloseLibrary(AslBase);
  384.     if ( IFFBase )        CloseLibrary(IFFBase);
  385.     if ( GfxBase )        CloseLibrary(GfxBase);
  386.     if ( IntuitionBase )    CloseLibrary(IntuitionBase);
  387.     exit(0);
  388. }
  389.  
  390. /* -------------------------------------------------------------------- */
  391. /* Open all used libraries, ports, etc. If this routine fails you are    */
  392. /* probably not up-to-date with one or several of the shared libraries    */
  393. /* used by me. Copy the provided libraries to your LIBS: directory,    */
  394. /* reboot (!) and try again.                        */
  395. /* -------------------------------------------------------------------- */
  396.  
  397. void OpenLibs(void)
  398. {
  399.     IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 36);
  400.     if ( ! IntuitionBase ) {
  401.         Apfel_Alert(1);
  402.         CleanUp();
  403.     }
  404.  
  405.     GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 36);
  406.     if ( ! GfxBase ) {
  407.         Apfel_Alert(2);
  408.         CleanUp();
  409.     }
  410.  
  411.     IFFBase = (struct IFFBase *) OpenLibrary(IFFNAME, IFFVERSION);
  412.     if ( ! IFFBase ) {
  413.         Apfel_Alert(3);
  414.         CleanUp();
  415.     }
  416.  
  417.     AslBase = OpenLibrary(AslName, 0);
  418.     if ( ! AslBase ) {
  419.         Apfel_Alert(4);
  420.         CleanUp();
  421.     }
  422.  
  423.     ColorBase = (struct ColorBase *) OpenLibrary(COLORNAME, COLORVERSION);
  424.     if ( ! ColorBase ) {
  425.         Apfel_Alert(5);
  426.         CleanUp();
  427.     }
  428.  
  429.     GadToolsBase = (struct GadToolsBase *) OpenLibrary("gadtools.library", 0);
  430.     if ( ! GadToolsBase ) {
  431.         Apfel_Alert(15);
  432.         CleanUp();
  433.     }
  434.  
  435.     FReq = AllocFileRequest();
  436.     if ( ! FReq ) {
  437.         Apfel_Alert(6);
  438.         CleanUp();
  439.     }
  440.  
  441.     printerPort = CreatePort("Apfel-01.port",0L);
  442.     if ( ! printerPort ) {
  443.         Apfel_Alert(7);
  444.         CleanUp();
  445.     }
  446.  
  447.     request = (union printerIO *) CreateExtIO(printerPort, sizeof(union printerIO));
  448.     if ( ! request ) {
  449.         Apfel_Alert(8);
  450.         CleanUp();
  451.     }
  452. }
  453.  
  454. /* -------------------------------------------------------------------- */
  455. /* Open the control window and set gadget texts to appropriate values    */
  456. /* -------------------------------------------------------------------- */
  457.  
  458. void OpenRW(void)
  459. {
  460.     int wbflag = FALSE;
  461.  
  462.     NW2.Screen = s;
  463.     if ( ! s ) {
  464.         NW2.Type = WBENCHSCREEN;
  465.     }
  466.     else {
  467.         NW2.Type = CUSTOMSCREEN;
  468.     }
  469.  
  470.     if ( task ) {
  471.         SelNo_TASK = 1;
  472.     }
  473.     else {
  474.         SelNo_TASK = 0;
  475.     }
  476.  
  477.     if ( cycle ) {
  478.         SelNo_CYCLE = 1;
  479.     }
  480.     else {
  481.         SelNo_CYCLE = 0;
  482.     }
  483.  
  484.     if ( ! s ) {
  485.         s    = LockPubScreen("Workbench");
  486.         wbflag    = TRUE;
  487.     }
  488.  
  489.     glist = InitGads(s);
  490.  
  491.     if ( ! glist ) CleanUp();
  492.  
  493.     u = OpenWindowTags(&NW2, WA_Gadgets, glist, TAG_END);
  494.     if ( wbflag ) {
  495.         UnlockPubScreen(NULL, s);
  496.         s    = NULL;
  497.     }
  498.                     /* open control window         */
  499.     if ( ! u ) {            /* if something goes wrong...    */
  500.         Apfel_Alert(9);        /* give message.        */
  501.         if ( s ) {        /* is the screen open, then ?    */
  502.             CloseScreen(s);    /* close it...            */
  503.             s = NULL;
  504.             OpenRW();    /* and retry on WB Screen...    */
  505.         }
  506.         else {            /* No screen, no hope...    */
  507.             CleanUp();    /* exiting...            */
  508.         }
  509.     }
  510.  
  511.     up = u->RPort;
  512.     GT_RefreshWindow(u, NULL);
  513. }
  514.  
  515. void CloseRW(void)
  516. {
  517.     if ( u ) {
  518.         strcpy(DefBuf_REAL0  ,Buf_REAL0);
  519.         strcpy(DefBuf_REAL1  ,Buf_REAL1);
  520.         strcpy(DefBuf_IMAG0  ,Buf_IMAG0);
  521.         strcpy(DefBuf_IMAG1  ,Buf_IMAG1);
  522.         strcpy(DefBuf_MAXITER,Buf_MAXITER);
  523.         strcpy(DefBuf_DIV    ,Buf_DIV);
  524.         strcpy(DefBuf_XSIZE  ,Buf_XSIZE);
  525.         strcpy(DefBuf_YSIZE  ,Buf_YSIZE);
  526.         strcpy(DefBuf_DEPTH  ,Buf_DEPTH);
  527.         DefText_REAL0    = DefBuf_REAL0; 
  528.         DefText_REAL1    = DefBuf_REAL1;
  529.         DefText_IMAG0    = DefBuf_IMAG0;
  530.         DefText_IMAG1    = DefBuf_IMAG1;
  531.         DefText_MAXITER    = DefBuf_MAXITER;
  532.         DefText_DIV    = DefBuf_DIV;
  533.         DefText_XSIZE    = DefBuf_XSIZE;
  534.         DefText_YSIZE    = DefBuf_YSIZE;
  535.         DefText_DEPTH    = DefBuf_DEPTH;
  536.         CloseWindow(u);
  537.         FreeGads();
  538.         u    = NULL;
  539.         glist    = NULL;
  540.     }
  541. }
  542.  
  543. /* -------------------------------------------------------------------- */
  544. /* Open screen & window for graphics rendition trying to evaluate a    */
  545. /* "best match" for the view modes for both PAL and NTSC. Maybe this    */
  546. /* needs a little work for optimal results on NTSC machines.        */
  547. /* I plan to rework this completely after CBM pops out Kick 2.0 for    */
  548. /* the A2000 in an official version.                    */
  549. /* -------------------------------------------------------------------- */
  550.  
  551. void OpenAll(void)
  552. {
  553.     USHORT    Modes = 0;
  554.     int    cnt;
  555.  
  556.     NS.Width    = xsize;
  557.     NS.Height    = ysize;
  558.     NS.Depth    = depth;
  559.     maxcol        = cnt        = 1 << depth;
  560.  
  561.     if ( xsize > 350 )        Modes  = HIRES;
  562.     if ( ! Modes && depth == 6 ) {
  563.         Modes    = EXTRA_HALFBRITE;
  564.         cnt    = 32;
  565.     }
  566.     if ( ysize > 262 )        Modes |= LACE;
  567.  
  568.     NS.ViewModes = Modes;
  569.  
  570.     s = OpenScreenTags(&NS,
  571.                 SA_Overscan,    OSCAN_STANDARD,
  572.                 SA_AutoScroll,    TRUE,
  573.                 SA_FullPalette,    TRUE,
  574.                 SA_SysFont,    0,
  575.                 SA_Pens,    PenSpec,
  576.                 TAG_DONE);
  577.     if ( ! s ) {
  578.         Apfel_Alert(10);
  579.     }
  580.     else {
  581.         NW.Screen    = s;
  582.         NW.Width    = gx;
  583.         NW.Height    = gy;
  584.         NW.LeftEdge    = (xsize - gx) / 2;
  585.         NW.TopEdge    = (ysize - gy) / 2;
  586.         w = OpenWindow(&NW);
  587.         if ( ! w ) {
  588.             Apfel_Alert(9);
  589.         }
  590.         else {
  591.             rp = w->RPort;
  592.             vp = &(s->ViewPort);
  593.             LoadRGB4(vp, Palette, cnt);
  594.         }
  595.     }
  596. }
  597.  
  598. /* -------------------------------------------------------------------- */
  599. /* Load an IFF ILBM file and get it displayed on the graphics screen.    */
  600. /* I have not put too much work into this, e.g. there is no chunk for    */
  601. /* the data needed to re-calculate the loaded Mandelbrot image.        */
  602. /* Comments and help are welcome, just send me a message to my E-Mail    */
  603. /* adress.                                */
  604. /* -------------------------------------------------------------------- */
  605.  
  606. BOOL LoadFile(char *Name)
  607. {
  608.     struct BitMapHeader *bmhd;
  609.     ULONG cnt;
  610.  
  611.     IFFfile = xOpenIFF(Name);
  612.     if ( ! IFFfile ) {
  613.         Apfel_Alert(12);
  614.     }
  615.     else {
  616.         bmhd = GetBMHD(IFFfile);
  617.         if ( ! bmhd ) {
  618.             Apfel_Alert(13);
  619.         }
  620.         else {
  621.             NS.Width    = gx    = xsize    = bmhd->w;
  622.             NS.Height    = gy    = ysize    = bmhd->h;
  623.             NS.Depth    = depth    = bmhd->nPlanes;
  624.             maxcol        = 1 << depth;
  625.             NS.ViewModes    = GetViewModes(IFFfile);
  626.             s        =
  627.                 OpenScreenTags(&NS,
  628.                     SA_Overscan,    OSCAN_STANDARD,
  629.                     SA_AutoScroll,    TRUE,
  630.                     SA_SysFont,    1,
  631.                     TAG_DONE);
  632.             if ( ! s ) {
  633.                 Apfel_Alert(10);
  634.             }
  635.             else {
  636.                 vp        = &(s->ViewPort);
  637.                 cnt        = GetColorTab(IFFfile, (WORD *) Palette);
  638.                 NW.Screen    = s;
  639.                 NW.Width    = gx;
  640.                 NW.Height    = gy;
  641.                 w        = OpenWindow(&NW);
  642.                 if ( ! w ) {
  643.                     Apfel_Alert(9);
  644.                     CloseScreen(s);
  645.                     s = NULL;
  646.                 }
  647.                 else {
  648.                     rp        = w->RPort;
  649.                     LoadRGB4(vp, Palette, cnt);
  650.                     if ( ! DecodePic(IFFfile, rp->BitMap) ) {
  651.                         Apfel_Alert(14);
  652.                         CloseWindow(w);
  653.                         w = NULL;
  654.                         CloseScreen(s);
  655.                         s = NULL;
  656.                     }
  657.                 }
  658.             }
  659.         }
  660.         xCloseIFF(IFFfile);
  661.         IFFfile        = NULL;
  662.     }
  663.     return ( w != NULL );        /* All OK if window still open */
  664. }
  665.  
  666. /* -------------------------------------------------------------------- */
  667. /* Set default values for the control window. Load the default image to    */
  668. /* comfortably get zoomed into this wonderful world of chaos.        */
  669. /* -------------------------------------------------------------------- */
  670.  
  671. void SetDefault(void)
  672. {
  673.     FILE    *fp;
  674.     char     defpic[FMSIZE];
  675.     int     i;
  676.     int     omt;
  677.     long     tmp;
  678.  
  679.     omt = task;
  680.  
  681.     fp = fopen("Apfelkiste.config", "r");
  682.     if ( ! fp ) fopen("DEVS:Apfelkiste.config", "r");
  683.     if ( ! fp ) fopen("S:Apfelkiste.config", "r");
  684.     if ( ! fp ) {
  685.         Apfel_Alert(11);
  686.         strcpy(defpic, "Apfel0.IFF");
  687.         rmin        = -2.3;
  688.         imin        = -1.25;
  689.         rmax        =  0.825;
  690.         imax        =  1.25;
  691.         maxiter        = 30;
  692.         divergenz    =  6.0;
  693.         cycle        = FALSE;
  694.         task        = TRUE;
  695.     }
  696.     else {
  697.         fscanf(fp, "FNAME=%s", defpic);
  698.         fscanf(fp, "RMIN=%lf", &rmin);
  699.         fscanf(fp, "RMAX=%lf", &rmax);
  700.         fscanf(fp, "IMIN=%lf", &imin);
  701.         fscanf(fp, "IMAX=%lf", &imax);
  702.         fscanf(fp, "MAXITER=%d", &maxiter);
  703.         fscanf(fp, "DIVERGENZ=%lf", &divergenz);
  704.         fscanf(fp, "TASK=%d", &task);
  705.         fscanf(fp, "CYCLE=%d", &cycle);
  706.         for ( i = 0; i < PaletteColorCount; i++ ) {
  707.             fscanf(fp, "COLOR=%x", &tmp);
  708.             Palette[i] = (UWORD) tmp;
  709.         }
  710.         fclose(fp);
  711.     }
  712.  
  713.     if ( ! LoadFile("Apfel0.IFF") ) {
  714.         xsize    = gx    = 320;
  715.         ysize    = gy    = 200;
  716.         depth    = 2;
  717.         maxcol    = 1 << depth;
  718.     }
  719.  
  720.     dx = (rmax - rmin) / (double) gx;
  721.     dy = (imax - imin) / (double) gy;
  722.  
  723.     sprintf(DefBuf_REAL0  , "%lf", rmin);
  724.     sprintf(DefBuf_REAL1  , "%lf", rmax);
  725.     sprintf(DefBuf_IMAG0  , "%lf", imin);
  726.     sprintf(DefBuf_IMAG1  , "%lf", imax);
  727.     sprintf(DefBuf_MAXITER, "%d" , maxiter);
  728.     sprintf(DefBuf_DIV    , "%lf", divergenz);
  729.     sprintf(DefBuf_XSIZE  , "%d" , gx);
  730.     sprintf(DefBuf_YSIZE  , "%d" , gy);
  731.     sprintf(DefBuf_DEPTH  , "%d" , depth);
  732.     DefText_REAL0    = DefBuf_REAL0; 
  733.     DefText_REAL1    = DefBuf_REAL1;
  734.     DefText_IMAG0    = DefBuf_IMAG0;
  735.     DefText_IMAG1    = DefBuf_IMAG1;
  736.     DefText_MAXITER    = DefBuf_MAXITER;
  737.     DefText_DIV    = DefBuf_DIV;
  738.     DefText_XSIZE    = DefBuf_XSIZE;
  739.     DefText_YSIZE    = DefBuf_YSIZE;
  740.     DefText_DEPTH    = DefBuf_DEPTH;
  741.  
  742.     if ( omt != task ) {
  743.         if ( task ) {
  744.             Permit();
  745.         }
  746.         else {
  747.             Forbid();
  748.         }
  749.     }
  750. }
  751.  
  752. /* -------------------------------------------------------------------- */
  753. /* Used by load/save routines to get filenames.                */
  754. /* -------------------------------------------------------------------- */
  755.  
  756. BOOL GetFileName(char *Name, char *Hail)
  757. {
  758.     if ( AslRequestTags(FReq,
  759.                 ASL_Hail,    Hail,
  760.                 ASL_Window,    w,
  761.                 TAG_DONE) ) {
  762.         strmfp(Name, FReq->rf_Dir, FReq->rf_File);
  763.         return TRUE;
  764.     }
  765.     else {
  766.         return FALSE;
  767.     }
  768. }
  769.  
  770. /************************************************************************/
  771. /* The main() function, at last...                    */
  772. /* Contains the handling to react on gadget activation and manage the    */
  773. /* call of the diverse subroutines.                    */
  774. /* Not commented at all, but shouldn't be too difficult to read anyway.    */
  775. /************************************************************************/
  776.  
  777. void main(int argc, char *argv[])
  778. {
  779.     char    fname[80];
  780.     int    i, x, y;
  781.     double    help;
  782.     int    mx1, my1, mx2, my2;
  783.     UWORD    c_palette[128];
  784.  
  785.     OpenLibs();
  786.     SetDefault();
  787.     OpenRW();
  788.  
  789.     do {
  790.         WaitPort(u -> UserPort);
  791.         GT_GetMessage(u);
  792.  
  793.         switch ( CLASS ) {
  794.         case IDCMP_REFRESHWINDOW:
  795.             GT_BeginRefresh(u);
  796.             GT_EndRefresh(u, TRUE);
  797.             break;
  798.         case IDCMP_GADGETUP:
  799.             switch ( GAD_ID ) {
  800.             case GAD_FLOAT:
  801.             case GAD_FXP:
  802.                 sscanf(Buf_REAL0  , "%lf", &rmin);
  803.                 sscanf(Buf_REAL1  , "%lf", &rmax);
  804.                 sscanf(Buf_IMAG0  , "%lf", &imin);
  805.                 sscanf(Buf_IMAG1  , "%lf", &imax);
  806.                 sscanf(Buf_MAXITER, "%d" , &maxiter);
  807.                 sscanf(Buf_DIV    , "%lf", &divergenz);
  808.                 sscanf(Buf_XSIZE  , "%d" , &gx);
  809.                 sscanf(Buf_YSIZE  , "%d" , &gy);
  810.                 sscanf(Buf_DEPTH  , "%d" , &depth);
  811.  
  812.                 xsize = gx;
  813.                 if ( gx <= 736 ) xsize = 736;    /* Max. Overscan Hires    */
  814.                 if ( gx <= 640 ) xsize = 640;    /* Nor. Size Hires    */
  815.                 if ( gx <= 368 ) xsize = 368;    /* Max. Overscan Lores    */
  816.                 if ( gx <= 320 ) xsize = 320;    /* Nor. Size Lores    */
  817.  
  818.                 ysize = gy;
  819.                 if ( gy <= 564 ) ysize = 564;    /* Max. Overscan Lace   PAL    */
  820.                 if ( gy <= 512 ) ysize = 512;    /* Nor. Size Lace       PAL    */
  821.                 if ( gy <= 400 ) ysize = 400;    /* Nor. Size Lace       NTSC    */
  822.                 if ( gy <= 282 ) ysize = 282;    /* Max. Overscan NoLace PAL    */
  823.                 if ( gy <= 256 ) ysize = 256;    /* Nor. Size NoLace    PAL    */ 
  824.                 if ( gy <= 200 ) ysize = 200;    /* Nor. Size NoLace     NTSC    */
  825.                 if ( w ) CloseWindow(w);
  826.                 w = NULL;
  827.                 CloseRW();
  828.                 if ( s ) CloseScreen(s);
  829.                 s = NULL;
  830.                 OpenAll();
  831.                 if (  w && s ) {
  832.                     dx   = (rmax - rmin) / (double) gx;
  833.                     dy   = (imax - imin) / (double) gy;
  834.  
  835.                     switch ( GAD_ID ) {
  836.                     case GAD_FLOAT:
  837.                         help = rmin;
  838.                         for ( x = 0; x < gx; x++ ) {
  839.                             SetAPen(rp, Iter_FLOAT(help, imin));
  840.                             WritePixel(rp, x, 0);
  841.                             SetAPen(rp, Iter_FLOAT(help, imax));
  842.                             WritePixel(rp, x, gy-1);
  843.                             help += dx;
  844.                         }
  845.  
  846.                         help = imin;
  847.                         for ( y = 0; y < gy; y++ ) {
  848.                             SetAPen(rp, Iter_FLOAT(rmin, help));
  849.                             WritePixel(rp, 0, y);
  850.                             SetAPen(rp, Iter_FLOAT(rmax, help));
  851.                             WritePixel(rp, gx-1, y);
  852.                             help += dy;
  853.                         }
  854.  
  855.                         Apfel_FLOAT(0, 0, gx - 1, gy - 1);
  856.                         break;
  857.                     case GAD_FXP:
  858.                          FixPoint(rmin, rmax, imin, imax, dx, dy,
  859.                              maxiter, divergenz,
  860.                              gx, gy, depth);
  861.                         break;
  862.                     }
  863.                 }
  864.                 else {
  865.                     if ( s ) {
  866.                         CloseScreen(s);
  867.                         s = NULL;
  868.                     }
  869.                 }
  870.                 OpenRW();
  871.                 break;
  872.             case GAD_QUIT:
  873.                 CleanUp();
  874.                 break;
  875.             case GAD_SAVE:
  876.                 CloseRW();
  877.                 if ( GetFileName(fname, "Save Picture") ) {
  878.                     SaveBitMap(fname, &(s->BitMap), Palette, 0x1L);
  879.                 }
  880.                 OpenRW();
  881.                 break;
  882.             case GAD_LOAD:
  883.                 CloseRW();
  884.                 if ( GetFileName(fname, "Load Picture") ) {
  885.                     if ( w ) CloseWindow(w);
  886.                     w = NULL;
  887.                     if ( s ) CloseScreen(s);
  888.                     s = NULL;
  889.                     if ( ! LoadFile(fname) ) {;}
  890.                 }
  891.                 OpenRW();
  892.                 break;
  893.             case GAD_REAL0:
  894.                 Activate_Gadget(u, GAD_REAL1);
  895.                 break;
  896.             case GAD_REAL1:
  897.                 Activate_Gadget(u, GAD_IMAG0);
  898.                 break;
  899.             case GAD_IMAG0:
  900.                 Activate_Gadget(u, GAD_IMAG1);
  901.                 break;
  902.             case GAD_IMAG1:
  903.                 Activate_Gadget(u, GAD_MAXITER);
  904.                 break;
  905.             case GAD_MAXITER:
  906.                 Activate_Gadget(u, GAD_DIV);
  907.                 break;
  908.             case GAD_DIV:
  909.                 Activate_Gadget(u, GAD_XSIZE);
  910.                 break;
  911.             case GAD_XSIZE:
  912.                 Activate_Gadget(u, GAD_YSIZE);
  913.                 break;
  914.             case GAD_YSIZE:
  915.                 Activate_Gadget(u, GAD_DEPTH);
  916.                 break;
  917.             case GAD_DEPTH:
  918.                 Activate_Gadget(u, GAD_REAL0);
  919.                 break;
  920.             case GAD_MOUSE:
  921.                 if ( s && w ) {
  922.                     CloseRW();
  923.                     ModifyIDCMP(w, MOUSEBUTTONS | INTUITICKS);
  924.                     do {
  925.                         WaitPort(w->UserPort);
  926.                         GetMessage(w);
  927.                     } while ( CLASS != MOUSEBUTTONS || CODE != SELECTDOWN );
  928.  
  929.                     mx2 = mx1 = w->MouseX;
  930.                     my2 = my1 = w->MouseY;
  931.                     SetDrMd(rp, JAM2 | COMPLEMENT);
  932.                     SetAPen(rp, 1L);
  933.                     DrawRect(rp, mx1, my1, mx2, my2);
  934.  
  935.                     do {
  936.                         if ( mx2 != w->MouseX || my2 != w->MouseY ) {
  937.                             DrawRect(rp, mx1, my1, mx2, my2);
  938.                             mx2 = w->MouseX;
  939.                             my2 = w->MouseY;
  940.                             DrawRect(rp, mx1, my1, mx2, my2);
  941.                         }
  942.                         Wait(1L << w->UserPort->mp_SigBit);
  943.                         GetMessage(w);
  944.                     } while ( CLASS != MOUSEBUTTONS || CODE != SELECTUP );
  945.  
  946.                     DrawRect(rp, mx1, my1, mx2, my2);
  947.                     if ( mx1 > mx2 ) {
  948.                         i    = mx1;
  949.                         mx1    = mx2;
  950.                         mx2    = i;
  951.                     }
  952.                     if ( my1 > my2 ) {
  953.                         i    = my1;
  954.                         my1    = my2;
  955.                         my2    = i;
  956.                     }
  957.                     ModifyIDCMP(w, NULL);
  958.  
  959.                     sprintf(DefBuf_REAL0, "%lf", mx1*dx+rmin);
  960.                     sprintf(DefBuf_REAL1, "%lf", mx2*dx+rmin);
  961.                     sprintf(DefBuf_IMAG0, "%lf", my1*dy+imin);
  962.                     sprintf(DefBuf_IMAG1, "%lf", my2*dy+imin);
  963.                     DefText_REAL0 = DefBuf_REAL0;
  964.                     DefText_REAL1 = DefBuf_REAL1;
  965.                     DefText_IMAG0 = DefBuf_IMAG0;
  966.                     DefText_IMAG1 = DefBuf_IMAG1;
  967.                     OpenRW();
  968.                 }
  969.                 break;
  970.             case GAD_VIEW:
  971.                 if ( s && w ) {
  972.                     CloseRW();
  973.                     memcpy(c_palette, Palette, sizeof(UWORD) * MIN(32, maxcol));
  974.                     ModifyIDCMP(w, MOUSEBUTTONS | INTUITICKS);
  975.                     while ( GetMessage(w) != MOUSEBUTTONS ) {
  976.                         if ( cycle ) {
  977.                             i = c_palette[MIN(31, maxcol-1)];
  978.                             movmem(c_palette+1, c_palette+2, sizeof(UWORD) * MIN(30, maxcol-2 ));
  979.                             c_palette[1] = i;
  980.                             LoadRGB4(vp, c_palette, MIN(32, maxcol));
  981.                             Delay(10L);
  982.                         }
  983.                         WaitPort(w->UserPort);
  984.                     }
  985.                     ModifyIDCMP(w, NULL);
  986.                     LoadRGB4(vp, Palette, MIN(32,maxcol));
  987.                     OpenRW();
  988.                 }
  989.                 break;
  990.             case GAD_PRINT:
  991.                 if ( s && w ) {
  992.                     if ( ! OpenPrinter(request) ) {
  993.                         DumpRPort(request, rp, vp->ColorMap,
  994.                         vp->Modes, 0, 0, s->Width, s->Height, 0, 0,
  995.                         SPECIAL_FULLCOLS | SPECIAL_ASPECT);
  996.                         ClosePrinter(request);
  997.                     }
  998.                 }
  999.                 break;
  1000.             case GAD_CYCLE:
  1001.                 cycle = CODE;
  1002.                 break;
  1003.             case GAD_DEFAULT:
  1004.                 if ( w ) CloseWindow(w);
  1005.                 w = NULL;
  1006.                 CloseRW();
  1007.                 if ( s ) CloseScreen(s);
  1008.                 s = NULL;
  1009.                 SetDefault();
  1010.                 OpenRW();
  1011.                 break;
  1012.             case GAD_TASK:
  1013.                 task = CODE;
  1014.                 if ( task ) {
  1015.                     Permit();
  1016.                 }
  1017.                 else {
  1018.                     Forbid();
  1019.                 }
  1020.                 break;
  1021.             case GAD_ABOUT:
  1022.                 CloseRW();
  1023.                 EasyRequest(w, &ES1, NULL, NULL);
  1024.                 OpenRW();
  1025.                 break;
  1026.             case GAD_COLOR:
  1027.                 if ( s ) {
  1028.                     CloseRW();
  1029.                     if ( ! DoColor(Palette, s) ) {
  1030.                         for ( i = 0; i < MIN(32, maxcol); i++ ) {
  1031.                             Palette[i] = GetRGB4(vp->ColorMap, i);
  1032.                         }
  1033.                     }
  1034.                     OpenRW();
  1035.                 }
  1036.                 break;
  1037.             }
  1038.         }
  1039.     } while ( TRUE );
  1040. }
  1041.