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