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

Revision 20148, 6.5 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/* -*- Mode: C; tab-width: 4 -*- */
2/* thornbird --- continuously varying Thornbird set */
3
4#if 0
5static const char sccsid[] = "@(#)thornbird.c   5.00 2000/11/01 xlockmore";
6#endif
7
8/*-
9 * Copyright (c) 1996 by Tim Auckland <Tim.Auckland@Procket.com>
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
33#define MODE_thornbird
34#define PROGCLASS "Thornbird"
35#define HACK_INIT init_thornbird
36#define HACK_DRAW draw_thornbird
37#define thornbird_opts xlockmore_opts
38#define DEFAULTS "*delay: 10000 \n" \
39 "*count: 800 \n" \
40 "*cycles: 16 \n" \
41 "*ncolors: 64 \n"
42#define SMOOTH_COLORS
43#include "xlockmore.h"          /* in xscreensaver distribution */
44#else /* STANDALONE */
45#include "xlock.h"              /* in xlockmore distribution */
46#endif /* STANDALONE */
47
48#ifdef MODE_thornbird
49
50ModeSpecOpt thornbird_opts =
51{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
52
53#ifdef USE_MODULES
54ModStruct   thornbird_description =
55{"thornbird", "init_thornbird", "draw_thornbird", "release_thornbird",
56 "refresh_thornbird", "init_thornbird", (char *) NULL, &thornbird_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
64typedef 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
91static thornbirdstruct *thornbirds = (thornbirdstruct *) NULL;
92
93static void
94free_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
107void
108init_thornbird(ModeInfo * mi)
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 = &thornbirds[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
163void
164draw_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 = &thornbirds[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));
238                if (erase == 0) /* change colours after "cycles" cycles */
239                        if (++hp->pix >= MI_NPIXELS(mi))
240                                hp->pix = 0;
241        } else
242                XSetForeground(dsp, gc, MI_WHITE_PIXEL(mi));
243
244        XDrawPoints(dsp, win, gc, hp->pointBuffer[current],
245                    batchcount, CoordModeOrigin);
246        hp->inc++;
247
248}
249
250void
251release_thornbird(ModeInfo * mi)
252{
253        if (thornbirds != NULL) {
254                int         screen;
255
256                for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
257                        free_thornbird(&thornbirds[screen]);
258                (void) free((void *) thornbirds);
259                thornbirds = (thornbirdstruct *) NULL;
260        }
261}
262
263void
264refresh_thornbird(ModeInfo * mi)
265{
266        MI_CLEARWINDOW(mi);
267}
268
269#endif /* MODE_thornbird */
Note: See TracBrowser for help on using the repository browser.