X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fsquiral.c;fp=hacks%2Fsquiral.c;h=fb7868feff039fcdb649a726e9fd51cbdcba1318;hb=df7adbee81405e2849728a24b498ad2117784b1f;hp=0000000000000000000000000000000000000000;hpb=41fae2ad67bc37e31c4d967bae81e4f3f50fa55a;p=xscreensaver diff --git a/hacks/squiral.c b/hacks/squiral.c new file mode 100644 index 00000000..fb7868fe --- /dev/null +++ b/hacks/squiral.c @@ -0,0 +1,223 @@ +/* squiral, by "Jeff Epler" , 18-mar-1999. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. No representations are made about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + */ + +#include "screenhack.h" +#include "colors.h" +#include "erase.h" +#include "yarandom.h" + +#define R(x) (abs(random())%x) +#define PROB(x) (abs(random())<(x*(double)RAND_MAX)) + +#define NCOLORSMAX 255 +static int width, height, count, cycle; +static double frac, disorder, handedness; +static int ncolors=0; +static GC draw_gc, erase_gc; +static XColor colors[NCOLORSMAX]; +#define STATES 8 + +/* 0- 3 left-winding */ +/* 4- 7 right-winding */ + +#define CLEAR1(x,y) (!fill[((y)%height)*width+(x)%width]) +#define MOVE1(x,y) (fill[((y)%height)*width+(x)%width]=1, XDrawPoint(dpy, window, draw_gc, (x)%width,(y)%height), cov++) + +static int cov; +static int dirh[4]; +static int dirv[4]; + +static int *fill; + +#define CLEARDXY(x,y,dx,dy) CLEAR1(x+dx, y+dy) && CLEAR1(x+dx+dx, y+dy+dy) +#define MOVEDXY(x,y,dx,dy) MOVE1 (x+dx, y+dy), MOVE1 (x+dx+dx, y+dy+dy) + +#define CLEAR(d) CLEARDXY(w->h,w->v, dirh[d],dirv[d]) +#define MOVE(d) (XSetForeground(dpy, draw_gc, colors[w->c].pixel), \ + MOVEDXY(w->h,w->v, dirh[d],dirv[d]), \ + w->h=w->h+dirh[d]*2, \ + w->v=w->v+dirv[d]*2, dir=d) + +#define RANDOM (void) (w->h = R(width), w->v = R(height), w->c = R(ncolors), \ + type=R(2), dir=R(4), (cycle && (w->cc=R(3)+ncolors))) + +struct worm { + int h; + int v; + int s; + int c; + int cc; +} *worms; + +#define SUCC(x) ((x+1)%4) +#define PRED(x) ((x+3)%4) +#define CCW PRED(dir) +#define CW SUCC(dir) +#define REV ((dir+2)%4) +#define STR (dir) +#define TRY(x) if (CLEAR(x)) { MOVE(x); break; } + +static void +do_worm(Display *dpy, Window window, struct worm *w) +{ + int type = w->s / 4; + int dir = w->s % 4; + + w->c = (w->c+w->cc) % ncolors; + + if (PROB(disorder)) type=PROB(handedness); + switch(type) { + case 0: /* CCW */ + TRY(CCW) + TRY(STR) + TRY(CW) + RANDOM; + break; + case 1: /* CW */ + TRY(CW) + TRY(STR) + TRY(CCW) + RANDOM; + break; + } + w->s = type*4+dir; + w->h = w->h % width; + w->v = w->v % height; +} + +static void +init_squiral(Display *dpy, Window window) +{ + XGCValues gcv; + Colormap cmap; + XWindowAttributes xgwa; + Bool writeable = False; + int i; + + XClearWindow(dpy, window); + XGetWindowAttributes(dpy, window, &xgwa); + width = xgwa.width; + height = xgwa.height; + + cmap = xgwa.colormap; + gcv.foreground = 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); + cmap = xgwa.colormap; + if( ncolors ) { + free_colors(dpy, cmap, colors, ncolors); + ncolors = 0; + } + if( mono_p ) { + ncolors=1; + colors[0].pixel=get_pixel_resource("foreground","Foreground", dpy, cmap); + } else { + ncolors = get_integer_resource("ncolors", "Integer"); + if (ncolors < 0 || ncolors > NCOLORSMAX) + ncolors = NCOLORSMAX; + make_uniform_colormap(dpy, xgwa.visual, cmap, colors, &ncolors, True, + &writeable, False); + if (ncolors <= 0) { + ncolors = 1; + colors[0].pixel=get_pixel_resource("foreground","Foreground",dpy, cmap); + } + } + count= get_integer_resource("count", "Integer"); + frac = get_integer_resource("fill", "Integer")*0.01; + cycle= get_boolean_resource("cycle", "Cycle"); + disorder=get_float_resource("disorder", "Float"); + handedness=get_float_resource("handedness", "Float"); + + if(frac<0.01) frac=0.01; + if(frac>0.99) frac=0.99; + if(count==0) count=width/32; + if(count<1) count=1; + if(count>1000) count=1000; + + if(worms) free(worms); + if(fill) free(fill); + + worms=calloc(count, sizeof(struct worm)); + fill=calloc(width*height, sizeof(int)); + + dirh[0]=0; dirh[1]=1; dirh[2]=0; dirh[3]=width-1; + dirv[0]=height-1; dirv[1]=0; dirv[2]=1; dirv[3]=0; + for(i=0;iheight/2) inclear=height; + } + else if(cov>(frac*width*height)) { + inclear=0; + cov=0; + } + for(i=0;i