v03i052: Asteroids for X, Part01/01

Mike Wexler mikew at wyse.wyse.com
Wed Mar 15 05:29:34 AEST 1989


Submitted-by: weissman at wsl.dec.com
Posting-number: Volume 3, Issue 52
Archive-name: roids/part01

[This one crashed my server.  I am running X11 Release 3 with all the
official patches and the latest purdue patches.  Your mileage may 
vary. -mcw]

#! /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 AUTHOR Imakefile Makefile explode.bit lines.c
#   main.c patchlevel.h rocks.c roids.h roids.man score.c ship.c
#   shot.c widget.c
# Wrapped by mikew at wyse on Tue Mar 14 11:27:33 1989
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'\" \(504 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
Xroids is an X11 game implementing the old Atari Asteroids video game.
X
XAs far as I know, this should be easy to install on anything running
XX11R3.  However, I have only tried it on Ultrix 2.0.  It requires Xt,
XXaw, and Xmu.
X
XI hereby grant permission for this game to be freely redistributed by
Xanyone.  I merely ask that I am given credit, that this notice
Xremains, that any changes made are also sent to me, and that nobody
Xever tries to sell it for any money.
X
X- Terry Weissman (weissman at wsl.dec.com)
END_OF_FILE
if test 504 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'AUTHOR' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'AUTHOR'\"
else
echo shar: Extracting \"'AUTHOR'\" \(844 characters\)
sed "s/^X//" >'AUTHOR' <<'END_OF_FILE'
X(Message inbox:1236)
XReturn-Path: decwrl!weissman at wsl.dec.com
XReceived:  by wyse.wyse.com (5.58/Wyse master/5-13-88)
X	id AA11202; Fri, 10 Mar 89 22:09:26 PST
XReceived: from gilroy.pa.dec.com by decwrl.dec.com (5.54.5/4.7.34)
X	id AA06235; Fri, 10 Mar 89 18:21:10 PST
XReceived: from gilroy.pa.dec.com by decwrl.dec.com (5.54.5/4.7.34)
X	for mikew at wyse.com; id AA06235; Fri, 10 Mar 89 18:21:10 PST
XReceived: from localhost by gilroy.pa.dec.com (5.54.5/4.7.34)
X	id AA09081; Fri, 10 Mar 89 18:21:07 PST
XMessage-Id: <8903110221.AA09081 at gilroy.pa.dec.com>
XTo: mikew at wyse.com
XSubject: Submission for comp.sources.x: roids
XDate: Fri, 10 Mar 89 18:21:06 PST
XFrom: weissman at wsl.dec.com
X
XThis is roids, an X11 implementation of the old Atari Asteroids video
Xgame.  It should only be run on very fast workstations!
X
X- Terry Weissman	(weissman at wsl.dec.com)
X
X
END_OF_FILE
if test 844 -ne `wc -c <'AUTHOR'`; then
    echo shar: \"'AUTHOR'\" unpacked with wrong size!
fi
# end of 'AUTHOR'
fi
if test -f 'Imakefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Imakefile'\"
else
echo shar: Extracting \"'Imakefile'\" \(232 characters\)
sed "s/^X//" >'Imakefile' <<'END_OF_FILE'
XLOCAL_LIBRARIES = $(XAWLIB) $(XTOOLLIB) $(XMULIB) $(XLIB)
X
XOBJS = ship.o widget.o main.o rocks.o lines.o shot.o score.o
X
XSRCS = ship.c widget.c main.c rocks.c lines.c shot.c score.c
X
XSYS_LIBRARIES = -lm
X
XComplexProgramTarget(roids)
END_OF_FILE
if test 232 -ne `wc -c <'Imakefile'`; then
    echo shar: \"'Imakefile'\" unpacked with wrong size!
fi
# end of 'Imakefile'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(6543 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# Makefile generated by imake - do not edit!
X# $XConsortium: imake.c,v 1.37 88/10/08 20:08:30 jim Exp $
X#
X# The cpp used on this machine replaces all newlines and multiple tabs and
X# spaces in a macro expansion with a single space.  Imake tries to compensate
X# for this, but is not always successful.
X#
X
X###########################################################################
X# X Window System Makefile generated from template file Imake.tmpl
X# $XConsortium: Imake.tmpl,v 1.91 88/10/23 22:37:10 jim Exp $
X#
X# Do not change the body of the imake template file.  Server-specific
X# parameters may be set in the appropriate .macros file; site-specific
X# parameters (but shared by all servers) may be set in site.def.  If you
X# make any changes, you'll need to rebuild the makefiles using
X# "make World" (at best) or "make Makefile; make Makefiles" (at least) in
X# the top level directory.
X#
X# If your C preprocessor doesn't define any unique symbols, you'll need
X# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
X# "make Makefile", "make Makefiles", or "make World").
X#
X# If you absolutely can't get imake to work, you'll need to set the
X# variables at the top of each Makefile as well as the dependencies at the
X# bottom (makedepend will do this automatically).
X#
X
X###########################################################################
X# platform-specific configuration parameters - edit Sun.macros to change
X
X# platform:  $XConsortium: Sun.macros,v 1.52 88/10/23 11:00:55 jim Exp $
X# operating system:   SunOS 3.4
X
XBOOTSTRAPCFLAGS =
X             AS = as
X             CC = cc
X            CPP = /lib/cpp
X             LD = ld
X           LINT = lint
X        INSTALL = install
X           TAGS = ctags
X             RM = rm -f
X             MV = mv
X             LN = ln -s
X         RANLIB = ranlib
XRANLIBINSTFLAGS = -t
X             AR = ar clq
X             LS = ls
X       LINTOPTS = -xz
X    LINTLIBFLAG = -C
X           MAKE = make
XSTD_CPP_DEFINES =
X    STD_DEFINES =
X
X###########################################################################
X# site-specific configuration parameters - edit site.def to change
X
X# site:  $XConsortium: site.def,v 1.16 88/10/12 10:30:24 jim Exp $
X
X###########################################################################
X# definitions common to all Makefiles - do not edit
X
X          SHELL =  /bin/sh
X
X        DESTDIR = /global
X      USRLIBDIR = $(DESTDIR)/lib
X         BINDIR = $(DESTDIR)/bin/X11
X         INCDIR = $(DESTDIR)/include
X         ADMDIR = $(DESTDIR)/usr/adm
X         LIBDIR = $(USRLIBDIR)/X11
X     LINTLIBDIR = $(USRLIBDIR)/lint
X        FONTDIR = $(LIBDIR)/fonts
X       XINITDIR = $(LIBDIR)/xinit
X         XDMDIR = $(LIBDIR)/xdm
X         UWMDIR = $(LIBDIR)/uwm
X         AWMDIR = $(LIBDIR)/awm
X         TWMDIR = $(LIBDIR)/twm
X          DTDIR = $(LIBDIR)/dt
X        MANPATH = /usr/man
X  MANSOURCEPATH = $(MANPATH)/man
X         MANDIR = $(MANSOURCEPATH)n
X      LIBMANDIR = $(MANSOURCEPATH)n3
X    XAPPLOADDIR = $(LIBDIR)/app-defaults
X
X   INSTBINFLAGS = -m 0755
X   INSTUIDFLAGS = -m 4755
X   INSTLIBFLAGS = -m 0664
X   INSTINCFLAGS = -m 0444
X   INSTMANFLAGS = -m 0444
X   INSTAPPFLAGS = -m 0444
X  INSTKMEMFLAGS = -m 4755
X        FCFLAGS = -t
X    CDEBUGFLAGS = -O
X
X        PATHSEP = /
X         DEPEND = $(BINDIR)/makedepend
X          IMAKE = $(BINDIR)/imake
X            RGB = $(LIBDIR)/rgb
X             FC = $(BINDIR)/bdftosnf
X      MKFONTDIR = $(BINDIR)/mkfontdir
X      MKDIRHIER = $(BINDIR)/mkdirhier.sh
X
X         CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(STD_DEFINES) $(DEFINES)
X      LINTFLAGS = $(LINTOPTS) $(INCLUDES) $(STD_DEFINES) $(DEFINES) -DLINT
X        LDFLAGS = $(CDEBUGFLAGS) -L$(USRLIBDIR) $(SYS_LIBRARIES) $(SYSAUX_LIBRARIES)
X
X       IRULESRC = $(LIBDIR)/imake.includes
X
X   EXTENSIONLIB = $(USRLIBDIR)/libext.a
X           XLIB = $(USRLIBDIR)/libX11.a
X         XMULIB = $(USRLIBDIR)/libXmu.a
X        OLDXLIB = $(USRLIBDIR)/liboldX.a
X       XTOOLLIB = $(USRLIBDIR)/libXt.a
X         XAWLIB = $(USRLIBDIR)/libXaw.a
X       LINTXLIB = $(USRLIBDIR)/lint/llib-lX11.ln
X        LINTXMU = $(USRLIBDIR)/lint/llib-lXmu.ln
X      LINTXTOOL = $(USRLIBDIR)/lint/llib-lXt.ln
X        LINTXAW = $(USRLIBDIR)/lint/llib-lXaw.ln
X       INCLUDES = -I$(INCDIR)
X      MACROFILE = Sun.macros
X   ICONFIGFILES = $(IRULESRC)/Imake.tmpl \
X			$(IRULESRC)/$(MACROFILE) $(IRULESRC)/site.def
X  IMAKE_DEFINES =
X      IMAKE_CMD = $(NEWTOP)$(IMAKE) -TImake.tmpl -I$(NEWTOP)$(IRULESRC) \
X			-s Makefile $(IMAKE_DEFINES)
X         RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a \
X			.emacs_* tags TAGS make.log MakeOut
X
X###########################################################################
X# rules:  $XConsortium: Imake.rules,v 1.71 88/10/23 22:46:34 jim Exp $
X
X###########################################################################
X# start of Imakefile
X
XLOCAL_LIBRARIES = $(XAWLIB) $(XTOOLLIB) $(XMULIB) $(XLIB)
X
XOBJS = ship.o widget.o main.o rocks.o lines.o shot.o score.o
X
XSRCS = ship.c widget.c main.c rocks.c lines.c shot.c score.c
X
XSYS_LIBRARIES = -lm
X
X PROGRAM = roids
X
Xall:: roids
X
Xroids: $(OBJS) $(LOCAL_LIBRARIES)
X	$(RM) $@
X	$(CC) -o $@ $(OBJS) $(LOCAL_LIBRARIES) $(LDFLAGS) $(SYSLAST_LIBRARIES)
X
Xrelink::
X	$(RM) $(PROGRAM)
X	$(MAKE) $(MFLAGS) $(PROGRAM)
X
Xinstall:: roids
X	$(INSTALL) -c $(INSTALLFLAGS) roids $(BINDIR)
X
Xinstall.man:: roids.man
X	$(INSTALL) -c $(INSTMANFLAGS) roids.man $(MANDIR)/roids.n
X
Xdepend:: $(DEPEND)
X
Xdepend::
X	$(DEPEND) -s "# DO NOT DELETE" -- $(CFLAGS) -- $(SRCS)
X
X$(DEPEND):
X	@echo "making $@"; \
X	cd $(DEPENDSRC); $(MAKE)
X
Xclean::
X	$(RM) $(PROGRAM)
X
X###########################################################################
X# Imake.tmpl common rules for all Makefiles - do not edit
X
Xemptyrule::
X
Xclean::
X	$(RM_CMD) \#*
X
XMakefile:: $(IMAKE)
X
XMakefile:: Imakefile \
X	$(IRULESRC)/Imake.tmpl \
X	$(IRULESRC)/Imake.rules \
X	$(IRULESRC)/site.def \
X	$(IRULESRC)/$(MACROFILE)
X	- at if [ -f Makefile ]; then \
X	echo "$(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
X	$(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
X	else exit 0; fi
X	$(IMAKE_CMD) -DTOPDIR=$(TOP)
X
X$(IMAKE):
X	@echo "making $@"; \
X	cd $(IMAKESRC); $(MAKE) BOOTSTRAPCFLAGS=$(BOOTSTRAPCFLAGS)
X
Xtags::
X	$(TAGS) -w *.[ch]
X	$(TAGS) -xw *.[ch] > TAGS
X
X###########################################################################
X# empty rules for directories that do not have SUBDIRS - do not edit
X
Xinstall::
X	@echo "install done"
X
Xinstall.man::
X	@echo "install.man done"
X
XMakefiles::
X
X###########################################################################
X# dependencies generated by makedepend
X
END_OF_FILE
if test 6543 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'explode.bit' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'explode.bit'\"
else
echo shar: Extracting \"'explode.bit'\" \(884 characters\)
sed "s/^X//" >'explode.bit' <<'END_OF_FILE'
X#define explode_width 32
X#define explode_height 32
Xstatic char explode_bits[] = {
X   0x00, 0x40, 0x00, 0x20, 0x00, 0xe0, 0x00, 0x38, 0x00, 0xb0, 0x00, 0x3c,
X   0x08, 0x90, 0x00, 0x16, 0x18, 0x90, 0x01, 0x13, 0x30, 0x18, 0x81, 0x11,
X   0xf0, 0x09, 0xc3, 0x08, 0x10, 0x0e, 0x62, 0x04, 0x10, 0x08, 0x36, 0xfe,
X   0x20, 0x00, 0x1c, 0x60, 0x10, 0x00, 0x00, 0x38, 0xd8, 0xc7, 0x09, 0x0a,
X   0x4c, 0x68, 0x0b, 0x1a, 0x46, 0x28, 0x0a, 0x72, 0x43, 0x24, 0x4a, 0xc2,
X   0xc1, 0x23, 0x52, 0x81, 0x47, 0x20, 0xf2, 0xc1, 0x4c, 0x60, 0xe3, 0x60,
X   0x58, 0xc0, 0xa1, 0x30, 0x10, 0x00, 0x00, 0x18, 0x10, 0x00, 0x00, 0x08,
X   0x10, 0x30, 0x20, 0x18, 0x10, 0x38, 0xf0, 0x30, 0x08, 0x68, 0x90, 0x23,
X   0x08, 0xc6, 0x10, 0x6c, 0x08, 0x83, 0x11, 0x58, 0xc8, 0x01, 0x11, 0xf0,
X   0x6c, 0x00, 0x13, 0xe0, 0x34, 0x00, 0x1e, 0x80, 0x1c, 0x00, 0x0c, 0x00,
X   0x0c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00};
END_OF_FILE
if test 884 -ne `wc -c <'explode.bit'`; then
    echo shar: \"'explode.bit'\" unpacked with wrong size!
fi
# end of 'explode.bit'
fi
if test -f 'lines.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lines.c'\"
else
echo shar: Extracting \"'lines.c'\" \(1284 characters\)
sed "s/^X//" >'lines.c' <<'END_OF_FILE'
X/* lines.c -- paint a bunch of lines with minimal requests. */
X
X/* %%% Too lazy to compress these; maybe I'll do it later. */
X
X
X#include "roids.h"
X
Xvoid BeginLines() {}
X
Xvoid AddLine(fromx, fromy, tox, toy, gc)
Xint fromx, fromy, tox, toy;
XGC gc;
X{
X    XDrawLine(dpy, gamewindow, gc, fromx, fromy, tox, toy);
X}
X
Xvoid EndLines() {}
X
X
X#define BETWEEN(x, a, b) ((a <= b && x >= a && x <= b) ||	\
X			  (a > b && x <= a && x >= b))
X
XBoolean CheckIntersects(ax, ay, bx, by, cx, cy, dx, dy)
Xint ax, ay, bx, by, cx, cy, dx, dy;
X{
X    float m1, m2, b1, b2, x, y;
X    if (bx == ax) {
X	if (dx == cx) return FALSE; /* Parallel; hacking, assume they miss. */
X	m2 = ((float) (dy - cy)) / ((float) (dx - cx));
X	b2 = cy - cx*m2;
X	x = ax;
X	y = m2 * x + b2;
X	return (BETWEEN(y, ay, by) && BETWEEN(x, cx, dx) &&
X		BETWEEN(y, cy, dy));
X    }
X    if (dx == cx) {
X	return CheckIntersects(cx, cy, dx, dy, ax, ay, bx, by);
X    }
X    m1 = ((float) (by - ay)) / ((float) (bx - ax));
X    m2 = ((float) (dy - cy)) / ((float) (dx - cx));
X    b1 = ay - ax*m1;
X    b2 = cy - cx*m2;
X    if (m1 == m2) {		/* Parallel lines */
X	return FALSE;		/* Hack. */
X    }
X    x = (b2 - b1) / (m1 - m2);
X    y = m1 * x + b1;
X    return (BETWEEN(x, ax, bx) && BETWEEN(y, ay, by) &&
X	    BETWEEN(x, cx, dx) && BETWEEN(y, cy, dy));
X}
END_OF_FILE
if test 1284 -ne `wc -c <'lines.c'`; then
    echo shar: \"'lines.c'\" unpacked with wrong size!
fi
# end of 'lines.c'
fi
if test -f 'main.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'main.c'\"
else
echo shar: Extracting \"'main.c'\" \(4487 characters\)
sed "s/^X//" >'main.c' <<'END_OF_FILE'
X/* main.c -- create our windows and initialize things. */
X
X#define MAIN
X#include "roids.h"
X#include <X11/Label.h>
X#include <X11/VPaned.h>
X
Xstatic int width, height;		/* Size of window. */
Xstatic Pixel defaultfore;	/* Default foreground */
Xstatic Pixel defaultback;	/* Default background */
Xstatic Pixel scorepixel;	/* Color for score. */
X
Xstatic XrmOptionDescRec table[] = {
X    {"-debug",	"*debug",	XrmoptionNoArg,	NULL},
X};
X
Xstatic XtResource resources[] = {
X    {XtNwidth, XtCWidth, XtRInt, sizeof(int),
X	 (Cardinal)&width, XtRImmediate, (caddr_t) 500},
X    {XtNheight, XtCHeight, XtRInt, sizeof(int),
X	 (Cardinal)&height, XtRImmediate, (caddr_t) 800},
X    {"debug", "Debug", XtRBoolean, sizeof(Boolean),
X	 (Cardinal)&debug, XtRString, "off"},
X    {"numdir", "NumDir", XtRInt, sizeof(int),
X	 (Cardinal)&numdir, XtRImmediate, (caddr_t) 48},
X    {"shipradius", "ShipRadius", XtRInt, sizeof(int),
X	 (Cardinal)&shipradius, XtRImmediate, (caddr_t) 12},
X    {"shipwait", "ShipWait", XtRInt, sizeof(int),
X	 (Cardinal)&shipwait, XtRImmediate, (caddr_t) 10},
X    {"rockwait", "RockWait", XtRInt, sizeof(int),
X	 (Cardinal)&rockwait, XtRImmediate, (caddr_t) 30},
X    {"shotwait", "ShotWait", XtRInt, sizeof(int),
X	 (Cardinal)&shotwait, XtRImmediate, (caddr_t) 30},
X    {"shipcolor", "ShipColor", XtRPixel, sizeof(Pixel),
X	 (Cardinal)&shippixel, XtRString, "green"},
X    {"rockcolor", "RockColor", XtRPixel, sizeof(Pixel),
X	 (Cardinal)&rockpixel, XtRString, "gold"},
X    {"shotcolor", "ShotColor", XtRPixel, sizeof(Pixel),
X	 (Cardinal)&shotpixel, XtRString, "red"},
X    {"scorecolor", "ScoreColor", XtRPixel, sizeof(Pixel),
X	 (Cardinal)&scorepixel, XtRString, "violetred"},
X    {"maxvelocity", "MaxVelocity", XtRFloat, sizeof(float),
X	 (Cardinal)&maxv, XtRString, "3.0"},
X    {"maxrockspeed", "MaxRockSpeed", XtRFloat, sizeof(float),
X	 (Cardinal)&maxrockspeed, XtRString, "5.0"},
X    {"accelerationPercentage", "AccelerationPercentage", XtRFloat,
X	 sizeof(float), (Cardinal) &accper, XtRString, "0.1"},
X    {"shotAcceleration", "ShotAcceleration", XtRFloat,
X	 sizeof(float), (Cardinal) &shotacc, XtRString, "2.0"},
X    {"maxshots", "MaxShots", XtRInt, sizeof(int),
X	 (Cardinal) &maxshots, XtRImmediate, (caddr_t) 4},
X    {"shotduration", "ShotDuration", XtRInt, sizeof(int),
X	 (Cardinal) &shotduration, XtRImmediate, (caddr_t) 1000},
X    {"defaultfore", "DefaultFore", XtRPixel, sizeof(Pixel),
X	 (Cardinal) &defaultfore, XtRString, "white"},
X    {"defaultback", "DefaultBack", XtRPixel, sizeof(Pixel),
X	 (Cardinal) &defaultback, XtRString, "black"},
X};
X
X
Xstatic void CvtStringToFloat(args, num_args, fromVal, toVal)
XArgList args;
XCardinal num_args;
XXrmValue    *fromVal;
XXrmValue    *toVal;
X{
X    static float  i;
X
X    if (sscanf((char *)fromVal->addr, "%f", &i) == 1) {
X	toVal->size = sizeof(float);
X	toVal->addr = (caddr_t) &i;
X    } else {
X	toVal->size = 0;
X	toVal->addr = NULL;
X    }
X}
X
Xstatic void AddResource(r, p)
Xchar *r;
XPixel *p;
X{
X    XrmValue value;
X    XrmDatabase db = XtDatabase(dpy);
X    value.size = sizeof(Pixel);
X    value.addr = (caddr_t) p;
X    XrmPutResource(&db, r, XtRPixel, &value);
X}
X
Xmain(argc, argv)
XCardinal argc;
Xchar **argv;
X{
X    static Arg args[] = {
X	{XtNwidth, NULL},
X	{XtNheight, NULL},
X    };
X    static Arg scoreargs[] = {
X	{XtNforeground, NULL},
X    };
X    Widget pane;
X    extern WidgetClass labelwidgetclass;
X    srandom(time(0));
X    toplevel = XtInitialize(argv[0], "Roids", table, XtNumber(table),
X			    &argc, argv);
X    dpy = XtDisplay(toplevel);
X    XtAddConverter(XtRString, XtRFloat, CvtStringToFloat, NULL, 0);
X    XtGetApplicationResources(toplevel, (caddr_t) NULL, 
X			      resources, XtNumber(resources),
X			      NULL, (Cardinal) 0);
X    AddResource("*background", &defaultback);
X    if (DisplayCells(dpy, 0) <= 2) {
X	shippixel = defaultfore;
X	rockpixel = defaultfore;
X	shotpixel = defaultfore;
X	scorepixel = defaultfore;
X    }
X    args[0].value = (XtArgVal) width;
X    args[1].value = (XtArgVal) height;
X    pane = XtCreateWidget("pane", vPanedWidgetClass, toplevel,
X			  args, XtNumber(args));
X    XtManageChild(pane);
X    scoreargs[0].value = (XtArgVal) scorepixel;
X    scorewidget = XtCreateWidget("score", labelWidgetClass, pane,
X				 scoreargs, XtNumber(scoreargs));
X    XtManageChild(scorewidget);
X    gamewidget = (RoidsWidget)
X	XtCreateWidget("field", roidsWidgetClass, pane, NULL, 0);
X    XtManageChild(gamewidget);
X    XtRealizeWidget(toplevel);
X    XtMainLoop();
X}
X
X
XPunt(msg)
X{
X    fprintf(stderr, "%s\n", msg);
X    exit(1);
X}
END_OF_FILE
if test 4487 -ne `wc -c <'main.c'`; then
    echo shar: \"'main.c'\" unpacked with wrong size!
fi
# end of 'main.c'
fi
if test -f 'patchlevel.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'patchlevel.h'\"
else
echo shar: Extracting \"'patchlevel.h'\" \(21 characters\)
sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
X#define PATCHLEVEL 0
END_OF_FILE
if test 21 -ne `wc -c <'patchlevel.h'`; then
    echo shar: \"'patchlevel.h'\" unpacked with wrong size!
fi
# end of 'patchlevel.h'
fi
if test -f 'rocks.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rocks.c'\"
else
echo shar: Extracting \"'rocks.c'\" \(7268 characters\)
sed "s/^X//" >'rocks.c' <<'END_OF_FILE'
X/* rkocks.c - handle movement, etc. of the rocks. */
X
X#include "roids.h"
X
X
X
X#define NUMTYPES	3	/* How many types of rocks there are. */
X#define MAXPOINTS	10	/* Maximum number of points in a rock. */
X
X#define MAXROCKS	256	/* Maximum rocks we'll have at one time. */
X
X
Xstatic int numtocreate = 4;	/* How many rocks to create each round. */
X
X
X#define DIAMONDDATA(size)	\
X{0, size},			\
X{size, 0},			\
X{0, -size},			\
X{-size, 0},
X
X
X
X
X
Xstatic int smallshape[][2] = {
X    DIAMONDDATA(10)
X    };
Xstatic int mediumshape[][2] = {
X    DIAMONDDATA(15)
X    };
Xstatic int largeshape[][2] = {
X    DIAMONDDATA(20)
X    };
X
X
Xstatic int ***shapes;
X
X
Xstatic int numpoints[NUMTYPES] = {XtNumber(largeshape), XtNumber(mediumshape),
X				      XtNumber(smallshape)};
X
Xint radius[NUMTYPES];
X
Xextern double sx, sy;		/* Ship location. */
X
Xtypedef struct _RockRec {
X    double x, y;		/* Location. */
X    double vx, vy;		/* Velocity. */
X    int radius;			/* Radius of this rock. */
X    int **shape;		/* Pointer to shape record. */
X    int numpoints;		/* Number of points in shape record. */
X} RockRec, *Rock;
X
XRockRec rocks[MAXROCKS+2];
X
Xint numrocks = 0;		/* Number of rocks existing. */
X
X
X#define RockNearBox(rock, minx, maxx, miny, maxy)	\
X    (rint((rock)->x) - (rock)->radius <= (maxx) &&		\
X     rint((rock)->y) - (rock)->radius <= (maxy) &&		\
X     rint((rock)->x) + (rock)->radius >= (minx) &&		\
X     rint((rock)->y) + (rock)->radius >= (miny))
X
X
X#define RandomSpeed()	(maxrockspeed * (random() % 2000 - 1000) / 1000.0)
X
XBoolean AreaForShipIsClear()
X{
X    int minx, maxx, miny, maxy, i;
X    Rock rock;
X    minx = sx - 5 * shipradius;
X    maxx = sx + 5 * shipradius;
X    miny = sy - 5 * shipradius;
X    maxy = sy + 5 * shipradius;
X    for (i=0, rock = rocks ; i<numrocks ; i++, rock++) {
X	if (RockNearBox(rock, minx, maxx, miny, maxy))
X	    return FALSE;
X    }
X    return TRUE;
X}
X
X
X
Xstatic void ConfigureRock(rock, x, y, vx, vy, shape, numpoints, radius)
XRock rock;
Xdouble x, y, vx, vy;
Xint **shape;
Xint numpoints, radius;
X{
X    rock->x = x;
X    rock->y = y;
X    rock->vx = vx;
X    rock->vy = vy;
X    rock->shape = shape;
X    rock->numpoints = numpoints;
X    rock->radius = radius;
X}
X
X
X
Xstatic void PaintRock(rock, gc)
XRock rock;
XGC gc;
X{
X    register int x = rock->x;
X    register int y = rock->y;
X    register int i;
X    for (i=0 ; i<rock->numpoints ; i++)
X	AddLine(x + rock->shape[i][0], y + rock->shape[i][1],
X		x + rock->shape[i+1][0], y + rock->shape[i+1][1],
X		gc);
X}
X
X
X
X/*
X * Destroy rock #i.  Often, this means creating two rocks in its place.  The
X * point given is used to determine the direction of the destroying influence,
X * and thus which direction the two rocks should go.
X */
X
Xstatic void DestroyRock(i, x, y)
Xint i, x, y;
X{
X    int num, value;
X    Rock rock = rocks + i;
X    double oldx = rock->x;
X    double oldy = rock->y;
X    PaintRock(rock, backgc);
X    value = 50;
X    for (num = 0 ; num < NUMTYPES ; num++)
X	if (rock->shape == shapes[num]) break;
X	else value *= 2;
X    if (num >= NUMTYPES)
X	Punt("Couldn't find shape in DestroyRock!");
X    score += value;
X    PaintScore();
X    numrocks--;
X    rocks[i] = rocks[numrocks];
X    num++;
X    if (num < NUMTYPES) {
X	for (i=numrocks ; i<MIN(MAXROCKS, numrocks+2) ; i++) {
X	    ConfigureRock(rocks + i, oldx, oldy, RandomSpeed(), RandomSpeed(),
X			  shapes[num], numpoints[num], radius[num]);
X	}
X	numrocks = MIN(MAXROCKS, numrocks + 2);
X    }
X}
X
X
X	
XBoolean LineHitsRock(ax, ay, bx, by)
Xint ax, ay, bx, by;
X{
X    register Rock rock;
X    int i, j, x, y;
X    register int minx, miny, maxx, maxy;
X    int **shape;
X    minx = MIN(ax, bx);
X    maxx = MAX(ax, bx);
X    miny = MIN(ay, by);
X    maxy = MAX(ay, by);
X    for (i=0, rock = rocks ; i<numrocks ; i++, rock++) {
X	if (RockNearBox(rock, minx, maxx,  miny, maxy)) {
X	    shape = rock->shape;
X	    x = rock->x;
X	    y = rock->y;
X	    for (j=0 ; j<rock->numpoints ; j++) {
X		if (CheckIntersects(ax, ay, bx, by,
X				    shape[j][0] + x, shape[j][1] + y,
X				    shape[j+1][0] + x, shape[j+1][1] + y)) {
X		    DestroyRock(i, ax, ay);
X		    return TRUE;
X		}
X	    }
X	}
X    }
X    return FALSE;
X}
X	    
X	
X
X/* 
X * Carefully check if the given rock has hit the ship.  If so, destroy the
X * rock (creating new rocks as necessary), and return TRUE.  This does not
X * touch the ship; that is left to the calling routine.
X */
X
Xstatic Boolean CheckForCrash(rock)
XRock rock;
X{
X    extern int px[], py[];
X    int i, j, ax, ay, bx, by;
X    int **shape = rock->shape;
X    int x = rock->x;
X    int y = rock->y;
X    if (shipdestroyed) return FALSE;
X    for (i=0 ; i < NPOINTS ; i++) {
X	ax = px[i];
X	ay = py[i];
X	bx = px[(i+1) % NPOINTS];
X	by = py[(i+1) % NPOINTS];
X	for (j=0 ; j<rock->numpoints ; j++) {
X	    if (CheckIntersects(ax, ay, bx, by,
X				shape[j][0] + x, shape[j][1] + y,
X				shape[j+1][0] + x, shape[j+1][1] + y)) {
X		DestroyRock(rock - rocks, rint(sx), rint(sy));
X		return TRUE;
X	    }
X	}
X    }
X    return FALSE;
X}
X
X
XBoolean CheckIfShipHitRocks()
X{
X    int i, minx, miny, maxx, maxy;
X    Rock rock;
X    minx = sx - shipradius;
X    miny = sy - shipradius;
X    maxx = sx + shipradius;
X    maxy = sy + shipradius;
X    for (i=0, rock = rocks ; i < numrocks ; i++, rock++) {
X	if (RockNearBox(rock, minx, maxx, miny, maxy)) {
X	    if (CheckForCrash(rock))
X		return TRUE;
X	}
X    }
X    return FALSE;
X}
X
X
X
Xvoid PaintAllRocks()
X{
X    int i;
X    for (i=0 ; i<numrocks ; i++)
X	PaintRock(rocks + i, rockgc);
X}
X
Xvoid MoveRocks(closure, id)
XOpaque closure;
XXtIntervalId id;
X{
X    register Rock rock;
X    register int i;
X    int minx, miny, maxx, maxy;
X    if (closure != (Opaque) MoveRocks) return;
X    rocktimerid = XtAddTimeOut(rockwait, MoveRocks, (Opaque) MoveRocks);
X    if (numrocks == 0) {
X	numrocks = MIN(numtocreate, MAXROCKS);
X	numtocreate += 2;
X	for (i=0 ; i<numrocks ; i++) {
X	    ConfigureRock(rocks + i, 0.0, 0.0,
X			  RandomSpeed(), RandomSpeed(),
X			  shapes[0], numpoints[0], radius[0]);
X	}
X    }
X    minx = sx - shipradius;
X    miny = sy - shipradius;
X    maxx = sx + shipradius;
X    maxy = sy + shipradius;
X    for (i=0 ; i<numrocks ; i++) {
X	rock = rocks + i;
X	PaintRock(rock, backgc);
X	rock->x += rock->vx;
X	rock->y += rock->vy;
X	rock->x = (rock->x < 0) ? rock->x + gamewidth :
X	    ((rock->x > gamewidth) ? rock->x - gamewidth : rock->x);
X	rock->y = (rock->y < 0) ? rock->y + gameheight :
X	    ((rock->y > gameheight)? rock->y - gameheight: rock->y);
X	PaintRock(rock, rockgc);
X	if (RockNearBox(rock, minx, maxx, miny, maxy)) {
X	    if (CheckForCrash(rock))
X		DestroyShip();
X	}
X    }
X}
X	
X	
X
Xstatic void SetIt(shape, init, num)
Xint **shape;
Xint init[][2];
Xint num;
X{
X    int i, j;
X    for (i=0 ; i<num+1 ; i++) {
X	shape[i] = (int *) XtMalloc(sizeof(int) * 2);
X	for (j=0 ; j<2 ; j++)
X	    shape[i][j] = init[i%num][j];
X    }
X}
X
Xvoid InitRocks()
X{
X    int i, j, m;
X    rocktimerid = NULL;
X    shapes = (int ***) XtMalloc(sizeof(int **) * NUMTYPES);
X    for (i=0 ; i<NUMTYPES ; i++) {
X	shapes[i] = (int **) XtMalloc(sizeof(int *) * (numpoints[i] + 1));
X    }
X    SetIt(shapes[0], largeshape, numpoints[0]);
X    SetIt(shapes[1], mediumshape, numpoints[1]);
X    SetIt(shapes[2], smallshape, numpoints[2]);
X    for (i=0 ; i<NUMTYPES ; i++) {
X	m = -1;
X	for (j=0 ; j<numpoints[i] ; j++) {
X	    m = MAX(m, shapes[i][j][0]);
X	    m = MAX(m, shapes[i][j][1]);
X	}
X	radius[i] = m;
X    }
X}
END_OF_FILE
if test 7268 -ne `wc -c <'rocks.c'`; then
    echo shar: \"'rocks.c'\" unpacked with wrong size!
fi
# end of 'rocks.c'
fi
if test -f 'roids.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'roids.h'\"
else
echo shar: Extracting \"'roids.h'\" \(3029 characters\)
sed "s/^X//" >'roids.h' <<'END_OF_FILE'
X/* roids.h - definitions of roids data structures. */
X
X#ifndef _roids_h
X#define _roids_h
X
X#include <stdio.h>
X#include <X11/Xos.h>
X#include <math.h>
X#include <X11/Xlib.h>
X
X#include <X11/Xutil.h>
X#include <X11/cursorfont.h>
X
X#include <X11/IntrinsicP.h>
X#include <X11/StringDefs.h>
X
X#define XtRFloat "Float"
X#define rint(x) ((int) (x))
X#define MIN(x, y)	((x) < (y) ? (x) : (y))
X#define MAX(x, y)	((x) > (y) ? (x) : (y))
X#define NPOINTS 3		/* Number of points on a ship. */
X
X#ifdef MAIN
X#define ext
X#else
X#define ext extern
X#endif
X
X/*
X * Definitions to make us act as a widget.
X */
X
X/* New fields for the Roids widget class record */
Xtypedef struct {
X     int mumble;   /* No new procedures */
X} RoidsClassPart;
X
X/* Full class record declaration */
Xtypedef struct _RoidsClassRec {
X    CoreClassPart       core_class;
X    RoidsClassPart    roids_class;
X} RoidsClassRec;
X
Xextern RoidsClassRec roidsClassRec;
Xextern WidgetClass roidsWidgetClass;
X
X/* New fields for the Roids widget record */
Xtypedef struct _RoidsPart {
X    int dummy;
X} RoidsPart;
X
X
X
X/* Full instance record declaration */
X
Xtypedef struct _RoidsRec {
X    CorePart core;
X    RoidsPart roids;
X} RoidsRec, *RoidsWidget;
X
X
X
X
X/*
X * Actual roids definitions.
X */
X
Xext Boolean debug;
X
Xext Display *dpy;
Xext Window gamewindow;
Xext RoidsWidget gamewidget;
Xext int gamewidth, gameheight;
Xext Widget toplevel, scorewidget;
Xext int score;
Xext int shipsleft;
X
X/* Ship info: */
X
Xext int shipradius;
Xext int numdir;
X
Xext int shipwait;		/* Number of milleseconds to wait between */
X				/* moving ship. */
Xext int numdestroyed;
X
X
X
Xext XtIntervalId shiptimerid;
X
Xext Pixel shippixel;
Xext float maxv;			/* Constant: what our maximum
Xvelocity is. */
Xext float accper;		/* Constant: how fast we accelerate. */
Xext Boolean shipdestroyed;	/* TRUE if the ship is non-existant */
X
X/* Rock info: */
X
Xext XtIntervalId rocktimerid;
Xext Pixel rockpixel;
Xext int rockwait;		/* Number of milleseconds to wait between */
X				/* moving rocks. */
Xext float maxrockspeed;		/* Constant: fastest velocity for a rock. */
X
X/* Shot info. */
X
Xext XtIntervalId shottimerid;
Xext Pixel shotpixel;
Xext int shotwait;
Xext float shotacc;		/* How many times faster a shot goes than */
X				/* the ship.*/
Xext int maxshots;		/* How many shots are allowed to exist at */
X				/* once. */
Xext int shotduration;		/* How long (in milleseconds) a shot lives. */
X
X
X
X
Xext GC backgc, shipgc, rockgc, shotgc;
X
X
X
X/* From widget.c */
X
Xextern Boolean TakeFocus();
Xextern void Quit();
X
X
X
X/* From ship.c */
X
Xextern void MoveShip();
Xextern void ThrustOn();
Xextern void ThrustOff();
Xextern void RotateLeft();
Xextern void RotateRight();
Xextern void RotateOff();
Xextern void RotateToPoint();
Xextern void StopRotateToPoint();
Xextern void RotateMouseMoved();
Xextern void Fire();
X
X/* From rocks.c */
X
Xextern Boolean CheckIfShipHitRocks();
Xextern Boolean AreaForShipIsClear();
Xextern Boolean LineHitsRock();
Xextern void MoveRocks();
Xextern void InitRocks();
X
X/* From shot.c */
X
Xextern void AddShot();
Xextern void MoveShots();
X
X#endif _roids_h
END_OF_FILE
if test 3029 -ne `wc -c <'roids.h'`; then
    echo shar: \"'roids.h'\" unpacked with wrong size!
fi
# end of 'roids.h'
fi
if test -f 'roids.man' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'roids.man'\"
else
echo shar: Extracting \"'roids.man'\" \(6172 characters\)
sed "s/^X//" >'roids.man' <<'END_OF_FILE'
X.\" Man page for roids, by Terry Weissman.
X.TH roids 1 "10 March 1989"
X.SH NAME
X\fIroids\fR \- Dodge and shoot the flying rocks.
X.SH SYNOPSIS
X.B roids
X[-display display:number]
X.SH DESCRIPTION
X.I roids
Xis an implementation of the old Atari Asteroids game, on top of the
XX11 window system.  Be warned that it only works on
X.B very
Xfast workstations.
X
X.SH PLAYING ROIDS
XInitially, you will be presented with a black window.  Nothing will
Xhappen until you give input focus to that window.  (How you do this
Xdepends on your window manager; in most of them, you just move the
Xmouse into the
X.I roids
Xwindow.  In some, you'll have to click the mouse as well.)
X
XOnce you get things going, you'll find yourself in control of a small
Xtriangular ship, dodging big rocks.  Your controls are:
X
X.PP
X.TP 8
X.B z
XRotate the ship to the left.  It will continue rotating as long as the
Xkey stays depressed.
X.PP
X.TP 8
X.B x
XRotate the ship to the right.  It will continue rotating as long as the
Xkey stays depressed.
X.PP
X.TP 8
X.B ,
XApply thrust.  Thrusting will continue as long as the key remains depressed.
X.PP
X.TP 8
X.B .
XFire a bullet.  You may have up to four bullets flying at once.
X.PP
X.TP 8
X.B Q
XAbort the game.  This must be entered as a capital Q (the shift key
Xmust be down).
X
XIf you prefer, you may control your ship with the mouse.  The controls
Xhere are:
X
X.PP
X.TP 8
X.B Left
XRotate the ship to point towards the mouse arrow.
X.PP
X.TP 8
X.B Middle
XApply thrust.
X.PP
X.TP 8
X.B Right
XFire a bullet.
X
X
X.SH SCORING
X
XBig rocks are worth 50 points.  Medium rocks are worth 100 points.
XSmall rocks are worth 200 points.
X
XYou have three ships.  You get a free ship every 10,000 points.
X
X
X
X
X.SH CUSTOMIZING COLORS
X
XAs with all standard X applications,
X.I roids
Xmay be customized through entries in the resource manager.  This
Xalmost always means editing your .Xdefaults file.  [Note: the entry names
Xmust be entered in either all lower-case, or in the exact
Xcase shown below.]
X
X.PP
X.TP 8
X.B ShipColor
XThe color to paint your ship.  (Default is green.)
X.PP
X.TP 8
X.B RockColor
XThe color to paint rocks.  (Default is gold.)
X.PP
X.TP 8
X.B ShotColor
XThe color to paint shots.  (Default is red.)
X.PP
X.TP 8
X.B ScoreColor
XThe color to paint the score.  (Default is violetred.)
X
X
X.SH CUSTOMIZING MOUSE AND KEYBOARD
X
XIf you wish to set up your own interpretation of the mouse and
Xkeyboard, the following actions are provided:
X
X.PP
X.TP 8
X.B grab-focus
XGrab the input focus.  This is only useful if bound to a mouse action.
X.PP
X.TP 8
X.B rotate-left
XStart rotating the ship to the left.
X.PP
X.TP 8
X.B rotate-right
XStart rotating the ship to the right.
X.PP
X.TP 8
X.B rotate-off
XStop any rotation.
X.PP
X.TP 8
X.B thrust-on
XBegin thrusting.
X.PP
X.TP 8
X.B thrust-off
XStop thrusting.
X.PP
X.TP 8
X.B rotate-to-point
XBegin rotating to point to where the mouse is pointing.  This may only be
Xbound to a mouse-down action.
X.PP
X.TP 8
X.B stop-rotate
XCancel a currently executing rotate-to-point.  This may only be bound
Xto a mouse-up action.
X.PP
X.TP 8
X.B rotate-moved
XChange the point to rotate to.  This may only be bound to a
Xmouse-motion action.
X.PP
X.TP 8
X.B fire
XFire a shot.
X.PP
X.TP 8
X.B quit
XQuit the game.
X.PP
X
XIt is beyond the scope of this document to describe how to use these
Xactions in your .Xdefaults file to change the keyboard and mouse
Xinterpretation.  As an example, though, here is what you would use to
Xget the default behavior:
X
XRoids*Roids*translation:	\\n\\
X     <Btn1Down>:	grab-focus() rotate-to-point()\\n\\
X     Button1<PtrMoved>:	rotate-moved()\\n\\
X     <Btn1Up>:		stop-rotate()\\n\\
X     <Btn2Down>:	thrust-on()\\n\\
X     <Btn2Up>:		thrust-off()\\n\\
X     <Btn3Down>:	fire()\\n\\
X     <KeyDown>z:	rotate-left()\\n\\
X     <KeyUp>z:		rotate-off()\\n\\
X     <KeyDown>x:	rotate-right()\\n\\
X     <KeyUp>x:		rotate-off()\\n\\
X     <KeyDown>\\\\,:	thrust-on()\\n\\
X     <KeyUp>\\\\,:	thrust-off()\\n\\
X     <KeyDown>.:	fire()\\n\\
X     Shift<KeyDown>q:	quit()
X
X
X.SH MOTIVATION
X
XI've always wanted to write one of these games.  Unfortunately, I
Xdon't enjoy optimizing code to be very fast, and that's what has
Xalways been necessary for good arcade games on every machine I've
Xused.
X
XUntil I got my DECstation 3100.  This machine is fast enough that I
Xdidn't have to write efficient code.
X.I Roids
Xdoes stupid things like repainting the ships location 100 times a second, and
Xit doesn't matter.
X
XThus, I have written a game that (probably unnecessarily) requires a
Xvery fast workstation.  Please don't interpret this as snobbishness on
Xmy part ("your workstation isn't as fast as mine so you can't play my
Xgame, nyah nyah"); it is just laziness.
X
X.SH NOTES
X
XThere are lots more resources.  The ones above are the only ones I
Xwant documented; the rest change the behavior of the game.  The
Xcurious should look at the source.
X
XThe mouse controls are, in my opinion, useless.  I'd be very
Xinterested if anyone actually likes them.  (I implemented them for a
Xfriend who refuses to use his keyboard to play games.)
X
XCollision detection is very good.  I actually check to see if things
Xtouch; I refused to use the standard method of just seeing if the centers
Xof objects are close.  Of course, this is a large part of why
X.I roids
Xneeds a fast workstation.
X
X.I Roids 
Xworks only on very fast workstations.  Don't try and play it over a
Xnetwork; it won't work.
X
X.SH BUGS
X
XThe rocks look really stupid.  Anyone have some good rock designs?
X
XYou shouldn't have to re-run the program to play another game.
X
XThere should be high-score mechanisms.
X
XDoesn't handle different visuals like a good X client should.  In
Xparticular, if you play this on a display with a StaticGrey visual,
Xyou will probably not be able to see anything.
X
XThe default colors don't show up well on all displays.
X
XNo enemy ships.  In a way, this is a feature; I always despised the
Xfact that people could get lots of points in the original Asteroids by
Xleaving one tiny little rock and blasting all the enemy ships.
X
XThe code really could be a lot more efficient, and therefore work well
Xover a larger variety of machines.
X
X
X.SH AUTHOR
X
XTerry Weissman
X.br
XWestern Software Laboratory
X.br
XDigital Equipment Corporation
X.br
Xweissman at wsl.dec.com
END_OF_FILE
if test 6172 -ne `wc -c <'roids.man'`; then
    echo shar: \"'roids.man'\" unpacked with wrong size!
fi
# end of 'roids.man'
fi
if test -f 'score.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'score.c'\"
else
echo shar: Extracting \"'score.c'\" \(512 characters\)
sed "s/^X//" >'score.c' <<'END_OF_FILE'
X/* score.c -- Print the score. */
X
X#include "roids.h"
X
Xstatic int nextbonus;
X
XPaintScore()
X{
X    static Arg args[] = {
X	{"label", NULL},
X    };
X    char str[500];
X    
X    if (score >= nextbonus) {
X	shipsleft++;
X	nextbonus += 10000;
X    }
X    sprintf(str, "Ships on reserve: %d                Score: %d",
X	    shipsleft, score);
X    args[0].value = (XtArgVal) str;
X    XtSetValues(scorewidget, args, XtNumber(args));
X}
X
X
XInitScore()
X{
X    score = 0;
X    shipsleft = 3;
X    nextbonus = 10000;
X    PaintScore();
X}
END_OF_FILE
if test 512 -ne `wc -c <'score.c'`; then
    echo shar: \"'score.c'\" unpacked with wrong size!
fi
# end of 'score.c'
fi
if test -f 'ship.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ship.c'\"
else
echo shar: Extracting \"'ship.c'\" \(5572 characters\)
sed "s/^X//" >'ship.c' <<'END_OF_FILE'
X/* ship.c - handle movement, etc. of the ship. */
X
X#include "roids.h"
X#include "explode.bit"
X
X#define MAXDIR 256
X
X
Xstatic int shipx[MAXDIR][NPOINTS];
Xstatic int shipy[MAXDIR][NPOINTS];
Xstatic double velx[MAXDIR];
Xstatic double vely[MAXDIR];
Xint px[NPOINTS], py[NPOINTS];	/* What points describe the ships outline */
X				/* now. */
X
Xstatic int orientation;
Xdouble sx, sy;			/* The ship's current location (where the */
X				/* center of it is, in units of pixels. */
Xstatic double vx, vy;		/* The ship's current velocity (in units */
X				/* of pixels per repaint.) */
Xstatic int ex, ey;		/* Where we're painting an explosion. */
Xstatic Boolean showingexplosion = FALSE;
X
Xstatic int dturn;
Xstatic int goalx = -1, goaly;
Xstatic Boolean thrust;
X
X
Xvoid InitShip()
X{
X    int i, d;
X    double angle;
X    shipdestroyed = TRUE;
X    showingexplosion = FALSE;
X    shiptimerid = NULL;
X    orientation = 0;
X    vx = vy = 0.0;
X    dturn = 0;
X    thrust = FALSE;
X    d = shipradius;
X    if (d > shipradius) d = shipradius;
X    for (i=0 ; i < numdir ; i++) {
X	angle = i * 2 * M_PI / (double) numdir;
X	shipx[i][0] = (int) rint(d * cos(angle + M_PI_2));
X	shipy[i][0] = (int) rint(-d * sin(angle + M_PI_2));
X	shipx[i][1] = (int) rint(d * cos(angle + M_PI + M_PI_4));
X	shipy[i][1] = (int) rint(-d * sin(angle + M_PI + M_PI_4));
X	shipx[i][2] = (int) rint(d * cos(angle - M_PI_4));
X	shipy[i][2] = (int) rint(-d * sin(angle - M_PI_4));
X	velx[i] = cos(angle + M_PI_2);
X	vely[i] = -sin(angle + M_PI_2);
X    }
X}
X
X
X
Xvoid PaintShip(gc)
XGC gc;
X{
X    static double lx = -100.0, ly = -100.0;
X    static int lorient = -1;
X    int i, j, x, y;
X    BeginLines();
X    if (sx != lx || sy != ly || orientation != lorient) {
X	lx = sx;
X	ly = sy;
X	lorient = orientation;
X	for (i=0 ; i<NPOINTS ; i++) {
X	    px[i] = sx + shipx[orientation][i];
X	    py[i] = sy + shipy[orientation][i];
X	}
X    }
X    for (i=0 ; i<NPOINTS ; i++) {
X	j = (i + 1) % NPOINTS;
X	AddLine(px[i], py[i], px[j], py[j], gc);
X    }
X    EndLines();
X}
X
X
Xvoid DestroyShip()
X{
X    XImage ximage;
X    PaintShip(backgc);
X    shipdestroyed = TRUE;
X    ex = sx - explode_width/2;
X    ey = sy - explode_height/2;
X    ximage.height = explode_height;
X    ximage.width = explode_width;
X    ximage.xoffset = 0;
X    ximage.format = XYBitmap;
X    ximage.data = (char *)explode_bits;
X    ximage.byte_order = LSBFirst;
X    ximage.bitmap_unit = 16; 
X    ximage.bitmap_bit_order = LSBFirst;
X    ximage.bitmap_pad = 16;
X    ximage.bytes_per_line = (ximage.width+15)/16 * 2;
X    ximage.depth = 1;
X    XPutImage(dpy, gamewindow, shipgc, &ximage,
X	      0, 0, ex, ey, explode_width, explode_height);
X    showingexplosion = TRUE;
X    if (shiptimerid) XtRemoveTimeOut(shiptimerid);
X    shiptimerid = XtAddTimeOut(1000, MoveShip, (Opaque) MoveShip);
X}
X
X
X
Xvoid MoveShip(closure, id)
XOpaque closure;
XXtIntervalId id;
X{
X    int i, j, newx, newy;
X    if (closure != (Opaque) MoveShip) return;
X    if (shipdestroyed) {
X	if (showingexplosion) {
X	    XClearArea(dpy, gamewindow, ex, ey, explode_width, explode_height,
X		       FALSE);
X	    showingexplosion = FALSE;
X	    shiptimerid = XtAddTimeOut(2000, MoveShip, (Opaque) MoveShip);
X	    return;
X	}
X	sx = gamewidth / 2.0;
X	sy = gameheight / 2.0;
X	if (!AreaForShipIsClear()) {
X	    shiptimerid = XtAddTimeOut(100, MoveShip, (Opaque) MoveShip);
X	    return;
X	}
X	if (shipsleft <= 0) Quit();
X	shipsleft--;
X	PaintScore();
X	shipdestroyed = FALSE;
X	vx = vy = 0.0;
X    }
X    shiptimerid = XtAddTimeOut(shipwait, MoveShip, (Opaque) MoveShip);
X    PaintShip(backgc);
X    if (goalx >= 0) dturn = FindGoalTurn();
X    if (dturn) {
X	orientation += dturn;
X	if (orientation < 0) orientation = numdir - 1;
X	else if (orientation >= numdir) orientation = 0;
X    }
X    if (thrust) {
X	vx += velx[orientation] * accper;
X	vy += vely[orientation] * accper;
X	vx = (vx > maxv) ? maxv : ((vx < -maxv) ? -maxv : vx);
X	vy = (vy > maxv) ? maxv : ((vy < -maxv) ? -maxv : vy);
X    }
X    sx += vx;
X    sy += vy;
X    sx = (sx < 0) ? sx + gamewidth : ((sx > gamewidth) ? sx - gamewidth : sx);
X    sy = (sy < 0) ? sy + gameheight: ((sy > gameheight)? sy - gameheight: sy);
X
X    PaintShip(shipgc);
X
X    if (CheckIfShipHitRocks())
X	DestroyShip();
X}
X
X
X
Xvoid ThrustOn()
X{
X    thrust = TRUE;
X}
X
X
Xvoid ThrustOff()
X{
X    thrust = FALSE;
X}
X
X
Xvoid RotateLeft()
X{
X    dturn = 1;
X    goalx = -1;
X}
X
X
Xvoid RotateRight()
X{
X    dturn = -1;
X    goaly = -1;
X}
X
X
Xvoid RotateOff()
X{
X    dturn = 0;
X}
X
X
Xint FindGoalTurn()
X{
X    double dx, dy;
X    double theta;
X    int dgoal;
X    dx = goalx - sx;
X    dy = goaly - sy;
X    if (rint(dy) == 0 && rint(dy) == 0)
X	return 0;
X    theta = atan2(-dy, dx);
X    theta += 3 * M_PI_2;
X    dgoal = (theta * numdir) / (2 * M_PI);
X    dgoal = dgoal % numdir;
X    if (dgoal == orientation) return 0;
X    else if (orientation < dgoal) {
X	if (dgoal - orientation <= numdir / 2)
X	    return 1;
X	else return -1;
X    } else {
X	if (orientation - dgoal <= numdir / 2)
X	    return -1;
X	else return 1;
X    }
X}
X
Xvoid RotateToPoint(w, event, params, num_params)
XWidget w;
XXEvent *event;
Xchar **params;
Xint *num_params;
X{
X    goalx = event->xbutton.x;
X    goaly = event->xbutton.y;
X}
X
Xvoid RotateMouseMoved(w, event, params, num_params)
XWidget w;
XXEvent *event;
Xchar **params;
Xint *num_params;
X{
X    goalx = event->xbutton.x;
X    goaly = event->xbutton.y;
X}
X
X    
Xvoid StopRotateToPoint()
X{
X    goalx = -1;
X    dturn = 0;
X}
X
X
Xvoid Fire()
X{
X    double dx, dy;
X    if (!shipdestroyed) {
X	dx = vx + velx[orientation] * shotacc;
X	dy = vy + vely[orientation] * shotacc;
X	dx = dx * shotwait / shipwait;
X	dy = dy * shotwait / shipwait;
X	AddShot(sx, sy, dx, dy);
X    }
X}
END_OF_FILE
if test 5572 -ne `wc -c <'ship.c'`; then
    echo shar: \"'ship.c'\" unpacked with wrong size!
fi
# end of 'ship.c'
fi
if test -f 'shot.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'shot.c'\"
else
echo shar: Extracting \"'shot.c'\" \(2170 characters\)
sed "s/^X//" >'shot.c' <<'END_OF_FILE'
X/* shot.c - handle movement, etc. of the shots. */
X
X#include "roids.h"
X
X#define MAXSHOTS	20
X
Xtypedef struct _ShotRec {
X    double x, y;		/* Location of this shot. */
X    double vx, vy;		/* Velocity of this shot. */
X    int count;			/* Countdown of life remaining to this shot. */
X} ShotRec, *Shot;
X
XShotRec shots[MAXSHOTS];
X
Xstatic int numshots;		/* Number of shots currently flying. */
X
Xstatic int shotcount;		/* Initial value for life countdown. */
X
Xstatic void PaintShot(shot, gc)
XShot shot;
XGC gc;
X{
X    AddLine(rint(shot->x), rint(shot->y),
X	    rint(shot->x - shot->vx), rint(shot->y - shot->vy), gc);
X}
X
X
Xvoid PaintAllShots()
X{
X    int i;
X    for (i=0 ; i<numshots ; i++)
X	PaintShot(shots + i, shotgc);
X}
X
X
Xstatic void DestroyShot(i)
Xint i;
X{
X    PaintShot(shots + i, backgc);
X    numshots--;
X    shots[i] = shots[numshots];
X}
X
X
Xvoid MoveShots(closure, id)
XOpaque closure;
XXtIntervalId id;
X{
X    int i;
X    double newx, newy;
X    Shot shot;
X    if (closure != (Opaque) MoveShots) return;
X    if (numshots > 0)
X        shottimerid = XtAddTimeOut(shotwait, MoveShots, (Opaque) MoveShots);
X    else
X	shottimerid = NULL;
X    for (i=0 ; i<numshots ; i++) {
X	shot = shots + i;
X	newx = shot->x + shot->vx;
X	newy = shot->y + shot->vy;
X	if (LineHitsRock(rint(shot->x - shot->vx), rint(shot->y - shot->vy),
X			 rint(newx), rint(newy))
X	    || --(shot->count) == 0) {
X	    DestroyShot(i);
X	    i--;		/* Ensures we don't skip moving a shot. */
X	} else {
X	    PaintShot(shot, backgc);
X	    shot->x = newx < 0 ? newx + gamewidth :
X		(newx > gamewidth ? newx - gamewidth : newx);
X	    shot->y = newy < 0 ? newy + gameheight :
X		(newy > gameheight ? newy - gameheight : newy);
X	    PaintShot(shot, shotgc);
X	}
X    }
X}
X
X
X
Xvoid AddShot(x, y, vx, vy)
Xdouble x, y, vx, vy;
X{
X    Shot shot;
X    if (numshots >= maxshots) return;
X    shot = shots + numshots;
X    numshots++;
X    shot->x = x;
X    shot->y = y;
X    shot->vx = vx;
X    shot->vy = vy;
X    shot->count = shotcount;
X    if (shottimerid == NULL)
X        shottimerid = XtAddTimeOut(shotwait, MoveShots, (Opaque) MoveShots);
X}
X
X
X
XInitShot()
X{
X    shottimerid = NULL;
X    shotcount = shotduration / shotwait;
X    numshots = 0;
X}
END_OF_FILE
if test 2170 -ne `wc -c <'shot.c'`; then
    echo shar: \"'shot.c'\" unpacked with wrong size!
fi
# end of 'shot.c'
fi
if test -f 'widget.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'widget.c'\"
else
echo shar: Extracting \"'widget.c'\" \(5392 characters\)
sed "s/^X//" >'widget.c' <<'END_OF_FILE'
X/* widget.c -- handle things that make the playing field behave as a widget. */
X
X#include "roids.h"
X
Xvoid HandleFocus();
Xvoid HandleStruct();
X
Xstatic XtActionsRec actions[] = {
X    {"grab-focus",	(XtActionProc) TakeFocus},
X    {"rotate-left",	RotateLeft},
X    {"rotate-right",	RotateRight},
X    {"rotate-off",	RotateOff},
X    {"thrust-on",	ThrustOn},
X    {"thrust-off",	ThrustOff},
X    {"rotate-to-point",	RotateToPoint},
X    {"stop-rotate",	StopRotateToPoint},
X    {"rotate-moved",	RotateMouseMoved},
X    {"fire",		Fire},
X    {"quit",		Quit},
X};
X
Xstatic char defaultTranslation[] =
X    "<Btn1Down>:	grab-focus() rotate-to-point()\n\
X     Button1<PtrMoved>:	rotate-moved()\n\
X     <Btn1Up>:		stop-rotate()\n\
X     <Btn2Down>:	thrust-on()\n\
X     <Btn2Up>:		thrust-off()\n\
X     <Btn3Down>:	fire()\n\
X     <KeyDown>z:	rotate-left()\n\
X     <KeyUp>z:		rotate-off()\n\
X     <KeyDown>x:	rotate-right()\n\
X     <KeyUp>x:		rotate-off()\n\
X     <KeyDown>\\,:	thrust-on()\n\
X     <KeyUp>\\,:	thrust-off()\n\
X     <KeyDown>.:	fire()\n\
X     Shift<KeyDown>q:	quit()";
X
X
X
X
X
X
Xstatic void ClassInitialize() {}
X
Xstatic void Initialize(request, w)
XWidget request, w;
X{
X    gamewidget = (RoidsWidget) w;
X    XtAddEventHandler(toplevel, (EventMask) FocusChangeMask, FALSE,
X		      HandleFocus, (Opaque) NULL);
X    XtAddEventHandler(toplevel, (EventMask) StructureNotifyMask, FALSE,
X		      HandleStruct, (Opaque) NULL);
X}
X
X
Xstatic void Realize(w, valueMask, attributes)
XWidget w;
XMask *valueMask;
XXSetWindowAttributes *attributes;
X{
X    int i;
X    XGCValues values;
X    XtCreateWindow(w, (unsigned int) InputOutput, (Visual *) CopyFromParent,
X		   *valueMask, attributes);
X    gamewidth = w->core.width;
X    gameheight = w->core.height;
X    gamewindow = w->core.window;
X    values.foreground = w->core.background_pixel;
X    values.background = w->core.background_pixel;
X    backgc = XtGetGC(w, (XtGCMask) GCForeground | GCBackground, &values);
X    values.foreground = shippixel;
X    shipgc = XtGetGC(w, (XtGCMask) GCForeground | GCBackground, &values);
X    values.foreground = rockpixel;
X    rockgc = XtGetGC(w, (XtGCMask) GCForeground | GCBackground, &values);
X    values.foreground = shotpixel;
X    shotgc = XtGetGC(w, (XtGCMask) GCForeground | GCBackground, &values);
X    InitShip();
X    InitRocks();
X    InitShot();
X    InitScore();
X}
X
X
Xstatic void HandleExpose(w, event)
XWidget w;
XXEvent *event;
X{
X    if (event->xexpose.count) return;
X    if (!shipdestroyed)
X	PaintShip(shipgc);
X    PaintAllRocks();
X    PaintAllShots();
X    XSync(dpy, 0);
X}
X
X
Xstatic Boolean wason = TRUE;	/* Whether the user had autorepeat set. */
X
Xvoid Quit()
X{
X    if (wason) XAutoRepeatOn(dpy);
X    XCloseDisplay(dpy);
X    printf("Score: %d\n", score);
X    exit(0);
X}
X
Xstatic void HandleFocus(w, closure, event)
XWidget w;
XOpaque closure;
XXEvent *event;
X{
X    XKeyboardState info;
X    if (event->type == FocusIn) {
X	XGetKeyboardControl(dpy, &info);
X	wason = info.global_auto_repeat;
X	XAutoRepeatOff(dpy);
X	XSync(dpy, 0);
X	if (shiptimerid == NULL)
X	    shiptimerid = XtAddTimeOut(shipwait, MoveShip, (Opaque) MoveShip);
X	if (rocktimerid == NULL)
X	    rocktimerid = XtAddTimeOut(rockwait, MoveRocks,
X				       (Opaque) MoveRocks);
X	if (shottimerid == NULL)
X	    shottimerid = XtAddTimeOut(shotwait, MoveShots,
X				       (Opaque) MoveShots);
X    } else if (event->type == FocusOut) {
X	if (wason) XAutoRepeatOn(dpy);
X	if (shiptimerid) 
X	    XtRemoveTimeOut(shiptimerid);
X	shiptimerid = NULL;
X	if (rocktimerid)
X	    XtRemoveTimeOut(rocktimerid);
X	rocktimerid = NULL;
X	if (shottimerid)
X	    XtRemoveTimeOut(shottimerid);
X	shottimerid = NULL;
X    }
X}
X
Xstatic void HandleStruct(w, closure, event)
XWidget w;
XOpaque closure;
XXEvent *event;
X{
X}
X
Xstatic void Destroy() {}
Xstatic void Resize() {}
Xstatic Boolean SetValues() {}
X
Xstatic Boolean TakeFocus()
X{
X    XSetInputFocus(dpy, gamewindow, RevertToPointerRoot, CurrentTime);
X    return TRUE;
X}
X
XRoidsClassRec roidsClassRec = {
X  {
X/* core_class fields      */
X    /* superclass         */    (WidgetClass) &widgetClassRec,
X    /* class_name         */    "Roids",
X    /* widget_size        */    sizeof(RoidsRec),
X    /* class_initialize   */    ClassInitialize,
X    /* class_part_initiali*/	NULL,
X    /* class_inited       */    FALSE,
X    /* initialize         */    Initialize,
X    /* initialize_hook	  */	NULL,
X    /* realize            */    Realize,
X    /* actions            */    actions,
X    /* num_actions        */    XtNumber(actions),
X    /* resources          */    NULL,
X    /* num_resources      */    (Cardinal) 0,
X    /* xrm_class          */    NULLQUARK,
X    /* compress_motion    */    TRUE,
X    /* compress_exposure  */    TRUE,
X    /* compress_enterleave*/	TRUE,
X    /* visible_interest   */    FALSE,
X    /* destroy            */    Destroy,
X    /* resize             */    Resize,
X    /* expose             */    HandleExpose,
X    /* set_values         */    SetValues,
X    /* set_values_hook	  */	NULL,
X    /* set_values_almost  */	NULL,
X    /* get_values_hook	  */	NULL,
X    /* accept_focus       */    TakeFocus,
X    /* version		  */	XtVersion,
X    /* callback_private	  */	NULL,
X    /* tm_table		  */	defaultTranslation,
X    /* query_geometry	  */	NULL,
X    /* display_accelerator*/	NULL,
X    /* extension`	  */	NULL,
X  },{
X    /* mumble             */    0       /* Make C compiler happy   */
X  }
X};
X
XWidgetClass roidsWidgetClass = (WidgetClass)&roidsClassRec;
END_OF_FILE
if test 5392 -ne `wc -c <'widget.c'`; then
    echo shar: \"'widget.c'\" unpacked with wrong size!
fi
# end of 'widget.c'
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
-- 
Mike Wexler(wyse!mikew)    Phone: (408)433-1000 x1330
Moderator of comp.sources.x



More information about the Comp.sources.x mailing list