X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fifs.c;h=5579abe04ed04780878f30c65bfff4c0dfab0ab5;hp=60d4d9cc503093e329c0e884fd5ea1659fa57069;hb=3f438031d610c7e15fd33876a879b97e290e05fb;hpb=447db08c956099b3b183886729108bf5b364c4b8 diff --git a/hacks/ifs.c b/hacks/ifs.c index 60d4d9cc..5579abe0 100644 --- a/hacks/ifs.c +++ b/hacks/ifs.c @@ -34,9 +34,10 @@ a groovier colouring mode. #include "screenhack.h" -static float myrandom(float up) +static float +myrandom(float up) { - return(((float)random()/RAND_MAX)*up); + return(((float)random()/RAND_MAX)*up); } static int delay; @@ -44,305 +45,325 @@ static int lensnum; static int length; static int mode; static Bool notranslate, noscale, norotate; -float ht,wt; -float hs,ws; -int width,height; -float r; -long wcol; -int coloffset; +static float ht,wt; +static float hs,ws; +static int width,height; +static long wcol; -float nx,ny; - -int count; +static int count; /*X stuff*/ -GC gc; -Window w; -Display *dpy; -Pixmap backbuffer; -XColor *colours; -int ncolours; -int screen_num; +static GC gc; +static Window w; +static Display *dpy; +static Pixmap backbuffer; +static XColor *colours; +static int ncolours; +static int screen_num; -int blackColor, whiteColor; +static int blackColor, whiteColor; char *progclass = "IFS"; char *defaults [] = { - ".lensnum: 3", - ".length: 9", - ".mode: 0", - ".colors: 200", - "*delay: 10000", - "*notranslate: False", - "*noscale: False", - "*norotate: False", + ".lensnum: 3", + ".length: 9", + ".mode: 0", + ".colors: 200", + "*delay: 10000", + "*notranslate: False", + "*noscale: False", + "*norotate: False", 0 }; XrmOptionDescRec options [] = { - { "-detail", ".length", XrmoptionSepArg, 0 }, - { "-delay", ".delay", XrmoptionSepArg, 0 }, - { "-mode", ".mode", XrmoptionSepArg, 0 }, - { "-colors", ".colors", XrmoptionSepArg, 0 }, - { "-functions", ".lensnum", XrmoptionSepArg, 0 }, - { "-notranslate", ".notranslate", XrmoptionNoArg, "True" }, - { "-noscale", ".noscale", XrmoptionNoArg, "True" }, - { "-norotate", ".norotate", XrmoptionNoArg, "True" }, + { "-detail", ".length", XrmoptionSepArg, 0 }, + { "-delay", ".delay", XrmoptionSepArg, 0 }, + { "-mode", ".mode", XrmoptionSepArg, 0 }, + { "-colors", ".colors", XrmoptionSepArg, 0 }, + { "-functions", ".lensnum", XrmoptionSepArg, 0 }, + { "-notranslate", ".notranslate", XrmoptionNoArg, "True" }, + { "-noscale", ".noscale", XrmoptionNoArg, "True" }, + { "-norotate", ".norotate", XrmoptionNoArg, "True" }, { 0, 0, 0, 0 } }; /*Takes the average of two colours, with some nifty bit-shifting*/ -static long blend(long c1, long c2) +static long +blend(long c1, long c2) { - long R1=(c1 & 0xFF0000) >> 16; - long R2=(c2 & 0xFF0000) >> 16; - long G1=(c1 & 0x00FF00) >> 8; - long G2=(c2 & 0x00FF00) >> 8; - long B1=(c1 & 0x0000FF); - long B2=(c2 & 0x0000FF); - - return (((R1+R2)/2 << 16) | ((G1+G2)/2 << 8) | ((B1+B2)/2)); + long R1=(c1 & 0xFF0000) >> 16; + long R2=(c2 & 0xFF0000) >> 16; + long G1=(c1 & 0x00FF00) >> 8; + long G2=(c2 & 0x00FF00) >> 8; + long B1=(c1 & 0x0000FF); + long B2=(c2 & 0x0000FF); + + return (((R1+R2)/2 << 16) | ((G1+G2)/2 << 8) | ((B1+B2)/2)); } /*Draw a point on the backbuffer*/ -static void sp(float x, float y, long c) +static void +sp(float x, float y, long c) { - x+=16; x*=wt; - y=16.5-y; y*=ht; - if(x<0 || x>=width || y<0 || y>=height) return; - XSetForeground(dpy, gc, c); - XDrawPoint(dpy, backbuffer, gc, (int)x, (int)y); + x+=16; x*=wt; + y=16.5-y; y*=ht; + if(x<0 || x>=width || y<0 || y>=height) return; + XSetForeground(dpy, gc, c); + XDrawPoint(dpy, backbuffer, gc, (int)x, (int)y); } /*Copy backbuffer to front buffer and clear backbuffer*/ -static void draw(void) +static void +draw(void) { - XCopyArea( dpy, - backbuffer, w, - gc, - 0, 0, - width, height, - 0, 0); - - XSetForeground(dpy, gc, blackColor); - XFillRectangle( dpy, - backbuffer, - gc, - 0, 0, - width, height); + XCopyArea( dpy, + backbuffer, w, + gc, + 0, 0, + width, height, + 0, 0); + + XSetForeground(dpy, gc, blackColor); + XFillRectangle( dpy, + backbuffer, + gc, + 0, 0, + width, height); } typedef struct { - float r,s,tx,ty; - /*Rotation, Scale, Translation X & Y*/ - float ra,raa,sa,txa,tya; - - int co; -} Lens; - - -static void CreateLens(float nr, - float ns, - float nx, - float ny, - int nco, - Lens *newlens) + float r,s,tx,ty; + /*Rotation, Scale, Translation X & Y*/ + float ro,rt,rc; + /*Old Rotation, Rotation Target, Rotation Counter*/ + float so,st,sc; + /*Old Scale, Scale Target, Scale Counter*/ + float sa,txa,tya; + /*Scale change, Translation change*/ + + int co; +} Lens; + + +static void +CreateLens( float nr, + float ns, + float nx, + float ny, + int nco, + Lens *newlens) { - newlens->ra=newlens->raa=newlens->sa=newlens->txa=newlens->tya=0; - if(!norotate) newlens->r=nr; - else newlens->r=0; - - if(!noscale) newlens->s=ns; - else newlens->s=0.5; - - if(!notranslate) { - newlens->tx=nx; - newlens->ty=ny; - } else { - newlens->tx=nx; - newlens->tx=ny; - } - - newlens->co=nco; + newlens->sa=newlens->txa=newlens->tya=0; + if(!norotate) newlens->r=nr; + else newlens->r=0; + + if(!noscale) newlens->s=ns; + else newlens->s=0.5; + + if(!notranslate) { + newlens->tx=nx; + newlens->ty=ny; + } else { + newlens->tx=nx; + newlens->tx=ny; + } + + newlens->rc=newlens->sc=1; + newlens->co=nco; } - -static float stepx(float x, float y, Lens *l) + +static float +stepx(float x, float y, Lens *l) { - return l->s*cos(l->r)*x+l->s*sin(l->r)*y+l->tx; + return l->s*cos(l->r)*x+l->s*sin(l->r)*y+l->tx; } - -static float stepy(float x, float y, Lens *l) +static float +stepy(float x, float y, Lens *l) { - return l->s*sin(l->r)*-x+l->s*cos(l->r)*y+l->ty; + return l->s*sin(l->r)*-x+l->s*cos(l->r)*y+l->ty; } - -static void mutate(Lens *l) +static void +mutate(Lens *l) { - if(!norotate) { - l->raa+=myrandom(0.002)-0.001; - l->ra+=l->raa; - l->r +=l->ra; - if(l->ra>0.07 || l->ra<-0.07) l->ra/=1.4; - if(l->raa>0.005 || l->raa<-0.005) l->raa/=1.2; - } - if(!noscale) { - l->sa+=myrandom(0.01)-0.005; - l->s +=l->sa; - if(l->s>0.4) l->sa -=0.004; - if(l->s<-0.4) l->sa +=0.004; - if(l->sa>0.07 || l->sa<-0.07) l->sa/=1.4; - } - if(!notranslate) { - l->txa+=myrandom(0.004)-0.002; - l->tya+=myrandom(0.004)-0.002; - l->tx+=l->txa; - l->ty+=l->tya; - if(l->tx>6) l->txa-=0.004; - if(l->ty>6) l->tya-=0.004; - if(l->tx<-6) l->txa+=0.004; - if(l->ty<-6) l->tya+=0.004; - if(l->txa>0.05 || l->txa<-0.05) l->txa/=1.7; - if(l->tya>0.05 || l->tya<-0.05) l->tya/=1.7; - } - - /*Groovy, colour-shifting functions!*/ - l->co++; - l->co %= ncolours; + if(!norotate) { + float factor; + if(l->rc >= 1) { + l->rc= 0; + l->ro = l->rt; + l->rt = myrandom(4)-2; + } + factor = (sin((-M_PI / 2.0) + M_PI * l->rc) + 1.0) / 2.0; + l->r=l->ro + (l->rt - l->ro) * factor; + l->rc+=0.01; + + } + if(!noscale) { + float factor; + if(l->sc >= 1) { + /*Reset counter, obtain new target value*/ + l->sc= 0; + l->so = l->st; + l->st = myrandom(2)-1; + } + factor = (sin((-M_PI / 2.0) + M_PI * l->sc) + 1.0) / 2.0; + /* Take average of old target and new target, using factor to * + * weight. It's computed sinusoidally, resulting in smooth, * + * rhythmic transitions. */ + l->s=l->so + (l->st - l->so) * factor; + l->sc+=0.01; + } + if(!notranslate) { + l->txa+=myrandom(0.004)-0.002; + l->tya+=myrandom(0.004)-0.002; + l->tx+=l->txa; + l->ty+=l->tya; + if(l->tx>6) l->txa-=0.004; + if(l->ty>6) l->tya-=0.004; + if(l->tx<-6) l->txa+=0.004; + if(l->ty<-6) l->tya+=0.004; + if(l->txa>0.05 || l->txa<-0.05) l->txa/=1.7; + if(l->tya>0.05 || l->tya<-0.05) l->tya/=1.7; + } + + /*Groovy, colour-shifting functions!*/ + l->co++; + l->co %= ncolours; } Lens **lenses; /* Calls itself times - with results from each lens/function. * * After calls to itself, it stops iterating and draws a point. */ -static void iterate(float x, float y, long curcol, int length) +static void +iterate(float x, float y, long curcol, int length) { - int i; - if(length == 0) { - sp(x,y,curcol); - } else { - /*iterate(lenses[0].stepx(x,y),lenses[0].stepy(x,y),length-1); - iterate(lenses[1].stepx(x,y),lenses[1].stepy(x,y),length-1); - iterate(lenses[2].stepx(x,y),lenses[2].stepy(x,y),length-1);*/ - for(i=0;ico].pixel ), length-1); break; - case 1 : iterate(stepx( x, y, lenses[i]), stepy( x, y, lenses[i]), colours[(int)lenses[i]->co].pixel, length-1); break; - case 2 : iterate(stepx( x, y, lenses[i]), stepy( x, y, lenses[i]), curcol, length-1); break; - default: exit(0); - } - } - } - count++; + int i; + if(length == 0) { + sp(x,y,curcol); + } else { + for(i=0;ico].pixel ), length-1); break; + case 1 : iterate(stepx( x, y, lenses[i]), stepy( x, y, lenses[i]), colours[(int)lenses[i]->co].pixel, length-1); break; + case 2 : iterate(stepx( x, y, lenses[i]), stepy( x, y, lenses[i]), curcol, length-1); break; + default: exit(0); + } + } + } + count++; } /* Come on and iterate, iterate, iterate and sing... * * Yeah, this function just calls iterate, mutate, * * and then draws everything. */ -static void step(void) +static void +step(void) { - int i; - if(mode == 2) { - wcol++; - wcol %= ncolours; - iterate(0,0,colours[wcol].pixel,length); - } else { - iterate(0,0,0xFFFFFF,length); - } - - - count=0; - - for(i=0;i