46
47
static Bool notranslate, noscale, norotate;
50
static int width,height;
59
static Pixmap backbuffer;
60
static XColor *colours;
62
static int screen_num;
67
int blackColor, whiteColor;
64
static int blackColor, whiteColor;
69
66
char *progclass = "IFS";
71
68
char *defaults [] = {
77
"*notranslate: False",
74
"*notranslate: False",
83
80
XrmOptionDescRec options [] = {
84
{ "-detail", ".length", XrmoptionSepArg, 0 },
85
{ "-delay", ".delay", XrmoptionSepArg, 0 },
86
{ "-mode", ".mode", XrmoptionSepArg, 0 },
87
{ "-colors", ".colors", XrmoptionSepArg, 0 },
88
{ "-functions", ".lensnum", XrmoptionSepArg, 0 },
89
{ "-notranslate", ".notranslate", XrmoptionNoArg, "True" },
90
{ "-noscale", ".noscale", XrmoptionNoArg, "True" },
91
{ "-norotate", ".norotate", XrmoptionNoArg, "True" },
81
{ "-detail", ".length", XrmoptionSepArg, 0 },
82
{ "-delay", ".delay", XrmoptionSepArg, 0 },
83
{ "-mode", ".mode", XrmoptionSepArg, 0 },
84
{ "-colors", ".colors", XrmoptionSepArg, 0 },
85
{ "-functions", ".lensnum", XrmoptionSepArg, 0 },
86
{ "-notranslate", ".notranslate", XrmoptionNoArg, "True" },
87
{ "-noscale", ".noscale", XrmoptionNoArg, "True" },
88
{ "-norotate", ".norotate", XrmoptionNoArg, "True" },
95
92
/*Takes the average of two colours, with some nifty bit-shifting*/
96
static long blend(long c1, long c2)
94
blend(long c1, long c2)
98
long R1=(c1 & 0xFF0000) >> 16;
99
long R2=(c2 & 0xFF0000) >> 16;
100
long G1=(c1 & 0x00FF00) >> 8;
101
long G2=(c2 & 0x00FF00) >> 8;
102
long B1=(c1 & 0x0000FF);
103
long B2=(c2 & 0x0000FF);
105
return (((R1+R2)/2 << 16) | ((G1+G2)/2 << 8) | ((B1+B2)/2));
96
long R1=(c1 & 0xFF0000) >> 16;
97
long R2=(c2 & 0xFF0000) >> 16;
98
long G1=(c1 & 0x00FF00) >> 8;
99
long G2=(c2 & 0x00FF00) >> 8;
100
long B1=(c1 & 0x0000FF);
101
long B2=(c2 & 0x0000FF);
103
return (((R1+R2)/2 << 16) | ((G1+G2)/2 << 8) | ((B1+B2)/2));
108
106
/*Draw a point on the backbuffer*/
109
static void sp(float x, float y, long c)
108
sp(float x, float y, long c)
113
if(x<0 || x>=width || y<0 || y>=height) return;
114
XSetForeground(dpy, gc, c);
115
XDrawPoint(dpy, backbuffer, gc, (int)x, (int)y);
112
if(x<0 || x>=width || y<0 || y>=height) return;
113
XSetForeground(dpy, gc, c);
114
XDrawPoint(dpy, backbuffer, gc, (int)x, (int)y);
118
117
/*Copy backbuffer to front buffer and clear backbuffer*/
119
static void draw(void)
128
XSetForeground(dpy, gc, blackColor);
128
XSetForeground(dpy, gc, blackColor);
138
/*Rotation, Scale, Translation X & Y*/
139
float ra,raa,sa,txa,tya;
145
static void CreateLens(float nr,
152
newlens->ra=newlens->raa=newlens->sa=newlens->txa=newlens->tya=0;
153
if(!norotate) newlens->r=nr;
156
if(!noscale) newlens->s=ns;
170
static float stepx(float x, float y, Lens *l)
172
return l->s*cos(l->r)*x+l->s*sin(l->r)*y+l->tx;
175
static float stepy(float x, float y, Lens *l)
177
return l->s*sin(l->r)*-x+l->s*cos(l->r)*y+l->ty;
180
static void mutate(Lens *l)
183
l->raa+=myrandom(0.002)-0.001;
186
if(l->ra>0.07 || l->ra<-0.07) l->ra/=1.4;
187
if(l->raa>0.005 || l->raa<-0.005) l->raa/=1.2;
190
l->sa+=myrandom(0.01)-0.005;
192
if(l->s>0.4) l->sa -=0.004;
193
if(l->s<-0.4) l->sa +=0.004;
194
if(l->sa>0.07 || l->sa<-0.07) l->sa/=1.4;
197
l->txa+=myrandom(0.004)-0.002;
198
l->tya+=myrandom(0.004)-0.002;
201
if(l->tx>6) l->txa-=0.004;
202
if(l->ty>6) l->tya-=0.004;
203
if(l->tx<-6) l->txa+=0.004;
204
if(l->ty<-6) l->tya+=0.004;
205
if(l->txa>0.05 || l->txa<-0.05) l->txa/=1.7;
206
if(l->tya>0.05 || l->tya<-0.05) l->tya/=1.7;
209
/*Groovy, colour-shifting functions!*/
138
/*Rotation, Scale, Translation X & Y*/
140
/*Old Rotation, Rotation Target, Rotation Counter*/
142
/*Old Scale, Scale Target, Scale Counter*/
144
/*Scale change, Translation change*/
151
CreateLens( float nr,
158
newlens->sa=newlens->txa=newlens->tya=0;
159
if(!norotate) newlens->r=nr;
162
if(!noscale) newlens->s=ns;
173
newlens->rc=newlens->sc=1;
178
stepx(float x, float y, Lens *l)
180
return l->s*cos(l->r)*x+l->s*sin(l->r)*y+l->tx;
183
stepy(float x, float y, Lens *l)
185
return l->s*sin(l->r)*-x+l->s*cos(l->r)*y+l->ty;
195
l->rt = myrandom(4)-2;
197
factor = (sin((-M_PI / 2.0) + M_PI * l->rc) + 1.0) / 2.0;
198
l->r=l->ro + (l->rt - l->ro) * factor;
205
/*Reset counter, obtain new target value*/
208
l->st = myrandom(2)-1;
210
factor = (sin((-M_PI / 2.0) + M_PI * l->sc) + 1.0) / 2.0;
211
/* Take average of old target and new target, using factor to *
212
* weight. It's computed sinusoidally, resulting in smooth, *
213
* rhythmic transitions. */
214
l->s=l->so + (l->st - l->so) * factor;
218
l->txa+=myrandom(0.004)-0.002;
219
l->tya+=myrandom(0.004)-0.002;
222
if(l->tx>6) l->txa-=0.004;
223
if(l->ty>6) l->tya-=0.004;
224
if(l->tx<-6) l->txa+=0.004;
225
if(l->ty<-6) l->tya+=0.004;
226
if(l->txa>0.05 || l->txa<-0.05) l->txa/=1.7;
227
if(l->tya>0.05 || l->tya<-0.05) l->tya/=1.7;
230
/*Groovy, colour-shifting functions!*/
216
237
/* Calls itself <lensnum> times - with results from each lens/function. *
217
238
* After <length> calls to itself, it stops iterating and draws a point. */
218
static void iterate(float x, float y, long curcol, int length)
240
iterate(float x, float y, long curcol, int length)
224
/*iterate(lenses[0].stepx(x,y),lenses[0].stepy(x,y),length-1);
225
iterate(lenses[1].stepx(x,y),lenses[1].stepy(x,y),length-1);
226
iterate(lenses[2].stepx(x,y),lenses[2].stepy(x,y),length-1);*/
227
for(i=0;i<lensnum;i++) {
229
case 0 : iterate(stepx( x, y, lenses[i]), stepy( x, y, lenses[i]), blend( curcol,colours[(int)lenses[i]->co].pixel ), length-1); break;
230
case 1 : iterate(stepx( x, y, lenses[i]), stepy( x, y, lenses[i]), colours[(int)lenses[i]->co].pixel, length-1); break;
231
case 2 : iterate(stepx( x, y, lenses[i]), stepy( x, y, lenses[i]), curcol, length-1); break;
246
for(i=0;i<lensnum;i++) {
248
case 0 : iterate(stepx( x, y, lenses[i]), stepy( x, y, lenses[i]), blend( curcol,colours[(int)lenses[i]->co].pixel ), length-1); break;
249
case 1 : iterate(stepx( x, y, lenses[i]), stepy( x, y, lenses[i]), colours[(int)lenses[i]->co].pixel, length-1); break;
250
case 2 : iterate(stepx( x, y, lenses[i]), stepy( x, y, lenses[i]), curcol, length-1); break;
239
258
/* Come on and iterate, iterate, iterate and sing... *
240
259
* Yeah, this function just calls iterate, mutate, *
241
260
* and then draws everything. */
242
static void step(void)
248
iterate(0,0,colours[wcol].pixel,length);
250
iterate(0,0,0xFFFFFF,length);
256
for(i=0;i<lensnum;i++) {
268
iterate(0,0,colours[wcol].pixel,length);
270
iterate(0,0,0xFFFFFF,length);
276
for(i=0;i<lensnum;i++) {
262
static void init_ifs(void)
266
XWindowAttributes xgwa;
268
delay = get_integer_resource("delay", "Delay");
269
length = get_integer_resource("length", "Detail");
270
mode = get_integer_resource("mode", "Mode");
272
norotate = get_boolean_resource("norotate", "NoRotate");
273
noscale = get_boolean_resource("noscale", "NoScale");
274
notranslate = get_boolean_resource("notranslate", "NoTranslate");
276
lensnum = get_integer_resource("lensnum", "Functions");
278
lenses = malloc(sizeof(Lens)*lensnum);
280
for(i=0;i<lensnum;i++) {
281
lenses[i]=malloc(sizeof(Lens));
284
/*Thanks go to Dad for teaching me how to allocate memory for struct**s . */
286
XGetWindowAttributes (dpy, w, &xgwa);
290
/*Initialise all this X shizzle*/
291
blackColor = BlackPixel(dpy, DefaultScreen(dpy));
292
whiteColor = WhitePixel(dpy, DefaultScreen(dpy));
293
rw = RootWindow(dpy, screen_num);
294
screen_num = DefaultScreen(dpy);
295
gc = XCreateGC(dpy, rw, 0, NULL);
297
/* Do me some colourmap magic. If we're using blend mode, this is just *
298
* for the nice colours - we're still using true/hicolour. Screw me if *
299
* I'm going to work out how to blend with colourmaps - I'm too young to *
300
* die!! On a sidenote, this is mostly stolen from halftone because I *
301
* don't really know what the hell I'm doing, here. */
302
ncolours = get_integer_resource("colors", "Colors");
303
if(ncolours < lensnum) ncolours=lensnum; /*apparently you're allowed to do this kind of thing...*/
304
colours = (XColor *)calloc(ncolours, sizeof(XColor));
305
make_smooth_colormap ( dpy,
311
/*No, I didn't have a clue what that really did... hopefully I have some colours in an array, now.*/
312
wcol = (int)myrandom(ncolours);
314
/*Double buffering - I can't be bothered working out the XDBE thingy*/
315
backbuffer = XCreatePixmap(dpy, w, width, height, XDefaultDepth(dpy, screen_num));
324
/*Colourmapped colours for the general prettiness*/
325
for(i=0;i<lensnum;i++) {
326
CreateLens( myrandom(1)-0.5,
287
XWindowAttributes xgwa;
289
delay = get_integer_resource("delay", "Delay");
290
length = get_integer_resource("length", "Detail");
291
mode = get_integer_resource("mode", "Mode");
293
norotate = get_boolean_resource("norotate", "NoRotate");
294
noscale = get_boolean_resource("noscale", "NoScale");
295
notranslate = get_boolean_resource("notranslate", "NoTranslate");
297
lensnum = get_integer_resource("lensnum", "Functions");
299
lenses = malloc(sizeof(Lens)*lensnum);
301
for(i=0;i<lensnum;i++) {
302
lenses[i]=malloc(sizeof(Lens));
305
/*Thanks go to Dad for teaching me how to allocate memory for struct**s . */
307
XGetWindowAttributes (dpy, w, &xgwa);
311
/*Initialise all this X shizzle*/
312
blackColor = BlackPixel(dpy, DefaultScreen(dpy));
313
whiteColor = WhitePixel(dpy, DefaultScreen(dpy));
314
rw = RootWindow(dpy, screen_num);
315
screen_num = DefaultScreen(dpy);
316
gc = XCreateGC(dpy, rw, 0, NULL);
318
/* Do me some colourmap magic. If we're using blend mode, this is just *
319
* for the nice colours - we're still using true/hicolour. Screw me if *
320
* I'm going to work out how to blend with colourmaps - I'm too young to *
321
* die!! On a sidenote, this is mostly stolen from halftone because I *
322
* don't really know what the hell I'm doing, here. */
323
ncolours = get_integer_resource("colors", "Colors");
324
if(ncolours < lensnum) ncolours=lensnum; /*apparently you're allowed to do this kind of thing...*/
325
colours = (XColor *)calloc(ncolours, sizeof(XColor));
326
make_smooth_colormap ( dpy,
332
/*No, I didn't have a clue what that really did... hopefully I have some colours in an array, now.*/
333
wcol = (int)myrandom(ncolours);
335
/*Double buffering - I can't be bothered working out the XDBE thingy*/
336
backbuffer = XCreatePixmap(dpy, w, width, height, XDefaultDepth(dpy, screen_num));
345
/*Colourmapped colours for the general prettiness*/
346
for(i=0;i<lensnum;i++) {
347
CreateLens( myrandom(1)-0.5,
336
357
screenhack (Display *display, Window window)
345
screenhack_handle_events(dpy);
346
if (delay) usleep(delay);
366
screenhack_handle_events(dpy);
367
if (delay) usleep(delay);