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