home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume5 / golddig2 / part04 < prev    next >
Encoding:
Internet Message Format  |  1989-12-13  |  19.8 KB

  1. Path: uunet!ssbell!kent@ssbell.uu.net
  2. From: kent@ssbell.uu.net (Kent Landfield)
  3. Newsgroups: comp.sources.x
  4. Subject: v05i048: golddig2 -- A game for X11, Part04/04
  5. Message-ID: <597@ssbell.uu.net>
  6. Date: 14 Dec 89 03:18:58 GMT
  7. Sender: kent@ssbell.uu.net
  8. Lines: 592
  9. Approved: kent@ssbell.uu.net (Kent Landfield)
  10.  
  11. Submitted-by: Alexander Siegel <siegel@cs.cornell.edu>
  12. Posting-number: Volume 5, Issue 48
  13. Archive-name: golddig2/part04
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 4 (of 4)."
  22. # Contents:  golddig2/golddig.c
  23. # Wrapped by kent@ssbell on Wed Dec 13 20:37:02 1989
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f 'golddig2/golddig.c' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'golddig2/golddig.c'\"
  27. else
  28. echo shar: Extracting \"'golddig2/golddig.c'\" \(17923 characters\)
  29. sed "s/^X//" >'golddig2/golddig.c' <<'END_OF_FILE'
  30. X/* This program was written by Alexander Siegel in September of 1989   */
  31. X/* at Cornell University.  It may may copied freely for private use or */
  32. X/* public dispersion provided that this comment is not removed.  This  */
  33. X/* program, any portion of this program, or any derivative of this     */
  34. X/* program may not be sold or traded for financial gain.               */
  35. X
  36. X/* Modified by Josh Siegel to work with NeWS/X11 */
  37. X
  38. X#include <stdio.h>
  39. X#include <X11/Xlib.h>
  40. X#include <X11/keysym.h>
  41. X#include <X11/Xutil.h>
  42. X#include <sys/time.h>
  43. X#include <signal.h>
  44. X#include "golddig.h"
  45. X
  46. Xextern char player_bits[];
  47. X#include "bitmap/fly.bits"
  48. X#include "bitmap/hang1.bits"
  49. X#include "bitmap/hang2.bits"
  50. X#include "bitmap/up1.bits"
  51. X#include "bitmap/up2.bits"
  52. X#include "bitmap/left1.bits"
  53. X#include "bitmap/left2.bits"
  54. X#include "bitmap/right1.bits"
  55. X#include "bitmap/right2.bits"
  56. X
  57. Xlong random();
  58. X
  59. X#define EVMASK KeyPressMask | ExposureMask | ButtonPressMask | FocusChangeMask
  60. X
  61. Xint newlevel = 0;       /* Non-zero if a new level was just drawn */
  62. Xstruct itimerval cycletime; /* Structure used when setting up timer */
  63. X/* These are the graphics cursors used for drawing the player at */
  64. X/* various times. */
  65. XGC standgc,flygc,hang1gc,hang2gc,up1gc,up2gc;
  66. XGC left1gc,left2gc,right1gc,right2gc;
  67. X
  68. Xenum directs curorder = STAND;  /* Current order which player has */
  69. X                                /* typed at the keyboard. */
  70. X
  71. X/* Plug into original block type definitions in shared.c */
  72. Xextern struct symbs_s symbs[];
  73. Xextern int numholes;        /* Total number of holes */
  74. X
  75. X/* This routine is called whenever the player dies. */
  76. Xvoid died(whydie)
  77. Xchar *whydie;       /* Textual description of reason for death */
  78. X{
  79. X  /* Prevent timer from firing inside of sleep */
  80. X  cycletime.it_value.tv_sec = cycletime.it_interval.tv_sec = 10;
  81. X  setitimer(ITIMER_REAL,&cycletime,(struct itimerval *) NULL);
  82. X  signal(SIGALRM,SIG_DFL);      /* Turn off timer signal */
  83. X  XSync(disp,False);            /* Synchronize with display */
  84. X  if(strcmp(whydie,"was abandoned"))
  85. X    sleep(2);                   /* Pause for 2 seconds to let player */
  86. X                                /* see situation */
  87. X  xend();                       /* Terminate X windows */
  88. X  /* Add score to high score list */
  89. X  add_score(whydie);
  90. X  exit(0);
  91. X}
  92. X
  93. X/* Redraw the player.  The graphics cursors all use the GXor function */
  94. X/* so they will not erase what is underneath. */
  95. Xvoid draw_player()
  96. X{
  97. X  GC drawgc;
  98. X  register int lpos,code;
  99. X
  100. X  /* Get position of level array of player */
  101. X  lpos = (player.xpos >> 1)*ysize + (player.ypos >> 1);
  102. X  /* Get the control code describing block underneath player */
  103. X  code = fast_lookup[level[lpos]].code;
  104. X  /* If the block is inactive, use the code for empty space */
  105. X  if((code & INACTIVE) && goldleft > 0)
  106. X    code = fast_lookup[SPACE].code;
  107. X
  108. X  /* Compute the graphics cursor appropriate to the player's current */
  109. X  /* state */
  110. X  drawgc = NULL;
  111. X  /* Check if player is hanging from a rope */
  112. X  if((player.ypos & 1) == 0) {
  113. X    if((code & DLEAVE) && ! (code & (ULEAVE | DFALL))) {
  114. X      if(player.xpos & 1)
  115. X        drawgc = hang2gc;
  116. X      else
  117. X        drawgc = hang1gc;
  118. X    }
  119. X  }
  120. X  else if((player.ypos & 1) && (code & DFALL))
  121. X    drawgc = flygc;
  122. X
  123. X  if(drawgc == NULL)
  124. X    switch(player.dir) {
  125. X    case UP:    case DOWN:
  126. X      if(player.ypos & 1)
  127. X        drawgc = up2gc;
  128. X      else
  129. X        drawgc = up1gc;
  130. X      break;
  131. X    case LEFT:
  132. X      if(player.xpos & 1)
  133. X        drawgc = left2gc;
  134. X      else
  135. X        drawgc = left1gc;
  136. X      break;
  137. X    case RIGHT:
  138. X      if(player.xpos & 1)
  139. X        drawgc = right2gc;
  140. X      else
  141. X        drawgc = right1gc;
  142. X      break;
  143. X    case STAND:
  144. X      if(code & ULEAVE)
  145. X        drawgc = up1gc;
  146. X      else
  147. X        drawgc = standgc;
  148. X      break;
  149. X    default:
  150. X      drawgc = standgc;
  151. X    }
  152. X  /* Fill the rectangle surrounding the player with the chosen */
  153. X  /* graphics cursor. */
  154. X  if(drawgc != NULL)
  155. X    XFillRectangle(disp,wind,drawgc,player.xpos << 3,player.ypos << 3,16,16);
  156. X}
  157. X
  158. X/* Erase the player by redrawing the block(s) underneath him */
  159. Xvoid drawmove_player()
  160. X{
  161. X  register int x,y; 
  162. X
  163. X  /* Do not erase redraw player if it is not nessary */
  164. X  if(! player.redraw)
  165. X    return;
  166. X  /* Draw block covering at least half of player */
  167. X  x = player.xold;
  168. X  y = player.yold;
  169. X  draw_block(x >> 1,y >> 1);
  170. X  /* If player is offset horizontally, redraw block to the right */
  171. X  if(x & 1)
  172. X    draw_block((x >> 1) + 1,y >> 1);
  173. X  /* If player is offset vertically, redraw block below */
  174. X  if(y & 1)
  175. X    draw_block(x >> 1,(y >> 1) + 1);
  176. X
  177. X  draw_player();
  178. X}
  179. X
  180. X/* Handle a key stroke by the user. */
  181. Xvoid handle_key(keyhit)
  182. XKeySym keyhit;     /* Key symbol for key stroke provided by X windows */
  183. X{
  184. X  /* Now that a key is hit, really begin the level */
  185. X  newlevel = 0;
  186. X  /* Do action depending on which key was hit */
  187. X  switch(keyhit) {
  188. X  /* If it is a 'h', '?', or '/', print out a list of commands */
  189. X  case XK_H:    case XK_h:    case XK_question:   case XK_slash:
  190. X    puts("Control the player using keyboard keys or the mouse.");
  191. X    puts("<space>,R11 - stop");
  192. X    puts("a,j,left arrow - move left");
  193. X    puts("d,l,right arrow - move right");
  194. X    puts("w,i,up arrow - move up");
  195. X    puts("s,k,down arrow - move down");
  196. X    puts("z,<,q,u,R13 - make hole left");
  197. X    puts("x,>,e,o,R15 - make hole right");
  198. X    puts("r,y,R7 - put down any held item");
  199. X    puts("1-9 - change the game speed");
  200. X    puts("\n^S,^Z - pause the game");
  201. X    puts("^Q,^Y - reactivate the game");
  202. X    puts("^C - kill the game");
  203. X    puts("^R - redraw the screen");
  204. X    break;
  205. X  /* A space bar changes the command to STAND */
  206. X  case XK_space:    case XK_R11:
  207. X    curorder = STAND; break;
  208. X  /* A 'z', ',', '<', 'q', or 'u' digs holes to the left */
  209. X  case XK_Z:    case XK_comma:  case XK_less:   case XK_Q: case XK_U:
  210. X  case XK_R13:  case XK_z:      case XK_q:      case XK_u:
  211. X    curorder = DIGLEFT; break;
  212. X  /* A 'x', '.', '>', 'e', or 'o' digs holes to the right */
  213. X  case XK_X:    case XK_period: case XK_greater: case XK_E: case XK_O:
  214. X  case XK_R15:  case XK_x:      case XK_e: case XK_o:
  215. X    curorder = DIGRIGHT; break;
  216. X  /* A 'j' or 'a' changes the command to LEFT */
  217. X  case XK_J:    case XK_A:  case XK_Left:   case XK_j:  case XK_a:
  218. X    curorder = LEFT; break;
  219. X  /* A 'i' or 'w' changes the command to UP */
  220. X  case XK_I:    case XK_W:  case XK_Up:     case XK_i:  case XK_w:
  221. X    curorder = UP; break;
  222. X  /* A 'k' or 's' changes the command to DOWN */
  223. X  case XK_K:    case XK_S:  case XK_Down:   case XK_k:  case XK_s:
  224. X    curorder = DOWN; break;
  225. X  /* A 'l' or 'd' changes the command to RIGHT */
  226. X  case XK_L:    case XK_D:  case XK_Right:  case XK_l:  case XK_d:
  227. X    curorder = RIGHT; break;
  228. X  /* A 'r' or 'y' drops whatever is being held */
  229. X  case XK_R:    case XK_Y:  case XK_R7:     case XK_r:  case XK_y:
  230. X    curorder = PUTDOWN; break;
  231. X  }
  232. X}
  233. X
  234. X/* Redraw everything.  This routine is called whenever something major */
  235. X/* changes or the window is exposed. */
  236. Xvoid redrawall()
  237. X{
  238. X  draw_level();
  239. X  draw_player();
  240. X  draw_badguys();
  241. X  XFlush(disp);
  242. X}
  243. X
  244. X/* Initialize a level from the current level file */
  245. Xvoid init_level()
  246. X{
  247. X  register int x,y,pos;
  248. X  
  249. X  /* Allow level sizes to be changes by new level */
  250. X  xsize = ysize = -1;
  251. X  /* Load the level data itself from the data file. */
  252. X  load_level();
  253. X  numholes = 0;
  254. X
  255. X  /* Initialize player information */
  256. X  player.xpos = player.ypos = player.xstart = player.ystart = goldleft = 0;
  257. X  player.dir = STAND;
  258. X  player.hold = SPACE;
  259. X  curorder = STAND;
  260. X  pos = 0;
  261. X  for(x=0;x<xsize;++x)
  262. X    for(y=0;y<ysize;++y) {
  263. X      /* Count the total number of treasures */
  264. X      if(fast_lookup[level[pos]].code & TREASURE)
  265. X        goldleft ++;
  266. X      /* Look for player blocks and remove them.  The last one */
  267. X      /* encountered sets the player position. */
  268. X      if(level[pos] == PLAYER) {
  269. X        player.xpos = player.xstart = x << 1;
  270. X        player.ypos = player.ystart = y << 1;
  271. X        level[pos] = SPACE;
  272. X      }
  273. X      pos ++;
  274. X    }
  275. X  printf("Collect %d gold dubloons.\n",goldleft);
  276. X
  277. X  /* Initialize bad guy information and other things. */
  278. X  start_badguy();
  279. X  regen_allow();
  280. X  regen_tree();
  281. X  /* Freeze action until a key is pressed */
  282. X  newlevel = 1;
  283. X}
  284. X
  285. X/* Move player one movement */
  286. Xvoid move_player()
  287. X{
  288. X  register int i,code;
  289. X
  290. X  /* Attempt to move player according to his standing orders */
  291. X  code = movething(&player,curorder,-1);
  292. X  /* If digging completed, or if the player fell, and he was trying to move */
  293. X  /* in the same direction, change the current order to STAND */
  294. X  if(code == 4 || (code == 2 && curorder == player.dir))
  295. X    curorder = STAND;
  296. X  /* Redraw player if he dropped something (which will overwrite the */
  297. X  /* block) */
  298. X  if(code == 3)
  299. X    player.redraw = 1;
  300. X  /* If player is in the middle of a block, interesting things can */
  301. X  /* happen. */
  302. X  if((player.xpos & 1) == 0 && (player.ypos & 1) == 0)  {
  303. X    /* If the player has picked up a gold piece, consume it and */
  304. X    /* increment the score. */
  305. X    if(fast_lookup[player.hold].code & TREASURE) {
  306. X      player.hold = SPACE;
  307. X      score++;
  308. X      goldleft--;
  309. X      /* If that was the last gold piece, escape ladder and other */
  310. X      /* stuff may need to appear. */
  311. X      if(goldleft == 0) {
  312. X        regen_allow();      /* Regenerate the allowable movement array */
  313. X        redrawall();        /* Refresh the entire screen */
  314. X      }
  315. X      /* Redraw the score line */
  316. X      else
  317. X        draw_score();
  318. X    }
  319. X    /* Get the control code for the block direction underneath the */
  320. X    /* player */
  321. X    i = (player.xpos >> 1)*ysize + (player.ypos >> 1);
  322. X    code = fast_lookup[level[i]].code;
  323. X    /* If the control code shows an active UPLEVEL block, or the */
  324. X    /* player is at the top of the screen, and there is no more gold */
  325. X    /* left, goto the next level. */
  326. X    if((goldleft == 0 && 
  327. X    (player.ypos == 0 || (code & UPLEVEL))) ||
  328. X       ((code & UPLEVEL) && ! (code & INACTIVE)))  {
  329. X      /* Increment the level number */
  330. X      levelnum ++;
  331. X      /* Load the next level in if the current one is done */
  332. X      init_level();
  333. X      /* Redraw the level */
  334. X      redrawall();
  335. X      /* Flush all the many X windows operations out to the server.  This */
  336. X      /* is the only flush in all the operations in this procedure. */
  337. X      XFlush(disp);
  338. X      return;
  339. X    }
  340. X    /* If the block is a killer block, kill the player */
  341. X    if(code & KILLIN)
  342. X      died("was crushed");
  343. X  }
  344. X  /* Do not let PUTDOWN order stay after movement has started */
  345. X  else if(curorder == PUTDOWN)
  346. X    curorder = STAND;
  347. X}
  348. X
  349. X/* Move everything one movement (or less).  This is the basic function */
  350. X/* which is called on every timer signal. */
  351. Xvoid moveall()
  352. X{
  353. X  /* Remember old position of player */
  354. X  player.xold = player.xpos;
  355. X  player.yold = player.ypos;
  356. X  /* Assume that the player does not need to be redrawn initially */
  357. X  player.redraw = 0;
  358. X  /* Do player movement */
  359. X  move_player();
  360. X  /* If the level has changed, do not move other stuff */
  361. X  if(newlevel)
  362. X    return;
  363. X  /* Do secondary movement if player is sped up */
  364. X  if(fast_lookup[player.hold].code & SPEED)
  365. X    move_player();
  366. X  /* If the level has changed, do not move other stuff */
  367. X  if(newlevel)
  368. X    return;
  369. X  /* Prevent time from advancing for bad guys if a TIMESTOP item is */
  370. X  /* held by player */
  371. X  if(! (fast_lookup[player.hold].code & TIMESTOP)) {
  372. X    /* Regenerate bad guys movement tree periodically */
  373. X    if((curtick & 0xf) == 0)
  374. X      regen_tree();
  375. X    /* Only move bad guys every other tick */
  376. X    if(curtick & 1)
  377. X      move_badguys();
  378. X  }
  379. X  /* Check if the player is overlapping one of the bad guys while not */
  380. X  /* holding armor. */
  381. X  if(! (fast_lookup[player.hold].code & ARMOR) &&
  382. X     overlap_badguy(player.xpos,player.ypos,-1))
  383. X    died("was eaten");
  384. X  /* Redraw player if he moved.  Redraw occasionally anyway. */
  385. X  if(player.xpos != player.xold || player.ypos != player.yold ||
  386. X     (curtick & 0xf) == 0)
  387. X    player.redraw = 1;
  388. X  /* Erase and draw player if necessary */
  389. X  drawmove_player();
  390. X  /* Flush all the many X windows operations out to the server.  This */
  391. X  /* is the only flush in all the operations in this procedure. */
  392. X  XFlush(disp);
  393. X}
  394. X
  395. X/* Function which is called whenever the timer signal goes off */
  396. Xvoid ticker(sig)
  397. Xint sig;
  398. X{
  399. X  /* Ignore any signal which is not an alarm.  Ignore alarm signals */
  400. X  /* after a new level has been drawn until a key is hit. */
  401. X  if(sig != SIGALRM || newlevel)
  402. X    return;
  403. X  
  404. X  /* increment the tick counter if time is advancing */
  405. X  if(! (fast_lookup[player.hold].code & TIMESTOP))
  406. X    curtick ++;
  407. X
  408. X  /* age all the holes */
  409. X  change_holes();
  410. X
  411. X  /* move the player and all the bad guys. */
  412. X  moveall();
  413. X}
  414. X
  415. X/* main procedure for game */
  416. Xvoid main(argc,argv)
  417. Xint argc;
  418. Xchar **argv;
  419. X{
  420. X  int keycount,i,gamestop = 0,gcfunc,firstevent;
  421. X  static XEvent xev;
  422. X  KeySym keyhit;
  423. X  char buf[50];
  424. X
  425. X  printf("type h for help.\n");
  426. X
  427. X  /* set up level and world description defaults */
  428. X  worldname = DEFWORLD;
  429. X  levelnum = 1;
  430. X  score = 0;
  431. X  speed = 5;
  432. X  /* scan the command line for executing parameters and flags */
  433. X  for(i=1;i<argc;++i) {
  434. X    if(argv[i][0] == '-') {
  435. X      /* look for the level number */
  436. X      if(argv[i][1] == 'l') {
  437. X        if(argv[i][2] == '\0' && i+1 < argc) {
  438. X          sscanf(argv[i+1],"%d",&levelnum);
  439. X          i++;
  440. X        }
  441. X        else
  442. X          sscanf(argv[i]+2,"%d",&levelnum);
  443. X      }
  444. X      /* look for the level number */
  445. X      else if(argv[i][1] == 's') {
  446. X        if(argv[i][2] == '\0' && i+1 < argc) {
  447. X          sscanf(argv[i+1],"%d",&speed);
  448. X          i++;
  449. X        }
  450. X        else
  451. X          sscanf(argv[i]+2,"%d",&speed);
  452. X      }
  453. X      else {
  454. X        printf("usage: golddig [-l <level>] [-s <speed 1-9>] [<world name>]\n");
  455. X        exit(1);
  456. X      }
  457. X    }
  458. X    /* if it doesn't start with a -, it must be the name of the world */
  459. X    else {
  460. X      worldname = argv[i];
  461. X      break;
  462. X    }
  463. X  }
  464. X  /* remember what the starting level was */
  465. X  levelstart = levelnum;
  466. X
  467. X  /* start up x windows and all graphics cursors for drawing level */
  468. X  xstart(EVMASK);
  469. X  /* reassemble the graphics cursors to prepare for actual play */
  470. X  for(i=0;symbs[i].symb != '\0';++i)
  471. X    fast_lookup[symbs[i].symb].gc  =
  472. X      fast_lookup[symbs[i].inplay].gc;
  473. X
  474. X  /* Decide whether to use GXand or GXor depending on screen type */
  475. X  if((BlackPixel(disp,0) & WhitePixel(disp,0)) == BlackPixel(disp,0))
  476. X    gcfunc = GXand;
  477. X  else
  478. X    gcfunc = GXor;
  479. X  /* compute all the graphics cursors for drawing the player in his */
  480. X  /* various states. */
  481. X  standgc = makegc(gcfunc,player_bits);
  482. X  flygc = makegc(gcfunc,fly_bits);
  483. X  hang1gc = makegc(gcfunc,hang1_bits);
  484. X  hang2gc = makegc(gcfunc,hang2_bits);
  485. X  up1gc = makegc(gcfunc,up1_bits);
  486. X  up2gc = makegc(gcfunc,up2_bits);
  487. X  left1gc = makegc(gcfunc,left1_bits);
  488. X  left2gc = makegc(gcfunc,left2_bits);
  489. X  right1gc = makegc(gcfunc,right1_bits);
  490. X  right2gc = makegc(gcfunc,right2_bits);
  491. X  /* initialize the bad guy's graphics cursors */
  492. X  init_badguy();
  493. X  /* name the game window */
  494. X  XStoreName(disp,wind,"gold digger 2.0");
  495. X  /* do the rest of the level initialization */
  496. X  init_level();
  497. X  /* initialize timer structure according to speed */
  498. X  if(speed <= 0)
  499. X    speed = 1;
  500. X  if(speed <= 5)
  501. X    cycletime.it_interval.tv_usec = (5-speed) * 50000 + 125000;
  502. X  else
  503. X    cycletime.it_interval.tv_usec = 625000 / speed;
  504. X  cycletime.it_interval.tv_sec = 0;
  505. X  cycletime.it_value = cycletime.it_interval;
  506. X  /* start the system timer.  the timer signal catcher will be set */
  507. X  /* after the first x event is received. */
  508. X  signal(SIGALRM,SIG_IGN);
  509. X  setitimer(ITIMER_REAL,&cycletime,(struct itimerval *) NULL);
  510. X
  511. X  /* main event loop */
  512. X  firstevent = 1;
  513. X  while(1) {
  514. X    /* get the next x window event */
  515. X    XWindowEvent(disp,wind,EVMASK,&xev);
  516. X    /* suppress the timer to prevent race conditions */
  517. X    signal(SIGALRM,SIG_IGN);
  518. X    /* If the window is exposed or the level is complete redraw the */
  519. X    /* entire level.  Also redraw everything if it is the first window */
  520. X    /* event to handle window managers which capture expose events in */
  521. X    /* an unfriendly way. */
  522. X    if((xev.type == Expose && xev.xexpose.count == 0) || firstevent) {
  523. X      /* Redraw the level */
  524. X      redrawall();
  525. X      /* Events after this are not the first event */
  526. X      firstevent = 0;
  527. X    }
  528. X    else if(xev.type == KeyPress) {
  529. X      keycount = XLookupString(&xev,buf,50,&keyhit,(XComposeStatus *) NULL);
  530. X      /* Check for special control command */
  531. X      if(xev.xkey.state & ControlMask)
  532. X        switch(keyhit)  {
  533. X        /* ^S and ^Z freeze the game in place */
  534. X        case XK_S: case XK_Z: case XK_s: case XK_z:
  535. X          gamestop = 1;
  536. X          break;
  537. X        /* ^Q and ^Y reactivate the game */
  538. X        case XK_Q: case XK_Y: case XK_q: case XK_y:
  539. X          gamestop = 0;
  540. X          break;
  541. X        /* ^C, ^U, and ^/ kill the game */
  542. X        case XK_C: case XK_U: case XK_c: case XK_u: case XK_backslash:
  543. X          goto game_over;
  544. X        /* ^R redraws the level */
  545. X        case XK_R: case XK_r:
  546. X          redrawall();
  547. X          break;
  548. X        }
  549. X      /* Pressing a number changes the game speed */
  550. X      else if(keyhit >= XK_1 && keyhit <= XK_9) {
  551. X        speed = (int) (keyhit - XK_0);
  552. X        /* Compute new cycle delay */
  553. X        if(speed <= 5)
  554. X          cycletime.it_interval.tv_usec = (5-speed) * 50000 + 125000;
  555. X        else
  556. X          cycletime.it_interval.tv_usec = 625000 / speed;
  557. X        cycletime.it_value = cycletime.it_interval;
  558. X        /* Reset the timer cycle time */
  559. X        setitimer(ITIMER_REAL,&cycletime,(struct itimerval *) NULL);
  560. X        /* Redraw score line with new speed */
  561. X        draw_score();
  562. X      }
  563. X      /* If it was a normal key stroke, hand it off to the handle_key */
  564. X      /* procedure */
  565. X      else
  566. X        handle_key(keyhit);
  567. X    }
  568. X    /* flush out pending x windows commands */
  569. X    XFlush(disp);
  570. X    /* reenable the alarm signal if game should be active */
  571. X    if(! gamestop)
  572. X      signal(SIGALRM,ticker);
  573. X  }
  574. X
  575. X  /* go to died procedure */
  576. X game_over:
  577. X  died("was abandoned");
  578. X}
  579. END_OF_FILE
  580. if test 17923 -ne `wc -c <'golddig2/golddig.c'`; then
  581.     echo shar: \"'golddig2/golddig.c'\" unpacked with wrong size!
  582. fi
  583. # end of 'golddig2/golddig.c'
  584. fi
  585. echo shar: End of archive 4 \(of 4\).
  586. cp /dev/null ark4isdone
  587. MISSING=""
  588. for I in 1 2 3 4 ; do
  589.     if test ! -f ark${I}isdone ; then
  590.     MISSING="${MISSING} ${I}"
  591.     fi
  592. done
  593. if test "${MISSING}" = "" ; then
  594.     echo You have unpacked all 4 archives.
  595.     rm -f ark[1-9]isdone
  596. else
  597.     echo You still need to unpack the following archives:
  598.     echo "        " ${MISSING}
  599. fi
  600. ##  End of shell archive.
  601. exit 0
  602.