home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!zephyr.ens.tek.com!master!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v13i080: xasteroids2 - asteroids arcade game for X, Part01/01
- Message-ID: <2667@master.CNA.TEK.COM>
- Date: 26 Mar 92 16:57:50 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 1515
- Approved: billr@saab.CNA.TEK.COM
-
- Submitted-by: goetz@cs.Buffalo.EDU
- Posting-number: Volume 13, Issue 80
- Archive-name: xasteroids2/Part01
- Environment: X11, Xlib
-
- [I added a simple Imakefile and generated Makefile.std and split the
- doc file from the source file. -br]
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 1)."
- # Contents: README Imakefile Makefile.std ast.c ast.doc
- # Wrapped by billr@saab on Thu Mar 26 08:44:49 1992
- 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'\" \(4947 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- X Here is the source to Xasteroids, version 4. Changes include better
- Xcollision detection, shields, & explosions. Many thanks to Peter
- XPhillips. If anyone wants the shorter & simpler version 3.1, write me.
- X
- X This program runs under UNIX in the X-Windows or OpenWindows
- Xenvironment. It could probably be modified for other operating systems
- Xwithout difficulty. I compile it under quasi-BSD with this command:
- X
- Xcc -I/util/X11/include -L/util/X11/lib ast.c -lX11 -lm -o ast.out -O
- X
- XThat is, include files /util/X11/include, use the library in /util/X11/lib,
- Xsource file ast.c, use the X11 library and the math library, object file
- Xwill be ast.out, and Optimize.
- X
- X Cut the stuff below into ast.docs and ast.c. Then compile ast.c.
- XI know it is bad practice to put everything in one file, but I wanted to
- Xmake it easy to compile.
- X
- X If you like the game, please send $5 to
- X
- X Phil Goetz
- X 4023 Huckleberry Row
- X Ellicott City, MD 21043
- X
- X Even if you don't register, please send a note to my e-mail address
- Xso I know how many people use Xasteroids. Then I may be motivated to
- Xupdate it again, or write new programs...
- XSend any comments, suggestions, bug reports, modifications, etc., to
- X
- X goetz@cs.buffalo.EDU
- X
- X Lots of people have complained that Xasteroids wouldn't run fast
- Xenough on their display. I had different ideas on how to affect the speed,
- Xand implemented all of them. So Version 3 came with more speed controls
- Xthan most people like to think about:
- X
- X 1 2: Scale of movement (default 1): Increasing this causes each object to
- Xmove further every turn.
- XAdvantage: Can be changed in smaller amounts than moves/frame.
- XDisadvantage: Increasing it too much can cause bullets to fly through
- Xasteroids without hitting them. Looks jerky.
- X
- X v b: Moves per frame (default 1): Increasing this causes the main loop to
- Xexecute more times before updating the display.
- XAdvantages: Avoids the problem of bullets flying through asteroids.
- XDisadvantages: Increases only by integer amounts.
- X
- X , .: Delay: Used when your client runs too fast to play comfortably.
- X
- X n m: Object size: If your client is too slow, decrease the size and resize
- Xthe window to a smaller size. Then type 'x' to use XFillRectangle erase.
- X
- X x: XFillRectangle erase: Use XFillRectangle to erase the entire pixmap
- Xeach turn. Faster on small windows.
- X
- X u: Undraw erase: Erase each object line-by-line. Faster on big windows.
- X
- X Playing with scale of movement, object size, and window size can give you
- Xvery different games.
- X
- X There are 3 known bugs, which apply to all versions:
- X1. The window does not accept keyboard input. I think this only happens
- Xunder some versions of OpenWindows. Works under mine.
- X2. While the game is paused (with a 'p'), you can
- Xinput commands to change direction and thrust, and they will be executed.
- XSo this is a way of cheating. This could be corrected, but why bother?
- XIf you don't like it, don't do it.
- X3. Once, the game lost count of numasts and refused to give me a new asteroid
- Xfield. Only once. I have no idea why. One other person has also reported
- Xthis.
- X Also, David Elliot (dce@sonyusa.sony.com) says that he had to put
- Xan XSync(disp) after the XDrawLines call or he would get protocol errors.
- X
- X On anything slower than a SPARCstation 1, or on any color screen,
- Xit will really drag. There should be a way to set color screens to use
- Xa bitmap of depth 1, but I don't know how. Please tell me if you do.
- X The code is not optimized because the XWindows
- Xcalls take the vast majority of the time. I tried, for instance,
- Xreading sines and cosines from a table instead of calculating them -
- Xit made no noticeable difference in speed. Similarly, the collision
- Xdetection could be optimized only to check objects nearby - but why
- Xbother. Same goes for using registers, pointers to frequently-referenced
- Xarray elements, etc. It MIGHT make a significant difference in runtime
- Xif you replace the vector drawing with bitmaps. It runs a LOT slower on
- Xcolor displays.
- X The vast majority of time seems to be used in erasing the pixmap
- Xeach round, & there isn't much to do about that. My tests have indicated
- Xthat blanking individual asteroids rather than the whole screen would
- Xtake comparable time, unless you had a complicated routine to optimize
- Xblanking.
- X If you modify this program, please send me a copy. Modifications
- XI would like to see include: sound (esp. for Sparcstations), drawing
- Xthe asteroids to pixmaps so they can be put on the screen quicker
- X(though not much quicker - the X calls seem to take most of the time),
- Xan options screen to set parameters such as speed, whether bullets
- Xcan be fired before your current ones are dead, whether to start in the
- Xcenter of the screen between levels), a permanent high score file
- Xto be displayed sometimes between games, and jagged fractal asteroids
- X(not just removal of the lines to the center; I like those).
- END_OF_FILE
- if test 4947 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'Imakefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Imakefile'\"
- else
- echo shar: Extracting \"'Imakefile'\" \(115 characters\)
- sed "s/^X//" >'Imakefile' <<'END_OF_FILE'
- X# simple Imakefile for xasteroids
- XSRCS = ast.c
- XOBJS = ast.o
- X
- XEXTRA_LIBRARIES = -lX11 -lm
- X
- XSimpleProgramTarget(ast)
- END_OF_FILE
- if test 115 -ne `wc -c <'Imakefile'`; then
- echo shar: \"'Imakefile'\" unpacked with wrong size!
- fi
- # end of 'Imakefile'
- fi
- if test -f 'Makefile.std' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile.std'\"
- else
- echo shar: Extracting \"'Makefile.std'\" \(10307 characters\)
- sed "s/^X//" >'Makefile.std' <<'END_OF_FILE'
- X# Makefile generated by imake - do not edit!
- X# $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws 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# Makefile generated from "Imake.tmpl" and </tmp/IIf.a06197>
- X# $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $
- X#
- X# Platform-specific parameters may be set in the appropriate <vendor>.cf
- X# configuration files. Site-specific parameters should be set in the file
- X# site.def. Full rebuilds are recommended if any parameters are changed.
- X#
- X# If your C preprocessor does not define any unique symbols, you will need
- X# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
- X# "make World" the first time).
- X#
- X
- X# -------------------------------------------------------------------------
- X# site-specific configuration parameters that need to come before
- X# the platform-specific parameters - edit site.def to change
- X
- X# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
- X
- X# -------------------------------------------------------------------------
- X# platform-specific configuration parameters - edit sun.cf to change
- X
- X# platform: $XConsortium: sun.cf,v 1.69 91/09/09 18:23:59 rws Exp $
- X
- X# operating system: SunOS 4.1.1
- X
- X# $XConsortium: sunLib.rules,v 1.6 91/03/24 17:55:58 rws Exp $
- X
- X# -------------------------------------------------------------------------
- X# site-specific configuration parameters that go after
- X# the platform-specific parameters - edit site.def to change
- X
- X# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
- X
- X SHELL = /bin/sh
- X
- X TOP = .
- X CURRENT_DIR = .
- X
- X AR = ar clq
- X BOOTSTRAPCFLAGS =
- X CC = cc
- X AS = as
- X
- X COMPRESS = compress
- X CPP = /lib/cpp $(STD_CPP_DEFINES)
- X PREPROCESSCMD = cc -E $(STD_CPP_DEFINES)
- X INSTALL = install
- X LD = ld
- X LINT = lint
- X LINTLIBFLAG = -C
- X LINTOPTS = -axz
- X LN = ln -s
- X MAKE = make
- X MV = mv
- X CP = cp
- X
- X RANLIB = ranlib
- X RANLIBINSTFLAGS =
- X
- X RM = rm -f
- X TROFF = psroff
- X MSMACROS = -ms
- X TBL = tbl
- X EQN = eqn
- X STD_INCLUDES =
- X STD_CPP_DEFINES =
- X STD_DEFINES =
- X EXTRA_LOAD_FLAGS =
- X EXTRA_LIBRARIES =
- X TAGS = ctags
- X
- X SHAREDCODEDEF = -DSHAREDCODE
- X SHLIBDEF = -DSUNSHLIB
- X
- X PROTO_DEFINES =
- X
- X INSTPGMFLAGS =
- X
- X INSTBINFLAGS = -m 0755
- X INSTUIDFLAGS = -m 4755
- X INSTLIBFLAGS = -m 0644
- X INSTINCFLAGS = -m 0444
- X INSTMANFLAGS = -m 0444
- X INSTDATFLAGS = -m 0444
- X INSTKMEMFLAGS = -m 4755
- X
- X PROJECTROOT = /usr/X11R5
- X
- X TOP_INCLUDES = -I$(INCROOT)
- X
- X CDEBUGFLAGS = -O
- X CCOPTIONS = -pipe
- X
- X ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES)
- X ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES)
- X CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
- X LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
- X
- X LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
- X
- X LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR)
- X
- X LDCOMBINEFLAGS = -X -r
- X DEPENDFLAGS =
- X
- X MACROFILE = sun.cf
- X RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
- X
- X IMAKE_DEFINES =
- X
- X IRULESRC = $(CONFIGDIR)
- X IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
- X
- X ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
- X $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
- X $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
- X
- X# -------------------------------------------------------------------------
- X# X Window System Build Parameters
- X# $XConsortium: Project.tmpl,v 1.138 91/09/10 09:02:12 rws Exp $
- X
- X# -------------------------------------------------------------------------
- X# X Window System make variables; this need to be coordinated with rules
- X
- X PATHSEP = /
- X USRLIBDIR = /usr/X11R5/lib
- X BINDIR = /usr/X11R5/bin
- X INCROOT = /usr/X11R5/include
- X BUILDINCROOT = $(TOP)
- X BUILDINCDIR = $(BUILDINCROOT)/X11
- X BUILDINCTOP = ..
- X INCDIR = $(INCROOT)/X11
- X ADMDIR = /usr/adm
- X LIBDIR = $(USRLIBDIR)/X11
- X CONFIGDIR = $(LIBDIR)/config
- X LINTLIBDIR = $(USRLIBDIR)/lint
- X
- X FONTDIR = $(LIBDIR)/fonts
- X XINITDIR = $(LIBDIR)/xinit
- X XDMDIR = $(LIBDIR)/xdm
- X TWMDIR = $(LIBDIR)/twm
- X MANPATH = /usr/X11R5/man
- X MANSOURCEPATH = $(MANPATH)/man
- X MANSUFFIX = n
- X LIBMANSUFFIX = 3
- X MANDIR = $(MANSOURCEPATH)$(MANSUFFIX)
- X LIBMANDIR = $(MANSOURCEPATH)$(LIBMANSUFFIX)
- X NLSDIR = $(LIBDIR)/nls
- X PEXAPIDIR = $(LIBDIR)/PEX
- X XAPPLOADDIR = $(LIBDIR)/app-defaults
- X FONTCFLAGS = -t
- X
- X INSTAPPFLAGS = $(INSTDATFLAGS)
- X
- X IMAKE = imake
- X DEPEND = makedepend
- X RGB = rgb
- X
- X FONTC = bdftopcf
- X
- X MKFONTDIR = mkfontdir
- X MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier
- X
- X CONFIGSRC = $(TOP)/config
- X DOCUTILSRC = $(TOP)/doc/util
- X CLIENTSRC = $(TOP)/clients
- X DEMOSRC = $(TOP)/demos
- X LIBSRC = $(TOP)/lib
- X FONTSRC = $(TOP)/fonts
- X INCLUDESRC = $(TOP)/X11
- X SERVERSRC = $(TOP)/server
- X UTILSRC = $(TOP)/util
- X SCRIPTSRC = $(UTILSRC)/scripts
- X EXAMPLESRC = $(TOP)/examples
- X CONTRIBSRC = $(TOP)/../contrib
- X DOCSRC = $(TOP)/doc
- X RGBSRC = $(TOP)/rgb
- X DEPENDSRC = $(UTILSRC)/makedepend
- X IMAKESRC = $(CONFIGSRC)
- X XAUTHSRC = $(LIBSRC)/Xau
- X XLIBSRC = $(LIBSRC)/X
- X XMUSRC = $(LIBSRC)/Xmu
- X TOOLKITSRC = $(LIBSRC)/Xt
- X AWIDGETSRC = $(LIBSRC)/Xaw
- X OLDXLIBSRC = $(LIBSRC)/oldX
- X XDMCPLIBSRC = $(LIBSRC)/Xdmcp
- X BDFTOSNFSRC = $(FONTSRC)/bdftosnf
- X BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf
- X BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf
- X MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir
- X FSLIBSRC = $(FONTSRC)/lib/fs
- X FONTSERVERSRC = $(FONTSRC)/server
- X EXTENSIONSRC = $(TOP)/extensions
- X XILIBSRC = $(EXTENSIONSRC)/lib/xinput
- X PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX
- X
- X# $XConsortium: sunLib.tmpl,v 1.11 91/07/31 11:32:08 rws Exp $
- X
- XSHLIBLDFLAGS = -assert pure-text
- XPICFLAGS = -pic
- X
- X DEPEXTENSIONLIB =
- X EXTENSIONLIB = -lXext
- X
- X DEPXLIB = $(DEPEXTENSIONLIB)
- X XLIB = $(EXTENSIONLIB) -lX11
- X
- X DEPXMULIB = $(USRLIBDIR)/libXmu.sa.$(SOXMUREV)
- X XMULIB = -lXmu
- X
- X DEPOLDXLIB =
- X OLDXLIB = -loldX
- X
- X DEPXTOOLLIB = $(USRLIBDIR)/libXt.sa.$(SOXTREV)
- X XTOOLLIB = -lXt
- X
- X DEPXAWLIB = $(USRLIBDIR)/libXaw.sa.$(SOXAWREV)
- X XAWLIB = -lXaw
- X
- X DEPXILIB =
- X XILIB = -lXi
- X
- X SOXLIBREV = 4.10
- X SOXTREV = 4.10
- X SOXAWREV = 5.0
- X SOOLDXREV = 4.10
- X SOXMUREV = 4.10
- X SOXEXTREV = 4.10
- X SOXINPUTREV = 4.10
- X
- X DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
- X XAUTHLIB = -lXau
- X DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a
- X XDMCPLIB = -lXdmcp
- X
- X DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a
- X PHIGSLIB = -lphigs
- X
- X DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a
- X XBSDLIB = -lXbsd
- X
- X LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln
- X LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln
- X LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln
- X LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln
- X LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln
- X LINTXI = $(LINTLIBDIR)/llib-lXi.ln
- X LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln
- X
- X DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
- X
- X DEPLIBS1 = $(DEPLIBS)
- X DEPLIBS2 = $(DEPLIBS)
- X DEPLIBS3 = $(DEPLIBS)
- X
- X# -------------------------------------------------------------------------
- X# Imake rules for building libraries, programs, scripts, and data files
- X# rules: $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $
- X
- X# -------------------------------------------------------------------------
- X# start of Imakefile
- X
- X# simple Imakefile for xasteroids
- XSRCS = ast.c
- XOBJS = ast.o
- X
- XEXTRA_LIBRARIES = -lX11 -lm
- X
- X OBJS = ast.o
- X SRCS = ast.c
- X
- X PROGRAM = ast
- X
- Xall:: ast
- X
- Xast: $(OBJS) $(DEPLIBS)
- X $(RM) $@
- X $(CC) -o $@ $(OBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS)
- X
- Xsaber_ast:: $(SRCS)
- X # load $(ALLDEFINES) $(SRCS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
- X
- Xosaber_ast:: $(OBJS)
- X # load $(ALLDEFINES) $(OBJS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
- X
- Xinstall:: ast
- X @if [ -d $(DESTDIR)$(BINDIR) ]; then set +x; \
- X else (set -x; $(MKDIRHIER) $(DESTDIR)$(BINDIR)); fi
- X $(INSTALL) -c $(INSTPGMFLAGS) ast $(DESTDIR)$(BINDIR)
- X
- Xinstall.man:: ast.man
- X @if [ -d $(DESTDIR)$(MANDIR) ]; then set +x; \
- X else (set -x; $(MKDIRHIER) $(DESTDIR)$(MANDIR)); fi
- X $(INSTALL) -c $(INSTMANFLAGS) ast.man $(DESTDIR)$(MANDIR)/ast.$(MANSUFFIX)
- X
- Xdepend::
- X $(DEPEND) $(DEPENDFLAGS) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
- X
- Xlint:
- X $(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS)
- Xlint1:
- X $(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS)
- X
- Xclean::
- X $(RM) $(PROGRAM)
- X
- X# -------------------------------------------------------------------------
- X# common rules for all Makefiles - do not edit
- X
- Xemptyrule::
- X
- Xclean::
- X $(RM_CMD) "#"*
- X
- XMakefile::
- X -@if [ -f Makefile ]; then set -x; \
- X $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
- X else exit 0; fi
- X $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
- X
- Xtags::
- X $(TAGS) -w *.[ch]
- X $(TAGS) -xw *.[ch] > TAGS
- X
- Xsaber:
- X # load $(ALLDEFINES) $(SRCS)
- X
- Xosaber:
- X # load $(ALLDEFINES) $(OBJS)
- X
- X# -------------------------------------------------------------------------
- X# empty rules for directories that do not have SUBDIRS - do not edit
- X
- Xinstall::
- X @echo "install in $(CURRENT_DIR) done"
- X
- Xinstall.man::
- X @echo "install.man in $(CURRENT_DIR) done"
- X
- XMakefiles::
- X
- Xincludes::
- X
- X# -------------------------------------------------------------------------
- X# dependencies generated by makedepend
- X
- END_OF_FILE
- if test 10307 -ne `wc -c <'Makefile.std'`; then
- echo shar: \"'Makefile.std'\" unpacked with wrong size!
- fi
- # end of 'Makefile.std'
- fi
- if test -f 'ast.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ast.c'\"
- else
- echo shar: Extracting \"'ast.c'\" \(27201 characters\)
- sed "s/^X//" >'ast.c' <<'END_OF_FILE'
- X/* Xasteroids
- X Copyright 1990 by Phil Goetz
- X goetz@cs.buffalo.EDU
- X Version 4, 2/19/92
- X
- X Changes from version 3.1:
- X
- X Better collision detection: Actually checks for intersection
- X of line segments if non-round objects are very close.
- X Explosions! (Thanks to Peter Phillips.)
- X Fine rotation repeating detected using KeyRelease.
- X Thrust indicator behind ship. (Thanks to Peter Phillips.)
- X Doesn't place ship in center of screen for new levels.
- X (Thanks to Peter Phillips.)
- X Seeds random-number generator with time.
- X (Thanks to Craig Smith.)
- X Shields! (Thanks to Peter Phillips. I rewrote the bounce code
- X & added the energy bar & other refinements.)
- X Detects failure of XOpenDisplay. (Thanks to Pat Ryan.)
- X
- X Contributors: Peter Phillips <pphillip@cs.ubc.ca>
- X Pat Ryan <pat@jaameri.gsfc.nasa.gov>
- X Craig Smith <csmith@cscs.UUCP>
- X*/
- X#include <stdio.h> /* For NULL */
- X#include <X11/Xlib.h>
- X#include <X11/Xutil.h>
- X#include <X11/cursorfont.h> /* For erasing cursor - not important */
- X#include <math.h>
- X
- X/* Indexes for 1st dimension of obj */
- X/* The order they are in is important */
- X#define AST 0
- X#define ENEMY 96
- X#define ENEMYBUL 97
- X#define FBUL 98
- X#define LASTBUL 102
- X#define SHIP 103
- X#define LASTOBJ 103 /* Must be ship! See makeasts(). */
- X
- X/* Shapes */
- X/* Order is important! See collide(). */
- X#define ASTSHAPE1 0
- X#define ASTSHAPE2 1
- X#define ASTSHAPE3 2
- X#define ENBULSH 3
- X#define BULSHAPE 4
- X#define SHIPSHAPE 5
- X#define SHIPTHRSHAPE 6
- X#define ENEMYSHAPE 7
- X#define LASTSHAPE 7
- X
- X/* Masses */
- X#define M_BIG 8.0
- X#define M_MED 4.0
- X#define M_SMALL 1.0
- X#define M_SHIP 1.5
- X#define M_ENEMY 1.0
- X#define M_BULLET 0.1
- X
- X/* Keys */
- X#define FIRE 'p'
- X#define PAUSE 27 /* escape */
- X#define SHIELD '`'
- X#define THRUST 'o'
- X
- X#define BMAX 300 /* Max particles in a "boom" + 1 */
- X#define letheight 20 /* height of font */
- X#define pi 3.1415926535897932384
- X#define SHIPSIZE 28
- X
- Xtypedef struct _Boom *Boom;
- Xstruct _Boom {Boom next; int dur, part; double bcoord[BMAX][2], bvec[BMAX][2]};
- Xtypedef struct {int shape, alive, time;
- X double mass, x, y, xvel, yvel, rot, rotvel} Objtype;
- Xtypedef struct {double angle; int length} PolarPair;
- Xtypedef struct {double x, y, mag} Vector;
- X
- X/* Global variables: */
- XObjtype obj[SHIP+1];
- X/* In shapes pairs, 1st # is radians, 2nd is length in pixels.
- X Degrees: 0 ->, pi/2 down, pi <-, 3*pi/2 up
- X IF YOU CHANGE THE SHAPES, you MUST change numpairs & shapesize
- X*/
- XPolarPair shapes[LASTSHAPE+1][11] =
- X { {{0,0}, {3*pi/2,40}, {0,20}, {pi/4,28}, {pi/2,40}, /* just crossed 0-deg line */
- X {3*pi/4,28},{pi,40},{5*pi/4,28},{3*pi/2,40},{7*pi/4,28},{0,20}},
- X/* hexagon if you prefer
- X {{0,0}, {3*pi/2, 20}, {pi/6, 20}, {pi/2, 20},
- X {5*pi/6, 20}, {7*pi/6, 20}, {3*pi/2, 20}, {11*pi/6, 20}},
- X*/
- X {{0,0}, {3*pi/2,20}, {0,10}, {pi/4,14}, {pi/2,20},
- X {3*pi/4,14},{pi,20},{5*pi/4,14},{3*pi/2,20},{7*pi/4,14},{0,10}},
- X {{0,0}, {3*pi/2,10}, {0,5}, {pi/4,7}, {pi/2,10},
- X {3*pi/4,7},{pi,10},{5*pi/4,7},{3*pi/2,10},{7*pi/4,7},{0,5}},
- X {{0,0}, {7*pi/4, 4}, {pi/4, 4}, {3*pi/4, 4}, {5*pi/4, 4}},
- X {{0,0}, {0,10}},
- X {{0,0}, {5*pi/4,28}, {0,20}, {pi/4,28},{3*pi/4,28},{pi,20},{7*pi/4,28}}, /* Ship */
- X {{0,0}, {5*pi/4,28}, {0,20}, {pi/4,28},{3*pi/4,28},{pi,20},
- X {7*pi/4,28}, {3*pi/4, 7}, {9*pi/8, 13}, {15*pi/8, 13}}, /* Thrusting ship */
- X {{0,0}, {pi,20},{7*pi/4,28},{pi/4,28},{pi,20}}
- X };
- XBoom blist = NULL;
- Xdouble drawscale = 1, speedscale = 1;
- Xint width, height,
- X energy, /* # of turns shield is good for */
- X highscore = 0,
- X nextbul = FBUL, /* Obj# of next bullet fired */
- X numasts, oldscore = 99,
- X rndint = 73, ships, score,
- X numpairs[LASTSHAPE+1] = {11, 11, 11, 5, 2, 7, 10, 5},
- X shapesize[LASTSHAPE+1] = {44, 21, 10, 2, 1, SHIPSIZE+1, 35, 20},
- X shield_on;
- X
- Xinitasts()
- X{ int i;
- X extern Objtype obj[SHIP+1];
- X
- X for (i = 0; i < LASTOBJ+1; i++)
- X { obj[i].rot = 0;
- X obj[i].rotvel = 0;
- X }
- X for (i = 0; i < ENEMY; i++)
- X { obj[i].shape = ASTSHAPE1;
- X }
- X obj[SHIP].shape = SHIPSHAPE;
- X obj[SHIP].mass = M_SHIP;
- X obj[ENEMY].shape = ENEMYSHAPE;
- X obj[ENEMY].mass = M_ENEMY;
- X obj[ENEMYBUL].shape = ENBULSH;
- X obj[ENEMYBUL].mass = M_BULLET;
- X for (i = FBUL; i < LASTBUL+1; i++)
- X { obj[i].shape = BULSHAPE;
- X obj[i].mass = M_BULLET;
- X} }
- X
- Xmakeasts(level)
- X{ int i;
- X extern Objtype obj[SHIP+1];
- X extern int numasts, rndint;
- X extern double speedscale;
- X unsigned char a;
- X
- X for (i = 0; i < SHIP; i++)
- X obj[i].alive = 0; /* Erase objs from last level except ship */
- X for (i = ENEMYBUL; i < LASTBUL+1; i++)
- X obj[i].time = 0; /* No bullets in the air */
- X for (i = 0; i < level+4; i++) /* Asteroids: */
- X { a = rand(rndint); a>>=1; /* a = rand# from 0 to 127 */
- X if (a > 63)
- X obj[i].x = (double) a;
- X else obj[i].x = (double) (width - a);
- X a = rand(rndint); a>>=1; /* Now the same for y */
- X if (a > 63)
- X obj[i].y = (double) a;
- X else obj[i].y = (double) height - a;
- X a = rand(rndint); a = 4 - a>>5;
- X obj[i].rot = (double) a;
- X a = rand(rndint);
- X obj[i].rotvel = ((double) a)/2048;
- X a = rand(rndint);
- X obj[i].xvel = cos((double) a);
- X obj[i].yvel = sin((double) a);
- X obj[i].shape = ASTSHAPE1;
- X obj[i].mass = M_BIG;
- X obj[i].alive = 1;
- X }
- X numasts = i;
- X}
- X
- Xmakeenemy(level) /* Start an enemy ship */
- X int level;
- X{ extern Objtype obj[SHIP+1];
- X extern int height, rndint;
- X unsigned char c;
- X
- X obj[ENEMY].alive = 1;
- X obj[ENEMY].x = 0;
- X obj[ENEMY].y = (double) height/4;
- X c = rand(rndint); obj[ENEMY].y += (double) c; /* May put enemy outside window */
- X obj[ENEMY].xvel = (double) level/2;
- X obj[ENEMY].yvel = 0;
- X}
- X
- Xint nextast() /* Find next unused asteroid object */
- X{ extern Objtype obj[SHIP+1];
- X int i;
- X for (i = 0; obj[i].alive; i++); /* guaranteed to find one */
- X return i;
- X}
- X
- Xint collide(i, j) /* Returns non-zero if i collided with j */
- X /* Ship must be j! (See below) */
- X int i, j;
- X{ extern Objtype obj[SHIP+1];
- X extern int shapesize[LASTSHAPE+1];
- X extern double drawscale;
- X double mi, mj, /* Slopes of lines */
- X ix1, ix2, iy1, iy2, jx1, jx2, jy1, jy2, /* Endpoints */
- X roti, rotj,
- X xcross, ycross, /* coord of intersection */
- X z;
- X int diff, xd, yd,
- X a, b,
- X shapei, shapej;
- X xd = obj[i].x - obj[j].x;
- X yd = obj[i].y - obj[j].y;
- X diff = sqrt((double)(xd*xd + yd*yd));
- X shapei = obj[i].shape; shapej = obj[j].shape;
- X /* Note this will miss if drawscale is < 0 */
- X if (diff < (shapesize[shapei] + shapesize[shapej])*drawscale)
- X { /* If both are round objects, approximation is good */
- X if (shapei < SHIPSHAPE && shapej < SHIPSHAPE) return 1;
- X if (j == SHIP && shield_on) return 1; /* Ship always j! */
- X roti = obj[i].rot; rotj = obj[j].rot;
- X ix1 = (double) obj[i].x; iy1 = (double) obj[i].y;
- X for (a = 1; a < numpairs[shapei]; a++)
- X { ix2 = ix1 + (double) shapes[shapei][a].length * drawscale *
- X cos(shapes[shapei][a].angle + roti);
- X iy2 = iy1 + (double) shapes[shapei][a].length * drawscale *
- X sin(shapes[shapei][a].angle + roti);
- X if (ix1 == ix2)
- X { printf("\nif1 = if2"); return 1;} /* Easy way out */
- X mi = (iy2-iy1)/(ix2-ix1);
- X z = mi*ix1;
- X jx1 = (double) obj[j].x; jy1 = (double) obj[j].y;
- X for (b = 1; b < numpairs[shapej]; b++)
- X { jx2 = jx1 + (double) shapes[shapej][b].length *
- X drawscale * cos(shapes[shapej][b].angle + rotj);
- X jy2 = jy1 + (double) shapes[shapej][b].length *
- X drawscale * sin(shapes[shapej][b].angle + rotj);
- X if (jx1 == jx2)
- X { ycross = ix1 + (jx1-ix1)*mi;
- X if ((jx1-ix1) * (ix2-jx1) >= 0 &&
- X (ycross-jy1)*(jy2-ycross) >= 0)
- X return 1;
- X }
- X mj = (jy2-jy1)/(jx2-jx1);
- X if (mj == mi) continue; /* Parallel lines */
- X xcross = (iy1 - jy1 + mj*jx1 - z) / (mj - mi);
- X if ((xcross-ix1) * (ix2-xcross) > 0
- X && (xcross-jx1) * (jx2-xcross) > 0) return 1;
- X jx1 = jx2; jy1 = jy2;
- X }
- X ix1 = ix2; iy1 = iy2;
- X } }
- X return 0;
- X}
- X
- Xblastpair(i, j) /* Generate random velocity vector v. */
- X int i, j ; /* Add v to i, -v to j. */
- X{ extern int rndint;
- X extern Objtype obj[SHIP+1];
- X unsigned char c; /* for rand */
- X double vx, vy;
- X c = rand(rndint);
- X/* c = 4 - c>>5; if you need angles from -3 to 4 */
- X c>>2; /* possibly save some time on sin/cos */
- X vx = cos((double) c); vy = sin((double) c);
- X obj[i].xvel = obj[i].xvel + vx;
- X obj[i].yvel = obj[i].yvel + vy;
- X obj[j].xvel = obj[j].xvel - vx;
- X obj[j].yvel = obj[j].yvel - vy;
- X obj[i].rotvel = obj[i].rotvel + .05;
- X obj[j].rotvel = obj[j].rotvel - .05;
- X}
- X
- X/* dot product of 2 vectors */
- X#define dot(i,j) (i.x*j.x + i.y*j.y)
- X/* rotational inertia (constant eliminated) of obj. i */
- X#define rotinert(i) (double) (obj[i].mass*shapesize[obj[i].shape]*shapesize[obj[i].shape])
- X
- X/* cause two objects to collide elastically */
- Xbounce(i, j)
- Xint i,j;
- X{
- Xdouble rotrat, temp;
- Xextern Objtype obj[SHIP+1];
- XVector vi, vj, /* velocity of objs i, j */
- X ij, /* vector from center of i to center of j */
- X vi_ij, vj_ij, /* velocity of obj along vector ij */
- X vipij, vjpij, /* velocity perpendicular to ij */
- X vi_ijf, vj_ijf; /* post-collision velocity along ij */
- X
- Xvi.x = obj[i].xvel; vi.y = obj[i].yvel;
- Xvj.x = obj[j].xvel; vj.y = obj[j].yvel;
- Xij.x = obj[j].x - obj[i].x; ij.y = obj[j].y - obj[i].y;
- Xij.mag = sqrt(ij.x*ij.x + ij.y*ij.y);
- X/*
- XCalculate velocities projected onto ij;
- X vi_ij = vi*cos(a) = (vi dot ij) / |ij| */
- Xvi_ij.mag = dot(vi, ij) / ij.mag;
- Xvi_ij.x = (ij.x * vi_ij.mag) / ij.mag;
- Xvi_ij.y = (ij.y * vi_ij.mag) / ij.mag;
- Xvj_ij.mag = dot(vj, ij) / ij.mag;
- Xvj_ij.x = (ij.x * vj_ij.mag) / ij.mag;
- Xvj_ij.y = (ij.y * vj_ij.mag) / ij.mag;
- Xif (vi_ij.mag - vj_ij.mag < 0) /* Objs moving away from each other -
- X Since objs are round (at least when bouncing), this means
- X they are moving away from each other already. */
- X return;
- X/*
- XCalculate component of velocities perpendicular to ij:
- X |vipij| = |vi|*sin(a) = |vi x ij| / |ij|
- XSame as
- X |vipij| = |vi|*cos(pi/2 - a) = (vi dot (perp. to ij)) / |ij| */
- Xtemp = vi.y*ij.x - vi.x*ij.y; /* - (cross product when 3rd coord is 0)*/
- Xtemp /= (ij.mag*ij.mag);
- Xvipij.x = -ij.y*temp; vipij.y = ij.x*temp;
- Xtemp = (vj.x*ij.y - vj.y*ij.x) / (ij.mag*ij.mag);
- Xvjpij.x = -ij.y*temp; vjpij.y = ij.x*temp;
- X/*
- XCalculate the linear elastic collision along ij:
- X mass(i)*vi_ij + mass(j)*vj_ij = mass(i)*vi_ijf + mass(j)*vj_ijf
- X vi_ij + vi_ijf = vj_ij + vj_ijf (derived by dividing equation
- X for conservation of kinetic energy by eq. for cons. of momentum) */
- Xtemp = obj[i].mass/obj[j].mass;
- Xvj_ijf.x = (temp * (2*vi_ij.x - vj_ij.x) + vj_ij.x) / (1 + temp);
- Xvj_ijf.y = (temp * (2*vi_ij.y - vj_ij.y) + vj_ij.y) / (1 + temp);
- Xvi_ijf.x = vj_ijf.x + vj_ij.x - vi_ij.x;
- Xvi_ijf.y = vj_ijf.y + vj_ij.y - vi_ij.y;
- X/*
- XNow, given vi_ijf and vj_ijf, add them to the perpendicular
- X components to get final velocity vectors */
- Xobj[i].xvel = vi_ijf.x + vipij.x;
- Xobj[i].yvel = vi_ijf.y + vipij.y;
- Xobj[j].xvel = vj_ijf.x + vjpij.x;
- Xobj[j].yvel = vj_ijf.y + vjpij.y;
- X/*
- XNow calculate rotational velocity exchange */
- Xrotrat = rotinert(i)/rotinert(j);
- Xtemp = rotrat * (2*obj[i].rotvel - obj[j].rotvel) / (1+rotrat);
- Xobj[i].rotvel = temp + obj[j].rotvel - obj[i].rotvel;
- Xobj[j].rotvel = temp;
- X}
- X
- Xbotline(disp, window, gc) /* Print status line text */
- X Display *disp;
- X Drawable window;
- X GC gc;
- X{ extern int highscore, ships, score;
- X char text[70];
- X sprintf(text, "Ships:%2d Score:%6d Shield: High:%6d",
- X ships, score, highscore);
- X XDrawImageString (disp, window, gc, 0, height+letheight,
- X text, strlen(text));
- X}
- X
- Xprintss(disp, window, gc) /* Print ships and score */
- X Display *disp;
- X Drawable window;
- X GC gc;
- X{ extern int height, highscore, oldscore, ships, score;
- X extern Objtype obj[SHIP+1]; /* to kill ship */
- X char sstring[30];
- X
- X if (score != oldscore)
- X { if (score/10000 > oldscore/10000)
- X { ships++; botline(disp, window, gc);}
- X if (score/10000 < oldscore/10000)
- X { ships--; botline(disp, window, gc);
- X if (!ships) obj[SHIP].alive = 0;
- X }
- X if (score > highscore) /* Separate if to avoid flashing */
- X { highscore = score;
- X sprintf(sstring, "%6d", highscore);
- X XDrawImageString (disp, window, gc, 460,
- X height+letheight, sstring, strlen(sstring));
- X }
- X sprintf(sstring, "%6d", score);
- X XDrawImageString (disp, window, gc, 170, height+letheight,
- X sstring, strlen(sstring));
- X oldscore = score;
- X }
- X
- X /* Draw shield energy bar */
- X XFillRectangle(disp, window, gc, 340, height+8, energy>>1, 10);
- X XClearArea(disp, window, 340+(energy>>1), height+8, 8, 10, False);
- X}
- X
- Xupscore(killer, up) /* Only award score for things the player shot */
- X int killer, up;
- X{ extern int score;
- X if (killer != ENEMYBUL && killer != SHIP)
- X score = score + up;
- X}
- X
- X/* boom, movebooms, drawbooms all by Peter Phillips */
- Xboom(ob, particles, duration)
- Xint ob;
- Xint particles;
- Xint duration;
- X{ extern int rndint;
- X int i;
- X unsigned int r1, r2;
- X Boom b;
- X double x, y;
- X double angle, length;
- X
- X b = (Boom) malloc(sizeof(struct _Boom));
- X b->dur = duration;
- X b->part = particles;
- X x = obj[ob].x;
- X y = obj[ob].y;
- X for (i = 0; i < particles; i++) {
- X r1 = (rand(rndint) >> 2) % 100;
- X r2 = (rand(rndint) >> 2) % 7;
- X
- X b->bcoord[i][0] = x;
- X b->bcoord[i][1] = y;
- X angle = r1 * pi / 50.0;
- X length = 3 + r2;
- X b->bvec[i][0] = cos(angle) * length + obj[ob].xvel;
- X b->bvec[i][1] = sin(angle) * length + obj[ob].yvel;
- X }
- X b->next = blist;
- X blist = b;
- X}
- X
- X/* move the various booms that are active */
- Xmovebooms()
- X{
- X int i;
- X Boom b, prevb;
- X
- X prevb = NULL;
- X b = blist;
- X while (b != NULL) {
- X b->dur--;
- X if (b->dur < 0) { /* delete this boom */
- X Boom temp;
- X
- X temp = b;
- X if (prevb == NULL) {
- X blist = b->next;
- X } else {
- X prevb->next = b->next;
- X }
- X b = b->next;
- X free(temp);
- X } else { /* move boom, advance list */
- X for (i = 0; i < b->part; i++) {
- X b->bcoord[i][0] += b->bvec[i][0];
- X b->bcoord[i][1] += b->bvec[i][1];
- X }
- X prevb = b;
- X b = b->next;
- X }
- X }
- X}
- X
- X/* Draw the various booms */
- Xdrawbooms(disp, window, gc)
- X Display *disp;
- X Drawable window;
- X GC gc;
- X{
- X int i;
- X Boom b;
- X XPoint figure[BMAX];
- X
- X b = blist;
- X while (b != NULL) {
- X for (i = 0; i < b->part; i++) {
- X figure[i].x = (int) b->bcoord[i][0];
- X figure[i].y = (int) b->bcoord[i][1];
- X }
- X XDrawPoints(disp, window, gc, figure, b->part, CoordModeOrigin);
- X b = b->next;
- X }
- X}
- X
- Xdeletebooms() /* delete all booms */
- X{ Boom b;
- X
- X b = blist;
- X while (b != NULL)
- X { b->dur = 0;
- X b = b->next;
- X} }
- X
- Xkillast(killer, i)
- X int killer, i; /* i = Asteroid # to kill */
- X{ extern Objtype obj[SHIP+1];
- X extern int numasts;
- X int k, na, oldna;
- X
- X if (obj[i].shape == ASTSHAPE1)
- X { na = nextast(); /* Could put 6 lines in a sub */
- X obj[na].x = obj[i].x;
- X obj[na].y = obj[i].y;
- X obj[na].xvel = obj[i].xvel;
- X obj[na].yvel = obj[i].yvel;
- X obj[na].alive++;
- X obj[na].shape = ASTSHAPE2;
- X obj[na].mass = M_MED;
- X obj[i].shape = ASTSHAPE2;
- X obj[i].mass = M_MED;
- X blastpair(i, na);
- X boom(i, 30, 12);
- X numasts = numasts + 1;
- X upscore(killer, 25);
- X }
- X else if (obj[i].shape == ASTSHAPE2)
- X {
- X for (k = 0; k < 3; k++)
- X { oldna = na;
- X na = nextast();
- X obj[na].x = obj[i].x;
- X obj[na].y = obj[i].y;
- X obj[na].xvel = obj[i].xvel;
- X obj[na].yvel = obj[i].yvel;
- X obj[na].alive++;
- X obj[na].shape = ASTSHAPE3;
- X obj[na].mass = M_SMALL;
- X if (k == 1) blastpair(oldna,na);
- X }
- X obj[i].shape = ASTSHAPE3;
- X obj[i].mass = M_SMALL;
- X blastpair(na, i);
- X boom(i, 20, 10);
- X numasts = numasts + 3;
- X upscore(killer, 50);
- X }
- X else if (obj[i].shape == ASTSHAPE3)
- X { boom(i, 10, 8);
- X obj[i].alive = 0; numasts--; upscore(killer, 100);}
- X else /* enemy {ship or bullet} */
- X { boom(i, 9, 7);
- X obj[i].alive = 0; upscore(killer, 500);}
- X}
- Xmoveobjs(crash)
- X int *crash;
- X{ extern Objtype obj[SHIP+1];
- X extern int ships;
- X extern double speedscale;
- X int i, j; /* Indexes */
- X double *temp;
- X
- X movebooms();
- X for (i = 0; i < LASTOBJ+1; i++)
- X if (obj[i].alive)
- X { temp = &obj[i].x;
- X *temp = *temp + obj[i].xvel*speedscale;
- X while (*temp < 0) *temp = *temp + (double) width;
- X while (*temp > width) *temp = *temp - (double) width;
- X temp = &obj[i].y;
- X *temp = *temp + obj[i].yvel*speedscale;
- X while (*temp < 0) *temp = *temp + height;
- X while (*temp > height) *temp = *temp - height;
- X obj[i].rot = obj[i].rot + obj[i].rotvel;
- X }
- X for (i = 0; i < FBUL; i++)
- X if (obj[i].alive)
- X {
- X if (obj[SHIP].alive && collide(i, SHIP))
- X { if (shield_on) bounce(SHIP, i);
- X else
- X { *crash = 2;
- X ships--; obj[SHIP].alive = 0;
- X killast(SHIP, i);
- X } }
- X for (j = ENEMYBUL; j < LASTBUL+1; j++)
- X if (obj[j].alive && collide(i, j) && (j != ENEMYBUL || (i != ENEMYBUL && i != ENEMY)))
- X { obj[j].alive = 0; /* Kill the bullet */
- X killast(j,i);
- X }
- X }
- X}
- X
- Xfire()
- X{ extern Objtype obj[SHIP+1];
- X extern int width, nextbul;
- X extern double drawscale, speedscale;
- X double *shiprot, cosrot, sinrot;
- X
- X obj[nextbul].alive++;
- X shiprot = &obj[SHIP].rot;
- X cosrot = cos(*shiprot); sinrot = sin(*shiprot);
- X obj[nextbul].x = obj[SHIP].x + 20 * cosrot * drawscale;
- X obj[nextbul].y = obj[SHIP].y + 20 * sinrot * drawscale;
- X obj[nextbul].xvel = obj[SHIP].xvel + 10 * cosrot;
- X obj[nextbul].yvel = obj[SHIP].yvel + 10 * sinrot;
- X obj[nextbul].rot = *shiprot;
- X obj[nextbul].time = width/(speedscale*11); /* loops before bullet expires */
- X nextbul++; if (nextbul == LASTBUL+1) nextbul = FBUL;
- X}
- X
- Xhyper()
- X{ extern Objtype obj[SHIP+1];
- X extern int width, height, rndint;
- X unsigned char c;
- X unsigned int i;
- X
- X c = rand(rndint); i = c; i<<=2; /* 0 - 1024 */
- X while (i > width) i -= width;
- X obj[SHIP].x = (double) i;
- X c = rand(rndint); i = c; i<<=2; /* 0 - 1024 */
- X while (i > height) i -= height;
- X obj[SHIP].y = (double) i;
- X}
- X
- Xvdraw(disp, window, gc, shape, x, y, rot)
- X Display *disp;
- X Drawable window;
- X GC gc;
- X int shape;
- X double x, y, rot;
- X
- X{ int line;
- X extern PolarPair shapes[LASTSHAPE+1][11];
- X extern int numpairs[LASTSHAPE+1];
- X extern double drawscale;
- X XPoint figure[20];
- X figure[0].x = (int) x; figure[0].y = (int) y;
- X for (line=1; line < numpairs[shape]; line++) /* 2 pairs = 1 line */
- X { figure[line].x = (int) shapes[shape][line].length *
- X cos(shapes[shape][line].angle + rot) * drawscale;
- X figure[line].y = (int) shapes[shape][line].length *
- X sin(shapes[shape][line].angle + rot) * drawscale;
- X }
- X XDrawLines (disp, window, gc, figure, numpairs[shape], CoordModePrevious);
- X}
- X
- Xmain(argc, argv)
- X int argc;
- X char **argv;
- X{ Colormap cmap;
- X Cursor cursor;
- X Display *disp;
- X Font font;
- X GC gc, pmgc;
- X KeySym key;
- X Pixmap pixmap;
- X Window window;
- X XColor black, exact;
- X XEvent event;
- X XSizeHints hint;
- X extern int width, height;
- X int screen, depth;
- X char text[30];
- X unsigned long fg, bg;
- X
- X extern double drawscale, speedscale;
- X extern int numasts, rndint, ships, score, oldscore;
- X extern Objtype obj[SHIP+1];
- X unsigned char c; /* for rand */
- X double *temp, dx, dy, dist;
- X int level, crashed, flashon, len, pause = 0, delay = 64,
- X enemycount, undraw = 0, counter, counterstart = 1,
- X i, /* index for drawing objs, counting bullets */
- X r; /* radius of shield circle */
- X
- X disp = XOpenDisplay(0);
- X if (disp == (Display *) NULL)
- X { fprintf(stderr, "Could not open display\n");
- X exit(1);
- X }
- X screen = DefaultScreen(disp);
- X bg = BlackPixel(disp, screen);
- X fg = WhitePixel(disp, screen);
- X hint.x = 150; hint.y = 200; hint.width = 550; hint.height = 550;
- X hint.flags = PPosition | PSize;
- X width = hint.width; height = hint.height-letheight-1;
- X depth = DefaultDepth (disp, screen);
- X window = XCreateSimpleWindow (disp, DefaultRootWindow(disp),
- X hint.x, hint.y, hint.width, hint.height, 5, fg, bg);
- X pixmap = XCreatePixmap (disp, window, width, height, depth);
- X XSetStandardProperties (disp, window, "asteroids", "asteroids", None,
- X argv, argc, &hint);
- X gc = XCreateGC (disp, window, 0, 0);
- X XSetGraphicsExposures(disp, gc, 0); /* IMPORTANT! If you do not
- X specifically ask not to get Expose events, every XCopyArea
- X will generate one, & the event queue will fill up. */
- X font = XLoadFont(disp, "10x20\0"); /* If you don't have this
- X font, try replacing it with 9x15\0 */
- X XSetFont(disp, gc, font);
- X pmgc = XCreateGC (disp, window, 0, 0);
- X XSetBackground (disp, gc, bg);
- X XSetForeground (disp, gc, fg);
- X XSetForeground (disp, pmgc, bg); /* fg of pixmap is bg of window */
- X XSelectInput (disp, window,
- X KeyPressMask | KeyReleaseMask | StructureNotifyMask);
- X XMapRaised (disp, window);
- X
- X /* Erase cursor. Just delete next 5 lines if any error. */
- X cmap = XDefaultColormap(disp, screen);
- X XAllocNamedColor(disp, cmap, "Black", &exact, &black);
- X cursor = XCreateFontCursor(disp, XC_dot);
- X XRecolorCursor(disp, cursor, &black, &black);
- X XDefineCursor(disp, window, cursor);
- X
- X XFillRectangle (disp, pixmap, pmgc, 0, 0, width, height);
- X/* Can delete next line if it causes trouble */
- X srand((unsigned) time(0)); /* By Craig Smith */
- X initasts();
- XNewgame:
- X deletebooms();
- X ships = 3;
- X score = 0; oldscore = -1;
- X for (level = 0; ;)
- X { if (level < 8) level++;
- X makeasts (level);
- XNewship: botline(disp, window, gc);
- X if (!obj[SHIP].alive)
- X { obj[SHIP].x = width/2;
- X obj[SHIP].y = height/2;
- X obj[SHIP].xvel = 0;
- X obj[SHIP].yvel = 0;
- X obj[SHIP].rot = 3*pi/2;
- X obj[SHIP].rotvel = 0;
- X energy = 80;
- X shield_on = 0;
- X }
- X obj[SHIP].alive = (ships > 0);
- X crashed = 0; flashon = 0; enemycount = 20;
- X counter = 0;
- X while (numasts)
- X { for (i = FBUL; i < LASTBUL+1; i++) /* Bullet timer */
- X if (obj[i].alive)
- X { obj[i].time--;
- X if (!obj[i].time) obj[i].alive = 0; /* Not --! */
- X }
- X while (XEventsQueued(disp, QueuedAfterReading))
- X { XNextEvent(disp, &event);
- X switch (event.type)
- X { case MappingNotify:
- X XRefreshKeyboardMapping (&event);
- X break;
- X case ConfigureNotify:
- X width = event.xconfigure.width;
- X height = event.xconfigure.height-letheight-1;
- X XFreePixmap (disp, pixmap);
- X pixmap = XCreatePixmap (disp, window, width, height, depth);
- X XFillRectangle (disp, pixmap, pmgc, 0, 0, width, height);
- X botline(disp, window, gc);
- X break;
- X case KeyPress:
- X len = XLookupString (&event, text, 10, &key, 0);
- X if (len == 1 && !shield_on) switch (text[0])
- X { case 'e':
- X obj[SHIP].rotvel = obj[SHIP].rotvel - .1; break;
- X case 'r':
- X obj[SHIP].rotvel = obj[SHIP].rotvel + .1; break;
- X case 'w':
- X obj[SHIP].rot -= pi/4; break;
- X case 't':
- X obj[SHIP].rot += pi/4; break;
- X case 'd':
- X obj[SHIP].rotvel = obj[SHIP].rotvel - .02; break;
- X case 'f':
- X obj[SHIP].rotvel = obj[SHIP].rotvel + .02; break;
- X case THRUST:
- X obj[SHIP].xvel += cos(obj[SHIP].rot);
- X obj[SHIP].yvel += sin(obj[SHIP].rot);
- X obj[SHIP].shape = SHIPTHRSHAPE;
- X break;
- X case FIRE:
- X if (obj[SHIP].alive) fire(); break;
- X case ' ':
- X if (obj[SHIP].alive)
- X { hyper(); flashon = 1;
- X/* NOT XSetForeground (disp, gc, bg);
- X If you set the fg black, & print the highscore, it will effectively erase it. */
- X XSetForeground (disp, pmgc, fg);
- X XFillRectangle (disp, pixmap, pmgc, 0, 0, width, height);
- X }
- X break;
- X case SHIELD:
- X if (energy)
- X { shield_on = 1;
- X obj[SHIP].shape = SHIPSHAPE;}
- X break;
- X case '.': /* decrease delay */
- X if (delay > 1) delay >>=1; break;
- X case ',': /* increase delay */
- X delay <<=1; break;
- X case 'm': /* decrease drawscale - may go negative */
- X drawscale -= .1; break;
- X case 'n': /* increase drawscale */
- X drawscale += .1; break;
- X case '2': /* increase speedscale */
- X speedscale += .1; break;
- X case '1': /* decrease speedscale */
- X speedscale -= .1; break;
- X case 'b': /* increase moves/update */
- X counterstart++; break;
- X case 'v': /* decrease moves/update */
- X if (counterstart > 1) counterstart--;
- X break;
- X case 'u': /* undraw erase */
- X undraw = 1; break;
- X case 'x': /* XFill erase */
- X undraw = 0; break;
- X case PAUSE: /* pause */
- X pause = 1 - pause; break;
- X case '+': /* cheat */
- X ships++; botline(disp, window, gc); break;
- X case 'Q': /* quit */
- X goto End;
- X case 's': /* start new ship */
- X if (!obj[SHIP].alive)
- X if (ships < 1) goto Newgame;
- X else goto Newship;
- X break;
- X }
- X break;
- X case KeyRelease:
- X len = XLookupString(&event, text, 10, &key, 0);
- X if (len == 1) switch (text[0])
- X { case 'e':
- X obj[SHIP].rotvel = 0; break;
- X case 'r':
- X obj[SHIP].rotvel = 0; break;
- X case THRUST:
- X obj[SHIP].shape = SHIPSHAPE;
- X break;
- X case SHIELD:
- X shield_on = 0; break;
- X }
- X/* break; */
- X } }
- X if (!pause)
- X { moveobjs(&crashed);
- X if (ships) score--; /* timer effect */
- X if (!counter)
- X { counter = counterstart; /* Restart counter */
- X if (crashed == 2)
- X { crashed--; flashon++;
- X boom(SHIP, BMAX-1, 70);
- X XSetForeground (disp, pmgc, fg);
- X XFillRectangle (disp, pixmap, pmgc, 0, 0, width, height);
- X botline(disp, window, gc);
- X }
- X /* Write copyright notice */
- X if (!ships && blist == NULL && !undraw)
- X { sprintf(text, "Xasteroids");
- X XDrawImageString (disp, pixmap, gc,
- X width/2-50, height/2-2*letheight,
- X text, strlen(text));
- X sprintf(text, "Copyright 1990 by Phil Goetz");
- X XDrawImageString (disp, pixmap, gc,
- X width/2-140, height/2,
- X text, strlen(text));
- X sprintf(text, "goetz@cs.buffalo.edu");
- X XDrawImageString (disp, pixmap, gc,
- X width/2-100, height/2+2*letheight,
- X text, strlen(text));
- X }
- X /* Draw objects */
- X for (i = 0; i <= LASTOBJ; i++)
- X if (obj[i].alive)
- X vdraw(disp, pixmap, gc, obj[i].shape,
- X obj[i].x, obj[i].y, obj[i].rot);
- X if (shield_on && obj[SHIP].alive)
- X { r = abs((int) (drawscale*SHIPSIZE));
- X XDrawArc(disp, pixmap, gc,
- X ((int) obj[SHIP].x) - r,
- X ((int) obj[SHIP].y) - r,
- X 2*r, 2*r, 0, 360*64);
- X energy--;
- X if (!energy) shield_on = 0;
- X }
- X drawbooms(disp, pixmap, gc);
- X /* update display: */
- X XCopyArea(disp, pixmap, window, gc, 0, 0, width, height, 0, 0);
- X printss(disp, window, gc);
- X /* erase objects */
- X if (undraw)
- X { for (i = 0; i <= LASTOBJ; i++)
- X if (obj[i].alive)
- X vdraw(disp, pixmap, pmgc, obj[i].shape,
- X obj[i].x, obj[i].y, obj[i].rot);
- X }
- X else
- X XFillRectangle (disp, pixmap, pmgc, 0, 0, width, height);
- X if (flashon)
- X { flashon--;
- X XSetForeground (disp, pmgc, bg);
- X XFillRectangle (disp, pixmap, pmgc, 0, 0, width, height);
- X }
- X XSync(disp, 0);
- X }
- X counter--;
- X c = rand(rndint)>>8;
- X if (!obj[ENEMY].alive)
- X { if (c < level)
- X { c = rand(rndint);
- X if (c < level * 10) makeenemy(level);
- X } }
- X else
- X obj[ENEMY].yvel += (c>128+6*obj[ENEMY].yvel) ? .5 : -.5;
- X enemycount--; if (!enemycount)
- X { enemycount = 100;
- X if (obj[ENEMY].alive)
- X { obj[ENEMYBUL].alive++;
- X obj[ENEMYBUL].x = obj[ENEMY].x;
- X obj[ENEMYBUL].y = obj[ENEMY].y;
- X dx = obj[SHIP].x - obj[ENEMY].x;
- X dy = obj[SHIP].y - obj[ENEMY].y;
- X dist = sqrt(dx*dx + dy*dy);
- X obj[ENEMYBUL].xvel = 3*dx/dist;
- X obj[ENEMYBUL].yvel = 3*dy/dist;
- X }
- X else obj[ENEMYBUL].alive = 0;
- X }
- X for (i = 0; i < delay; i++);
- X }
- X }
- X }
- XEnd: printf("\nYour high score was %d\n", highscore);
- X XFreeGC (disp, gc);
- X XFreeGC (disp, pmgc);
- X XFreePixmap (disp, pixmap);
- X XDestroyWindow (disp, window);
- X XCloseDisplay (disp);
- X exit(0);
- X}
- END_OF_FILE
- if test 27201 -ne `wc -c <'ast.c'`; then
- echo shar: \"'ast.c'\" unpacked with wrong size!
- fi
- # end of 'ast.c'
- fi
- if test -f 'ast.doc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ast.doc'\"
- else
- echo shar: Extracting \"'ast.doc'\" \(1291 characters\)
- sed "s/^X//" >'ast.doc' <<'END_OF_FILE'
- X Xasteroids
- X Copyright 1990 by Phil Goetz
- X goetz@cs.Buffalo.EDU
- X
- XKeypress Command
- X-------- -------
- X e Rotate counterclockwise ("left")
- X r Rotate clockwise ("right")
- X w Rotate 45 degrees counterclockwise
- X t Rotate 45 degrees clockwise
- X d Increase counterclockwise rotational velocity
- X f Increase clockwise rotational velocity
- X o Thrust
- X p Fire
- X ` Shields
- X space Hyperspace
- X s Start new ship in center of playing field
- X (Also used to start a new game)
- X esc Pause
- X Q Quit
- XSpeed commands: Key associated with faster speed is to the right of its
- X corresponding key associated with slower speed.
- X . Decrease delay: Speed game up
- X , Increase delay: Slow the game down
- X m Decrease size ("Minimize")
- X n Increase size
- X b Increase # of moves/frame
- X v Decrease # of moves/frame
- X 2 Increase scale of movement
- X 1 Decrease scale of movement
- X x Use XFillRectangle to erase screen
- X u Use undraw to erase screen
- X
- XObject Score
- X------- -----
- XBig asteroid 25
- XMedium asteroid 50
- XLittle asteroid 100
- XEnemy spaceship 500
- XEnemy bullet 500
- X
- XCommands can only be entered when the mouse pointer is in the
- Xasteroids window.
- X
- XResize the window with your window manager
- Xat any time for a different playing field.
- END_OF_FILE
- if test 1291 -ne `wc -c <'ast.doc'`; then
- echo shar: \"'ast.doc'\" unpacked with wrong size!
- fi
- # end of 'ast.doc'
- 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
-