2 * Copyright (c) 1988-91 by Patrick J. Naughton.
4 * Permission to use, copy, modify, and distribute this software and its
5 * documentation for any purpose and without fee is hereby granted,
6 * provided that the above copyright notice appear in all copies and that
7 * both that copyright notice and this permission notice appear in
8 * supporting documentation.
10 * This file is provided AS IS with no warranties of any kind. The author
11 * shall have no liability with respect to the infringement of copyrights,
12 * trade secrets or any patents by this file or any part thereof. In no
13 * event will the author be liable for any lost revenue or profits or
14 * other special, indirect and consequential damages.
18 * Copyright (c) 1990, 2015, Oracle and/or its affiliates. All rights reserved.
20 * Permission is hereby granted, free of charge, to any person obtaining a
21 * copy of this software and associated documentation files (the "Software"),
22 * to deal in the Software without restriction, including without limitation
23 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
24 * and/or sell copies of the Software, and to permit persons to whom the
25 * Software is furnished to do so, subject to the following conditions:
27 * The above copyright notice and this permission notice (including the next
28 * paragraph) shall be included in all copies or substantial portions of the
31 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
34 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
36 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
37 * DEALINGS IN THE SOFTWARE.
40 * swarm.c - swarm of bees for xlock, the X Window System lockscreen.
42 * Copyright (c) 1991 by Patrick J. Naughton.
45 * 31-Aug-90: Adapted from xswarm by Jeff Butterworth. (butterwo@ncsc.org)
50 #define TIMES 4 /* number of time positions recorded */
51 #define BEEACC 3 /* acceleration of bees */
52 #define WASPACC 5 /* maximum acceleration of wasp */
53 #define BEEVEL 11 /* maximum bee velocity */
54 #define WASPVEL 12 /* maximum wasp velocity */
55 #define BORDER 50 /* wasp won't go closer than this to the edge */
58 #define X(t,b) (sp->x[(t)*sp->beecount+(b)])
59 #define Y(t,b) (sp->y[(t)*sp->beecount+(b)])
60 #define RAND(v) ((random()%(v))-((v)/2)) /* random number around 0 */
67 uint_t beecount
; /* number of bees */
68 XSegment
*segs
; /* bee lines */
69 XSegment
*old_segs
; /* old bee lines */
71 short *y
; /* bee positions x[time][bee#] */
73 short *yv
; /* bee velocities xv[bee#] */
80 static swarmstruct swarms
[MAXSCREENS
];
85 XWindowAttributes xgwa
;
86 swarmstruct
*sp
= &swarms
[screen
];
89 sp
->startTime
= seconds();
90 if ((batchcount
< 1) || (batchcount
> 1024))
92 sp
->beecount
= (uint_t
) batchcount
;
94 XGetWindowAttributes(dsp
, win
, &xgwa
);
95 sp
->width
= xgwa
.width
;
96 sp
->height
= xgwa
.height
;
98 /* Clear the background. */
99 XSetForeground(dsp
, Scr
[screen
].gc
, ssblack
[screen
].pixel
);
100 XFillRectangle(dsp
, win
, Scr
[screen
].gc
, 0, 0, sp
->width
, sp
->height
);
102 /* Allocate memory. */
105 sp
->segs
= malloc(sizeof(XSegment
) * sp
->beecount
);
106 sp
->old_segs
= malloc(sizeof(XSegment
) * sp
->beecount
);
107 sp
->x
= malloc(sizeof(short) * sp
->beecount
* TIMES
);
108 sp
->y
= malloc(sizeof(short) * sp
->beecount
* TIMES
);
109 sp
->xv
= malloc(sizeof(short) * sp
->beecount
);
110 sp
->yv
= malloc(sizeof(short) * sp
->beecount
);
112 if ((sp
->segs
== NULL
) || (sp
->old_segs
== NULL
) ||
113 (sp
->x
== NULL
) || (sp
->y
== NULL
) ||
114 (sp
->xv
== NULL
) || (sp
->yv
== NULL
)) {
115 error("allocation failed, colony collapsed, no bees left in the swarm\n");
118 /* Initialize point positions, velocities, etc. */
121 sp
->wx
[0] = (short) (BORDER
+ random() % (sp
->width
- 2 * BORDER
));
122 sp
->wy
[0] = (short) (BORDER
+ random() % (sp
->height
- 2 * BORDER
));
123 sp
->wx
[1] = sp
->wx
[0];
124 sp
->wy
[1] = sp
->wy
[0];
129 for (b
= 0; b
< sp
->beecount
; b
++) {
130 X(0, b
) = (short) (random() % sp
->width
);
132 Y(0, b
) = (short) (random() % sp
->height
);
134 sp
->xv
[b
] = (short) RAND(7);
135 sp
->yv
[b
] = (short) RAND(7);
142 drawswarm(Window win
)
144 swarmstruct
*sp
= &swarms
[screen
];
148 /* Age the arrays. */
149 sp
->wx
[2] = sp
->wx
[1];
150 sp
->wx
[1] = sp
->wx
[0];
151 sp
->wy
[2] = sp
->wy
[1];
152 sp
->wy
[1] = sp
->wy
[0];
154 sp
->wxv
+= (short) RAND(WASPACC
);
155 sp
->wyv
+= (short) RAND(WASPACC
);
157 /* Speed Limit Checks */
158 if (sp
->wxv
> WASPVEL
)
160 if (sp
->wxv
< -WASPVEL
)
162 if (sp
->wyv
> WASPVEL
)
164 if (sp
->wyv
< -WASPVEL
)
168 sp
->wx
[0] = (short) (sp
->wx
[1] + sp
->wxv
);
169 sp
->wy
[0] = (short) (sp
->wy
[1] + sp
->wyv
);
172 if ((sp
->wx
[0] < BORDER
) || (sp
->wx
[0] > sp
->width
- BORDER
- 1)) {
174 sp
->wx
[0] += sp
->wxv
;
176 if ((sp
->wy
[0] < BORDER
) || (sp
->wy
[0] > sp
->height
- BORDER
- 1)) {
178 sp
->wy
[0] += sp
->wyv
;
180 /* Don't let things settle down. */
181 sp
->xv
[random() % sp
->beecount
] += (short) RAND(3);
182 sp
->yv
[random() % sp
->beecount
] += (short) RAND(3);
185 for (b
= 0; b
< sp
->beecount
; b
++) {
189 /* Age the arrays. */
196 dx
= sp
->wx
[1] - X(1, b
);
197 dy
= sp
->wy
[1] - Y(1, b
);
198 distance
= abs(dx
) + abs(dy
); /* approximation */
201 sp
->xv
[b
] += (dx
* BEEACC
) / distance
;
202 sp
->yv
[b
] += (dy
* BEEACC
) / distance
;
204 /* Speed Limit Checks */
205 if (sp
->xv
[b
] > BEEVEL
)
207 if (sp
->xv
[b
] < -BEEVEL
)
209 if (sp
->yv
[b
] > BEEVEL
)
211 if (sp
->yv
[b
] < -BEEVEL
)
215 X(0, b
) = X(1, b
) + sp
->xv
[b
];
216 Y(0, b
) = Y(1, b
) + sp
->yv
[b
];
218 /* Fill the segment lists. */
219 sp
->segs
[b
].x1
= X(0, b
);
220 sp
->segs
[b
].y1
= Y(0, b
);
221 sp
->segs
[b
].x2
= X(1, b
);
222 sp
->segs
[b
].y2
= Y(1, b
);
223 sp
->old_segs
[b
].x1
= X(1, b
);
224 sp
->old_segs
[b
].y1
= Y(1, b
);
225 sp
->old_segs
[b
].x2
= X(2, b
);
226 sp
->old_segs
[b
].y2
= Y(2, b
);
229 XSetForeground(dsp
, Scr
[screen
].gc
, ssblack
[screen
].pixel
);
230 XDrawLine(dsp
, win
, Scr
[screen
].gc
,
231 sp
->wx
[1], sp
->wy
[1], sp
->wx
[2], sp
->wy
[2]);
232 XDrawSegments(dsp
, win
, Scr
[screen
].gc
, sp
->old_segs
, (int) sp
->beecount
);
234 XSetForeground(dsp
, Scr
[screen
].gc
, sswhite
[screen
].pixel
);
235 XDrawLine(dsp
, win
, Scr
[screen
].gc
,
236 sp
->wx
[0], sp
->wy
[0], sp
->wx
[1], sp
->wy
[1]);
237 if (!mono
&& Scr
[screen
].npixels
> 2) {
238 XSetForeground(dsp
, Scr
[screen
].gc
, Scr
[screen
].pixels
[sp
->pix
]);
239 if (++sp
->pix
>= Scr
[screen
].npixels
)
242 XDrawSegments(dsp
, win
, Scr
[screen
].gc
, sp
->segs
, (int) sp
->beecount
);