home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / x / volume10 / xlock / part01 / swarm.c < prev    next >
C/C++ Source or Header  |  1990-12-07  |  7KB  |  231 lines

  1. #ifndef lint
  2. static char sccsid[] = "@(#)swarm.c    1.3 90/10/28 XLOCK SMI";
  3. #endif
  4. /*-
  5.  * swarm.c - swarm of bees for the xlock X11 terminal locker.
  6.  *
  7.  * Copyright (c) 1990 by Sun Microsystems Inc.
  8.  *
  9.  * Permission to use, copy, modify, and distribute this software and its
  10.  * documentation for any purpose and without fee is hereby granted,
  11.  * provided that the above copyright notice appear in all copies and that
  12.  * both that copyright notice and this permission notice appear in
  13.  * supporting documentation.
  14.  *
  15.  * This file is provided AS IS with no warranties of any kind.  The author
  16.  * shall have no liability with respect to the infringement of copyrights,
  17.  * trade secrets or any patents by this file or any part thereof.  In no
  18.  * event will the author be liable for any lost revenue or profits or
  19.  * other special, indirect and consequential damages.
  20.  *
  21.  * Comments and additions should be sent to the author:
  22.  *
  23.  *               naughton@eng.sun.com
  24.  *
  25.  *               Patrick J. Naughton
  26.  *               MS 14-01
  27.  *               Windows and Graphics Group
  28.  *               Sun Microsystems, Inc.
  29.  *               2550 Garcia Ave
  30.  *               Mountain View, CA  94043
  31.  *
  32.  * Revision History:
  33.  * 31-Aug-90: Adapted from xswarm by Jeff Butterworth. (butterwo@ncsc.org)
  34.  */
  35.  
  36. #include "xlock.h"
  37.  
  38. #define TIMES    4        /* number of time positions recorded */
  39. #define BEEACC    3        /* acceleration of bees */
  40. #define WASPACC 5        /* maximum acceleration of wasp */
  41. #define BEEVEL    11        /* maximum bee velocity */
  42. #define WASPVEL 12        /* maximum wasp velocity */
  43. #define BORDER    50        /* wasp won't go closer than this to the edge */
  44.  
  45. /* Macros */
  46. #define X(t,b)    (sp->x[(t)*sp->beecount+(b)])
  47. #define Y(t,b)    (sp->y[(t)*sp->beecount+(b)])
  48. #define RAND(v)    ((random()%(v))-((v)/2))    /* random number around 0 */
  49.  
  50. typedef struct {
  51.     int         pix;
  52.     long        startTime;
  53.     int         width;
  54.     int         height;
  55.     int         beecount;    /* number of bees */
  56.     XSegment   *segs;        /* bee lines */
  57.     XSegment   *old_segs;    /* old bee lines */
  58.     short      *x;
  59.     short      *y;        /* bee positions x[time][bee#] */
  60.     short      *xv;
  61.     short      *yv;        /* bee velocities xv[bee#] */
  62.     short       wx[3];
  63.     short       wy[3];
  64.     short       wxv;
  65.     short       wyv;
  66. }           swarmstruct;
  67.  
  68. static swarmstruct swarms[MAXSCREENS];
  69.  
  70. void
  71. initswarm(win)
  72.     Window      win;
  73. {
  74.     XWindowAttributes xgwa;
  75.     swarmstruct *sp = &swarms[screen];
  76.     int         b;
  77.  
  78.     sp->startTime = seconds();
  79.     srandom(time((long *) 0));
  80.  
  81.     sp->beecount = batchcount;
  82.  
  83.     XGetWindowAttributes(dsp, win, &xgwa);
  84.     sp->width = xgwa.width;
  85.     sp->height = xgwa.height;
  86.  
  87.     /* Clear the background. */
  88.     XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen));
  89.     XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, sp->width, sp->height);
  90.  
  91.     /* Get the random number generator reasp->dy. */
  92.     srandom((int) time(0) % 231);
  93.  
  94.     /* Allocate memory. */
  95.  
  96.     if (!sp->segs) {
  97.     sp->segs = (XSegment *) malloc(sizeof(XSegment) * sp->beecount);
  98.     sp->old_segs = (XSegment *) malloc(sizeof(XSegment) * sp->beecount);
  99.     sp->x = (short *) malloc(sizeof(short) * sp->beecount * TIMES);
  100.     sp->y = (short *) malloc(sizeof(short) * sp->beecount * TIMES);
  101.     sp->xv = (short *) malloc(sizeof(short) * sp->beecount);
  102.     sp->yv = (short *) malloc(sizeof(short) * sp->beecount);
  103.     }
  104.     /* Initialize point positions, velocities, etc. */
  105.  
  106.     /* wasp */
  107.     sp->wx[0] = BORDER + random() % (sp->width - 2 * BORDER);
  108.     sp->wy[0] = BORDER + random() % (sp->height - 2 * BORDER);
  109.     sp->wx[1] = sp->wx[0];
  110.     sp->wy[1] = sp->wy[0];
  111.     sp->wxv = 0;
  112.     sp->wyv = 0;
  113.  
  114.     /* bees */
  115.     for (b = 0; b < sp->beecount; b++) {
  116.     X(0, b) = random() % sp->width;
  117.     X(1, b) = X(0, b);
  118.     Y(0, b) = random() % sp->height;
  119.     Y(1, b) = Y(0, b);
  120.     sp->xv[b] = RAND(7);
  121.     sp->yv[b] = RAND(7);
  122.     }
  123. }
  124.  
  125.  
  126.  
  127. void
  128. drawswarm(win)
  129.     Window      win;
  130. {
  131.     swarmstruct *sp = &swarms[screen];
  132.     int         b;
  133.  
  134.     /* <=- Wasp -=> */
  135.     /* Age the arrays. */
  136.     sp->wx[2] = sp->wx[1];
  137.     sp->wx[1] = sp->wx[0];
  138.     sp->wy[2] = sp->wy[1];
  139.     sp->wy[1] = sp->wy[0];
  140.     /* Accelerate */
  141.     sp->wxv += RAND(WASPACC);
  142.     sp->wyv += RAND(WASPACC);
  143.  
  144.     /* Speed Limit Checks */
  145.     if (sp->wxv > WASPVEL)
  146.     sp->wxv = WASPVEL;
  147.     if (sp->wxv < -WASPVEL)
  148.     sp->wxv = -WASPVEL;
  149.     if (sp->wyv > WASPVEL)
  150.     sp->wyv = WASPVEL;
  151.     if (sp->wyv < -WASPVEL)
  152.     sp->wyv = -WASPVEL;
  153.  
  154.     /* Move */
  155.     sp->wx[0] = sp->wx[1] + sp->wxv;
  156.     sp->wy[0] = sp->wy[1] + sp->wyv;
  157.  
  158.     /* Bounce Checks */
  159.     if ((sp->wx[0] < BORDER) || (sp->wx[0] > sp->width - BORDER - 1)) {
  160.     sp->wxv = -sp->wxv;
  161.     sp->wx[0] += sp->wxv;
  162.     }
  163.     if ((sp->wy[0] < BORDER) || (sp->wy[0] > sp->height - BORDER - 1)) {
  164.     sp->wyv = -sp->wyv;
  165.     sp->wy[0] += sp->wyv;
  166.     }
  167.     /* Don't let things settle down. */
  168.     sp->xv[random() % sp->beecount] += RAND(3);
  169.     sp->yv[random() % sp->beecount] += RAND(3);
  170.  
  171.     /* <=- Bees -=> */
  172.     for (b = 0; b < sp->beecount; b++) {
  173.     int         distance,
  174.                 dx,
  175.                 dy;
  176.     /* Age the arrays. */
  177.     X(2, b) = X(1, b);
  178.     X(1, b) = X(0, b);
  179.     Y(2, b) = Y(1, b);
  180.     Y(1, b) = Y(0, b);
  181.  
  182.     /* Accelerate */
  183.     dx = sp->wx[1] - X(1, b);
  184.     dy = sp->wy[1] - Y(1, b);
  185.     distance = abs(dx) + abs(dy);    /* approximation */
  186.     if (distance == 0)
  187.         distance = 1;
  188.     sp->xv[b] += (dx * BEEACC) / distance;
  189.     sp->yv[b] += (dy * BEEACC) / distance;
  190.  
  191.     /* Speed Limit Checks */
  192.     if (sp->xv[b] > BEEVEL)
  193.         sp->xv[b] = BEEVEL;
  194.     if (sp->xv[b] < -BEEVEL)
  195.         sp->xv[b] = -BEEVEL;
  196.     if (sp->yv[b] > BEEVEL)
  197.         sp->yv[b] = BEEVEL;
  198.     if (sp->yv[b] < -BEEVEL)
  199.         sp->yv[b] = -BEEVEL;
  200.  
  201.     /* Move */
  202.     X(0, b) = X(1, b) + sp->xv[b];
  203.     Y(0, b) = Y(1, b) + sp->yv[b];
  204.  
  205.     /* Fill the segment lists. */
  206.     sp->segs[b].x1 = X(0, b);
  207.     sp->segs[b].y1 = Y(0, b);
  208.     sp->segs[b].x2 = X(1, b);
  209.     sp->segs[b].y2 = Y(1, b);
  210.     sp->old_segs[b].x1 = X(1, b);
  211.     sp->old_segs[b].y1 = Y(1, b);
  212.     sp->old_segs[b].x2 = X(2, b);
  213.     sp->old_segs[b].y2 = Y(2, b);
  214.     }
  215.  
  216.     XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen));
  217.     XDrawLine(dsp, win, Scr[screen].gc,
  218.           sp->wx[1], sp->wy[1], sp->wx[2], sp->wy[2]);
  219.     XDrawSegments(dsp, win, Scr[screen].gc, sp->old_segs, sp->beecount);
  220.  
  221.     XSetForeground(dsp, Scr[screen].gc, WhitePixel(dsp, screen));
  222.     XDrawLine(dsp, win, Scr[screen].gc,
  223.           sp->wx[0], sp->wy[0], sp->wx[1], sp->wy[1]);
  224.     if (!mono && Scr[screen].npixels > 2) {
  225.     XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[sp->pix]);
  226.     if (++sp->pix >= Scr[screen].npixels)
  227.         sp->pix = 0;
  228.     }
  229.     XDrawSegments(dsp, win, Scr[screen].gc, sp->segs, sp->beecount);
  230. }
  231.