Fix dttypes for BSD systems
[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 <stdlib.h>
42 #include "dtscreen.h"
43
44 #define TIMES   4               /* number of time positions recorded */
45 #define BEEACC  3               /* acceleration of bees */
46 #define WASPACC 5               /* maximum acceleration of wasp */
47 #define BEEVEL  11              /* maximum bee velocity */
48 #define WASPVEL 12              /* maximum wasp velocity */
49 #define BORDER  50              /* wasp won't go closer than this to the edge */
50
51 /* Macros */
52 #define X(t,b)  (sp->x[(t)*sp->beecount+(b)])
53 #define Y(t,b)  (sp->y[(t)*sp->beecount+(b)])
54 #define RAND(v) ((random()%(v))-((v)/2))        /* random number around 0 */
55
56 typedef struct {
57     int         pix;
58     long        startTime;
59     int         width;
60     int         height;
61     int         beecount;       /* number of bees */
62     XSegment   *segs;           /* bee lines */
63     XSegment   *old_segs;       /* old bee lines */
64     short      *x;
65     short      *y;              /* bee positions x[time][bee#] */
66     short      *xv;
67     short      *yv;             /* bee velocities xv[bee#] */
68     short       wx[3];
69     short       wy[3];
70     short       wxv;
71     short       wyv;
72 }           swarmstruct;
73
74 void
75 initswarm(pwin)
76     perwindow *pwin;
77 {
78     XWindowAttributes xgwa;
79     swarmstruct *sp;
80     int         b;
81
82     if (pwin->data) free(pwin->data);
83     pwin->data = (void *)malloc(sizeof(swarmstruct));
84     memset(pwin->data, '\0', sizeof(swarmstruct));
85     sp = (swarmstruct *)pwin->data;
86     sp->startTime = seconds();
87     sp->beecount = batchcount;
88
89     XGetWindowAttributes(dsp, pwin->w, &xgwa);
90     sp->width = xgwa.width;
91     sp->height = xgwa.height;
92
93     /* Clear the background. */
94     XSetForeground(dsp, pwin->gc, BlackPixelOfScreen(pwin->perscreen->screen));
95     XFillRectangle(dsp, pwin->w, pwin->gc, 0, 0, sp->width, sp->height);
96
97     /* Allocate memory. */
98
99     sp->segs = (XSegment *) malloc(sizeof(XSegment) * sp->beecount);
100     sp->old_segs = (XSegment *) malloc(sizeof(XSegment) * sp->beecount);
101     sp->x = (short *) malloc(sizeof(short) * sp->beecount * TIMES);
102     sp->y = (short *) malloc(sizeof(short) * sp->beecount * TIMES);
103     sp->xv = (short *) malloc(sizeof(short) * sp->beecount);
104     sp->yv = (short *) malloc(sizeof(short) * sp->beecount);
105
106     /* Initialize point positions, velocities, etc. */
107
108     /* wasp */
109     sp->wx[0] = BORDER + random() % (sp->width - 2 * BORDER);
110     sp->wy[0] = BORDER + random() % (sp->height - 2 * BORDER);
111     sp->wx[1] = sp->wx[0];
112     sp->wy[1] = sp->wy[0];
113     sp->wxv = 0;
114     sp->wyv = 0;
115
116     /* bees */
117     for (b = 0; b < sp->beecount; b++) {
118         X(0, b) = random() % sp->width;
119         X(1, b) = X(0, b);
120         Y(0, b) = random() % sp->height;
121         Y(1, b) = Y(0, b);
122         sp->xv[b] = RAND(7);
123         sp->yv[b] = RAND(7);
124     }
125 }
126
127
128
129 void
130 drawswarm(pwin)
131     perwindow *pwin;
132 {
133     swarmstruct *sp;
134     int         b;
135
136     sp = (swarmstruct *)pwin->data;
137     /* <=- Wasp -=> */
138     /* Age the arrays. */
139     sp->wx[2] = sp->wx[1];
140     sp->wx[1] = sp->wx[0];
141     sp->wy[2] = sp->wy[1];
142     sp->wy[1] = sp->wy[0];
143     /* Accelerate */
144     sp->wxv += RAND(WASPACC);
145     sp->wyv += RAND(WASPACC);
146
147     /* Speed Limit Checks */
148     if (sp->wxv > WASPVEL)
149         sp->wxv = WASPVEL;
150     if (sp->wxv < -WASPVEL)
151         sp->wxv = -WASPVEL;
152     if (sp->wyv > WASPVEL)
153         sp->wyv = WASPVEL;
154     if (sp->wyv < -WASPVEL)
155         sp->wyv = -WASPVEL;
156
157     /* Move */
158     sp->wx[0] = sp->wx[1] + sp->wxv;
159     sp->wy[0] = sp->wy[1] + sp->wyv;
160
161     /* Bounce Checks */
162     if ((sp->wx[0] < BORDER) || (sp->wx[0] > sp->width - BORDER - 1)) {
163         sp->wxv = -sp->wxv;
164         sp->wx[0] += sp->wxv;
165     }
166     if ((sp->wy[0] < BORDER) || (sp->wy[0] > sp->height - BORDER - 1)) {
167         sp->wyv = -sp->wyv;
168         sp->wy[0] += sp->wyv;
169     }
170     /* Don't let things settle down. */
171     sp->xv[random() % sp->beecount] += RAND(3);
172     sp->yv[random() % sp->beecount] += RAND(3);
173
174     /* <=- Bees -=> */
175     for (b = 0; b < sp->beecount; b++) {
176         int         distance,
177                     dx,
178                     dy;
179         /* Age the arrays. */
180         X(2, b) = X(1, b);
181         X(1, b) = X(0, b);
182         Y(2, b) = Y(1, b);
183         Y(1, b) = Y(0, b);
184
185         /* Accelerate */
186         dx = sp->wx[1] - X(1, b);
187         dy = sp->wy[1] - Y(1, b);
188         distance = abs(dx) + abs(dy);   /* approximation */
189         if (distance == 0)
190             distance = 1;
191         sp->xv[b] += (dx * BEEACC) / distance;
192         sp->yv[b] += (dy * BEEACC) / distance;
193
194         /* Speed Limit Checks */
195         if (sp->xv[b] > BEEVEL)
196             sp->xv[b] = BEEVEL;
197         if (sp->xv[b] < -BEEVEL)
198             sp->xv[b] = -BEEVEL;
199         if (sp->yv[b] > BEEVEL)
200             sp->yv[b] = BEEVEL;
201         if (sp->yv[b] < -BEEVEL)
202             sp->yv[b] = -BEEVEL;
203
204         /* Move */
205         X(0, b) = X(1, b) + sp->xv[b];
206         Y(0, b) = Y(1, b) + sp->yv[b];
207
208         /* Fill the segment lists. */
209         sp->segs[b].x1 = X(0, b);
210         sp->segs[b].y1 = Y(0, b);
211         sp->segs[b].x2 = X(1, b);
212         sp->segs[b].y2 = Y(1, b);
213         sp->old_segs[b].x1 = X(1, b);
214         sp->old_segs[b].y1 = Y(1, b);
215         sp->old_segs[b].x2 = X(2, b);
216         sp->old_segs[b].y2 = Y(2, b);
217     }
218
219     XSetForeground(dsp, pwin->gc, BlackPixelOfScreen(pwin->perscreen->screen));
220     XDrawLine(dsp, pwin->w, pwin->gc,
221               sp->wx[1], sp->wy[1], sp->wx[2], sp->wy[2]);
222     XDrawSegments(dsp, pwin->w, pwin->gc, sp->old_segs, sp->beecount);
223
224     XSetForeground(dsp, pwin->gc, WhitePixelOfScreen(pwin->perscreen->screen));
225     XDrawLine(dsp, pwin->w, pwin->gc,
226               sp->wx[0], sp->wy[0], sp->wx[1], sp->wy[1]);
227     if (!mono && pwin->perscreen->npixels > 2) {
228         XSetForeground(dsp, pwin->gc, pwin->perscreen->pixels[sp->pix]);
229         if (++sp->pix >= pwin->perscreen->npixels)
230             sp->pix = 0;
231     }
232     XDrawSegments(dsp, pwin->w, pwin->gc, sp->segs, sp->beecount);
233 }