swarm.c 6.8 KB

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