billr@saab.CNA.TEK.COM (Bill Randle) (11/20/90)
Submitted-by: "Werner P. Keilholz" <keilholz@rrze2.rrze.uni-erlangen.de> Posting-number: Volume 11, Issue 70 Archive-name: swarm/Part01 Environment: MS-DOS, Turbo C [This is a PC port of a X-windows game of the same (or similar) name. The author comments that it is written in Turbo C++, but it doesn't use any C++'isms and by commenting out a few lines should be compilable with Turbo C. -br] #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 1)." # Contents: README swarm.c swarm.h # Wrapped by billr@saab on Mon Nov 19 13:13:39 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(1010 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' X Swarm X ===== X X Purpose: Display a swarm of lines. X X Features: uses only integer math X has no redeeming social value X X Comments: This code is derived from a program by Jeff Butterworth, X written for the UNIX XWINDOW system. X Like it's predecessor, this PC version (written in X TURBO C[++]) has still "no redeeming social value" X and is really good for nothing except, maybe, practicing X C (in my case). But it looks nice and maybe someone X turnes it into some kind of game or something ... X I didn't spent too much time with this, so there might X still be some 'leftovers' from the UNIX version and, X of course, bugs. X X Any comments, enhances, or fixes are welcome! X X Created: by Jeff Butterworth on 7/11/90 X X Updated: by Jeff Butterworth on 8/1/90 X PC-Version: by Werner Keilholz on 10/19/90 X (KEILHOLZ@CNVE.RRZE.UNI-ERLANGEN.DE) END_OF_FILE if test 1010 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'swarm.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'swarm.c'\" else echo shar: Extracting \"'swarm.c'\" \(14177 characters\) sed "s/^X//" >'swarm.c' <<'END_OF_FILE' X/* X** Swarm X** ===== X** X** Purpose: Display a swarm of lines. X** X** Features: uses only integer math X** has no redeeming social value X** X** Comments: This code is derived from a program by Jeff Butterworth, X** written for the UNIX XWINDOW system. X** Like it's predecessor, this PC version (written in X** TURBO C[++]) has still "no redeeming social value" X** and is really good for nothing except, maybe, practicing X** C (in my case). But it looks nice and maybe someone X** turnes it into some kind of game or something ... X** I didn't spent too much time with this, so there might X** still be some 'leftovers' from the UNIX version and, X** of course, bugs. X** X** Any comments, enhances, or fixes are welcome! X** X** Created: by Jeff Butterworth on 7/11/90 X** X** Updated: by Jeff Butterworth on 8/1/90 X** PC-Version: by Werner Keilholz on 10/19/90 X** (KEILHOLZ@CNVE.RRZE.UNI-ERLANGEN.DE) X*/ X X/* Standard Includes */ X#include <stdio.h> X#include <stdlib.h> X X/* Graphics Includes (TURBO C++) */ X#include <graphics.h> X X/* Includes for this project. */ X#include <swarm.h> X X/* This is needed for the kbhit function in TURBO C++ */ X#include <conio.h> X X X/* Main() X** process command line parameters, setup X stuff X*/ X Xmain(argc, argv) Xint argc; Xchar *argv[]; X X{ X /* variables used by the graphic */ X int errorcode; X int graphdriver = DETECT; X int graphmode; X X X /* These variables are used to analyze the command line parameters. */ X char option[80]; X extern int optind; X extern char *optarg; X int i; X X /* X printf("\n%d Arguments:\n\n",argc); X for (i=0; i<= argc; i++) X printf("Argument Nr. %d: = %s\n",i,argv[i]); X */ X X /* Check the command line. */ X X i=1; X X while (i < argc) X { X strcpy(option,argv[i]); X X i++; X X switch (option[0]) X { X case 'v': X verbose = TRUE; X break; X case 'r': X break; X case 'x': X xor = TRUE; X break; X case 'g': X break; X case 'b': X sscanf(option+1,"%d",&bees); X break; X case 'a': X sscanf(option+1,"%d",&bee_acc); X break; X case 's': X sscanf(option+1,"%d",&bee_vel); X break; X case 'A': X sscanf(option+1,"%d",&wasp_acc); X break; X case 'S': X sscanf(option+1,"%d",&wasp_vel); X break; X case 'd': X { X sscanf(option+1,"%d",&delay); X } X break; X case 'B': X sscanf(option+1,"%d",&border); X break; X case 'w': X sscanf(option+1,"%d",&wasp_color); X break; X case 'c': X sscanf(option+1,"%d",&bee_color); X break; X case 'C': X sscanf(option+1,"%d",&bg_color); X break; X case 'h': X case 'q': X case '?': X Usage(*argv); X break; X default: X { X printf("\nOption %s unknown !\n", argv[i-1]); X X HandleError("The command line parameters were incorrect.", X FATAL); X break; X } X } X } X X /* Display the arguments. */ X if (verbose) X { X printf("\nHere are the current settings...\n"); X if (xor) X printf("Trails are not erased.\n"); X else X printf("Trails are erased.\n"); X printf("There are %d bees.\n", bees); X printf("Bee acceleration is %d pixels 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 delay is %d millikeilholz.\n", X delay); X printf("The wasp can't go within %d pixels of the window edge.\n", X border); X if (!(wasp_color==0)) X printf("The wasp color is \"%d\"\n", wasp_color); X else X printf("The wasp color is (default)\n"); X if (!(bee_color==0)) X printf("The bee color is \"%d\"\n", bee_color); X else X printf("The bee color is (default)\n"); X if (!(bg_color==0)) X printf("The background color is \"%d\"\n", bg_color); X else X printf("The background color is (default)\n", bg_color); X X printf("\nHit a key to continue ...\n"); X getch(); X X } X X X winW = winH = winX = winY = 0; X X /* Open the display. */ X initgraph(&graphdriver, &graphmode,"\\tc\\bgi"); X errorcode = graphresult(); X X if (errorcode != grOk) X { X HandleError("Cannot open display.\n"); X exit(-1); X } X X /* Set the colors. */ X if (!(bg_color == 0)) setbkcolor(bg_color); X X /* Set up window parameters, create and map window if necessary */ X winW = getmaxx(); X winH = getmaxy(); X winX = 0; X winY = 0; X X X /* Animate the swarm. */ X Animate(); X X closegraph(); X X printf("\n SWARM by Jeff Butterworth and Werner Keilholz\n"); X printf("\n type SWARM h for options"); X Xreturn(0); X} X X X Xint Animate() 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 int FGcolor; X int BGcolor; 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(231) % (winW - 2*BORDER); X wy[0] = BORDER + random(231) % (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(231) % winW; X X(1,b) = X(0,b); X Y(0,b) = random(231) % winH; X Y(1,b) = Y(0,b); X xv[b] = RAND(7); X yv[b] = RAND(7); X } X X /* loop until key is pressed */ X while (!kbhit()) 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(231) % bees] += RAND(3); X yv[random(231) % 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) /* xor doesn't make sense on a PC (no root window,...) X therfore I slightly changed the meaning of this X switch :-) */ X { X if (init == FALSE) X { X if ((goodCoord(wx[1], wy[1])) && (goodCoord(wx[2],wy[2]))) X { X if (!(wasp_color == 0)) X setcolor(wasp_color); X line(wx[1], wy[1], wx[2], wy[2]); X } X } X if ((goodCoord(wx[0], wy[0])) && (goodCoord(wx[1],wy[1]))) X { X if (!(wasp_color == 0)) X setcolor(wasp_color); X line(wx[0], wy[0], wx[1], wy[1]); X } X } X else X { X if (init == FALSE) X FGcolor=getcolor(); X BGcolor=getbkcolor(); X setcolor(BGcolor); /* */ X if ((goodCoord(wx[1], wy[1])) && (goodCoord(wx[2],wy[2]))) X line(wx[1], wy[1], wx[2], wy[2]); /* erase */ X setcolor(FGcolor); /* */ X if ((goodCoord(wx[0], wy[0])) && (goodCoord(wx[1],wy[1]))) X { X if (!(wasp_color == 0)) X setcolor(wasp_color); X line(wx[0], wy[0], wx[1], wy[1]); X } X } X X /* Bees */ X if (xor) X { X if (init == FALSE) X { X setcolor(BGcolor); /* */ X DrawSegments(old_segs, bees); /* XOR */ X setcolor(FGcolor); /* */ X } X else X init = FALSE; X if (!(bee_color == 0)) X setcolor(bee_color); X DrawSegments(segs, bees); X } X else X { X if (init == FALSE) X { X setcolor(BGcolor); /* */ X DrawSegments(old_segs, bees); /* erase */ X setcolor(FGcolor); /* */ X } X X else X init = FALSE; X DrawSegments(segs,bees); X } X X X /* Clean up and shut down. X if (stop) X { X if (xor) X { X DrawSegments(segs, bees); X DrawLine(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(delay); X } X return(0); X} X X X/* nap X** X** put the process to sleep for a while X*/ X Xvoid nap(usec) Xint usec; X X{ Xint i; X Xfor (i=1; i<usec; i++); X X} X X Xvoid Usage(program) Xchar *program; X{ X X printf("swarm [options] where options are listed below\n", program); X printf(" ! no space between option and value; e.g.: swarm b30\n"); X printf("d delay delay between screen updates in millikeilholz\n"); X printf(" ( 0 <= d <= 32000 )\n"); X printf("x do not erase bees's and wasp's trails\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(" ( 0 <= d <= 65 )\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("v verbose\n"); X printf("h|q|? display this message\n"); X printf("\nPress any key to stop the insanity.\n"); X exit(0); X} X X Xvoid HandleError(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 X Xvoid DrawSegments(XSegment *segments, int bees) X X{ X int i; X X for (i=1; i<= bees; i++) X { X if ((goodCoord(segments[i].x1, segments[i].y1) ) && X (goodCoord(segments[i].x2, segments[i].y2) ) ) X line(segments[i].x1, segments[i].y1, segments[i].x2,segments[i].y2); X } X X} X Xint goodCoord(int x, int y) /* boolean */ X X/* In TURBO C++ we need to check the boundaries ... X drawing lines outside the viewport would mess X up the display */ X X{ Xif ( (x >0) && (x <= getmaxx()) & X (y >0) && (y <= getmaxy()) ) X return(true); Xelse X return(false); X X} X X END_OF_FILE if test 14177 -ne `wc -c <'swarm.c'`; then echo shar: \"'swarm.c'\" unpacked with wrong size! fi # end of 'swarm.c' fi if test -f 'swarm.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'swarm.h'\" else echo shar: Extracting \"'swarm.h'\" \(2704 characters\) sed "s/^X//" >'swarm.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 0 /* 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#define NULL 0 /* not predefined ??? &&& */ X X#define MaxBees 200 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) - (v/2)) /*random number around 0 */ X X/* Type Definitions */ X Xtypedef int Window; /* Nonsense &&& */ Xtypedef int Display; /* Nonsense &&& */ Xtypedef int GC; /* Nonsense &&& */ Xtypedef int Atom; /* Nonsense &&& */ Xtypedef Colormap; /* Nonsense &&& */ X X X 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 Xtypedef struct X{ X short x1; X short x2; X short y1; X short y2; X} XSegment; X Xenum boolean {false, true}; X X/* Function Prototypes */ Xvoid nap(); Xvoid Usage(); Xvoid HandleError(); Xlong GetColor(); Xvoid DrawSegments(XSegment *segments, int bees); Xint goodCoord(int x, int y); /* int = boolean ? */ X X/* Global Variables */ X X/* X related */ Xint winX, winY; Xunsigned int winW, winH; 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 */ Xint wasp_color = 0; Xint bee_color = 0; Xint bg_color = 0; Xchar stop = FALSE; Xint xor = FALSE; /* use GXxor if TRUE */ Xint verbose = FALSE; /* display settings if TRUE */ X END_OF_FILE if test 2704 -ne `wc -c <'swarm.h'`; then echo shar: \"'swarm.h'\" unpacked with wrong size! fi # end of 'swarm.h' fi echo shar: End of archive 1 \(of 1\). cp /dev/null ark1isdone MISSING="" for I in 1 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have the archive. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0