X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fhelix.c;h=97de40dc7fb360ddd50a89b3ba5aba9659bb2a46;hb=0bd2eabab3e404c6769fe8f59b639275e960c415;hp=31ab7f02c552792a37ef00c89243941d504d7c7b;hpb=258170f6204e23da06f272ffda1f4504b6ae2eaf;p=xscreensaver diff --git a/hacks/helix.c b/hacks/helix.c index 31ab7f02..97de40dc 100644 --- a/hacks/helix.c +++ b/hacks/helix.c @@ -1,4 +1,5 @@ -/* xscreensaver, Copyright (c) 1992 Jamie Zawinski +/* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997 + * Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -9,22 +10,28 @@ * implied warranty. */ -#include "screenhack.h" +/* Algorithm from a Mac program by Chris Tate, written in 1988 or so. */ + +/* 18-Sep-97: Johannes Keukelaar (johannes@nada.kth.se): Improved screen + * eraser. + * 10-May-97: merged ellipse code by Dan Stromberg + * as found in xlockmore 4.03a10. + * 1992: jwz created. + */ + #include -#if __STDC__ -#include -#endif +#include "screenhack.h" +#include "erase.h" static double sins [360]; static double coss [360]; -static GC draw_gc, erase_gc; +static GC draw_gc; static unsigned int default_fg_pixel; +static int sleep_time; static void -init_helix (dpy, window) - Display *dpy; - Window window; +init_helix (Display *dpy, Window window) { int i; XGCValues gcv; @@ -36,7 +43,6 @@ init_helix (dpy, window) get_pixel_resource ("foreground", "Foreground", dpy, cmap); draw_gc = XCreateGC (dpy, window, GCForeground, &gcv); gcv.foreground = get_pixel_resource ("background", "Background", dpy, cmap); - erase_gc = XCreateGC (dpy, window, GCForeground, &gcv); for (i = 0; i < 360; i++) { @@ -46,8 +52,7 @@ init_helix (dpy, window) } static int -gcd (a, b) - int a, b; +gcd (int a, int b) { while (b > 0) { @@ -60,13 +65,9 @@ gcd (a, b) } static void -helix (dpy, window, - radius1, radius2, d_angle, - factor1, factor2, factor3, factor4) - Display *dpy; - Window window; - int radius1, radius2, d_angle; - int factor1, factor2, factor3, factor4; +helix (Display *dpy, Window window, + int radius1, int radius2, int d_angle, + int factor1, int factor2, int factor3, int factor4) { XWindowAttributes xgwa; int width, height; @@ -91,31 +92,65 @@ helix (dpy, window, for (i = 0; i < limit; i++) { int tmp; -#define pmod(x,y) (tmp = (x % y), (tmp >= 0 ? tmp : tmp + y)) +#define pmod(x,y) (tmp=((x) % (y)), (tmp >= 0 ? tmp : (tmp + (y)))) + x1 = xmid + (((double) radius1) * sins [pmod ((angle * factor1), 360)]); y1 = ymid + (((double) radius2) * coss [pmod ((angle * factor2), 360)]); XDrawLine (dpy, window, draw_gc, x1, y1, x2, y2); x2 = xmid + (((double) radius2) * sins [pmod ((angle * factor3), 360)]); y2 = ymid + (((double) radius1) * coss [pmod ((angle * factor4), 360)]); + XDrawLine (dpy, window, draw_gc, x1, y1, x2, y2); angle += d_angle; XFlush (dpy); } } +static void +trig (Display *dpy, Window window, + int d_angle, int factor1, int factor2, + int offset, int d_angle_offset, int dir, int density) +{ + XWindowAttributes xgwa; + int width, height; + int xmid, ymid; + int x1, y1, x2, y2; + int tmp, angle; + Colormap cmap; + + XClearWindow (dpy, window); + XGetWindowAttributes (dpy, window, &xgwa); + cmap = xgwa.colormap; + width = xgwa.width; + height = xgwa.height; + + xmid = width / 2; + ymid = height / 2; + + while (d_angle >= -360 && d_angle <= 360) + { + angle = d_angle + d_angle_offset; + x1 = (sins [pmod(angle * factor1, 360)] * xmid) + xmid; + y1 = (coss [pmod(angle * factor1, 360)] * ymid) + ymid; + x2 = (sins [pmod(angle * factor2 + offset, 360)] * xmid) + xmid; + y2 = (coss [pmod(angle * factor2 + offset, 360)] * ymid) + ymid; + XDrawLine(dpy, window, draw_gc, x1, y1, x2, y2); + tmp = (int) 360 / (2 * density * factor1 * factor2); + if (tmp == 0) /* Do not want it getting stuck... */ + tmp = 1; /* Would not need if floating point */ + d_angle += dir * tmp; + } +} + #define min(a,b) ((a)<(b)?(a):(b)) static void -random_helix (dpy, window) - Display *dpy; - Window window; +random_helix (Display *dpy, Window window, XColor *color, Bool *got_color) { Colormap cmap; int width, height; int radius, radius1, radius2, d_angle, factor1, factor2, factor3, factor4; double divisor; - XColor color; - int i, got_color = 0; XWindowAttributes xgwa; XGetWindowAttributes (dpy, window, &xgwa); width = xgwa.width; @@ -163,28 +198,82 @@ random_helix (dpy, window) else { hsv_to_rgb (random () % 360, frand (1.0), frand (0.5) + 0.5, - &color.red, &color.green, &color.blue); - if ((got_color = XAllocColor (dpy, cmap, &color))) - XSetForeground (dpy, draw_gc, color.pixel); + &color->red, &color->green, &color->blue); + if ((*got_color = XAllocColor (dpy, cmap, color))) + XSetForeground (dpy, draw_gc, color->pixel); else XSetForeground (dpy, draw_gc, default_fg_pixel); } helix (dpy, window, radius1, radius2, d_angle, factor1, factor2, factor3, factor4); +} - XSync (dpy, True); - sleep (5); +static void +random_trig (Display *dpy, Window window, XColor *color, Bool *got_color) +{ + Colormap cmap; + int width, height; + int radius, d_angle, factor1, factor2; + int offset, d_angle_offset, dir, density; + + XWindowAttributes xgwa; + XGetWindowAttributes (dpy, window, &xgwa); + width = xgwa.width; + height = xgwa.height; + cmap = xgwa.colormap; + + radius = min (width, height) / 2; + + d_angle = 0; + factor1 = (random() % 8) + 1; + do { + factor2 = (random() % 8) + 1; + } while (factor1 == factor2); + + dir = (random() & 1) ? 1 : -1; + d_angle_offset = random() % 360; + offset = ((random() % ((360 / 4) - 1)) + 1) / 4; + density = 1 << ((random() % 4) + 4); /* Higher density, higher angles */ - for (i = 0; i < height; i++) + if (mono_p) + XSetForeground (dpy, draw_gc, default_fg_pixel); + else { - int y = (random () % height); - XDrawLine (dpy, window, erase_gc, 0, y, width, y); - XFlush (dpy); - if ((i % 50) == 0) - usleep (10000); + hsv_to_rgb (random () % 360, frand (1.0), frand (0.5) + 0.5, + &color->red, &color->green, &color->blue); + if ((*got_color = XAllocColor (dpy, cmap, color))) + XSetForeground (dpy, draw_gc, color->pixel); + else + XSetForeground (dpy, draw_gc, default_fg_pixel); } - XClearWindow (dpy, window); - if (got_color) XFreeColors (dpy, cmap, &color.pixel, 1, 0); + trig (dpy, window, d_angle, factor1, factor2, + offset, d_angle_offset, dir, density); +} + +static void +random_helix_or_trig (Display *dpy, Window window) +{ + Bool free_color = False; + XColor color; + int width, height; + XWindowAttributes xgwa; + Colormap cmap; + XGetWindowAttributes (dpy, window, &xgwa); + width = xgwa.width; + height = xgwa.height; + cmap = xgwa.colormap; + + if (random() & 1) + random_helix(dpy, window, &color, &free_color); + else + random_trig(dpy, window, &color, &free_color); + + XSync (dpy, True); + sleep ( sleep_time ); + + erase_full_window(dpy, window); + + if (free_color) XFreeColors (dpy, cmap, &color.pixel, 1, 0); XSync (dpy, True); sleep (1); } @@ -193,19 +282,22 @@ random_helix (dpy, window) char *progclass = "Helix"; char *defaults [] = { - "*background: black", + ".background: black", + "*delay: 5", 0 }; -XrmOptionDescRec options [] = { 0 }; -int options_size = 0; +XrmOptionDescRec options [] = { + { "-delay", ".delay", XrmoptionSepArg, 0 }, + { 0 }, +}; +int options_size = (sizeof (options) / sizeof (options[0])); void -screenhack (dpy, window) - Display *dpy; - Window window; +screenhack (Display *dpy, Window window) { + sleep_time = get_integer_resource("delay", "Integer"); init_helix (dpy, window); while (1) - random_helix (dpy, window); + random_helix_or_trig (dpy, window); }