X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fhelix.c;h=7ca03da7760377aed93d87006bac39bb71ae977d;hb=96a411663168b0ba5432b407a83be55f3df0c802;hp=25149c30def1bd1878e5b61d30088e4da605535b;hpb=65740e2a8dea3d6309ae6e8914a0fb79e993ada8;p=xscreensaver diff --git a/hacks/helix.c b/hacks/helix.c old mode 100755 new mode 100644 index 25149c30..7ca03da7 --- 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,25 +10,32 @@ * 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. + */ + +/* 25 April 2002: Matthew Strait added +-subdelay option so the drawing process can be watched */ + #include -#ifdef VMS -#define M_PI 3.14159265358979323846 -#endif -#if __STDC__ -#include /* for M_PI */ -#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 int subdelay; static void -init_helix (dpy, window) - Display *dpy; - Window window; +init_helix (Display *dpy, Window window) { int i; XGCValues gcv; @@ -39,7 +47,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++) { @@ -49,8 +56,7 @@ init_helix (dpy, window) } static int -gcd (a, b) - int a, b; +gcd (int a, int b) { while (b > 0) { @@ -63,13 +69,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; @@ -94,7 +96,8 @@ 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); @@ -102,6 +105,52 @@ helix (dpy, window, y2 = ymid + (((double) radius1) * coss [pmod ((angle * factor4), 360)]); XDrawLine (dpy, window, draw_gc, x1, y1, x2, y2); angle += d_angle; + + /* if we sleep every time, it's too slow */ + if(subdelay && i%16 == 0) usleep(subdelay); + + 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; + + /* this draws faster, so we sleep somewhat more often */ + if(subdelay && d_angle%4 == 0) usleep(subdelay); + + /* without this, the subdelay effect is lost */ XFlush (dpy); } } @@ -109,16 +158,12 @@ helix (dpy, window, #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; @@ -166,29 +211,86 @@ 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); +} + +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; - XSync (dpy, True); - sleep (5); + radius = min (width, height) / 2; + + d_angle = 0; + factor1 = (random() % 8) + 1; + do { + factor2 = (random() % 8) + 1; + } while (factor1 == factor2); - for (i = 0; i < height; i++) + 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 */ + + 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); - XSync (dpy, True); + 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, False); + screenhack_handle_events (dpy); + sleep ( sleep_time ); + + screenhack_handle_events (dpy); + erase_full_window(dpy, window); + + if (free_color) XFreeColors (dpy, cmap, &color.pixel, 1, 0); + XSync (dpy, False); + screenhack_handle_events (dpy); sleep (1); } @@ -196,19 +298,25 @@ random_helix (dpy, window) char *progclass = "Helix"; char *defaults [] = { - "Helix.background: black", /* to placate SGI */ + ".background: black", + "*delay: 5", + "*subdelay: 0", 0 }; -XrmOptionDescRec options [] = { 0 }; -int options_size = 0; +XrmOptionDescRec options [] = { + { "-delay", ".delay", XrmoptionSepArg, 0 }, + { "-subdelay", ".subdelay", XrmoptionSepArg, 0 }, + { 0, 0, 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"); + subdelay = get_integer_resource("subdelay", "Integer"); init_helix (dpy, window); while (1) - random_helix (dpy, window); + random_helix_or_trig (dpy, window); }