instant: partially revert commit bc96e6f1ff6c72d4d2cafb6a4088ffa32cd3019f. remove...
[oweals/cde.git] / cde / programs / dtscreen / swarm.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: swarm.c /main/3 1995/11/02 16:08:42 rswiston $ */
24 /*
25  */
26 /*                                                                      *
27  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
28  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
29  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
30  * (c) Copyright 1993, 1994 Novell, Inc.                                *
31  */
32 /*-
33  * swarm.c - swarm of bees for dtscreen, the X Window System lockscreen.
34  *
35  * Copyright (c) 1991 by Patrick J. Naughton.
36  *
37  * Revision History:
38  * 31-Aug-90: Adapted from xswarm by Jeff Butterworth. (butterwo@ncsc.org)
39  */
40
41 #include "dtscreen.h"
42
43 #define TIMES   4               /* number of time positions recorded */
44 #define BEEACC  3               /* acceleration of bees */
45 #define WASPACC 5               /* maximum acceleration of wasp */
46 #define BEEVEL  11              /* maximum bee velocity */
47 #define WASPVEL 12              /* maximum wasp velocity */
48 #define BORDER  50              /* wasp won't go closer than this to the edge */
49
50 /* Macros */
51 #define X(t,b)  (sp->x[(t)*sp->beecount+(b)])
52 #define Y(t,b)  (sp->y[(t)*sp->beecount+(b)])
53 #define RAND(v) ((random()%(v))-((v)/2))        /* random number around 0 */
54
55 typedef struct {
56     int         pix;
57     long        startTime;
58     int         width;
59     int         height;
60     int         beecount;       /* number of bees */
61     XSegment   *segs;           /* bee lines */
62     XSegment   *old_segs;       /* old bee lines */
63     short      *x;
64     short      *y;              /* bee positions x[time][bee#] */
65     short      *xv;
66     short      *yv;             /* bee velocities xv[bee#] */
67     short       wx[3];
68     short       wy[3];
69     short       wxv;
70     short       wyv;
71 }           swarmstruct;
72
73 void
74 initswarm(pwin)
75     perwindow *pwin;
76 {
77     XWindowAttributes xgwa;
78     swarmstruct *sp;
79     int         b;
80
81     if (pwin->data) free(pwin->data);
82     pwin->data = (void *)malloc(sizeof(swarmstruct));
83     memset(pwin->data, '\0', sizeof(swarmstruct));
84     sp = (swarmstruct *)pwin->data;
85     sp->startTime = seconds();
86     sp->beecount = batchcount;
87
88     XGetWindowAttributes(dsp, pwin->w, &xgwa);
89     sp->width = xgwa.width;
90     sp->height = xgwa.height;
91
92     /* Clear the background. */
93     XSetForeground(dsp, pwin->gc, BlackPixelOfScreen(pwin->perscreen->screen));
94     XFillRectangle(dsp, pwin->w, pwin->gc, 0, 0, sp->width, sp->height);
95
96     /* Allocate memory. */
97
98     sp->segs = (XSegment *) malloc(sizeof(XSegment) * sp->beecount);
99     sp->old_segs = (XSegment *) malloc(sizeof(XSegment) * sp->beecount);
100     sp->x = (short *) malloc(sizeof(short) * sp->beecount * TIMES);
101     sp->y = (short *) malloc(sizeof(short) * sp->beecount * TIMES);
102     sp->xv = (short *) malloc(sizeof(short) * sp->beecount);
103     sp->yv = (short *) malloc(sizeof(short) * sp->beecount);
104
105     /* Initialize point positions, velocities, etc. */
106
107     /* wasp */
108     sp->wx[0] = BORDER + random() % (sp->width - 2 * BORDER);
109     sp->wy[0] = BORDER + random() % (sp->height - 2 * BORDER);
110     sp->wx[1] = sp->wx[0];
111     sp->wy[1] = sp->wy[0];
112     sp->wxv = 0;
113     sp->wyv = 0;
114
115     /* bees */
116     for (b = 0; b < sp->beecount; b++) {
117         X(0, b) = random() % sp->width;
118         X(1, b) = X(0, b);
119         Y(0, b) = random() % sp->height;
120         Y(1, b) = Y(0, b);
121         sp->xv[b] = RAND(7);
122         sp->yv[b] = RAND(7);
123     }
124 }
125
126
127
128 void
129 drawswarm(pwin)
130     perwindow *pwin;
131 {
132     swarmstruct *sp;
133     int         b;
134
135     sp = (swarmstruct *)pwin->data;
136     /* <=- Wasp -=> */
137     /* Age the arrays. */
138     sp->wx[2] = sp->wx[1];
139     sp->wx[1] = sp->wx[0];
140     sp->wy[2] = sp->wy[1];
141     sp->wy[1] = sp->wy[0];
142     /* Accelerate */
143     sp->wxv += RAND(WASPACC);
144     sp->wyv += RAND(WASPACC);
145
146     /* Speed Limit Checks */
147     if (sp->wxv > WASPVEL)
148         sp->wxv = WASPVEL;
149     if (sp->wxv < -WASPVEL)
150         sp->wxv = -WASPVEL;
151     if (sp->wyv > WASPVEL)
152         sp->wyv = WASPVEL;
153     if (sp->wyv < -WASPVEL)
154         sp->wyv = -WASPVEL;
155
156     /* Move */
157     sp->wx[0] = sp->wx[1] + sp->wxv;
158     sp->wy[0] = sp->wy[1] + sp->wyv;
159
160     /* Bounce Checks */
161     if ((sp->wx[0] < BORDER) || (sp->wx[0] > sp->width - BORDER - 1)) {
162         sp->wxv = -sp->wxv;
163         sp->wx[0] += sp->wxv;
164     }
165     if ((sp->wy[0] < BORDER) || (sp->wy[0] > sp->height - BORDER - 1)) {
166         sp->wyv = -sp->wyv;
167         sp->wy[0] += sp->wyv;
168     }
169     /* Don't let things settle down. */
170     sp->xv[random() % sp->beecount] += RAND(3);
171     sp->yv[random() % sp->beecount] += RAND(3);
172
173     /* <=- Bees -=> */
174     for (b = 0; b < sp->beecount; b++) {
175         int         distance,
176                     dx,
177                     dy;
178         /* Age the arrays. */
179         X(2, b) = X(1, b);
180         X(1, b) = X(0, b);
181         Y(2, b) = Y(1, b);
182         Y(1, b) = Y(0, b);
183
184         /* Accelerate */
185         dx = sp->wx[1] - X(1, b);
186         dy = sp->wy[1] - Y(1, b);
187         distance = abs(dx) + abs(dy);   /* approximation */
188         if (distance == 0)
189             distance = 1;
190         sp->xv[b] += (dx * BEEACC) / distance;
191         sp->yv[b] += (dy * BEEACC) / distance;
192
193         /* Speed Limit Checks */
194         if (sp->xv[b] > BEEVEL)
195             sp->xv[b] = BEEVEL;
196         if (sp->xv[b] < -BEEVEL)
197             sp->xv[b] = -BEEVEL;
198         if (sp->yv[b] > BEEVEL)
199             sp->yv[b] = BEEVEL;
200         if (sp->yv[b] < -BEEVEL)
201             sp->yv[b] = -BEEVEL;
202
203         /* Move */
204         X(0, b) = X(1, b) + sp->xv[b];
205         Y(0, b) = Y(1, b) + sp->yv[b];
206
207         /* Fill the segment lists. */
208         sp->segs[b].x1 = X(0, b);
209         sp->segs[b].y1 = Y(0, b);
210         sp->segs[b].x2 = X(1, b);
211         sp->segs[b].y2 = Y(1, b);
212         sp->old_segs[b].x1 = X(1, b);
213         sp->old_segs[b].y1 = Y(1, b);
214         sp->old_segs[b].x2 = X(2, b);
215         sp->old_segs[b].y2 = Y(2, b);
216     }
217
218     XSetForeground(dsp, pwin->gc, BlackPixelOfScreen(pwin->perscreen->screen));
219     XDrawLine(dsp, pwin->w, pwin->gc,
220               sp->wx[1], sp->wy[1], sp->wx[2], sp->wy[2]);
221     XDrawSegments(dsp, pwin->w, pwin->gc, sp->old_segs, sp->beecount);
222
223     XSetForeground(dsp, pwin->gc, WhitePixelOfScreen(pwin->perscreen->screen));
224     XDrawLine(dsp, pwin->w, pwin->gc,
225               sp->wx[0], sp->wy[0], sp->wx[1], sp->wy[1]);
226     if (!mono && pwin->perscreen->npixels > 2) {
227         XSetForeground(dsp, pwin->gc, pwin->perscreen->pixels[sp->pix]);
228         if (++sp->pix >= pwin->perscreen->npixels)
229             sp->pix = 0;
230     }
231     XDrawSegments(dsp, pwin->w, pwin->gc, sp->segs, sp->beecount);
232 }