1 /* xscreensaver, Copyright (c) 1993, 1995 Jamie Zawinski <jwz@netscape.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"
51 #define POINT_BUFFER_SIZE 10
54 static double f[2][3][MAXLEV]; /* three non-homogeneous transforms */
56 static int max_levels;
57 static int max_points;
61 static int num_points;
62 static int total_points;
65 static unsigned long *pixels;
66 static XPoint points [POINT_BUFFER_SIZE];
69 static int delay, delay2;
70 static int width, height;
76 static short lasthalf = 0;
94 init_flame (dpy, window)
99 XWindowAttributes xgwa;
101 XGetWindowAttributes (dpy, window, &xgwa);
103 height = xgwa.height;
104 cmap = xgwa.colormap;
106 max_points = get_integer_resource ("iterations", "Integer");
107 if (max_points <= 0) max_points = 100;
109 max_levels = max_points;
111 max_total = get_integer_resource ("points", "Integer");
112 if (max_total <= 0) max_total = 10000;
114 delay = get_integer_resource ("delay", "Integer");
115 if (delay < 0) delay = 0;
116 delay2 = get_integer_resource ("delay2", "Integer");
117 if (delay2 < 0) delay2 = 0;
123 int i = get_integer_resource ("ncolors", "Integer");
124 double saturation = 1.0;
129 pixels = (unsigned long *) malloc ((i+1) * sizeof (*pixels));
130 for (npixels = 0; npixels < i; npixels++)
132 hsv_to_rgb ((360*npixels)/i, saturation, value,
133 &color.red, &color.green, &color.blue);
134 if (! XAllocColor (dpy, cmap, &color))
136 pixels [npixels] = color.pixel;
140 gcv.foreground = get_pixel_resource ("foreground", "Foreground", dpy, cmap);
141 gcv.background = get_pixel_resource ("background", "Background", dpy, cmap);
145 pixcol = halfrandom (npixels);
146 gcv.foreground = (pixels [pixcol]);
149 gc = XCreateGC (dpy, window, GCForeground | GCBackground, &gcv);
153 recurse (x, y, l, dpy, win)
154 register double x, y;
165 if (total_points > max_total) /* how long each fractal runs */
168 if (x > -1.0 && x < 1.0 && y > -1.0 && y < 1.0)
170 xp = points[num_points].x = (int) ((width / 2) * (x + 1.0));
171 yp = points[num_points].y = (int) ((height / 2) * (y + 1.0));
173 if (num_points >= POINT_BUFFER_SIZE)
175 XDrawPoints (dpy, win, gc, points, num_points, CoordModeOrigin);
177 /* if (delay) usleep (delay); */
178 /* XSync (dpy, True); */
184 for (i = 0; i < snum; i++)
186 nx = f[0][0][i] * x + f[0][1][i] * y + f[0][2][i];
187 ny = f[1][0][i] * x + f[1][1][i] * y + f[1][2][i];
193 if (!recurse (nx, ny, l + 1, dpy, win))
209 if (!(cur_level++ % max_levels))
211 if (delay2) usleep (delay2);
212 XClearWindow (dpy, window);
219 XSetForeground (dpy, gc, pixels [pixcol]);
221 pixcol = npixels - 1;
225 /* number of functions */
226 snum = 2 + (cur_level % (MAXLEV - 1));
228 /* how many of them are of alternate form */
232 anum = halfrandom (snum) + 2;
234 /* 6 coefs per function */
235 for (k = 0; k < snum; k++)
237 for (i = 0; i < 2; i++)
238 for (j = 0; j < 3; j++)
239 f[i][j][k] = ((double) (random() & 1023) / 512.0 - 1.0);
243 (void) recurse (0.0, 0.0, 0, dpy, window);
244 XDrawPoints (dpy, window, gc, points, num_points, CoordModeOrigin);
246 if (delay) usleep (delay);
251 /* I don't understand why this is necessary, but I'm told that this program
252 does nothing at all on HP-sUX without it.
258 register struct exception *x;
260 if (x->type == PLOSS) return 1;
267 char *progclass = "Flame";
269 char *defaults [] = {
270 "Flame.background: black", /* to placate SGI */
271 "Flame.foreground: white",
280 XrmOptionDescRec options [] = {
281 { "-ncolors", ".colors", XrmoptionSepArg, 0 },
282 { "-iterations", ".iterations", XrmoptionSepArg, 0 },
283 { "-delay", ".delay", XrmoptionSepArg, 0 },
284 { "-delay2", ".delay2", XrmoptionSepArg, 0 },
285 { "-points", ".points", XrmoptionSepArg, 0 }
287 int options_size = (sizeof (options) / sizeof (options[0]));
290 screenhack (dpy, window)
294 init_flame (dpy, window);