home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / fractal / biomorph.arc / biomorph.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-11  |  17.2 KB  |  872 lines

  1. /*
  2.             BioMorph
  3.             By:  Chris MacDonald & Steve Martin
  4.             Version:  1.0
  5.             Last Revision:  28 July 89
  6.  
  7.     
  8. */
  9.  
  10.  
  11.  
  12.  
  13.  
  14. #include <exec/types.h>
  15. #include <intuition/intuition.h>
  16. #include <stdio.h>
  17. #include <graphics/gfxmacros.h>
  18. #include <math.h>
  19.  
  20.  
  21. /* 
  22. system functions 
  23. */
  24.  
  25. extern struct Screen *OpenScreen ();
  26. extern struct Window *OpenWindow();
  27. extern struct Library *OpenLibrary();
  28. extern struct ViewPort *ViewPortAddress();
  29.  
  30.  
  31.  
  32. /* 
  33. system variables 
  34. */
  35.  
  36. struct IntuitionBase *IntuitionBase;
  37. struct GfxBase *GfxBase;
  38. struct MathBase *MathBase;
  39. struct Screen *s;
  40. struct Window *w;
  41. struct IntuiMessage *msg;
  42. struct RastPort *rp;
  43. struct ViewPort *vp;
  44.  
  45. /*  
  46. menu stuff
  47. */
  48.  
  49. struct TextAttr Font = 
  50. {
  51.     (STRPTR)"topaz.font",
  52.     TOPAZ_SIXTY,
  53.     FS_NORMAL,
  54.     FPF_ROMFONT
  55. };
  56.  
  57. struct IntuiText GenerateText = {4,1,JAM1,1,1,&Font,
  58.                 (UBYTE *)               "  Generate",NULL};
  59. struct IntuiText StopText ={4,1,JAM1,1,1,&Font,(UBYTE *)"  Stop",NULL};
  60. struct IntuiText QuitText ={4,1,JAM1,1,1,&Font,(UBYTE *)"  Quit",NULL};
  61.     
  62. struct IntuiText GreyText = {4,1,JAM1,1,1,&Font,(UBYTE *) "  Grey",NULL};
  63. struct IntuiText RedText = {4,1,JAM1,1,1,&Font,(UBYTE *)  "  Red",NULL};
  64. struct IntuiText GreenText = {4,1,JAM1,1,1,&Font,(UBYTE *)"  Green",NULL};
  65. struct IntuiText BlueText = {4,1,JAM1,1,1,&Font,(UBYTE *) "  Blue",NULL};
  66.  
  67.  
  68. struct IntuiText TwoText = {4,1,JAM1,1,1,&Font,(UBYTE *)    "   2",NULL};
  69. struct IntuiText FourText = {4,1,JAM1,1,1,&Font,(UBYTE *)   "   4",NULL};
  70. struct IntuiText EightText = {4,1,JAM1,1,1,&Font,(UBYTE *)  "   8",NULL};
  71. struct IntuiText SixteenText = {4,1,JAM1,1,1,&Font,(UBYTE *)"  16",NULL};
  72. struct IntuiText TwentyText = {4,1,JAM1,1,1,&Font,(UBYTE *) "  20",NULL};
  73.  
  74.  
  75. struct IntuiText SquareText ={4,1,JAM1,1,1,&Font,(UBYTE *)"  z^2 + c",NULL};
  76. struct IntuiText CubeText = {4,1,JAM1,1,1,&Font,(UBYTE *) "  z^3 + c",NULL};
  77. struct IntuiText FifthText = {4,1,JAM1,1,1,&Font,(UBYTE *)"  z^5 + c",NULL};
  78.  
  79.     
  80. struct MenuItem Quit = 
  81. {
  82.     NULL,1,26,140,10,ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ,
  83.     0,(APTR) &QuitText,NULL,0x51,NULL,0
  84. };
  85.  
  86. struct MenuItem Stop = 
  87. {
  88.     &Quit,1,14,140,10,ITEMTEXT | ITEMENABLED | HIGHCOMP |
  89.     CHECKIT | COMMSEQ,0xfffffff9,(APTR) &StopText,NULL,0x53,NULL,0
  90. };
  91.  
  92. struct MenuItem Generate = 
  93. {
  94.     &Stop,1,2,140,10,ITEMTEXT | ITEMENABLED | HIGHCOMP | 
  95.     CHECKIT | CHECKED | COMMSEQ,0xfffffffa,(APTR) &GenerateText,
  96.     NULL,0x47,NULL,0
  97. };
  98.  
  99.  
  100. struct MenuItem Blue = 
  101. {
  102.     NULL,1,38,70,10,ITEMTEXT | ITEMENABLED | HIGHCOMP 
  103.     | CHECKIT,0xfffffff7,(APTR) &BlueText,NULL,0,NULL,0
  104. };
  105.  
  106. struct MenuItem Green = 
  107. {
  108.     &Blue,1,26,70,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
  109.     | CHECKIT,0xfffffffb,(APTR) &GreenText,NULL,0,NULL,0
  110. };
  111.  
  112. struct MenuItem Red = 
  113. {
  114.     &Green,1,14,70,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
  115.     | CHECKIT,0xfffffffd,(APTR) &RedText,NULL,0,NULL,0
  116. };
  117.  
  118. struct MenuItem Grey = 
  119. {
  120.     &Red,1,2,70,10,ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKED
  121.     | CHECKIT,0xfffffffe,(APTR) &GreyText,NULL,0,NULL,0
  122. };
  123.  
  124.  
  125. struct MenuItem Twenty = 
  126. {
  127.     NULL,1,50,60,10,ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKED 
  128.     | CHECKIT,0xffffffef,(APTR) &TwentyText,NULL,0,NULL,0
  129. };
  130.  
  131. struct MenuItem Sixteen = 
  132. {
  133.     &Twenty,1,38,60,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
  134.     | CHECKIT,0xfffffff7,(APTR) &SixteenText,NULL,0,NULL,0
  135. };
  136.  
  137. struct MenuItem Eight = 
  138. {
  139.     &Sixteen,1,26,60,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
  140.     | CHECKIT,0xfffffffb,(APTR) &EightText,NULL,0,NULL,0
  141. };
  142.  
  143. struct MenuItem Four = 
  144. {
  145.     &Eight,1,14,60,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
  146.     | CHECKIT,0xfffffffd,(APTR) &FourText,NULL,0,NULL,0
  147. };
  148.  
  149. struct MenuItem Two = 
  150. {
  151.     &Four,1,2,60,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
  152.     | CHECKIT,0xfffffffe,(APTR) &TwoText,NULL,0,NULL,0
  153. };
  154.  
  155.  
  156. struct MenuItem Fifth = 
  157. {
  158.     NULL,1,26,100,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
  159.     | CHECKIT,0xfffffffb,(APTR) &FifthText,NULL,0,NULL,0
  160. };
  161.  
  162. struct MenuItem Cube = 
  163. {
  164.     &Fifth,1,14,100,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
  165.     | CHECKED | CHECKIT,0xfffffffd,(APTR) &CubeText,NULL,0,NULL,0
  166. };
  167.  
  168. struct MenuItem Square = 
  169. {
  170.     &Cube,1,2,100,10,ITEMTEXT | ITEMENABLED | HIGHCOMP
  171.     | CHECKIT,0xfffffffe,(APTR) &SquareText,NULL,0,NULL,0
  172. };
  173.  
  174.  
  175.  
  176.  
  177. struct Menu Zx = {NULL,165,0,80,0,NULL,(BYTE *) "Equation",&Square};
  178. struct Menu Zoom = {&Zx,115,0,50,0,NULL,(BYTE *) "Zoom",&Two};
  179. struct Menu Colors = {&Zoom,55,0,60,0,MENUENABLED,(BYTE *) "Colors",&Grey};
  180. struct Menu File = {&Colors,10,0,45,10,MENUENABLED,
  181.             (BYTE *) "File",&Generate};
  182.  
  183.  
  184.  
  185. /*
  186. voidoids
  187. */
  188.  
  189. void open_all(), close_all(), initmenu();
  190. void addplex(),multplex(),sqrplex(),cubeplex(),analyze(),genmorph();
  191. void mousezoom();
  192.  
  193.  
  194.  
  195. /*
  196. window and screen  (windscreen?)
  197. */
  198.  
  199. struct NewScreen myScreen = 
  200. {
  201.     0,0,
  202.     320,200,
  203.     4,
  204.     1,0,
  205.     0,
  206.     CUSTOMSCREEN,
  207.     NULL,
  208.     (UBYTE *)"BioMorph 1.0",
  209.     NULL,
  210.     NULL
  211. };
  212.  
  213.  
  214. struct NewWindow myWindow =
  215. {
  216.       80,9,
  217.       165, 160,
  218.       0,
  219.       1,
  220.       MENUPICK | MOUSEBUTTONS,
  221.       SMART_REFRESH | ACTIVATE | WINDOWSIZING | 
  222.       WINDOWDRAG | GIMMEZEROZERO,
  223.       NULL,
  224.       NULL,
  225.       (UBYTE *)"z^3 + c",
  226.       NULL,
  227.       NULL,
  228.       50, 40,
  229.       210, 200,
  230.       WBENCHSCREEN
  231. };
  232.  
  233.  
  234. /*
  235. color maps
  236. */
  237.  
  238.  
  239. UWORD greycolortable[] =
  240. {
  241.     0x004,0xfff,0x990,0x059,
  242.     0x666,0x777,0x888,0x999,
  243.     0xaaa,0xbbb,0xccc,0xddd,
  244.     0xeee,0xfff,0x000
  245. };
  246.  
  247. UWORD redcolortable[] =
  248. {
  249.     0x004,0xfff,0x990,0x059,
  250.     0x600,0x700,0x800,0x900,
  251.     0xa00,0xb00,0xc00,0xd00,
  252.     0xe00,0xf00,0x000
  253. };
  254.  
  255. UWORD greencolortable[] =
  256. {
  257.     0x004,0xfff,0x990,0x059,
  258.     0x060,0x070,0x080,0x090,
  259.     0x0a0,0x0b0,0x0c0,0x0d0,
  260.     0x0e0,0x0f0,0x000
  261. };
  262.  
  263. UWORD bluecolortable[] =
  264. {
  265.     0x004,0xfff,0x990,0x059,
  266.     0x006,0x007,0x008,0x009,
  267.     0x00a,0x00b,0x00c,0x00d,
  268.     0x00e,0x00f,0x000
  269. };
  270.  
  271. /*
  272. IDCMP stuff
  273. */
  274.  
  275. struct IntuiMessage *message;
  276. USHORT MessageClass, MessageCode, MousX, MousY;
  277.  
  278.  
  279.  
  280.  
  281. /*        
  282. global variable descriptions        
  283.  
  284.  
  285.     creal,      =    real & imaginary portion of 
  286.     cimag        constant
  287.  
  288.     magfactor =    magnification factor of graph
  289.     
  290.     fnum      =    function power value (2 = square,
  291.             3 = cube, 4 = z ^ 5)
  292.             
  293.     stopflag  =    flag which tells genmorph() to
  294.             quit when Stop is selected from
  295.             File menu
  296.             
  297.     minwinx,  =    minimum window size values, set
  298.     minwiny        to insure user can't size window
  299.             down while generating graph
  300.             
  301.     winx,     =    size of window user selects for
  302.     winy        next graph
  303.  
  304.     mxstart,  =    upper left corner value for mouse
  305.     mystart        zoom box.  transferred to xstart, ystart
  306.             in genmorph()
  307.  
  308.     xstart,   =    upper left corner value of last generated
  309.     ystart        or currently generating graph
  310.     
  311.     increment =    distance between adjacent graph points
  312.     
  313.     size      =     size in pixels of most recently computed
  314.             or currently computing graph
  315.         
  316. */
  317.  
  318.  
  319. float creal, cimag, magfactor, xstart, ystart, mxstart, mystart, increment;
  320. short fnum,stopflag,minwinx,minwiny,winx,winy,size;
  321.  
  322.  
  323.  
  324. main(argc,argv)
  325. int argc;
  326. UBYTE *argv[];
  327. {
  328. /* 
  329. user can enter a '?' or a complex constant 
  330. when starting the program
  331. */
  332.  
  333.     printf("\nBioMorph 1.0\n\nby Chris MacDonald & Steve Martin\n\n");
  334.  
  335.     if (argc == 1)    /* no arguments */
  336.     {
  337.         creal = 0.5;
  338.         cimag = 0.0;
  339.  
  340.         printf("Using default constant:   real      = 0.5\n");
  341.         printf("                          imaginary = 0.0\n\n");
  342.         printf("Next time, try your own constant!\n\n");
  343.         printf("Usage:  Biomorph (real) (imaginary)\n");
  344.         printf("Where real and imaginary are a complex constant\n\n");
  345.         Delay(125);
  346.     }
  347.     else if (argc == 2 && (*argv[1] == '?'))   /* user types '?' */
  348.     {
  349.         printf("\nUsage:  Biomorph (real) (imaginary)\n");
  350.         printf("Where real and imaginary are a complex constant\n\n");
  351.         exit(TRUE);
  352.     }
  353.     else
  354.     {    
  355.         creal = atof(argv[1]);   /* user enters complex constant */
  356.         cimag = 0.0;
  357.         if(argc >= 3) cimag = atof(argv[2]);
  358.         printf("\nComplex constant:\n");
  359.         printf("real      = %f\n",creal);
  360.         printf("imaginary = %f\n\n",cimag);
  361.         Delay(130);
  362.     }
  363.         
  364.     open_all();              /* opens libraries, screen and window */
  365.  
  366.     LoadRGB4(vp,&greycolortable[0],15);     /* load color table */
  367.  
  368.     SetRast(rp,3);                          /* clear window */
  369.  
  370.             /* default graph drawn when program starts */
  371.     magfactor = 20;
  372.  
  373.             /*where upper left corner of graph should be */
  374.     mxstart = -1.0 * magfactor / 2.0;
  375.     mystart = mxstart;
  376.  
  377.     fnum = 3;                       /* function is cube (z^3 + c) */
  378.     genmorph();                     /* generate graph */
  379.     
  380.     
  381.             /* loop which waits for user to access menu */
  382.     while (1)
  383.     {
  384.         if((message = (struct IntuiMessage *)
  385.             GetMsg(w->UserPort)) == NULL)
  386.         {
  387.             Wait(1L << w->UserPort->mp_SigBit);
  388.             continue;
  389.         }
  390.         stopflag = 0;
  391.         MessageClass = message->Class; /* get needed data */
  392.         MessageCode = message->Code;
  393.         MousX = w->GZZMouseX;
  394.         MousY = w->GZZMouseY;
  395.         ReplyMsg(message);              /* respond to message */
  396.         
  397.         switch(MessageClass)
  398.         {
  399.             case MENUPICK :        analyze(MessageCode);
  400.             break;                   /* accessed menu */
  401.             
  402.             case MOUSEBUTTONS :    mousezoom(MessageCode);
  403.             break;             /* pressed mouse button */
  404.         }
  405.         
  406.     }
  407.     
  408. }
  409.  
  410.  
  411.  
  412.  
  413. /*
  414. mousezoom()'s purpose is to generate a "zoom box" while mouse button is
  415. pressed and held down.  When the button is released, the starting 
  416. coordinates and magnification of the selected box are computed.
  417. */
  418.  
  419. /*        mousezoom variable descriptions
  420.  
  421.     loop    =    flag indicating end of zoom
  422.             box loop
  423.     
  424.     setx,    =    the starting window coordinates
  425.     sety        of the zoom box
  426.     
  427.     mx    =    x distance mouse moves from setx
  428. */
  429.  
  430.  
  431. void mousezoom(code)
  432. USHORT code;        /* message code  */
  433. {
  434.     short loop = 1;
  435.     USHORT mx,setx,sety; 
  436.     
  437.     switch(code)
  438.     {
  439.         case SELECTDOWN :            /*left button down*/
  440.         
  441.             setx = MousX;        /*set starting point of*/
  442.             sety = MousY;        /*zoom box             */
  443.             
  444.             if(setx >= 215) setx = 0;  /*fixes problem when mouse*/
  445.             if(sety >= 215) sety = 0;  /*points to left | up edge*/
  446.             
  447.             mx = w->GZZMouseX;    /*get current mouse x position*/
  448.             
  449.             SetWindowTitles(w,"Zooming!",-1);
  450.             
  451.             SetDrMd(rp,COMPLEMENT);    /* "self erasing" mode*/
  452.             SetAPen(rp,1);
  453.             Move(rp,setx,sety);        /*  draw the zoom box */
  454.             Draw(rp,mx,sety);
  455.             Draw(rp,mx,sety + mx - setx);
  456.             Draw(rp,setx,sety + mx -setx);
  457.             Draw(rp,setx,sety);
  458.             
  459.             while (loop)    /*adjusts zoom box while button down*/
  460.             
  461.             {
  462.                 while((message = (struct IntuiMessage *)
  463.                     GetMsg(w->UserPort)) == NULL)
  464.                 {
  465.                     Move(rp,setx,sety);   /* erase old box */
  466.                     Draw(rp,mx,sety);
  467.                     Draw(rp,mx,sety + mx - setx);
  468.                     Draw(rp,setx,sety + mx -setx);
  469.                     Draw(rp,setx,sety);
  470.  
  471.                     mx = w->GZZMouseX;  /* get new x value */
  472.  
  473.                     /*stops dragging box to the left*/
  474.                     if((mx < setx) || (mx > 400)) mx = setx;
  475.  
  476.                     Move(rp,setx,sety);  /* draw new box */
  477.                     Draw(rp,mx,sety);
  478.                     Draw(rp,mx,sety + mx - setx);
  479.                     Draw(rp,setx,sety + mx -setx);
  480.                     Draw(rp,setx,sety);
  481.  
  482.                 }
  483.                 MessageClass = message->Class; /*drops out of loop*/
  484.                 MessageCode = message->Code;   /*when a message   */
  485.                 ReplyMsg(message);             /*occurs           */
  486.                 
  487.                 switch(MessageClass)
  488.                 
  489.                 {
  490.                     case MOUSEBUTTONS:
  491.                     
  492.                     switch(MessageCode)
  493.                     
  494.                     {
  495.                     case SELECTUP:   /* user releases button */
  496.                     
  497.                 /* set new mag & position based on zoom box */
  498.                     magfactor =(mx - setx) * increment;
  499.                     mxstart = xstart +
  500.                           ((setx - 2) * increment);
  501.                     mystart = ystart +
  502.                           ((sety - 1) * increment);
  503.  
  504.                     SetWindowTitles(w,"Got it.",-1);
  505.                     Delay(20);
  506.                     
  507.                     switch(fnum)  /* put window title back */
  508.                     {
  509.                     case 2:
  510.                     SetWindowTitles(w,"z^2 + c",-1);
  511.                     break;
  512.                     
  513.                     case 3:
  514.                     SetWindowTitles(w,"z^3 + c",-1);
  515.                     break;
  516.                     
  517.                     case 4:
  518.                     SetWindowTitles(w,"z^5 + c",-1);
  519.                     break;
  520.                     }
  521.                     
  522.                     Move(rp,setx,sety);  /* erase box */
  523.                     Draw(rp,mx,sety);
  524.                     Draw(rp,mx,sety + mx - setx);
  525.                     Draw(rp,setx,sety + mx -setx);
  526.                     Draw(rp,setx,sety);
  527.  
  528.                     loop = 0;   /* set flag to end loop */
  529.                     break;
  530.                     }
  531.                     break;
  532.                     
  533.                 }
  534.             }    
  535.     }
  536. }
  537.  
  538.  
  539.  
  540. void genmorph()
  541. {
  542.  
  543. /*    
  544.     x,    =    graph loop vars. derived from
  545.     y        current window size
  546.             
  547.     n    =    iteration loop variable
  548.     
  549.     value    =    contains result of window sizing
  550.             call
  551.     
  552.     zreal,    =    current equation coordinates
  553.     zimag
  554.     
  555.     a, b    =    temporary storage for math routines
  556.     
  557. */
  558.     
  559.     
  560.     short x,y,n,value;
  561.     float zreal,zimag,a,b;
  562.  
  563.     SetDrMd(rp,JAM1);
  564.  
  565.     stopflag = 0;   /* flag to stop generating */
  566.     
  567.     /* setting limits of window size */
  568.     winx = w->Width;
  569.     winy = w->Height;
  570.     value = WindowLimits(w,winx,winy,210,200);
  571.     
  572.     /* how large the graph should be, based on window size */
  573.     if(winx < winy)
  574.     {
  575.         size = winx - 8;
  576.     }
  577.     else
  578.     {
  579.         size = winy - 8;
  580.     }
  581.     
  582.     /* how much zreal&imag should be incremented each
  583.        time through loop                  */
  584.     increment = magfactor / size;
  585.     
  586.     xstart = mxstart;    /* assign mousezoom() values */
  587.     ystart = mystart;
  588.  
  589.  
  590.     for(y = 0; y <= size - 6; ++y)   /* y graph loop */
  591.     {
  592.         for(x = 0; x <= size; ++x)   /* x graph loop */
  593.         {
  594.             /* setting z value for current coordinates */
  595.             zreal = ((float) xstart + (increment * x));
  596.             zimag = ((float) ystart + (increment * y));
  597.             
  598.             /* iteration loop */    
  599.             for(n = 1; n <= 10; ++n)
  600.             {
  601.                 a = zreal;
  602.                 b = zimag;
  603.                 
  604.                 if (fnum == 2)    /* square */
  605.                 {
  606.                     zreal = a*a - b*b + creal;
  607.                     zimag = 2*a*b + cimag;
  608.                 }
  609.                 
  610.                 else if (fnum == 3)   /* cube */
  611.                 {
  612.                     zreal = a*(a*a - 3*b*b) + creal;
  613.                     zimag = b*(3*a*a - b*b) + cimag;
  614.                 }
  615.  
  616.                 else if (fnum == 4)   /* fifth */
  617.                 {
  618.                     a = zreal;
  619.                     b = zimag;
  620.  
  621.         zreal = a * (a*a*a*a - 10*a*a*b*b + 5*b*b*b*b) + creal;
  622.         zimag = b * (5*a*a*a*a - 10*a*a*b*b + b*b*b*b) + cimag;
  623.                 }
  624.             
  625.                 
  626.     /* break out of loop if result is ever greater than ten    */
  627.             
  628.                 if(fabs(zreal) > 10 || fabs(zimag) > 10 ||
  629.                     (zreal*zreal + zimag*zimag) > 100)
  630.                     break;
  631.             }
  632.  
  633.             
  634.     /* setting color of pixel based on value of z after iteration */
  635.             
  636.             if(!(fabs(zreal) < 10 || fabs(zimag) < 10))
  637.             {
  638.                 SetAPen(rp,14);
  639.             }
  640.             else if(fabs(zreal) < fabs(zimag)) 
  641.             {
  642.                 SetAPen(rp,((short) fabs(zreal)) + 4);
  643.             }
  644.             else
  645.             {
  646.                 SetAPen(rp,((short) fabs(zimag)) + 4);
  647.             }
  648.             WritePixel(rp,x,y);
  649.         }
  650.  
  651.         
  652.         /* test for menu access at end of each x loop */
  653.         /* clears all messages except newest          */
  654.         MessageClass = NULL;
  655.         while(message = (struct IntuiMessage *)GetMsg(w->UserPort))
  656.         {
  657.             MessageClass = message->Class;
  658.             MessageCode = message->Code;
  659.             ReplyMsg(message);
  660.         }    
  661.         
  662.         if(MessageClass)
  663.         {
  664.             switch(MessageClass)
  665.             {
  666.                 case MENUPICK :    analyze(MessageCode);
  667.                 break;
  668.             }
  669.         }
  670.         
  671.  
  672.         /* quit generating if user picks Stop from File menu */
  673.         if(stopflag)
  674.         {
  675.             stopflag = 0;
  676.             x = size;
  677.             y = size - 6;
  678.         }
  679.  
  680.     }
  681.     
  682.     /* set window size limits back to normal */
  683.     value = WindowLimits(w,50,40,210,200);
  684.     
  685.     /* enable zoom and power menus */
  686.     ClearMenuStrip(w);
  687.     Zx.Flags = MENUENABLED;
  688.     Zoom.Flags = MENUENABLED;
  689.     Stop.Flags |= CHECKED;       /* set Stop checkmark */
  690.     Generate.Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP
  691.     | COMMSEQ | CHECKIT;         /* unset Generate checkmark */
  692.     SetMenuStrip(w,&File);
  693.     DisplayBeep(NULL);           /* flash screen when done */
  694.  
  695. }
  696.  
  697.  
  698.  
  699.  
  700.  
  701.  
  702.  
  703. /* 
  704. analyze():  responds to user menu access 
  705. */
  706.  
  707. void analyze(Menunumber)
  708. USHORT Menunumber;
  709. {
  710.     USHORT Menu, MenuItem;
  711.     
  712.     Menu = MENUNUM(Menunumber);
  713.     MenuItem = ITEMNUM(Menunumber);
  714.     
  715.     switch(Menu)
  716.     {
  717.         case 0    : /* File Menu */
  718.             switch(MenuItem)
  719.             {
  720.                 case 0    : /* Generate */
  721.                     if (!(stopflag))
  722.                     {
  723.                         SetRast(rp,0);
  724.                         ClearMenuStrip(w);
  725.                         Zoom.Flags = NULL;
  726.                         Zx.Flags = NULL;
  727.                         SetMenuStrip(w,&File);
  728.                         genmorph();
  729.                     }
  730.                     break;
  731.                 
  732.                 case 1    : /* Stop */
  733.                     stopflag = 1;
  734.                     ClearMenuStrip(w);
  735.                     Zoom.Flags = MENUENABLED;
  736.                     Zx.Flags = MENUENABLED;
  737.                     SetMenuStrip(w,&File);
  738.                     break;
  739.                     
  740.                 case 2    : /* Quit */
  741.                     close_all();
  742.                     exit(TRUE);
  743.                     break;
  744.             }
  745.         break;
  746.             
  747.         case 1    : /* Colors */
  748.             switch(MenuItem)
  749.             {
  750.                 case 0    : /* Grey */
  751.                     LoadRGB4(vp,&greycolortable[0],15);
  752.                     break;
  753.             
  754.                 case 1    : /* Red */
  755.                     LoadRGB4(vp,&redcolortable[0],15);
  756.                     break;
  757.  
  758.                 case 2    : /* Green */
  759.                     LoadRGB4(vp,&greencolortable[0],15);
  760.                     break;
  761.  
  762.                 case 3    : /* Blue */
  763.                     LoadRGB4(vp,&bluecolortable[0],15);
  764.                     break;
  765.             }
  766.         break;
  767.  
  768.         case 2    : /* Zoom */
  769.             switch(MenuItem)
  770.             {
  771.                 case 0    :
  772.                     magfactor = 2;
  773.                     mxstart = -1.0 * magfactor / 2.0;
  774.                     mystart = mxstart;
  775.                     break;
  776.                     
  777.                 case 1    :
  778.                     magfactor = 4;
  779.                     mxstart = -1.0 * magfactor / 2.0;
  780.                     mystart = mxstart;
  781.                     break;
  782.                 
  783.                 case 2    :
  784.                     magfactor = 8;
  785.                     mxstart = -1.0 * magfactor / 2.0;
  786.                     mystart = mxstart;
  787.                     break;
  788.                 
  789.                 case 3    :
  790.                     magfactor = 16;
  791.                     mxstart = -1.0 * magfactor / 2.0;
  792.                     mystart = mxstart;
  793.                     break;
  794.                 
  795.                 case 4    :
  796.                     magfactor = 20;
  797.                     mxstart = -1.0 * magfactor / 2.0;
  798.                     mystart = mxstart;
  799.                     break;
  800.             }
  801.         break;
  802.  
  803.         case 3    : /* Power */
  804.             switch(MenuItem)
  805.             {
  806.                 case 0    :
  807.                     fnum = 2;
  808.                     SetWindowTitles(w,"z^2 + c",-1);
  809.                     break;
  810.                     
  811.                 case 1    :
  812.                     fnum = 3;
  813.                     SetWindowTitles(w,"z^3 + c",-1);
  814.                     break;
  815.                 
  816.                 case 2    :
  817.                     fnum = 4;
  818.                     SetWindowTitles(w,"z^5 + c",-1);
  819.                     break;
  820.             }
  821.         break;
  822.  
  823.     }
  824. }    
  825.         
  826.         
  827.         
  828. void open_all()
  829. {
  830.     if((IntuitionBase = (struct IntuitionBase *)
  831.           OpenLibrary("intuition.library", 0L)) == NULL)
  832.             exit(1);
  833.     if((MathBase = (struct MathBase *)
  834.           OpenLibrary("mathffp.library", 0L)) == NULL)
  835.             exit(1);
  836.     if ((GfxBase = (struct GfxBase *)
  837.         OpenLibrary("graphics.library", 0L)) == NULL)
  838.             exit(1);
  839.  
  840. if ((s = OpenScreen(&myScreen)) == NULL)
  841.     exit(1);
  842.  
  843. vp = &(s -> ViewPort);
  844.  
  845. myWindow.Screen = s;
  846. myWindow.Type = CUSTOMSCREEN;
  847.     
  848.     if ((w = OpenWindow(&myWindow)) == NULL)
  849.         exit(1);
  850.     rp = w->RPort;
  851.     
  852.     SetMenuStrip(w,&File);
  853. }
  854.  
  855.  
  856.  
  857.  
  858. void close_all()
  859. {
  860.     while(message = (struct IntuiMessage *)GetMsg(w->UserPort))
  861.     {
  862.         ReplyMsg(message);
  863.     }
  864.  
  865.     if (w) ClearMenuStrip(w);
  866.     if (w) CloseWindow(w);
  867.     if (s) CloseScreen(s);
  868.     if (GfxBase) CloseLibrary(GfxBase);
  869.     if (IntuitionBase) CloseLibrary(IntuitionBase);
  870. }
  871.  
  872.