1 /* -*- Mode: C; tab-width: 4 -*- */
2 /* thornbird --- continuously varying Thornbird set */
5 static const char sccsid[] = "@(#)thornbird.c 5.00 2000/11/01 xlockmore";
9 * Copyright (c) 1996 by Tim Auckland <tda10.geo@yahoo.com>
11 * Permission to use, copy, modify, and distribute this software and its
12 * documentation for any purpose and without fee is hereby granted,
13 * provided that the above copyright notice appear in all copies and that
14 * both that copyright notice and this permission notice appear in
15 * supporting documentation.
17 * This file is provided AS IS with no warranties of any kind. The author
18 * shall have no liability with respect to the infringement of copyrights,
19 * trade secrets or any patents by this file or any part thereof. In no
20 * event will the author be liable for any lost revenue or profits or
21 * other special, indirect and consequential damages.
23 * "thornbird" shows a view of the "Bird in a Thornbush" fractal,
24 * continuously varying the three free parameters.
27 * 01-Nov-2000: Allocation checks
28 * 04-Jun-1999: 3D tumble added by Tim Auckland
29 * 31-Jul-1997: Adapted from discrete.c Copyright (c) 1996 by Tim Auckland
33 # define MODE_thornbird
34 #define DEFAULTS "*delay: 10000 \n" \
38 "*fpsSolid: true \n" \
40 # define BRIGHT_COLORS
41 # define thornbird_handle_event 0
42 # include "xlockmore.h" /* in xscreensaver distribution */
43 #else /* STANDALONE */
44 # include "xlock.h" /* in xlockmore distribution */
45 #endif /* STANDALONE */
49 ENTRYPOINT ModeSpecOpt thornbird_opts =
50 {0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
53 ModStruct thornbird_description =
54 {"thornbird", "init_thornbird", "draw_thornbird", "release_thornbird",
55 "refresh_thornbird", "init_thornbird", (char *) NULL, þbird_opts,
56 1000, 800, 16, 1, 64, 1.0, "",
57 "Shows an animated Bird in a Thorn Bush fractal map", 0, NULL};
61 #define balance_rand(v) ((LRAND()/MAXRAND*(v))-((v)/2)) /* random around 0 */
65 int maxy; /* max of the screen */
72 double j; /* thornbird parameters */
87 XPoint **pointBuffer; /* pointer for XDrawPoints */
90 static thornbirdstruct *thornbirds = (thornbirdstruct *) NULL;
93 free_thornbird(thornbirdstruct *hp)
95 if (hp->pointBuffer != NULL) {
98 for (buffer = 0; buffer < hp->nbuffers; buffer++)
99 if (hp->pointBuffer[buffer] != NULL)
100 (void) free((void *) hp->pointBuffer[buffer]);
101 (void) free((void *) hp->pointBuffer);
102 hp->pointBuffer = (XPoint **) NULL;
107 init_thornbird (ModeInfo * mi)
111 if (thornbirds == NULL) {
113 (thornbirdstruct *) calloc(MI_NUM_SCREENS(mi),
114 sizeof (thornbirdstruct))) == NULL)
117 hp = þbirds[MI_SCREEN(mi)];
120 hp->maxx = MI_WIDTH(mi);
121 hp->maxy = MI_HEIGHT(mi);
129 hp->nbuffers = MI_CYCLES(mi);
131 if (hp->pointBuffer == NULL)
132 if ((hp->pointBuffer = (XPoint **) calloc(MI_CYCLES(mi),
133 sizeof (XPoint *))) == NULL) {
138 if (hp->pointBuffer[0] == NULL)
139 if ((hp->pointBuffer[0] = (XPoint *) malloc(MI_COUNT(mi) *
140 sizeof (XPoint))) == NULL) {
145 /* select frequencies for parameter variation */
146 hp->liss.f1 = LRAND() % 5000;
147 hp->liss.f2 = LRAND() % 2000;
149 /* choose random 3D tumbling */
150 hp->tumble.theta = 0;
152 hp->tumble.dtheta = balance_rand(0.001);
153 hp->tumble.dphi = balance_rand(0.005);
155 /* Clear the background. */
163 draw_thornbird(ModeInfo * mi)
165 Display *dsp = MI_DISPLAY(mi);
166 Window win = MI_WINDOW(mi);
168 int batchcount = MI_COUNT(mi);
175 double sint, cost, sinp, cosp;
178 if (thornbirds == NULL)
180 hp = þbirds[MI_SCREEN(mi)];
181 if (hp->pointBuffer == NULL)
184 erase = (hp->inc + 1) % MI_CYCLES(mi);
185 current = hp->inc % MI_CYCLES(mi);
189 xp = hp->pointBuffer[current];
191 /* vary papameters */
192 hp->a = 1.99 + (0.4 * sin(hp->inc / hp->liss.f1) +
193 0.05 * cos(hp->inc / hp->liss.f2));
194 hp->c = 0.80 + (0.15 * cos(hp->inc / hp->liss.f1) +
195 0.05 * sin(hp->inc / hp->liss.f2));
198 hp->tumble.theta += hp->tumble.dtheta;
199 hp->tumble.phi += hp->tumble.dphi;
200 sint = sin(hp->tumble.theta);
201 cost = cos(hp->tumble.theta);
202 sinp = sin(hp->tumble.phi);
203 cosp = cos(hp->tumble.phi);
210 hp->i = (1 - hp->c) * cos(M_PI * hp->a * oldj) + hp->c * hp->b;
215 + sint*hp->j + cost*cosp*hp->i - cost*sinp*hp->b));
218 - cost*hp->j + sint*cosp*hp->i - sint*sinp*hp->b));
222 MI_IS_DRAWN(mi) = True;
224 if (hp->pointBuffer[erase] == NULL) {
225 if ((hp->pointBuffer[erase] = (XPoint *) malloc(MI_COUNT(mi) *
226 sizeof (XPoint))) == NULL) {
231 XSetForeground(dsp, gc, MI_BLACK_PIXEL(mi));
232 XDrawPoints(dsp, win, gc, hp->pointBuffer[erase],
233 batchcount, CoordModeOrigin);
235 if (MI_NPIXELS(mi) > 2) {
236 XSetForeground(dsp, gc, MI_PIXEL(mi, hp->pix));
238 if (erase == 0) /* change colours after "cycles" cycles */
240 if (!((hp->inc + 1) % (1 + (MI_CYCLES(mi) / 3)))) /* jwz: sooner */
242 if (++hp->pix >= MI_NPIXELS(mi))
245 XSetForeground(dsp, gc, MI_WHITE_PIXEL(mi));
247 XDrawPoints(dsp, win, gc, hp->pointBuffer[current],
248 batchcount, CoordModeOrigin);
253 reshape_thornbird(ModeInfo * mi, int width, int height)
255 XClearWindow (MI_DISPLAY (mi), MI_WINDOW(mi));
260 release_thornbird(ModeInfo * mi)
262 if (thornbirds != NULL) {
265 for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
266 free_thornbird(þbirds[screen]);
267 (void) free((void *) thornbirds);
268 thornbirds = (thornbirdstruct *) NULL;
273 refresh_thornbird (ModeInfo * mi)
279 XSCREENSAVER_MODULE ("Thornbird", thornbird)
281 #endif /* MODE_thornbird */