[comp.sources.x] v12i008: acm - X aerial combat simulation, Part03/09

riley@mipsdal.mips.com (Riley Rainey) (03/02/91)

Submitted-by: riley@mipsdal.mips.com (Riley Rainey)
Posting-number: Volume 12, Issue 8
Archive-name: acm/part03

#! /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 3 (of 9)."
# Contents:  acm/MANIFEST acm/README acm/V/lib/VBindColors.c
#   acm/V/lib/Vlib.h acm/V/test/app.c acm/fsim/acm.man
#   acm/fsim/aim9m.c acm/fsim/doEvents.c acm/fsim/doScale.c
#   acm/fsim/server.c
# Wrapped by riley@mipsdal on Thu Feb 14 10:09:18 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'acm/MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'acm/MANIFEST'\"
else
echo shar: Extracting \"'acm/MANIFEST'\" \(3444 characters\)
sed "s/^X//" >'acm/MANIFEST' <<'END_OF_FILE'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X acm                        1	
X acm/Imakefile              1	
X acm/MANIFEST               3	
X acm/Makefile               7	
X acm/README                 3	
X acm/V                      1	
X acm/V/Imakefile            1	
X acm/V/Makefile             7	
X acm/V/lib                  1	
X acm/V/lib/Imakefile        1	
X acm/V/lib/Makefile         5	
X acm/V/lib/VAllocColor.c    1	
X acm/V/lib/VBindColors.c    3	
X acm/V/lib/VClipPoly.c      2	
X acm/V/lib/VCloseVp.c       1	
X acm/V/lib/VCopyPoly.c      1	
X acm/V/lib/VCrPoints.c      1	
X acm/V/lib/VCrPoly.c        1	
X acm/V/lib/VCrossProd.c     1	
X acm/V/lib/VDispObjects.c   1	
X acm/V/lib/VDotProd.c       1	
X acm/V/lib/VDrawPoly.c      1	
X acm/V/lib/VDrawString.c    1	
X acm/V/lib/VExpBuffer.c     1	
X acm/V/lib/VEyeToScr.c      1	
X acm/V/lib/VFillPoly.c      1	
X acm/V/lib/VGetEyeSpace.c   2	
X acm/V/lib/VGetPlanes.c     1	
X acm/V/lib/VIdentMat.c      1	
X acm/V/lib/VMatDet.c        1	
X acm/V/lib/VMatInvert.c     1	
X acm/V/lib/VMatMult.c       1	
X acm/V/lib/VOpenVp.c        2	
X acm/V/lib/VPrintPoly.c     1	
X acm/V/lib/VReadObject.c    1	
X acm/V/lib/VResizeVp.c      1	
X acm/V/lib/VRotate.c        1	
X acm/V/lib/VTrans.c         1	
X acm/V/lib/VTransPoly.c     1	
X acm/V/lib/VWorldToScr.c    1	
X acm/V/lib/VWriteObject.c   1	
X acm/V/lib/Vlib.h           3	
X acm/V/lib/Vmalloc.c        1	
X acm/V/lib/strdup.c         1	
X acm/V/test                 1	
X acm/V/test/Imakefile       1	
X acm/V/test/Makefile        4	
X acm/V/test/animate.c       4	
X acm/V/test/app.c           3	
X acm/V/test/f               2	
X acm/V/test/f16             2	
X acm/V/test/fixf16.c        1	
X acm/V/test/fixmig.c        1	
X acm/V/test/fullrwy         5	
X acm/V/test/mig23           2	
X acm/V/test/rwy             5	
X acm/acm.def                1	
X acm/acmdoc.ps              9	
X acm/fsim                   1	
X acm/fsim/Imakefile         2	
X acm/fsim/Makefile          6	
X acm/fsim/V2tgif.c          1	
X acm/fsim/acm.c             2	
X acm/fsim/acm.man           3	
X acm/fsim/aim-9             1	
X acm/fsim/aim9m.c           3	
X acm/fsim/bullet            1	
X acm/fsim/damage.c          2	
X acm/fsim/damage.h          1	
X acm/fsim/doEvents.c        3	
X acm/fsim/doRadar.c         4	
X acm/fsim/doScale.c         3	
X acm/fsim/doViews.c         6	
X acm/fsim/droneCalc.c       1	
X acm/fsim/eng.xbm           2	
X acm/fsim/exp.xbm           2	
X acm/fsim/exp1.xbm          2	
X acm/fsim/f16               2	
X acm/fsim/flaps.c           2	
X acm/fsim/flaps0.xbm        1	
X acm/fsim/flaps1.xbm        2	
X acm/fsim/flaps2.xbm        1	
X acm/fsim/flaps3.xbm        1	
X acm/fsim/getStick.c        1	
X acm/fsim/header            1	
X acm/fsim/init.c            2	
X acm/fsim/m61a1.c           7	
X acm/fsim/manifest.h        1	
X acm/fsim/mig23             2	
X acm/fsim/missile.c         5	
X acm/fsim/missileCalc.c     2	
X acm/fsim/mtn               1	
X acm/fsim/newPlane.c        4	
X acm/fsim/newPlayer.c       6	
X acm/fsim/panel.c           2	
X acm/fsim/patchlevel.h      1	
X acm/fsim/placeCraft.c      1	
X acm/fsim/pm.c              8	
X acm/fsim/pm.h              6	
X acm/fsim/rwy               4	
X acm/fsim/rwy2              1	
X acm/fsim/scale.h           1	
X acm/fsim/server.c          3	
X acm/fsim/tower             1	
X acm/fsim/transpose.c       1	
X acm/fsim/update.c          1	
X acm/fsim/weapon.c          1	
X acm/install-objects        1	
END_OF_FILE
if test 3444 -ne `wc -c <'acm/MANIFEST'`; then
    echo shar: \"'acm/MANIFEST'\" unpacked with wrong size!
fi
# end of 'acm/MANIFEST'
fi
if test -f 'acm/README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'acm/README'\"
else
echo shar: Extracting \"'acm/README'\" \(5313 characters\)
sed "s/^X//" >'acm/README' <<'END_OF_FILE'
Xacm Flight Simulator version 2.0
X
XWhat is acm?
X------------
X
XAcm is a LAN-oriented, multiplayer aerial combat simulation.  My main design
Xobjective was to provide source code that could be easily compiled and
Xexecuted on a wide variety of platforms.  To that end, acm is written entirely
Xin C, exploiting the programming features of Unix, X11, and the BSD socket
Xinterface.
X
XPlayers engage in air to air combat against one another using heat seeking
Xmissiles and cannons.
X
XAcm exists as two programs.  The first, named "acm", is a small program
Xthat, when invoked, starts a flight session on a given workstation.  The
Xsecond component, named "acms", is a server process that manages the
Xmultiplayer environment.  It also manages the flight simulation and
Xdisplay management that is required.  Most players will prefer to run the
Xacms process on a back-end server system on their local area network.  Players
Xat client workstations can then invoke the acm program to begin play.
X
XI play acm using a server that is a Mips RC3240 (rated at roughly 18.5
XSPECmarks).  I get very adequate display performance using a Mips RS2030
Xcolor workstation (10.0 SPECmarks) or an NCD monochrome X terminal.  My
Xchoice of servers is probably overkill.  I suspect that an 10+ SPECmark
Xsystem could handle a typical mutiplayer load.
X
XThis is the second release of acm.  The original version has been ported
Xto a variety of Unix derivatives and system architectures.
X
XRiley Rainey
Xriley@mips.com
XJanuary 26, 1991
X
X
X
XWhat's different with revision 2.0:
X-----------------------------------
X
XThe flight simulation model has been substantially revamped.
X
XRudder controls have been added.
X
XMonochrome support has been added with the generous help of Glen Dudek
X(dudek@ksr.com).
X
XFilenames have been shortened, where required, to get along with System V
Xconventions.
X
XSubstantial corrections and enhancements to the portability of this code
Xwere provided by Johnathan Kamens (jik@Athena.MIT.EDU).  imake can now
Xbe used to build the entire product tree.
X
XSun-specific changes were provided by Dave Safford (auvsaff@auvsun.tamu.edu).
X
XA bug that prevented acm from operating with certain window managers
Xhas been corrected.
X
XLead Computing Optical Sight (LCOS) support has been added to the
Xcannon weapon display.  A reticle (sight) is displayed on the HUD, showing
Xa good aiming sight for the cannon.
X
XCannons will now inflict damage on other aircraft.
X
XAircraft can now be damaged, but remain airworthy.
X
X
X
XGENERAL NOTES
X-------------
X
XThis software is divided into two major parts: the 3-D graphics routines
Xand the flight simulator itself.  The 3-D stuff is contained in the V
Xdirectory.  V/lib holds the library itself.  V/test contains a program
Xthat can be used to test your port of the V library.
X
XFsim contains the remainder of the flight simulator. imake and make files
Xhave been provided.  The code has a Berkeley tilt to it in many
Xplaces, so people with hybrid OS's will probably want to lean that
Xdirection when selecting compiling and linking options.
X
XAcm binaries can be installed in your standard games directory.  In addition
Xto running "make install" to install the executables, you must run the
X"install-objects" script.
X
XThe acm server, acms, must currently be started manually.  It's intended
Xthat it will eventually be managed automatically by inetd, but that's
Xnot in the code yet.  I have access to a network that includes a 16+ SPECMark
Xserver and 12 to 18 SPECMark workstations (i.e. a MIPS 3240 along with
XMIPS 2030 and Magnum workstations) (translate SPECMarks into millions of
Xinstructions per second by whatever formula you like ..).  I generally 
Xrlogin to the 3240 and start the acms process on it and leave that xterm
Xwindow hanging around;  then, from another xterm window, I'll fire off
Xthe acm command that starts my flying session.  Other players enter the
Xgame by simply firing off an "acm servername" command.
X
XI'm not saying that acm is a particularly accurate flight simulator. I'm
Xnot an aero engineer, but I did spend a fair amount of time studying
Xseveral college-level texts on the subject while I was designing this
Xsoftware.  This probably doesn't resemble real-time flight simulators
Xtoo much but, again, that's not my line of work.  Comments and
Xsuggestions to improve this software are welcome.
X
XSeveral "features" in this revision of the software:
X
X	* landing gear is ignored.  Raise it, lower it; it's
X	  not handled by the software.
X
X	* flaps can be lowered at rediculously high speeds.
X
X	* you can fly through mountains.
X
X	* engines do not flame-out.  Fly really high (and fast enough)
X	  and you can just about get into orbit.  Non-afterburning
X	  engine performance does degrade as altitude increases, but
X	  afterburner performance gives the extra kick needed to fly
X	  much higher than you should be able to.
X
X
XCREDITS
X
XIn the original release, I overlooked several important credits.  The
Xinput routine at the heart of the acm server is based on code from xtrek
Xthat was written by Dan A. Dickey, he has provided some valuable help in
Ximproving the robustness of this code.  The 3-D routines were written by
Xme, but are based closely on two valuable articles from the March and
XApril 1981 issues of Byte Magazine titled "Three-Dimensional Computer
XGraphics" by Franklin C. Crow.
END_OF_FILE
if test 5313 -ne `wc -c <'acm/README'`; then
    echo shar: \"'acm/README'\" unpacked with wrong size!
fi
# end of 'acm/README'
fi
if test -f 'acm/V/lib/VBindColors.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'acm/V/lib/VBindColors.c'\"
else
echo shar: Extracting \"'acm/V/lib/VBindColors.c'\" \(4009 characters\)
sed "s/^X//" >'acm/V/lib/VBindColors.c' <<'END_OF_FILE'
X#include "Vlib.h"
X#include <math.h>
X
Xint	pmap (vec, n)
Xunsigned long	*vec;
Xint		n; {
X
X    static int itbl[] = {1, 2, 4, 8};
X    register int i, r=0;
X
X    for (i=0; i<4; ++i)
X	if (itbl[i] & n)
X	   r += vec[i];
X    return r;
X}
X
Xint VBindColors (v, background)
XViewport *v;
Xchar * background; {
X
X    register int i, j, k, n, c;
X    static   int parseComplete = 0;
X    unsigned int pixel;
X    VColor 	*p;
X    Display	*dpy;
X    XColor	colorSet[MAXPCOLORS];
X    unsigned long planemask[PLANES*2];
X    unsigned long pixels[1];
X
X
X    if (v->flags & VPMono)
X	return 0;
X
X    dpy = v->dpy;
X
X    v->cmap = DefaultColormap(dpy, DefaultScreen(dpy));
X
X/*
X *  If this is a color or greyscale pixmap, allocate color cells for each
X *  color, and then set up the Viewport for drawing.
X */
X
X    if (v->flags & VPPixmap) {
X
X	if (XParseColor(dpy, v->cmap, background, &colorSet[0]) == 0) {
X		fprintf (stderr, "Can't parse color %s\n", background);
X		return -1;
X        }
X	if (XAllocColor (dpy, v->cmap, &colorSet[0]) == 0) {
X		fprintf (stderr, "Not enough pixel space for all colors\n");
X		return -1;
X	}
X	v->aPixel[0] = colorSet[0].pixel;
X
X	for ((i=0, p=VColorList); p != (VColor *) 0; i++) {
X
X	    if (i > MAXPCOLORS) {
X	        fprintf (stderr, "Too many colors selected.\n");
X	        return -1;
X	    }
X
X	    if (XParseColor (dpy, v->cmap, p->color_name, &colorSet[i+1]) == 0) {
X	        fprintf (stderr, "Can't parse color %s\n", p->color_name);
X	        return -1;
X	    }
X	    p->xcolor = colorSet[i+1];
X
X	    if (XAllocColor (dpy, v->cmap, &colorSet[i+1]) == 0) {
X		fprintf (stderr, "Not enough pixel space for all colors\n");
X		return -1;
X	    }
X	    v->aPixel[i+1] = colorSet[i+1].pixel;
X	    p->index = i+1;
X	    p = p->next;
X	}
X
X	v->colors = i+1;
X	v->set = 0;
X	v->pixel = &(v->aPixel[0]);
X	v->mask = AllPlanes;
X
X	return 0;
X    }
X
X    n = PLANES;
X    c = (int) (pow(2.0, (double) n) + 0.01);
X
X
X    if (XAllocColorCells (dpy, v->cmap, False, planemask, n*2, pixels, 1) == 0) {
X        fprintf (stderr, "Cannot allocate color cells\n");
X        return -1;
X    }
X
X/*
X *  Parse background color
X */
X
X    if (/*parseComplete == 0*/ 1) {
X
X	if (XParseColor(dpy, v->cmap, background, &colorSet[0]) == 0) {
X	    fprintf (stderr, "Can't parse color %s\n", background);
X            return -1;
X        }
X
X/*
X *  Parse each color defined in the V Color List
X */
X
X	for ((i=0, p=VColorList); p != (VColor *) 0; i++) {
X	    if (i > c) {
X	        fprintf (stderr, "Too many colors selected.\n");
X	        return -1;
X	    }
X	    if (XParseColor (dpy, v->cmap, p->color_name, &colorSet[i+1]) == 0) {
X	        fprintf (stderr, "Can't parse color %s\n", p->color_name);
X	        return -1;
X	    }
X	    p->xcolor = colorSet[i+1];
X	    p->index = i+1;
X	    p = p->next;
X	}
X
X	parseComplete = 1;
X    }
X
X    v->colors = i+1;
X
X#ifdef DEBUG
X    fprintf (stderr, "%d colors defined in the V color list.\n", i);
X#endif
X
X/*
X *  PAY ATTENTION!
X *
X *  We will now create a two lists of XColors. Each will expose a particular
X *  drawing buffer (there are two drawing buffers created here).
X *  A drawing is exposed by passing one of these lists to the XSetColors
X *  procedure.
X *  We create a list by iterating through each possible combination of
X *  pixel values, based on the values returned in pixel and planemask.
X *  The pixel value is determined using a function called pmap.  Each pixel
X *  value is assigned the appropriate XColor.
X */
X
X    k = 0;
X    for (i=0; i<v->colors; ++i) {
X	pixel = v->aPixel[i] = pmap(&planemask[0], i) | pixels[0];
X	for (j=0; j<v->colors; ++j) {
X	    v->aColor[k] = colorSet[i];
X	    v->aColor[k++].pixel = pixel | pmap (&planemask[n], j);
X	}
X    }
X
X    v->aMask = pmap(&planemask[0], (c-1)) | pixels[0];
X
X    k = 0;
X    for (i=0; i<v->colors; ++i) {
X	pixel = v->bPixel[i] = pmap(&planemask[n], i) | pixels[0];
X	for (j=0; j<v->colors; ++j) {
X	    v->bColor[k] = colorSet[i];
X	    v->bColor[k++].pixel = pixel | pmap(&planemask[0], j);
X	}
X    }
X
X    v->bMask = pmap(&planemask[n], (c-1)) | pixels[0];
X
X    return 0;
X}
END_OF_FILE
if test 4009 -ne `wc -c <'acm/V/lib/VBindColors.c'`; then
    echo shar: \"'acm/V/lib/VBindColors.c'\" unpacked with wrong size!
fi
# end of 'acm/V/lib/VBindColors.c'
fi
if test -f 'acm/V/lib/Vlib.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'acm/V/lib/Vlib.h'\"
else
echo shar: Extracting \"'acm/V/lib/Vlib.h'\" \(4364 characters\)
sed "s/^X//" >'acm/V/lib/Vlib.h' <<'END_OF_FILE'
X#ifndef __Vlib
X#define __Vlib
X
X#define VmaxVP	32		/* max # of vertices in a polygon */
X
X#define MAXCOLORS 8		/* max number of colors available */
X				/* when double buffering */
X
X#define MAXPCOLORS	256	/* maximum colors available when */
X				/* using a pixmap */
X
X#if (MAXCOLORS==4)
X#define PLANES 2
X#endif
X#if (MAXCOLORS==8)
X#define PLANES 3
X#endif
X#if (MAXCOLORS==16)
X#define PLANES 4
X#endif
X
X#include <X11/Xlib.h>
X#include <stdio.h>
X#include <memory.h>
X
Xtypedef struct _vcolor {
X	char	*color_name;	/* text name */
X	short	index;		/* index into pixel value table */
X	XColor	xcolor;		/* representation of this color */
X	struct _vcolor *next;
X	} VColor;
X
Xtypedef struct {
X	double	x, y, z;	/* A point or vector in 3-space */
X	} VPoint;
X
Xtypedef struct {
X	short	numVtces;	/* vertex count */
X	VPoint	*vertex;	/* pointer to array of vertices */
X	VColor	*color;		/* pointer to color descriptor */
X	} VPolygon;
X
Xtypedef struct {
X	char	*name;		/* object name */
X	int	numPolys;	/* polygon count */
X	VPolygon **polygon;	/* pointer to array of polygon pointers */
X	} VObject;
X
Xtypedef struct {
X	double	m[4][4];
X	} VMatrix;
X
Xtypedef struct {
X	unsigned long flags;	/* viewport flags */
X	VMatrix	  eyeSpace;	/* transforms from world to eyeSpace system */
X	VPolygon  *clipPoly;	/* planes to clip viewed polygons */
X	double	  units;	/* world units expressed in meters */
X	double	  dist;		/* distance in units from eye to screen */
X	double	  xres;		/* x screen resolution in dots per unit */
X	double	  yres;		/* y screen resolution in dots per unit */
X	int	  width;	/* width of window in dots */
X	int	  height;	/* height of window in dots */
X	VPoint	  Middl;	/* center of window */
X	VPoint	  Scale;	/* scaling factor */
X	Display	  *dpy;		/* Display associated with this viewport */
X	int	  screen;	/* X screen number */
X	Window	  win;
X	Pixmap	  monoPixmap;	/* Pixmap used to buffer drawing */
X
X	int	  colors;	/* color count */
X	int	  set;		/* id of buffer currently in use */
X	unsigned long mask;	/* current plane mask */
X	unsigned long aMask, bMask;
X	unsigned long *pixel;	/* current pixel drawing values */
X	unsigned long aPixel[MAXPCOLORS];
X	unsigned long bPixel[MAXCOLORS];
X	XColor	  aColor[MAXCOLORS*MAXCOLORS];
X	XColor	  bColor[MAXCOLORS*MAXCOLORS];
X	Colormap  cmap;
X	} Viewport;
X
X#define VGetPolygonPixel(p)		(p->color->xcolor.pixel)
X#define VLookupViewportColor(v,n)	(v->pixel[n])
X#define VGetViewportMask(v) 		(v->mask)
X
X/*
X *  Globals
X */
X
XVColor   *VColorList;		/* list of colors needed for drawing */
Xint	 usePixmaps;		/* set to one to use Pixmaps on color
X					viewports */
X
X/*
X *  V macros and function prototypes
X */
X
X#define VDestroyPoints(a)	free((char *) a)
X#define VDestroyPolygon(a)	{free((char *) a->vertex); free((char *) a);}
X
XViewport *VOpenViewport(); 	/* (Display *, .. ) */
Xvoid	 VResizeViewport();	/* (Viewport *, ... ) */
Xvoid	 VCloseViewport();	/* (Viewport *) */
XVPolygon *VCreatePolygon();	/* (VPoint *, int, VColor *) */
XVPolygon *VCopyPolygon();	/* (VPolygon *) */
XVPolygon *VClipPolygon();	/* (VPolygon *, VPoint) */
XVPoint	 *VCreatePoints();	/* (int) */
XVColor	 *VAllocColor();	/* (char *) */
Xint	 VBindColors();		/* (Viewport *, char *) */
Xvoid	 VExposeBuffer();	/* (Viewport *, GC) */
XVObject	 *VReadObject();	/* (FILE *) */
Xint	 VWriteObject();	/* (FILE *, VObject *) */
XVMatrix	 *VRotate();		/* (VMatrix *, int) */
XVMatrix  *VTranslate();		/* (VMatrix *, double, double, double) */
XVMatrix  *VTranslatePoint();	/* (VMatrix *, VPoint) */
Xdouble	 VMatrixDeterminant();	/* (VMatrix *) */
XVMatrix  *VMatrixInvert();	/* (VMatrix *, VMatrix *) */
Xvoid	 VTransform();		/* (VPoint *, VMatrix *, VPoint *) */
Xdouble	 VDotProd();		/* (Vpoint *, VPoint *) */
Xvoid	 VCrossProd();		/* (Vpoint *, VPoint *, VPoint *) */
Xchar	 *Vmalloc();		/* (int) */
Xint	 VEyeToScreen();
Xint	 VWorldToScreen();
X
X/*
X *  Viewport flags (must be changed manually after VOpenViewport for now)
X */
X
X#define	VPClip		1	/* polygons should be clipped before drawing */
X#define VPPerspective	2	/* Z coordinate used for depth information */
X#define VPMono		4	/* Monochrome environment */
X#define VPPixmap	8	/* Use color Pixmap rather than double
X					buffering */
X
X/*
X *  VRotate options
X */
X
X#define XRotation	1	/* rotate about X axis */
X#define YRotation	2	/* rotate about Y axis */
X#define ZRotation	3	/* rotate about Z axis */
X
X#ifndef SYSV
Xextern char *strdup();
X#endif
X
X#endif
END_OF_FILE
if test 4364 -ne `wc -c <'acm/V/lib/Vlib.h'`; then
    echo shar: \"'acm/V/lib/Vlib.h'\" unpacked with wrong size!
fi
# end of 'acm/V/lib/Vlib.h'
fi
if test -f 'acm/V/test/app.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'acm/V/test/app.c'\"
else
echo shar: Extracting \"'acm/V/test/app.c'\" \(5373 characters\)
sed "s/^X//" >'acm/V/test/app.c' <<'END_OF_FILE'
X#include "../lib/Vlib.h"
X#include <X11/Xutil.h>
X#include <math.h>
X
X#define VIEW1
X
Xextern Display  *dpy;
Xextern Window   win;
Xextern GC       curGC;
Xextern XSizeHints xsh;
Xextern int	mono;
X
XVPolygon *poly[1024];
X
Xvoid placeObject (obj, loc, roll, pitch, yaw, poly, cnt)
XVObject *obj;
XVPoint  loc;
Xdouble roll;
Xdouble pitch;
Xdouble yaw;
XVPolygon **poly;
Xint	 *cnt; {
X
X	int	 i, j, k;
X	VPoint	 *q, tmp;
X	VMatrix	 mtx;
X
X	j = *cnt;
X
X	VIdentMatrix (&mtx);
X	if (roll != 0.0)
X		VRotate (&mtx, XRotation, roll);
X	if (pitch != 0.0)
X		VRotate (&mtx, YRotation, pitch);
X	if (yaw != 0.0)
X		VRotate (&mtx, ZRotation, yaw);
X	VTranslatePoint (&mtx, loc);
X
X	for (i=0; i<obj->numPolys; ++i) {
X
X		if (poly[j] != (VPolygon *) NULL)
X			VDestroyPolygon (poly[j]);
X
X		poly[j] = VCopyPolygon(obj->polygon[i]);
X		for ((k=0, q=poly[j]->vertex); k<poly[j]->numVtces; (++k, ++q)) {
X			VTransform(q, &mtx, &tmp);
X			*q = tmp;
X		}
X		++j;
X	}
X
X	*cnt = j;
X}
X
Xapp(background)
Xchar *background; {
X
X	int	i, cnt, black;
X	unsigned int j, curPixel = 0;
X	char	*str;
X	FILE	*file;
X	VObject	*obj, *ftr, *mig;
X	VPoint	viewPt, centerInt, up, ftrLoc, ftrLoc2, ftrLoc3, migLoc1, migLoc2;
X	Viewport *v;
X	double	dist, p, migV, v1, a, migRoll;
X	double	updateRate = 5.0;
X
X	str = "fullrwy";
X
X	if ((file = fopen(str, "r")) == (FILE *) NULL) {
X		perror ("Cannot open object file");
X		exit (1);
X	}
X
X	if ((obj = VReadObject(file)) == (VObject *) NULL) {
X		fprintf (stderr, "Error reading the object definition.\n");
X		exit (1);
X	}
X
X	fclose (file);
X
X	str = "f16";
X
X	if ((file = fopen(str, "r")) == (FILE *) NULL) {
X		perror ("Cannot open object file");
X		exit (1);
X	}
X
X	if ((ftr = VReadObject(file)) == (VObject *) NULL) {
X		fprintf (stderr, "Error reading the object definition.\n");
X		exit (1);
X	}
X
X	fclose (file);
X	
X
X	str = "mig23";
X
X	if ((file = fopen(str, "r")) == (FILE *) NULL) {
X		perror ("Cannot open object file");
X		exit (1);
X	}
X
X	if ((mig = VReadObject(file)) == (VObject *) NULL) {
X		fprintf (stderr, "Error reading the object definition.\n");
X		exit (1);
X	}
X
X	fclose (file);
X	
X	usePixmaps = 0;
X
X	v = VOpenViewport (dpy, 0, win, 12 * 25.4 / 1000.0, 1.5, 1.0, xsh.width,
X		xsh.height);
X
X	if (VBindColors (v, background) < 0) {
X		fprintf (stderr, "Error in binding colors.\n");
X		exit (1);
X	}
X	VExposeBuffer (v, curGC);
X
X
X	ftrLoc.x = 80.0;
X	ftrLoc.y = -110.0;
X	ftrLoc.z = -7.0;
X
X	ftrLoc2.x = 475.0;
X	ftrLoc2.y = 3.7;
X	ftrLoc2.z = -7.0;
X
X	migLoc1.z = -310.0;
X	migLoc2.z = -320.0;
X	migV = 370.0 / 3600.0 * 5280.0 / updateRate;	/* mig speed in fps */
X	migV = migV / (2500.0 * 3.14 * 2.0); /* mig speed in rad/update */
X	migRoll = 28.0 * 3.14 / 180.0;
X	a = 90.0 * 3.14 / 180.0;
X
X	v1 = 130.0 / 3600.0 * 5280.0 / updateRate;
X
X	centerInt.x = 80.0;
X	centerInt.y = -90.0;
X	centerInt.z = -6.0;
X
X	dist = -10000.0; p = 0;
X
X	while (1) {
X
X		ftrLoc3.x = dist+150.0;
X		ftrLoc3.y = -15.0;
X		ftrLoc3.z = (dist+150.0) * 50.0 / 1000.0 - 40.0;
X		if (ftrLoc3.z > -13.0)
X			ftrLoc3.z = -13.0;
X		viewPt.x = dist;
X		viewPt.y = 15.0;
X		viewPt.z = dist * 50.0 / 1000.0 - 50.0;
X		if (viewPt.z > -13.0)
X			viewPt.z = -13.0;
X		up = viewPt;
X		up.z = up.z - 1.0;
X		if (viewPt.z < -14.0)
X			up.y = up.y + 0.1 * sin(p);
X		p = p + 0.03;
X		dist = dist + v1;
X		if (dist > 10000.0)
X			exit (1);
X
X		migLoc1.x = 0.0 + 2200.0 * cos (a);
X		migLoc1.y = -800.0 + 2200.0 * sin (a);
X		migLoc2.x = 0.0 + 2225.0 * cos (a-0.04);
X		migLoc2.y = -800.0 + 2225.0 * sin (a-0.04);
X		a = a + migV;
X
X/*
X *  Now create a vector containing all polygons from the objects.
X */
X
X	for (i=0; i<obj->numPolys; ++i) {
X		if (poly[i] != (VPolygon *) NULL)
X			VDestroyPolygon(poly[i]);
X		poly[i] = VCopyPolygon(obj->polygon[i]);
X	}
X	cnt = obj->numPolys;
X#ifndef VIEW3
X	placeObject (ftr, ftrLoc, 0.0, 0.0, 90.0*3.14/180.0, &poly[0], &cnt);
X#endif
X	placeObject (ftr, ftrLoc2, 0.0, 0.0, -3.0*3.14/180.0, &poly[0], &cnt);
X	placeObject (ftr, ftrLoc3, 0.0, -11.0*3.14/180.0, 0.0, &poly[0], &cnt);
X#ifndef VIEW1
X	placeObject (ftr, viewPt, 0.0, -11.0*3.14/180.0, 0.0, &poly[0], &cnt);
X#endif
X	placeObject (mig, migLoc1, migRoll, 0.0, a+90.0*3.14/180.0, &poly[0], &cnt);
X#ifndef VIEW2
X	placeObject (mig, migLoc2, migRoll, 0.0, a+90.0*3.14/180.0, &poly[0], &cnt);
X#endif
X
X/*
X *  Calculate eye space information based on our current viewpoint.
X */
X
X#ifdef VIEW1
X	VGetEyeSpace (v, viewPt, centerInt, up);
X#endif
X#ifdef VIEW2
X	up = migLoc2;
X	up.z = up.z - 1.0;
X	VGetEyeSpace (v, migLoc2, viewPt, up);
X#endif
X#ifdef VIEW3
X	up = ftrLoc;
X	up.z = up.z - 1.0;
X	VGetEyeSpace (v, ftrLoc, viewPt, up);
X#endif
X
X	black = BlackPixel(dpy, 0);
X
X
X/*
X *  First clip, then draw each polygon.
X */
X
X	for (i=0; i<cnt; ++i) {
X
X		if (mono)
X			XSetForeground (dpy, curGC, black);
X
X		VTransformPolygon (poly[i], &(v->eyeSpace));
X		poly[i] = VClipPolygon(poly[i], v->clipPoly);
X		if (poly[i]) {
X		    if (mono == 0 && curPixel != (j=v->pixel[poly[i]->color->index])) {
X			XSetForeground (dpy, curGC, j);
X			curPixel = j;
X		    }
X		    if (mono)
X		        VDrawPolygon (v, win, curGC, poly[i]);
X		    else
X		        VFillPolygon (v, win, curGC, poly[i]);
X		}
X
X	}
X
X	VExposeBuffer (v, curGC);
X
X/*
X * Erase the un-displayed planes.
X */
X
X	if (mono == 0) {
X		curPixel = *(v->pixel);
X        	XSetForeground (dpy, curGC, curPixel);
X		if (usePixmaps == 1)
X        	XFillRectangle (dpy, v->monoPixmap, curGC, 0, 0, xsh.width, xsh.height);
X		else
X        	XFillRectangle (dpy, win, curGC, 0, 0, xsh.width, xsh.height);
X	}
X
X        }
X
X}
END_OF_FILE
if test 5373 -ne `wc -c <'acm/V/test/app.c'`; then
    echo shar: \"'acm/V/test/app.c'\" unpacked with wrong size!
fi
# end of 'acm/V/test/app.c'
fi
if test -f 'acm/fsim/acm.man' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'acm/fsim/acm.man'\"
else
echo shar: Extracting \"'acm/fsim/acm.man'\" \(6366 characters\)
sed "s/^X//" >'acm/fsim/acm.man' <<'END_OF_FILE'
X.TH ACM l "4 September 1990"
X.SH NAME
Xacm \- an aerial combat simulator for X
X.SH SYNOPSIS
X.B acm
X[
X.I server
X] [
X.I options
X]  
X.LP
X
X.SH DESCRIPTION
X
Xacm is an air combat simulator that runs under the X window system.  Up to
Xeight players can engage in simultaneous air combat.  Players fly jet aircraft
Xequipped with radar, heat seeking missiles and cannon.
X
XThe program, "acm", calls a deamon already running on the specified
Xserver_hostname and requests that your enter the game.  The shell variable
X"ACMSERVER" optionally specifies the name of the server host.
X
XEach player flies something close to either an F-16C Falcon or MIG-23.
X
X
X.SH USAGE REFERENCE
X
XTo begin play, the flight simulator server must be started manually on a
Xsystem that is accessible to all players. 
X
XThe following command line will do that:
X
X.LP
X.TP
X	% acms
X
XThe following command line options are recognized by acm:
X.LP
X.TP
X-geometry geometry_spec
XAn X compatible window geometry specification
X.TP
X-team <1 or 2>
XSpecifies the starting airfield.  Airfields are about 50 nm apart.
XTeam 1 flies F-16's, team 2 flies MIG-23's.
X
X
X.SH HOW TO TAKE-OFF
X
X
XYour mouse is the control stick.  The neutral position is the center of your
Xview display -- denoted by the dot in the center of your heads-up-display (HUD).
XMoving the mouse away from you pitches the plane down, moving it back
Xpitches the plane up.  Left and right inputs roll the aircraft in the
Xcorresponding direction.  On the ground at speeds up to 100 kts, nose
Xwheel steering guides the aircraft.
X
XTo take off for the first time, select 20 degrees of flaps (press H twice),
Xthen press the full throttle key (the 4 key on the main keyboard).  Keep the
Xmouse in the neutral position until you are moving at about 140 kts, then pull
Xthe mouse about two-thirds of the way down the view window.  You should pitch
Xup and lift off the ground fairly easily.  Gradually move the stick closer
Xto the neutral position and let your airspeed build -- don't move it back to
Xneutral too quickly or you will end up back on the ground again!  As your
Xairspeed passes about 250 kts, raise the flaps (press Y twice). Congratulations,
Xyou're flying a multi-million dollar jet.
X
X
X.SH ENGINE CONTROLS
X
X
XThe following keys control your engine thrust:
X
X.LP
X	4	Full Power
X.LP
X	3	Increase Power (about 2 percent)
X.LP
X	2	Decrease Power (about the same amount)
X.LP
X	1	Idle Power
X.LP
X	A	Toggle Afterburner
X
XYour engine gauge displays the power that you are generating.  Below that,
Xyou have displays showing your total fuel remaining as well as your current
Xfuel consumption rate.  The afterburner uses fuel at an amazing rate; use it
Xwisely.
X
X
X.SH LOOKING AROUND
X
X
XThe keys of the numeric keypad control which direction you're looking outside
Xof the cockpit:
X
X.LP
X		8 Forward
X.LP	
X	4 Left	5 Up	6 Right
X.LP
X		2 Aft
X
XIt pays to look around when you're in a combat environment.  Your chances
Xof staying alive increase remarkably.
X
X
X.SH THE HEADS UP DISPLAY (HUD)
X
X
XOn the left side of the HUD is a ladder showing your current airspeed in
Xnautical miles per hour (it displays true airspeed).  Above that, in the
Xupper left corner, is a G-meter.  
X
XThe right ladder shows altitude; above that
Xis a readout of your current angle-of-attack in degrees ("a=X.X").  
XYour
Xjet will stall at a 30 degrees positive angle of attack and negative 16 
Xdegrees. 
X
XThe airplane symbol (something like "-O-") shows the direction
Xthat the relative wind is coming from.  The relative wind combines your
Xcurrent angles of attack and sideslip.  A ladder in the center of the
XHUD show your aircraft's current attitude. 
X
XThe lower, horizontal ladder shows your current heading.  Discretes in the
Xlower left-hand corner show the state of your weapons systems.  Slightly
Xabove them is a readout of your current thrust percentage as well as the
Xstate of your engine's afterburner -- the "AB" symbol means the
Xafterburner is on.
X
X
X.SH USING YOUR RADAR DISPLAY
X
X
XThe radar system has a field of view of 130 degrees vertically and side-to-side.
XRadar automatically locks onto the closest threat in its field of view.  A
Xlocked target is displayed as a solid block.  Other hostile targets are 
Xdisplayed as hollow squares.
X
XTargetting information is displayed in the lower right corner of the display.
XThe top number is the heading of the locked target, the next number is the
Xrelative heading you should steer to intercept the target (displayed as
X"ddd R", and the third number is the rate that you are closing with this
Xtarget, expressed in knots.
X
XYou can lock onto other targets by pressing the target designator key (Q).
X
X
X.SH WHO'S GUNNING FOR ME?
X
X
XRadar sets that are tracking your aircraft can be detected.  Your Threat
XEarly Warning System (TEWS) display warns you of potential threats.  This
Xcircular display shows the relative direction of radars (other aircraft)
Xthat are looking at you.
X
X.SH ARMAMENTS
X
X
XYour aircraft is equipped with heat-seeking missiles and a 20 millimeter
Xcannon.  Weapon information is displayed in the lower left-hand corner of
Xyour HUD.  Different weapons may be selected by pressing mouse button 3.
X
XThe missiles are patterned after U.S. AIM-9M Sidewinders.  They can
Xdetect infared (IR) targets at any aspect (not just from the rear).  Their
Xrange varies dramatically with the altitude and closure rate.  The
Xmissile subsystem couples with your radar set to provide time-to-impact
Xinformation when AIM-9's are selected.
X
X
X.SH EXAMPLES
X
X acm bismarck 
X
X acm bismarck -geometry 1000x500
X
X.SH KEYBOARD COMMAND LIST
X
XStick and Rudder Controls
X
X.LP
XThe Mouse if your stick.  It controls pitch and roll.
X.LP
XZ -- Rudder Left
X.LP
XC -- Rudder Right
X.LP
XX -- Center the Rudder
X
X
X
XEngine Controls
X
X.LP
X4 -- Full Power
X.LP
X3 -- Increase Power
X.LP
X2 -- Decrease Power
X.LP
X1 -- Idle
X.LP
XA -- Toggle Afterburner State
X
X
X
XRadar Controls
X
X.LP
XR -- Toggle Radar State (On/Standby)
X.LP
XQ -- Target Designator
X
X
X
XFlaps
X
X.LP
XH -- Extend 10 degrees
X.LP
XY -- Retract 10 degrees
X
X
X
XSpeed Brakes
X
X.LP
XS -- Extend
X.LP
XW -- Retract
X
X
XWeapon Controls
X
X.LP
XMouse Button 2 -- Fire the selected weapon
X.LP
XMouse Button 3 -- Select another weapon
X
X
XOther Controls
X
X.LP
XP -- Self-Destruct (Quit the game)
X.LP
XL -- Launch a target drone
X
X
X
XView Controls (Numeric Keypad)
X
X.LP
X8 -- Forward
X.LP
X2 -- Aft
X.LP
X4 -- Left
X.LP
X6 -- Right
X.LP
X5 -- Up
X
X
X.SH AUTHOR
XRiley Rainey, riley@mips.com
END_OF_FILE
if test 6366 -ne `wc -c <'acm/fsim/acm.man'`; then
    echo shar: \"'acm/fsim/acm.man'\" unpacked with wrong size!
fi
# end of 'acm/fsim/acm.man'
fi
if test -f 'acm/fsim/aim9m.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'acm/fsim/aim9m.c'\"
else
echo shar: Extracting \"'acm/fsim/aim9m.c'\" \(4304 characters\)
sed "s/^X//" >'acm/fsim/aim9m.c' <<'END_OF_FILE'
X/*
X *	xflight : an aerial combat simulator for X
X *
X *	Written by Riley Rainey,  riley@mips.com
X *
X *	Permission to use, copy, modify and distribute (without charge) this
X *	software, documentation, images, etc. is granted, provided that this 
X *	comment and the author's name is retained.
X *
X */
X 
X#include "pm.h"
X#include <stdio.h>
X#include <string.h>
X#include <math.h>
X
Xint select_aim9m();
Xint display_aim9m();
Xint update_aim9m();
Xint fire_aim9m();
Xint getIRTarget();
Xextern int fireMissile ();
Xextern void createMissileEyeSpace();
Xextern FILE * acm_fopen ();
X
XweaponDesc aim9mDesc = {
X	WK_AIM9M,
X	select_aim9m,		/* select */
X	update_aim9m,		/* update */
X	display_aim9m,		/* display procedure */
X	fire_aim9m,		/* fire */
X	(int (*)()) NULL,	/* fire button release */
X	};
X
Xint	hasFired[MAXPLAYERS];
X
X/*
X *  aim9m selection function
X *
X *  A selection function normally determines whether there are any weapons
X *  of this type on-board.  If so, and the weapon system is functional
X *  (in other words, undamaged) then return 1; otherwise return 0.
X */
X
X/*ARGSUSED*/
Xint select_aim9m (c)
Xcraft *c; {
X
X	hasFired[c->index] = 0;
X	return 1;
X
X}
X
X/*ARGSUSED*/
Xint update_aim9m (c)
Xcraft *c; {
X
X	if (hasFired[c->index]) {
X		fireMissile (c);
X		hasFired[c->index] = 0;
X	}
X}
X
X/*ARGSUSED*/
Xint fire_aim9m (c)
Xcraft *c; {
X
X	hasFired[c->index] = 1;
X}
X
X/*
X * aim9m display function
X *
X *  Update the HUD display strings associated with this weapon system.
X */
X
X/*ARGSUSED*/
Xint display_aim9m (c, w, u)
Xcraft *c;
XcraftType *w;
Xviewer *u; {
X
X	char	s[16];
X	double	d, a1, v, r, root1, root2, n, t;
X	VPoint	tmp;
X	VMatrix	m;
X	int	target, count;
X
X	count = 8;
X
X	sprintf (s, "%d AIM-9M", count);
X	strcpy (c->leftHUD[1], s);
X
X	v = mag (c->Cg);
X	a1 = (w->maxThrust - 0.5 * c->rho * w->CDOrigin * v * v)
X		/ (w->emptyWeight + w->maxFuel) * a;
X
X	if (c->curRadarTarget >= 0 && a1 >= 0.0) {
X
X	d = c->targetDistance;
X	r = c->targetClosure;
X
X	n = 4.0 * d / a1 + (r * r) / (a1 * a1);
X	if (n > 0) {
X		n = sqrt (n);
X		root1 = (- r / a + n) / 2.0;
X		root2 = (- r / a - n) / 2.0;
X		if (root1 >= 0.0)
X			if (root2 >= 0.0)
X				if (root1 < root2)
X					t = root1;
X				else
X					t = root2;
X			else
X				t = root1;
X		else if (root2 >= 0.0)
X			t = root2;
X		else
X			t = -1.0;
X	}
X	else
X		t = -1.0;
X	}
X
X	else
X		t = -1.0;
X
X/*
X *  See if the missiles can lock onto any target.
X */
X
X	if (count > 0) {
X		createMissileEyeSpace (c, &m);
X		target = getIRTarget (c, &m, &tmp);
X	}
X	else
X		target = -1;
X
X	if (target >= 0 && t <= 15.0)
X		sprintf (s, "LOCKED   %d", (int)(t+0.5));
X	else if (t < 0.0)
X		sprintf (s, "ARM      --");
X	else if (t <= 15.0)
X		sprintf (s, "IN RANGE %d", (int)(t+0.5));
X	else 
X		sprintf (s, "ARM      %d", (int)(t+0.5));
X
X	strcpy (c->leftHUD[0], s);
X
X	strcpy (c->leftHUD[2], "");
X
X	return(0);
X}
X
Xextern craftType * newCraft ();
X
Xvoid initaim9()
X{
X
X	craftType	*c;
X	FILE    	*f;
X
X	c = newCraft();
X	c->name = strdup("aim-9m");
X
X	wtbl[0] = aim9mDesc;
X	wtbl[0].w = c;
X
X	c->CLOrigin = 0.0;
X	c->CLSlope = 4.41235;
X	c->CLNegStall = -15.0 * pi / 180.0;
X	c->CLPosStall =  15.0 * pi / 180.0;
X
X	c->CDOrigin = 0.1963494;	/* 4" radius of body */
X	c->CDFactor = -2.56694;
X	c->CDPhase = 0.0;
X
X	c->CDBOrigin = 0.0;
X	c->CDBFactor = 0.0;
X	c->CDBPhase = 0.0;
X
X	c->CMOrigin = 0.0;
X	c->CMFactor = -0.75;
X
X	c->CNOrigin = 0.0;
X	c->CNFactor = -0.75;
X
X	VIdentMatrix(&(c->I));
X	c->I.m[0][0] =  0.0;
X	c->I.m[1][1] = 0.0;
X	c->I.m[2][2] = 0.0;
X	c->LDamp =  700000.0;
X	c->MDamp = 1000000.0;
X	c->NDamp = 1000000.0;
X	c->cmSlope = -1.88;
X	c->cmFactor = -1.00;
X	c->cnSlope = 1.00;
X	c->cnFactor = 0.50;
X	c->betaStall = 15.0 * pi / 180.0;
X
X	c->wingS = 1.0;
X
X/*
X *  Assume 150.0 lbs of weight is fuel and that it burns for 20 seconds.
X *  That yields a fuel burn rate of 7.5 lbs/second.
X */
X
X	c->emptyWeight = 40.0;
X	c->maxFuel = 150.0;
X	c->maxThrust = 791.0;
X	c->spFuelConsump = 34.134;
X
X/*
X *  Three second arming delay
X */
X
X	c->armDelay = 3.0;
X
X	c->groundingPoint.x = 0.0;
X	c->groundingPoint.y = 0.0;
X	c->groundingPoint.z = 0.0;
X
X	c->viewPoint.x = 0.0;
X	c->viewPoint.y = 0.0;
X	c->viewPoint.z = 0.0;
X
X	c->crashC = 1.0;
X
X	c->muStatic = 0.0;
X	c->muKinetic = 0.0;
X	c->muBStatic = 0.0;
X	c->muBKinetic = 0.0;
X
X	c->maxNWDef = 0.0;
X	c->NWIncr = 0.0;
X	c->maxNWS = 0.0;
X	c->gearD1 = 0.0;
X	c->gearD2 = 0.0;
X
X	f = acm_fopen ("aim-9", "r");
X	c->object = VReadObject(f);
X	fclose (f);
X
X}
END_OF_FILE
if test 4304 -ne `wc -c <'acm/fsim/aim9m.c'`; then
    echo shar: \"'acm/fsim/aim9m.c'\" unpacked with wrong size!
fi
# end of 'acm/fsim/aim9m.c'
fi
if test -f 'acm/fsim/doEvents.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'acm/fsim/doEvents.c'\"
else
echo shar: Extracting \"'acm/fsim/doEvents.c'\" \(5451 characters\)
sed "s/^X//" >'acm/fsim/doEvents.c' <<'END_OF_FILE'
X/*
X *	xflight : an aerial combat simulator for X
X *
X *	Written by Riley Rainey,  riley@mips.com
X *
X *	Permission to use, copy, modify and distribute (without charge) this
X *	software, documentation, images, etc. is granted, provided that this 
X *	comment and the author's name is retained.
X *
X */
X 
X#include "pm.h"
X#include <X11/Xutil.h>
X#include <X11/keysym.h>
X
X#define MAX_MAPPED_STRING_LEN	10
X#define MAX_POPUP_STRING_LEN	40
X
Xextern int cur;
X
Xvoid doEvents(c)
Xcraft *c; 
X{
X
X	XEvent		ev;
X	viewer		*u;
X	int		player;
X	double		scale;
X
X/*
X *  Process events for each player and any "back seaters"
X */
X
X	player = 1;
X	for (u=c->vl; u != (viewer *) NULL; u=u->next) {
X
X
X#define mask 	(-1L)
X
X		if (cur % REDRAW_EVERY == 0)
X			getStick (c, u);
X
X		while (XEventsQueued(u->dpy, QueuedAlready)) {
X
X			XWindowEvent (u->dpy, u->win, mask, &ev);
X
X			switch (ev.type) {
X
X			case KeyPress:
X				if (doKeyEvent (c, u, &ev, player) < 0)
X					return;
X				break;
X
X			case ButtonPress:
X				if (doButtonEvent (c, u, &ev, player) < 0)
X					return;
X				break;
X
X			case ButtonRelease:
X				if (doButtonReleaseEvent (c, u, &ev, player) < 0)
X					return;
X				break;
X
X			case ConfigureNotify:
X				scale = (double) ev.xconfigure.height /
X					(double) FS_WINDOW_HEIGHT;
X				u->width = ev.xconfigure.width;
X				u->height = ev.xconfigure.height;
X				u->height = u->height * VIEW_WINDOW_HEIGHT /
X					FS_WINDOW_HEIGHT;
X				u->xCenter = u->width / 2;
X				u->yCenter = u->height / 2;
X				VResizeViewport (u->v, 12.0*25.4/1000.0,
X					0.40, scale, u->width, u->height);
X				break;
X
X			default:
X				break;
X			}
X
X		}
X
X		player = 0;
X
X	}
X}
X
X/*ARGSUSED*/
Xint doButtonEvent (c, u, ev, player)
Xcraft	*c;
Xviewer	*u;
XXEvent	*ev;
Xint	player; {
X
X	if (ev->xbutton.button == Button2)
X		fireWeapon (c);
X
X	else if (ev->xbutton.button == Button3)
X		selectWeapon (c);
X
X	return 0;
X}
X
X/*ARGSUSED*/
Xint doButtonReleaseEvent (c, u, ev, player)
Xcraft	*c;
Xviewer	*u;
XXEvent	*ev;
Xint	player; {
X
X	if (ev->xbutton.button == Button2)
X		ceaseFireWeapon (c);
X
X	return 0;
X}
X
X/*ARGSUSED*/
Xint doKeyEvent (c, u, ev, player)
Xcraft	*c;
Xviewer	*u;
XXEvent	*ev;
Xint	player; 
X{
X
X	KeySym		keysym;
X	XComposeStatus	compose;
X	char		buffer[MAX_MAPPED_STRING_LEN];
X	int		buflen = MAX_MAPPED_STRING_LEN;
X
X	(void) XLookupString (&ev->xkey, buffer, buflen, &keysym, &compose);
X
X	if (player) {
X
X		switch (keysym) {
X
X		case XK_Left:
X			if (c->flags & FL_NWS) {
X				c->curNWDef = c->curNWDef - c->cinfo->NWIncr;
X				if (c->curNWDef < - c->cinfo->maxNWDef)
X					c->curNWDef = - c->cinfo->maxNWDef;
X			}
X			else {
X				c->Sa =  c->Sa - 0.05;
X			}
X			break;
X
X		case XK_Right:
X			if (c->flags & FL_NWS) {
X				c->curNWDef = c->curNWDef + c->cinfo->NWIncr;
X				if (c->curNWDef > c->cinfo->maxNWDef)
X					c->curNWDef = c->cinfo->maxNWDef;
X			}
X			else {
X				c->Sa = c->Sa + 0.05;
X			}
X			break;
X
X		case XK_Up:
X			c->Se = c->Se - 0.01;
X			break;
X
X		case XK_Down:
X			c->Se = c->Se + 0.01;
X			break;
X
X		case XK_z:
X		case XK_Z:
X			c->Sr = c->Sr + 0.01;
X			break;
X
X		case XK_c:
X		case XK_C:
X			c->Sr = c->Sr - 0.01;
X			break;
X
X		case XK_x:
X		case XK_X:
X			c->Sr = 0.0;
X			break;
X
X		case XK_Home:
X			c->Se = 0.0;
X			c->Sr = 0.0;
X			c->Sa = 0.0;
X			break;
X
X		case XK_y:
X		case XK_Y:
X			flapsUp (c);
X			break;
X
X		case XK_h:
X		case XK_H:
X			flapsDown (c);
X			break;
X
X		case XK_w:
X		case XK_W:
X			speedBrakeRetract (c);
X			break;
X
X		case XK_s:
X		case XK_S:
X			speedBrakeExtend (c);
X			break;
X
X		case XK_2:
X		case XK_KP_Subtract:
X			c->throttle = (c->throttle <= 6553) ? 6553 :
X				c->throttle - 512;
X			c->curThrust = calcThrust(c);
X			break;
X
X		case XK_3:
X		case XK_KP_Add:
X			c->throttle = (c->throttle >= 32768) ? 32768 :
X				c->throttle + 512;
X			c->curThrust = calcThrust(c);
X			break;
X
X		case XK_4:
X		case XK_Prior:
X			c->throttle = 32768;
X			c->curThrust = calcThrust(c);
X			break;
X
X		case XK_1:
X		case XK_Next:
X			c->throttle = 8192;
X			c->curThrust = calcThrust(c);
X			break;
X
X		case XK_A:
X		case XK_a:
X			c->flags ^= FL_AFTERBURNER;
X			c->curThrust = calcThrust(c);
X			break;
X
X		case XK_B:
X		case XK_b:
X			c->flags ^= FL_BRAKES;
X			break;
X
X		case XK_L:
X		case XK_l:
X			newDrone (c);
X			break;
X
X		case XK_KP_8:
X			c->viewDirection.x = 1.0;
X			c->viewDirection.y = 0.0;
X			c->viewDirection.z = 0.0;
X			c->viewUp.x = 0.0;
X			c->viewUp.y = 0.0;
X			c->viewUp.z = -1.0;
X			break;
X
X/* look right */
X
X		case XK_KP_6:
X			c->viewDirection.x = 0.0;
X			c->viewDirection.y = 1.0;
X			c->viewDirection.z = 0.0;
X			c->viewUp.x = 0.0;
X			c->viewUp.y = 0.0;
X			c->viewUp.z = -1.0;
X			break;
X
X/* look left */
X
X		case XK_KP_4:
X			c->viewDirection.x = 0.0;
X			c->viewDirection.y = -1.0;
X			c->viewDirection.z = 0.0;
X			c->viewUp.x = 0.0;
X			c->viewUp.y = 0.0;
X			c->viewUp.z = -1.0;
X			break;
X
X/* look back */
X
X		case XK_KP_2:
X			c->viewDirection.x = -1.0;
X			c->viewDirection.y = 0.0;
X			c->viewDirection.z = 0.0;
X			c->viewUp.x = 0.0;
X			c->viewUp.y = 0.0;
X			c->viewUp.z = -1.0;
X			break;
X
X/* look up */
X
X		case XK_KP_5:
X			c->viewDirection.x = 0.0;
X			c->viewDirection.y = 0.0;
X			c->viewDirection.z = -1.0;
X			c->viewUp.x = -1.0;
X			c->viewUp.y = 0.0;
X			c->viewUp.z = 0.0;
X			break;
X
X		case XK_Q:
X		case XK_q:
X			c->curRadarTarget = getRadarTarget (c, 1);
X			break;
X
X		case XK_R:
X		case XK_r:
X			c->radarMode = (c->radarMode == RM_STANDBY) ?
X				RM_NORMAL : RM_STANDBY;
X			break;
X
X		case XK_o:
X			if (absorbDamage(c, 3) == 0) {
X				killPlayer (c);
X				return -1;
X			}
X			break;
X
X		case XK_P:
X		case XK_p:
X			killPlayer (c);
X			return -1;
X		}
X
X	}
X
X	return 0;
X}
END_OF_FILE
if test 5451 -ne `wc -c <'acm/fsim/doEvents.c'`; then
    echo shar: \"'acm/fsim/doEvents.c'\" unpacked with wrong size!
fi
# end of 'acm/fsim/doEvents.c'
fi
if test -f 'acm/fsim/doScale.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'acm/fsim/doScale.c'\"
else
echo shar: Extracting \"'acm/fsim/doScale.c'\" \(3959 characters\)
sed "s/^X//" >'acm/fsim/doScale.c' <<'END_OF_FILE'
X#include <X11/Xlib.h>
X#include <stdio.h>
X#include "scale.h"
X
Xstatic char *skipBlanks (s)
Xchar *s; {
X
X	for (; *s == ' '; s++) ;
X	return s;
X}
X
Xvoid doScale (dpy, win, gc, s, value, fth, ftw)
XDisplay		*dpy;
XWindow		win;
XGC		gc;
XscaleControl	*s;
Xdouble		value;
Xint		fth;
Xint		ftw; {
X
X	XPoint		p;
X	XSegment	seg[32];
X	int		is = 0;
X	double		vStart;
X	int		top = s->yorg - s->length;
X	int		y, w, v, n;
X	int		ytick = (double) s->minorInterval / s->scale + 0.5;
X	int		doMajor;
X	char		str[16], *q;
X
X	vStart = value - (double) (s->length / 2) * s->scale;
X	n = (int) vStart % s->minorInterval;
X	if (n > 0)
X		n = n - s->minorInterval;
X	y = s->yorg + (int) (n / s->scale);
X	if (vStart > 0.0)
X		v = (int) (vStart + s->minorInterval - 1.0);
X	else
X		v = (int) vStart;
X	v = v / s->minorInterval * s->minorInterval;
X
X/*
X *  Draw the index mark
X */
X
X	seg[is].y1 = seg[is].y2 = s->yorg - ((double) s->length / 2.0);
X	if (s->orientation & orientRight) {
X		seg[is].x1 = s->xorg - 2;
X		seg[is].x2 = seg[is].x1 - s->indexSize;
X	}
X	else {
X		seg[is].x1 = s->xorg + 2;
X		seg[is].x2 = seg[is].x1 + s->indexSize;
X	}
X	++ is;
X
X/*
X *  step through the doMajor and minor ticks
X */
X
X	for (; y > top; (y -= ytick, v += s->minorInterval)) {
X
X/*  we don't mark negative ticks */
X
X		if (v < 0)
X			continue;
X
X		seg[is].x1 = s->xorg;
X		seg[is].y1 = seg[is].y2 = p.y = y;
X
X		if ((v % s->majorInterval) == 0) {
X			doMajor = 1;
X			w = s->majorSize;
X			if (s->orientation & orientRight)
X				seg[is].x2 = s->xorg + w;
X			else
X				seg[is].x2 = s->xorg - w;
X			sprintf (str, s->format, (double) v / s->divisor);
X			q = skipBlanks (str);
X			p.y += 0.30 * (double) fth;
X			if (s->orientation & orientRight) {
X				p.x = seg[is].x2 + 3;
X			}
X			else {
X				p.x = seg[is].x2 - 3 - ftw * strlen(q);
X			}
X		}
X		else {
X			doMajor = 0;
X			w = s->minorSize;
X			if (s->orientation & orientRight)
X				seg[is].x2 = s->xorg + w;
X			else
X				seg[is].x2 = s->xorg - w;
X		}
X
X		if (doMajor)
X			XDrawString (dpy, win, gc, p.x, p.y, q,
X				strlen (q));
X		++ is;	 
X	}
X
X	XDrawSegments (dpy, win, gc, seg, is);
X
X}
X
Xvoid doCompassScale (dpy, win, gc, s, value, fth, ftw)
XDisplay		*dpy;
XWindow		win;
XGC		gc;
XscaleControl	*s;
Xdouble		value;
Xint		fth;
Xint		ftw; {
X
X	XPoint		p;
X	XSegment	seg[32];
X	int		is = 0;
X	double		vStart;
X	int		top = s->xorg + s->length;
X	int		x, w, v, n;
X	int		xtick = (double) s->minorInterval / s->scale + 0.5;
X	int		doMajor;
X	char		str[16], *q;
X
X	vStart = value - (double) (s->length / 2) * s->scale;
X	if (vStart <= 0.0)
X		vStart += 36000.0;
X	n = (int) vStart % s->minorInterval;
X	if (n > 0)
X		n = n - s->minorInterval;
X	x = s->xorg - (int) (n / s->scale);
X	if (vStart > 0.0)
X		v = (int) (vStart + s->minorInterval - 1.0);
X	else
X		v = (int) vStart;
X	v = v / s->minorInterval * s->minorInterval;
X
X/*
X *  Draw the index mark
X */
X
X	seg[is].x1 = seg[is].x2 = s->xorg + (int) ((double) s->length / 2.0 + 0.5);
X	if (s->orientation & orientRight) {
X		seg[is].y1 = s->yorg - 2;
X		seg[is].y2 = seg[is].y1 - s->indexSize;
X	}
X	else {
X		seg[is].y1 = s->yorg + 2;
X		seg[is].y2 = seg[is].y1 + s->indexSize;
X	}
X	++ is;
X
X/*
X *  step through the doMajor and minor ticks
X */
X
X	for (; x < top; (x += xtick, v += s->minorInterval)) {
X
X		if (v > 36000)
X			v -= 36000;
X
X		seg[is].y1 = s->yorg;
X		seg[is].x1 = seg[is].x2 = p.x = x;
X
X		if ((v % s->majorInterval) == 0) {
X			doMajor = 1;
X			w = s->majorSize;
X			if (s->orientation & orientRight)
X				seg[is].y2 = s->yorg + w;
X			else
X				seg[is].y2 = s->yorg - w;
X			sprintf (str, s->format, (double) v / s->divisor);
X			q = skipBlanks (str);
X			p.x -= (strlen(q) * ftw) / 2;
X			if (s->orientation & orientRight) {
X				p.y = seg[is].y2 + 3 + fth;
X			}
X			else {
X				p.y = seg[is].y2 - 3;
X			}
X		}
X		else {
X			doMajor = 0;
X			w = s->minorSize;
X			if (s->orientation & orientRight)
X				seg[is].y2 = s->yorg + w;
X			else
X				seg[is].y2 = s->yorg - w;
X		}
X
X		if (doMajor)
X			XDrawString (dpy, win, gc, p.x, p.y, q,
X				strlen (q));
X		++ is;	 
X	}
X
X	XDrawSegments (dpy, win, gc, seg, is);
X
X}
END_OF_FILE
if test 3959 -ne `wc -c <'acm/fsim/doScale.c'`; then
    echo shar: \"'acm/fsim/doScale.c'\" unpacked with wrong size!
fi
# end of 'acm/fsim/doScale.c'
fi
if test -f 'acm/fsim/server.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'acm/fsim/server.c'\"
else
echo shar: Extracting \"'acm/fsim/server.c'\" \(4922 characters\)
sed "s/^X//" >'acm/fsim/server.c' <<'END_OF_FILE'
X/*
X *	xflight : an aerial combat simulator for X
X *
X *	Written by Riley Rainey,  riley@mips.com
X *
X *	Permission to use, copy, modify and distribute (without charge) this
X *	software, documentation, images, etc. is granted, provided that this 
X *	comment and the author's name is retained.
X *
X */
X 
X#include "manifest.h"
X#include <sys/types.h>
X#include <stdio.h>
X#include <pwd.h>
X#include <signal.h>
X#include <sys/socket.h>
X#include <sys/ioctl.h>
X#include <sys/time.h>
X#include <netinet/in.h>
X#include <netdb.h>
X#include <setjmp.h>
X
X#if !defined(lint) && !defined(SABER)
Xstatic char rcsid[] = "$Revision: acm by Riley Rainey; Revision 2.0 $";
X#endif
X
Xextern struct servent *getservent();
Xint sdebug = 1;
Xint listen_socket;
X
Xvoid parseinfo (s, a, b, c)
Xchar *s, *a, *b, *c; {
X
X	char	*p;
X
X	for (p=a; *s; ++s, ++p)
X		if ((*p = *s) == ' ') {
X			*p = '\0';
X			break;
X		}
X
X	++ s;
X
X	for (p=b; *s; ++s, ++p)
X		if ((*p = *s) == ' ') {
X			*p = '\0';
X			break;
X		}
X
X	++ s;
X
X	strcpy (c, s);
X
X	return;
X}
X
Xmain (argc, argv)
Xint	argc;
Xchar	*argv[]; {
X
X	struct sockaddr_in sin;
X#ifdef notdef
X	struct	servent *sp;
X#endif
X	int	on = 1;
X	int	i, background = 0;
X
X/*
X *  parse arguments
X */
X
X	for (i=1; i<argc; ++i) {
X
X		if (*argv[i] == '-')
X			switch (*(argv[i]+1)) {
X
X			case 'b':
X				background = 1;
X				break;
X
X			default:
X				fprintf (stderr, "Invalid switch \"%s\"\n", argv[i]);
X				break;
X			}
X	}
X
X	if (sdebug) {
X#ifdef notdef
X		if ((sp = getservbyname ("acm", "tcp");
X			fprintf (stderr, "can't find acm service\n");
X			exit (1);
X		}
X#endif
X
X		if ((listen_socket = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
X			perror ("socket");
X			exit (1);
X		}
X
X		sin.sin_family = AF_INET;
X		sin.sin_addr.s_addr = INADDR_ANY;
X		sin.sin_port = htons(ACM_PORT);
X
X		if (bind (listen_socket, &sin, sizeof(sin)) < 0) {
X			perror ("bind");
X			exit (1);
X		}
X	}
X	else {
X		listen_socket = 0;		/* inetd sets this up for us */
X/*		freopen ("/people/riley/acm.error", "a", stderr); */
X	}
X
X    	(void) setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR,
X		(char *) &on, sizeof on);
X	(void) setsockopt(listen_socket, SOL_SOCKET, SO_KEEPALIVE,
X		(char *) &on, sizeof on);
X	ioctl(listen_socket, FIONBIO, (char *) &on);
X
X	if (listen (listen_socket, 5) < 0) {
X		perror ("listen");
X		close (listen_socket);
X		exit (1);
X	}
X
X	if (background)
X#ifdef SYSV
X		setpgrp (1);
X#else
X		setpgrp (0, 1);
X#endif
X
X	init ();
X	input();
X
X}
X
Xint peerdied = 0;
X
Xacm_sig_t deadpeer () {
X	fprintf (stderr, "SIGPIPE\n");
X	peerdied = 1;
X#ifndef SIGVOID
X	return(0);
X#endif
X}
X
Xstruct	sigvec	alrm, pipe;
Xint doUpdate = 0;
X
Xacm_sig_t myalarm () {
X	doUpdate++;
X	sigvec (SIGALRM, &alrm, (struct sigvec *) 0);
X#ifndef SIGVOID
X	return(0);
X#endif
X}
X
Xinput () {
X
X	fd_set	fdset, ofdset;
X	int	news = -1, playerchange = 0, n, pno, addrlen;
X	int	on = 1;
X	struct	sockaddr addr;
X	struct	itimerval update;
X	char	*bp, buf[128], name[64], display[64], args[128];
X
X	alrm.sv_handler = myalarm;
X	alrm.sv_mask = 0;
X#ifdef hpux
X	alrm.sv_flags = SV_BSDSIG;
X#else
X	alrm.sv_flags = SV_INTERRUPT;
X#endif
X	sigvec (SIGALRM, &alrm, (struct sigvec *) 0);
X
X/*
X *  Set real time clock to interrupt us every UPDATE_INTERVAL usecs.
X */
X
X	update.it_interval.tv_sec = 0;
X	update.it_interval.tv_usec = UPDATE_INTERVAL;
X	update.it_value.tv_sec = 0;
X	update.it_value.tv_usec = UPDATE_INTERVAL;
X	setitimer (ITIMER_REAL, &update, 0);
X
X	pipe.sv_handler = SIG_DFL;
X	pipe.sv_mask = 0;
X	pipe.sv_flags = SV_INTERRUPT;
X	sigvec (SIGPIPE, &pipe, (struct sigvec *) 0);
X
X	FD_ZERO (&ofdset);
X	FD_ZERO (&fdset);
X	FD_SET (listen_socket, &ofdset);
X
X	for (;;) {
X
X		sigsetmask (0);
X
X		fdset = ofdset;
X		pno = select (32, &fdset, (fd_set *) NULL, (fd_set *) NULL,
X			(struct itimerval *) NULL);
X
X		sigblock (SIGALRM);
X
X		if (pno < 0) {
X			FD_CLR (listen_socket, &fdset);
X			if (news > 0)
X				FD_CLR (news, &fdset);
X		}
X
X		if (FD_ISSET (listen_socket, &fdset) ||
X			(news > 0 && FD_ISSET(news, &fdset))) {
X			if (news == -1) {
X				addrlen = sizeof (addr);
X				news = accept(listen_socket, &addr, &addrlen);
X				if (news > 0) {
X					peerdied = 0;
X					pipe.sv_handler = deadpeer;
X					sigvec(SIGPIPE, &pipe, (struct sigvec *) 0);
X					ioctl (news, FIONBIO, &on);
X					FD_SET (news, &ofdset);
X					bp = buf;
X				}
X			}
X			if (news > 0 && FD_ISSET (news, &fdset)) {
X				if ((n = read (news, bp, 1)) > 0) {
X					if (*bp == '\n') {
X						*bp = '\0';
X						parseinfo (buf, display,
X							name, args);
X						if (newPlayer (news,
X							display, name, args) == 0)
X							write (news, "Ready.\n", 7);
X							printf ("%s\n", display);
X						close (news);
X						news = -1;
X					}
X					else
X						bp++;
X					playerchange = 1;
X				}
X				if (n == 0)
X					peerdied = 1;
X			}
X		}
X
X		if (playerchange) {
X			FD_ZERO (&ofdset);
X			FD_SET (listen_socket, &ofdset);
X			if (news >= 0)
X				FD_SET (news, &ofdset);
X			pipe.sv_handler = SIG_DFL;
X			sigvec (SIGPIPE, &pipe, (struct sigvec *) 0);
X			playerchange = 0;
X		}
X
X		if (doUpdate) {
X			doUpdate = 0;
X			redraw ();
X		}
X
X	}
X}
END_OF_FILE
if test 4922 -ne `wc -c <'acm/fsim/server.c'`; then
    echo shar: \"'acm/fsim/server.c'\" unpacked with wrong size!
fi
# end of 'acm/fsim/server.c'
fi
echo shar: End of archive 3 \(of 9\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 9 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Riley Rainey			Internet: riley@mips.com
MIPS Computer Systems		Phone:    +1 214 770-7979
Dallas, Texas