home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Science / Science.zip / MANDELPM.ZIP / MANDEL.C < prev    next >
C/C++ Source or Header  |  1990-12-05  |  19KB  |  807 lines

  1. /* 
  2.  *  Microsoft C 5.1 source code 
  3.  *  { Turbo Pascal 4.0 source code }
  4.  *  {$I-}
  5.  *  program Mandel;
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <malloc.h>
  11. #include <string.h>
  12. #include <time.h>
  13.  
  14.  
  15. #if OS2
  16.  
  17. #define INCL_DOS
  18. #define INCL_WIN
  19. #define INCL_GPI
  20. #ifdef M_I386
  21.    #define huge
  22.    #define far
  23.    #define _far
  24.    #define halloc(a,b) malloc(a*b)
  25.    #define CREATETHREAD(a,b,c,d) _beginthread(a,d,NULL)
  26. #else
  27.    #define CREATETHREAD(a,b,c,d) (c=malloc(d),DosCreateThread(a,b,c+d))
  28. #endif
  29. #include "os2.h"
  30. #include "api2.h"
  31.  
  32.  
  33. static HBITMAP   hbm = NULL;
  34. static HDC       hdm ;
  35. static HPS       hpm ;
  36. HAB hab;
  37. HPS hps;
  38. #define plotflag   0x10000L
  39. HWND hwndframe, hwndclient;
  40. #define delay(x) DosSleep((ULONG)(x))
  41. #define restore_palette() gpisetpalette(NULL,NULL,-1L,plotflag)
  42. #define keypressed keypress
  43. #define putpixel(x,y,c) (bitmap[(iymax-1-(y))*(ULONG)ixmax+(x)] = (c),\
  44.                               plot((x),iymax-1-(y),(c)))
  45.  
  46. #else
  47.  
  48. #define INCL_GRAPHICS
  49. #include "api.h"
  50. #define refresh(i)
  51. #define quit   exit
  52. #define delay  dosdelay
  53. #define keypressed inkey
  54. #define putpixel(x,y,c) grphfunc.setpixel((x),(y),(c))
  55.  
  56. #endif
  57.  
  58. USHORT palflag = 1;
  59.  
  60. typedef void far *HANDLE;
  61. #define CX1 320
  62. #define CY1 200
  63. #define MAXPAL  64
  64. #define NCOLORS 256
  65. #define NN      (ncolors/3)
  66. #define MAXCOLOR (NN*3)
  67. #define random(x) ((ULONG)rand() * (x) >> 15)
  68. #define abs(x) ((x) < 0 ? -(x) : (x))
  69. #define SETRGB(r,g,b) (((ULONG)(r)<<16) | ((g) << 8) | (b))
  70. USHORT ncolors = 16, key=0;
  71. static int sem=0;
  72. USHORT ixmax, iymax, xscreen,yscreen;
  73.  
  74. #define real double
  75. int log=0;
  76. int MAX_ITERATIES = 100;
  77. #define MAXITER_MIN  50
  78. #define MAXITER_MAX  1000
  79. int firstcolor = 0;
  80. #define MAX_VALUE     4.0
  81. #define NORMAL          0
  82. #define INIT            1
  83. real range, delta_x, delta_y, x_coord, y_coord;
  84. int x,y;
  85.  
  86. #define MAX_X     ixmax
  87. #define MAX_Y     iymax
  88. int arg_c; char **arg_v;
  89.  
  90. typedef union
  91. {
  92.    ULONG mask;
  93.    struct
  94.    {
  95.       UCHAR blue;
  96.       UCHAR green;
  97.       UCHAR red;
  98.    } color;
  99.    UCHAR array[3];
  100. } COLORS;
  101.  
  102. #define  F   2  /* the "roughness" of the image */
  103.  
  104. char huge *bitmap;
  105. char   ch;
  106. COLORS p[NCOLORS];
  107. COLORS ctbl[NCOLORS];
  108.  
  109. /* static USHORT colorgrad[] = { 1, 2, 4, 9, 10, 11, 13 } ; */
  110. static USHORT colorgrad[] = { 1, 2, 3, 4, 5, 6, 7 } ;
  111. USHORT ngrad  = (sizeof(colorgrad)/sizeof(USHORT));
  112. FILE   *image;
  113. USHORT ixmax, iymax, cx, cy;
  114. char active=0;
  115. USHORT duration=0;
  116.  
  117. #if OS2
  118.                              /* should be called from WM_CHAR message */
  119. int charfrommsg(MPARAM mp1, MPARAM mp2)
  120. {
  121.    int i,ctrl=0,vk; USHORT ch;
  122.    int state = 0;
  123.  
  124.    ch = SHORT1FROMMP(mp2);       /* char code */
  125.    vk = SHORT2FROMMP(mp2);       /* virtual key code */
  126.  
  127.    i = SHORT1FROMMP(mp1);
  128.    if (i & KC_KEYUP)
  129.       return 0 ;
  130.  
  131.    if (i & KC_INVALIDCHAR)
  132.       return 0 ;
  133.  
  134.    if (i & KC_SHIFT)
  135.       state |= 0x300;
  136.    if (i & KC_CTRL)
  137.       state |= 0x400;
  138.    if (i & KC_ALT)
  139.       state |= 0x800;
  140.    if (!vk)
  141.    {
  142.       ctrl = (i & KC_CTRL);
  143.    }
  144.    else
  145.    {
  146.       switch (vk)
  147.       {
  148.          case VK_SHIFT:
  149.          case VK_CTRL:
  150.          case VK_ALT:
  151.             return 0;
  152.          case VK_BACKSPACE:
  153.             return 8 | state;
  154.          case VK_ENTER:
  155.          case VK_NEWLINE:
  156.             return 13 | state;
  157.          case VK_ESC:
  158.             return 27 | state;
  159.          case VK_SPACE:
  160.             return ' ' | state;
  161.          case VK_TAB:
  162.             return 9   | state;
  163.          default:
  164.             return vk | 0x80 | state;
  165.       }
  166.    }
  167.  
  168.    i = CHAR1FROMMP(mp2);         /* ascii code */
  169.    if (i && ctrl)
  170.    {
  171.       return (i & 0x1F) | state;           /* control key */
  172.    }
  173.  
  174.    return i; /* | state; */
  175. }
  176.  
  177. int keypress()
  178. {
  179.  
  180.    if (key == 27)
  181.       return key;
  182.    return 0;
  183. }
  184.  
  185. MRESULT EXPENTRY wndproc (HWND, USHORT, MPARAM, MPARAM) ;
  186.  
  187. main(int argc, char **argv)
  188. {
  189.    static char  name [] = "mandel" ;
  190.    static ULONG fl =
  191.  
  192.                      FCF_SHELLPOSITION ;
  193.    HMQ          hmq ;
  194.    QMSG         qmsg ;
  195.    RECTL r;
  196.  
  197.    arg_c = argc; arg_v = argv;
  198.  
  199.    hab = WinInitialize (0) ;
  200.    hmq = WinCreateMsgQueue (hab, 0) ;
  201.  
  202.    WinRegisterClass (
  203.                   hab,                /* Anchor block handle */
  204.                   name,               /* Name of class being registered */
  205.                   wndproc,            /* Window procedure for class */
  206.                   CS_SIZEREDRAW,      /* Class style */
  207.                   0) ;                /* Extra bytes to reserve */
  208.  
  209.    cx = ixmax = CX1;
  210.    cy = iymax = CY1;
  211.    hwndframe = WinCreateStdWindow (
  212.                   HWND_DESKTOP,       /* Parent window handle */
  213.                   0L,                 /* Style of frame window */
  214.                   &fl,                /* Pointer to control data */
  215.                   name,               /* Client window class name */
  216.                   "Mandelbrot",       /* Title bar text */
  217.                   0L,                 /* Style of client window */
  218.                   NULL,               /* Module handle for resources */
  219.                   0,                  /* ID of resources */
  220.                   &hwndclient) ;      /* Pointer to client window handle */
  221.  
  222.    fl = SWP_SHOW;
  223.    if (argoption('b'))
  224.       fl = SWP_SHOW;
  225.  
  226.    r.xLeft = 0;
  227.    r.yBottom = 0;
  228.    r.xRight = CX1;
  229.    r.yTop = CY1;
  230.  
  231.    WinCalcFrameRect(hwndframe,&r,0);
  232. /*    if (argoption('f')) */
  233.       fl |= SWP_MAXIMIZE;
  234.  
  235.    WinSetWindowPos(hwndframe,NULL, 60,60,r.xRight-r.xLeft, r.yTop-r.yBottom,fl);
  236.  
  237.    while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
  238.         WinDispatchMsg (hab, &qmsg) ;
  239.  
  240.    WinDestroyWindow (hwndframe) ;
  241.    WinDestroyMsgQueue (hmq) ;
  242.    WinTerminate (hab) ;
  243.    return 0 ;
  244. }
  245.  
  246. makebitmap()
  247. {
  248.    int i;
  249.    static BITMAPINFO       *pbmi ;
  250.    static BITMAPINFOHEADER bmp ;
  251.  
  252.    if (!hbm)
  253.    {
  254.                          /*--------------------------
  255.                             Create 320 by 200 bitmap
  256.                            --------------------------*/
  257.  
  258.       bmp.cbFix     = sizeof bmp ;
  259.       bmp.cx        = ixmax;
  260.       bmp.cy        = iymax;
  261.       bmp.cPlanes   = 1 ;
  262.       bmp.cBitCount = 8 ;
  263.  
  264.       if (!pbmi)
  265.       {
  266.          pbmi = malloc (sizeof (BITMAPINFO) + sizeof (RGB)*(NCOLORS-1)) ;
  267.  
  268.          memmove(pbmi, &bmp, sizeof(bmp));
  269.  
  270.          for (i=0; i<ncolors; i++)
  271.          {
  272.             pbmi->argbColor[i].bRed   = ctbl[i].color.red  ;
  273.             pbmi->argbColor[i].bGreen = ctbl[i].color.green;
  274.             pbmi->argbColor[i].bBlue  = ctbl[i].color.blue ;
  275.          }
  276.       }
  277.       hbm = GpiCreateBitmap(hps, &bmp, CBM_INIT, 
  278.          bitmap, (PBITMAPINFO)pbmi);
  279.  
  280.       GpiSetBitmap (hps, hbm) ;
  281.    }
  282.    return TRUE;
  283. }
  284.  
  285. void _cdecl leave(int i)
  286. {
  287.    restore_palette();
  288.    sem = 3;
  289. }
  290.  
  291. clearsquare(int x1, int y1, int x2, int y2, int color)
  292. {
  293.    RECTL r;
  294.    if (x1 < x2 && y1 < y2)
  295.    {
  296.       r.xLeft = x1;
  297.       r.xRight = x2;
  298.       r.yTop = y2;
  299.       r.yBottom = y1;
  300.       WinFillRect(hps, &r, color == -1 ? CLR_BACKGROUND : ctbl[color].mask);
  301.    }
  302. }
  303.  
  304. redraw(int read)
  305. {
  306.    POINTL ptl[4];
  307.    RECTL r;
  308.  
  309.    if (!sem)
  310.       GpiErase(hps);
  311.    else        /* clear remainder of window */
  312.    {
  313.       clearsquare(0, iymax, cx, cy, -1);
  314.       clearsquare(ixmax, 0, cx, iymax, -1);
  315.    }
  316.  
  317.    if (!sem)
  318.       return 0;
  319.  
  320.    makebitmap();
  321.    r.xLeft = 0;
  322.    r.yBottom = 0;
  323.    r.xRight = ixmax;
  324.    r.yTop =   iymax;
  325.    ptl[0].x = ptl[2].x = 0;
  326.    ptl[0].y = ptl[2].y = 0;
  327.    ptl[1].x = cx;
  328.    ptl[1].y = cy;
  329.    ptl[3].x = ixmax;
  330.    ptl[3].y = iymax;
  331.    if (hbm)
  332.    {
  333.       WinDrawBitmap(hps,hbm,&r,&ptl[0],0L,0L,DBM_IMAGEATTRS);
  334. /*       GpiWCBitBlt(hps, hbm, 4L, ptl, ROP_SRCCOPY, BBO_IGNORE); */
  335.       GpiDeleteBitmap(hbm);
  336.       hbm = NULL;
  337.    }
  338.  
  339.    return 0 ;
  340. }
  341.  
  342. refresh(int i)
  343. {
  344.    WinInvalidateRect(hwndclient,NULL ,0);
  345.    WinUpdateWindow(hwndclient);
  346. }
  347.  
  348. static int hidden;
  349. int showhide(HANDLE h, int flag)
  350. {
  351.    static HWND h1,h2,h3,h4;
  352.    static int start;
  353.    if (!h) h = hwndframe;
  354.  
  355. /*
  356.    Hide the title bar and associated controls
  357. */
  358.    if (!hidden && flag)    /* no hide at end of program */
  359.    {
  360.       if (!start)
  361.       {
  362.          h1 = WinWindowFromID ( h , FID_TITLEBAR ) ;
  363.          h2 = WinWindowFromID ( h , FID_SYSMENU ) ;
  364.          h3 = WinWindowFromID ( h , FID_MINMAX ) ;
  365.          h4 = WinWindowFromID ( h , FID_MENU ) ;
  366.          start = 1;
  367.       }
  368.   
  369.       hidden = 1;
  370.   
  371.       if (h1) WinSetParent ( h1 , HWND_OBJECT , FALSE ) ;
  372.       if (h2) WinSetParent ( h2 , HWND_OBJECT , FALSE ) ;
  373.       if (h3) WinSetParent ( h3 , HWND_OBJECT , FALSE ) ;
  374.       if (h4) WinSetParent ( h4 , HWND_OBJECT , FALSE ) ;
  375.   
  376.       WinSendMsg ( h , WM_UPDATEFRAME ,
  377.           ( MPARAM ) ( FCF_TITLEBAR | FCF_SYSMENU | FCF_MINMAX | FCF_MENU ) ,
  378.           NULL ) ;
  379.    }
  380.    else if (hidden)
  381. /*
  382.    Show the title bar and associated controls
  383. */
  384.    {
  385.       hidden = 0;
  386.  
  387.       if (h1) WinSetParent ( h1 , h , FALSE ) ;
  388.       if (h2) WinSetParent ( h2 , h , FALSE ) ;
  389.       if (h3) WinSetParent ( h3 , h , FALSE ) ;
  390.       if (h4) WinSetParent ( h4 , h , FALSE ) ;
  391.   
  392.       WinSendMsg ( h , WM_UPDATEFRAME ,
  393.           ( MPARAM ) ( FCF_TITLEBAR | FCF_SYSMENU | FCF_MINMAX | FCF_MENU ) ,
  394.           NULL ) ;
  395.       if (flag)
  396.          WinInvalidateRect ( h , NULL , TRUE ) ;
  397.    }
  398. }
  399.  
  400. initcolors()
  401. {
  402.    HDC hdc;
  403.    ULONG x,y;
  404.    SIZEL SL;
  405.    gpicolorinit(&x, &y, &ncolors, (PVOID)ctbl, 1L);
  406.    hdc = WinOpenWindowDC(hwndclient);
  407.  
  408.    ixmax = x;
  409.    iymax = y;
  410.    xscreen = x;
  411.    yscreen = y;
  412.  
  413.    SL.cx = 0000;
  414.    SL.cy = 0000;
  415.    hps = GpiCreatePS(hab,hdc,&SL,PU_PELS | GPIF_DEFAULT | GPIT_NORMAL |
  416.          GPIA_ASSOC);
  417.    GpiCreateLogColorTable(hps,LCOL_RESET,LCOLF_RGB,0L,0L,0L);
  418. }
  419.  
  420. void far thread()
  421. {
  422.    int i,j;
  423.    WinInitialize(0);
  424.  
  425.    if (!bitmap)
  426.       bitmap = halloc(((ULONG)ixmax*iymax) >> 4, 0x10);
  427.    if (!bitmap)
  428.       exit(1);
  429.  
  430.    for (i=0; i<ixmax; i++)               /* initialize with zeroes */
  431.    {
  432.       for (j=0; j<iymax; j++)
  433.          bitmap[(ULONG)ixmax*j+i] = 0;
  434.    }
  435.  
  436.    mandelcalc();
  437.    DosExit(EXIT_THREAD,0);
  438. }
  439.  
  440. MRESULT EXPENTRY wndproc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  441. {
  442.    int i;
  443.    static UCHAR start;
  444.    char *stk;
  445.  
  446.    switch (msg)
  447.    {
  448.       case WM_CREATE:
  449.          hwndclient = hwnd;
  450.          initcolors();
  451.          atexit(leave);
  452.          CREATETHREAD(thread, (PUSHORT)&i, stk, 4096);
  453.          DosSetPrty(2,1, 0,i);
  454.          break;
  455.  
  456.       case WM_SETFOCUS:
  457.          active = SHORT1FROMMP(mp2);
  458.          focusevent(active);
  459.          return 0L;
  460.  
  461.       case WM_SIZE:
  462.          cx = SHORT1FROMMP(mp2);
  463.          cy = SHORT2FROMMP(mp2);
  464.          break;
  465.  
  466.       case WM_PAINT:
  467.          WinBeginPaint(hwnd, hps, NULL);
  468.          redraw(0);
  469.  
  470.          WinEndPaint(hps);
  471.          break;
  472.  
  473.       case WM_CHAR:
  474.          key = charfrommsg(mp1,mp2);
  475.          if (key)
  476.             keyevent(key);
  477.          return 0;
  478.  
  479.       case WM_DESTROY:
  480.          showhide(NULL, 0);
  481.          hwndframe = NULL;
  482.          GpiAssociate(hps,NULL);
  483.          GpiDestroyPS(hps);
  484.          break;
  485.  
  486.    }
  487.    return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
  488. }
  489.  
  490. focusevent(int active)
  491. {
  492.    if (!sem)
  493.       return 0;
  494.    if (!active)
  495.       restore_palette();
  496.    else if (palflag)
  497.       setvgapalette(p);
  498. }
  499.  
  500. keyevent(USHORT key)
  501. {
  502.    switch (key & 0xFF)
  503.    {
  504.       case 27:
  505.          exit(1);
  506.          break;
  507.    }
  508. }
  509.  
  510. plot(int x, int y, UCHAR color)
  511. {
  512.    POINTL ptl;
  513.  
  514.    ptl.x = x;
  515.    ptl.y = y;
  516.    GpiSetColor(hps,ctbl[color&(ncolors-1)].mask);
  517.    GpiSetPel(hps, &ptl);
  518. }
  519. #else
  520.  
  521. dosdelay(USHORT i)
  522. {
  523.    time_t t;
  524.    t = clock();
  525.    while (clock() -t < (ULONG)i) ;
  526. }
  527.  
  528. restore()
  529. {
  530.    grphtmode();
  531. }
  532.  
  533. is80x87()        /* DOES NOT WORK ON AN XT !!!! */
  534. {
  535.    int i;
  536.    _asm
  537.    {
  538.       int   11h
  539.       mov   [i],ax
  540.    }
  541.    return i & 2;
  542. }
  543.  
  544. main(int argc, char **argv)
  545. {
  546.    int i;
  547.  
  548.    arg_c = argc; arg_v = argv;
  549.    bitmap = (void far*)(0xA0000000);
  550.    i = grphvideotype();
  551.    if (arg_c < 2)
  552.    {
  553.       printf("MANDEL mandelbrot program.\n");
  554.       printf("Usage: mandel <options>\n");
  555.       printf("-l:     draws a fern leaf\n");
  556.       printf("-innn:  maximum number of iterations (%d..%d)\n",MAXITER_MIN, MAXITER_MAX);
  557.       printf("-n:     do not use color 0 and last entry in color table\n");
  558.       printf("-d:     Log elapsed time after each scan line.");
  559.       printf("-f:     Use 320x200x256\n");
  560.       printf("-p:     Use 640x400x256 mode on Paradise or Video 7 cards\n");
  561.       if (is80x87())
  562.          printf("Math coprocessor installed.\n");
  563.       else
  564.          printf("No Math coprocessor found (or an XT): it will take   H O U R S !!\n");
  565.  
  566.       exit(0);
  567.    }
  568.    if (i != VGA && i != EEGA)
  569.    {
  570.       printf("VGA or EGA required.\n");
  571.       exit(1);
  572.    }
  573.    if (i == VGA && argoption('p'))      /* set 256 color super-VGA */
  574.    {
  575.       grphdata.graph = E_640x400x256;
  576.       grphqchipset(0,1);
  577.    }                                    /* set 320x200x256 */
  578.    if (argoption('f') && grphdata.graph == VGA)
  579.       grphdata.graph = CGA_256;
  580.    onexit(restore);
  581.    grphplinit();
  582.    xscreen = ixmax = grphdata.ixmax;
  583.    yscreen = iymax = grphdata.iymax;
  584.    ncolors = (1 << grphdata.ncolors);
  585.    grphgmode();
  586.    mandelcalc();
  587. }
  588. #endif
  589.  
  590. setvgapalette(COLORS *tp)
  591. {
  592.    int i,j;
  593.    static UCHAR start;
  594.  
  595.    for (i=0; !start && i<ncolors; i++)
  596.    {
  597.       for (j=0; j<3; j++)
  598.          tp[i].array[j] = tp[i].array[j] * (256/MAXPAL);
  599.    }
  600.    start = 1;
  601. #if OS2
  602.    
  603.    if (active && sem != 3) 
  604.       gpisetpalette(NULL, (PVOID)tp, -1L, plotflag);
  605.                          /* break when task switched */
  606. #else
  607.    grphremapallpalette(ncolors, tp);
  608. #endif
  609. }
  610.  
  611. int argoption(char letter)
  612. {
  613.    char c,d;
  614.    int j;
  615.    for (j=1; j<arg_c; j++)
  616.    {
  617.       c = arg_v[j][0]; d = toupper(arg_v[j][1]);
  618.       if ((c == '/' || c == '-') && d == toupper(letter))
  619.        return(j);
  620.    }
  621.    return(0);
  622. }
  623.  
  624. ULONG mixcolor(COLORS color1, COLORS color2, int x1, int x2, int xx, 
  625.                   USHORT max)
  626. {
  627.    int i,tot,diff;
  628.    COLORS result;
  629.  
  630.    tot = x2-x1;
  631.    diff = xx-x1;
  632.    for (i=0; i<3; i++)
  633.    {
  634.       result.array[i] = (((int)color2.array[i]-(int)color1.array[i])*diff/tot)
  635.                         +(int)color1.array[i];
  636.       if (result.array[i] >= max) result.array[i] = max-1;
  637.    }
  638.    return result.mask;
  639. }
  640.  
  641. void change_palette()
  642. {
  643.    int i;
  644.    COLORS c1,c2,c3;
  645.  
  646.  
  647.    p[0].color.red   = 0;
  648.    p[0].color.green = 0;
  649.    p[0].color.blue  = 0;
  650.    p[ncolors-1].color.red   = MAXPAL-1;
  651.    p[ncolors-1].color.green = MAXPAL-1;
  652.    p[ncolors-1].color.blue  = MAXPAL-1;
  653.    c1.mask=SETRGB(0,0,(MAXPAL-1)*2);
  654.    c2.mask=SETRGB(0,(MAXPAL-1)*2,0);
  655.    c3.mask=SETRGB((MAXPAL-1)*2,0,0);
  656.  
  657.    for (i=0; i<NN; i++)   /* create the color wheel */
  658.    {
  659.       p[i+1].mask       = mixcolor(c1, c2, 0, NN, i, MAXPAL);
  660.       p[i+1+NN].mask    = mixcolor(c2, c3, 0, NN, i, MAXPAL);
  661.       if (firstcolor)
  662.       {
  663.          if (i != NN-1)
  664.             p[i+1+NN+NN].mask = mixcolor(c3, c1, 0, NN-1, i, MAXPAL);
  665.       }
  666.       else
  667.          p[i+1+NN+NN].mask = mixcolor(c3, c1, 0, NN+1, i, MAXPAL);
  668.    }
  669.    if (!firstcolor)
  670.       p[0].mask = mixcolor(c3,c1,0,NN+1,NN,MAXPAL);
  671. /* for (i=0; i<ncolors; i++) */
  672. /*   printf("i=%3d,mask=%06lXh\n",i,p[i].mask); */
  673.    setvgapalette(p);
  674. }
  675.  
  676. void init()
  677. {
  678.    range = 0.2;
  679.    delta_x = (range / MAX_X);
  680.    delta_y = (range / MAX_Y);
  681.    y=x=0;
  682.  
  683. /* fijne mandelbrot (x,y) coordinaten voor mooie plaatjes */
  684. /* x_coord = -0.25;  */
  685. /* y_coord = 1.13;   */
  686. /* x_coord = -0.20;  */
  687. /* y_coord = 0.9950; */
  688.  
  689.    x_coord = -0.15;
  690.    y_coord = 0.995;
  691. }
  692.  
  693. static real AAA[] = { 0,    .20,   -.15,  .85 };
  694. static real CCC[] = { 0,    .23,    .26, -.04 };
  695. static real DDD[] = { .16,  .22,    .24,  .85 };
  696. static real EEE[] = { 0,    .00,    .00,  .00 };
  697. static real FFF[] = { 0,   1.6 ,    .44, 1.6  };
  698. static real BBB[] = { 0,   -.26,    .28,  .04 };
  699.  
  700. static real PPP[] = { .01,  .08,    .15, 1.0  };
  701.  
  702. fern()
  703. {
  704.    real ran,x,y,xnew,ynew;
  705.    int i,k,zmax, smax,ix,iy;
  706.  
  707.    sem = 1;
  708.    palflag = 0;
  709.    zmax = yscreen/10;
  710.    smax = xscreen/10;
  711.    x = y = 0.;
  712.  
  713.    for (i=0; i<25000; i++)
  714.    {
  715.       ran = (real)rand()/32768.;
  716.       if (ran < PPP[0])
  717.          k = 0;
  718.       else if (ran < PPP[1])
  719.          k = 1;
  720.       else if (ran < PPP[2])
  721.          k = 2;
  722.       else if (ran < PPP[3])
  723.          k = 3;
  724.       else
  725.          continue;
  726. /*          k = 4; */
  727.  
  728.       xnew =  AAA[k]*x + BBB[k] *y + EEE[k];
  729.       ynew =  CCC[k]*x + DDD[k] *y + FFF[k];
  730.       x = xnew; y = ynew;
  731.       ix = (USHORT)(x*smax)+xscreen/2;
  732.       iy = yscreen-(USHORT)(y*zmax);
  733.       if (ix < xscreen && iy < yscreen)
  734.          putpixel(ix,iy,10);
  735.       if (keypressed())
  736.          exit(1);
  737.    }
  738. }
  739.  
  740. mandelcalc()
  741. {
  742.    int i,j;
  743.    time_t t;
  744.    real a,b,ac,bc,M,b1,t1,t2;
  745.    int I, color;
  746.  
  747.    log = argoption('d');
  748.    if (log)
  749.       freopen("lo","w",stdout);
  750.    if (argoption('l'))
  751.    {
  752.       fern();
  753.       return 0;
  754.    }
  755.    if (argoption('n'))         /* leave first and last color unchanged */
  756.       firstcolor = 1;
  757.    init();
  758.    sem=1;
  759.    for (i=0; i<ncolors; i++)
  760.       p[i] = ctbl[i];
  761.  
  762.    if (i = argoption('i'))
  763.    {
  764.       i = atoi(arg_v[i]+2);
  765.       if (i > MAXITER_MIN && i < MAXITER_MAX)
  766.          MAX_ITERATIES = i;
  767.    }
  768.  
  769.    change_palette();
  770.  
  771.    for (y=0; y < MAX_Y; y++) 
  772.    {
  773.       t = clock();
  774.       bc = (y_coord - (y * delta_y));
  775.       for (x=0; x < MAX_X; x++) 
  776.       {
  777.  
  778.          a = ac =(x_coord + (x * delta_x));
  779.          b = bc;
  780.          M = 0.0;
  781.          I = 0;
  782.          color = firstcolor;
  783.          do 
  784.          {
  785.             b1 = 2.0 * a * b;
  786.             t1 = a*a;
  787.             t2 = b*b;
  788.             a = t1 - t2 + ac;
  789.             b = b1 + bc;
  790.             M =  t1 + t2;
  791.             if (++color > ncolors-firstcolor-1)
  792.                color=firstcolor;
  793.          }
  794.          while (M < MAX_VALUE && ++I < MAX_ITERATIES);
  795.          putpixel(x,y,color);
  796.  
  797.          if (keypressed())
  798.             exit(1);
  799.       } /* while x */
  800.       if (log)
  801.          printf("time=%.2f seconds\n",(real)(clock()-t)/(real)CLK_TCK);
  802.    } /* while y */
  803.  
  804.    sem=2;
  805.    delay(-1);
  806. }  /* end MandelCalc */
  807.