1 /* xscreensaver, Copyright (c) 1993 Jamie Zawinski <jwz@mcom.com>
3 * Permission to use, copy, modify, distribute, and sell this software and its
4 * documentation for any purpose is hereby granted without fee, provided that
5 * the above copyright notice appear in all copies and that both that
6 * copyright notice and this permission notice appear in supporting
7 * documentation. No representations are made about the suitability of this
8 * software for any purpose. It is provided "as is" without express or
12 /* This file was ported from xlock for use in xscreensaver (and standalone)
13 * by jwz on 18-Oct-93. Original copyright reads:
15 * static char sccsid[] = "@(#)flame.c 1.4 91/09/27 XLOCK";
17 * flame.c - recursive fractal cosmic flames.
19 * Copyright (c) 1991 by Patrick J. Naughton.
21 * Permission to use, copy, modify, and distribute this software and its
22 * documentation for any purpose and without fee is hereby granted,
23 * provided that the above copyright notice appear in all copies and that
24 * both that copyright notice and this permission notice appear in
25 * supporting documentation.
27 * This file is provided AS IS with no warranties of any kind. The author
28 * shall have no liability with respect to the infringement of copyrights,
29 * trade secrets or any patents by this file or any part thereof. In no
30 * event will the author be liable for any lost revenue or profits or
31 * other special, indirect and consequential damages.
33 * Comments and additions should be sent to the author:
35 * naughton@eng.sun.com
39 * Sun Laboritories, Inc.
41 * Mountain View, CA 94043
44 * 27-Jun-91: vary number of functions used.
45 * 24-Jun-91: fixed portability problem with integer mod (%).
46 * 06-Jun-91: Written. (received from Scott Graves, spot@cs.cmu.edu).
49 #include "screenhack.h"
53 #define POINT_BUFFER_SIZE 10
56 static double f[2][3][MAXLEV]; /* three non-homogeneous transforms */
58 static int max_levels;
59 static int max_points;
63 static int num_points;
64 static int total_points;
67 static unsigned long *pixels;
68 static XPoint points [POINT_BUFFER_SIZE];
71 static int delay, delay2;
72 static int width, height;
78 static short lasthalf = 0;
96 init_flame (dpy, window)
101 XWindowAttributes xgwa;
103 XGetWindowAttributes (dpy, window, &xgwa);
105 height = xgwa.height;
106 cmap = xgwa.colormap;
108 max_points = get_integer_resource ("iterations", "Integer");
109 if (max_points <= 0) max_points = 100;
111 max_levels = max_points;
113 max_total = get_integer_resource ("points", "Integer");
114 if (max_total <= 0) max_total = 10000;
116 delay = get_integer_resource ("delay", "Integer");
117 if (delay < 0) delay = 0;
118 delay2 = get_integer_resource ("delay2", "Integer");
119 if (delay2 < 0) delay2 = 0;
125 int i = get_integer_resource ("ncolors", "Integer");
126 double saturation = 1.0;
131 pixels = (unsigned long *) malloc ((i+1) * sizeof (*pixels));
132 for (npixels = 0; npixels < i; npixels++)
134 hsv_to_rgb ((360*npixels)/i, saturation, value,
135 &color.red, &color.green, &color.blue);
136 if (! XAllocColor (dpy, cmap, &color))
138 pixels [npixels] = color.pixel;
142 gcv.foreground = get_pixel_resource ("foreground", "Foreground", dpy, cmap);
143 gcv.background = get_pixel_resource ("background", "Background", dpy, cmap);
147 pixcol = halfrandom (npixels);
148 gcv.foreground = (pixels [pixcol]);
151 gc = XCreateGC (dpy, window, GCForeground | GCBackground, &gcv);
155 recurse (x, y, l, dpy, win)
156 register double x, y;
167 if (total_points > max_total) /* how long each fractal runs */
170 if (x > -1.0 && x < 1.0 && y > -1.0 && y < 1.0)
172 xp = points[num_points].x = (int) ((width / 2) * (x + 1.0));
173 yp = points[num_points].y = (int) ((height / 2) * (y + 1.0));
175 if (num_points >= POINT_BUFFER_SIZE)
177 XDrawPoints (dpy, win, gc, points, num_points, CoordModeOrigin);
179 /* if (delay) usleep (delay); */
180 /* XSync (dpy, True); */
186 for (i = 0; i < snum; i++)
188 nx = f[0][0][i] * x + f[0][1][i] * y + f[0][2][i];
189 ny = f[1][0][i] * x + f[1][1][i] * y + f[1][2][i];
195 if (!recurse (nx, ny, l + 1, dpy, win))
211 if (!(cur_level++ % max_levels))
213 if (delay2) usleep (delay2);
214 XClearWindow (dpy, window);
221 XSetForeground (dpy, gc, pixels [pixcol]);
223 pixcol = npixels - 1;
227 /* number of functions */
228 snum = 2 + (cur_level % (MAXLEV - 1));
230 /* how many of them are of alternate form */
234 anum = halfrandom (snum) + 2;
236 /* 6 coefs per function */
237 for (k = 0; k < snum; k++)
239 for (i = 0; i < 2; i++)
240 for (j = 0; j < 3; j++)
241 f[i][j][k] = ((double) (random() & 1023) / 512.0 - 1.0);
245 (void) recurse (0.0, 0.0, 0, dpy, window);
246 XDrawPoints (dpy, window, gc, points, num_points, CoordModeOrigin);
248 if (delay) usleep (delay);
252 char *progclass = "Flame";
254 char *defaults [] = {
255 "Flame.background: black", /* to placate SGI */
256 "Flame.foreground: white",
265 XrmOptionDescRec options [] = {
266 { "-ncolors", ".colors", XrmoptionSepArg, 0 },
267 { "-iterations", ".iterations", XrmoptionSepArg, 0 },
268 { "-delay", ".delay", XrmoptionSepArg, 0 },
269 { "-delay2", ".delay2", XrmoptionSepArg, 0 },
270 { "-points", ".points", XrmoptionSepArg, 0 }
272 int options_size = (sizeof (options) / sizeof (options[0]));
275 screenhack (dpy, window)
279 init_flame (dpy, window);