* Cloudlife only draws one pixel of each cell per tick, whether the cell is
* alive or dead. So gliders look like little comets.
+ * 20 May 2003 -- now includes color cycling and a man page.
+
* Based on several examples from the hacks directory of:
* xscreensaver, Copyright (c) 1997, 1998, 2002 Jamie Zawinski <jwz@jwz.org>
#define inline /* */
#endif
-typedef struct {
+struct field {
unsigned int height;
unsigned int width;
unsigned int max_age;
unsigned int cell_size;
unsigned char *cells;
unsigned char *new_cells;
-} field;
+};
static void
*xrealloc(void *p, size_t size)
return ret;
}
-field
+struct field
*init_field(void)
{
- field *f = xrealloc(NULL, sizeof(field));
+ struct field *f = xrealloc(NULL, sizeof(struct field));
f->height = 0;
f->width = 0;
f->cell_size = get_integer_resource("cellSize", "Integer");
}
void
-resize_field(field * f, unsigned int w, unsigned int h)
+resize_field(struct field * f, unsigned int w, unsigned int h)
{
f->width = w;
f->height = h;
}
inline unsigned char
-*cell_at(field * f, unsigned int x, unsigned int y)
+*cell_at(struct field * f, unsigned int x, unsigned int y)
{
return (f->cells + x * sizeof(unsigned char) +
y * f->width * sizeof(unsigned char));
}
inline unsigned char
-*new_cell_at(field * f, unsigned int x, unsigned int y)
+*new_cell_at(struct field * f, unsigned int x, unsigned int y)
{
return (f->new_cells + x * sizeof(unsigned char) +
y * f->width * sizeof(unsigned char));
static void
draw_field(Display * dpy,
- Window window, Colormap cmap, GC fgc, GC bgc, field * f)
+ Window window, GC fgc, GC bgc, struct field * f)
{
unsigned int x, y;
unsigned int rx, ry = 0; /* random amount to offset the dot */
}
inline unsigned int
-is_alive(field * f, unsigned int x, unsigned int y)
+is_alive(struct field * f, unsigned int x, unsigned int y)
{
unsigned int count;
unsigned int i, j;
}
unsigned int
-do_tick(field * f)
+do_tick(struct field * f)
{
unsigned int x, y;
unsigned int count = 0;
}
void
-populate_field(field * f, unsigned int p)
+populate_field(struct field * f, unsigned int p)
{
unsigned int x, y;
}
void
-populate_edges(field * f, unsigned int p)
+populate_edges(struct field * f, unsigned int p)
{
unsigned int i;
".background: black",
".foreground: blue",
"*cycleDelay: 25000",
+ "*cycleColors: 2",
+ "*ncolors: 64",
"*maxAge: 64",
- "*initialDensity: 160",
+ "*initialDensity: 30",
"*cellSize: 3",
0
};
{"-background", ".background", XrmoptionSepArg, 0},
{"-foreground", ".foreground", XrmoptionSepArg, 0},
{"-cycle-delay", ".cycleDelay", XrmoptionSepArg, 0},
+ {"-cycle-colors", ".cycleColors", XrmoptionSepArg, 0},
+ {"-ncolors", ".ncolors", XrmoptionSepArg, 0},
{"-cell-size", ".cellSize", XrmoptionSepArg, 0},
{"-initial-density", ".initialDensity", XrmoptionSepArg, 0},
{"-max-age", ".maxAge", XrmoptionSepArg, 0},
void screenhack(Display * dpy, Window window)
{
- field *f = init_field();
+ struct field *f = init_field();
#ifdef TIME_ME
time_t start_time = time(NULL);
#endif
unsigned int cycles = 0;
+ unsigned int colorindex = 0; /* which color in the colormap are we on */
+ unsigned int colortimer = 0; /* when this reaches 0, cycle to next color */
+
+ int cycle_delay;
+ int cycle_colors;
+ int ncolors;
+ int density;
GC fgc, bgc;
XGCValues gcv;
XWindowAttributes xgwa;
+ XColor *colors = NULL;
+ Bool tmp = True;
+
+ cycle_delay = get_integer_resource("cycleDelay", "Integer");
+ cycle_colors = get_integer_resource("cycleColors", "Integer");
+ ncolors = get_integer_resource("ncolors", "Integer");
+ density = (get_integer_resource("initialDensity", "Integer")
+ % 100 * 256)/100;
- unsigned int cycle_delay = (unsigned int)
- get_integer_resource("cycleDelay", "Integer");
- unsigned int density = (unsigned int)
- get_integer_resource("initialDensity", "Integer") & 0xff;
XGetWindowAttributes(dpy, window, &xgwa);
+ if (cycle_colors) {
+ colors = (XColor *) xrealloc(colors, sizeof(XColor) * (ncolors+1));
+ make_smooth_colormap (dpy, xgwa.visual, xgwa.colormap, colors, &ncolors,
+ True, &tmp, True);
+ }
+
gcv.foreground = get_pixel_resource("foreground", "Foreground",
dpy, xgwa.colormap);
fgc = XCreateGC(dpy, window, GCForeground, &gcv);
bgc = XCreateGC(dpy, window, GCForeground, &gcv);
while (1) {
+
+ if (cycle_colors) {
+ if (colortimer == 0) {
+ colortimer = cycle_colors;
+ if( colorindex == 0 )
+ colorindex = ncolors;
+ colorindex--;
+ XSetForeground(dpy, fgc, colors[colorindex].pixel);
+ }
+ colortimer--;
+ }
+
XGetWindowAttributes(dpy, window, &xgwa);
if (f->height != xgwa.height / (1 << f->cell_size) + 2 ||
f->width != xgwa.width / (1 << f->cell_size) + 2) {
screenhack_handle_events(dpy);
- draw_field(dpy, window, xgwa.colormap, fgc, bgc, f);
+ draw_field(dpy, window, fgc, bgc, f);
if (do_tick(f) < (f->height + f->width) / 4) {
populate_field(f, density);
}
XSync(dpy, False);
-
+
cycles++;
if (cycle_delay)