/* * * IFSout.c - Iterated Function System * uses IFS to create a IFS-Construction Image * Released to the Public Domain - 1989 The Software Glen Company * * */ #include "standard.h" #include "ifs.h" #include "ifsout.h" #include "safeclose.h" long timeint; short gadcount; float x=0., y=0.; /* the (real) x y before translation*/ UWORD colortab[32]; int currentfun = 0; int numoffun = 1; /* startout with two functions=numfun+1 */ char fname[MAXFNLEN]; char fn[MAXFNLEN/2]; char fdir[MAXFNLEN/2] = ":coors"; short vectorsw = FALSE, displaynumsw = TRUE, pausesw = FALSE, blackbacksw = TRUE, adjopen = FALSE; USHORT mx, my; /* mouse location */ /***************** ** Main Program ** *****************/ int main() { ULONG class; UWORD tempcolor; USHORT MenuNum, ItemNum, code; struct MenuItem *Item; APTR aAddress; short corner=0, adjdown = FALSE, boxmoved = FALSE; void graphit(); void gadgetmessage(); void initialit(); void clearscreen(); void setcolor(); void setupgad(); void closeout(); void drawvectors(); void autoadj(); int closeby(); void adjust(); void displaynums(); void getifsfun(); void checkswitches(); void putifsfun(); /* default to small flower */ float funs[FUNLIMIT][6] = { {0.20, 1.00, -0.65, 0.82, 1.11, 0.00}, {0.40, 0.00, 0.30, -0.32, 0.32, 0.00}}, percent[FUNLIMIT] = { 0.66, 1.00}, xyscale = 0.11; /* could be .25; */ int xoff = WIDTH/2 - 24, yoff = HEIGHT/2 + 28, i, j; initialit(funs,percent,&xyscale,&xoff,&yoff,¤tfun); FOREVER { if (pausesw) Wait((1 << w->UserPort->mp_SigBit) | (1 << adjwin->UserPort->mp_SigBit)); if ((message = (struct IntuiMessage *)GetMsg(w->UserPort))) { class = message->Class; code = message->Code; mx = message->MouseX; my = message->MouseY; aAddress = message->IAddress; ReplyMsg(message); /* Can't reply until done using it! */ switch (class) { case CLOSEWINDOW: /* Exit the program */ if (adjopen) CloseWindowSafely(adjwin); closeout(); exit(0); break; case MOUSEBUTTONS: if (code == SELECTDOWN) { if (vectorsw) { if (corner=closeby (funs, ¤tfun, numoffun, mx, my) ) adjdown = TRUE; else if (numoffun > 0) currentfun = (currentfun + 1) % (numoffun + 1); } else setcolor(); } else if (code == SELECTUP) { adjdown = FALSE; if (boxmoved) { clearscreen(); boxmoved = FALSE; for (j=0;j<10;j++) /* settle in on function */ graphit(funs,percent, xyscale, xoff, yoff, FALSE); } checkswitches(rp,funs,percent,currentfun, numoffun,vectorsw,displaynumsw); } setpots(adjwin, gads, PInfos, funs, percent, xyscale, xoff, yoff, currentfun, numoffun, stxt, adjopen); break; case INTUITICKS: if (adjdown) { boxmoved = TRUE; adjust(corner, rp, funs, currentfun, mx, my); } break; case MENUPICK: while (code != MENUNULL) { Item = (struct MenuItem *) ItemAddress(&Menu[0], code); MenuNum = MENUNUM( code ); ItemNum = ITEMNUM( code ); switch( MenuNum) { case 0: /* Project Menu */ switch( ItemNum ) { case 0: /* About Menu */ AutoRequest(w, &ReqText1, NULL, &OKIText, 10, 20, 310, 180); break; case 1: /* Save Current */ if (get_fname(w,screen,"Save File",fn,fdir) != NULL) { fname[0] = '\0'; strcat(fname,fdir); /* need to check if we need a / or not */ if (fdir[strlen(fdir) - 1] != ':') strcat(fname,"/"); strcat(fname,fn); putifsfun(fname,numoffun,funs,percent, colortab,xoff,yoff,xyscale); } checkswitches(rp,funs,percent,currentfun, numoffun,vectorsw,displaynumsw); break; case 2: /* Get IFS */ if (get_fname(w,screen,"Get File",fn,fdir) != NULL) { fname[0] = '\0'; strcat(fname,fdir); /* need to check if we need a / or not */ if (fdir[strlen(fdir) - 1] != ':') strcat(fname,"/"); strcat(fname,fn); getifsfun(fname,&numoffun,funs, percent, colortab,&xoff,&yoff,&xyscale); currentfun = 0; PInfos[0].HorizBody = FFFF/(numoffun+1); setpots(adjwin, gads, PInfos, funs, percent, xyscale, xoff, yoff, currentfun, numoffun, stxt, adjopen); for (j=0;j<10;j++) /* settle in on function */ graphit(funs, percent, xyscale, xoff, yoff, FALSE); clearscreen(); checkswitches(rp,funs,percent,currentfun, numoffun,vectorsw,displaynumsw); } break; case 3: /* To WB */ ScreenToBack(screen); break; case 4: /* quit */ if (adjopen) CloseWindowSafely(adjwin); closeout(); exit(0); break; } break; case 1: /* Function Menu */ switch( ItemNum ) { case 0: /* Zoom to Fit */ x=0.; y=0.; autoadj(funs, percent, &xyscale, &xoff, &yoff, ¤tfun); clearscreen(); checkswitches(rp,funs,percent,currentfun, numoffun,vectorsw,displaynumsw); break; case 1: /* Zoom out x 2 */ xyscale = xyscale / 2; clearscreen(); checkswitches(rp,funs,percent,currentfun, numoffun,vectorsw,displaynumsw); setpots(adjwin, gads, PInfos, funs, percent, xyscale, xoff, yoff, currentfun, numoffun, stxt, adjopen); break; case 2: /* Open adjust window in our new screen */ if (!adjopen) { nadjwin.Screen = screen; adjwin = (struct Window *)OpenWindow(&nadjwin); if (adjwin == NULL) { closeout(); exit(6); } adjopen = TRUE; setpots(adjwin, gads, PInfos, funs, percent, xyscale, xoff, yoff,currentfun, numoffun, stxt, adjopen); } else { WindowToFront(adjwin); } break; case 3: /* Another Function */ if (numoffun < FUNLIMIT-1) { numoffun++; currentfun = numoffun; /* reset the new function */ if(displaynumsw) clearscreen(); funs[currentfun][0] = 1.; funs[currentfun][1] = 0.; funs[currentfun][2] = 0.; funs[currentfun][3] = 1.; funs[currentfun][4] = 0.; funs[currentfun][5] = 0.; adjpercent(numoffun, percent); setpots(adjwin, gads, PInfos, funs, percent, xyscale, xoff, yoff, currentfun, numoffun, stxt, adjopen); checkswitches(rp,funs,percent,currentfun, numoffun,vectorsw,displaynumsw); } break; case 4: /* Erase Current */ if(numoffun > 1) { for (i=currentfun;iNextSelect; } /* end of if */ break; } /* end of outer outer switch */ } /* end of while */ /* lets see if you want me to do something to adjwin */ if (adjopen) if((message=(struct IntuiMessage *)GetMsg(adjwin->UserPort))) { class = message->Class; code = message->Code; aAddress = message->IAddress; ReplyMsg(message); switch (class) { case CLOSEWINDOW: /* Get rid of the requester */ if (adjopen){ CloseWindow(adjwin); adjopen = FALSE; } break; case GADGETUP: /*reply, then process */ gadgetmessage(aAddress,adjwin,funs,percent,&xyscale,&xoff,&yoff, gads,PInfos,&numoffun,¤tfun,stxt, displaynumsw,adjopen); for (j=0;j<10;j++) /* settle in on function */ graphit(funs, percent, xyscale, xoff, yoff, FALSE); checkswitches(rp,funs,percent,currentfun, numoffun,vectorsw,displaynumsw); break; } /* end switch */ } /* end if */ if(!adjdown) graphit(funs, percent, xyscale, xoff, yoff, TRUE); } /* end FOREVER */ return(0); } /* end main */ void clearscreen() { SetAPen(rp,0); RectFill(rp, XSTART, YSTART-HEIGHT, WIDTH-XSTART, YSTART); } void graphit(funs,percent,xyscale,xoff,yoff,drawit) float funs[][6],percent[],xyscale; int xoff,yoff,drawit; { double pk; int i, ix, iy, p; static int color; float newx, newy; p = rand(); pk = p/(float) INT_MAX; i=0; while(i percent[i]) { i++; } newx = funs[i][0] * x + funs[i][1] * y + funs[i][4]; newy = funs[i][2] * x + funs[i][3] * y + funs[i][5]; x = newx; y = newy; ix = x*HEIGHT*xyscale+xoff; /* Assumes that H0 && ix0 && iyViewPort; /* Set colors in screen's VP */ rp = w->RPort; /* Render into the window's RP */ clearscreen(); /* check and write indicators */ checkswitches(rp,funs,percent,currentfun,numoffun,vectorsw,displaynumsw); /* Set the color registers */ setcolor(); /* default color for small flower */ colortab[2] = 1404; colortab[3] = 3913; LoadRGB4(ViewPortAddress(w), colortab, 16); } /* end initialit */ void setcolor() { int i, colorinc; colorinc = rand() % 4096; colortab[2] = rand() % 4096; for (i=3; i<32; i++) colortab[i] = (colortab[i-1] + colorinc) % 4096; LoadRGB4(ViewPortAddress(w), colortab, 16); SetBPen(rp, 0); /* Insure clean text */ } void setupgad() { /* This is where the proportional gadgets are set up, using * the templates that were declared staticly. */ short i, gadcount; /* index to next available Gadget */ for(gadcount = 0; gadcount < NUMPROPS-2; gadcount++) { gads[gadcount] = TPropGadget; PInfos[gadcount] = TPropInfo; gads[gadcount].GadgetText = NULL; /* no text on prop gads */ gads[gadcount].GadgetRender = (APTR) &PImages[gadcount]; gads[gadcount].SpecialInfo = (APTR)&PInfos[gadcount]; gads[gadcount].TopEdge = GADSIZE * (gadcount+2); if(gadcount != 0) gads[gadcount].NextGadget = &gads[gadcount-1]; } /* end for */ gads[NUMPROPS-2] = ZoomGadget; PInfos[NUMPROPS-2] = TPropInfo; PInfos[NUMPROPS-2].Flags = AUTOKNOB | FREEVERT; gads[NUMPROPS-2].SpecialInfo = (APTR)&PInfos[NUMPROPS-2]; gads[NUMPROPS-2].GadgetRender = (APTR) &PImages[NUMPROPS-2]; gads[NUMPROPS-2].NextGadget = &gads[NUMPROPS-3]; gads[NUMPROPS-1] = CenterGadget; PInfos[NUMPROPS-1] = TPropInfo; PInfos[NUMPROPS-1].Flags = AUTOKNOB | FREEVERT | FREEHORIZ; gads[NUMPROPS-1].SpecialInfo = (APTR)&PInfos[NUMPROPS-1]; gads[NUMPROPS-1].GadgetRender = (APTR) &PImages[NUMPROPS-1]; gads[NUMPROPS-1].NextGadget = &gads[NUMPROPS-2]; PInfos[0].HorizBody = FFFF/(numoffun+1); /* This is where the String gadgets are set up, using the templates that were declared staticly. */ for(i=0; i0) ? percent[i]-percent[i-1] : percent[i])); Text(rp,str,strlen(str)); j = j+8; Move(rp,0,j); } } void autoadj(funs, percent, xyscale, xoff, yoff, currentfun) float funs[][6],percent[],*xyscale; int *xoff,*yoff,*currentfun; { int j; float minx = 1e20; float miny = 1e20; float maxx = -minx; float maxy = -minx; for (j=0;j<100;j++) {graphit(funs, percent, *xyscale, *xoff, *yoff, FALSE); if (x < minx) minx = x; if (x > maxx) maxx = x; if (y < miny) miny = y; if (y > maxy) maxy = y; } if (maxx > minx && maxy > miny && minx > -1e20 && maxx < 1e20 && miny > -1e20 && maxy < 1e20) { /* don't scale if either diff = 0 */ if ( (maxx-minx)/WIDTH > (maxy-miny)/HEIGHT) { *xyscale = (SCRNSCALE*ASPECT)/ (maxx - minx); *xoff = (WIDTH>>1) * (1 - (SCRNSCALE*(maxx+minx)/(maxx-minx))); *yoff = (HEIGHT>>1) * (1 - (*xyscale * (maxy+miny))); } else { *xyscale = SCRNSCALE / (maxy - miny); *xoff = ((WIDTH - HEIGHT * *xyscale * (maxx-minx))/2.0) - (minx * HEIGHT * *xyscale); *yoff = (HEIGHT>>1) * (1 - SCRNSCALE - (2.0 * miny * *xyscale)); } setpots(adjwin, gads, PInfos, funs, percent, *xyscale, *xoff, *yoff, *currentfun, numoffun, stxt, adjopen); } } /* end autoadj */ void getifsfun(fname,numoffun,funs,percent,colortab,xoff,yoff,xyscale) char fname[MAXFNLEN]; int *numoffun; float funs[][6], percent[]; UWORD colortab[]; int *xoff,*yoff; float *xyscale; { FILE *fp; int tempcolor; int i, j; if ((fp = fopen(fname, "r")) == NULL) { printf("ifsout: can't open %s\n", fname); } else { fscanf(fp, "%d %d %d %f\n", numoffun, xoff, yoff, xyscale); for(i=0;i <= *numoffun;i++) { for(j=0; j<6; j++) fscanf(fp, "%f ", &funs[i][j]); fscanf(fp, "%f %d\n", &percent[i], &tempcolor); colortab[i+2] = (UWORD) tempcolor; /* assumes that i<= FUNLIMIT */ } fclose(fp); LoadRGB4(ViewPortAddress(w), colortab, 16); } } void putifsfun(fname,numoffun,funs,percent,colortab,xoff,yoff,xyscale) char fname[MAXFNLEN]; int numoffun; float funs[][6], percent[]; UWORD colortab[]; int xoff,yoff; float xyscale; { FILE *fp; int i,j; if ((fp = fopen(fname, "w")) == NULL) { printf("ifsout: can't open %s for write\n", fname); } else { fprintf(fp, "%d %d %d %f\n", numoffun, xoff, yoff, xyscale); for(i=0;i<=numoffun;i++) { for(j=0; j<6; j++) fprintf(fp, "%5.2f ", funs[i][j]); /* assumes that FUNLIMIT <= 29 */ fprintf(fp, " %5.2f %d\n", percent[i], colortab[i+2]); } fclose(fp); } }