home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d0xx / d052 / fractal.lha / Fractal / fractal.c next >
Encoding:
C/C++ Source or Header  |  1987-01-13  |  6.2 KB  |  264 lines

  1. /****************************************************************
  2.  * Fractal.c © John M. Olsen.   9-1-86
  3.  * This is a fractal program which produces random square fractal
  4.  * terrain, with resolution where the size of the sides is
  5.  * 2^n + 1 where n is between 0 and 6.
  6.  * The 3D view uses a light source off to the upper left.
  7.  *
  8.  * This program requires both c.lib and m.lib when linked.  It was written for
  9.  * Aztec and I have no idea what it will do when compiled with Lettuce C.
  10.  * 
  11.  * This program is freely distributable as long as this notice remains
  12.  * with it.  Do not use any part of this program in a commercial application
  13.  * without written consent from the author:
  14.  *
  15.  * John M. Olsen
  16.  * 1547 Jamestown Drive
  17.  * Salt Lake City, UT  84121
  18.  ****************************************************************/
  19.  
  20. #define MAXFRACT 65    /* This must be 2^something + 1 */
  21. #define EVEN(a) (!(a & 1))
  22. #define ODD(a)  (a & 1)
  23.  
  24. #include <exec/types.h>
  25. #include <graphics/gfx.h>
  26. #include <graphics/gfxbase.h>
  27. #include <graphics/gfxmacros.h>
  28. #include <graphics/rastport.h>
  29. #include <intuition/intuition.h>
  30. #include <stdio.h>
  31. #include <math.h>
  32.  
  33. void *OpenLibrary(), *ScreenToBack(), *ScreenToFront();
  34. struct IntuitionBase *IntuitionBase;
  35. struct GfxBase *GfxBase;
  36. struct Screen *OpenScreen(), *s;
  37. struct Window *OpenWindow(), *w;
  38. struct IntuiMessage *GetMsg();
  39. float myrand();
  40.  
  41. BYTE *AllocRaster();
  42. WORD areabuffer[250];
  43. struct TmpRas tmpras;
  44. struct AreaInfo myAreaInfo;
  45.  
  46. struct NewScreen ss =
  47. {    0, 0, 320, 200,        /* Edges & size        */
  48.     5, 0, 1,        /* Depth, pens        */
  49.     NULL, CUSTOMSCREEN,    /* Viewmodes, type    */
  50.     NULL,            /* *font        */
  51.     (UBYTE *) "3D Random Fractal Terrain",
  52.     NULL, NULL        /* Gadgets, bit map    */
  53. };
  54.  
  55. float p[MAXFRACT][MAXFRACT], divisor, scale;
  56. int shadows, degree, size;
  57.  
  58. main()
  59. {
  60.     long sc, mc;
  61.  
  62.     printf("Fractal generator by John M. Olsen ©1986\n\n");
  63.     printf("This program is freely distributable so long as the above\n");
  64.     printf("notice remains in it.\n");
  65.     printf("After a fractal has been computed and drawn, you need to\n");
  66.     printf("push the picture screen back, bringing this screen foreward\n");
  67.     printf("before trying to enter more data.\n");
  68.     if(!(GfxBase = OpenLibrary("graphics.library",0l)))
  69.         die(1);
  70.     if(!(IntuitionBase = OpenLibrary("intuition.library")))
  71.         die(2);
  72.     if(!(s = OpenScreen(&ss)))
  73.         die(3);
  74.     InitArea(&myAreaInfo, areabuffer, 100l);
  75.     s->RastPort.AreaInfo = &myAreaInfo;
  76.     tmpras.RasPtr = AllocRaster(320l, 200l);
  77.     tmpras.Size = (long) RASSIZE(320l, 200l);
  78.     s->RastPort.TmpRas = &tmpras;
  79.     ScreenToBack(s);
  80.     docolors(&(s->RastPort));
  81.     while(1)
  82.     {
  83.         CurrentTime(&sc,&mc);    /* Seed the random number by time */
  84.         myrand(-(int)sc);
  85.         getsize();    /* Exits from this routine. */
  86.         compute();
  87.         ScreenToFront(s);
  88.         draw(&(s->RastPort));
  89.     }
  90. }
  91.  
  92. /* Compute the array. */
  93. compute()
  94. {
  95.     float tempscale, rnum, t1, t2, t3, t4;
  96.     int x, y, n;
  97.  
  98.     /* Zero out the corner of the array. */
  99.     for(x = 0;x < 2; x++)
  100.         for(y = 0; y < 2; y++)
  101.             p[x][y] = 0;
  102.     tempscale = 64.0;
  103.     size = 1;
  104.     for(n = 1; n <= degree; n++)
  105.     {
  106.         size *= 2;
  107.         for(x = size; x >= 0; x--)
  108.         {
  109.             for(y = size; y >= 0; y--)
  110.             {
  111.                 t1 = p[x / 2][y / 2];
  112.                 t2 = p[(x+1) / 2][(y+1)  / 2];
  113.                 t3 = p[x / 2][(y + 1) / 2];
  114.                 t4 = p[(x + 1) / 2][y / 2];
  115.                 rnum = myrand(0) - .5;
  116.                 rnum *= tempscale;
  117.                 if(ODD(x) && EVEN(y))
  118.                 {
  119.                     p[x][y] = (t1 + t4) / 2.0 + rnum;
  120.                 }
  121.                 else if(EVEN(x) && ODD(y))
  122.                 {
  123.                     p[x][y] = (t1 + t3) / 2.0 + rnum;
  124.                 }
  125.                 else if(ODD(x) && ODD(y))
  126.                 {
  127.                     p[x][y] = (t1+t2+t3+t4) / 4.0 + rnum;
  128.                 }
  129.                 else if(EVEN(x) && EVEN(y))
  130.                 {
  131.                     p[x][y] = t1;
  132.                 }
  133.                 else
  134.                     printf("Toasted.\n");
  135.             }
  136.         }
  137.         tempscale /= divisor;
  138.     }
  139.     /* now run it through the scaler. */
  140.     for(x = 0; x <= size; x++)
  141.         for(y = 0; y <= size; y++)
  142.             p[x][y] *= scale;
  143. }
  144.  
  145. die(kind)
  146. int kind;
  147. {
  148.     static char *errortext[] = {    "No error.\n",
  149.                     "Unable to open graphics.\n",
  150.                     "Unable to open Intuition.\n",
  151.                     "Unable to open screen.\n",
  152.                     "4\n",
  153.                     "5\n",
  154.                     "6\n"
  155.                 };
  156.  
  157.     if(kind)
  158.         puts(errortext[kind]);
  159.     if(tmpras.RasPtr)    FreeRaster(tmpras.RasPtr,320l,200l);
  160.     if(s)            CloseScreen(s);
  161.     if(GfxBase)        CloseLibrary(GfxBase);
  162.     if(IntuitionBase)    CloseLibrary(IntuitionBase);
  163.     exit(kind);
  164. }
  165.  
  166. float myrand(seed)
  167. int seed;
  168. {
  169.     static unsigned int val;
  170.  
  171.     if(seed < 0)
  172.         val = - seed;
  173.     val *= 25173;
  174.     val += 13849;
  175.     val %= 32768;
  176.     return((float) val / 32768.0);
  177. }
  178.  
  179. draw(r)
  180. struct RastPort *r;
  181. {
  182.     int h, x, y, cl, sz;
  183.     float slopex, slopey;
  184.  
  185.     SetAPen(r, 0l);
  186.     RectFill(r, 0l,10l,320l,200l);
  187. /*    SetRast(r,0l);  this line took out the title bar.*/
  188.     h = 150;    /* use this many of the 200 lines. */
  189.     for(y = 1; y <= size; y++)
  190.     {
  191.         for(x = 1; x <= size; x++)
  192.         {
  193.             if(shadows)
  194.             {
  195.                 slopex = p[x][y-1];
  196.                 slopex += p[x][y];
  197.                 slopex -= p[x-1][y-1];
  198.                 slopex -= p[x-1][y];
  199.  
  200.                 slopey = p[x][y];
  201.                 slopey -= p[x][y-1];
  202.                 slopey -= p[x-1][y-1];
  203.                 slopey += p[x-1][y];
  204.                 cl = (int) (slopex + slopey) + 15;
  205.             }
  206.             else
  207.             {
  208.                 cl = (int) p[x][y];
  209.                 cl += (int) p[x-1][y];
  210.                 cl += (int) p[x][y-1];
  211.                 cl += (int) p[x-1][y-1];
  212.                 cl /= 8;
  213.                 cl += 16;
  214.             }
  215.             sz = h / (size + 1);
  216.             if(cl > 31)
  217.                 cl = 31;
  218.             if(cl < 1)
  219.                 cl = 1;
  220.             SetAPen(r, (long)cl);
  221.             AreaMove(r, (long)(50+((x-1)*sz+(size-y+1)*60/size)+1),
  222.                 (long)(((y-1)*sz-(int)p[x-1][y-1])+30));
  223. /*+1extra*/        AreaDraw(r, (long)(50+(x*sz+(size-y+1)*60/size)+1),
  224.                 (long)(((y-1)*sz-(int)p[x][y-1])+30));
  225. /*+1 extra*/        AreaDraw(r, (long)(50+(x*sz+(size-y)*60/size)+1),
  226. /*+1 extra*/            (long)((y*sz-(int)p[x][y])+30));
  227.             AreaDraw(r, (long)(50+((x-1)*sz+(size-y)*60/size)+1),
  228.                 (long)((y*sz-(int)p[x-1][y])+30));
  229.             AreaEnd(r);
  230.         }
  231.     }
  232. }
  233.  
  234. /*********************
  235. Set up the colors to 32 gray shades.
  236. *********************/
  237. docolors(r)
  238. struct RastPort *r;
  239. {
  240.     long loop;
  241.  
  242.     r = &(s->RastPort);
  243.     for(loop = 1l; loop < 32l; loop++)
  244.         SetRGB4(&s->ViewPort, loop, loop/2l, (loop - 1)/2l, loop/2l);
  245. }
  246.  
  247. getsize()
  248. {
  249.     printf("Enter the degree(1-6 or invalid to quit): ");
  250.     scanf(" %d", °ree);
  251.     if(degree < 1 || degree > 6)
  252.         die(0);
  253.     printf("Enter the scale(0.0 to 3.0, 1.0 is standard): ");
  254.     scanf(" %f", &scale);
  255.     if(scale > 3.0 || scale < 0.0)
  256.         die(0);
  257.     printf("Enter the divisor(1.0 to 4.0, 2.0 is standard): ");
  258.     scanf(" %f", &divisor);
  259.     if(divisor > 4.0 || divisor < 1.0)
  260.         die(0);
  261.     printf("Altitudes (0) or shadows(non-zero)? ");
  262.     scanf(" %d", &shadows);
  263. }
  264.