home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume17 / xastrds3 / part01 < prev    next >
Encoding:
Internet Message Format  |  1993-03-20  |  40.4 KB

  1. Path: uunet!news.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v17i034:  xasteroids3 - asteroids arcade game for X, Ver 5, Part01/01
  5. Message-ID: <4575@master.CNA.TEK.COM>
  6. Date: 16 Feb 93 23:38:34 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 1316
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1713
  11.  
  12. Submitted-by: goetz@cs.Buffalo.EDU (Phil Goetz)
  13. Posting-number: Volume 17, Issue 34
  14. Archive-name: xasteroids3/Part01
  15. Supersedes: xasteroids2: Volume 13, Issue 80
  16. Environment: X11, Xlib
  17.  
  18.     [I added a simple Imakefile. Compiles and runs fine on a Sparc.  -br]
  19.  
  20. #! /bin/sh
  21. # This is a shell archive.  Remove anything before this line, then unpack
  22. # it by saving it into a file and typing "sh file".  To overwrite existing
  23. # files, type "sh file -c".  You can also feed this as standard input via
  24. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  25. # will see the following message at the end:
  26. #        "End of archive 1 (of 1)."
  27. # Contents:  README MANIFEST Imakefile Makefile.std xast.c xast.docs
  28. #   xast.man xasteroids
  29. # Wrapped by billr@saab on Tue Feb 16 15:34:54 1993
  30. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  31. if test -f 'README' -a "${1}" != "-c" ; then 
  32.   echo shar: Will not clobber existing file \"'README'\"
  33. else
  34. echo shar: Extracting \"'README'\" \(3060 characters\)
  35. sed "s/^X//" >'README' <<'END_OF_FILE'
  36. X     Here is the source to Xasteroids, version 5, 9 Feb 93.
  37. X
  38. X     This program runs under UNIX in the X-Windows or OpenWindows
  39. Xenvironment.  It could probably be modified for other operating systems
  40. Xwithout difficulty.  I compile it under quasi-BSD with this command:
  41. X
  42. X    cc -I/util/X11/include -L/util/X11/lib xast.c -lm -lX11 -o xast.exe -O
  43. X
  44. XThat is, include files /util/X11/include, use the library in /util/X11/lib,
  45. Xsource file ast.c, use the math and X11 libraries, object file will be ast.out,
  46. Xand Optimize.  The Makefile provided should do this for you if you type
  47. X
  48. X    make xast.exe
  49. X
  50. X     To run the program, type
  51. X
  52. X    xasteroids &
  53. X
  54. XThis runs the shell script which runs the game and saves high scores.
  55. XYou should modify the first line of the shell script to move to the proper
  56. Xdirectory.
  57. X
  58. X     Playing with scale of movement, object size, and window size can give you
  59. Xvery different games.
  60. X
  61. X     If you like the game, please send $5 to
  62. X
  63. X    Phil Goetz
  64. X    4023 Huckleberry Row
  65. X    Ellicott City, MD 21043
  66. X
  67. X     Even if you don't register, please send a note to my e-mail address
  68. Xso I know how many people use Xasteroids.
  69. XSend any comments, suggestions, bug reports, modifications, etc., to
  70. X
  71. X    goetz@cs.buffalo.EDU
  72. X
  73. X     If you modify the game, feel free to post your version, PROVIDED that
  74. Xyou retain my copyright notice, the credits, and note which version yours
  75. Xwas derived from and its release date, what changes you made, and your
  76. Xrelease date.  I do not intend to release any more versions myself.
  77. XI wash my hands of it.
  78. X
  79. X     David Elliot (dce@sonyusa.sony.com) says that he had to put an
  80. XXSync(disp) after the XDrawLines call or he would get protocol errors.
  81. X
  82. X     On anything slower than a SPARCstation 1, or on any color screen,
  83. Xit will really drag.  There should be a way to set color screens to use
  84. Xa bitmap of depth 1, but I don't know how.  Please tell me if you do.
  85. X     The code is not optimized because the XWindows
  86. Xcalls take the vast majority of the time.  I tried, for instance,
  87. Xreading sines and cosines from a table instead of calculating them -
  88. Xit made no noticeable difference in speed.  Similarly, the collision
  89. Xdetection could be optimized only to check objects nearby - but why
  90. Xbother.  Same goes for using registers, pointers to frequently-referenced
  91. Xarray elements, etc.  It MIGHT make a significant difference in runtime
  92. Xif you replace the vector drawing with bitmaps.  It runs a LOT slower on
  93. Xcolor displays.
  94. X     The vast majority of time seems to be used in erasing the pixmap
  95. Xeach round, & there isn't much to do about that.  My tests have indicated
  96. Xthat blanking individual asteroids rather than the whole screen would
  97. Xtake comparable time, unless you had a complicated routine to optimize
  98. Xblanking.
  99. X
  100. XBy
  101. X    Phil Goetz    <goetz@cs.buffalo.edu>
  102. XContributors:
  103. X    Peter Phillips    <pphillip@cs.ubc.ca>
  104. X    Pat Ryan    <pat@jaameri.gsfc.nasa.gov>
  105. X    Craig Smith    <csmith@cscs.UUCP>
  106. X    Doug Merritt    <doug@netcom.com>
  107. X    James Berg    <berg@plains>        (makefile)
  108. X    David Partain    <dlp@ida.liu.se>    (original man page)
  109. X    Chris Moore    <moore@src.bae.co.uk>    (hi score script)
  110. END_OF_FILE
  111. if test 3060 -ne `wc -c <'README'`; then
  112.     echo shar: \"'README'\" unpacked with wrong size!
  113. fi
  114. # end of 'README'
  115. fi
  116. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  117.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  118. else
  119. echo shar: Extracting \"'MANIFEST'\" \(362 characters\)
  120. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  121. X   File Name        Archive #    Description
  122. X-----------------------------------------------------------
  123. X Imakefile                  1    
  124. X MANIFEST                   1    This shipping list
  125. X Makefile.std               1    
  126. X README                     1    
  127. X xast.c                     1    
  128. X xast.docs                  1    
  129. X xast.man                   1    
  130. X xasteroids                 1    
  131. END_OF_FILE
  132. if test 362 -ne `wc -c <'MANIFEST'`; then
  133.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  134. fi
  135. # end of 'MANIFEST'
  136. fi
  137. if test -f 'Imakefile' -a "${1}" != "-c" ; then 
  138.   echo shar: Will not clobber existing file \"'Imakefile'\"
  139. else
  140. echo shar: Extracting \"'Imakefile'\" \(253 characters\)
  141. sed "s/^X//" >'Imakefile' <<'END_OF_FILE'
  142. X# simple Imakefile for xasteroids
  143. XSRCS = xast.c
  144. XOBJS = xast.o
  145. X
  146. XEXTRA_LIBRARIES = -lX11 -lm
  147. X
  148. XSimpleProgramTarget(xast)
  149. X#
  150. X#   define dependencies
  151. XDependTarget()
  152. X#
  153. X#   define installation rules
  154. XInstallProgram(xast,$(BINDIR))
  155. XInstallManPage(xast,$(MANDIR))
  156. END_OF_FILE
  157. if test 253 -ne `wc -c <'Imakefile'`; then
  158.     echo shar: \"'Imakefile'\" unpacked with wrong size!
  159. fi
  160. # end of 'Imakefile'
  161. fi
  162. if test -f 'Makefile.std' -a "${1}" != "-c" ; then 
  163.   echo shar: Will not clobber existing file \"'Makefile.std'\"
  164. else
  165. echo shar: Extracting \"'Makefile.std'\" \(488 characters\)
  166. sed "s/^X//" >'Makefile.std' <<'END_OF_FILE'
  167. X#CC = gcc -Wall
  168. XCC = cc
  169. XCFLAGS = -O
  170. X#INCLUDES = -I/usr/local/include
  171. XINCLUDES = -I/util/X11/include
  172. X#LDFLAGS = -s -L/usr/local/lib
  173. XLDFLAGS = -s -L/util/X11/lib
  174. XLIBS = -lm -lX11
  175. XTARGET = xast.exe
  176. XSRCS = xast.c
  177. XOBJS = xast.o 
  178. XALL = README xasteroids xast.docs xast.man Makefile $(SRCS) 
  179. X
  180. Xall:    $(TARGET)
  181. X
  182. X$(TARGET):    $(OBJS)
  183. X    $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
  184. X
  185. X.c.o:
  186. X    $(CC) $(CFLAGS) $(INCLUDES) -c $*.c
  187. X
  188. Xclean:
  189. X    rm -f $(OBJS) $(TARGET) core
  190. X
  191. Xshar:    $(ALL)
  192. X    shar -o $(TARGET).shar $(ALL)
  193. END_OF_FILE
  194. if test 488 -ne `wc -c <'Makefile.std'`; then
  195.     echo shar: \"'Makefile.std'\" unpacked with wrong size!
  196. fi
  197. # end of 'Makefile.std'
  198. fi
  199. if test -f 'xast.c' -a "${1}" != "-c" ; then 
  200.   echo shar: Will not clobber existing file \"'xast.c'\"
  201. else
  202. echo shar: Extracting \"'xast.c'\" \(27746 characters\)
  203. sed "s/^X//" >'xast.c' <<'END_OF_FILE'
  204. X/*    Xasteroids
  205. X    Copyright 1990 by Phil Goetz
  206. X    goetz@cs.buffalo.EDU
  207. X    Version 5, 9 Feb 93
  208. X
  209. X    Changes from version 4.3:
  210. X
  211. X        High score script.
  212. X        Enemy moves towards you at higher levels.
  213. X
  214. X    Changes from version 3:
  215. X
  216. X        Better collision detection:  Actually checks for intersection
  217. X            of line segments if non-round objects are very close.
  218. X        Explosions!  (Thanks to Peter Phillips.)
  219. X        Fine rotation repeating detected using KeyRelease.
  220. X        Thrust indicator behind ship.  (Thanks to Peter Phillips.)
  221. X        Doesn't place ship in center of screen for new levels.
  222. X        Seeds random-number generator with time.
  223. X            (Thanks to Craig Smith.)
  224. X        Shields!  (Thanks to Peter Phillips.  I rewrote the bounce code
  225. X            & added the energy bar & other refinements.)
  226. X        Solved won't-take-input bug. (Thanks to Doug Merritt.)
  227. X        Detects failure of XOpenDisplay. (Thanks to Pat Ryan.)
  228. X
  229. X    Contributors:    Peter Phillips <pphillip@cs.ubc.ca>
  230. X            Pat Ryan <pat@jaameri.gsfc.nasa.gov>
  231. X            Craig Smith <csmith@cscs.UUCP>
  232. X            Doug Merritt <doug@netcom.com>
  233. X            Makefile by James Berg <berg@plains>
  234. X            Hi score script by Chris Moore <moore@src.bae.co.uk>
  235. X            Man page by David Partain <dpl@ida.liu.se>
  236. X*/
  237. X#include <stdio.h>        /* For NULL    */
  238. X#include <X11/Xlib.h>
  239. X#include <X11/Xutil.h>
  240. X#include <X11/cursorfont.h>    /* For erasing cursor - not important    */
  241. X#include <math.h>
  242. X
  243. X/* Indexes for 1st dimension of obj    */
  244. X/* The order they are in is important    */
  245. X#define    AST    0
  246. X#define    ENEMY    96
  247. X#define ENEMYBUL 97
  248. X#define    FBUL    98
  249. X#define    LASTBUL    102
  250. X#define    SHIP    103
  251. X#define LASTOBJ 103    /* Must be ship!  See makeasts().    */
  252. X
  253. X/* Shapes    */
  254. X/* Order is important!  See collide().    */
  255. X#define    ASTSHAPE1    0
  256. X#define ASTSHAPE2    1
  257. X#define ASTSHAPE3    2
  258. X#define ENBULSH        3
  259. X#define    BULSHAPE    4
  260. X#define    SHIPSHAPE    5
  261. X#define SHIPTHRSHAPE    6
  262. X#define    ENEMYSHAPE    7
  263. X#define LASTSHAPE    7
  264. X
  265. X/* Masses    */
  266. X#define M_BIG    8.0
  267. X#define M_MED    4.0
  268. X#define M_SMALL    1.0
  269. X#define M_SHIP    1.5
  270. X#define M_ENEMY    1.0
  271. X#define M_BULLET 0.1
  272. X
  273. X/* Keys        */
  274. X#define FIRE        'p'
  275. X#define PAUSE        27    /* escape    */
  276. X#define SHIELD        '`'
  277. X#define THRUST        'o'
  278. X
  279. X#define BMAX        300    /* Max particles in a "boom" + 1    */
  280. X#define letheight    20    /* height of font    */
  281. X#define    pi        3.1415926535897932384
  282. X#define SHIPSIZE    28
  283. X
  284. Xtypedef struct _Boom *Boom;
  285. Xstruct _Boom {Boom next; int dur, part; double bcoord[BMAX][2], bvec[BMAX][2];};
  286. Xtypedef struct {int shape, alive, time;
  287. X        double mass, x, y, xvel, yvel, rot, rotvel;} Objtype;
  288. Xtypedef struct {double angle; int length;} PolarPair;
  289. Xtypedef struct {double x, y, mag;} Vector;
  290. X
  291. X/* Global variables:    */
  292. XObjtype    obj[SHIP+1];
  293. X/*    In shapes pairs, 1st # is radians, 2nd is length in pixels.
  294. X    Degrees: 0 ->, pi/2 down, pi <-, 3*pi/2 up
  295. X    IF YOU CHANGE THE SHAPES, you MUST change numpairs & shapesize
  296. X*/
  297. XPolarPair shapes[LASTSHAPE+1][11] =
  298. X    {    {{0,0}, {3*pi/2,40}, {0,20}, {pi/4,28}, {pi/2,40}, /* just crossed 0-deg line */
  299. X         {3*pi/4,28},{pi,40},{5*pi/4,28},{3*pi/2,40},{7*pi/4,28},{0,20}},
  300. X/*    hexagon if you prefer
  301. X        {{0,0}, {3*pi/2, 20}, {pi/6, 20}, {pi/2, 20},
  302. X                 {5*pi/6, 20}, {7*pi/6, 20}, {3*pi/2, 20}, {11*pi/6, 20}},
  303. X*/
  304. X        {{0,0}, {3*pi/2,20}, {0,10}, {pi/4,14}, {pi/2,20},
  305. X         {3*pi/4,14},{pi,20},{5*pi/4,14},{3*pi/2,20},{7*pi/4,14},{0,10}},
  306. X        {{0,0}, {3*pi/2,10}, {0,5}, {pi/4,7}, {pi/2,10},
  307. X         {3*pi/4,7},{pi,10},{5*pi/4,7},{3*pi/2,10},{7*pi/4,7},{0,5}},
  308. X        {{0,0}, {7*pi/4, 4}, {pi/4, 4}, {3*pi/4, 4}, {5*pi/4, 4}},
  309. X        {{0,0}, {0,10}},
  310. X        {{0,0}, {5*pi/4,28}, {0,20}, {pi/4,28},{3*pi/4,28},{pi,20},{7*pi/4,28}},    /* Ship */
  311. X        {{0,0}, {5*pi/4,28}, {0,20}, {pi/4,28},{3*pi/4,28},{pi,20},
  312. X         {7*pi/4,28}, {3*pi/4, 7}, {9*pi/8, 13}, {15*pi/8, 13}},    /* Thrusting ship */
  313. X        {{0,0}, {pi,20},{7*pi/4,28},{pi/4,28},{pi,20}}
  314. X    };
  315. XBoom    blist = NULL;
  316. Xdouble    drawscale = 1, speedscale = 1;
  317. Xint    width, height,
  318. X    energy,        /* # of turns shield is good for    */
  319. X    highscore = 0, level,
  320. X    nextbul = FBUL,            /* Obj# of next bullet fired    */
  321. X    numasts, oldscore = 99,
  322. X    rndint = 73, ships, score,
  323. X    numpairs[LASTSHAPE+1]    = {11, 11, 11, 5, 2, 7, 10, 5},
  324. X    shapesize[LASTSHAPE+1]    = {44, 21, 10, 2, 1, SHIPSIZE+1, 35, 20},
  325. X    shield_on;
  326. X
  327. Xinitasts()
  328. X{    int i;
  329. X    extern Objtype obj[SHIP+1];
  330. X
  331. X    for (i = 0; i < LASTOBJ+1; i++)
  332. X    {    obj[i].rot = 0;
  333. X        obj[i].rotvel = 0;
  334. X    }
  335. X    for (i = 0; i < ENEMY; i++)
  336. X    {    obj[i].shape = ASTSHAPE1;
  337. X    }
  338. X    obj[SHIP].shape = SHIPSHAPE;
  339. X    obj[SHIP].mass = M_SHIP;
  340. X    obj[ENEMY].shape = ENEMYSHAPE;
  341. X    obj[ENEMY].mass = M_ENEMY;
  342. X    obj[ENEMYBUL].shape = ENBULSH;
  343. X    obj[ENEMYBUL].mass = M_BULLET;
  344. X    for (i = FBUL; i < LASTBUL+1; i++)
  345. X    {    obj[i].shape = BULSHAPE;
  346. X        obj[i].mass = M_BULLET;
  347. X}    }
  348. X
  349. Xmakeasts()
  350. X{    int i;
  351. X    extern Objtype obj[SHIP+1];
  352. X    extern int level, numasts, rndint;
  353. X    extern double speedscale;
  354. X    unsigned char a;
  355. X
  356. X    for (i = 0; i < SHIP; i++)
  357. X        obj[i].alive = 0; /* Erase objs from last level except ship */
  358. X    for (i = ENEMYBUL; i < LASTBUL+1; i++)
  359. X        obj[i].time = 0;        /* No bullets in the air */
  360. X    for (i = 0; i < ((level > 8) ? 8 : level+4); i++)    /* Asteroids:    */
  361. X    {    a = rand(rndint); a>>=1;    /* a = rand# from 0 to 127 */
  362. X        if (a > 63)
  363. X            obj[i].x = (double) a;
  364. X            else obj[i].x = (double) (width - a);
  365. X        a = rand(rndint); a>>=1;    /* Now the same for y    */
  366. X        if (a >  63)
  367. X            obj[i].y = (double) a;
  368. X            else obj[i].y = (double) height - a;
  369. X        a = rand(rndint); a = 4 - a>>5;
  370. X        obj[i].rot = (double) a;
  371. X        a = rand(rndint);
  372. X        obj[i].rotvel = ((double) a)/2048;
  373. X        a = rand(rndint);
  374. X        obj[i].xvel = cos((double) a);
  375. X        obj[i].yvel = sin((double) a);
  376. X        obj[i].shape = ASTSHAPE1;
  377. X        obj[i].mass = M_BIG;
  378. X        obj[i].alive = 1;
  379. X    }
  380. X    numasts = i;
  381. X}
  382. X
  383. Xmakeenemy()    /* Start an enemy ship    */
  384. X{    extern Objtype obj[SHIP+1];
  385. X    extern int height, level, rndint;
  386. X    unsigned char c;
  387. X
  388. X    obj[ENEMY].alive = 1;
  389. X    obj[ENEMY].x = 0;
  390. X    obj[ENEMY].y = (double) height/4;
  391. X    c = rand(rndint); obj[ENEMY].y += (double) c; /* May put enemy outside window    */
  392. X    obj[ENEMY].xvel = .4 + ((double) level)/3.;
  393. X    obj[ENEMY].yvel = 0;
  394. X    obj[ENEMY].rot = 0;
  395. X    obj[ENEMY].rotvel = 0;
  396. X}
  397. X
  398. Xint nextast()    /* Find next unused asteroid object    */
  399. X{    extern Objtype obj[SHIP+1];
  400. X    int i;
  401. X    for (i = 0; obj[i].alive; i++);    /* guaranteed to find one    */
  402. X    return i;
  403. X}
  404. X
  405. Xint collide(i, j)    /* Returns non-zero if i collided with j    */
  406. X            /* Ship must be j!  (See below)            */
  407. X    int i, j;
  408. X{    extern Objtype obj[SHIP+1];
  409. X    extern int shapesize[LASTSHAPE+1];
  410. X    extern double drawscale;
  411. X    double    mi, mj,                /* Slopes of lines    */
  412. X        ix1, ix2, iy1, iy2, jx1, jx2, jy1, jy2,    /* Endpoints    */
  413. X        roti, rotj,
  414. X        xcross,    ycross,        /* coord of intersection    */
  415. X        z;
  416. X    int    diff, xd, yd,
  417. X        a, b,
  418. X        shapei, shapej;
  419. X    xd = obj[i].x - obj[j].x;
  420. X    yd = obj[i].y - obj[j].y;
  421. X    diff = sqrt((double)(xd*xd + yd*yd));
  422. X    shapei = obj[i].shape; shapej = obj[j].shape;
  423. X    /* Note this will miss if drawscale is < 0    */
  424. X    if (diff < (shapesize[shapei] + shapesize[shapej])*drawscale)
  425. X    {   /* If both are round objects, approximation is good */
  426. X        if (shapei < SHIPSHAPE && shapej < SHIPSHAPE) return 1;
  427. X        if (j == SHIP && shield_on) return 1;    /* Ship always j! */
  428. X        roti = obj[i].rot; rotj = obj[j].rot;
  429. X        ix1 = (double) obj[i].x; iy1 = (double) obj[i].y;
  430. X        for (a = 1; a < numpairs[shapei]; a++)
  431. X        {    ix2 = ix1 + (double) shapes[shapei][a].length * drawscale *
  432. X            cos(shapes[shapei][a].angle + roti);
  433. X        iy2 = iy1 + (double) shapes[shapei][a].length * drawscale *
  434. X            sin(shapes[shapei][a].angle + roti);
  435. X        if (ix1 == ix2)
  436. X        {    printf("\nif1 = if2"); return 1;} /* Easy way out */
  437. X        mi = (iy2-iy1)/(ix2-ix1);
  438. X        z = mi*ix1;
  439. X        jx1 = (double) obj[j].x; jy1 = (double) obj[j].y;
  440. X        for (b = 1; b < numpairs[shapej]; b++)
  441. X        {    jx2 = jx1 + (double) shapes[shapej][b].length *
  442. X                drawscale * cos(shapes[shapej][b].angle + rotj);
  443. X            jy2 = jy1 + (double) shapes[shapej][b].length *
  444. X                drawscale * sin(shapes[shapej][b].angle + rotj);
  445. X            if (jx1 == jx2)
  446. X            {    ycross = ix1 + (jx1-ix1)*mi;
  447. X                if ((jx1-ix1) * (ix2-jx1) >= 0 &&
  448. X                    (ycross-jy1)*(jy2-ycross) >= 0)
  449. X                    return 1;
  450. X                else jx2 += .0001;    /* Avoid divide by 0 */
  451. X            }
  452. X            mj = (jy2-jy1)/(jx2-jx1);
  453. X            if (mj == mi) goto Loopend;    /* Parallel lines */
  454. X            xcross = (iy1 - jy1 + mj*jx1 - z) / (mj - mi);
  455. X            if ((xcross-ix1) * (ix2-xcross) > 0
  456. X                && (xcross-jx1) * (jx2-xcross) > 0) return 1;
  457. XLoopend:        jx1 = jx2; jy1 = jy2;
  458. X        }
  459. X        ix1 = ix2; iy1 = iy2;
  460. X    }   }
  461. X    return 0;
  462. X}
  463. X
  464. Xblastpair(i, j)        /* Generate random velocity vector v.    */
  465. X    int i, j ;    /* Add v to i, -v to j.            */
  466. X{    extern int rndint;
  467. X    extern Objtype obj[SHIP+1];
  468. X    unsigned char c;    /* for rand    */
  469. X    double vx, vy;
  470. X    c = rand(rndint);
  471. X/*    c = 4 - c>>5;    if you need angles from -3 to 4        */
  472. X    c>>2;        /* possibly save some time on sin/cos    */
  473. X    vx = cos((double) c); vy = sin((double) c);
  474. X    obj[i].xvel = obj[i].xvel + vx;
  475. X    obj[i].yvel = obj[i].yvel + vy;
  476. X    obj[j].xvel = obj[j].xvel - vx;
  477. X    obj[j].yvel = obj[j].yvel - vy;
  478. X    obj[i].rotvel = obj[i].rotvel + .05;
  479. X    obj[j].rotvel = obj[j].rotvel - .05;
  480. X}
  481. X
  482. X/* dot product of 2 vectors    */
  483. X#define dot(i,j)    (i.x*j.x + i.y*j.y)
  484. X/* rotational inertia (constant eliminated) of obj. i    */
  485. X#define rotinert(i)    (double) (obj[i].mass*shapesize[obj[i].shape]*shapesize[obj[i].shape])
  486. X
  487. X/* cause two objects to collide elastically    */
  488. Xbounce(i, j)
  489. Xint    i,j;
  490. X{
  491. Xdouble    rotrat, temp;
  492. Xextern    Objtype obj[SHIP+1];
  493. XVector    vi, vj,        /* velocity of objs i, j        */
  494. X    ij,        /* vector from center of i to center of j */
  495. X    vi_ij, vj_ij,    /* velocity of obj along vector ij    */
  496. X    vipij, vjpij,    /* velocity perpendicular to ij        */
  497. X    vi_ijf, vj_ijf;    /* post-collision velocity along ij    */
  498. X
  499. Xvi.x = obj[i].xvel; vi.y = obj[i].yvel;
  500. Xvj.x = obj[j].xvel; vj.y = obj[j].yvel;
  501. Xij.x = obj[j].x - obj[i].x; ij.y = obj[j].y - obj[i].y;
  502. Xij.mag = sqrt(ij.x*ij.x + ij.y*ij.y);
  503. X/*
  504. XCalculate velocities projected onto ij;
  505. X    vi_ij = vi*cos(a) = (vi dot ij) / |ij|        */
  506. Xvi_ij.mag = dot(vi, ij) / ij.mag;
  507. Xvi_ij.x = (ij.x * vi_ij.mag) / ij.mag;
  508. Xvi_ij.y = (ij.y * vi_ij.mag) / ij.mag;
  509. Xvj_ij.mag = dot(vj, ij) / ij.mag;
  510. Xvj_ij.x = (ij.x * vj_ij.mag) / ij.mag;
  511. Xvj_ij.y = (ij.y * vj_ij.mag) / ij.mag;
  512. Xif (vi_ij.mag - vj_ij.mag < 0)    /* Objs moving away from each other -
  513. X    Since objs are round (at least when bouncing), this means
  514. X    they are moving away from each other already.    */
  515. X    return;
  516. X/*
  517. XCalculate component of velocities perpendicular to ij:
  518. X    |vipij| = |vi|*sin(a) = |vi x ij| / |ij|
  519. XSame as
  520. X    |vipij| = |vi|*cos(pi/2 - a) = (vi dot (perp. to ij)) / |ij|    */
  521. Xtemp = vi.y*ij.x - vi.x*ij.y;    /* - (cross product when 3rd coord is 0)*/
  522. Xtemp /= (ij.mag*ij.mag);
  523. Xvipij.x = -ij.y*temp; vipij.y = ij.x*temp;
  524. Xtemp = (vj.x*ij.y - vj.y*ij.x) / (ij.mag*ij.mag);
  525. Xvjpij.x = -ij.y*temp; vjpij.y = ij.x*temp;
  526. X/*
  527. XCalculate the linear elastic collision along ij:
  528. X    mass(i)*vi_ij + mass(j)*vj_ij = mass(i)*vi_ijf + mass(j)*vj_ijf
  529. X    vi_ij + vi_ijf = vj_ij + vj_ijf    (derived by dividing equation
  530. X    for conservation of kinetic energy by eq. for cons. of momentum) */
  531. Xtemp = obj[i].mass/obj[j].mass;
  532. Xvj_ijf.x = (temp * (2*vi_ij.x - vj_ij.x) + vj_ij.x) / (1 + temp);
  533. Xvj_ijf.y = (temp * (2*vi_ij.y - vj_ij.y) + vj_ij.y) / (1 + temp);
  534. Xvi_ijf.x = vj_ijf.x + vj_ij.x - vi_ij.x;
  535. Xvi_ijf.y = vj_ijf.y + vj_ij.y - vi_ij.y;
  536. X/*
  537. XNow, given vi_ijf and vj_ijf, add them to the perpendicular
  538. X    components to get final velocity vectors        */
  539. Xobj[i].xvel = vi_ijf.x + vipij.x;
  540. Xobj[i].yvel = vi_ijf.y + vipij.y;
  541. Xobj[j].xvel = vj_ijf.x + vjpij.x;
  542. Xobj[j].yvel = vj_ijf.y + vjpij.y;
  543. X/*
  544. XNow calculate rotational velocity exchange    */
  545. Xrotrat = rotinert(i)/rotinert(j);
  546. Xtemp = rotrat * (2*obj[i].rotvel - obj[j].rotvel) / (1+rotrat);
  547. Xobj[i].rotvel = temp + obj[j].rotvel - obj[i].rotvel;
  548. Xobj[j].rotvel = temp;
  549. X}
  550. X
  551. Xbotline(disp, window, gc)    /* Print status line text    */
  552. X    Display *disp;
  553. X    Drawable window;
  554. X    GC gc;
  555. X{    extern int highscore, ships, score;
  556. X    char text[70];
  557. X    sprintf(text, "Ships:%2d   Score:%6d   Shield:        High:%6d",
  558. X        ships, score, highscore);
  559. X    XDrawImageString (disp, window, gc, 0, height+letheight,
  560. X            text, strlen(text));
  561. X}
  562. X
  563. Xprintss(disp, window, gc)    /* Print ships and score    */
  564. X    Display *disp;
  565. X    Drawable window;
  566. X    GC gc;
  567. X{    extern int height, highscore, oldscore, ships, score;
  568. X    extern Objtype obj[SHIP+1];    /* to kill ship    */
  569. X    char sstring[30];
  570. X
  571. X    if (score != oldscore)
  572. X    {    if (score/10000 > oldscore/10000)
  573. X        {    ships++; botline(disp, window, gc);}
  574. X        if (score/10000 < oldscore/10000)
  575. X        {    ships--; botline(disp, window, gc);
  576. X            if (!ships) obj[SHIP].alive = 0;
  577. X        }
  578. X        if (score > highscore)    /* Separate if to avoid flashing */
  579. X        {    highscore = score;
  580. X            sprintf(sstring, "%6d", highscore);
  581. X            XDrawImageString (disp, window, gc, 460,
  582. X                height+letheight, sstring, strlen(sstring));
  583. X        }
  584. X        sprintf(sstring, "%6d", score);
  585. X        XDrawImageString (disp, window, gc, 170, height+letheight,
  586. X                sstring, strlen(sstring));
  587. X        oldscore = score;
  588. X    }
  589. X
  590. X    /* Draw shield energy bar    */
  591. X    XFillRectangle(disp, window, gc, 340, height+8, energy>>1, 10);
  592. X    XClearArea(disp, window, 340+(energy>>1), height+8, 8, 10, False);
  593. X}
  594. X
  595. Xupscore(killer, up)    /* Only award score for things the player shot */
  596. X    int killer, up;
  597. X{    extern int score;
  598. X    if (killer != ENEMYBUL && killer != SHIP)
  599. X        score = score + up;
  600. X}
  601. X
  602. X/* boom, movebooms, drawbooms all by Peter Phillips */
  603. Xboom(ob, particles, duration)
  604. Xint ob;
  605. Xint particles;
  606. Xint duration;
  607. X{ extern int rndint;
  608. X  int i;
  609. X  unsigned int r1, r2;
  610. X  Boom b;
  611. X  double x, y;
  612. X  double angle, length;
  613. X
  614. X  b = (Boom) malloc(sizeof(struct _Boom));
  615. X  b->dur = duration;
  616. X  b->part = particles;
  617. X  x = obj[ob].x;
  618. X  y = obj[ob].y;
  619. X  for (i = 0; i < particles; i++) {
  620. X    r1 = (rand(rndint) >> 2) % 100;
  621. X    r2 = (rand(rndint) >> 2) % 7;
  622. X
  623. X    b->bcoord[i][0] = x;
  624. X    b->bcoord[i][1] = y;
  625. X    angle = r1 * pi / 50.0;
  626. X    length = 3 + r2;
  627. X    b->bvec[i][0] = cos(angle) * length + obj[ob].xvel;
  628. X    b->bvec[i][1] = sin(angle) * length + obj[ob].yvel;
  629. X  }
  630. X  b->next = blist;
  631. X  blist = b;
  632. X}
  633. X
  634. X/* move the various booms that are active */
  635. Xmovebooms()
  636. X{
  637. X  int i;
  638. X  Boom b, prevb;
  639. X
  640. X  prevb = NULL;
  641. X  b = blist;
  642. X  while (b != NULL) {
  643. X    b->dur--;
  644. X    if (b->dur < 0) { /* delete this boom */
  645. X      Boom temp;
  646. X
  647. X      temp = b;
  648. X      if (prevb == NULL) {
  649. X        blist = b->next;
  650. X      } else {
  651. X        prevb->next = b->next;
  652. X      }
  653. X      b = b->next;
  654. X      free(temp);
  655. X    } else {  /* move boom, advance list */
  656. X      for (i = 0; i < b->part; i++) {
  657. X        b->bcoord[i][0] += b->bvec[i][0];
  658. X        b->bcoord[i][1] += b->bvec[i][1];
  659. X      }
  660. X      prevb = b;
  661. X      b = b->next;
  662. X    }
  663. X  }
  664. X}
  665. X
  666. X/* Draw the various booms */
  667. Xdrawbooms(disp, window, gc)
  668. X     Display *disp;
  669. X     Drawable window;
  670. X     GC gc;
  671. X{
  672. X  int i;
  673. X  Boom b;
  674. X  XPoint figure[BMAX];
  675. X
  676. X  b = blist;
  677. X  while (b != NULL) {
  678. X    for (i = 0; i < b->part; i++) {
  679. X      figure[i].x = (int) b->bcoord[i][0];
  680. X      figure[i].y = (int) b->bcoord[i][1];
  681. X    }
  682. X    XDrawPoints(disp, window, gc, figure, b->part, CoordModeOrigin);
  683. X    b = b->next;
  684. X  }
  685. X}
  686. X
  687. Xdeletebooms()    /* delete all booms */
  688. X{    Boom b;
  689. X
  690. X    b = blist;
  691. X    while (b != NULL)
  692. X    {    b->dur = 0;
  693. X        b = b->next;
  694. X}    }
  695. X
  696. Xkillast(killer, i)
  697. X    int killer, i;        /* i = Asteroid # to kill    */
  698. X{    extern Objtype obj[SHIP+1];
  699. X    extern int numasts;
  700. X    int k, na, oldna;
  701. X
  702. X    if (obj[i].shape == ASTSHAPE1)
  703. X    {    na = nextast();        /* Could put 6 lines in a sub */
  704. X        obj[na].x = obj[i].x;
  705. X        obj[na].y = obj[i].y;
  706. X        obj[na].xvel = obj[i].xvel;
  707. X        obj[na].yvel = obj[i].yvel;
  708. X        obj[na].alive++;
  709. X        obj[na].shape = ASTSHAPE2;
  710. X        obj[na].mass = M_MED;
  711. X        obj[i].shape = ASTSHAPE2;
  712. X        obj[i].mass = M_MED;
  713. X        blastpair(i, na);
  714. X        boom(i, 30, 12);
  715. X        numasts++;
  716. X        if (numasts == 2)    /* Big asteroid was last remaining */
  717. X            upscore(killer, 25+level*2000);
  718. X        else    upscore(killer, 25);
  719. X    }
  720. X    else if (obj[i].shape == ASTSHAPE2)
  721. X    {
  722. X        for (k = 0; k < 3; k++)
  723. X        {    oldna = na;
  724. X            na = nextast();
  725. X            obj[na].x = obj[i].x;
  726. X            obj[na].y = obj[i].y;
  727. X            obj[na].xvel = obj[i].xvel;
  728. X            obj[na].yvel = obj[i].yvel;
  729. X            obj[na].alive++;
  730. X            obj[na].shape = ASTSHAPE3;
  731. X            obj[na].mass = M_SMALL;
  732. X            if (k == 1) blastpair(oldna,na);
  733. X        }
  734. X        obj[i].shape = ASTSHAPE3;
  735. X        obj[i].mass = M_SMALL;
  736. X        blastpair(na, i);
  737. X        boom(i, 20, 10);
  738. X        if (numasts == 1) upscore(killer, 500*level);
  739. X        numasts = numasts + 3;
  740. X        upscore(killer, 50);
  741. X    }
  742. X    else if (obj[i].shape == ASTSHAPE3)
  743. X    {    boom(i, 10, 8);
  744. X        obj[i].alive = 0; numasts--; upscore(killer, 100);}
  745. X    else    /* enemy {ship or bullet}    */
  746. X    {    boom(i, 9, 7);
  747. X        obj[i].alive = 0; upscore(killer, 500);}
  748. X}
  749. Xmoveobjs(crash)
  750. X    int *crash;
  751. X{    extern Objtype obj[SHIP+1];
  752. X    extern int ships;
  753. X    extern double speedscale;
  754. X    int i, j;    /* Indexes    */
  755. X    double *temp;
  756. X
  757. X    movebooms();
  758. X    for (i = 0; i < LASTOBJ+1; i++)
  759. X        if (obj[i].alive)
  760. X        {    temp = &obj[i].x;
  761. X            *temp = *temp + obj[i].xvel*speedscale;
  762. X            while (*temp < 0) *temp = *temp + (double) width;
  763. X            while (*temp > width) *temp = *temp - (double) width;
  764. X            temp = &obj[i].y;
  765. X            *temp = *temp + obj[i].yvel*speedscale;
  766. X            while (*temp < 0) *temp = *temp + height;
  767. X            while (*temp > height) *temp = *temp - height;
  768. X            obj[i].rot = obj[i].rot + obj[i].rotvel;
  769. X        }
  770. X    for (i = 0; i < FBUL; i++)
  771. X        if (obj[i].alive)
  772. X        {
  773. X        if (obj[SHIP].alive && collide(i, SHIP))
  774. X        {    if (shield_on) bounce(SHIP, i);
  775. X            else
  776. X            {    *crash = 2;
  777. X                ships--; obj[SHIP].alive = 0;
  778. X                killast(SHIP, i);
  779. X                continue;
  780. X        }    }
  781. X        for (j = ENEMYBUL; j < LASTBUL+1; j++)
  782. X            if (obj[j].alive && collide(i, j) &&
  783. X               (j != ENEMYBUL || (i != ENEMYBUL && i != ENEMY)))
  784. X            {    obj[j].alive = 0;    /* Kill the bullet */
  785. X                /* Don't have 2 bullets kill same asteroid */
  786. X                if (obj[i].alive) killast(j,i);
  787. X            }
  788. X        }
  789. X}
  790. X
  791. Xfire()
  792. X{    extern Objtype obj[SHIP+1];
  793. X    extern int width, nextbul;
  794. X    extern double drawscale, speedscale;
  795. X    double *shiprot, cosrot, sinrot;
  796. X
  797. X    obj[nextbul].alive++;
  798. X    shiprot = &obj[SHIP].rot;
  799. X    cosrot = cos(*shiprot); sinrot = sin(*shiprot);
  800. X    obj[nextbul].x = obj[SHIP].x + 20 * cosrot * drawscale;
  801. X    obj[nextbul].y = obj[SHIP].y + 20 * sinrot * drawscale;
  802. X    obj[nextbul].xvel = obj[SHIP].xvel + 10 * cosrot;
  803. X    obj[nextbul].yvel = obj[SHIP].yvel + 10 * sinrot;
  804. X    obj[nextbul].rot = *shiprot;
  805. X    obj[nextbul].time = width/(speedscale*11);    /* loops before bullet expires    */
  806. X    nextbul++; if (nextbul == LASTBUL+1) nextbul = FBUL;
  807. X}
  808. X
  809. Xhyper()
  810. X{    extern Objtype obj[SHIP+1];
  811. X    extern int width, height, rndint;
  812. X    unsigned char c;
  813. X    unsigned int i;
  814. X
  815. X    c = rand(rndint); i = c; i<<=2;    /* 0 - 1024    */
  816. X    while (i > width) i -= width;
  817. X    obj[SHIP].x = (double) i;
  818. X    c = rand(rndint); i = c; i<<=2;    /* 0 - 1024    */
  819. X    while (i > height) i -= height;
  820. X    obj[SHIP].y = (double) i;
  821. X}
  822. X
  823. Xvdraw(disp, window, gc, shape, x, y, rot)
  824. X    Display *disp;
  825. X    Drawable window;
  826. X    GC gc;
  827. X    int shape;
  828. X    double x, y, rot;
  829. X
  830. X{    int line;
  831. X    extern PolarPair shapes[LASTSHAPE+1][11];
  832. X    extern int numpairs[LASTSHAPE+1];
  833. X    extern double drawscale;
  834. X    XPoint figure[20];
  835. X    figure[0].x = (int) x; figure[0].y = (int) y;
  836. X    for (line=1; line < numpairs[shape]; line++)    /* 2 pairs = 1 line */
  837. X    {    figure[line].x  = (int) shapes[shape][line].length *
  838. X            cos(shapes[shape][line].angle + rot) * drawscale;
  839. X        figure[line].y  = (int) shapes[shape][line].length *
  840. X            sin(shapes[shape][line].angle + rot) * drawscale;
  841. X    }
  842. X    XDrawLines (disp, window, gc, figure, numpairs[shape], CoordModePrevious);
  843. X}
  844. X
  845. Xmain(argc, argv)
  846. X    int argc;
  847. X    char **argv;
  848. X{    Colormap cmap;
  849. X    Cursor cursor;
  850. X    Display *disp;
  851. X    Font font;
  852. X    GC gc, pmgc;
  853. X    KeySym key;
  854. X    Pixmap pixmap;
  855. X    Window window;
  856. X    XColor black, exact;
  857. X    XEvent event;
  858. X    XSizeHints hint;
  859. X    XWMHints wmhints;
  860. X    extern int width, height;
  861. X    int screen, depth;
  862. X    char text[30];
  863. X    unsigned long fg, bg;
  864. X
  865. X    extern double drawscale, speedscale;
  866. X    extern int level, numasts, rndint, ships, score, oldscore;
  867. X    extern Objtype obj[SHIP+1];
  868. X    unsigned char c;    /* for rand    */
  869. X    double *temp, dx, dy, dist;
  870. X    int crashed, flashon, len, pause = 0, delay = 64,
  871. X        enemycount, counter, counterstart = 1,
  872. X        i,    /* index for drawing objs, counting bullets */
  873. X        r;    /* radius of shield circle    */
  874. X
  875. X    disp = XOpenDisplay(0);
  876. X    if (disp == (Display *) NULL)
  877. X    {    fprintf(stderr, "Could not open display\n");
  878. X        exit(1);
  879. X    }
  880. X    screen = DefaultScreen(disp);
  881. X    bg = BlackPixel(disp, screen);
  882. X    fg = WhitePixel(disp, screen);
  883. X    hint.x = 150; hint.y = 200; hint.width = 550; hint.height = 550;
  884. X    hint.flags = PPosition | PSize;
  885. X    width = hint.width; height = hint.height-letheight-1;
  886. X    depth = DefaultDepth (disp, screen);
  887. X    window = XCreateSimpleWindow (disp, DefaultRootWindow(disp),
  888. X        hint.x, hint.y, hint.width, hint.height, 5, fg, bg);
  889. X    pixmap = XCreatePixmap (disp, window, width, height, depth);
  890. X    XSetStandardProperties (disp, window, "asteroids", "asteroids", None,
  891. X        argv, argc, &hint);
  892. X    gc = XCreateGC (disp, window, 0, 0);
  893. X    XSetGraphicsExposures(disp, gc, 0);    /* IMPORTANT!  If you do not
  894. X        specifically ask not to get Expose events, every XCopyArea
  895. X        will generate one, & the event queue will fill up.    */
  896. X    font = XLoadFont(disp, "10x20\0");    /* If you don't have this
  897. X        font, try replacing it with 9x15\0    */
  898. X    XSetFont(disp, gc, font);
  899. X    pmgc = XCreateGC (disp, window, 0, 0);
  900. X    XSetBackground (disp, gc, bg);
  901. X    XSetForeground (disp, gc, fg);
  902. X    XSetForeground (disp, pmgc, bg);  /* fg of pixmap is bg of window */
  903. X    wmhints.flags = InputHint;
  904. X    wmhints.input = True;
  905. X    XSetWMHints(disp, window, &wmhints);    /* Thanks to Doug Merritt */
  906. X    XSelectInput (disp, window,
  907. X        KeyPressMask | KeyReleaseMask | StructureNotifyMask);
  908. X    XMapRaised (disp, window);
  909. X
  910. X    /* Erase cursor. Just delete next 5 lines if any error.    */
  911. X    cmap = XDefaultColormap(disp, screen);
  912. X    XAllocNamedColor(disp, cmap, "Black", &exact, &black);
  913. X    cursor = XCreateFontCursor(disp, XC_dot);
  914. X    XRecolorCursor(disp, cursor, &black, &black);
  915. X    XDefineCursor(disp, window, cursor);
  916. X
  917. X    XFillRectangle (disp, pixmap, pmgc, 0, 0, width, height);
  918. X/*    Can delete next line if it causes trouble    */
  919. X    srand((unsigned) time(0));    /* By Craig Smith    */
  920. X    initasts();
  921. XNewgame:
  922. X    deletebooms();
  923. X    ships = 3;
  924. X    score = 0; oldscore = -1;
  925. X    for (level = 0; ;)
  926. X    {   if (level < 15) level++;
  927. X        makeasts ();
  928. XNewship:    botline(disp, window, gc);
  929. X        if (!obj[SHIP].alive)
  930. X        {    obj[SHIP].x = width/2;
  931. X        obj[SHIP].y = height/2;
  932. X        obj[SHIP].xvel = 0;
  933. X        obj[SHIP].yvel = 0;
  934. X        obj[SHIP].rot = 3*pi/2;
  935. X        obj[SHIP].rotvel = 0;
  936. X        energy = 80;
  937. X        shield_on = 0;
  938. X        }
  939. X        obj[SHIP].alive = (ships > 0);
  940. X        crashed = 0; flashon = 0; enemycount = 20;
  941. X        counter = 0;
  942. X        while (numasts)
  943. X        {    for (i = FBUL; i < LASTBUL+1; i++)  /* Bullet timer */
  944. X            if (obj[i].alive)
  945. X            {    obj[i].time--;
  946. X            if (!obj[i].time) obj[i].alive = 0; /* Not --! */
  947. X            }
  948. X        while (XEventsQueued(disp, QueuedAfterReading))
  949. X        {   XNextEvent(disp, &event);
  950. X            switch (event.type)
  951. X            {    case MappingNotify:
  952. X                XRefreshKeyboardMapping (&event);
  953. X                break;
  954. X            case ConfigureNotify:
  955. X                width = event.xconfigure.width;
  956. X                height = event.xconfigure.height-letheight-1;
  957. X                XFreePixmap (disp, pixmap);
  958. X                pixmap = XCreatePixmap (disp, window, width, height, depth);
  959. X                XFillRectangle (disp, pixmap, pmgc, 0, 0, width, height);
  960. X                botline(disp, window, gc);
  961. X                break;
  962. X            case KeyPress:
  963. X                len = XLookupString (&event, text, 10, &key, 0);
  964. X                if (len == 1 && !shield_on) switch (text[0])
  965. X                {    case 'e':
  966. X                    obj[SHIP].rotvel = obj[SHIP].rotvel - .1; break;
  967. X                case 'r':
  968. X                    obj[SHIP].rotvel = obj[SHIP].rotvel + .1; break;
  969. X                case 'w':
  970. X                    obj[SHIP].rot -= pi/4; break;
  971. X                case 't':
  972. X                    obj[SHIP].rot += pi/4; break;
  973. X                case 'd':
  974. X                    obj[SHIP].rotvel = obj[SHIP].rotvel - .02; break;
  975. X                case 'f':
  976. X                    obj[SHIP].rotvel = obj[SHIP].rotvel + .02; break;
  977. X                case THRUST:
  978. X                    obj[SHIP].xvel += cos(obj[SHIP].rot);
  979. X                    obj[SHIP].yvel += sin(obj[SHIP].rot);
  980. X                    obj[SHIP].shape = SHIPTHRSHAPE;
  981. X                    break;
  982. X                case FIRE:
  983. X                    if (obj[SHIP].alive) fire(); break;
  984. X                case ' ':
  985. X                    if (obj[SHIP].alive)
  986. X                    {    hyper(); flashon = 1;
  987. X/*                    NOT XSetForeground (disp, gc, bg);
  988. X    If you set the fg black, & print the highscore, it will effectively erase it.    */
  989. X                        XSetForeground (disp, pmgc, fg);
  990. X                    XFillRectangle (disp, pixmap, pmgc, 0, 0, width, height);
  991. X                    }
  992. X                    break;
  993. X                case SHIELD:
  994. X                    if (energy)
  995. X                    {    shield_on = 1;
  996. X                    obj[SHIP].shape = SHIPSHAPE;}
  997. X                    break;
  998. X                case '.':    /* decrease delay    */
  999. X                    if (delay > 1) delay >>=1; break;
  1000. X                case ',':    /* increase delay    */
  1001. X                    delay <<=1; break;
  1002. X                case 'm':    /* decrease drawscale - may go negative */
  1003. X                    drawscale -= .1; break;
  1004. X                case 'n':    /* increase drawscale    */
  1005. X                    drawscale += .1; break;
  1006. X                case '2':    /* increase speedscale    */
  1007. X                    speedscale += .1; break;
  1008. X                case '1':    /* decrease speedscale    */
  1009. X                    speedscale -= .1; break;
  1010. X                case 'b':    /* increase moves/update */
  1011. X                    counterstart++; break;
  1012. X                case 'v':    /* decrease moves/update */
  1013. X                    if (counterstart > 1) counterstart--;
  1014. X                    break;
  1015. X                case PAUSE:    /* pause    */
  1016. X                    pause = 1 - pause; break;
  1017. X                case '+':    /* cheat    */
  1018. X                    ships++; botline(disp, window, gc); break;
  1019. X                case 'Q':    /* quit        */
  1020. X                    goto End;
  1021. X                case 's':    /* start new ship */
  1022. X                    if (!obj[SHIP].alive)
  1023. X                    if (ships < 1) goto Newgame;
  1024. X                    else goto Newship;
  1025. X                    break;
  1026. X                }
  1027. X                break;
  1028. X            case KeyRelease:
  1029. X                len = XLookupString(&event, text, 10, &key, 0);
  1030. X                if (len == 1) switch (text[0])
  1031. X                {    case 'e':
  1032. X                    obj[SHIP].rotvel = 0; break;
  1033. X                case 'r':
  1034. X                    obj[SHIP].rotvel = 0; break;
  1035. X                case THRUST:
  1036. X                    obj[SHIP].shape = SHIPSHAPE;
  1037. X                    break;
  1038. X                case SHIELD:
  1039. X                    shield_on = 0; break;
  1040. X                }
  1041. X/*                break;        */
  1042. X        }   }
  1043. X        if (!pause)
  1044. X        {   moveobjs(&crashed);
  1045. X            if (ships) score--;    /* timer effect    */
  1046. X            if (!counter)
  1047. X            {    counter = counterstart;    /* Restart counter */
  1048. X            if (crashed == 2)
  1049. X            {   crashed--; flashon++;
  1050. X                boom(SHIP, BMAX-1, 70);
  1051. X                XSetForeground (disp, pmgc, fg);
  1052. X                XFillRectangle (disp, pixmap, pmgc, 0, 0, width, height);
  1053. X                botline(disp, window, gc);
  1054. X            }
  1055. X            /* Write copyright notice    */
  1056. X            if (!ships && blist == NULL)
  1057. X            {   sprintf(text, "Xasteroids");
  1058. X                XDrawImageString (disp, pixmap, gc,
  1059. X                width/2-50, height/2-2*letheight,
  1060. X                text, strlen(text));
  1061. X                sprintf(text, "Copyright 1990 by Phil Goetz");
  1062. X                XDrawImageString (disp, pixmap, gc,
  1063. X                width/2-140, height/2,
  1064. X                text, strlen(text));
  1065. X                sprintf(text, "goetz@cs.buffalo.edu");
  1066. X                XDrawImageString (disp, pixmap, gc,
  1067. X                width/2-100, height/2+2*letheight,
  1068. X                text, strlen(text));
  1069. X            }
  1070. X            /*    Draw objects    */
  1071. X            for (i = 0; i <= LASTOBJ; i++)
  1072. X                if (obj[i].alive)
  1073. X                vdraw(disp, pixmap, gc, obj[i].shape,
  1074. X                    obj[i].x, obj[i].y, obj[i].rot);
  1075. X            if (shield_on && obj[SHIP].alive)
  1076. X            {   r = abs((int) (drawscale*SHIPSIZE));
  1077. X                XDrawArc(disp, pixmap, gc,
  1078. X                ((int) obj[SHIP].x) - r,
  1079. X                ((int) obj[SHIP].y) - r,
  1080. X                2*r, 2*r, 0, 360*64);
  1081. X                energy--;
  1082. X                if (!energy) shield_on = 0;
  1083. X            }
  1084. X            drawbooms(disp, pixmap, gc);
  1085. X            /* update display:    */
  1086. X            XCopyArea(disp, pixmap, window, gc, 0, 0, width, height, 0, 0);
  1087. X            printss(disp, window, gc);
  1088. X            /* erase objects    */
  1089. X            XFillRectangle (disp, pixmap, pmgc, 0, 0, width, height);
  1090. X            if (flashon)
  1091. X            {   flashon--;
  1092. X                XSetForeground (disp, pmgc, bg);
  1093. X                XFillRectangle (disp, pixmap, pmgc, 0, 0, width, height);
  1094. X            }
  1095. X            XSync(disp, 0);
  1096. X            }
  1097. X            counter--;
  1098. X            i = (rand(rndint)>>8) & 255;
  1099. X            if (!obj[ENEMY].alive)
  1100. X            {   if (i < level)
  1101. X                {    c = rand(rndint);
  1102. X                if (c < level * 10) makeenemy();
  1103. X            }   }
  1104. X            else
  1105. X            {    i += (obj[SHIP].y > obj[ENEMY].y)
  1106. X                ? level>>1 : -(level>>1);
  1107. X            obj[ENEMY].yvel += (i>128+6*obj[ENEMY].yvel) ? .5 : -.5;
  1108. X            }
  1109. X            enemycount--; if (!enemycount)
  1110. X            {    enemycount = 100;
  1111. X            if (obj[ENEMY].alive)
  1112. X            {   obj[ENEMYBUL].alive++;
  1113. X                obj[ENEMYBUL].x = obj[ENEMY].x;
  1114. X                obj[ENEMYBUL].y = obj[ENEMY].y;
  1115. X                dx = obj[SHIP].x - obj[ENEMY].x;
  1116. X                dy = obj[SHIP].y - obj[ENEMY].y;
  1117. X                dist = sqrt(dx*dx + dy*dy);
  1118. X                obj[ENEMYBUL].xvel = 3*dx/dist;
  1119. X                obj[ENEMYBUL].yvel = 3*dy/dist;
  1120. X            }
  1121. X            else    obj[ENEMYBUL].alive = 0;
  1122. X            }
  1123. X            for (i = 0; i < delay; i++);
  1124. X        }
  1125. X        }
  1126. X    }
  1127. XEnd:    printf("\nYour high score was %d\n", highscore);
  1128. X    XFreeGC (disp, gc);
  1129. X    XFreeGC (disp, pmgc);
  1130. X    XFreePixmap (disp, pixmap);
  1131. X    XDestroyWindow (disp, window);
  1132. X    XCloseDisplay (disp);
  1133. X    exit(0);
  1134. X}
  1135. END_OF_FILE
  1136. if test 27746 -ne `wc -c <'xast.c'`; then
  1137.     echo shar: \"'xast.c'\" unpacked with wrong size!
  1138. fi
  1139. # end of 'xast.c'
  1140. fi
  1141. if test -f 'xast.docs' -a "${1}" != "-c" ; then 
  1142.   echo shar: Will not clobber existing file \"'xast.docs'\"
  1143. else
  1144. echo shar: Extracting \"'xast.docs'\" \(1405 characters\)
  1145. sed "s/^X//" >'xast.docs' <<'END_OF_FILE'
  1146. X        X-Asteroids
  1147. X    Copyright 1990 by Phil Goetz
  1148. X        goetz@cs.Buffalo.EDU
  1149. X
  1150. XKeypress    Command
  1151. X--------        -------
  1152. X    e        Rotate counterclockwise ("left")
  1153. X    r        Rotate clockwise ("right")
  1154. X    w        Rotate 45 degrees counterclockwise
  1155. X    t        Rotate 45 degrees clockwise
  1156. X    d        Increase counterclockwise rotational velocity
  1157. X    f        Increase clockwise rotational velocity
  1158. X    o        Thrust
  1159. X    p        Fire
  1160. X  space        Hyperspace
  1161. X    `        Shields
  1162. X    s        Start new ship in center of playing field
  1163. X        (Also used to start a new game)
  1164. X   esc        Pause
  1165. X    Q        Quit
  1166. XSpeed commands:    Key associated with faster speed is to the right of its
  1167. X        corresponding key associated with slower speed.
  1168. X    .        Decrease delay:  Speed game up
  1169. X    ,        Increase delay:  Slow the game down
  1170. X    m        Decrease size    ("Minimize")
  1171. X    n        Increase size
  1172. X    b        Increase # of moves/frame
  1173. X    v        Decrease # of moves/frame
  1174. X    2        Increase scale of movement
  1175. X    1        Decrease scale of movement
  1176. X
  1177. XObject        Score
  1178. X-------        -----
  1179. XBig asteroid     25, or 2000*level if it is the last asteroid remaining
  1180. XMedium asteroid     50, or  500*level if it is the last asteroid remaining
  1181. XLittle asteroid    100
  1182. XEnemy spaceship    500
  1183. XEnemy bullet    500
  1184. X
  1185. XCommands can only be entered when the mouse pointer is in the
  1186. Xasteroids window.
  1187. X
  1188. XResize the window with your window manager
  1189. Xat any time for a different playing field.
  1190. X
  1191. XUse the command-line option -s on the xasteroids script
  1192. Xto see the high score list.
  1193. END_OF_FILE
  1194. if test 1405 -ne `wc -c <'xast.docs'`; then
  1195.     echo shar: \"'xast.docs'\" unpacked with wrong size!
  1196. fi
  1197. # end of 'xast.docs'
  1198. fi
  1199. if test -f 'xast.man' -a "${1}" != "-c" ; then 
  1200.   echo shar: Will not clobber existing file \"'xast.man'\"
  1201. else
  1202. echo shar: Extracting \"'xast.man'\" \(1976 characters\)
  1203. sed "s/^X//" >'xast.man' <<'END_OF_FILE'
  1204. X.TH xasteroids n
  1205. X.SH NAME
  1206. Xxasteroids - X windows based asteroids style arcade game
  1207. X.SH SYNOPSIS
  1208. X.ta 8n
  1209. X\fBxasteroids\fP
  1210. X.br
  1211. X.SH DESCRIPTION
  1212. XMake big rocks into little ones.
  1213. X.br
  1214. X.SH COMMANDS
  1215. X.I xasteroids 
  1216. X
  1217. X e           Rotate counterclockwise ("left")
  1218. X r           Rotate clockwise ("right")
  1219. X w           Rotate 45 degrees counterclockwise
  1220. X t           Rotate 45 degrees clockwise
  1221. X d           Increase counterclockwise rotational velocity
  1222. X f           Increase clockwise rotational velocity
  1223. X o           Thrust
  1224. X p           Fire
  1225. X `           Shields
  1226. X space       Hyperspace
  1227. X s           Start new ship in center of playing field
  1228. X             (Also used to start a new game)
  1229. X esc         Pause
  1230. X Q           Quit
  1231. X
  1232. XSpeed commands: Key associated with faster speed is to the right of its
  1233. X                corresponding key associated with slower speed.
  1234. X
  1235. X .           Decrease delay:  Speed game up
  1236. X ,           Increase delay:  Slow the game down
  1237. X m           Decrease size   ("Minimize")
  1238. X n           Increase size
  1239. X b           Increase # of moves/frame
  1240. X v           Decrease # of moves/frame
  1241. X 2           Increase scale of movement
  1242. X 1           Decrease scale of movement
  1243. X
  1244. XObject          Score
  1245. X
  1246. X Big asteroid    25, or 2000*level if it is the last asteroid remaining
  1247. X Medium asteroid 50, or  500*level if it is the last asteroid remaining
  1248. X Little asteroid 100
  1249. X Enemy spaceship 500
  1250. X Enemy bullet    500
  1251. X
  1252. XCommands can only be entered when the mouse pointer is in the
  1253. Xasteroids window.
  1254. X
  1255. XResize the window with your window manager
  1256. Xat any time for a different playing field.
  1257. X
  1258. X.SH OPTIONS
  1259. X.I xasteroids [-s]
  1260. X-s Display high scores without running game.
  1261. X.PP
  1262. X.SH AUTHOR
  1263. XPhil Goetz
  1264. X.br
  1265. Xgoetz@cs.Buffalo.EDU
  1266. X.SH CONTRIBUTORS
  1267. XPeter Phillips    pphillip@cs.ubc.ca
  1268. XPat Ryan    pat@jaameri.gsfc.nasa.gov
  1269. XCraig Smith    csmith@cscs.UUCP
  1270. XDoug Merritt    doug@netcom.com
  1271. XJames Berg    berg@plains        (makefile)
  1272. XChris Moore    moore@src.bae.co.uk    (hi score script)
  1273. XDavid Partain    dlp@ida.liu.se        (original man page)
  1274. END_OF_FILE
  1275. if test 1976 -ne `wc -c <'xast.man'`; then
  1276.     echo shar: \"'xast.man'\" unpacked with wrong size!
  1277. fi
  1278. # end of 'xast.man'
  1279. fi
  1280. if test -f 'xasteroids' -a "${1}" != "-c" ; then 
  1281.   echo shar: Will not clobber existing file \"'xasteroids'\"
  1282. else
  1283. echo shar: Extracting \"'xasteroids'\" \(497 characters\)
  1284. sed "s/^X//" >'xasteroids' <<'END_OF_FILE'
  1285. X#!/bin/sh
  1286. X#cd /u5/grads/goetz/X
  1287. Xif [ "$1" = "-s" ]
  1288. Xthen
  1289. X  /bin/cat xast.hs
  1290. Xelse
  1291. X  /bin/echo ""
  1292. X  /bin/cat xast.hs
  1293. X  /bin/echo ""
  1294. X  /bin/echo Type 'Q' to save your high score...
  1295. X  umask 77
  1296. X  score=`xast.exe | /bin/cut '-d ' -f5`
  1297. X  if [ "$score" != "" ]
  1298. X  then
  1299. X    (/bin/echo $score"    "$USER"        `/bin/date | /bin/sed 's/  / 0/g' | cut '-d ' -f1,2,3,6 | /bin/sed 's/ 0/  /g'`"; cat xast.hs) | /bin/sort +0rn -1 +5n +3M | head -10 > xast.hs2
  1300. X    /bin/mv -f xast.hs2 xast.hs
  1301. X    /bin/cat xast.hs
  1302. X  fi
  1303. Xfi
  1304. END_OF_FILE
  1305. if test 497 -ne `wc -c <'xasteroids'`; then
  1306.     echo shar: \"'xasteroids'\" unpacked with wrong size!
  1307. fi
  1308. chmod +x 'xasteroids'
  1309. # end of 'xasteroids'
  1310. fi
  1311. echo shar: End of archive 1 \(of 1\).
  1312. cp /dev/null ark1isdone
  1313. MISSING=""
  1314. for I in 1 ; do
  1315.     if test ! -f ark${I}isdone ; then
  1316.     MISSING="${MISSING} ${I}"
  1317.     fi
  1318. done
  1319. if test "${MISSING}" = "" ; then
  1320.     echo You have the archive.
  1321.     rm -f ark[1-9]isdone
  1322. else
  1323.     echo You still need to unpack the following archives:
  1324.     echo "        " ${MISSING}
  1325. fi
  1326. ##  End of shell archive.
  1327. exit 0
  1328.