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