home *** CD-ROM | disk | FTP | other *** search
- /*
- * Spy vs "Bob"
- *
- * Based on the Apple ][ game "Spy vs Spy", and 'dodger' by Bert Nelson
- */
-
- /*
- * Copyright 1992 David Lemke and Network Computing Devices
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Network Computing Devices not be
- * used in advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission. Network Computing
- * Devices makes no representations about the suitability of this software
- * for any purpose. It is provided "as is" without express or implied
- * warranty.
- *
- * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
- * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
- * OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author:
- * Dave Lemke
- * lemke@ncd.com
- *
- * Network Computing Devices, Inc
- * 350 North Bernardo Ave
- * Mountain View, CA 94043
- *
- * @(#)svs.c 1.9 92/02/10
- *
- */
-
- #include <stdio.h>
- #include <X11/Xos.h>
- #include <sys/types.h>
- //#include <sys/time.h>
- #include <errno.h>
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <math.h>
-
- extern char *getenv();
-
- extern int errno;
- char *progname;
- char user_name[40];
- Bool debug = False;
-
- #define rnd(x) (random() % (x))
-
- /* game stuff */
- //#define NUM_LEDGES 10
- #define NUM_LEDGES 6
- #define NUM_VATORS 4
-
- #define MIN_LEDGE 3 /* tightest it will get */
-
- #define NUM_LIVES 5
- #define START_LEDGE (NUM_LEDGES - 1)
- #define START_TIME 100
- #define DELAY_TIME 20000
- #define ROUNDS_PER_UPDATE 8
-
- #define GIFT_SCORE 500
- #define GIFT_NOTYET 1
- #define GIFT_OUT 2
- #define GIFT_TAKEN 3
-
-
- extern void update_scores();
- extern void show_scores();
-
- int score = 0;
- int highscore = 0;
- int time_left;
- int time_interval = ROUNDS_PER_UPDATE;
- int lives = 0;
- int ledge_num;
- int ledge_side;
- int level;
- int ledge;
- int vator_loc[NUM_VATORS];
- int vator_speed[NUM_VATORS];
- int vator_run;
- int man_x,
- man_y;
- int man_speed;
- int man_delta;
-
- int gift_x,
- gift_y;
- int gift_state;
- Bool refresh_gift;
- int gift_time;
-
- /* increase with each level */
- double level_factor = 1.0;
-
- /* speeds */
- #define MIN_VATOR_SPEED 5
- #define VATOR_SPEED_RANGE 10
-
- #ifdef fast
- #define LEVEL_INCREASE (0.2)
- #else
- #define LEVEL_INCREASE (0.0)
- #endif
-
- /* X stuff */
-
- Display *dpy;
- Window game_win;
- Colormap cmap;
- GC text_gc;
- GC vator_gc;
- GC draw_gc;
- unsigned long man_color,
- vator_color,
- vator_bg_color,
- timer_color,
- gift_color,
- splat_color,
- ledge_color;
- unsigned long text_color;
- unsigned long bg_color;
- Bool paused = False;
- Pixmap man_left,
- man_right,
- man_stand,
- splat_map,
- slack_map,
- vator_map;
-
- #define MAN 0
- #define VATOR 1
- #define TIMER 2
- #define LEDGE 3
- #define TEXT 4
- #define BACKGROUND 5
- #define GIFT 6
- #define VATOR_BG 7
- #define SPLAT 8
-
- static char *game_colors[] = {
- "pink", /* MAN */
- "blue", /* VATOR */
- "yellow", /* TIMER */
- "brown", /* LEDGE */
- "white", /* TEXT */
- "black", /* BACKGROUND */
- "green", /* GIFT */
- "white", /* VATOR_BG */
- "pink", /* SPLAT */
- };
-
-
- static char bob_vator_bits[] = {
- 0xff, 0x01, 0x50, 0x25, 0x00, 0xfe, 0x03, 0x07, 0x00, 0xfc, 0xff, 0x03,
- 0x80, 0x03, 0x03, 0x00, 0xff, 0x5e, 0x06, 0x00, 0x03, 0x03, 0xc0, 0x97,
- 0x44, 0x0a, 0x00, 0x03, 0x03, 0xc0, 0x17, 0xa9, 0x1d, 0x00, 0x03, 0x03,
- 0xe0, 0x7f, 0xdd, 0x7f, 0x00, 0x03, 0x03, 0xf0, 0xff, 0xff, 0xf3, 0x00,
- 0x03, 0x03, 0xf0, 0xff, 0xdf, 0xf0, 0x00, 0x03, 0x03, 0xf0, 0xa5, 0x17,
- 0xf0, 0x01, 0x03, 0x03, 0xf0, 0x00, 0x00, 0xf0, 0x00, 0x03, 0x03, 0xf8,
- 0x00, 0x00, 0xe8, 0x00, 0x03, 0x03, 0xf0, 0x01, 0x00, 0xe8, 0x00, 0x03,
- 0x03, 0xf0, 0x00, 0x00, 0xe4, 0x00, 0x03, 0x03, 0xf8, 0x00, 0x00, 0xe8,
- 0x00, 0x03, 0x03, 0xf0, 0x09, 0x80, 0xfb, 0x00, 0x03, 0x03, 0xe8, 0x3e,
- 0xe0, 0xee, 0x00, 0x03, 0x03, 0xf8, 0x68, 0x70, 0xfd, 0x00, 0x03, 0x03,
- 0x30, 0xee, 0x78, 0xe3, 0x00, 0x03, 0x03, 0x30, 0xf2, 0xa8, 0x60, 0x00,
- 0x03, 0x03, 0x30, 0xb4, 0xc0, 0x63, 0x00, 0x03, 0x03, 0x30, 0x98, 0x00,
- 0x40, 0x00, 0x03, 0x03, 0x20, 0x80, 0x00, 0xa0, 0x00, 0x03, 0x03, 0xb0,
- 0x40, 0x00, 0x60, 0x00, 0x03, 0x03, 0x80, 0xd1, 0x70, 0x18, 0x00, 0x03,
- 0x03, 0xc0, 0xe9, 0x8e, 0x0d, 0x00, 0x03, 0x03, 0x80, 0xf7, 0x87, 0x3f,
- 0x00, 0x03, 0x03, 0x80, 0xfa, 0xea, 0x0c, 0x00, 0x03, 0x03, 0x80, 0x32,
- 0x49, 0x0c, 0x00, 0x03, 0x03, 0x00, 0x35, 0x35, 0x0c, 0x00, 0x03, 0x03,
- 0x00, 0xf1, 0x0f, 0x06, 0x00, 0x03, 0x03, 0x00, 0xf6, 0x15, 0x02, 0x00,
- 0x03, 0x03, 0x10, 0xda, 0x0b, 0x03, 0x00, 0x03, 0x03, 0x48, 0x4e, 0x00,
- 0x01, 0x00, 0x03, 0x03, 0x58, 0x77, 0x80, 0x00, 0x00, 0x03, 0x03, 0xe2,
- 0xf3, 0xc0, 0x00, 0x00, 0x03, 0x03, 0xcc, 0x41, 0x3f, 0x00, 0x00, 0x03,
- 0x03, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0xdc, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x07, 0x70, 0x00, 0x00, 0x00, 0x80, 0x03, 0xff, 0x01, 0x00,
- 0x00, 0x00, 0xfe, 0x03};
-
- static char man_left_bits[] = {
- 0x18, 0x01, 0x00, 0xf8, 0x00, 0x00, 0x7e, 0x00, 0x00, 0xfe, 0x00, 0x00,
- 0xfc, 0x01, 0x00, 0xfa, 0x03, 0x00, 0xf1, 0xff, 0x01, 0x20, 0xff, 0x01,
- 0x84, 0x1f, 0x01, 0x86, 0x3f, 0x01, 0xce, 0xff, 0x01, 0x78, 0xff, 0x03,
- 0x20, 0xff, 0x01, 0x00, 0xff, 0x00, 0x80, 0x7f, 0x04, 0xc0, 0xfe, 0x0e,
- 0xc0, 0x9c, 0x0b, 0x80, 0x09, 0x09, 0x00, 0x03, 0x00, 0xc0, 0x01, 0x00};
-
- static char man_right_bits[] = {
- 0x00, 0x88, 0x01, 0x00, 0xf0, 0x01, 0x00, 0xe0, 0x07, 0x00, 0xf0, 0x07,
- 0x00, 0xf8, 0x03, 0x00, 0xfc, 0x05, 0xf8, 0xff, 0x08, 0xf8, 0x4f, 0x00,
- 0x88, 0x1f, 0x02, 0xc8, 0x1f, 0x06, 0xf8, 0x3f, 0x07, 0xfc, 0xef, 0x01,
- 0xf8, 0x4f, 0x00, 0xf0, 0x0f, 0x00, 0xe2, 0x1f, 0x00, 0xf7, 0x37, 0x00,
- 0x9d, 0x33, 0x00, 0x09, 0x19, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x38, 0x00};
-
- static char man_stand_bits[] = {
- 0x80, 0x03, 0x00, 0xc0, 0x07, 0x00, 0xf0, 0x1f, 0x00, 0xc0, 0x07, 0x00,
- 0x80, 0x03, 0x00, 0x00, 0x01, 0x00, 0x80, 0x03, 0x00, 0xf0, 0x0f, 0x00,
- 0xfc, 0x1f, 0x00, 0xfe, 0xbf, 0x0f, 0xf3, 0x7f, 0x01, 0xf3, 0xff, 0x01,
- 0xfe, 0x1f, 0x01, 0xfc, 0x1f, 0x00, 0xf8, 0x3f, 0x00, 0xf0, 0x3f, 0x00,
- 0xf0, 0x7f, 0x00, 0xc0, 0x0c, 0x00, 0xc0, 0x0c, 0x00, 0xf0, 0x3c, 0x00};
-
-
- static char slack_bits[] = {
- 0xeb, 0x56, 0xa9, 0x32, 0xeb, 0x32, 0xaa, 0x52, 0xbb, 0x56};
-
- static char splatter_bits[] = {
- 0x68, 0x20, 0x02, 0x00, 0x2b, 0x49, 0x31, 0x1e, 0x3e, 0x92, 0x88, 0x11,
- 0x26, 0x22, 0x45, 0x1e, 0x6e, 0xec, 0xe3, 0x07, 0xf8, 0xff, 0xff, 0x00,
- 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00};
-
- #define MAN_WIDTH 20
- #define MAN_HEIGHT 20
- #define MAN_DELTA 6 /* motion per step */
- #define MIN_MAN_DELTA 4
-
- #define SPLAT_WIDTH 30
- #define SPLAT_HEIGHT 10
-
- #define VATOR_WIDTH 50
- #define VATOR_HEIGHT 40
- #define VATOR_GAP 40 /* space between them */
-
- #define GIFT_WIDTH 15
- #define GIFT_HEIGHT 5
-
- #define LEDGE_WIDTH 30
- #define LEDGE_HEIGHT 4
-
- #define LEDGE_GAP ((int)(VATOR_HEIGHT * 1.2 + LEDGE_HEIGHT))
-
- #define TIMER_HEIGHT 25
- #define TIMER_SLICE 1 /* visual size of each tick */
-
- #define INFO_HEIGHT 100 /* size of timer, score, etc */
-
- #define DELIM_HEIGHT 10 /* bar between game and info */
-
- #define WIN_WIDTH (NUM_VATORS * VATOR_WIDTH + (NUM_VATORS - 1) * VATOR_GAP + 2 * LEDGE_WIDTH)
- #define WIN_HEIGHT (NUM_LEDGES * LEDGE_GAP + INFO_HEIGHT + DELIM_HEIGHT)
-
- /* range of y locs for elevators */
- #define VATOR_RUN (WIN_HEIGHT - (INFO_HEIGHT + DELIM_HEIGHT) - VATOR_HEIGHT)
-
- /* range of man */
- #define MAN_MAX_X (WIN_WIDTH - MAN_DELTA - MAN_WIDTH)
-
- #define TIMER_Y (WIN_HEIGHT - ((INFO_HEIGHT * 2) / 3))
- #define EXTRA_MAN_X (WIN_WIDTH - 2 * MAN_WIDTH)
- #define STATUS_Y (TIMER_Y + 15)
- #define STATUS_X (2 * TIMER_SLICE)
-
- #define FONTNAME "fixed"
-
- #define COLLISION_FUDGE 4
-
- #define vator_pos(i) (LEDGE_WIDTH + (i) * (VATOR_GAP + VATOR_WIDTH))
- #define man_start_pos(i) (MAN_DELTA + (i) * (WIN_WIDTH - MAN_WIDTH - (2 * MAN_DELTA)))
- #define man_y_pos(l) ((LEDGE_GAP * ((l) + 1)) - (LEDGE_HEIGHT + MAN_HEIGHT))
-
- #define min(a, b) (((a) < (b)) ? (a) : (b))
- #define max(a, b) (((a) > (b)) ? (a) : (b))
-
- static void wait_for_start();
- static void run();
- static void finish_up();
-
- static void draw_ledges();
- static void draw_init_screen();
- static void draw_scores();
- static void draw_obj();
- static void draw_timer();
- static void draw_status();
- static void draw_message();
- static void draw_message2();
- static void erase_obj();
- static void new_man();
- static void new_gift();
- static void flush_keyboard();
-
- static void
- usage()
- {
- fprintf(stderr, "Usage: %s [-display displayname]\n", progname);
- exit(0);
- }
-
- static unsigned long
- get_color(cname)
- char *cname;
- {
- XColor col;
-
- XParseColor(dpy, cmap, cname, &col);
- XAllocColor(dpy, cmap, &col);
- return col.pixel;
- }
-
- static void
- init_display(ac, av, dname)
- int ac;
- char **av;
- char *dname;
- {
- Bool is_color = False;
- int screen;
- unsigned long wmask,
- gcmask;
- XSetWindowAttributes wattr;
- XGCValues gcv;
- XFontStruct *pfont;
- int x,
- y;
- XSizeHints xsh;
- XWMHints wmhints;
-
- dpy = XOpenDisplay(dname);
- if (!dpy) {
- fprintf(stderr, "%s: Couldn't open display \"%s\"\n", progname, dname);
- exit(-1);
- }
- screen = DefaultScreen(dpy);
-
- if (debug)
- XSynchronize(dpy, 1);
-
- if (DisplayCells(dpy, screen) > 2)
- is_color = True;
- cmap = DefaultColormap(dpy, screen);
-
- /* set up colors */
- if (is_color) {
- man_color = get_color(game_colors[MAN]);
- splat_color = get_color(game_colors[SPLAT]);
- vator_color = get_color(game_colors[VATOR]);
- vator_bg_color = get_color(game_colors[VATOR_BG]);
- ledge_color = get_color(game_colors[LEDGE]);
- timer_color = get_color(game_colors[TIMER]);
- text_color = get_color(game_colors[TEXT]);
- gift_color = get_color(game_colors[GIFT]);
- bg_color = get_color(game_colors[BACKGROUND]);
- } else {
- man_color = WhitePixel(dpy, screen);
- splat_color = WhitePixel(dpy, screen);
- vator_color = BlackPixel(dpy, screen);
- vator_bg_color = WhitePixel(dpy, screen);
- ledge_color = WhitePixel(dpy, screen);
- timer_color = WhitePixel(dpy, screen);
- text_color = WhitePixel(dpy, screen);
- gift_color = WhitePixel(dpy, screen);
- bg_color = BlackPixel(dpy, screen);
- }
-
- x = 100;
- y = 100;
-
- wattr.background_pixel = bg_color;
- wattr.event_mask = ExposureMask | KeyPressMask |
- ButtonPressMask | ButtonReleaseMask;
-
- wmask = CWEventMask | CWBackPixel;
-
- game_win = XCreateWindow(dpy, RootWindow(dpy, screen), x, y, WIN_WIDTH,
- WIN_HEIGHT, 0, CopyFromParent, CopyFromParent, CopyFromParent,
- wmask, &wattr);
-
- xsh.flags = PSize | PMinSize | PMaxSize;
- xsh.width = xsh.min_width = xsh.max_width = WIN_WIDTH;
- xsh.height = xsh.min_height = xsh.max_height = WIN_HEIGHT;
- XSetStandardProperties(dpy, game_win, "Spy vs \"Bob\"", "SvB", None,
- av, ac, &xsh);
-
- wmhints.input = True;
- wmhints.flags = InputHint;
- XSetWMHints(dpy, game_win, &wmhints);
-
- pfont = XLoadQueryFont(dpy, FONTNAME);
-
- gcmask = GCForeground | GCBackground;
- gcv.foreground = text_color;
- gcv.background = bg_color;
- if (pfont) {
- gcv.font = pfont->fid;
- gcmask |= GCFont;
- }
- text_gc = XCreateGC(dpy, game_win, gcmask, &gcv);
-
- gcmask = GCForeground | GCBackground | GCGraphicsExposures;
- gcv.foreground = man_color;
- gcv.background = bg_color;
- gcv.graphics_exposures = False;
- draw_gc = XCreateGC(dpy, game_win, gcmask, &gcv);
-
- gcmask = GCForeground | GCBackground | GCGraphicsExposures;
- gcv.foreground = vator_color;
- gcv.background = vator_bg_color;
- gcv.graphics_exposures = False;
- vator_gc = XCreateGC(dpy, game_win, gcmask, &gcv);
-
- /* make bitmaps */
- vator_map = XCreateBitmapFromData(dpy, game_win, bob_vator_bits,
- VATOR_WIDTH, VATOR_HEIGHT);
- man_left = XCreateBitmapFromData(dpy, game_win, man_left_bits,
- MAN_WIDTH, MAN_HEIGHT);
- man_right = XCreateBitmapFromData(dpy, game_win, man_right_bits,
- MAN_WIDTH, MAN_HEIGHT);
- man_stand = XCreateBitmapFromData(dpy, game_win, man_stand_bits,
- MAN_WIDTH, MAN_HEIGHT);
- slack_map = XCreateBitmapFromData(dpy, game_win, slack_bits,
- GIFT_WIDTH, GIFT_HEIGHT);
- splat_map = XCreateBitmapFromData(dpy, game_win, splatter_bits,
- SPLAT_WIDTH, SPLAT_HEIGHT);
-
- XMapWindow(dpy, game_win);
- }
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int i;
- char *dname = NULL;
-
- progname = argv[0];
- for (i = 1; i < argc; i++) {
- if (!strncmp(argv[i], "-d", 2)) {
- if (argv[++i])
- dname = argv[i];
- else
- usage();
- }
- }
- strcpy(user_name, "Unknown");
- if (getenv("USER"))
- strcpy(user_name, getenv("USER"));
- srandom(getpid());
- init_display(argc, argv, dname);
- update_scores();
- draw_init_screen();
- while (1) {
- wait_for_start();
- run();
- finish_up();
- }
- }
-
- static void
- refresh_screen()
- {
- int i;
-
- XClearWindow(dpy, game_win);
-
- draw_ledges();
-
- /* delimiter */
- XFillRectangle(dpy, game_win, text_gc, 0, WIN_HEIGHT - INFO_HEIGHT,
- WIN_WIDTH, DELIM_HEIGHT);
-
- for (i = 0; i < NUM_VATORS; i++) {
- draw_obj(vator_pos(i), vator_loc[i], VATOR);
- }
- draw_obj(man_x, man_y, MAN);
- if (gift_state == GIFT_OUT)
- draw_obj(gift_x, gift_y, GIFT);
- draw_scores();
- draw_message(NULL);
- draw_message2(NULL);
- }
-
- static void
- draw_init_screen()
- {
- int i;
-
- XClearWindow(dpy, game_win);
-
- /* place some random elevators */
- for (i = 0; i < NUM_VATORS; i++) {
- vator_loc[i] = rnd(VATOR_RUN);
- }
-
- /* and the man */
- man_x = man_start_pos(rnd(2));
- man_y = man_y_pos(rnd(NUM_LEDGES));
-
- gift_state = GIFT_NOTYET;
- new_gift();
-
- draw_message(" Spy Vs \"Bob\" Hit 's' to Start, 'q' to Quit, 'h' for Hi Scores");
- draw_message2(" Use 'j', 'k', SPACE or Mouse buttons to move, 'p' to Pause");
-
- refresh_screen();
- }
-
- char
- get_key(kev)
- XKeyPressedEvent *kev;
- {
- char buffer[10];
- int len;
-
- len = XLookupString(kev, buffer, 10, NULL, NULL);
- if (len)
- return buffer[0];
- else
- return (char) -1;
- }
-
- /*
- * draws instructions, waits for 'q' or 's'
- */
- static void
- wait_for_start()
- {
- XEvent ev;
- Bool done = False;
- char c;
-
- while (!done) {
- XNextEvent(dpy, &ev);
- switch (ev.type) {
- case Expose:
- if (ev.xexpose.count == 0)
- refresh_screen();
- break;
- case KeyPress:
- c = get_key((XKeyPressedEvent *) & ev);
- switch (c) {
- case 'q':
- exit(0);
- break;
- case 's':
- done = True;
- break;
- case 'h':
- show_scores();
- refresh_screen();
- break;
- default:
- break;
- }
- }
- }
- score = 0;
- draw_message("");
- draw_message2("");
- }
-
- static void
- init_vators()
- {
- int i;
-
- for (i = 0; i < NUM_VATORS; i++) {
- vator_loc[i] = rnd(vator_run);
- vator_speed[i] = rnd(VATOR_SPEED_RANGE) + MIN_VATOR_SPEED;
- }
- }
-
- static void
- got_across()
- {
- if (gift_state == GIFT_OUT)
- erase_obj(gift_x, gift_y, GIFT);
- man_speed = 0;
- ledge_num--;
- score += 200 + (time_left * 5);
- ledge++;
- if (ledge_num < 0) { /* finished level */
- /* shrink the game board */
- if (level < (START_LEDGE - MIN_LEDGE)) {
- /* don't drop it to 0, in case anyone's that good */
- ledge_num = START_LEDGE - level;
- vator_run -= LEDGE_GAP;
- } else {
- ledge_num = MIN_LEDGE;
- }
- lives++;
- ledge_side = 0;
- new_man();
- level_factor += LEVEL_INCREASE;
- level++;
- time_interval--; /* speed it up too */
- if (time_interval < 1)
- time_interval = 1;
- man_delta--;
- if (man_delta <= MIN_MAN_DELTA)
- man_delta = MIN_MAN_DELTA;
- }
- man_y = man_y_pos(ledge_num);
- time_left = START_TIME;
- gift_time = START_TIME - rnd(START_TIME / 2);
- gift_state = GIFT_NOTYET;
- flush_keyboard();
- draw_scores();
- }
-
- static void
- move_man()
- {
- erase_obj(man_x, man_y, MAN);
- man_x += man_speed;
- if (man_x < man_start_pos(0)) {
- man_x = man_start_pos(0);
- if (ledge_side == 1) { /* made it across */
- ledge_side = 0;
- got_across();
- }
- }
- if (man_x > man_start_pos(1)) {
- man_x = man_start_pos(1);
- if (ledge_side == 0) {
- ledge_side = 1;
- got_across();
- }
- }
- draw_obj(man_x, man_y, MAN);
- }
-
- static void
- move_vators()
- {
- int i;
-
- for (i = 0; i < NUM_VATORS; i++) {
- erase_obj(vator_pos(i), vator_loc[i], VATOR);
- vator_loc[i] += vator_speed[i];
- if (vator_loc[i] <= 0) {
- vator_loc[i] = 0;
- vator_speed[i] = level_factor *
- (rnd(VATOR_SPEED_RANGE) + MIN_VATOR_SPEED);
- } else if (vator_loc[i] >= vator_run) {
- vator_loc[i] = vator_run;
- vator_speed[i] = -level_factor *
- (rnd(VATOR_SPEED_RANGE) + MIN_VATOR_SPEED);
- }
- draw_obj(vator_pos(i), vator_loc[i], VATOR);
- }
- }
-
- static void
- new_man()
- {
- int i;
-
- erase_obj(man_x, man_y, MAN);
- if (gift_state == GIFT_OUT)
- erase_obj(gift_x, gift_y, GIFT);
- for (i = 0; i < NUM_VATORS; i++)
- erase_obj(vator_pos(i), vator_loc[i], VATOR);
- time_left = START_TIME;
- gift_time = START_TIME - rnd(START_TIME / 2);
- init_vators();
- man_speed = 0;
- man_x = man_start_pos(ledge_side);
- man_y = man_y_pos(ledge_num);
- draw_obj(man_x, man_y, MAN);
- draw_status();
- flush_keyboard();
- }
-
- static void
- check_collision()
- {
- int i;
-
- for (i = 0; i < NUM_VATORS; i++) {
- if (((man_x + MAN_WIDTH - COLLISION_FUDGE) > vator_pos(i)) &&
- (man_x < (vator_pos(i) + VATOR_WIDTH - COLLISION_FUDGE))) {
- if ((man_y > vator_loc[i]) &&
- (man_y < vator_loc[i] + VATOR_HEIGHT)) {
- lives--;
- draw_message("SPLAT!!!");
- erase_obj(man_x, man_y, MAN);
- draw_obj(vator_pos(i), vator_loc[i], VATOR);
- draw_obj(man_x - 5, man_y + 10, SPLAT);
- XSync(dpy, 0);
- sleep(1);
- refresh_screen();
- new_man();
- return;
- }
- }
- }
-
- if (gift_state == GIFT_OUT) {
- if (((man_x + MAN_WIDTH) > gift_x) &&
- (man_x < (gift_x + GIFT_WIDTH))) {
- score += GIFT_SCORE;
- gift_state = GIFT_TAKEN;
- draw_scores();
- return;
- }
- }
- }
-
- static void
- flush_keyboard()
- {
- XEvent ev;
-
- while (XCheckTypedEvent(dpy, KeyPress, &ev));
- while (XCheckTypedEvent(dpy, ButtonPress, &ev));
- while (XCheckTypedEvent(dpy, ButtonRelease, &ev));
- }
-
- static void
- new_gift()
- {
- if (gift_state == GIFT_NOTYET) {
- gift_y = man_y + GIFT_HEIGHT;
- gift_x = rnd(WIN_WIDTH - 2 * LEDGE_WIDTH) + LEDGE_WIDTH;
- draw_obj(gift_x, gift_y, GIFT);
- gift_state = GIFT_OUT;
- }
- }
-
- static Bool
- handle_event()
- {
- char c = '\0';
- XEvent ev;
- int button;
-
- XNextEvent(dpy, &ev);
- switch (ev.type) {
- case KeyPress:
- c = get_key((XKeyPressedEvent *) & ev);
- switch (c) {
- case 'q':
- return False;
- case 'j':
- man_speed = -man_delta;
- break;
- case 'k':
- man_speed = man_delta;
- break;
- case ' ':
- man_speed = 0;
- break;
- case 'p':
- paused = !paused;
- draw_status();
- break;
- default:
- break;
- }
- break;
- case Expose:
- refresh_screen();
- break;
- case ButtonPress:
- button = ev.xbutton.button;
- if (button == 1) {
- man_speed = -man_delta;
- } else {
- man_speed = man_delta;
- }
- break;
- case ButtonRelease:
- button = ev.xbutton.button;
- man_speed = 0;
- break;
- }
- return True;
- }
-
- static void
- init_parms()
- {
- ledge_num = START_LEDGE;
- ledge_side = 0;
- level = 1;
- ledge = 0;
- lives = NUM_LIVES;
- man_delta = MAN_DELTA;
- vator_run = VATOR_RUN;
- erase_obj(gift_x, gift_y, GIFT);
- gift_state = GIFT_NOTYET;
- level_factor = 1.0;
- time_interval = ROUNDS_PER_UPDATE;
- }
-
- /*
- * plays the game
- */
- static void
- run()
- {
- int time = 0;
- int ret;
- int serverfd = XConnectionNumber(dpy);
- fd_set read_fds,
- base;
- struct timeval tval,
- *tm;
-
- FD_ZERO(&base);
- FD_SET(serverfd, &base);
- init_parms();
- new_man();
-
- tval.tv_sec = 0;
- tval.tv_usec = DELAY_TIME;
- while (1) {
- if (XPending(dpy)) {
- if (!handle_event())
- return;
- continue;
- }
- if (!paused)
- tm = &tval;
- else
- tm = (struct timeval *) 0;
- read_fds = base;
- ret = select(serverfd + 1, &read_fds, (fd_set *) 0, (fd_set *) 0, tm);
- if (ret == -1)
- if (errno == EINTR)
- continue;
- if (ret == 1) {
- if (!handle_event())
- return;
- continue;
- }
- if (paused)
- continue;
- if (time_left == 0) {
- lives--;
- draw_message("Time's Up");
- XSync(dpy, 0);
- sleep(1);
- new_man();
- time = 0;
- }
- if (lives == 0)
- return;
-
- time++;
- if (time >= time_interval) {
- time = 0;
- time_left--;
- if (gift_time <= time_left) {
- new_gift();
- gift_time = -1;
- }
- draw_timer();
- /* XXX this shouldn't really be necessray, but on a slow display,
- * output can get queueed enough that the action gets delayed
- */
- XSync(dpy, 0);
- }
- move_vators();
- move_man();
- check_collision();
- if (gift_state == GIFT_OUT)
- draw_obj(gift_x, gift_y, GIFT);
- }
- }
-
- /*
- * cleans up screen, shows score
- */
- static void
- finish_up()
- {
- draw_message(" Spy Vs \"Bob\" Hit 's' to Start, 'q' to Quit, 'h' for Hi Scores");
- draw_message2(" Use 'j', 'k', SPACE or Mouse buttons to move, 'p' to Pause");
- add_score(score, ledge);
- draw_scores();
- refresh_screen();
- }
-
- static void
- erase_obj(x, y, type)
- int x,
- y,
- type;
- {
- switch (type) {
- case VATOR:
- XClearArea(dpy, game_win, x, y, VATOR_WIDTH, VATOR_HEIGHT, False);
- break;
- case GIFT:
- XClearArea(dpy, game_win, x, y, GIFT_WIDTH, GIFT_HEIGHT, False);
- break;
- case MAN:
- XClearArea(dpy, game_win, x, y, MAN_WIDTH, MAN_HEIGHT, False);
- break;
- }
- }
-
- static void
- draw_obj(x, y, type)
- int x,
- y,
- type;
- {
- Pixmap mmap;
-
- switch (type) {
- case VATOR:
- XCopyPlane(dpy, vator_map, game_win, vator_gc,
- 0, 0, VATOR_WIDTH, VATOR_HEIGHT, x, y, 1);
- break;
- case GIFT:
- XSetForeground(dpy, draw_gc, gift_color);
- XCopyPlane(dpy, slack_map, game_win, draw_gc,
- 0, 0, GIFT_WIDTH, GIFT_HEIGHT, x, y, 1);
- break;
- case MAN:
- XSetForeground(dpy, draw_gc, man_color);
- if (man_speed == 0)
- mmap = man_stand;
- else if (man_speed < 0)
- mmap = man_left;
- else
- mmap = man_right;
- XCopyPlane(dpy, mmap, game_win, draw_gc,
- 0, 0, MAN_WIDTH, MAN_HEIGHT, x, y, 1);
- break;
- case SPLAT:
- XSetForeground(dpy, draw_gc, splat_color);
- XCopyPlane(dpy, splat_map, game_win, draw_gc,
- 0, 0, SPLAT_WIDTH, SPLAT_HEIGHT, x, y, 1);
- break;
- case LEDGE:
- XSetForeground(dpy, draw_gc, ledge_color);
- XFillRectangle(dpy, game_win, draw_gc, x, y, LEDGE_WIDTH, LEDGE_HEIGHT);
- break;
- }
- }
-
- static void
- draw_ledges()
- {
- int i;
- int y;
-
- for (i = 0; i < NUM_LEDGES; i++) {
- y = (i + 1) * LEDGE_GAP;
- draw_obj(0, y, LEDGE);
- draw_obj(WIN_WIDTH - LEDGE_WIDTH, y, LEDGE);
- }
- }
-
- static void
- draw_scores()
- {
- char score_buffer[256];
-
- sprintf(score_buffer, "Time Left Level %2d Best %7d Score %7d Lives %2d",
- level, highscore, score, lives);
- XDrawImageString(dpy, game_win, text_gc, STATUS_X, WIN_HEIGHT - 5,
- score_buffer, strlen(score_buffer));
- }
-
- static void
- draw_timer()
- {
- if (paused) {
- draw_message("PAUSED");
- } else {
- XClearArea(dpy, game_win, TIMER_SLICE,
- TIMER_Y, TIMER_SLICE * START_TIME, TIMER_HEIGHT, False);
- XSetForeground(dpy, draw_gc, timer_color);
- XFillRectangle(dpy, game_win, draw_gc, TIMER_SLICE,
- TIMER_Y, TIMER_SLICE * time_left, TIMER_HEIGHT);
- }
- }
-
- static void
- draw_status()
- {
- int i,
- x,
- y;
- int old_sp;
-
- XClearArea(dpy, game_win, TIMER_SLICE * (START_TIME + 1), TIMER_Y,
- 10000, MAN_HEIGHT, False);
- y = TIMER_Y;
- x = EXTRA_MAN_X;
- old_sp = man_speed;
- man_speed = 0; /* make sure they're standing */
- for (i = 0; i < min(lives - 1, 7); i++) {
- draw_obj(x, y, MAN);
- x -= (int) (MAN_WIDTH * 1.5);
- }
- man_speed = old_sp;
- draw_timer();
- draw_scores();
- }
-
- static void
- draw_message(str)
- char *str;
- {
- static char msgbuf[256];
-
- if (str)
- strcpy(msgbuf, str);
- XClearArea(dpy, game_win, TIMER_SLICE,
- TIMER_Y, TIMER_SLICE * START_TIME, TIMER_HEIGHT, False);
- XDrawImageString(dpy, game_win, text_gc, STATUS_X, STATUS_Y,
- msgbuf, strlen(msgbuf));
- }
-
- static void
- draw_message2(str)
- char *str;
- {
- static char msgbuf2[256];
-
- if (str)
- strcpy(msgbuf2, str);
- XClearArea(dpy, game_win, STATUS_X,
- STATUS_Y + 10, 1000, 15, False);
- XDrawImageString(dpy, game_win, text_gc, STATUS_X, STATUS_Y + 20,
- msgbuf2, strlen(msgbuf2));
- }
-