home *** CD-ROM | disk | FTP | other *** search
- #include <exec/types.h>
- #include <graphics/gfxbase.h>
- #include <intuition/intuition.h>
- #include <math.h>
- #include <libraries/iff.h>
- #include <ctype.h>
- #include <stdio.h>
-
- #define BITS2SHIFT 27
-
- double atof();
- long atol();
- void *OpenLibrary();
- int height=256;
- struct Window *OpenWindow();
- struct Screen *OpenScreen();
- struct IntuiMessage *GetMsg();
- struct IntuitionBase *IntuitionBase=NULL;
- struct GfxBase *GfxBase=NULL;
- struct Library *IFFBase=NULL;
-
- struct Window *w=NULL;
- struct Screen *s=NULL;
- struct IntuiMessage *msg;
-
- struct NewScreen ns = {0,0,640,512,4,0,0,HIRES|LACE,CUSTOMSCREEN,NULL,NULL,NULL,NULL};
-
- struct NewWindow nw = {
- 0,1,640,511,-1,-1,VANILLAKEY|CLOSEWINDOW,WINDOWCLOSE|NOCAREREFRESH|
- ACTIVATE,NULL,NULL,NULL,NULL,NULL,0,0,0,0,CUSTOMSCREEN};
-
- short ColorMap[32] = { /* format 0x0RGB */
- /* 0-7 */ 0x0000,0x0F00,0x0FB0,0x0FE4,0x0ED9,0x0DDC,0x0CCD,0x0BBC ,
- /* 8-15 */ 0x0AAB,0x099A,0x0889,0x0778,0x0667,0x0556,0x0445,0x0334 ,
- /* 16-23 */ 0x066F,0x0FFF,0x0EEE,0x0DDD,0x0CCC,0x0BBB,0x0AAA,0x0999 ,
- /* 24-31 */ 0x0888,0x0777,0x0666,0x0555,0x0444,0x0333,0x0222,0x0111 };
-
- OpenAll()
- {
- if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0L)))
- abort("No Intuition");
- if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0L)))
- abort("No GFXBase");
- ns.Height=height=GfxBase->NormalDisplayRows;
- nw.Height=height-1;
-
- if (!(IFFBase = (struct Library *) OpenLibrary(IFFNAME,IFFVERSION)))
- abort("Somebody's using IFF-library - or it is absent");
- if ((s=(struct Screen *)OpenScreen(&ns))==NULL)
- abort("No screen here");
-
- LoadRGB4(&s->ViewPort,&ColorMap[0],(long)1<<s->BitMap.Depth);
- nw.Screen=s;
- if ((w = (struct Window *) OpenWindow(&nw)) == NULL)
- abort("Can't (and won't) open window");
- }
-
- abort(exitcode)
- char *exitcode;
- {
- if (exitcode) puts(exitcode);
- if (w) CloseWindow(w);
- if (s) CloseScreen(s);
- if (IFFBase) CloseLibrary(IFFBase);
- if (GfxBase) CloseLibrary(GfxBase);
- OpenWorkBench();
- if (IntuitionBase) CloseLibrary(IntuitionBase);
- exit(0);
- }
-
- double MSetPot(cx,cy,maxiter)
- double cx,cy;
- long maxiter;
- {
- long iter=0,;
- register double x,y,x2,y2,temp,pot=0.0;
-
- for (x=cx,y=cy,x2=x*x,y2=y*y;(iter<maxiter)&&(x2+y2<10000.0);iter++)
- {
- temp=x2-y2+cx;
- y=2*x*y+cy;
- x=temp;
- x2=x*x;
- y2=y*y;
- }
-
- if (iter<maxiter) pot=0.5*log(x2+y2)/pow(2.0,(double)iter);
- return(pot);
- }
-
- long oldh[640];
-
- MSetCPM3D(xmin,xmax,ymin,ymax,maxiter,angle,scale,lift)
- double xmin,xmax,ymin,ymax,scale,lift;
- long maxiter,angle;
- {
- register long ix,iy,shx,shh,shdep,col,h,maxh,cut,allsteps=0;
- double delta,cx,cy,pot,cutf;
-
- maxh=w->Height;
- if (angle<0)
- {
- allsteps=1;
- angle=-angle;
- }
- cut=w->Height/2;
- if (ymax-ymin!=xmax-xmin) ymax=ymin+xmax-xmin;
- SetAPen(w->RPort,1L);
- for (iy=0;(iy<angle*w->Height/2)&&(msg==NULL);)
- {
- cy=ymin+iy*(ymax-ymin)/s->Width;
- for (ix=0;(ix<s->Width)&&((msg=GetMsg(w->UserPort))==NULL);ix++)
- {
- cx=xmin+ix*(xmax-xmin)/s->Width;
- pot=(double)MSetPot(cx,cy,maxiter);
- h=maxh*(1-pow(pow(2.0,scale)*pot,lift));
- if (iy>0)
- {
- col=(oldh[ix]+h)/2-oldh[ix-1]+8;
- if (col<4) col=8;
- if (col<6) col=7;
- if ((oldh[ix]>=cut)&&(h>=cut))
- {
- col=8;
- if (oldh[ix]>cut+(maxh-cut)/8) col=7;
- if (oldh[ix]>cut+(maxh-cut)/6) col=6;
- if (oldh[ix]>cut+(maxh-cut)/4) col=5;
- if (oldh[ix]>cut+(maxh-cut)/2) col=4;
- if (oldh[ix]>cut+3*(maxh-cut)/4) col=3;
- if (oldh[ix]>cut+5*(maxh-cut)/6) col=2;
- if (oldh[ix]>cut+7*(maxh-cut)/8) col=1;
- oldh[ix]=cut;
- }
- if (oldh[ix]>=cut) oldh[ix]=cut;
- if (oldh[ix]<cut)
- {
- shh=oldh[ix]-ix;
- for (shdep=0,shx=ix;(shx<w->Width)&&(shx+shh<cut)&&(shdep<2);shx++)
- if (shx+shh<oldh[shx]) shdep++;
- col+=shdep;
- }
- if (col>15) col=15;
- if (pot==0.0) col=0;
- if (ix>0)
- {
- Move(w->RPort,ix,(long)(w->Height/2+(iy-1)/angle));
- SetAPen(w->RPort,col);
- Draw(w->RPort,ix,(long)(w->Height/2+(iy-1)/angle-oldh[ix]));
- }
- }
- oldh[ix]=h;
- }
- if (allsteps==0) iy+=angle;
- else iy++;
- }
- if (msg==NULL)
- {
- for (ix=1;ix<s->Width;ix++)
- {
- SetAPen(w->RPort,9L);
- if (oldh[ix]>cut) oldh[ix]=cut;
- Move(w->RPort,ix,(long)(w->Height/2+(iy-1)/angle));
- Draw(w->RPort,ix,(long)(w->Height/2+(iy-1)/angle-oldh[ix]+1));
- }
- }
- }
-
- getdoub(doub,datafile)
- double *doub;
- FILE *datafile;
- {
- int i;
- char doublebuf[30];
-
- i=-1;
- doublebuf[0]=0;
- do fread(&doublebuf[++i],1,1,datafile);
- while ((doublebuf[i]!=';')&&(i<30));
- doublebuf[i]=0;
- *doub=atof(&doublebuf[0]);
- }
-
- getlong(lon,datafile)
- long *lon;
- FILE *datafile;
- {
- int i;
- char doublebuf[30];
-
- i=-1;
- doublebuf[0]=0;
- do fread(&doublebuf[++i],1,1,datafile);
- while ((doublebuf[i]!=';')&&(i<30));
- *lon=atol(&doublebuf[0]);
- }
-
- DisplayUsage(fromcli)
- int fromcli;
- {
- puts("CPM - 3D Mandelbrot program using Continuous Potiential Method");
- puts(" 1989 by Lars R. Clausen (2:230/22.34)");
- puts(" Algorithm from 'The Science of Fractal Images'.");
- puts("Usage: CPM [datafile] or");
- puts(" CPM xmin xmax ymin ymin maxit angle scale lift H|L outputfile");
- puts("This program is PD, copy it as you see fit. (No fun for hackers!)");
- if (fromcli==0) gets();
- exit(0);
- }
-
- DoSize(size)
- char size;
- {
- switch (size)
- {
- case 'H': ns.Height=2*height; nw.Height=2*height-1;
- ns.Width=nw.Width=640;
- ns.ViewModes=HIRES|LACE;
- break;
- case 'L': ns.Height=height; nw.Height=height-1;
- ns.Width=nw.Width=320;
- ns.ViewModes=0;
- break;
- default: puts("Illegal screen type");
- }
- }
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- long i,end=0,fromfile=1,maxit,angle;
- FILE *datafile=NULL;
- double xmin,xmax,ymin,ymax,scale,lift;
- char size,oldsize,savefile[200],*dataname="CPMDataFile";
-
- if (argc==0) DisplayUsage(0);
- if ((argc==2)&&(strcmp(argv[1],"?")==0)) DisplayUsage(1);
- switch (argc)
- {
- case 2: dataname=argv[1]; break;
- case 11:
- xmin=atof(argv[1]);
- xmax=atof(argv[2]);
- ymin=atof(argv[3]);
- ymax=atof(argv[4]);
- maxit=atoi(argv[5]);
- angle=atoi(argv[6]);
- scale=atof(argv[7]);
- lift=atof(argv[8]);
- size=*argv[9];
- strcpy(savefile,argv[10]);
- fromfile=0;
- size=toupper(size);
- if (size!='H') DoSize(size);
- case 1: break;
- default: DisplayUsage(argc);
- }
- OpenAll();
-
- /* format xmin;xmax;ymin;ymax;maxit;angle;scale;buttom;size;savefile[EOL] */
- if (fromfile)
- {
- datafile=fopen(dataname,"r");
- if (datafile==NULL) abort("Can't open file");
- }
- do
- {
- if (fromfile)
- {
- getdoub(&xmin,datafile);
- getdoub(&xmax,datafile);
- getdoub(&ymin,datafile);
- getdoub(&ymax,datafile);
- getlong(&maxit,datafile);
- getlong(&angle,datafile);
- getdoub(&scale,datafile);
- getdoub(&lift,datafile);
- do
- fread(&size,1,1,datafile);
- while (!(isalpha(size)));
- size=toupper(size);
- if (oldsize!=size)
- {
- CloseWindow(w);
- CloseScreen(s);
- DoSize(size);
- if ((s=(struct Screen *)OpenScreen(&ns))==NULL)
- abort("No screen here");
-
- LoadRGB4(&s->ViewPort,&ColorMap[0],(long)1<<s->BitMap.Depth);
- nw.Screen=s;
- if ((w = (struct Window *) OpenWindow(&nw)) == NULL)
- abort("Can't (and won't) open window");
- }
- i=-1;
- fread(&savefile[0],1,1,datafile);
- do
- fread(&savefile[++i],1,1,datafile);
- while ((savefile[i]!=EOF)&&(savefile[i]!='\n')&&(i<200));
- if (savefile[i]==EOF) end=1;
- savefile[i]=0;
- if (i==200) {fclose(datafile);abort("filename too long");}
- }
- Move(w->RPort,0L,0L);
- ClearScreen(w->RPort);
- printf("Doing: %s Maxit %ld Angle %ld Scale %2.0f Lift %1.5f Size %c\n",savefile,maxit,angle,scale,lift,size);
- MSetCPM3D(xmin,xmax,ymin,ymax,maxit,angle,scale,lift);
- if (msg==NULL) SaveBitMap(savefile,&s->BitMap,&s->ViewPort.ColorMap->ColorTable[0],1L);
- Move(w->RPort,0L,0L);
- ClearScreen(w->RPort);
- if (msg->Class==CLOSEWINDOW) end=1;
- for (msg=GetMsg(w->UserPort);msg!=NULL;ReplyMsg(msg),msg=GetMsg(w->UserPort));
- msg=NULL;
- }
- while ((end==0)&&(fromfile==1));
- if (fromfile) fclose(datafile);
- abort(NULL);
- }
-