ftp://ftp.krokus.ru/pub/OpenBSD/distfiles/xscreensaver-4.22.tar.gz
[xscreensaver] / hacks / ifs.c
index 60d4d9cc503093e329c0e884fd5ea1659fa57069..5579abe04ed04780878f30c65bfff4c0dfab0ab5 100644 (file)
@@ -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 <lensnum> times - with results from each lens/function.  *
  * After <length> 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;i<lensnum;i++) {
-      switch(mode) {
-      case 0 : iterate(stepx( x, y, lenses[i]), stepy( x, y, lenses[i]), blend( curcol,colours[(int)lenses[i]->co].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;i<lensnum;i++) {
+                       switch(mode) {
+                               case 0 : iterate(stepx( x, y, lenses[i]), stepy( x, y, lenses[i]), blend( curcol,colours[(int)lenses[i]->co].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<lensnum;i++) {
-    mutate(lenses[i]);
-  }
-  draw();
+       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<lensnum;i++) {
+               mutate(lenses[i]);
+       }
+       draw();
 }
 
-static void init_ifs(void)
+static void
+init_ifs(void)
 {
-  Window rw;
-  int i;
-  XWindowAttributes xgwa;
-  
-  delay = get_integer_resource("delay", "Delay");
-  length = get_integer_resource("length", "Detail");
-  mode = get_integer_resource("mode", "Mode");
-
-  norotate    = get_boolean_resource("norotate", "NoRotate");
-  noscale     = get_boolean_resource("noscale", "NoScale");
-  notranslate = get_boolean_resource("notranslate", "NoTranslate");
-
-  lensnum = get_integer_resource("lensnum", "Functions");
-  
-  lenses = malloc(sizeof(Lens)*lensnum);
-  
-  for(i=0;i<lensnum;i++) {
-    lenses[i]=malloc(sizeof(Lens));
-  }
-  
-  /*Thanks go to Dad for teaching me how to allocate memory for struct**s . */
-  
-  XGetWindowAttributes (dpy, w, &xgwa);
-  width=xgwa.width;
-  height=xgwa.height;
-  
-  /*Initialise all this X shizzle*/
-  blackColor = BlackPixel(dpy, DefaultScreen(dpy));
-  whiteColor = WhitePixel(dpy, DefaultScreen(dpy));
-  rw = RootWindow(dpy, screen_num);
-  screen_num = DefaultScreen(dpy);
-  gc = XCreateGC(dpy, rw, 0, NULL);
-  
-  /* Do me some colourmap magic. If we're using blend mode, this is just   *
-   * for the nice colours - we're still using true/hicolour. Screw me if   *
-   * I'm going to work out how to blend with colourmaps - I'm too young to *
-   * die!! On a sidenote, this is mostly stolen from halftone because I    *
-   * don't really know what the hell I'm doing, here.                      */
-  ncolours = get_integer_resource("colors", "Colors");
-  if(ncolours < lensnum) ncolours=lensnum; /*apparently you're allowed to do this kind of thing...*/
-  colours = (XColor *)calloc(ncolours, sizeof(XColor));
-  make_smooth_colormap (  dpy,
-                          xgwa.visual,
-                          xgwa.colormap,
-                          colours,
-                          &ncolours,
-                          True, 0, False);
-  /*No, I didn't have a clue what that really did... hopefully I have some colours in an array, now.*/
-  wcol = (int)myrandom(ncolours);
-    
-  /*Double buffering - I can't be bothered working out the XDBE thingy*/
-  backbuffer = XCreatePixmap(dpy, w, width, height, XDefaultDepth(dpy, screen_num));
-  
-  /*Scaling factor*/
-  wt=width/32;
-  ht=height/24;
-  
-  ws=400;
-  hs=400;
-
-  /*Colourmapped colours for the general prettiness*/
-  for(i=0;i<lensnum;i++) {
-    CreateLens( myrandom(1)-0.5,
-                myrandom(1),
-                myrandom(4)-2,
-                myrandom(4)+2,
-                myrandom(ncolours),
-                lenses[i]);
-  }
+       Window rw;
+       int i;
+       XWindowAttributes xgwa;
+       
+       delay = get_integer_resource("delay", "Delay");
+       length = get_integer_resource("length", "Detail");
+       mode = get_integer_resource("mode", "Mode");
+
+       norotate    = get_boolean_resource("norotate", "NoRotate");
+       noscale     = get_boolean_resource("noscale", "NoScale");
+       notranslate = get_boolean_resource("notranslate", "NoTranslate");
+
+       lensnum = get_integer_resource("lensnum", "Functions");
+       
+       lenses = malloc(sizeof(Lens)*lensnum);
+       
+       for(i=0;i<lensnum;i++) {
+               lenses[i]=malloc(sizeof(Lens));
+       }
+       
+       /*Thanks go to Dad for teaching me how to allocate memory for struct**s . */
+       
+       XGetWindowAttributes (dpy, w, &xgwa);
+       width=xgwa.width;
+       height=xgwa.height;
+       
+       /*Initialise all this X shizzle*/
+       blackColor = BlackPixel(dpy, DefaultScreen(dpy));
+       whiteColor = WhitePixel(dpy, DefaultScreen(dpy));
+       rw = RootWindow(dpy, screen_num);
+       screen_num = DefaultScreen(dpy);
+       gc = XCreateGC(dpy, rw, 0, NULL);
+       
+       /* Do me some colourmap magic. If we're using blend mode, this is just   *
+        * for the nice colours - we're still using true/hicolour. Screw me if   *
+        * I'm going to work out how to blend with colourmaps - I'm too young to *
+        * die!! On a sidenote, this is mostly stolen from halftone because I    *
+        * don't really know what the hell I'm doing, here.                      */
+       ncolours = get_integer_resource("colors", "Colors");
+       if(ncolours < lensnum) ncolours=lensnum; /*apparently you're allowed to do this kind of thing...*/
+       colours = (XColor *)calloc(ncolours, sizeof(XColor));
+       make_smooth_colormap ( dpy,
+                              xgwa.visual,
+                              xgwa.colormap,
+                           colours,
+                           &ncolours,
+                           True, 0, False);
+       /*No, I didn't have a clue what that really did... hopefully I have some colours in an array, now.*/
+       wcol = (int)myrandom(ncolours);
+               
+       /*Double buffering - I can't be bothered working out the XDBE thingy*/
+       backbuffer = XCreatePixmap(dpy, w, width, height, XDefaultDepth(dpy, screen_num));
+       
+       /*Scaling factor*/
+       wt=width/32;
+       ht=height/24;
+       
+       ws=400;
+       hs=400;
+
+       /*Colourmapped colours for the general prettiness*/
+       for(i=0;i<lensnum;i++) {
+               CreateLens(     myrandom(1)-0.5,
+                           myrandom(1),
+                           myrandom(4)-2,
+                           myrandom(4)+2,
+                           myrandom(ncolours),
+                           lenses[i]);
+       }
 }
 
 void
 screenhack (Display *display, Window window)
 {
-  dpy = display;
-  w   = window;
-  
-  init_ifs();
-  
-  while (1) {
-    step();
-    screenhack_handle_events(dpy);
-    if (delay) usleep(delay);
-  }
+       dpy = display;
+       w   = window;
+       
+       init_ifs();
+       
+       while (1) {
+               step();
+               screenhack_handle_events(dpy);
+               if (delay) usleep(delay);
+       }
 }