argv@island.uu.net (Dan Heller) (10/14/89)
Submitted-by: Jerry Shekhel <eddie.mit.edu!polygen!jerry> Posting-number: Volume 5, Issue 10 Archive-name: xchomp/part01 #! /bin/sh # This is a shell archive. Remove anything before this line, then feed it # into a shell via "sh file" or similar. To overwrite existing files, # type "sh file -c". # The tool that generated this appeared in the comp.sources.unix newsgroup; # send mail to comp-sources-unix@uunet.uu.net if you want that tool. # If this archive is complete, you will see the following message at the end: # "End of archive 1 (of 3)." # Contents: xchomp/Makefile xchomp/bitmaps xchomp/bitmaps/demo/ # xchomp/bitmaps/frame/ xchomp/bitmaps/fruit/ # xchomp/bitmaps/fruit/ff1.h xchomp/bitmaps/maze/ # xchomp/bitmaps/pac/ xchomp/contact.c xchomp/drivers.c # xchomp/main.c xchomp/resources.c # Wrapped by argv@island on Fri Oct 13 12:17:29 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH mkdir xchomp if test -f 'xchomp/Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xchomp/Makefile'\" else echo shar: Extracting \"'xchomp/Makefile'\" \(1002 characters\) sed "s/^X//" >'xchomp/Makefile' <<'END_OF_FILE' X X# X# MAKEFILE FOR XCHOMP X# X X X# X# Add -DFRAME_DELAY=xxxxx to CFLAGS if the game runs too fast without it. X# The "xxxxx" is the number of microseconds to wait between motion frames. X# X XCFLAGS = -O X XCC = cc $(CFLAGS) X XOBJECTS = contact.o \ X demo.o \ X drivers.o \ X main.o \ X maze.o \ X props.o \ X resources.o \ X status.o X XBITMAPFILES = bitmaps/demo/*.h \ X bitmaps/frame/*.h \ X bitmaps/fruit/*.h \ X bitmaps/maze/*.h \ X bitmaps/pac/*.h X Xxchomp: $(OBJECTS) X $(CC) -o xchomp $(OBJECTS) -lX11 X strip xchomp X Xcontact.o: contact.c xchomp.h X $(CC) -c contact.c X Xdemo.o: demo.c xchomp.h X $(CC) -c demo.c X Xdrivers.o: drivers.c xchomp.h X $(CC) -c drivers.c X Xmain.o: main.c xchomp.h X $(CC) -c main.c X Xmaze.o: maze.c xchomp.h X $(CC) -c maze.c X Xprops.o: props.c xchomp.h X $(CC) -c props.c X Xresources.o: resources.c xchomp.h bitmaps.h X $(CC) -c resources.c X Xstatus.o: status.c xchomp.h X $(CC) -c status.c X Xbitmaps.h: $(BITMAPFILES) X cat $(BITMAPFILES) | sed '/^\#define/d' > bitmaps.h END_OF_FILE if test 1002 -ne `wc -c <'xchomp/Makefile'`; then echo shar: \"'xchomp/Makefile'\" unpacked with wrong size! fi # end of 'xchomp/Makefile' fi if test ! -d 'xchomp/bitmaps' ; then echo shar: Creating directory \"'xchomp/bitmaps'\" mkdir 'xchomp/bitmaps' fi if test ! -d 'xchomp/bitmaps/demo/' ; then echo shar: Creating directory \"'xchomp/bitmaps/demo/'\" mkdir 'xchomp/bitmaps/demo/' fi if test ! -d 'xchomp/bitmaps/frame/' ; then echo shar: Creating directory \"'xchomp/bitmaps/frame/'\" mkdir 'xchomp/bitmaps/frame/' fi if test ! -d 'xchomp/bitmaps/fruit/' ; then echo shar: Creating directory \"'xchomp/bitmaps/fruit/'\" mkdir 'xchomp/bitmaps/fruit/' fi if test -f 'xchomp/bitmaps/fruit/ff1.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xchomp/bitmaps/fruit/ff1.h'\" else echo shar: Extracting \"'xchomp/bitmaps/fruit/ff1.h'\" \(371 characters\) sed "s/^X//" >'xchomp/bitmaps/fruit/ff1.h' <<'END_OF_FILE' X#define ff1_width 20 X#define ff1_height 16 Xstatic char ff1_bits[] = { X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x63, 0x00, X 0xa0, 0x94, 0x00, 0xa0, 0x94, 0x00, 0xa0, 0x94, 0x00, 0xa0, 0x94, 0x00, X 0xa0, 0x94, 0x00, 0xa0, 0x94, 0x00, 0xa0, 0x94, 0x00, 0x20, 0x63, 0x00, X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; END_OF_FILE if test 371 -ne `wc -c <'xchomp/bitmaps/fruit/ff1.h'`; then echo shar: \"'xchomp/bitmaps/fruit/ff1.h'\" unpacked with wrong size! fi # end of 'xchomp/bitmaps/fruit/ff1.h' fi if test ! -d 'xchomp/bitmaps/maze/' ; then echo shar: Creating directory \"'xchomp/bitmaps/maze/'\" mkdir 'xchomp/bitmaps/maze/' fi if test ! -d 'xchomp/bitmaps/pac/' ; then echo shar: Creating directory \"'xchomp/bitmaps/pac/'\" mkdir 'xchomp/bitmaps/pac/' fi if test -f 'xchomp/contact.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xchomp/contact.c'\" else echo shar: Extracting \"'xchomp/contact.c'\" \(5693 characters\) sed "s/^X//" >'xchomp/contact.c' <<'END_OF_FILE' X X#include "xchomp.h" X X/* X * This file contains player-ghost contact handling functions. X * When a collision is detected, execution is vectored to one X * of these functions, depending on the state of the ghost X * with which the player collided. X */ X X X/* X * The following function is called when the player collides with X * a solid ghost; the player dies. This is the death sequence. X * The parameter to this function, as well as all of the collision X * handling function, is the number (array index) of the ghost X * with which the player collided. In this case, it doesn't matter. X */ Xdie(dummy) Xint dummy; X{ X register int xx = x[PAC_SLOT], yy = y[PAC_SLOT], i, dx, dy; X XImage *old, *new; X X /* X * Since the player may be facing one of four directions at X * the time of death, there would be way too many images for X * me to draw in order to handle all possible cases. Therefore, I X * only drew the images for the case in which the player is facing X * left -- they are stored in dead_prot[]. The images for the X * other cases are generated here, dynamically, by using the X * Xlib image facilities. Since we can easily read and place X * single pixels using images, we can rotate all the death frames X * to the desired direction very easily. The final series of X * bitmaps is stored in deadpac[]. X */ X new = XGetImage(display, dead_prot[1], 0, 0, GHOST_SIZE, X GHOST_SIZE, 1, XYPixmap); X for (i = 0; i < 11; i++) { X old = XGetImage(display, dead_prot[i], 0, 0, GHOST_SIZE, X GHOST_SIZE, 1, XYPixmap); X for (dy = 0; dy < GHOST_SIZE; dy++) X for (dx = 0; dx < GHOST_SIZE; dx++) X if (pac == lpac) X XPutPixel(new, dx, dy, XGetPixel(old, dx, dy)); X else if (pac == rpac) X XPutPixel(new, dx, dy, XGetPixel(old, GHOST_SIZE - dx - 1, dy)); X else if (pac == dpac) X XPutPixel(new, dx, dy, XGetPixel(old, GHOST_SIZE - dy - 1, dx)); X else X XPutPixel(new, dx, dy, XGetPixel(old, dy, dx)); X XPutImage(display, deadpac[i], bitmapGC, new, 0, 0, 0, 0, X GHOST_SIZE, GHOST_SIZE); X XDestroyImage(old); X } X XDestroyImage(new); X sleep(1); X X /* deactivate the fruit (if displayed) */ X if (fruit_shown) { X XFillRectangle(display, save, clearGC, fruit_x - 2, fruit_y, X FRUIT_WIDTH, FRUIT_HEIGHT); X dd[fruit_y >> 4][fruit_x >> 4] = '\0'; X ++fruit_times; X fruit_shown = False; X } X X /* X * Now we'll get rid of all of the ghosts on the screen, X * and display the first frame of the death animation at the X * position of the player. X */ X XCopyArea(display, save, map, fullcopyGC, 0, 0, WIN_WIDTH, X WIN_HEIGHT, 0, 0); X XCopyPlane(display, deadpac[0], map, orGC, 0, 0, GHOST_SIZE, X GHOST_SIZE, xx, yy, 1); X XCopyArea(display, map, window, fullcopyGC, 0, 0, WIN_WIDTH, X WIN_HEIGHT, 0, 0); X XSync(display, False); X sleep(1); X X /* X * Now we'll cycle through the death animation frames using X * our normal animation mechanism. X */ X for (i = 0; i < 11; i++) { X XCopyArea(display, save, map, fullcopyGC, xx, yy, GHOST_SIZE, X GHOST_SIZE, xx, yy); X XCopyPlane(display, deadpac[i], map, orGC, 0, 0, GHOST_SIZE, X GHOST_SIZE, xx, yy, 1); X XCopyArea(display, map, window, fullcopyGC, xx, yy, GHOST_SIZE, X GHOST_SIZE, xx, yy); X XSync(display, False); X usleep(125000); X } X usleep(150000); X X /* X * Now we'll remove everything except the maze from the X * screen, and return. X */ X XCopyArea(display, save, map, fullcopyGC, xx, yy, GHOST_SIZE, X GHOST_SIZE, xx, yy); X XCopyArea(display, map, window, fullcopyGC, xx, yy, GHOST_SIZE, X GHOST_SIZE, xx, yy); X XSync(display, False); X dead = True; X} X X X/* X * The following function is executed when the player collides X * with a transparent or flashing ghost; the player eats the X * ghost. The game pauses for a moment, displaying the value X * of the eaten ghost, and then continues. The parameter is X * the array index of the eaten ghost. X */ Xeat(i) Xint i; X{ X register int xx = x[PAC_SLOT], yy = y[PAC_SLOT], j; X static long val[] = { 200, 400, 800, 1600 }; X X /* X * The image we want to create here is the following: all of X * the ghosts except the one being eaten are drawn, as well as X * the score value of the eaten ghost in the position of the X * player. We'll use the normal method: first create the image X * on the map, and then copy the selected areas of the map onto X * the window. The "copyGC" graphics context, at this point, X * should contain the necessary clipping information. X */ X for (j = 0; j < PAC_SLOT; j++) X if (j != i) X XCopyPlane(display, ghost[j][count], map, orGC, 0, 0, X GHOST_SIZE, GHOST_SIZE, x[j], y[j], 1); X XCopyPlane(display, eat_pix[eat_index], map, orGC, 0, 0, X GHOST_SIZE, GHOST_SIZE, xx, yy, 1); X XCopyArea(display, map, window, copyGC, 0, 0, WIN_WIDTH, X WIN_HEIGHT, 0, 0); X X /* adjust the score and wait a second */ X print_score(val[eat_index]); X eat_index = (eat_index + 1) & 0x03; X XSync(display, False); X sleep(1); X X /* remove all moving figures from the map */ X XCopyArea(display, save, map, copyGC, 0, 0, WIN_WIDTH, X WIN_HEIGHT, 0, 0); X X /* X * Now we'll change the ghost state, so that it appears X * as a pair of harmless eyes seeking return to the ghost X * box. X */ X ghost[i] = eghost; X drive[i] = go_home; X contact[i] = noop; X} X X X/* X * The following is the collision handler for ghost-eyes. X * The eyes are harmless; this is a no-op. X */ Xnoop(dummy) Xint dummy; X{ X} X END_OF_FILE if test 5693 -ne `wc -c <'xchomp/contact.c'`; then echo shar: \"'xchomp/contact.c'\" unpacked with wrong size! fi # end of 'xchomp/contact.c' fi if test -f 'xchomp/drivers.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xchomp/drivers.c'\" else echo shar: Extracting \"'xchomp/drivers.c'\" \(20425 characters\) sed "s/^X//" >'xchomp/drivers.c' <<'END_OF_FILE' X X#include "xchomp.h" X X/* X * This file contains functions which control the motion of the player X * and the ghosts. X */ X X X/* X * The following function is called explicitly during each animation X * cycle, to control the motion of the player. It updates the position X * variables (x[], y[]), the direction variables (ix[], iy[]), and the X * array of clipping rectangles (rectangle[]). X */ Xcontrol_pac() X{ X register int xx = x[PAC_SLOT], yy = y[PAC_SLOT], i, dx, dy; X register char *pc = md[yy >> 4] + (xx >> 4); X register int *px = ix + PAC_SLOT, *py = iy + PAC_SLOT; X X /* check for a collision */ X for (i = 0; i < PAC_SLOT; i++) { X dx = x[i] - xx; X dy = y[i] - yy; X if ((abs(dx) < 6) && (abs(dy) < 6)) X (*contact[i])(i); X if (dead) return; X } X X /* X * The rest of this function determines the direction of the X * player according to the surroundings and the last key pressed X * by the user. This took a while to implement correctly, and I X * don't quite recall all of the reasoning that went into the X * implementation of this code. X */ X X if (!(xx & 0x0f) && !(yy & 0x0f)) { X if (*px > 0) { X if (pc[1]) *px = 0; X } X else if (*px < 0) { X if (pc[-1]) *px = 0; X } X else if (*py < 0) { X if (pc[-BLOCK_WIDTH]) *py = 0; X } X else if (pc[BLOCK_WIDTH]) *py = 0; X switch (last_key) { X case XK_Up: X if (!pc[-BLOCK_WIDTH]) *py = (-2), *px = 0, pac = upac; X break; X case XK_Down: X if (!pc[BLOCK_WIDTH]) *py = 2, *px = 0, pac = dpac; X break; X case XK_Left: X if (!pc[-1]) *px = (-2), *py = 0, pac = lpac; X break; X case XK_Right: X if (!pc[1]) *px = 2, *py = 0, pac = rpac; X break; X default: break; X } X check_dots(); X rectangle[PAC_SLOT].x = (x[PAC_SLOT] += *px) - 2; X rectangle[PAC_SLOT].y = (y[PAC_SLOT] += *py) - 2; X return; X } X X if (*px > 0) { X if (last_key == XK_Left) X *px = (-2), pac = lpac; X } X else if (*px < 0) { X if (last_key == XK_Right) X *px = 2, pac = rpac; X } X else if (*py > 0) { X if (last_key == XK_Up) X *py = (-2), pac = upac; X } X else if (last_key == XK_Down) X *py = 2, pac = dpac; X rectangle[PAC_SLOT].x = (x[PAC_SLOT] += *px) - 2; X rectangle[PAC_SLOT].y = (y[PAC_SLOT] += *py) - 2; X} X X X/* X * The following function checks to see whether the player has X * eaten something which is not a ghost -- a dot, a power-dot, X * or the fruit. If so, the appropriate action is taken. X */ Xcheck_dots() X{ X register char *pi; X register int i; X register funcptr driver; X static long fval[] = { 100, 200, 300, 300, 500, 700, 700, X 1000, 1000, 2000, 2000, 3000, 3000, X 5000 }; X X /* X * The following line produces a pointer to the character in the X * dot information array (dd[]) which corresponds to the player's X * position on the screen. X */ X pi = dd[y[PAC_SLOT] >> 4] + (x[PAC_SLOT] >> 4); X X /* check for a regular dot */ X if (*pi == '.') { X *pi = '\0'; X X /* erase the dot from the background image */ X XFillRectangle(display, save, clearGC, x[PAC_SLOT] + 6, X y[PAC_SLOT] + 6, 4, 4); X print_score(10L); X if (--numdots == 0) { X completed = True; X return; X } X } X X /* check for a power-dot */ X else if (*pi == 'O') { X *pi = '\0'; X X /* X * Here we'll erase the power-dot from both the power-dot X * map and the background map, so that it no longer flashes. X */ X XFillRectangle(display, powermap, clearGC, x[PAC_SLOT], X y[PAC_SLOT], GHOST_SIZE, GHOST_SIZE); X XCopyArea(display, powermap, save, fullcopyGC, x[PAC_SLOT], X y[PAC_SLOT], GHOST_SIZE, GHOST_SIZE, x[PAC_SLOT], y[PAC_SLOT]); X print_score(50L); X if (--numdots == 0) { X completed = True; X return; X } X X /* set up ghost-eating mode */ X eat_index = 0; X eat_mode = True; X grey_tick = 0; X count_sync = count; X X /* X * Change the state of each solid ghost to that of a white X * ghost running away from the player at half speed. X */ X for (i = 0; i < PAC_SLOT; i++) { X if ((driver = drive[i]) == follow) { X drive[i] = run; X contact[i] = eat; X ghost[i] = gghost; X ix[i] = -ix[i] / 2; X iy[i] = -iy[i] / 2; X } X else if (driver == hover) { X drive[i] = hover2; X contact[i] = eat; X ghost[i] = gghost; X ix[i] /= 2; X iy[i] /= 2; X } X else if ((driver == hover2) || (driver == run)) X ghost[i] = gghost; X } X } X X /* check for the fruit */ X else if (*pi == 'F') { X *pi = '\0'; X print_score(fval[plevel]); X X /* X * We have to do some fancy stuff here. We want to instantly X * change the fruit on the screen to the image of a score value, X * without stopping the game (as with ghost eating). The problem X * is that this subroutine is called AFTER the background image has X * been restored onto the map in the game loop, and therefore, AFTER X * the clipping information has been set for the pending screen X * update. Therefore, we have to copy this image onto BOTH off- X * screen maps, and we have to reset the clipping information here, X * so that the image is displayed on the screen immediately. This X * would not be a problem if the score value images were the same X * size as the player, as in the case of dots and power-dots. X */ X XCopyPlane(display, fval_pix[plevel], save, fullcopyGC, X 0, 0, FRUIT_WIDTH, FRUIT_HEIGHT, fruit_x - 2, fruit_y, 1); X XCopyArea(display, save, map, fullcopyGC, fruit_x - 2, X fruit_y, FRUIT_WIDTH, FRUIT_HEIGHT, fruit_x - 2, fruit_y); X XSetClipRectangles(display, copyGC, 0, 0, rectangle, X NUM_FIGURES + MAX_POWER_DOTS + 1, Unsorted); X X /* X * Now we'll set the fruit frame counter to 43. The main loop will X * clear the fruit area when it is at 50, so the fruit score value X * will disappear nicely in a few seconds. X */ X fruit_count = 43; X } X} X X X/*-- GHOST DRIVERS -----------------------------------------------------*/ X X X/* X * The rest of this file contains ghost drivers. These routines are invoked X * through pointers, to control the motion of the ghosts. There are several X * of these routines, corresponding to the several different ghost states. X * The parameter to each of these is the ghost number (array index) for which X * to update the direction arrays (ix[], iy[]). X */ X X X/* X * The function below causes ghosts to follow the player around, with a bit X * of randomness thrown in as well. X */ Xfollow(i) Xregister int i; X{ X register char *pc = md[y[i] >> 4] + (x[i] >> 4); X register int dir = 0x0f, sense; X register int *px = ix + i, *py = iy + i; X int xx = x[i], yy = y[i], pmx = x[PAC_SLOT], pmy = y[PAC_SLOT]; X static intm find[3] = { { 0, 1, 2 }, { 3, 3, 4 }, { 5, 6, 7 } }; X X static intm fxvec[16] = { X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* no way to go */ X { 2, 2, 2, 2, 2, 2, 2, 2 }, /* right only */ X { -2, -2, -2, -2, -2, -2, -2, -2 }, /* left only */ X { -2, 2, 2, -2, 2, -2, -2, 2 }, /* left or right */ X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* down only */ X { 2, 2, 2, 0, 2, 0, 0, 2 }, /* down or right */ X { -2, -2, -2, -2, 0, 0, 0, 0 }, /* down or left */ X { -2, -2, 2, -2, 2, -2, 0, 0 }, /* down, left, or right */ X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* up only */ X { 0, 0, 0, 0, 2, 2, 2, 2 }, /* up or right */ X { -2, 0, 0, -2, 0, -2, -2, -2 }, /* up or left */ X { 0, 0, 2, -2, 2, -2, -2, 2 }, /* up, left, or right */ X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* up or down */ X { 0, 0, 2, 0, 2, 0, 0, 2 }, /* up, down, or right */ X { -2, 0, 0, -2, 0, 0, 0, 0 }, /* up, down, or left */ X { -2, 0, 0, -2, 2, 0, 0, 2 } }; /* any which way */ X X static intm fyvec[16] = { X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* no way to go */ X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* right only */ X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* left only */ X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* left or right */ X { 2, 2, 2, 2, 2, 2, 2, 2 }, /* down only */ X { 0, 0, 0, 2, 0, 2, 2, 0 }, /* down or right */ X { 0, 0, 0, 0, 2, 2, 2, 2 }, /* down or left */ X { 0, 0, 0, 0, 0, 0, 2, 2 }, /* down, left, or right */ X { -2, -2, -2, -2, -2, -2, -2, -2 }, /* up only */ X { -2, -2, -2, -2, 0, 0, 0, 0 }, /* up or right */ X { 0, -2, -2, 0, -2, 0, 0, 0 }, /* up or left */ X { -2, -2, 0, 0, 0, 0, 0, 0 }, /* up, left, or right */ X { -2, -2, -2, -2, 2, 2, 2, 2 }, /* up or down */ X { -2, -2, 0, 2, 0, 2, 2, 0 }, /* up, down, or right */ X { 0, -2, -2, 0, -2, 2, 2, 2 }, /* up, down, or left */ X { 0, -2, -2, 0, 0, 2, 2, 0 } }; /* any which way */ X X /* first, find the directions in which this ghost can go */ X if (pc[1] || (*px < 0)) dir &= ~0x01; X if (pc[-1] || (*px > 0)) dir &= ~0x02; X if (pc[BLOCK_WIDTH] || (*py < 0)) dir &= ~0x04; X if (pc[-BLOCK_WIDTH] || (*py > 0)) dir &= ~0x08; X X /* now choose the new direction for the ghost */ X if ((dir != 0x01) && (dir != 0x02) && (dir != 0x04) && (dir != 0x08)) { X if ((random() & 0x0f) > 4) X sense = find[sgn(pmy - yy) + 1][sgn(pmx - xx) + 1]; X else sense = random() & 0x07; X *px = fxvec[dir][sense]; X *py = fyvec[dir][sense]; X } X else { X *px = *fxvec[dir]; X *py = *fyvec[dir]; X } X} X X X/* X * The function below causes ghosts to run away from the player X * at half speed. It is set up as the driver function during X * the ghost-eating periods of the game. X */ Xrun(i) Xregister int i; X{ X register char *pc = md[y[i] >> 4] + (x[i] >> 4); X register int dir = 0x0f, sense; X register int *px = ix + i, *py = iy + i; X int xx = x[i], yy = y[i], pmx = x[PAC_SLOT], pmy = y[PAC_SLOT]; X static intm find[3] = { { 0, 1, 2 }, { 3, 3, 4 }, { 5, 6, 7 } }; X X static intm rxvec[16] = { X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* no way to go */ X { 1, 1, 1, 1, 1, 1, 1, 1 }, /* right only */ X { -1, -1, -1, -1, -1, -1, -1, -1 }, /* left only */ X { 1, -1, -1, 1, -1, 1, 1, -1 }, /* left or right */ X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* down only */ X { 0, 1, 0, 0, 0, 1, 1, 0 }, /* down or right */ X { 0, -1, -1, 0, 0, 0, -1, -1 }, /* down or left */ X { 1, 1, -1, 0, 0, 1, 1, -1 }, /* down, left, or right */ X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* up only */ X { 1, 1, 0, 0, 0, 1, 1, 0 }, /* up or right */ X { 0, -1, -1, 0, 0, 0, -1, -1 }, /* up or left */ X { 1, -1, -1, 0, 0, 0, -1, -1 }, /* up, left, or right */ X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* up or down */ X { 0, 1, 0, 0, 0, 1, 1, 0 }, /* up, down, or right */ X { 0, -1, -1, 0, 0, 0, -1, -1 }, /* up, down, or left */ X { 1, -1, 0, 0, 0, 0, 1, -1 } }; /* any which way */ X X static intm ryvec[16] = { X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* no way to go */ X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* right only */ X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* left only */ X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* left or right */ X { 1, 1, 1, 1, 1, 1, 1, 1 }, /* down only */ X { 1, 0, 1, 1, 1, 0, 0, 1 }, /* down or right */ X { 1, 0, 0, 1, 1, 1, 0, 0 }, /* down or left */ X { 0, 0, 0, 1, 1, 0, 0, 0 }, /* down, left, or right */ X { -1, -1, -1, -1, -1, -1, -1, -1 }, /* up only */ X { 0, 0, -1, -1, -1, 0, 0, -1 }, /* up or right */ X { -1, 0, 0, -1, -1, -1, 0, 0 }, /* up or left */ X { 0, 0, 0, -1, -1, -1, 0, 0 }, /* up, left, or right */ X { 1, 1, 1, 1, -1, -1, -1, -1 }, /* up or down */ X { 1, 0, 1, 1, -1, 0, 0, -1 }, /* up, down, or right */ X { 1, 0, 0, -1, 1, -1, 0, 0 }, /* up, down, or left */ X { 0, 0, 1, 1, -1, -1, 0, 0 } }; /* any which way */ X X /* first, find the directions in which this ghost can go */ X if (pc[1] || (*px < 0)) dir &= ~0x01; X if (pc[-1] || (*px > 0)) dir &= ~0x02; X if (pc[BLOCK_WIDTH] || (*py < 0)) dir &= ~0x04; X if (pc[-BLOCK_WIDTH] || (*py > 0)) dir &= ~0x08; X X /* now choose the new direction for the ghost */ X if ((dir != 0x01) && (dir != 0x02) && (dir != 0x04) && (dir != 0x08)) { X sense = find[sgn(pmy - yy) + 1][sgn(pmx - xx) + 1]; X *px = rxvec[dir][sense]; X *py = ryvec[dir][sense]; X } X else { X *px = *rxvec[dir]; X *py = *ryvec[dir]; X } X} X X X/* X * The function below causes ghosts to return to the ghost box at X * high speed. It is set up as the driver for ghosts which have X * been eaten. X */ Xgo_home(i) Xregister int i; X{ X register char *pc = md[y[i] >> 4] + (x[i] >> 4); X register int dir = 0x0f, sense; X register int *px = ix + i, *py = iy + i; X int xx = x[i], yy = y[i], pmx = door_x << 4, pmy = (door_y - 1) << 4; X static intm find[3] = { { 0, 1, 2 }, { 3, 3, 4 }, { 5, 6, 7 } }; X X static intm pxvec[16] = { X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* no way to go */ X { 4, 4, 4, 4, 4, 4, 4, 4 }, /* right only */ X { -4, -4, -4, -4, -4, -4, -4, -4 }, /* left only */ X { -4, 4, 4, -4, 4, -4, -4, 4 }, /* left or right */ X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* down only */ X { 4, 4, 4, 0, 4, 0, 0, 4 }, /* down or right */ X { -4, -4, -4, -4, 0, 0, 0, 0 }, /* down or left */ X { -4, -4, 4, -4, 4, -4, 0, 0 }, /* down, left, or right */ X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* up only */ X { 0, 0, 0, 0, 4, 4, 4, 4 }, /* up or right */ X { -4, 0, 0, -4, 0, -4, -4, -4 }, /* up or left */ X { 0, 0, 4, -4, 4, -4, -4, 4 }, /* up, left, or right */ X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* up or down */ X { 0, 0, 4, 0, 4, 0, 0, 4 }, /* up, down, or right */ X { -4, 0, 0, -4, 0, 0, 0, 0 }, /* up, down, or left */ X { -4, 0, 0, -4, 4, 0, 0, 4 } }; /* any which way */ X X static intm pyvec[16] = { X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* no way to go */ X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* right only */ X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* left only */ X { 0, 0, 0, 0, 0, 0, 0, 0 }, /* left or right */ X { 4, 4, 4, 4, 4, 4, 4, 4 }, /* down only */ X { 0, 0, 0, 4, 0, 4, 4, 0 }, /* down or right */ X { 0, 0, 0, 0, 4, 4, 4, 4 }, /* down or left */ X { 0, 0, 0, 0, 0, 0, 4, 4 }, /* down, left, or right */ X { -4, -4, -4, -4, -4, -4, -4, -4 }, /* up only */ X { -4, -4, -4, -4, 0, 0, 0, 0 }, /* up or right */ X { 0, -4, -4, 0, -4, 0, 0, 0 }, /* up or left */ X { -4, -4, 0, 0, 0, 0, 0, 0 }, /* up, left, or right */ X { -4, -4, -4, -4, 4, 4, 4, 4 }, /* up or down */ X { -4, -4, 0, 4, 0, 4, 4, 0 }, /* up, down, or right */ X { 0, -4, -4, 0, -4, 4, 4, 4 }, /* up, down, or left */ X { 0, -4, -4, 0, 0, 4, 4, 0 } }; /* any which way */ X X if (xx == pmx) { X if (yy == pmy) { X X /* X * The ghost is right above the door to the ghost box. X * We'll send it down into the box. We're assuming X * here that the ghost box is shaped a certain way. X * If not, the results will be unpredictable. X */ X *px = 0; X *py = 4; X return; X } X else if (yy == (pmy + 48)) { X X /* X * The ghost is all the way inside the box. Here it'll X * be "reborn" -- its state will be changed to that of a X * solid ghost hovering inside the ghost box. X */ X drive[i] = hover; X loops[i] = 0; X ghost[i] = bghost; X contact[i] = die; X *px = 2; X *py = 0; X return; X } X } X else { X X /* otherwise, find the directions in which this ghost can go */ X if (pc[1] || (*px < 0)) dir &= ~0x01; X if (pc[-1] || (*px > 0)) dir &= ~0x02; X if (pc[BLOCK_WIDTH] || (*py < 0)) dir &= ~0x04; X if (pc[-BLOCK_WIDTH] || (*py > 0)) dir &= ~0x08; X X /* now choose the new direction for the ghost */ X if ((dir != 0x01) && (dir != 0x02) && (dir != 0x04) && (dir != 0x08)) { X sense = find[sgn(pmy - yy) + 1][sgn(pmx - xx) + 1]; X *px = pxvec[dir][sense]; X *py = pyvec[dir][sense]; X } X else { X *px = *pxvec[dir]; X *py = *pyvec[dir]; X } X } X} X X X/* X * The function below drives the solid ghosts inside the ghost box. X * They simply hover around in a circular pattern. Randomness is X * used to decide when the ghosts leave the box. X */ Xhover(i) Xregister int i; X{ X register int yy = y[i] >> 4, xx = x[i] >> 4; X char *pc = md[yy] + xx; X register int *px = ix + i, *py = iy + i; X X if (xx == door_x) X if (yy == (door_y - 1)) { X X /* X * The ghost is now completely outside the box; we will X * change its driver so that it follows the player around X */ X drive[i] = follow; X follow(i); X return; X } X else if (yy == (door_y + 1)) X X /* X * The ghost is directly underneath the door to the X * outside. We'll use the number of loops it has made X * inside the box, as well as a bit of randomness, X * to determine whether or not to send it out. X */ X if ((++loops[i]) > 1) X if ((random() & 0x0f) > 7) { X *px = 0, *py = (-2); X return; X } X X /* X * The rest of the function drives the ghost around the X * box in a circular counterclockwise pattern. X */ X if (*px > 0) { X if (pc[1]) *px = 0, *py = (-2); X } X else if (*px < 0) { X if (pc[-1]) *px = 0, *py = 2; X } X else if (*py > 0) { X if (pc[BLOCK_WIDTH]) *px = 2, *py = 0; X } X else if (pc[-BLOCK_WIDTH]) *px = (-2), *py = 0; X} X X X/* X * The function below is just like hover() above, except that X * it handles the motion of ghosts inside the box during X * the ghost-eating periods of the game -- they move at half X * speed. X */ Xhover2(i) Xregister int i; X{ X register int yy = y[i] >> 4, xx = x[i] >> 4; X char *pc = md[yy] + xx; X register int *px = ix + i, *py = iy + i; X X if (xx == door_x) X if (yy == (door_y - 1)) { X drive[i] = run; X run(i); X return; X } X else if (yy == (door_y + 1)) X if ((++loops[i]) > 1) { X *px = 0, *py = (-1); X return; X } X X if (*px > 0) { X if (pc[1]) *px = 0, *py = (-1); X } X else if (*px < 0) { X if (pc[-1]) *px = 0, *py = 1; X } X else if (*py > 0) { X if (pc[BLOCK_WIDTH]) *px = 1, *py = 0; X } X else if (pc[-BLOCK_WIDTH]) *px = (-1), *py = 0; X} END_OF_FILE if test 20425 -ne `wc -c <'xchomp/drivers.c'`; then echo shar: \"'xchomp/drivers.c'\" unpacked with wrong size! fi # end of 'xchomp/drivers.c' fi if test -f 'xchomp/main.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xchomp/main.c'\" else echo shar: Extracting \"'xchomp/main.c'\" \(8900 characters\) sed "s/^X//" >'xchomp/main.c' <<'END_OF_FILE' X X#define EXTERN X#include "xchomp.h" X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X XEvent event; X int dummy; X XCharStruct chars; X unsigned long event_mask; X X /* open the display */ X display = XOpenDisplay(NULL); X screen = DefaultScreen(display); X root = DefaultRootWindow(display); X depth = DefaultDepth(display, screen); X black = BlackPixel(display, screen); X white = WhitePixel(display, screen); X X /* get a font */ X font = XLoadFont(display, "fixed"); X XQueryTextExtents(display, font, "000000", 6, &dummy, X &ascent, &descent, &chars); X X /* X * We want to suspend the game in case the window is iconified. X * This is more difficult than it sounds. On the Sun, iconification X * seems to produce an UnmapNotify event -- very nice. DECwindows, X * however, informs the application by generating a PropertyNotify X * event on a DEC-specific property -- very nasty. The atom is X * not defined in any of the DECwindows headers, so we will try X * to get its value from the server, and use it later. We are X * hoping here that all non-DECwindows servers will return None X * for this atom. X */ X DEC_icon_atom = XInternAtom(display, "DEC_WM_ICON_STATE", True); X X /* assemble resources */ X create_ghost(); X create_pac(); X create_fruit(); X create_maze_symbols(); X create_demo_images(); X create_window(argc, argv); X create_GCs(); X create_maps(); X X /* select the event mask for the window */ X event_mask = ExposureMask | KeyPressMask; X if (DEC_icon_atom == None) X event_mask |= StructureNotifyMask; X else event_mask |= PropertyChangeMask; X XSelectInput(display, window, event_mask); X X /* display the window */ X XMapWindow(display, window); X while (True) { X XNextEvent(display, &event); X if (event.xany.window != window) continue; X if (event.type == Expose) break; X } X X /*-- The Game Starts Here -----------------------------------------*/ X { X register int i, num_clips; X char c_buf; X XComposeStatus status; X X static int flash_ticks[] = { X 13, 8, 4, 1, 13, 8, 4, 1, X 8, 4, 1, 4, 1, 8, 4, 1, X 0, 0, 8, 4, 0, 0, 1, 0 }; X static int off_ticks[] = { X 19, 14, 10, 7, 19, 14, 10, 7, X 14, 10, 7, 10, 7, 14, 10, 7, X 1, 1, 14, 10, 1, 1, 7, 1 }; X static int screens[] = { X 1, 1, 1, 1, 2, 2, 2, 2, X 3, 3, 3, 4, 4, 5, 5, 5, X 1, 2, 6, 6, 3, 4, 6, 5 }; X X high_score = 0L; X X demo: X X /* run the demo screen */ X demo_seq(); X X /* initialize the game */ X lives = 3; X level = (-1); X score = 0L; X print_score(0L); X X new_screen: X X /* advance the level */ X plevel = (++level > 13) ? 13 : level; X flash_tick = flash_ticks[level % 24]; X off_tick = off_ticks[level % 24]; X display_level(True); X X /* initialize dynamic parameters */ X completed = False; X fruit_times = 0; X X /* build the maze */ X clear_maps(); X read_maze(screens[level % 24] - 1); X X new_life: X X /* initialize more dynamic parameters */ X last_key = XK_Left; X dead = False; X eat_mode = False; X count = (-1); X fruit_count = (-1); X fruit_shown = False; X position_players(); X X /* display the number of lives */ X (void)set_lives(lives); X X /* copy the maze to the map and the screen */ X XCopyArea(display, save, map, fullcopyGC, 0, 0, X WIN_WIDTH, WIN_HEIGHT, 0, 0); X XCopyArea(display, map, window, fullcopyGC, 0, 0, X WIN_WIDTH, WIN_HEIGHT, 0, 0); X X /* display the ready message */ X get_ready(); X X X /*-- The Animation Loop ----------------------------------------*/ X X while (True) { X X /*-- Xlib Event Section -------------------------------------*/ X X while (QLength(display) > 0) { X XNextEvent(display, &event); X if (event.xany.window != window) continue; X switch (event.type) { X case KeyPress: X XLookupString(&event, &c_buf, 1, &last_key, &status); X if (last_key == XK_space) X if (!pause_seq()) X goto demo; X break; X case UnmapNotify: X while (True) { X XNextEvent(display, &event); X if (event.xany.window != window) continue; X if (event.type == MapNotify) break; X } X XCopyArea(display, map, window, fullcopyGC, 0, 0, X WIN_WIDTH, WIN_HEIGHT, 0, 0); X restore_status(); X if (!pause_seq()) X goto demo; X break; X case PropertyNotify: X if (event.xproperty.atom != DEC_icon_atom) break; X while (True) { X XNextEvent(display, &event); X if (event.xany.window != window) continue; X if (event.type != PropertyNotify) continue; X if (event.xproperty.atom == DEC_icon_atom) break; X } X XCopyArea(display, map, window, fullcopyGC, 0, 0, X WIN_WIDTH, WIN_HEIGHT, 0, 0); X restore_status(); X if (!pause_seq()) X goto demo; X break; X case Expose: X XCopyArea(display, map, window, fullcopyGC, 0, 0, X WIN_WIDTH, WIN_HEIGHT, 0, 0); X restore_status(); X break; X default: break; X } X } X X /*-- Adjust Frame Counter -----------------------------------*/ X X count = (count + 1) & 0x0f; X X /*-- Flashing Power-Dot And Fruit Section -------------------*/ X X num_clips = NUM_FIGURES; X X if (count == 0) { X X /* it's time to flash the power-dots */ X XCopyArea(display, powermap, save, powerGC, 0, 0, X WIN_WIDTH, WIN_HEIGHT, 0, 0); X num_clips = NUM_FIGURES + MAX_POWER_DOTS; X X /* see if it's time to display or erase the fruit */ X if (fruit_times < 2) { X if (++fruit_count == 30) { X XCopyPlane(display, fruit_pix[plevel], save, fullcopyGC, X 0, 0, GHOST_SIZE, GHOST_SIZE, fruit_x, fruit_y, 1); X num_clips = NUM_FIGURES + MAX_POWER_DOTS + 1; X dd[fruit_y >> 4][fruit_x >> 4] = 'F'; X fruit_shown = True; X } X else if (fruit_count == 50) { X XFillRectangle(display, save, clearGC, fruit_x - 2, X fruit_y, FRUIT_WIDTH, FRUIT_HEIGHT); X dd[fruit_y >> 4][fruit_x >> 4] = '\0'; X fruit_count = 0; X ++fruit_times; X num_clips = NUM_FIGURES + MAX_POWER_DOTS + 1; X fruit_shown = False; X } X } X } X X /*-- Set Clipping Information -------------------------------*/ X X XSetClipRectangles(display, copyGC, 0, 0, rectangle, X num_clips, Unsorted); X X /*-- Restore Background Image -------------------------------*/ X X XCopyArea(display, save, map, copyGC, 0, 0, WIN_WIDTH, X WIN_HEIGHT, 0, 0); X X /*-- Motion Control Section ---------------------------------*/ X X control_pac(); X if (dead || completed) break; X for (i = 0; i < PAC_SLOT; i++) X if (!(x[i] & 0x0f) && !(y[i] & 0x0f)) X (*drive[i])(i); X for (i = 0; i < PAC_SLOT; i++) { X rectangle[i].x = (x[i] += ix[i]) - 2; X rectangle[i].y = (y[i] += iy[i]) - 2; X } X X /*-- Flashing Ghost Section ---------------------------------*/ X X /* X * If we're in the middle of a ghost-eating period, this section X * handles the timing and changes ghost states when necessary X */ X if (eat_mode) X if (count == count_sync) { X ++grey_tick; X if (grey_tick == flash_tick) { X for (i = 0; i < PAC_SLOT; i++) X if (ghost[i] == gghost) X ghost[i] = fghost; X } X else if (grey_tick == off_tick) { X eat_mode = False; X for (i = 0; i < PAC_SLOT; i++) X if (drive[i] == run) { X ghost[i] = bghost; X contact[i] = die; X drive[i] = follow; X x[i] &= ~0x1; y[i] &= ~0x01; X ix[i] *= 2; iy[i] *= 2; X } X else if (drive[i] == hover2) { X ghost[i] = bghost; X contact[i] = die; X drive[i] = hover; X x[i] &= ~0x1; y[i] &= ~0x01; X ix[i] *= 2; iy[i] *= 2; X } X } X } X X /*-- Offscreen Figure Overlay -------------------------------*/ X X for (i = 0; i < PAC_SLOT; i++) X XCopyPlane(display, ghost[i][count], map, orGC, 0, 0, X GHOST_SIZE, GHOST_SIZE, x[i], y[i], 1); X XCopyPlane(display, pac[count], map, orGC, 0, 0, X GHOST_SIZE, GHOST_SIZE, x[PAC_SLOT], y[PAC_SLOT], 1); X X /*-- Screen Update ------------------------------------------*/ X X XCopyArea(display, map, window, copyGC, 0, 0, WIN_WIDTH, X WIN_HEIGHT, 0, 0); X X /*-- Synchronization And Delay ------------------------------*/ X X XSync(display, False); X X#ifdef FRAME_DELAY X usleep(FRAME_DELAY); X#endif X X } /* while */ X X /*-- End of Animation Loop -------------------------------------*/ X X if (dead) { X if (set_lives(lives - 1)) { X sleep(2); X goto new_life; X } X game_over(); X goto demo; X } X X if (completed) { X finish(); X goto new_screen; X } X } X /*-- The Game Ends Here -------------------------------------------*/ X X do_exit(); X} X X Xdo_exit() X{ X XUnmapWindow(display, window); X XUnloadFont(display, font); X XFlush(display); X XCloseDisplay(display); X exit(1); X} END_OF_FILE if test 8900 -ne `wc -c <'xchomp/main.c'`; then echo shar: \"'xchomp/main.c'\" unpacked with wrong size! fi # end of 'xchomp/main.c' fi if test -f 'xchomp/resources.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xchomp/resources.c'\" else echo shar: Extracting \"'xchomp/resources.c'\" \(12858 characters\) sed "s/^X//" >'xchomp/resources.c' <<'END_OF_FILE' X X#include "xchomp.h" X#include "bitmaps.h" X X X/* X * This file contains all of the functions which build the image and X * window/pixmap resources for the game, as well as the graphics X * contexts. X */ X Xcreate_window(argc, argv) Xint argc; Xchar *argv[]; X{ X XSizeHints hints; X char *name = "xchomp"; X X window = XCreateSimpleWindow(display, root, 0, 0, WIN_WIDTH, X WIN_HEIGHT + GHOST_SIZE + 2, 1, black, white); X X icon = XCreatePixmapFromBitmapData(display, root, icon_bits, X ICON_WIDTH, ICON_HEIGHT, 1, 0, 1); X X hints.flags = PSize | PMinSize | PMaxSize; X hints.width = hints.min_width = hints.max_width = WIN_WIDTH; X hints.height = hints.min_height = hints.max_height = WIN_HEIGHT + GHOST_SIZE + 2; X X XSetStandardProperties(display, window, name, name, icon, X argv, argc, &hints); X} X X Xcreate_pac() X{ X int i; X X lpac[3] = XCreatePixmapFromBitmapData(display, root, pacl1_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X lpac[2] = XCreatePixmapFromBitmapData(display, root, pacl2_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X lpac[1] = XCreatePixmapFromBitmapData(display, root, pacl3_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X lpac[0] = XCreatePixmapFromBitmapData(display, root, pacl4_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X lpac[4] = lpac[3]; X lpac[5] = lpac[2]; X lpac[6] = lpac[1]; X lpac[7] = lpac[0]; X for (i = 8; i < 16; i++) X lpac[i] = lpac[i - 8]; X X rpac[3] = XCreatePixmapFromBitmapData(display, root, pacr1_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X rpac[2] = XCreatePixmapFromBitmapData(display, root, pacr2_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X rpac[1] = XCreatePixmapFromBitmapData(display, root, pacr3_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X rpac[0] = lpac[0]; X rpac[4] = rpac[3]; X rpac[5] = rpac[2]; X rpac[6] = rpac[1]; X rpac[7] = rpac[0]; X for (i = 8; i < 16; i++) X rpac[i] = rpac[i - 8]; X X upac[3] = XCreatePixmapFromBitmapData(display, root, pacu1_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X upac[2] = XCreatePixmapFromBitmapData(display, root, pacu2_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X upac[1] = XCreatePixmapFromBitmapData(display, root, pacu3_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X upac[0] = lpac[0]; X upac[4] = upac[3]; X upac[5] = upac[2]; X upac[6] = upac[1]; X upac[7] = upac[0]; X for (i = 8; i < 16; i++) X upac[i] = upac[i - 8]; X X dpac[3] = XCreatePixmapFromBitmapData(display, root, pacd1_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X dpac[2] = XCreatePixmapFromBitmapData(display, root, pacd2_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X dpac[1] = XCreatePixmapFromBitmapData(display, root, pacd3_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X dpac[0] = lpac[0]; X dpac[4] = dpac[3]; X dpac[5] = dpac[2]; X dpac[6] = dpac[1]; X dpac[7] = dpac[0]; X for (i = 8; i < 16; i++) X dpac[i] = dpac[i - 8]; X X dead_prot[0] = lpac[0]; X dead_prot[1] = lpac[1]; X dead_prot[2] = lpac[2]; X dead_prot[3] = lpac[3]; X dead_prot[4] = XCreatePixmapFromBitmapData(display, root, pdie4_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X dead_prot[5] = XCreatePixmapFromBitmapData(display, root, pdie5_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X dead_prot[6] = XCreatePixmapFromBitmapData(display, root, pdie6_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X dead_prot[7] = XCreatePixmapFromBitmapData(display, root, pdie7_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X dead_prot[8] = XCreatePixmapFromBitmapData(display, root, pdie8_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X dead_prot[9] = XCreatePixmapFromBitmapData(display, root, pdie9_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X dead_prot[10] = XCreatePixmapFromBitmapData(display, root, pdie10_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X X for (i = 0; i < 11; i++) X deadpac[i] = XCreatePixmap(display, root, GHOST_SIZE, GHOST_SIZE, 1); X X small_pac = XCreatePixmapFromBitmapData(display, root, pacsmall_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X} X X Xcreate_ghost() X{ X int i; X X bghost[0] = XCreatePixmapFromBitmapData(display, root, frame1_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X bghost[2] = XCreatePixmapFromBitmapData(display, root, frame2_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X bghost[6] = XCreatePixmapFromBitmapData(display, root, frame3_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X bghost[1] = bghost[4] = bghost[5] = bghost[0]; X bghost[3] = bghost[2]; X bghost[7] = bghost[6]; X for (i = 8; i < 16; i++) X bghost[i] = bghost[i - 8]; X X gghost[0] = XCreatePixmapFromBitmapData(display, root, grey1_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X gghost[2] = XCreatePixmapFromBitmapData(display, root, grey2_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X gghost[6] = XCreatePixmapFromBitmapData(display, root, grey3_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X gghost[1] = gghost[4] = gghost[5] = gghost[0]; X gghost[3] = gghost[2]; X gghost[7] = gghost[6]; X for (i = 8; i < 16; i++) X gghost[i] = gghost[i - 8]; X X for (i = 0; i < 8; i++) fghost[i] = gghost[i]; X for (i = 8; i < 16; i++) fghost[i] = bghost[i]; X X eghost[0] = XCreatePixmapFromBitmapData(display, root, eye_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X for (i = 1; i < 16; i++) eghost[i] = eghost[0]; X} X X Xcreate_maze_symbols() X{ X int i; X Pixmap empty; X static char index[] = { '1', '2', '3', '4', '5', '6', '7', '8', X 'a', 'b', 'c', 'd', 'v', 'e', 'g', '-', X 'j', '[', 'm', 'n', 'o', 'q', ']', 's', X 't', 'u', '^', '|', 'w', 'x', 'y', 'z', X '.', 'O' }; X static char *data[] = { m1_bits, m2_bits, m3_bits, m4_bits, m5_bits, X m6_bits, m7_bits, m8_bits, ma_bits, mb_bits, X mc_bits, md_bits, mdown_bits, me_bits, mg_bits, X mhorz_bits, mj_bits, mleft_bits, mm_bits, mn_bits, X mo_bits, mq_bits, mright_bits, ms_bits, mt_bits, X mu_bits, mup_bits, mvert_bits, mw_bits, mx_bits, X my_bits, mz_bits, mdot_bits, mpower_bits }; X X empty = XCreatePixmapFromBitmapData(display, root, mempty_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X for (i = 0; i < 128; maze[i++] = empty); X X for (i = 0; i < sizeof(index); i++) X maze[index[i]] = XCreatePixmapFromBitmapData(display, root, X data[i], GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X} X X Xcreate_maps() X{ X map = XCreatePixmap(display, root, WIN_WIDTH, WIN_HEIGHT, depth); X save = XCreatePixmap(display, root, WIN_WIDTH, WIN_HEIGHT, depth); X powermap = XCreatePixmap(display, root, WIN_WIDTH, WIN_HEIGHT, depth); X} X X X Xcreate_fruit() X{ X fruit_pix[0] = XCreatePixmapFromBitmapData(display, root, fcherry_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X fruit_pix[1] = XCreatePixmapFromBitmapData(display, root, fstraw_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X fruit_pix[2] = XCreatePixmapFromBitmapData(display, root, fwater_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X fruit_pix[3] = fruit_pix[2]; X fruit_pix[4] = XCreatePixmapFromBitmapData(display, root, fapple_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X fruit_pix[5] = XCreatePixmapFromBitmapData(display, root, fgrape_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X fruit_pix[6] = fruit_pix[5]; X fruit_pix[7] = XCreatePixmapFromBitmapData(display, root, fbell_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X fruit_pix[8] = fruit_pix[7]; X fruit_pix[9] = XCreatePixmapFromBitmapData(display, root, fclock_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X fruit_pix[10] = fruit_pix[9]; X fruit_pix[11] = XCreatePixmapFromBitmapData(display, root, fxlogo_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X fruit_pix[12] = fruit_pix[11]; X fruit_pix[13] = XCreatePixmapFromBitmapData(display, root, fkey_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X X fval_pix[0] = XCreatePixmapFromBitmapData(display, root, ff1_bits, X FRUIT_WIDTH, FRUIT_HEIGHT, 1, 0, 1); X fval_pix[1] = XCreatePixmapFromBitmapData(display, root, ff2_bits, X FRUIT_WIDTH, FRUIT_HEIGHT, 1, 0, 1); X fval_pix[2] = XCreatePixmapFromBitmapData(display, root, ff3_bits, X FRUIT_WIDTH, FRUIT_HEIGHT, 1, 0, 1); X fval_pix[3] = fval_pix[2]; X fval_pix[4] = XCreatePixmapFromBitmapData(display, root, ff4_bits, X FRUIT_WIDTH, FRUIT_HEIGHT, 1, 0, 1); X fval_pix[5] = XCreatePixmapFromBitmapData(display, root, ff5_bits, X FRUIT_WIDTH, FRUIT_HEIGHT, 1, 0, 1); X fval_pix[6] = fval_pix[5]; X fval_pix[7] = XCreatePixmapFromBitmapData(display, root, ff6_bits, X FRUIT_WIDTH, FRUIT_HEIGHT, 1, 0, 1); X fval_pix[8] = fval_pix[7]; X fval_pix[9] = XCreatePixmapFromBitmapData(display, root, ff7_bits, X FRUIT_WIDTH, FRUIT_HEIGHT, 1, 0, 1); X fval_pix[10] = fval_pix[9]; X fval_pix[11] = XCreatePixmapFromBitmapData(display, root, ff8_bits, X FRUIT_WIDTH, FRUIT_HEIGHT, 1, 0, 1); X fval_pix[12] = fval_pix[11]; X fval_pix[13] = XCreatePixmapFromBitmapData(display, root, ff9_bits, X FRUIT_WIDTH, FRUIT_HEIGHT, 1, 0, 1); X X eat_pix[0] = XCreatePixmapFromBitmapData(display, root, fg1_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X eat_pix[1] = XCreatePixmapFromBitmapData(display, root, fg2_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X eat_pix[2] = XCreatePixmapFromBitmapData(display, root, fg3_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X eat_pix[3] = XCreatePixmapFromBitmapData(display, root, fg4_bits, X GHOST_SIZE, GHOST_SIZE, 1, 0, 1); X} X X Xcreate_GCs() X{ X XGCValues gcv; X unsigned long mask; X X mask = GCForeground | GCBackground | GCFunction | X GCFont | GCGraphicsExposures; X X /* resolve colors */ X if ((black | white) == black) X normal = True; X else if ((black | white) == white) X normal = False; X else { X black &= white; X normal = False; X } X X /* context for copying; used for animation */ X gcv.foreground = black; X gcv.background = white; X gcv.function = GXcopy; X gcv.font = font; X gcv.graphics_exposures = False; X copyGC = XCreateGC(display, root, mask, &gcv); X X /* context for copying; used for full size areas */ X gcv.foreground = black; X gcv.background = white; X gcv.function = GXcopy; X gcv.font = font; X gcv.graphics_exposures = False; X fullcopyGC = XCreateGC(display, root, mask, &gcv); X X /* context for overlaying; used for animation */ X gcv.foreground = black; X gcv.background = white; X gcv.function = normal ? GXor : GXand; X gcv.font = font; X gcv.graphics_exposures = False; X orGC = XCreateGC(display, root, mask, &gcv); X X /* context for clearing */ X gcv.foreground = white; X gcv.background = black; X gcv.function = GXcopy; X gcv.font = font; X gcv.graphics_exposures = False; X clearGC = XCreateGC(display, root, mask, &gcv); X X /* context for inverting */ X gcv.foreground = white; X gcv.background = black; X gcv.function = GXinvert; X gcv.font = font; X gcv.graphics_exposures = False; X gcv.plane_mask = black ^ white; X invertGC = XCreateGC(display, root, mask | GCPlaneMask, &gcv); X X /* context for flashing the power dots */ X gcv.foreground = black; X gcv.background = white; X gcv.function = normal ? GXxor : GXequiv; X gcv.plane_mask = black ^ white; X gcv.font = font; X gcv.graphics_exposures = False; X powerGC = XCreateGC(display, root, mask | GCPlaneMask, &gcv); X X /* context of depth 1; used for transferring onto bitmaps */ X gcv.foreground = 1; X gcv.background = 0; X gcv.function = GXcopy; X gcv.font = font; X gcv.graphics_exposures = False; X bitmapGC = XCreateGC(display, bghost[0], mask, &gcv); X} X X Xcreate_demo_images() X{ X demo_map[0] = XCreatePixmapFromBitmapData(display, root, bigc_bits, X 48, 48, 1, 0, 1); X demo_map[1] = XCreatePixmapFromBitmapData(display, root, bigh_bits, X 48, 48, 1, 0, 1); X demo_map[2] = XCreatePixmapFromBitmapData(display, root, bigo_bits, X 48, 48, 1, 0, 1); X demo_map[3] = XCreatePixmapFromBitmapData(display, root, bigm_bits, X 48, 48, 1, 0, 1); X demo_map[4] = XCreatePixmapFromBitmapData(display, root, bigp_bits, X 48, 48, 1, 0, 1); X} X X Xclear_maps() X{ X XFillRectangle(display, powermap, clearGC, 0, 0, WIN_WIDTH, WIN_HEIGHT); X XFillRectangle(display, save, clearGC, 0, 0, WIN_WIDTH, WIN_HEIGHT); X XFillRectangle(display, map, clearGC, 0, 0, WIN_WIDTH, WIN_HEIGHT); X} END_OF_FILE if test 12858 -ne `wc -c <'xchomp/resources.c'`; then echo shar: \"'xchomp/resources.c'\" unpacked with wrong size! fi # end of 'xchomp/resources.c' fi echo shar: End of archive 1 \(of 3\). cp /dev/null ark1isdone MISSING="" for I in 1 2 3 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 3 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0