--- xasteroids-5.0.orig/xast.c +++ xasteroids-5.0/xast.c @@ -3,6 +3,13 @@ goetz@cs.buffalo.EDU Version 5, 9 Feb 93 + Changes after version 5.0: + + Improved cursor-hiding. + Arrow keys. + ANSI-C cleanups. + Use usleep() instead of a delay loop, when available. + Changes from version 4.3: High score script. @@ -27,16 +34,29 @@ Pat Ryan Craig Smith Doug Merritt + Stephen McCamant Makefile by James Berg Hi score script by Chris Moore Man page by David Partain */ #include /* For NULL */ +#include /* For malloc(), rand() etc */ +#include /* For time() */ #include #include -#include /* For erasing cursor - not important */ +#include #include +#ifdef HAS_USLEEP +#include +#endif + +#ifndef __STDC__ +define void +#endif + +#define rand(rndint) rand() /* ??? */ + /* Indexes for 1st dimension of obj */ /* The order they are in is important */ #define AST 0 @@ -68,10 +88,10 @@ #define M_BULLET 0.1 /* Keys */ -#define FIRE 'p' -#define PAUSE 27 /* escape */ -#define SHIELD '`' -#define THRUST 'o' +#define FIRE XK_p +#define PAUSE XK_Escape /* escape */ +#define SHIELD XK_grave /* ` */ +#define THRUST XK_o #define BMAX 300 /* Max particles in a "boom" + 1 */ #define letheight 20 /* height of font */ @@ -121,6 +141,7 @@ shapesize[LASTSHAPE+1] = {44, 21, 10, 2, 1, SHIPSIZE+1, 35, 20}, shield_on; +void initasts() { int i; extern Objtype obj[SHIP+1]; @@ -143,6 +164,7 @@ obj[i].mass = M_BULLET; } } +void makeasts() { int i; extern Objtype obj[SHIP+1]; @@ -163,7 +185,7 @@ if (a > 63) obj[i].y = (double) a; else obj[i].y = (double) height - a; - a = rand(rndint); a = 4 - a>>5; + a = rand(rndint); a = 4 - (a>>5); obj[i].rot = (double) a; a = rand(rndint); obj[i].rotvel = ((double) a)/2048; @@ -177,6 +199,7 @@ numasts = i; } +void makeenemy() /* Start an enemy ship */ { extern Objtype obj[SHIP+1]; extern int height, level, rndint; @@ -258,6 +281,7 @@ return 0; } +void blastpair(i, j) /* Generate random velocity vector v. */ int i, j ; /* Add v to i, -v to j. */ { extern int rndint; @@ -266,7 +290,7 @@ double vx, vy; c = rand(rndint); /* c = 4 - c>>5; if you need angles from -3 to 4 */ - c>>2; /* possibly save some time on sin/cos */ + c >>= 2; /* possibly save some time on sin/cos */ vx = cos((double) c); vy = sin((double) c); obj[i].xvel = obj[i].xvel + vx; obj[i].yvel = obj[i].yvel + vy; @@ -282,6 +306,7 @@ #define rotinert(i) (double) (obj[i].mass*shapesize[obj[i].shape]*shapesize[obj[i].shape]) /* cause two objects to collide elastically */ +void bounce(i, j) int i,j; { @@ -345,6 +370,7 @@ obj[j].rotvel = temp; } +void botline(disp, window, gc) /* Print status line text */ Display *disp; Drawable window; @@ -357,6 +383,7 @@ text, strlen(text)); } +void printss(disp, window, gc) /* Print ships and score */ Display *disp; Drawable window; @@ -389,6 +416,7 @@ XClearArea(disp, window, 340+(energy>>1), height+8, 8, 10, False); } +void upscore(killer, up) /* Only award score for things the player shot */ int killer, up; { extern int score; @@ -397,6 +425,7 @@ } /* boom, movebooms, drawbooms all by Peter Phillips */ +void boom(ob, particles, duration) int ob; int particles; @@ -429,6 +458,7 @@ } /* move the various booms that are active */ +void movebooms() { int i; @@ -461,6 +491,7 @@ } /* Draw the various booms */ +void drawbooms(disp, window, gc) Display *disp; Drawable window; @@ -481,6 +512,7 @@ } } +void deletebooms() /* delete all booms */ { Boom b; @@ -490,11 +522,12 @@ b = b->next; } } +void killast(killer, i) int killer, i; /* i = Asteroid # to kill */ { extern Objtype obj[SHIP+1]; extern int numasts; - int k, na, oldna; + int k, na = 0, oldna; if (obj[i].shape == ASTSHAPE1) { na = nextast(); /* Could put 6 lines in a sub */ @@ -543,6 +576,8 @@ { boom(i, 9, 7); obj[i].alive = 0; upscore(killer, 500);} } + +void moveobjs(crash) int *crash; { extern Objtype obj[SHIP+1]; @@ -585,6 +620,7 @@ } } +void fire() { extern Objtype obj[SHIP+1]; extern int width, nextbul; @@ -603,6 +639,7 @@ nextbul++; if (nextbul == LASTBUL+1) nextbul = FBUL; } +void hyper() { extern Objtype obj[SHIP+1]; extern int width, height, rndint; @@ -617,6 +654,7 @@ obj[SHIP].y = (double) i; } +void vdraw(disp, window, gc, shape, x, y, rot) Display *disp; Drawable window; @@ -639,6 +677,7 @@ XDrawLines (disp, window, gc, figure, numpairs[shape], CoordModePrevious); } +int main(argc, argv) int argc; char **argv; @@ -663,8 +702,8 @@ extern int level, numasts, rndint, ships, score, oldscore; extern Objtype obj[SHIP+1]; unsigned char c; /* for rand */ - double *temp, dx, dy, dist; - int crashed, flashon, len, pause = 0, delay = 64, + double dx, dy, dist; + int crashed, flashon, pause = 0, delay = 64, enemycount, counter, counterstart = 1, i, /* index for drawing objs, counting bullets */ r; /* radius of shield circle */ @@ -704,11 +743,30 @@ KeyPressMask | KeyReleaseMask | StructureNotifyMask); XMapRaised (disp, window); - /* Erase cursor. Just delete next 5 lines if any error. */ + /* Make cursor invisible. Just delete chunk if any error. */ cmap = XDefaultColormap(disp, screen); XAllocNamedColor(disp, cmap, "Black", &exact, &black); +#if 0 /* Easy way, but can leave a black spot */ +#include cursor = XCreateFontCursor(disp, XC_dot); XRecolorCursor(disp, cursor, &black, &black); +#else /* Hard, good way */ + { unsigned wd, ht; + Pixmap pm, maskpm; + GC cleargc; + XQueryBestCursor(disp, window, 1, 1, &wd, &ht); + pm = XCreatePixmap(disp, window, wd, ht, 1); + maskpm = XCreatePixmap(disp, window, wd, ht, 1); + cleargc = XCreateGC(disp, pm, 0, 0); + XFillRectangle(disp, pm, cleargc, 0, 0, wd, ht); + XFillRectangle(disp, maskpm, cleargc, 0, 0, wd, ht); + cursor = XCreatePixmapCursor(disp, pm, maskpm, + &black, &black, 1, 1); + XFreePixmap(disp, pm); + XFreePixmap(disp, maskpm); + XFreeGC(disp, cleargc); + } +#endif XDefineCursor(disp, window, cursor); XFillRectangle (disp, pixmap, pmgc, 0, 0, width, height); @@ -746,7 +804,7 @@ { XNextEvent(disp, &event); switch (event.type) { case MappingNotify: - XRefreshKeyboardMapping (&event); + XRefreshKeyboardMapping ((XMappingEvent *)&event); break; case ConfigureNotify: width = event.xconfigure.width; @@ -757,28 +815,29 @@ botline(disp, window, gc); break; case KeyPress: - len = XLookupString (&event, text, 10, &key, 0); - if (len == 1 && !shield_on) switch (text[0]) - { case 'e': + key = XLookupKeysym ((XKeyEvent *)&event, 0); + if (!shield_on) switch (key) + { case XK_Left: case XK_e: obj[SHIP].rotvel = obj[SHIP].rotvel - .1; break; - case 'r': + case XK_Right: case XK_r: obj[SHIP].rotvel = obj[SHIP].rotvel + .1; break; - case 'w': + case XK_w: obj[SHIP].rot -= pi/4; break; - case 't': + case XK_t: obj[SHIP].rot += pi/4; break; - case 'd': + case XK_d: obj[SHIP].rotvel = obj[SHIP].rotvel - .02; break; - case 'f': + case XK_f: obj[SHIP].rotvel = obj[SHIP].rotvel + .02; break; - case THRUST: + case XK_Up: case THRUST: obj[SHIP].xvel += cos(obj[SHIP].rot); obj[SHIP].yvel += sin(obj[SHIP].rot); obj[SHIP].shape = SHIPTHRSHAPE; break; + case XK_Control_L: case XK_Control_R: case FIRE: if (obj[SHIP].alive) fire(); break; - case ' ': + case XK_space: if (obj[SHIP].alive) { hyper(); flashon = 1; /* NOT XSetForeground (disp, gc, bg); @@ -787,35 +846,37 @@ XFillRectangle (disp, pixmap, pmgc, 0, 0, width, height); } break; - case SHIELD: + case XK_Down: case SHIELD: if (energy) { shield_on = 1; obj[SHIP].shape = SHIPSHAPE;} break; - case '.': /* decrease delay */ + case XK_period: /* decrease delay */ if (delay > 1) delay >>=1; break; - case ',': /* increase delay */ + case XK_comma: /* increase delay */ delay <<=1; break; - case 'm': /* decrease drawscale - may go negative */ + case XK_m: /* decrease drawscale - may go negative */ drawscale -= .1; break; - case 'n': /* increase drawscale */ + case XK_n: /* increase drawscale */ drawscale += .1; break; - case '2': /* increase speedscale */ + case XK_2: /* increase speedscale */ speedscale += .1; break; - case '1': /* decrease speedscale */ + case XK_1: /* decrease speedscale */ speedscale -= .1; break; - case 'b': /* increase moves/update */ + case XK_b: /* increase moves/update */ counterstart++; break; - case 'v': /* decrease moves/update */ + case XK_v: /* decrease moves/update */ if (counterstart > 1) counterstart--; break; case PAUSE: /* pause */ pause = 1 - pause; break; - case '+': /* cheat */ + case XK_plus: /* cheat */ ships++; botline(disp, window, gc); break; - case 'Q': /* quit */ - goto End; - case 's': /* start new ship */ + case XK_q: /* quit */ + if (event.xkey.state & ShiftMask) + goto End; + break; + case XK_s: /* start new ship */ if (!obj[SHIP].alive) if (ships < 1) goto Newgame; else goto Newship; @@ -823,16 +884,16 @@ } break; case KeyRelease: - len = XLookupString(&event, text, 10, &key, 0); - if (len == 1) switch (text[0]) - { case 'e': + key = XLookupKeysym((XKeyEvent *)&event, 0); + switch (key) + { case XK_Left: case XK_e: obj[SHIP].rotvel = 0; break; - case 'r': + case XK_Right: case XK_r: obj[SHIP].rotvel = 0; break; - case THRUST: + case XK_Up: case THRUST: obj[SHIP].shape = SHIPSHAPE; break; - case SHIELD: + case XK_Down: case SHIELD: shield_on = 0; break; } /* break; */ @@ -850,7 +911,7 @@ botline(disp, window, gc); } /* Write copyright notice */ - if (!ships && blist == NULL) + if (!ships) { sprintf(text, "Xasteroids"); XDrawImageString (disp, pixmap, gc, width/2-50, height/2-2*letheight, @@ -917,7 +978,11 @@ } else obj[ENEMYBUL].alive = 0; } +#ifdef HAS_USLEEP + usleep(delay); +#else for (i = 0; i < delay; i++); +#endif } } } --- xasteroids-5.0.orig/xast.docs +++ xasteroids-5.0/xast.docs @@ -4,16 +4,16 @@ Keypress Command -------- ------- - e Rotate counterclockwise ("left") - r Rotate clockwise ("right") + e / <- Rotate counterclockwise ("left") + r / -> Rotate clockwise ("right") w Rotate 45 degrees counterclockwise t Rotate 45 degrees clockwise d Increase counterclockwise rotational velocity f Increase clockwise rotational velocity - o Thrust - p Fire + o / Up Arrow Thrust + p / Control Fire space Hyperspace - ` Shields + ` / Down Arrow Shields s Start new ship in center of playing field (Also used to start a new game) esc Pause @@ -42,6 +42,3 @@ Resize the window with your window manager at any time for a different playing field. - -Use the command-line option -s on the xasteroids script -to see the high score list. --- xasteroids-5.0.orig/xast.man +++ xasteroids-5.0/xast.man @@ -1,9 +1,9 @@ -.TH xasteroids n +.TH xasteroids 6 .SH NAME xasteroids - X windows based asteroids style arcade game .SH SYNOPSIS -.ta 8n -\fBxasteroids\fP +.ta 6 +\fBxasteroids\fP [-s] .br .SH DESCRIPTION Make big rocks into little ones. @@ -11,60 +11,70 @@ .SH COMMANDS .I xasteroids - e Rotate counterclockwise ("left") - r Rotate clockwise ("right") - w Rotate 45 degrees counterclockwise - t Rotate 45 degrees clockwise - d Increase counterclockwise rotational velocity - f Increase clockwise rotational velocity - o Thrust - p Fire - ` Shields - space Hyperspace - s Start new ship in center of playing field - (Also used to start a new game) - esc Pause - Q Quit +.ft CW + e Left Arrow Rotate counterclockwise ("left") + r Right Arrow Rotate clockwise ("right") + w Rotate 45 degrees counterclockwise + t Rotate 45 degrees clockwise + d Increase CCWise rotational velocity + f Increase clockwise rotational velocity + o Up Arrow Thrust + p Control Fire + ` Down Arrow Shields + space Hyperspace + s Start new ship in center of playing field + (Also used to start a new game) + esc Pause + Q Quit +.ft R Speed commands: Key associated with faster speed is to the right of its - corresponding key associated with slower speed. +corresponding key associated with slower speed. - . Decrease delay: Speed game up - , Increase delay: Slow the game down - m Decrease size ("Minimize") - n Increase size - b Increase # of moves/frame - v Decrease # of moves/frame - 2 Increase scale of movement - 1 Decrease scale of movement +.ft CW + . Decrease delay: Speed game up + , Increase delay: Slow the game down + m Decrease size ("Minimize") + n Increase size + b Increase # of moves/frame + v Decrease # of moves/frame + 2 Increase scale of movement + 1 Decrease scale of movement Object Score - Big asteroid 25, or 2000*level if it is the last asteroid remaining - Medium asteroid 50, or 500*level if it is the last asteroid remaining + Big asteroid 25, or + 2000*level if last asteroid remaining + Medium asteroid 50, or + 500*level if last asteroid remaining Little asteroid 100 Enemy spaceship 500 Enemy bullet 500 +.ft R Commands can only be entered when the mouse pointer is in the asteroids window. Resize the window with your window manager at any time for a different playing field. - -.SH OPTIONS -.I xasteroids [-s] --s Display high scores without running game. .PP .SH AUTHOR Phil Goetz .br goetz@cs.Buffalo.EDU .SH CONTRIBUTORS -Peter Phillips pphillip@cs.ubc.ca -Pat Ryan pat@jaameri.gsfc.nasa.gov -Craig Smith csmith@cscs.UUCP -Doug Merritt doug@netcom.com -James Berg berg@plains (makefile) -Chris Moore moore@src.bae.co.uk (hi score script) -David Partain dlp@ida.liu.se (original man page) +Peter Phillips +.br +Pat Ryan +.br +Craig Smith +.br +Doug Merritt +.br +Stephen McCamant +.br +James Berg (makefile) +.br +Chris Moore (hi score script) +.br +David Partain (original man page)