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