#include #include #include #include #include #include #include #define BITS2SHIFT 27 double atof(); long atol(); int height=256; void *OpenLibrary(),*GetBMHD(),*OpenIFF(),*AllocRaster(); struct Window *OpenWindow(); struct Screen *OpenScreen(); struct IntuiMessage *GetMsg(); struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; struct Library *IFFBase=NULL; struct Window *w; struct Screen *s; struct IntuiMessage *msg; struct BitMap *SBitMap=NULL; struct NewScreen ns = {0,0,640,512,1,0,0,HIRES|LACE,CUSTOMSCREEN,NULL,NULL,NULL,NULL}; struct NewWindow nw = { 0,1,640,511,-1,-1,VANILLAKEY|CLOSEWINDOW,WINDOWCLOSE|NOCAREREFRESH|SIMPLE_REFRESH| ACTIVATE,NULL,NULL,NULL,NULL,NULL,0,0,0,0,CUSTOMSCREEN}; short ColorMap[32] = { /* format 0x0RGB */ /* 0-7 */ 0x0000,0x0FFF,0x0EEE,0x0DDD,0x0CCC,0x0BBB,0x0AAA,0x0999 , /* 8-15 */ 0x0888,0x0777,0x0666,0x0555,0x0444,0x0333,0x0222,0x0111 , /* 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<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); } max(x,y) double x,y; { if (x>y) return(x); else return(y); } long LoadPicture(filename) char *filename; { APTR ifffile = NULL; struct BitMapHeader *bmhd; long count,bd,bw,bh; register long x,y,inity; UWORD colortable[128]; char *iffinfile=":Pics/WBBackPic.ILBM"; if(!(ifffile=OpenIFF(filename))) { return(0L); } if(!(bmhd=GetBMHD(ifffile))) { abort("Bad BitMap Header on IFF file"); } count = GetColorTab(ifffile,colortable); /* LoadRGB4(&(s->ViewPort),colortable,count); */ if(!(DecodePic(ifffile,&s->BitMap))) { abort("Decoding IFF - bad things happened!"); } CloseIFF(ifffile); printf("Analyzing picture for resume..."); fflush(stdout); for (y=0,x=0;(yHeight)&&(xHeight);y++) for (x=0;(xWidth)&&(ReadPixel(w->RPort,x,y)==0);x++); if (y>1) y-=2; else y=0; printf(" resuming at line %ld.\n",y); DisplayBeep(0L); return(y); } double xorbit[2001],yorbit[2001]; double MSetDist(cx,cy,maxiter) double cx,cy; long maxiter; { long iter=0,i,flag; double huge=100000.0; double x=0.0,y=0.0,x2=0.0,y2=0.0,temp,xder,yder; double dist=0.0; xorbit[0]=yorbit[0]=0.0; do { temp=x2-y2+cx; y=2*x*y+cy; x=temp; x2=x*x; y2=y*y; iter++; xorbit[iter]=x; yorbit[iter]=y; } while ((iterhuge) { xder=yder=0.0; i=flag=0; do { temp=2*(xorbit[i]*xder-yorbit[i]*yder)+1; yder=2*(yorbit[i]*xder+xorbit[i]*yder); xder=temp; if ((max(abs(xder),abs(yder)))>10000000.0) flag=1; i++; } while ((iWidth; ymax=ymin+(w->Width/w->Height)*(xmax-xmin); SetAPen(w->RPort,1L); msg=GetMsg(w->UserPort); for (iy=inity;(iyHeight)&&(msg->Code!=27)&&(msg->Class!=CLOSEWINDOW);iy++) { cy=ymin+iy*(ymax-ymin)/s->Width; for (ix=0;(ixWidth)&&(msg->Code!=27)&&(msg->Class!=CLOSEWINDOW);ix++) { cx=xmin+ix*(xmax-xmin)/s->Width; dist=(double)MSetDist(cx,cy,maxiter); if (dist>=delta) WritePixel(w->RPort,ix,iy); msg=GetMsg(w->UserPort); if (msg->Code==115) SaveBitMap(savefile,&s->BitMap,&s->ViewPort.ColorMap->ColorTable[0],1L); } } } 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("DEM - B & W MandelBrot generator using Distance Estimator Method"); puts(" Algorithm from 'The Science of Fractal Images."); puts("(c) 1989 by Lars R. Clausen (2:230/22.34)"); puts("Usage: DEM [datafilename] or"); puts(" DEM xmin xmax ymin ymax maxit [L|W|H|G|F] savefilename"); puts("This program is PD (no fun for hackers)."); puts("Improvements, bugreports and $$$ are welcome."); if (!FromCLI) gets(); exit(0); } DoSize(size) char size; { switch (size) { case 'L': ns.Height=height; ns.Width=320; nw.Height=height-1; nw.Width=320; ns.ViewModes=0; break; case 'W': ns.Height=height; ns.Width=640; nw.Height=height-1; nw.Width=640; ns.ViewModes=HIRES; break; case 'H': ns.Height=2*height; ns.Width=640; nw.Height=2*height-1; nw.Width=640; ns.ViewModes=HIRES|LACE; break; case 'G': ns.Height=1024; ns.Width=960; nw.Height=1023; nw.Width=960; ns.ViewModes=HIRES|LACE; break; case 'F': ns.Height=ns.Width=nw.Width=1024; nw.Height=1023; ns.ViewModes=HIRES|LACE; break; default: puts("Illegal screen type"); } } main(argc,argv) int argc; char *argv[]; { long i,end=0,fromfile=1,maxit,inity; FILE *datafile=NULL; double xmin,xmax,ymin,ymax; char size,oldsize='H',savefile[200],*dataname="DEMDataFile"; if ((argc==2)&&(strcmp(argv[1],"?")==0)) DisplayUsage(1); switch (argc) { case 1: break; case 2: dataname=argv[1]; break; case 8: xmin=atof(argv[1]); xmax=atof(argv[2]); ymin=atof(argv[3]); ymax=atof(argv[4]); maxit=atoi(argv[5]); size=*argv[6]; strcpy(savefile,argv[7]); fromfile=0; size=toupper(size); if (size!='H') DoSize(size); oldsize=size; break; default: DisplayUsage(argc); } OpenAll(); if (GfxBase->DisplayFlags&NTSC) height=200; /* format xmin;xmax;ymin;ymax;maxit;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); 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],1L); 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");} } oldsize=size; Move(w->RPort,0L,0L); ClearScreen(w->RPort); inity=LoadPicture(savefile); printf("Doing: %s Maxit %ld Size %c\n",savefile,maxit,size); MSetDEM(inity,xmin,xmax,ymin,ymax,maxit,0.5,savefile); if (msg==NULL) SaveBitMap(savefile,&s->BitMap,&s->ViewPort.ColorMap->ColorTable[0],1L); 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); }