home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
352.lha
/
IFS_v1.4
/
source
/
ifsout.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-03-10
|
23KB
|
717 lines
/*
*
* 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] = ":ifs/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;i<numoffun;i++)
for (j=0;j<6;j++)
funs[i][j] = funs[i+1][j];
funs[numoffun][0] = 1.;
funs[numoffun][1] = 0.;
funs[numoffun][2] = 0.;
funs[numoffun][3] = 1.;
funs[numoffun][4] = 0.;
funs[numoffun][5] = 0.;
percent[numoffun] = 0.;
if (currentfun == numoffun) currentfun--;
numoffun--;
setpots(adjwin, gads, PInfos, funs, percent, xyscale,
xoff, yoff, currentfun, numoffun, stxt, adjopen);
clearscreen();
checkswitches(rp,funs,percent,currentfun,
numoffun,vectorsw,displaynumsw);
}
break;
case 5: /* Erase All */
numoffun = 1; /* Leave two */
currentfun = 0;
for (i=0;i<FUNLIMIT;i++) {
funs[i][0] = 1.;
funs[i][1] = 0.;
funs[i][2] = 0.;
funs[i][3] = 1.;
funs[i][4] = 0.;
funs[i][5] = 0.;
percent[i] = 0.;
}
percent[0]=0.5; /* for the two left */
percent[1]=1.;
setpots(adjwin, gads, PInfos, funs, percent, xyscale,
xoff, yoff, currentfun, numoffun, stxt, adjopen);
clearscreen();
checkswitches(rp,funs,percent,currentfun,
numoffun,vectorsw,displaynumsw);
break;
} /* end of inner switch */
break;
case 2: /* Switches */
switch( ItemNum ) {
case 0: /* Toggle Boxes */
if (vectorsw) {
vectorsw = FALSE;
clearscreen();
}
else {
vectorsw = TRUE;
}
checkswitches(rp,funs,percent,currentfun,
numoffun,vectorsw,displaynumsw);
break;
case 1: /* Toggle Numbers */
if (displaynumsw) {
displaynumsw = FALSE;
clearscreen();
if (vectorsw)
drawvectors(rp, funs, numoffun, currentfun);
}
else {
displaynumsw = TRUE;
displaynums(rp, funs, percent, currentfun, numoffun);
}
break;
case 2: /* Pause*/
if (pausesw) {
pausesw = FALSE;
ModifyIDCMP(w,CLOSEWINDOW|MOUSEBUTTONS|MENUPICK|INTUITICKS);
if(adjopen)
ModifyIDCMP(adjwin,CLOSEWINDOW|GADGETUP);
}
else {
pausesw = TRUE; /* set to only look at menupicks/close */
ModifyIDCMP(w,CLOSEWINDOW|MENUPICK);
if(adjopen)
ModifyIDCMP(adjwin,CLOSEWINDOW);
}
break;
case 3: /* Toggle Bk/Fg */
if (blackbacksw) {
blackbacksw = FALSE;
}
else {
blackbacksw = TRUE;
}
tempcolor = colortab[0];
colortab[0] = colortab[1];
colortab[1] = tempcolor;
LoadRGB4(ViewPortAddress(w), colortab, 16);
break;
} /* end of inner switch */
} /* end of outer switch */
code = Item->NextSelect;
} /* 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<numoffun && pk > 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 H<W */
iy = y*HEIGHT*xyscale+yoff;
if ((color = (i+2)%MAXCOLORS) < 2)
color = color+2;
if (drawit && ix>0 && ix<WIDTH && iy>0 && iy<HEIGHT) {
SetAPen(rp, color);
WritePixel(rp, ix, HEIGHT-iy);
}
}
void initialit (funs,percent,xyscale,xoff,yoff,currentfun)
float funs[][6],percent[],*xyscale;
int *xoff,*yoff,*currentfun;
{
int i;
srand(time(&timeint)); /* Set Random Generator Seed */
/* From Time */
colortab[0] = 0;
colortab[1] = 4095;
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0);
if (GfxBase == NULL)
exit(2);
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
if (IntuitionBase == NULL) {
CloseLibrary(GfxBase);
exit(3);
}
screen = (struct Screen *)OpenScreen(&ns);
if (screen == NULL) {
CloseLibrary(IntuitionBase);
CloseLibrary(GfxBase);
exit(4);
}
nw.Screen = screen; /* Open window in our new screen */
w = (struct Window *)OpenWindow(&nw);
if (w == NULL) {
CloseScreen(screen);
CloseLibrary(IntuitionBase);
CloseLibrary(GfxBase);
exit(5);
}
setupgad();
for (i=2;i<FUNLIMIT;i++) {
funs[i][0] = 1.;
funs[i][1] = 0.;
funs[i][2] = 0.;
funs[i][3] = 1.;
funs[i][4] = 0.;
funs[i][5] = 0.;
percent[i] = 0.5;
}
setpots(adjwin, gads, PInfos, funs, percent, *xyscale, *xoff, *yoff,
*currentfun, numoffun, stxt, adjopen);
SetMenuStrip(w, &Menu[0]);
ShowTitle(screen, FALSE); /* No Bars in Arizona */
vp = &screen->ViewPort; /* 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; i<NUMSTRS; i++) {
SInfo[i].Buffer = &stxt[i][0];
SInfo[i].UndoBuffer = NULL;
SInfo[i].BufferPos = 0;
SInfo[i].MaxChars = GSTRLEN;
SInfo[i].DispPos = 0;
}
for(gadcount = NUMPROPS; gadcount < NUMGADS; gadcount++) {
gads[gadcount] = TStrngGadget;
gads[gadcount].GadgetText =
(struct IntuiText *) &StrngText[gadcount-NUMPROPS];
gads[gadcount].GadgetRender = NULL;
gads[gadcount].SpecialInfo = (APTR)&SInfo[gadcount-NUMPROPS];
if(gadcount==NUMPROPS)
gads[gadcount].TopEdge = 20;
else
gads[gadcount].TopEdge = GADSIZE * (gadcount+2-NUMPROPS);
gads[gadcount].NextGadget = &gads[gadcount-1];
} /* end for */
} /* end setupgad */
void closeout() {
ClearMenuStrip(w);
CloseWindow(w);
CloseScreen(screen);
CloseLibrary(IntuitionBase);
CloseLibrary(GfxBase);
}
void displaynums(rp, funs, percent, currentfun, numoffun)
struct RastPort *rp;
float funs[][6], percent[];
int currentfun, numoffun;
{
short i, j, k, color;
char str[80];
j = HEIGHT - (8*numoffun) - 10;
Move(rp,0,j);
for (i=0; i<=numoffun; i++) {
if ((color = (i+2)%MAXCOLORS) < 2)
color = color+2;
SetAPen(rp, color);
sprintf (str, "%3d ", i+1);
Text(rp,str,strlen(str));
for(k=0; k<6; k++) {
sprintf (str, "%5.2f ", funs[i][k]);
Text(rp,str,strlen(str));
}
sprintf (str, "%5.2f", ((i>0) ? 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);
}