1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1 |
/* -*- Mode: C; tab-width: 4 -*- */
|
2 |
/* thornbird --- continuously varying Thornbird set */
|
|
3 |
||
4 |
#if 0
|
|
5 |
static const char sccsid[] = "@(#)thornbird.c 5.00 2000/11/01 xlockmore";
|
|
6 |
#endif
|
|
7 |
||
8 |
/*-
|
|
1.1.2
by Adam Conrad
Import upstream version 4.23 |
9 |
* Copyright (c) 1996 by Tim Auckland <tda10.geo@yahoo.com>
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
10 |
*
|
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.
|
|
16 |
*
|
|
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.
|
|
22 |
*
|
|
23 |
* "thornbird" shows a view of the "Bird in a Thornbush" fractal,
|
|
24 |
* continuously varying the three free parameters.
|
|
25 |
*
|
|
26 |
* Revision History:
|
|
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
|
|
30 |
*/
|
|
31 |
||
32 |
#ifdef STANDALONE
|
|
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
33 |
# define MODE_thornbird
|
34 |
#define DEFAULTS "*delay: 10000 \n" \
|
|
35 |
"*count: 100 \n" \
|
|
36 |
"*cycles: 400 \n" \
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
37 |
"*ncolors: 64 \n" \
|
38 |
"*fpsSolid: true \n" \
|
|
39 |
||
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
40 |
# define BRIGHT_COLORS
|
41 |
# define reshape_thornbird 0
|
|
42 |
# define thornbird_handle_event 0
|
|
43 |
# include "xlockmore.h" /* in xscreensaver distribution */ |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
44 |
#else /* STANDALONE */ |
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
45 |
# include "xlock.h" /* in xlockmore distribution */ |
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
46 |
#endif /* STANDALONE */ |
47 |
||
48 |
#ifdef MODE_thornbird
|
|
49 |
||
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
50 |
ENTRYPOINT ModeSpecOpt thornbird_opts = |
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
51 |
{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; |
52 |
||
53 |
#ifdef USE_MODULES
|
|
54 |
ModStruct thornbird_description = |
|
55 |
{"thornbird", "init_thornbird", "draw_thornbird", "release_thornbird", |
|
56 |
"refresh_thornbird", "init_thornbird", (char *) NULL, þbird_opts, |
|
57 |
1000, 800, 16, 1, 64, 1.0, "", |
|
58 |
"Shows an animated Bird in a Thorn Bush fractal map", 0, NULL}; |
|
59 |
||
60 |
#endif
|
|
61 |
||
62 |
#define balance_rand(v) ((LRAND()/MAXRAND*(v))-((v)/2)) /* random around 0 */ |
|
63 |
||
64 |
typedef struct { |
|
65 |
int maxx; |
|
66 |
int maxy; /* max of the screen */ |
|
67 |
double a; |
|
68 |
double b; |
|
69 |
double c; |
|
70 |
double d; |
|
71 |
double e; |
|
72 |
double i; |
|
73 |
double j; /* thornbird parameters */ |
|
74 |
struct { |
|
75 |
double f1; |
|
76 |
double f2; |
|
77 |
} liss; |
|
78 |
struct { |
|
79 |
double theta; |
|
80 |
double dtheta; |
|
81 |
double phi; |
|
82 |
double dphi; |
|
83 |
} tumble; |
|
84 |
int inc; |
|
85 |
int pix; |
|
86 |
int count; |
|
87 |
int nbuffers; |
|
88 |
XPoint **pointBuffer; /* pointer for XDrawPoints */ |
|
89 |
} thornbirdstruct; |
|
90 |
||
91 |
static thornbirdstruct *thornbirds = (thornbirdstruct *) NULL; |
|
92 |
||
93 |
static void |
|
94 |
free_thornbird(thornbirdstruct *hp) |
|
95 |
{
|
|
96 |
if (hp->pointBuffer != NULL) { |
|
97 |
int buffer; |
|
98 |
||
99 |
for (buffer = 0; buffer < hp->nbuffers; buffer++) |
|
100 |
if (hp->pointBuffer[buffer] != NULL) |
|
101 |
(void) free((void *) hp->pointBuffer[buffer]); |
|
102 |
(void) free((void *) hp->pointBuffer); |
|
103 |
hp->pointBuffer = (XPoint **) NULL; |
|
104 |
}
|
|
105 |
}
|
|
106 |
||
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
107 |
ENTRYPOINT void |
108 |
init_thornbird (ModeInfo * mi) |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
109 |
{
|
110 |
thornbirdstruct *hp; |
|
111 |
||
112 |
if (thornbirds == NULL) { |
|
113 |
if ((thornbirds = |
|
114 |
(thornbirdstruct *) calloc(MI_NUM_SCREENS(mi), |
|
115 |
sizeof (thornbirdstruct))) == NULL) |
|
116 |
return; |
|
117 |
}
|
|
118 |
hp = þbirds[MI_SCREEN(mi)]; |
|
119 |
||
120 |
||
121 |
hp->maxx = MI_WIDTH(mi); |
|
122 |
hp->maxy = MI_HEIGHT(mi); |
|
123 |
||
124 |
hp->b = 0.1; |
|
125 |
hp->i = hp->j = 0.1; |
|
126 |
||
127 |
hp->pix = 0; |
|
128 |
hp->inc = 0; |
|
129 |
||
130 |
hp->nbuffers = MI_CYCLES(mi); |
|
131 |
||
132 |
if (hp->pointBuffer == NULL) |
|
133 |
if ((hp->pointBuffer = (XPoint **) calloc(MI_CYCLES(mi), |
|
134 |
sizeof (XPoint *))) == NULL) { |
|
135 |
free_thornbird(hp); |
|
136 |
return; |
|
137 |
}
|
|
138 |
||
139 |
if (hp->pointBuffer[0] == NULL) |
|
140 |
if ((hp->pointBuffer[0] = (XPoint *) malloc(MI_COUNT(mi) * |
|
141 |
sizeof (XPoint))) == NULL) { |
|
142 |
free_thornbird(hp); |
|
143 |
return; |
|
144 |
}
|
|
145 |
||
146 |
/* select frequencies for parameter variation */
|
|
147 |
hp->liss.f1 = LRAND() % 5000; |
|
148 |
hp->liss.f2 = LRAND() % 2000; |
|
149 |
||
150 |
/* choose random 3D tumbling */
|
|
151 |
hp->tumble.theta = 0; |
|
152 |
hp->tumble.phi = 0; |
|
153 |
hp->tumble.dtheta = balance_rand(0.001); |
|
154 |
hp->tumble.dphi = balance_rand(0.005); |
|
155 |
||
156 |
/* Clear the background. */
|
|
157 |
MI_CLEARWINDOW(mi); |
|
158 |
||
159 |
hp->count = 0; |
|
160 |
}
|
|
161 |
||
162 |
||
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
163 |
ENTRYPOINT void |
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
164 |
draw_thornbird(ModeInfo * mi) |
165 |
{
|
|
166 |
Display *dsp = MI_DISPLAY(mi); |
|
167 |
Window win = MI_WINDOW(mi); |
|
168 |
double oldj, oldi; |
|
169 |
int batchcount = MI_COUNT(mi); |
|
170 |
int k; |
|
171 |
XPoint *xp; |
|
172 |
GC gc = MI_GC(mi); |
|
173 |
int erase; |
|
174 |
int current; |
|
175 |
||
176 |
double sint, cost, sinp, cosp; |
|
177 |
thornbirdstruct *hp; |
|
178 |
||
179 |
if (thornbirds == NULL) |
|
180 |
return; |
|
181 |
hp = þbirds[MI_SCREEN(mi)]; |
|
182 |
if (hp->pointBuffer == NULL) |
|
183 |
return; |
|
184 |
||
185 |
erase = (hp->inc + 1) % MI_CYCLES(mi); |
|
186 |
current = hp->inc % MI_CYCLES(mi); |
|
187 |
k = batchcount; |
|
188 |
||
189 |
||
190 |
xp = hp->pointBuffer[current]; |
|
191 |
||
192 |
/* vary papameters */
|
|
193 |
hp->a = 1.99 + (0.4 * sin(hp->inc / hp->liss.f1) + |
|
194 |
0.05 * cos(hp->inc / hp->liss.f2)); |
|
195 |
hp->c = 0.80 + (0.15 * cos(hp->inc / hp->liss.f1) + |
|
196 |
0.05 * sin(hp->inc / hp->liss.f2)); |
|
197 |
||
198 |
/* vary view */
|
|
199 |
hp->tumble.theta += hp->tumble.dtheta; |
|
200 |
hp->tumble.phi += hp->tumble.dphi; |
|
201 |
sint = sin(hp->tumble.theta); |
|
202 |
cost = cos(hp->tumble.theta); |
|
203 |
sinp = sin(hp->tumble.phi); |
|
204 |
cosp = cos(hp->tumble.phi); |
|
205 |
||
206 |
while (k--) { |
|
207 |
oldj = hp->j; |
|
208 |
oldi = hp->i; |
|
209 |
||
210 |
hp->j = oldi; |
|
211 |
hp->i = (1 - hp->c) * cos(M_PI * hp->a * oldj) + hp->c * hp->b; |
|
212 |
hp->b = oldj; |
|
213 |
||
214 |
xp->x = (short) |
|
215 |
(hp->maxx / 2 * (1 |
|
216 |
+ sint*hp->j + cost*cosp*hp->i - cost*sinp*hp->b)); |
|
217 |
xp->y = (short) |
|
218 |
(hp->maxy / 2 * (1 |
|
219 |
- cost*hp->j + sint*cosp*hp->i - sint*sinp*hp->b)); |
|
220 |
xp++; |
|
221 |
}
|
|
222 |
||
223 |
MI_IS_DRAWN(mi) = True; |
|
224 |
||
225 |
if (hp->pointBuffer[erase] == NULL) { |
|
226 |
if ((hp->pointBuffer[erase] = (XPoint *) malloc(MI_COUNT(mi) * |
|
227 |
sizeof (XPoint))) == NULL) { |
|
228 |
free_thornbird(hp); |
|
229 |
return; |
|
230 |
}
|
|
231 |
} else { |
|
232 |
XSetForeground(dsp, gc, MI_BLACK_PIXEL(mi)); |
|
233 |
XDrawPoints(dsp, win, gc, hp->pointBuffer[erase], |
|
234 |
batchcount, CoordModeOrigin); |
|
235 |
}
|
|
236 |
if (MI_NPIXELS(mi) > 2) { |
|
237 |
XSetForeground(dsp, gc, MI_PIXEL(mi, hp->pix)); |
|
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
238 |
#if 0
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
239 |
if (erase == 0) /* change colours after "cycles" cycles */
|
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
240 |
#else
|
241 |
if (!((hp->inc + 1) % (1 + (MI_CYCLES(mi) / 3)))) /* jwz: sooner */ |
|
242 |
#endif
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
243 |
if (++hp->pix >= MI_NPIXELS(mi)) |
244 |
hp->pix = 0; |
|
245 |
} else |
|
246 |
XSetForeground(dsp, gc, MI_WHITE_PIXEL(mi)); |
|
247 |
||
248 |
XDrawPoints(dsp, win, gc, hp->pointBuffer[current], |
|
249 |
batchcount, CoordModeOrigin); |
|
250 |
hp->inc++; |
|
251 |
||
252 |
}
|
|
253 |
||
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
254 |
ENTRYPOINT void |
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
255 |
release_thornbird(ModeInfo * mi) |
256 |
{
|
|
257 |
if (thornbirds != NULL) { |
|
258 |
int screen; |
|
259 |
||
260 |
for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) |
|
261 |
free_thornbird(þbirds[screen]); |
|
262 |
(void) free((void *) thornbirds); |
|
263 |
thornbirds = (thornbirdstruct *) NULL; |
|
264 |
}
|
|
265 |
}
|
|
266 |
||
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
267 |
ENTRYPOINT void |
268 |
refresh_thornbird (ModeInfo * mi) |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
269 |
{
|
270 |
MI_CLEARWINDOW(mi); |
|
271 |
}
|
|
272 |
||
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
273 |
|
274 |
XSCREENSAVER_MODULE ("Thornbird", thornbird) |
|
275 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
276 |
#endif /* MODE_thornbird */ |