butterwo@kimchee.ncsc.org (08/11/90)
Submitted-by: butterwo@kimchee.ncsc.org Posting-number: Volume 8, Issue 69 Archive-name: xswarm/part01 This program animates a bunch of little line segments chasing a randomly accelerating line segment. The concept is simple, but the effect is pretty cute. By default, it comes up in a window, but it can be put in the root window too. In order to make it usable as a screen background, you can alter the delay between updates, making it use very little cpu time. One of the reasons why it doesn't use much cpu time is that it only uses integer arithmetic. This program has been tested successfully on a Sun4, a DECStation 3100, and a Stardent Titan. The 3100 and the Titan were running X11R3 and the Sun4 was running X11R4. The only thing you will probably have to change in the Makefile is the location of X include files. Sorry for the lack of an Imakefile, but imake on all of the systems I have access to is installed improperly. Try xswarm -h for help. Fiddle with the parameters. You can get really different effects! Jeff ------------------------------------------------------------------------------- "Between two evils, I always choose the one I haven't tried." -Mae West Jeff Butterworth Home: 100-G Misty Woods Cir., Chapel Hill, NC 27514 (919) 967-7359 School: 235 Sitterson, UNC-Chapel Hill, NC 27599 (919) 962-1719 butterwo@cs.unc.edu Work: North Carolina Supercomputing Center, RTP, NC 27709 (919) 248-1147 butterwo@ncsc.org #! /bin/sh # This is a shell archive. Remove anything before this line, then feed it # into a shell via "sh file" or similar. To overwrite existing files, # type "sh file -c". # The tool that generated this appeared in the comp.sources.unix newsgroup; # send mail to comp-sources-unix@uunet.uu.net if you want that tool. # If this archive is complete, you will see the following message at the end: # "End of shell archive." # Contents: xswarm xswarm/Imakefile xswarm/Makefile xswarm/README # xswarm/TODO xswarm/patchlevel.h xswarm/xswarm.c xswarm/xswarm.h # Wrapped by argv@turnpike on Fri Aug 10 11:31:55 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test ! -d 'xswarm' ; then echo shar: Creating directory \"'xswarm'\" mkdir 'xswarm' fi if test -f 'xswarm/Imakefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xswarm/Imakefile'\" else echo shar: Extracting \"'xswarm/Imakefile'\" \(225 characters\) sed "s/^X//" >'xswarm/Imakefile' <<'END_OF_FILE' X#ifdef BandAidCompiler X#include BandAidCompiler X#endif X XDEFINES = XINCLUDES = -I$(TOP) -I$(TOP)/X11 XDEPLIBS = $(DEPXLIB) XLOCAL_LIBRARIES = $(XLIB) XSYS_LIBRARIES = X XSRCS = xswarm.c XOBJS = xswarm.o X XComplexProgramTarget(xswarm) END_OF_FILE if test 225 -ne `wc -c <'xswarm/Imakefile'`; then echo shar: \"'xswarm/Imakefile'\" unpacked with wrong size! fi # end of 'xswarm/Imakefile' fi if test -f 'xswarm/Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xswarm/Makefile'\" else echo shar: Extracting \"'xswarm/Makefile'\" \(406 characters\) sed "s/^X//" >'xswarm/Makefile' <<'END_OF_FILE' X# Gcc usually works better if you have it. X#CC = gcc XCC = cc X X# Uncomment this if you use X11 Release 3 instead of Release 4. X#XVERSION = -DX11R3 X X# If the path to Xlib.h needs to be set explicitly... X#XINC = X X# If you are on a Stardent Titan, then this will help it find random(). X#BSD = -43 X XCFLAGS = -O ${BSD} -I. ${XVERSION} X XLIBS = -lX11 X Xxswarm: xswarm.c X $(CC) $(CFLAGS) -o xswarm xswarm.c $(LIBS) X END_OF_FILE if test 406 -ne `wc -c <'xswarm/Makefile'`; then echo shar: \"'xswarm/Makefile'\" unpacked with wrong size! fi # end of 'xswarm/Makefile' fi if test -f 'xswarm/README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xswarm/README'\" else echo shar: Extracting \"'xswarm/README'\" \(1360 characters\) sed "s/^X//" >'xswarm/README' <<'END_OF_FILE' XThis program animates a bunch of little line segments chasing a randomly Xaccelerating line segment. The concept is simple, but the effect is pretty Xcute. By default, it comes up in a window, but it can be put in the root Xwindow too. In order to make it usable as a screen background, you can Xalter the delay between updates, making it use very little cpu time. One of Xthe reasons why it doesn't use much cpu time is that it only uses integer Xarithmetic. X XThis program has been tested successfully on a Sun4, a DECStation 3100, and Xa Stardent Titan. The 3100 and the Titan were running X11R3 and the Sun4 Xwas running X11R4. X XThe only thing you will probably have to change in the Makefile is the Xlocation of X include files. Sorry for the lack of an Imakefile, but imake Xon all of the systems I have access to is installed improperly. X XTry xswarm -h for help. Fiddle with the parameters. You can get really Xdifferent effects! X XJeff X X------------------------------------------------------------------------------- X"Between two evils, I always choose the one I haven't tried." -Mae West X XJeff Butterworth XHome: 100-G Misty Woods Cir., Chapel Hill, NC 27514 (919) 967-7359 XSchool: 235 Sitterson, UNC-Chapel Hill, NC 27599 (919) 962-1719 X butterwo@cs.unc.edu XWork: North Carolina Supercomputing Center, RTP, NC 27709 (919) 248-1147 X butterwo@ncsc.org X END_OF_FILE if test 1360 -ne `wc -c <'xswarm/README'`; then echo shar: \"'xswarm/README'\" unpacked with wrong size! fi # end of 'xswarm/README' fi if test -f 'xswarm/TODO' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xswarm/TODO'\" else echo shar: Extracting \"'xswarm/TODO'\" \(1288 characters\) sed "s/^X//" >'xswarm/TODO' <<'END_OF_FILE' XThese features and bug fixes are in no particular order. I'll get to them Xas soon as I can, but other people are more than welcome to give these things Xa try. X XIf you do improve Xswarm, then please send me your new version so that I can Xincorporate the changes into the next release. Please don't distribute Xaltered versions of this program! I'll post it to the net with all new Xchanges. X X Jeff Butterworth X butterwo@cs.unc.edu X XBugs X---- X- The xor feature has problems. In the root window any movement of windows X over the swarm will cause it to leave an ugly trail. X- The program doesn't receive the f.delete event from twm when it is in the X root window. X- A very short delay between updates (like 5 milliseconds) can cause xswarm X to hang. Someone mentioned to me that this may be a race condition. X What the heck is a race condition? If anyone wants to look at the X non-blocking delay subroutine Nap(), then please feel free. X XNew Features X------------ X- Allow the user to control the wasp with the cursor. I did this in the gl X implementation on the SGI Iris. It's pretty fun. X- Colorize the bees base on speed or proximity to the wasp. Again, I did this X on an Iris and it made the whole thing more attractive. X- Use shapes other than simple line segments. END_OF_FILE if test 1288 -ne `wc -c <'xswarm/TODO'`; then echo shar: \"'xswarm/TODO'\" unpacked with wrong size! fi # end of 'xswarm/TODO' fi if test -f 'xswarm/patchlevel.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xswarm/patchlevel.h'\" else echo shar: Extracting \"'xswarm/patchlevel.h'\" \(21 characters\) sed "s/^X//" >'xswarm/patchlevel.h' <<'END_OF_FILE' X#define PATCHLEVEL 0 END_OF_FILE if test 21 -ne `wc -c <'xswarm/patchlevel.h'`; then echo shar: \"'xswarm/patchlevel.h'\" unpacked with wrong size! fi # end of 'xswarm/patchlevel.h' fi if test -f 'xswarm/xswarm.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xswarm/xswarm.c'\" else echo shar: Extracting \"'xswarm/xswarm.c'\" \(15525 characters\) sed "s/^X//" >'xswarm/xswarm.c' <<'END_OF_FILE' X/* X** XSwarm X** ====== X** X** Purpose: Display a swarm of bees chasing a wasp. X** X** Features: uses only integer math X** can be put in the root window X** uses non-blocking delays to decrease cpu usage and control speed X** has no redeeming social value X** X** Comments: I used psychoII (I assume it's a derivative of ico.) as an X** an example of how to open up a window and draw some lines. X** Most of this program is now totally rewritten by me, but the X** initial window manager hints stuff is left over from the older X** program. X** X** Any comments, enhances, or fixes are welcome! X** X** Created: by Jeff Butterworth on 7/11/90 X** butterwo@cs.unc.edu or butterwo@ncsc.org X** X** Updated: by Jeff Butterworth on 8/1/90 X** X*/ X X/* These are needed for the nap function. */ X#include <sys/time.h> X#include <signal.h> X X/* X Includes */ X#include <X11/Xlib.h> X#include <X11/Xatom.h> X#include <X11/Xutil.h> X X/* Standard Includes */ X#include <stdio.h> X X/* Includes for this project. */ X#include <xswarm.h> X X X/* Main() X** process command line parameters, setup X stuff X*/ X Xmain(argc, argv) Xint argc; Xchar **argv; X{ X /* These variables are used to analyze the command line parameters. */ X int option; X extern int optind; X extern char *optarg; X X char *geom = NULL; X int root = FALSE; X XSetWindowAttributes xswa; X XWMHints wmhints; X unsigned char wname[32]; X XSizeHints sizehint; X X X /* Check the command line. */ X while ((option = getopt(argc,argv,"hq?vrxg:b:a:s:A:S:d:B:w:c:C:")) != EOF) X { X switch (option) X { X case 'v': X verbose = TRUE; X break; X case 'r': X root = TRUE; X break; X case 'x': X xor = TRUE; X break; X case 'g': X geom = optarg; X break; X case 'b': X bees = atoi(optarg); X break; X case 'a': X bee_acc = atoi(optarg); X break; X case 's': X bee_vel = atoi(optarg); X break; X case 'A': X wasp_acc = atoi(optarg); X break; X case 'S': X wasp_vel = atoi(optarg); X break; X case 'd': X delay = atoi(optarg) * 1000; /* convert to microseconds */ X break; X case 'B': X border = atoi(optarg); X break; X case 'w': X wasp_color = optarg; X break; X case 'c': X bee_color = optarg; X break; X case 'C': X bg_color = optarg; X break; X case 'h': X case 'q': X case '?': X Usage(*argv); X HandleError("The command line parameters were incorrect.", X FATAL); X break; X } X } X X /* Display the arguments. */ X if (verbose) X { X printf("Here are the current settings...\n"); X if (xor) X printf("The logical raster operation GXxor is being used.\n"); X else X printf("The logical raster operation GXcopy is being used.\n"); X printf("There are %d bees.\n", bees); X printf("Bee acceleration is %d pixels per frame per frame.\n",bee_acc); X printf("Bee speed limit is %d pixels per frame.\n", bee_vel); X printf("Wasp acceleration is %d pixels per frame per frame.\n", X wasp_acc); X printf("Wasp speed limit is %d pixels per frame.\n", wasp_vel); X printf("The non-blocking delay is %d milliseconds per frame.\n", X delay / 1000); X printf("The wasp can't go within %d pixels of the window edge.\n", X border); X printf("The wasp color is \"%s\"\n", wasp_color); X printf("The bee color is \"%s\"\n", bee_color); X printf("The background color is \"%s\"\n", bg_color); X } X X /* This is a remnant of an earlier program. I don't remember if it is X necessary. */ X display.dname = NULL; X X winW = winH = winX = winY = 0; X X /* Open the display. */ X if (!(display.dpy = XOpenDisplay(display.dname))) X { X HandleError("Cannot open display.\n"); X exit(-1); X } X X /* Set the colors. */ X display.cmap = XDefaultColormap(display.dpy, DefaultScreen(display.dpy)); X if (!display.cmap) HandleError("There was no default colormap!", FATAL); X X if (wasp_color == NULL) X display.wasp =WhitePixel(display.dpy, DefaultScreen(display.dpy)); X else X display.wasp = GetColor(&display, wasp_color); X X if (bee_color == NULL) X display.bee =WhitePixel(display.dpy, DefaultScreen(display.dpy)); X else X display.bee = GetColor(&display, bee_color); X X if (bg_color == NULL) X display.bg =BlackPixel(display.dpy, DefaultScreen(display.dpy)); X else X display.bg = GetColor(&display, bg_color); X X /* Set up window parameters, create and map window if necessary */ X if (!root) X { X winW = WINWIDTH; X winH = WINHEIGHT; X winX = (DisplayWidth(display.dpy, X DefaultScreen(display.dpy)) - winW) >> 1; X winY = (DisplayHeight(display.dpy, X DefaultScreen(display.dpy)) - winH) >> 1; X if (geom) X XParseGeometry(geom, &winX, &winY, &winW, &winH); X } X else X { X winW = DisplayWidth(display.dpy, DefaultScreen(display.dpy)); X winH = DisplayHeight(display.dpy, DefaultScreen(display.dpy)); X winX = 0; X winY = 0; X } X X if (!root) X { X xswa.event_mask = 0; X xswa.background_pixel = display.bg; X xswa.border_pixel = display.wasp; X display.win = XCreateWindow(display.dpy, X DefaultRootWindow(display.dpy), X winX + winW + 50, winY, X winW, winH, 0, X DefaultDepth(display.dpy, DefaultScreen(display.dpy)), X InputOutput, DefaultVisual(display.dpy, X DefaultScreen(display.dpy)), X CWEventMask | CWBackPixel | CWBorderPixel, &xswa); X X sizehint.flags = PPosition | PSize; X X XSetNormalHints(display.dpy, display.win, &sizehint); X display.protocol_atom = XInternAtom(display.dpy, "WM_PROTOCOLS", False); X display.kill_atom = XInternAtom(display.dpy, "WM_DELETE_WINDOW", False); X#ifdef X11R4 X XSetWMProtocols(display.dpy, display.win, &display.kill_atom, 1); X#endif X X /* Title */ X sprintf(wname, "XSwarm, Version 1.1, by Jeff Butterworth"); X XChangeProperty(display.dpy, display.win, X XA_WM_NAME, XA_STRING, 8, PropModeReplace, wname, X strlen(wname)); X X /* Window Manager Hints (This is supposed to make input work.) */ X wmhints.flags = InputHint; X wmhints.input = True; X XSetWMHints(display.dpy, display.win, &wmhints); X X XMapWindow(display.dpy, display.win); X } X else X display.win = display.dpy->screens[display.dpy->default_screen].root; X X /* Event Mask */ X XSelectInput(display.dpy, display.win, KeyPressMask | CWEventMask); X X /* Set up the bees' graphics context. */ X display.bee_gc = XCreateGC(display.dpy, display.win, 0, NULL); X XSetForeground(display.dpy, display.bee_gc, display.bee); X XSetBackground(display.dpy, display.bee_gc, display.bg); X X /* Set up the wasp's graphics context. */ X display.wasp_gc = XCreateGC(display.dpy, display.win, 0, NULL); X XSetForeground(display.dpy, display.wasp_gc, display.wasp); X XSetBackground(display.dpy, display.wasp_gc, display.bg); X X /* Set up an erasing graphics context. */ X display.erase_gc = XCreateGC(display.dpy, display.win, 0, NULL); X XCopyGC(display.dpy, display.bee_gc, 0xffffffff, display.erase_gc); X XSetForeground(display.dpy, display.erase_gc, display.bg); X X /* Set up an xor wasp graphics context. */ X display.wasp_xor_gc = XCreateGC(display.dpy, display.win, 0, NULL); X XCopyGC(display.dpy, display.wasp_gc, 0xffffffff, display.wasp_xor_gc); X XSetFunction(display.dpy, display.wasp_xor_gc, GXxor); X XSetForeground(display.dpy, display.wasp_xor_gc, display.bg); X X /* Set up an xor bee graphics context. */ X display.bee_xor_gc = XCreateGC(display.dpy, display.win, 0, NULL); X XCopyGC(display.dpy, display.bee_gc, 0xffffffff, display.bee_xor_gc); X XSetFunction(display.dpy, display.bee_xor_gc, GXxor); X XSetForeground(display.dpy, display.bee_xor_gc, display.bg); X X /* Clear the background. */ X if (!xor) X { X XSetWindowBackground(display.dpy, display.win, display.bg); X XFillRectangle(display.dpy, display.win, display.erase_gc, X 0,0, winW, winH); X } X X /* Animate the swarm. */ X Animate(); X} X X X XAnimate() X{ X register int b; /* bee index */ X XSegment *segs; /* bee lines */ X XSegment *old_segs; /* old bee lines */ X short *x, *y; /* bee positions x[time][bee#] */ X short *xv, *yv; /* bee velocities xv[bee#] */ X short wx[3], wy[3]; X short wxv, wyv; X XEvent xev; X short dx,dy,distance; X int init = TRUE; X X X /* Get the random number generator ready. */ X srandom((int) time(0) % 231); X X /* Allocate memory. */ X segs = (XSegment *) malloc(sizeof(XSegment) * bees); X old_segs = (XSegment *) malloc(sizeof(XSegment) * bees); X x = (short *) malloc(sizeof(short) * bees * times); X y = (short *) malloc(sizeof(short) * bees * times); X xv = (short *) malloc(sizeof(short) * bees); X yv = (short *) malloc(sizeof(short) * bees); X X /* Initialize point positions, velocities, etc. */ X X /* wasp */ X wx[0] = BORDER + random() % (winW - 2*BORDER); X wy[0] = BORDER + random() % (winH - 2*BORDER); X wx[1] = wx[0]; X wy[1] = wy[0]; X wxv = 0; X wyv = 0; X X /* bees */ X for (b = 0 ; b < bees ; b++) X { X X(0,b) = random() % winW; X X(1,b) = X(0,b); X Y(0,b) = random() % winH; X Y(1,b) = Y(0,b); X xv[b] = RAND(7); X yv[b] = RAND(7); X } X X /* Seemingly endless loop. */ X for (;;) X { X /* <=- Wasp -=> */ X /* Age the arrays. */ X wx[2] = wx[1]; X wx[1] = wx[0]; X wy[2] = wy[1]; X wy[1] = wy[0]; X /* Accelerate */ X wxv += RAND(wasp_acc); X wyv += RAND(wasp_acc); X X /* Speed Limit Checks */ X if (wxv > wasp_vel) wxv = wasp_vel; X if (wxv < -wasp_vel) wxv = -wasp_vel; X if (wyv > wasp_vel) wyv = wasp_vel; X if (wyv < -wasp_vel) wyv = -wasp_vel; X X /* Move */ X wx[0] = wx[1] + wxv; X wy[0] = wy[1] + wyv; X X /* Bounce Checks */ X if ((wx[0] < border) || (wx[0] > winW-border-1)) X { X wxv = -wxv; X wx[0] += wxv; X } X if ((wy[0] < border) || (wy[0] > winH-border-1)) X { X wyv = -wyv; X wy[0] += wyv; X } X X /* Don't let things settle down. */ X xv[random() % bees] += RAND(3); X yv[random() % bees] += RAND(3); X X /* <=- Bees -=> */ X for (b = 0 ; b < bees ; b++) X { X /* Age the arrays. */ X X(2,b) = X(1,b); X X(1,b) = X(0,b); X Y(2,b) = Y(1,b); X Y(1,b) = Y(0,b); X X /* Accelerate */ X dx = wx[1] - X(1,b); X dy = wy[1] - Y(1,b); X distance = abs(dx)+abs(dy); /* approximation */ X if (distance == 0) distance = 1; X xv[b] += (dx*bee_acc)/distance; X yv[b] += (dy*bee_acc)/distance; X X /* Speed Limit Checks */ X if (xv[b] > bee_vel) xv[b] = bee_vel; X if (xv[b] < -bee_vel) xv[b] = -bee_vel; X if (yv[b] > bee_vel) yv[b] = bee_vel; X if (yv[b] < -bee_vel) yv[b] = -bee_vel; X X /* Move */ X X(0,b) = X(1,b) + xv[b]; X Y(0,b) = Y(1,b) + yv[b]; X X /* Fill the segment lists. */ X segs[b].x1 = X(0,b); X segs[b].y1 = Y(0,b); X segs[b].x2 = X(1,b); X segs[b].y2 = Y(1,b); X old_segs[b].x1 = X(1,b); X old_segs[b].y1 = Y(1,b); X old_segs[b].x2 = X(2,b); X old_segs[b].y2 = Y(2,b); X } X X /* Erase previous, draw current, sync for smoothness. */ X X /* Wasp */ X if (xor) X { X if (init == FALSE) X XDrawLine(display.dpy, display.win, display.wasp_xor_gc, X wx[1], wy[1], wx[2], wy[2]); X XDrawLine(display.dpy, display.win, display.wasp_xor_gc, X wx[0], wy[0], wx[1], wy[1]); X } X else X { X if (init == FALSE) X XDrawLine(display.dpy, display.win, display.erase_gc, X wx[1], wy[1], wx[2], wy[2]); X XDrawLine(display.dpy, display.win, display.wasp_gc, X wx[0], wy[0], wx[1], wy[1]); X } X X /* Bees */ X if (xor) X { X if (init == FALSE) X XDrawSegments(display.dpy, display.win, display.bee_xor_gc, X old_segs, bees); X else X init = FALSE; X XDrawSegments(display.dpy, display.win, display.bee_xor_gc, X segs, bees); X } X else X { X if (init == FALSE) X XDrawSegments(display.dpy, display.win, display.erase_gc, X old_segs, bees); X else X init = FALSE; X XDrawSegments(display.dpy, display.win, display.bee_gc, segs, bees); X } X X XSync(display.dpy, False); X X /* Check for events. */ X if (XPending(display.dpy)) X { X XNextEvent(display.dpy, &xev); X HandleEvent(&xev); X } X X /* Clean up and shut down. */ X if (stop) X { X if (xor) X { X XDrawSegments(display.dpy, display.win, display.bee_xor_gc, X segs, bees); X XDrawLine(display.dpy, display.win, display.wasp_xor_gc, X wx[0], wy[0], wx[1], wy[1]); X } X else X XFillRectangle(display.dpy, display.win, display.erase_gc, X 0,0, winW, winH); X XSync(display.dpy, 0); X exit(0); X } X X /* Delay so we don't use all of the cpu time. */ X if (delay != 0) nap(0,delay); X } X} X X X/* X** HandleEvent() X** X** process X events X*/ X XHandleEvent(event) XXEvent *event; X{ X switch (event->type) X { X case ClientMessage: /* sent by f.delete from twm */ X { X XClientMessageEvent *ev = (XClientMessageEvent *) event; X if (ev->message_type == display.protocol_atom && ev->data.l[0] == display.kill_atom) X stop = TRUE; X } X break; X case KeyPress: X { X XKeyEvent *key_event = (XKeyEvent *) event; X char buf[128]; X KeySym ks; X XComposeStatus status; X X XLookupString(key_event,buf,128,&ks,&status); X if (buf[0]=='q' || buf[0]=='Q') X stop = TRUE; X } X break; X default: X break; X } X} X X X/* nap X** X** put the process to sleep for a while X*/ X Xint catchalarm() { } /* SIGALRM (null) signal handler */ X Xvoid nap(sec,usec) Xlong sec, usec; X{ X extern int setitimer(); X extern void sigpause(); X struct itimerval wait; X static int sigset = FALSE; X X /* If usec is larger than 1 second: */ X while(usec >= 1e6) { sec++; usec -= 1e6; } X X if(!sigset) { X signal(SIGALRM,catchalarm); X sigset = TRUE; X } X X wait.it_value.tv_sec = sec; X wait.it_value.tv_usec = usec; X wait.it_interval.tv_sec = 0; X wait.it_interval.tv_usec = 0; X X if((setitimer(ITIMER_REAL,&wait,NULL)) == -1) { X HandleError("bad setitimer()", FATAL); X } X X sigpause(0); X} X X Xvoid XUsage(program) Xchar *program; X{ X printf("%s [options] where options are listed below\n", program); X printf("-r use root window\n"); X printf("-d delay non-blocking delay between screen updates in milliseconds\n"); X printf(" (Less than 10 is dangerous!)\n"); X printf("-x use the logical xor raster operation\n"); X printf(" (This is buggy, but it leaves your root bitmap alone!)\n"); X printf("-g geom window geometry\n"); X printf("-b bees number of bees\n"); X printf("-a bee_acc bee acceleration in pixels per frame per frame\n"); X printf("-s bee_vel bee speed limit in pixels per frame\n"); X printf("-A wasp_acc wasp max acceleration in pixels per frame per frame\n"); X printf("-S wasp_vel wasp speed limit in pixels per frame\n"); X printf("-B width border width that wasp can't cross\n"); X printf("-w wasp_clr wasp color\n"); X printf("-c bee_clr bee color\n"); X printf("-C bg_color background color\n"); X printf("-h|q|? display this message\n"); X printf("\nPress q in the window to stop the insanity.\n\n"); X} X X Xvoid XHandleError(description, degree) Xchar *description; Xint degree; X{ X fprintf(stderr, "An error has occurred. The description is below...\n"); X fprintf(stderr, "%s\n", description); X X if (degree == FATAL) X { X fprintf(stderr, "Program aborting...\n"); X exit(-1); X } X} X Xlong XGetColor(display, color) Xdisp *display; Xchar *color; X{ X XColor cdef; X char error_str[STD_STR]; X X if (XParseColor(display->dpy, display->cmap, color, &cdef) && X XAllocColor(display->dpy, display->cmap, &cdef)) X return(cdef.pixel); X else X { X sprintf(error_str, "Color \"%s\" wasn't found.", color); X HandleError(error_str, FATAL); X } X} END_OF_FILE if test 15525 -ne `wc -c <'xswarm/xswarm.c'`; then echo shar: \"'xswarm/xswarm.c'\" unpacked with wrong size! fi # end of 'xswarm/xswarm.c' fi if test -f 'xswarm/xswarm.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xswarm/xswarm.h'\" else echo shar: Extracting \"'xswarm/xswarm.h'\" \(1914 characters\) sed "s/^X//" >'xswarm/xswarm.h' <<'END_OF_FILE' X/* Constants */ X#define TRUE 1 X#define FALSE 0 X#define STD_STR 100 X#define BEES 20 /* number of bees */ X#define TIMES 3 /* number of time positions recorded */ X#define BEEACC 3 /* acceleration of bees */ X#define WASPACC 5 /* maximum acceleration of wasp */ X#define BEEVEL 11 /* maximum bee velocity */ X#define WASPVEL 12 /* maximum wasp velocity */ X#define DELAY 40000 /* microsecond delay between updates */ X#define WINWIDTH 512 /* default window width */ X#define WINHEIGHT 512 /* default window height */ X#define BORDER 50 /* wasp won't go closer than this to the edges */ X X/* Error Codes */ X#define FATAL -1 X#define WARNING -2 X X/* Macros */ X#define X(t,b) (x[t*bees + b]) /* addressing into dynamic array */ X#define Y(t,b) (y[t*bees + b]) /* addressing into dynamic array */ X#define RAND(v) ((random() % v) - (v/2)) /* random number around 0 */ X X/* Type Definitions */ Xtypedef struct _disp X{ X Window win; X Display *dpy; X char *dname; X long wasp, bee, bg; /* colors */ X GC wasp_gc; X GC bee_gc; X GC erase_gc; X GC wasp_xor_gc; X GC bee_xor_gc; X Atom kill_atom, protocol_atom; X Colormap cmap; X} disp; X X/* Function Prototypes */ Xvoid nap(); Xvoid Usage(); Xvoid HandleError(); Xlong GetColor(); X X/* Global Variables */ X X/* X related */ Xint winX, winY; Xunsigned int winW, winH; Xdisp display; X X/* animation related */ Xint times = TIMES; /* number of time steps recorded */ Xint bees = BEES; /* number of bees */ Xint wasp_vel = WASPVEL; /* maximum wasp speed */ Xint bee_vel = BEEVEL; /* maximum bee speed */ Xint wasp_acc = WASPACC; /* maximum wasp acceleration */ Xint bee_acc = BEEACC; /* bee acceleration */ Xint delay = DELAY; /* delay between updates, in microseconds */ Xint border = BORDER; /* border limiting wasp travel */ Xchar *wasp_color = NULL; Xchar *bee_color = NULL; Xchar *bg_color = NULL; Xchar stop = FALSE; Xint xor = FALSE; /* use GXxor if TRUE */ Xint verbose = FALSE; /* display settings if TRUE */ END_OF_FILE if test 1914 -ne `wc -c <'xswarm/xswarm.h'`; then echo shar: \"'xswarm/xswarm.h'\" unpacked with wrong size! fi # end of 'xswarm/xswarm.h' fi echo shar: End of shell archive. exit 0 dan ---------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com Opinions expressed reflect those of the author only.