From d3a98cf6cbc3bd0b9efc570f58e8812c03931c18 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 16 Oct 2018 10:08:48 +0200 Subject: Original 5.40 --- hacks/squiral.c | 290 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 hacks/squiral.c (limited to 'hacks/squiral.c') diff --git a/hacks/squiral.c b/hacks/squiral.c new file mode 100644 index 0000000..a38e060 --- /dev/null +++ b/hacks/squiral.c @@ -0,0 +1,290 @@ +/* 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) (random()%x) +#define PROB(x) (frand(1.0) < (x)) + +#define NCOLORSMAX 255 +#define STATES 8 + +/* 0- 3 left-winding */ +/* 4- 7 right-winding */ + +struct worm { + int h; + int v; + int s; + int c; + int cc; +}; + + +struct state { + Display *dpy; + Window window; + + int width, height, count, cycle; + double frac, disorder, handedness; + int ncolors; + GC draw_gc, erase_gc; + XColor colors[NCOLORSMAX]; + + int delay; + + int cov; + int dirh[4]; + int dirv[4]; + + int *fill; + + struct worm *worms; + int inclear; +}; + +#define CLEAR1(x,y) (!st->fill[((y)%st->height)*st->width+(x)%st->width]) +#define MOVE1(x,y) (st->fill[((y)%st->height)*st->width+(x)%st->width]=1, XDrawPoint(st->dpy, st->window, st->draw_gc, (x)%st->width,(y)%st->height), st->cov++) + +#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, st->dirh[d],st->dirv[d]) +#define MOVE(d) (XSetForeground(st->dpy, st->draw_gc, st->colors[w->c].pixel), \ + MOVEDXY(w->h,w->v, st->dirh[d],st->dirv[d]), \ + w->h=w->h+st->dirh[d]*2, \ + w->v=w->v+st->dirv[d]*2, dir=d) + +#define RANDOM (void) (w->h = R(st->width), w->v = R(st->height), w->c = R(st->ncolors), \ + type=R(2), dir=R(4), (st->cycle && (w->cc=R(3)+st->ncolors))) + + + +#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(struct state *st, struct worm *w) +{ + int type = w->s / 4; + int dir = w->s % 4; + + w->c = (w->c+w->cc) % st->ncolors; + + if (PROB(st->disorder)) type=PROB(st->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 % st->width; + w->v = w->v % st->height; +} + +static void +squiral_init_1 (struct state *st) +{ + int i; + if (st->worms) free (st->worms); + if (st->fill) free (st->fill); + + st->worms=calloc(st->count, sizeof(struct worm)); + st->fill=calloc(st->width*st->height, sizeof(int)); + + st->dirh[0]=0; st->dirh[1]=1; st->dirh[2]=0; st->dirh[3]=st->width-1; + st->dirv[0]=st->height-1; st->dirv[1]=0; st->dirv[2]=1; st->dirv[3]=0; + for(i=0;icount;i++) { + st->worms[i].h=R(st->width); + st->worms[i].v=R(st->height); + st->worms[i].s=R(4)+4*PROB(st->handedness); + st->worms[i].c=R(st->ncolors); + if(st->cycle) { st->worms[i].cc=R(3)+st->ncolors; } + else st->worms[i].cc=0; + } +} + +static void * +squiral_init (Display *dpy, Window window) +{ + struct state *st = (struct state *) calloc (1, sizeof(*st)); + XGCValues gcv; + Colormap cmap; + XWindowAttributes xgwa; + Bool writeable = False; + + st->dpy = dpy; + st->window = window; + + st->delay= get_integer_resource(st->dpy, "delay", "Integer"); + + XClearWindow(st->dpy, st->window); + XGetWindowAttributes(st->dpy, st->window, &xgwa); + st->width = xgwa.width; + st->height = xgwa.height; + + cmap = xgwa.colormap; + gcv.foreground = get_pixel_resource(st->dpy, cmap, "foreground", + "Foreground"); + st->draw_gc = XCreateGC(st->dpy, st->window, GCForeground, &gcv); + gcv.foreground = get_pixel_resource (st->dpy, cmap, "background", "Background"); + st->erase_gc = XCreateGC (st->dpy, st->window, GCForeground, &gcv); + cmap = xgwa.colormap; + if( st->ncolors ) { + free_colors(xgwa.screen, cmap, st->colors, st->ncolors); + st->ncolors = 0; + } + if( mono_p ) { + st->ncolors=1; + st->colors[0].pixel=get_pixel_resource(st->dpy, cmap, "foreground","Foreground"); + } else { + st->ncolors = get_integer_resource(st->dpy, "ncolors", "Integer"); + if (st->ncolors < 0 || st->ncolors > NCOLORSMAX) + st->ncolors = NCOLORSMAX; + make_uniform_colormap(xgwa.screen, xgwa.visual, cmap, + st->colors, &st->ncolors, True, + &writeable, False); + if (st->ncolors <= 0) { + st->ncolors = 1; + st->colors[0].pixel=get_pixel_resource(st->dpy, cmap, "foreground","Foreground"); + } + } + st->count= get_integer_resource(st->dpy, "count", "Integer"); + st->frac = get_integer_resource(st->dpy, "fill", "Integer")*0.01; + st->cycle= get_boolean_resource(st->dpy, "cycle", "Cycle"); + st->disorder=get_float_resource(st->dpy, "disorder", "Float"); + st->handedness=get_float_resource(st->dpy, "handedness", "Float"); + + if(st->frac<0.01) st->frac=0.01; + if(st->frac>0.99) st->frac=0.99; + if(st->count==0) st->count=st->width/32; + if(st->count<1) st->count=1; + if(st->count>1000) st->count=1000; + + if(st->worms) free(st->worms); + if(st->fill) free(st->fill); + + squiral_init_1 (st); + + return st; +} + +static unsigned long +squiral_draw (Display *dpy, Window window, void *closure) +{ + struct state *st = (struct state *) closure; + int i; + + if(st->inclearheight) { + XDrawLine(st->dpy, st->window, st->erase_gc, 0, st->inclear, st->width-1, st->inclear); + memset(&st->fill[st->inclear*st->width], 0, sizeof(int)*st->width); + XDrawLine(st->dpy, st->window, st->erase_gc, 0, st->height-st->inclear-1, st->width-1, + st->height-st->inclear-1); + memset(&st->fill[(st->height-st->inclear-1)*st->width], 0, sizeof(int)*st->width); + st->inclear++; + XDrawLine(st->dpy, st->window, st->erase_gc, 0, st->inclear, st->width-1, st->inclear); + if (st->inclear < st->height) + memset(&st->fill[st->inclear*st->width], 0, sizeof(int)*st->width); + XDrawLine(st->dpy, st->window, st->erase_gc, 0, st->height-st->inclear-1, st->width-1, + st->height-st->inclear-1); + if (st->height - st->inclear >= 1) + memset(&st->fill[(st->height-st->inclear-1)*st->width], 0, sizeof(int)*st->width); + st->inclear++; + if(st->inclear>st->height/2) st->inclear=st->height; + } + else if(st->cov>(st->frac*st->width*st->height)) { + st->inclear=0; + st->cov=0; + } + for(i=0;icount;i++) do_worm(st, &st->worms[i]); + return st->delay; +} + +static void +squiral_reshape (Display *dpy, Window window, void *closure, + unsigned int w, unsigned int h) +{ + struct state *st = (struct state *) closure; + st->width = w; + st->height = h; + squiral_init_1 (st); + XClearWindow (dpy, window); +} + +static Bool +squiral_event (Display *dpy, Window window, void *closure, XEvent *event) +{ + struct state *st = (struct state *) closure; + if (screenhack_event_helper (dpy, window, event)) + { + squiral_init_1 (st); + XClearWindow (dpy, window); + return True; + } + return False; +} + +static void +squiral_free (Display *dpy, Window window, void *closure) +{ + struct state *st = (struct state *) closure; + free (st); +} + + +static const char *squiral_defaults[] = { + ".lowrez: true", + ".background: black", + ".foreground: white", + "*fpsSolid: true", + "*fill: 75", + "*count: 0", + "*ncolors: 100", + "*delay: 10000", + "*disorder: 0.005", + "*cycle: False", + "*handedness: 0.5", +#ifdef HAVE_MOBILE + "*ignoreRotation: True", +#endif + 0 +}; + +static XrmOptionDescRec squiral_options[] = { + {"-fill", ".fill", XrmoptionSepArg, 0}, + {"-count", ".count", XrmoptionSepArg, 0}, + {"-delay", ".delay", XrmoptionSepArg, 0}, + {"-disorder", ".disorder", XrmoptionSepArg, 0}, + {"-handedness", ".handedness", XrmoptionSepArg, 0}, + {"-ncolors", ".ncolors", XrmoptionSepArg, 0}, + {"-cycle", ".cycle", XrmoptionNoArg, "True"}, + {"-no-cycle", ".cycle", XrmoptionNoArg, "False"}, + { 0, 0, 0, 0 } +}; + +XSCREENSAVER_MODULE ("Squiral", squiral) -- cgit v1.2.3-55-g7522