546N/A/*
546N/A * Copyright (c) 1988-91 by Patrick J. Naughton.
546N/A *
546N/A * Permission to use, copy, modify, and distribute this software and its
546N/A * documentation for any purpose and without fee is hereby granted,
546N/A * provided that the above copyright notice appear in all copies and that
546N/A * both that copyright notice and this permission notice appear in
546N/A * supporting documentation.
546N/A *
546N/A * This file is provided AS IS with no warranties of any kind. The author
546N/A * shall have no liability with respect to the infringement of copyrights,
546N/A * trade secrets or any patents by this file or any part thereof. In no
546N/A * event will the author be liable for any lost revenue or profits or
546N/A * other special, indirect and consequential damages.
546N/A */
546N/A
546N/A/*
943N/A * Copyright (c) 1990, 1994, Oracle and/or its affiliates. All rights reserved.
546N/A *
546N/A * Permission is hereby granted, free of charge, to any person obtaining a
919N/A * copy of this software and associated documentation files (the "Software"),
919N/A * to deal in the Software without restriction, including without limitation
919N/A * the rights to use, copy, modify, merge, publish, distribute, sublicense,
919N/A * and/or sell copies of the Software, and to permit persons to whom the
919N/A * Software is furnished to do so, subject to the following conditions:
546N/A *
919N/A * The above copyright notice and this permission notice (including the next
919N/A * paragraph) shall be included in all copies or substantial portions of the
919N/A * Software.
546N/A *
919N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
919N/A * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
919N/A * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
919N/A * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
919N/A * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
919N/A * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
919N/A * DEALINGS IN THE SOFTWARE.
546N/A */
546N/A/*-
546N/A * swarm.c - swarm of bees for xlock, the X Window System lockscreen.
546N/A *
546N/A * Copyright (c) 1991 by Patrick J. Naughton.
546N/A *
546N/A * Revision History:
546N/A * 31-Aug-90: Adapted from xswarm by Jeff Butterworth. (butterwo@ncsc.org)
546N/A */
546N/A
546N/A#include "xlock.h"
546N/A
546N/A#define TIMES 4 /* number of time positions recorded */
546N/A#define BEEACC 3 /* acceleration of bees */
546N/A#define WASPACC 5 /* maximum acceleration of wasp */
546N/A#define BEEVEL 11 /* maximum bee velocity */
546N/A#define WASPVEL 12 /* maximum wasp velocity */
546N/A#define BORDER 50 /* wasp won't go closer than this to the edge */
546N/A
546N/A/* Macros */
546N/A#define X(t,b) (sp->x[(t)*sp->beecount+(b)])
546N/A#define Y(t,b) (sp->y[(t)*sp->beecount+(b)])
546N/A#define RAND(v) ((random()%(v))-((v)/2)) /* random number around 0 */
546N/A
546N/Atypedef struct {
546N/A int pix;
546N/A long startTime;
546N/A int width;
546N/A int height;
546N/A int beecount; /* number of bees */
546N/A XSegment *segs; /* bee lines */
546N/A XSegment *old_segs; /* old bee lines */
546N/A short *x;
546N/A short *y; /* bee positions x[time][bee#] */
546N/A short *xv;
546N/A short *yv; /* bee velocities xv[bee#] */
546N/A short wx[3];
546N/A short wy[3];
546N/A short wxv;
546N/A short wyv;
546N/A} swarmstruct;
546N/A
546N/Aextern XColor ssblack[];
546N/Aextern XColor sswhite[];
546N/A
546N/Astatic swarmstruct swarms[MAXSCREENS];
546N/A
546N/Avoid
546N/Ainitswarm(win)
546N/A Window win;
546N/A{
546N/A XWindowAttributes xgwa;
546N/A swarmstruct *sp = &swarms[screen];
546N/A int b;
546N/A
546N/A sp->startTime = seconds();
546N/A sp->beecount = batchcount;
546N/A
546N/A XGetWindowAttributes(dsp, win, &xgwa);
546N/A sp->width = xgwa.width;
546N/A sp->height = xgwa.height;
546N/A
546N/A /* Clear the background. */
546N/A XSetForeground(dsp, Scr[screen].gc, ssblack[screen].pixel);
546N/A XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, sp->width, sp->height);
546N/A
546N/A /* Allocate memory. */
546N/A
546N/A if (!sp->segs) {
546N/A sp->segs = (XSegment *) malloc(sizeof(XSegment) * sp->beecount);
546N/A sp->old_segs = (XSegment *) malloc(sizeof(XSegment) * sp->beecount);
546N/A sp->x = (short *) malloc(sizeof(short) * sp->beecount * TIMES);
546N/A sp->y = (short *) malloc(sizeof(short) * sp->beecount * TIMES);
546N/A sp->xv = (short *) malloc(sizeof(short) * sp->beecount);
546N/A sp->yv = (short *) malloc(sizeof(short) * sp->beecount);
546N/A }
546N/A /* Initialize point positions, velocities, etc. */
546N/A
546N/A /* wasp */
546N/A sp->wx[0] = BORDER + random() % (sp->width - 2 * BORDER);
546N/A sp->wy[0] = BORDER + random() % (sp->height - 2 * BORDER);
546N/A sp->wx[1] = sp->wx[0];
546N/A sp->wy[1] = sp->wy[0];
546N/A sp->wxv = 0;
546N/A sp->wyv = 0;
546N/A
546N/A /* bees */
546N/A for (b = 0; b < sp->beecount; b++) {
546N/A X(0, b) = random() % sp->width;
546N/A X(1, b) = X(0, b);
546N/A Y(0, b) = random() % sp->height;
546N/A Y(1, b) = Y(0, b);
546N/A sp->xv[b] = RAND(7);
546N/A sp->yv[b] = RAND(7);
546N/A }
546N/A}
546N/A
546N/A
546N/A
546N/Avoid
546N/Adrawswarm(win)
546N/A Window win;
546N/A{
546N/A swarmstruct *sp = &swarms[screen];
546N/A int b;
546N/A
546N/A /* <=- Wasp -=> */
546N/A /* Age the arrays. */
546N/A sp->wx[2] = sp->wx[1];
546N/A sp->wx[1] = sp->wx[0];
546N/A sp->wy[2] = sp->wy[1];
546N/A sp->wy[1] = sp->wy[0];
546N/A /* Accelerate */
546N/A sp->wxv += RAND(WASPACC);
546N/A sp->wyv += RAND(WASPACC);
546N/A
546N/A /* Speed Limit Checks */
546N/A if (sp->wxv > WASPVEL)
546N/A sp->wxv = WASPVEL;
546N/A if (sp->wxv < -WASPVEL)
546N/A sp->wxv = -WASPVEL;
546N/A if (sp->wyv > WASPVEL)
546N/A sp->wyv = WASPVEL;
546N/A if (sp->wyv < -WASPVEL)
546N/A sp->wyv = -WASPVEL;
546N/A
546N/A /* Move */
546N/A sp->wx[0] = sp->wx[1] + sp->wxv;
546N/A sp->wy[0] = sp->wy[1] + sp->wyv;
546N/A
546N/A /* Bounce Checks */
546N/A if ((sp->wx[0] < BORDER) || (sp->wx[0] > sp->width - BORDER - 1)) {
546N/A sp->wxv = -sp->wxv;
546N/A sp->wx[0] += sp->wxv;
546N/A }
546N/A if ((sp->wy[0] < BORDER) || (sp->wy[0] > sp->height - BORDER - 1)) {
546N/A sp->wyv = -sp->wyv;
546N/A sp->wy[0] += sp->wyv;
546N/A }
546N/A /* Don't let things settle down. */
546N/A sp->xv[random() % sp->beecount] += RAND(3);
546N/A sp->yv[random() % sp->beecount] += RAND(3);
546N/A
546N/A /* <=- Bees -=> */
546N/A for (b = 0; b < sp->beecount; b++) {
546N/A int distance,
546N/A dx,
546N/A dy;
546N/A /* Age the arrays. */
546N/A X(2, b) = X(1, b);
546N/A X(1, b) = X(0, b);
546N/A Y(2, b) = Y(1, b);
546N/A Y(1, b) = Y(0, b);
546N/A
546N/A /* Accelerate */
546N/A dx = sp->wx[1] - X(1, b);
546N/A dy = sp->wy[1] - Y(1, b);
546N/A distance = abs(dx) + abs(dy); /* approximation */
546N/A if (distance == 0)
546N/A distance = 1;
546N/A sp->xv[b] += (dx * BEEACC) / distance;
546N/A sp->yv[b] += (dy * BEEACC) / distance;
546N/A
546N/A /* Speed Limit Checks */
546N/A if (sp->xv[b] > BEEVEL)
546N/A sp->xv[b] = BEEVEL;
546N/A if (sp->xv[b] < -BEEVEL)
546N/A sp->xv[b] = -BEEVEL;
546N/A if (sp->yv[b] > BEEVEL)
546N/A sp->yv[b] = BEEVEL;
546N/A if (sp->yv[b] < -BEEVEL)
546N/A sp->yv[b] = -BEEVEL;
546N/A
546N/A /* Move */
546N/A X(0, b) = X(1, b) + sp->xv[b];
546N/A Y(0, b) = Y(1, b) + sp->yv[b];
546N/A
546N/A /* Fill the segment lists. */
546N/A sp->segs[b].x1 = X(0, b);
546N/A sp->segs[b].y1 = Y(0, b);
546N/A sp->segs[b].x2 = X(1, b);
546N/A sp->segs[b].y2 = Y(1, b);
546N/A sp->old_segs[b].x1 = X(1, b);
546N/A sp->old_segs[b].y1 = Y(1, b);
546N/A sp->old_segs[b].x2 = X(2, b);
546N/A sp->old_segs[b].y2 = Y(2, b);
546N/A }
546N/A
546N/A XSetForeground(dsp, Scr[screen].gc, ssblack[screen].pixel);
546N/A XDrawLine(dsp, win, Scr[screen].gc,
546N/A sp->wx[1], sp->wy[1], sp->wx[2], sp->wy[2]);
546N/A XDrawSegments(dsp, win, Scr[screen].gc, sp->old_segs, sp->beecount);
546N/A
546N/A XSetForeground(dsp, Scr[screen].gc, sswhite[screen].pixel);
546N/A XDrawLine(dsp, win, Scr[screen].gc,
546N/A sp->wx[0], sp->wy[0], sp->wx[1], sp->wy[1]);
546N/A if (!mono && Scr[screen].npixels > 2) {
546N/A XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[sp->pix]);
546N/A if (++sp->pix >= Scr[screen].npixels)
546N/A sp->pix = 0;
546N/A }
546N/A XDrawSegments(dsp, win, Scr[screen].gc, sp->segs, sp->beecount);
546N/A}