source: trunk/third/xscreensaver/hacks/squiral.c @ 20148

Revision 20148, 6.2 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20147, which included commits to RCS files with non-trunk default branches.
Line 
1/* squiral, by "Jeff Epler" <jepler@inetnebr.com>, 18-mar-1999.
2 *
3 * Permission to use, copy, modify, distribute, and sell this software and its
4 * documentation for any purpose is hereby granted without fee, provided that
5 * the above copyright notice appear in all copies and that both that
6 * copyright notice and this permission notice appear in supporting
7 * documentation.  No representations are made about the suitability of this
8 * software for any purpose.  It is provided "as is" without express or
9 * implied warranty.
10 */
11
12#include "screenhack.h"
13#include "colors.h"
14#include "erase.h"
15#include "yarandom.h"
16
17#define R(x)  (abs(random())%x)
18#define PROB(x) (frand(1.0) < (x))
19
20#define NCOLORSMAX 255
21static int width, height, count, cycle;
22static double frac, disorder, handedness;
23static int ncolors=0;
24static GC draw_gc, erase_gc;
25static XColor colors[NCOLORSMAX];
26#define STATES 8
27
28/* 0- 3 left-winding  */
29/* 4- 7 right-winding */
30
31#define CLEAR1(x,y) (!fill[((y)%height)*width+(x)%width])
32#define MOVE1(x,y) (fill[((y)%height)*width+(x)%width]=1, XDrawPoint(dpy, window, draw_gc, (x)%width,(y)%height), cov++)
33
34static int cov;
35static int dirh[4];
36static int dirv[4];
37
38static int *fill;
39
40#define CLEARDXY(x,y,dx,dy) CLEAR1(x+dx, y+dy) && CLEAR1(x+dx+dx, y+dy+dy)
41#define MOVEDXY(x,y,dx,dy)  MOVE1 (x+dx, y+dy), MOVE1 (x+dx+dx, y+dy+dy)
42
43#define CLEAR(d) CLEARDXY(w->h,w->v, dirh[d],dirv[d])
44#define MOVE(d) (XSetForeground(dpy, draw_gc, colors[w->c].pixel), \
45                  MOVEDXY(w->h,w->v, dirh[d],dirv[d]), \
46                  w->h=w->h+dirh[d]*2, \
47                  w->v=w->v+dirv[d]*2, dir=d)
48
49#define RANDOM (void) (w->h = R(width), w->v = R(height), w->c = R(ncolors), \
50                  type=R(2), dir=R(4), (cycle && (w->cc=R(3)+ncolors)))
51
52struct worm {
53    int h;
54    int v;
55    int s;
56    int c;
57    int cc;
58} *worms;
59
60#define SUCC(x) ((x+1)%4)
61#define PRED(x) ((x+3)%4)
62#define CCW     PRED(dir)
63#define CW      SUCC(dir)
64#define REV     ((dir+2)%4)
65#define STR     (dir)
66#define TRY(x)  if (CLEAR(x)) { MOVE(x); break; }
67
68static void
69do_worm(Display *dpy, Window window, struct worm *w)
70{
71    int type = w->s / 4;
72    int dir = w->s % 4;
73
74    w->c = (w->c+w->cc) % ncolors;
75
76    if (PROB(disorder)) type=PROB(handedness);
77    switch(type) {
78    case 0: /* CCW */
79        TRY(CCW)
80        TRY(STR)
81        TRY(CW)
82        RANDOM;
83        break;
84    case 1: /* CW */
85        TRY(CW)
86        TRY(STR)
87        TRY(CCW)
88        RANDOM;
89        break;
90    }
91    w->s = type*4+dir;
92    w->h = w->h % width;
93    w->v = w->v % height;
94}
95
96static void
97init_squiral(Display *dpy, Window window)
98{
99    XGCValues gcv;
100    Colormap cmap;
101    XWindowAttributes xgwa;
102    Bool writeable = False;
103    int i;
104
105    XClearWindow(dpy, window);
106    XGetWindowAttributes(dpy, window, &xgwa);
107    width  = xgwa.width;
108    height = xgwa.height;
109
110    cmap = xgwa.colormap;
111    gcv.foreground = get_pixel_resource("foreground",
112        "Foreground", dpy, cmap);
113    draw_gc = XCreateGC(dpy, window, GCForeground, &gcv);
114    gcv.foreground = get_pixel_resource ("background", "Background",dpy, cmap);
115    erase_gc = XCreateGC (dpy, window, GCForeground, &gcv);
116    cmap = xgwa.colormap;
117    if( ncolors ) {
118        free_colors(dpy, cmap, colors, ncolors);
119        ncolors = 0;
120    }
121    if( mono_p ) {
122      ncolors=1;
123      colors[0].pixel=get_pixel_resource("foreground","Foreground", dpy, cmap);
124    } else {
125      ncolors = get_integer_resource("ncolors", "Integer");
126      if (ncolors < 0 || ncolors > NCOLORSMAX)
127        ncolors = NCOLORSMAX;
128      make_uniform_colormap(dpy, xgwa.visual, cmap, colors, &ncolors, True,
129          &writeable, False);
130      if (ncolors <= 0) {
131        ncolors = 1;
132        colors[0].pixel=get_pixel_resource("foreground","Foreground",dpy, cmap);
133      }
134    }
135    count= get_integer_resource("count", "Integer");
136    frac = get_integer_resource("fill",  "Integer")*0.01;
137    cycle= get_boolean_resource("cycle", "Cycle");
138    disorder=get_float_resource("disorder", "Float");
139    handedness=get_float_resource("handedness", "Float");
140
141    if(frac<0.01) frac=0.01;
142    if(frac>0.99) frac=0.99;
143    if(count==0) count=width/32;
144    if(count<1) count=1;
145    if(count>1000) count=1000;
146
147    if(worms) free(worms);
148    if(fill)  free(fill);
149
150    worms=calloc(count, sizeof(struct worm));
151    fill=calloc(width*height, sizeof(int));
152
153    dirh[0]=0; dirh[1]=1; dirh[2]=0; dirh[3]=width-1;
154    dirv[0]=height-1; dirv[1]=0; dirv[2]=1; dirv[3]=0;
155    for(i=0;i<count;i++) {
156        worms[i].h=R(width);
157        worms[i].v=R(height);
158        worms[i].s=R(4)+4*PROB(handedness);
159        worms[i].c=R(ncolors);
160        if(cycle) { worms[i].cc=R(3)+ncolors; }
161        else worms[i].cc=0;
162    }
163}
164
165void
166screenhack(Display *dpy, Window window)
167{
168   int inclear, i;
169   int delay= get_integer_resource("delay", "Integer");
170   init_squiral(dpy, window);
171   cov=0; inclear=height;
172   while(1) {
173        if(inclear<height) {
174            XDrawLine(dpy, window, erase_gc, 0, inclear, width-1, inclear);
175            memset(&fill[inclear*width], 0, sizeof(int)*width);
176            XDrawLine(dpy, window, erase_gc, 0, height-inclear-1, width-1,
177                    height-inclear-1);
178            memset(&fill[(height-inclear-1)*width], 0, sizeof(int)*width);
179            inclear++;
180            XDrawLine(dpy, window, erase_gc, 0, inclear, width-1, inclear);
181            memset(&fill[inclear*width], 0, sizeof(int)*width);
182            XDrawLine(dpy, window, erase_gc, 0, height-inclear-1, width-1,
183                    height-inclear-1);
184            memset(&fill[(height-inclear-1)*width], 0, sizeof(int)*width);
185            inclear++;
186            if(inclear>height/2) inclear=height;
187        }
188        else if(cov>(frac*width*height)) {
189            inclear=0;
190            cov=0;
191        }
192        for(i=0;i<count;i++) do_worm(dpy, window, &worms[i]);
193        screenhack_handle_events(dpy);
194        usleep(delay);
195    }   
196}
197
198char *progclass="Squiral";
199
200char *defaults[] = {
201  ".background: black",
202  ".foreground: white",
203  "*fill:       75",
204  "*count:      0",
205  "*ncolors:    100",
206  "*delay:      1000",
207  "*disorder:   0.005",
208  "*cycle:      False",
209  "*handedness: .5",
210  0
211};
212
213XrmOptionDescRec options[] = {
214    {"-fill", ".fill", XrmoptionSepArg, 0},
215    {"-count", ".count", XrmoptionSepArg, 0},
216    {"-delay", ".delay", XrmoptionSepArg, 0},
217    {"-disorder", ".disorder", XrmoptionSepArg, 0},
218    {"-handedness", ".handedness", XrmoptionSepArg, 0},
219    {"-ncolors", ".ncolors", XrmoptionSepArg, 0},
220    {"-cycle", ".cycle", XrmoptionNoArg, "True"},
221    {"-no-cycle", ".cycle", XrmoptionNoArg, "False"},
222    { 0, 0, 0, 0 }
223};
Note: See TracBrowser for help on using the repository browser.