home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume18 / xboing / part09 < prev    next >
Encoding:
Internet Message Format  |  1993-09-13  |  59.1 KB

  1. Path: uunet!news.tek.com!news.cna.tek.com!not-for-mail
  2. From: billr@saab.cna.tek.com (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v18i068:  xboing - blockout variant with color and sound for X, Part09/30
  5. Date: 30 Aug 1993 10:27:38 -0700
  6. Organization: Tektronix, Inc., Redmond, OR
  7. Lines: 1979
  8. Approved: billr@saab.CNA.TEK.COM
  9. Message-ID: <25tdaa$hun@saab.cna.tek.com>
  10. NNTP-Posting-Host: saab.cna.tek.com
  11. Xref: uunet comp.sources.games:1868
  12.  
  13. Submitted-by: jck@kimba.catt.citri.edu.au (Justin Kibell)
  14. Posting-number: Volume 18, Issue 68
  15. Archive-name: xboing/part09
  16. Environment: X11, Xlib, XPM
  17.  
  18.  
  19.  
  20. #! /bin/sh
  21. # This is a shell archive.  Remove anything before this line, then unpack
  22. # it by saving it into a file and typing "sh file".  To overwrite existing
  23. # files, type "sh file -c".  You can also feed this as standard input via
  24. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  25. # will see the following message at the end:
  26. #        "End of archive 9 (of 30)."
  27. # Contents:  ball.c bitmaps/exblueblock1.xpm.uu sounds/whoosh.au.uu
  28. # Wrapped by billr@saab on Mon Aug 30 09:14:24 1993
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'ball.c' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'ball.c'\"
  32. else
  33. echo shar: Extracting \"'ball.c'\" \(43559 characters\)
  34. sed "s/^X//" >'ball.c' <<'END_OF_FILE'
  35. X#include "include/copyright.h"
  36. X
  37. X/*
  38. X *  Include file dependencies:
  39. X */
  40. X
  41. X#include <stdio.h>
  42. X#include <stdlib.h>
  43. X#include <math.h>
  44. X#include <xpm.h>
  45. X
  46. X#include "bitmaps/ball1.xpm"
  47. X#include "bitmaps/ball2.xpm"
  48. X#include "bitmaps/ball3.xpm"
  49. X#include "bitmaps/ball4.xpm"
  50. X#include "bitmaps/killer.xpm"
  51. X
  52. X#include "bitmaps/ballbirth1.xpm"
  53. X#include "bitmaps/ballbirth2.xpm"
  54. X#include "bitmaps/ballbirth3.xpm"
  55. X#include "bitmaps/ballbirth4.xpm"
  56. X#include "bitmaps/ballbirth5.xpm"
  57. X#include "bitmaps/ballbirth6.xpm"
  58. X#include "bitmaps/ballbirth7.xpm"
  59. X#include "bitmaps/ballbirth8.xpm"
  60. X
  61. X#include "include/audio.h"
  62. X#include "include/error.h"
  63. X#include "include/score.h"
  64. X#include "include/sfx.h"
  65. X#include "include/init.h"
  66. X#include "include/main.h"
  67. X#include "include/stage.h"
  68. X#include "include/blocks.h"
  69. X#include "include/paddle.h"
  70. X#include "include/misc.h"
  71. X#include "include/level.h"
  72. X#include "include/mess.h"
  73. X#include "include/special.h"
  74. X
  75. X#include "include/ball.h"
  76. X
  77. X/*
  78. X *  Internal macro definitions:
  79. X */
  80. X
  81. X#define X2COL(col, x) (col = x / colWidth)
  82. X#define Y2ROW(row, y) (row = y / rowHeight)
  83. X
  84. X#define COL2X(x, col) (x = col * colWidth)
  85. X#define ROW2Y(y, row) (y = row * rowHeight)
  86. X
  87. X/*
  88. X *  Internal type declarations:
  89. X */
  90. X
  91. X#if NeedFunctionPrototypes
  92. Xstatic void MoveBall(Display *display, Window window, int x, int y, int replace,
  93. X    int i);
  94. Xstatic void MoveBallBirth(Display *display, Window window, int x, int y, 
  95. X    int slide, int replace, int i);
  96. Xstatic void DoBoardTilt(Display *display, int i);
  97. Xstatic void TeleportBall(Display *display, Window window, int i);
  98. Xstatic int BallHitPaddle(Display *display, Window window, int *hit, int i,
  99. X    int *x, int *y);
  100. Xstatic void UpdateABall(Display *display, Window window, int i);
  101. Xstatic int CheckRegions(Display *display, Window window, int row, int col,
  102. X    int x, int y, int i);
  103. Xstatic int CheckForCollision(Display *display, Window window, int x, int y, 
  104. X    int *r, int *c, int i);
  105. Xstatic void updateBallVariables(int i);
  106. Xstatic void SetBallWait(int newMode, int waitFrame, int i);
  107. Xstatic void DoBallWait(int i);
  108. Xstatic void EraseTheBall(Display *display, Window window, int x, int y);
  109. X#else
  110. Xstatic void MoveBall();
  111. Xstatic void MoveBallBirth();
  112. Xstatic void DoBoardTilt();
  113. Xstatic void TeleportBall();
  114. Xstatic int BallHitPaddle();
  115. Xstatic void UpdateABall();
  116. Xstatic int CheckRegions();
  117. Xstatic int CheckForCollision();
  118. Xstatic void updateBallVariables();
  119. Xstatic void SetBallWait();
  120. Xstatic void DoBallWait();
  121. Xstatic void EraseTheBall();
  122. X#endif
  123. X
  124. X/*
  125. X *  Internal variable declarations:
  126. X */
  127. X
  128. Xstatic Pixmap ballsPixmap[BALL_SLIDES];
  129. Xstatic Pixmap ballsMask[BALL_SLIDES];
  130. Xstatic Pixmap ballBirthPixmap[BIRTH_SLIDES];
  131. Xstatic Pixmap ballBirthMask[BIRTH_SLIDES];
  132. XBALL balls[MAX_BALLS];
  133. X
  134. X#if NeedFunctionPrototypes
  135. Xvoid InitialiseBall(Display *display, Window window, Colormap colormap)
  136. X#else
  137. Xvoid InitialiseBall(display, window, colormap)
  138. X    Display     *display;
  139. X    Window         window;
  140. X    Colormap     colormap;
  141. X#endif
  142. X{
  143. X    XpmAttributes   attributes;
  144. X    int                XpmErrorStatus;
  145. X
  146. X    attributes.valuemask = XpmColormap;
  147. X    attributes.colormap = colormap;
  148. X
  149. X    /* Create the xpm pixmap ball frames */
  150. X    XpmErrorStatus = XpmCreatePixmapFromData(display, window, ball1_xpm,
  151. X        &ballsPixmap[0], &ballsMask[0], &attributes);
  152. X    HandleXPMError(display, XpmErrorStatus, "InitialiseBall()");
  153. X
  154. X    XpmErrorStatus = XpmCreatePixmapFromData(display, window, ball2_xpm,
  155. X        &ballsPixmap[1], &ballsMask[1], &attributes);
  156. X    HandleXPMError(display, XpmErrorStatus, "InitialiseBall()");
  157. X
  158. X    XpmErrorStatus = XpmCreatePixmapFromData(display, window, ball3_xpm,
  159. X        &ballsPixmap[2], &ballsMask[2], &attributes);
  160. X    HandleXPMError(display, XpmErrorStatus, "InitialiseBall()");
  161. X
  162. X    XpmErrorStatus = XpmCreatePixmapFromData(display, window, ball4_xpm,
  163. X        &ballsPixmap[3], &ballsMask[3], &attributes);
  164. X    HandleXPMError(display, XpmErrorStatus, "InitialiseBall()");
  165. X
  166. X    XpmErrorStatus = XpmCreatePixmapFromData(display, window, killer_xpm,
  167. X        &ballsPixmap[4], &ballsMask[4], &attributes);
  168. X    HandleXPMError(display, XpmErrorStatus, "InitialiseBall()");
  169. X
  170. X    /* Ball birth sequence */
  171. X
  172. X    /* Create the xpm pixmap ball birth frames */
  173. X    XpmErrorStatus = XpmCreatePixmapFromData(display, window, ballbirth1_xpm,
  174. X        &ballBirthPixmap[0], &ballBirthMask[0], &attributes);
  175. X    HandleXPMError(display, XpmErrorStatus, "InitialiseBall()");
  176. X
  177. X    XpmErrorStatus = XpmCreatePixmapFromData(display, window, ballbirth2_xpm,
  178. X        &ballBirthPixmap[1], &ballBirthMask[1], &attributes);
  179. X    HandleXPMError(display, XpmErrorStatus, "InitialiseBall()");
  180. X
  181. X    XpmErrorStatus = XpmCreatePixmapFromData(display, window, ballbirth3_xpm,
  182. X        &ballBirthPixmap[2], &ballBirthMask[2], &attributes);
  183. X    HandleXPMError(display, XpmErrorStatus, "InitialiseBall()");
  184. X
  185. X    XpmErrorStatus = XpmCreatePixmapFromData(display, window, ballbirth4_xpm,
  186. X        &ballBirthPixmap[3], &ballBirthMask[3], &attributes);
  187. X    HandleXPMError(display, XpmErrorStatus, "InitialiseBall()");
  188. X
  189. X    XpmErrorStatus = XpmCreatePixmapFromData(display, window, ballbirth5_xpm,
  190. X        &ballBirthPixmap[4], &ballBirthMask[4], &attributes);
  191. X    HandleXPMError(display, XpmErrorStatus, "InitialiseBall()");
  192. X
  193. X    XpmErrorStatus = XpmCreatePixmapFromData(display, window, ballbirth6_xpm,
  194. X        &ballBirthPixmap[5], &ballBirthMask[5], &attributes);
  195. X    HandleXPMError(display, XpmErrorStatus, "InitialiseBall()");
  196. X
  197. X    XpmErrorStatus = XpmCreatePixmapFromData(display, window, ballbirth7_xpm,
  198. X        &ballBirthPixmap[6], &ballBirthMask[6], &attributes);
  199. X    HandleXPMError(display, XpmErrorStatus, "InitialiseBall()");
  200. X
  201. X    XpmErrorStatus = XpmCreatePixmapFromData(display, window, ballbirth8_xpm,
  202. X        &ballBirthPixmap[7], &ballBirthMask[7], &attributes);
  203. X    HandleXPMError(display, XpmErrorStatus, "InitialiseBall()");
  204. X
  205. X    /* Free the xpm pixmap attributes */
  206. X    XpmFreeAttributes(&attributes);
  207. X
  208. X    /* Make sure that all the balls are initialised */
  209. X    ClearAllBalls();
  210. X}
  211. X
  212. X#if NeedFunctionPrototypes
  213. Xvoid FreeBall(Display *display)
  214. X#else
  215. Xvoid FreeBall(display)
  216. X    Display *display;
  217. X#endif
  218. X{
  219. X    int i;
  220. X
  221. X    /* Free all animation frames for the ball */
  222. X    for (i = 0; i < BALL_SLIDES; i++)
  223. X    {
  224. X        if (ballsPixmap[i])     XFreePixmap(display, ballsPixmap[i]);
  225. X         if (ballsMask[i])         XFreePixmap(display, ballsMask[i]);
  226. X    }
  227. X
  228. X    /* Free all animation frames for the ball birth */
  229. X    for (i = 0; i < BIRTH_SLIDES; i++)
  230. X    {
  231. X        /* Free the ball birth animation pixmaps */
  232. X        if (ballBirthPixmap[i])     XFreePixmap(display, ballBirthPixmap[i]);
  233. X         if (ballBirthMask[i])         XFreePixmap(display, ballBirthMask[i]);
  234. X    }
  235. X}
  236. X
  237. X#if NeedFunctionPrototypes
  238. Xvoid RedrawBall(Display *display, Window window)
  239. X#else
  240. Xvoid RedrawBall(display, window)
  241. X    Display *display; 
  242. X    Window window;
  243. X#endif
  244. X{
  245. X    /* STILL TO BE IMPLEMENTED */
  246. X}
  247. X
  248. X#if NeedFunctionPrototypes
  249. Xstatic void EraseTheBall(Display *display, Window window, int x, int y)
  250. X#else
  251. Xstatic void EraseTheBall(display, window, x, y)
  252. X    Display *display;
  253. X    Window window;
  254. X    int x;
  255. X    int y;
  256. X#endif
  257. X{
  258. X    /* Clear the ball area! The x, y coordinates are the centre of ball */
  259. X    XClearArea(display, window, x - BALL_WC, y - BALL_HC, 
  260. X        BALL_WIDTH, BALL_HEIGHT, False);
  261. X}
  262. X
  263. X#if NeedFunctionPrototypes
  264. Xvoid DrawTheBall(Display *display, Window window, int x, int y, int slide)
  265. X#else
  266. Xvoid DrawTheBall(display, window, x, y, slide)
  267. X    Display *display;
  268. X    Window window;
  269. X    int x;
  270. X    int y; 
  271. X    int slide;
  272. X#endif
  273. X{
  274. X    /* Draw the ball using the slide variable as the index into the frames
  275. X     * of the ball animation. The x,y are the centre of the ball.
  276. X     */
  277. X    RenderShape(display, window, ballsPixmap[slide], ballsMask[slide],
  278. X        x - BALL_WC, y - BALL_HC, BALL_WIDTH, BALL_HEIGHT, False);
  279. X}
  280. X
  281. X#if NeedFunctionPrototypes
  282. Xvoid DrawTheBallBirth(Display *display, Window window, int x, int y, int slide)
  283. X#else
  284. Xvoid DrawTheBallBirth(display, window, x, y, slide)
  285. X    Display *display;
  286. X    Window window;
  287. X    int x;
  288. X    int y;
  289. X    int slide;
  290. X#endif
  291. X{
  292. X    /* Draw the ball using the slide variable as the index into the frames
  293. X     * of the ball animation. The x,y are the centre of the ball birth anim.
  294. X     */
  295. X    RenderShape(display, window, ballBirthPixmap[slide], ballBirthMask[slide],
  296. X        x - BALL_WC, y - BALL_HC, BALL_WIDTH, BALL_HEIGHT, False);
  297. X}
  298. X
  299. X#if NeedFunctionPrototypes
  300. Xstatic void MoveBallBirth(Display *display, Window window, int x, int y, 
  301. X    int slide, int replace, int i)
  302. X#else
  303. Xstatic void MoveBallBirth(display, window, x, y, slide, replace, i)
  304. X    Display *display;
  305. X    Window window;
  306. X    int x;
  307. X    int y; 
  308. X    int slide;
  309. X    int replace;
  310. X    int i;
  311. X#endif
  312. X{
  313. X    /* Remove any debris under ball first by clearing it */
  314. X    if (replace)
  315. X    {
  316. X        XClearArea(display, window, 
  317. X            balls[i].oldx - BALL_WC, balls[i].oldy - BALL_HC, 
  318. X            BALL_WIDTH, BALL_HEIGHT, False);
  319. X    }    
  320. X
  321. X    balls[i].oldx = x;
  322. X    balls[i].oldy = y;
  323. X
  324. X    /* If slide is -1 then clear the ball area */
  325. X    if (slide == -1)
  326. X        XClearArea(display, window, 
  327. X            x - BALL_WC, y - BALL_HC, BALL_WIDTH, BALL_HEIGHT, False);
  328. X    else
  329. X        DrawTheBallBirth(display, window, x, y, slide);
  330. X}
  331. X
  332. X#if NeedFunctionPrototypes
  333. Xstatic void MoveBall(Display *display, Window window, int x, int y, int replace,
  334. X    int i)
  335. X#else
  336. Xstatic void MoveBall(display, window, x, y, replace, i)
  337. X    Display *display; 
  338. X    Window window;
  339. X    int x;
  340. X    int y;
  341. X    int replace;
  342. X    int i;
  343. X#endif
  344. X{
  345. X    if (replace)
  346. X    {
  347. X        EraseTheBall(display, window, balls[i].oldx, balls[i].oldy);
  348. X    }
  349. X
  350. X    balls[i].oldx = x;
  351. X    balls[i].oldy = y;
  352. X
  353. X    if (Killer == True)
  354. X    {
  355. X        /* Render the killer ball now ie: red ball */
  356. X        DrawTheBall(display, window, x, y, BALL_SLIDES-1);
  357. X    }
  358. X    else
  359. X    {
  360. X        /* Render the ball now */
  361. X        DrawTheBall(display, window, x, y, balls[i].slide);
  362. X    }    
  363. X
  364. X    /* Change slide for ball every n frames of animation */
  365. X    if ((frame % BALL_ANIM_RATE) == 0)
  366. X        balls[i].slide++;
  367. X    
  368. X    /* wrap around slides */
  369. X    if (balls[i].slide == BALL_SLIDES-1) balls[i].slide = 0;
  370. X}
  371. X
  372. X#if NeedFunctionPrototypes
  373. Xstatic void DoBoardTilt(Display *display, int i)
  374. X#else
  375. Xstatic void DoBoardTilt(display, i)
  376. X    Display *display;
  377. X    int i;
  378. X#endif
  379. X{
  380. X    if (balls[i].ballState == BALL_ACTIVE)
  381. X    {
  382. X        /* Tilt the board to remove any endless loops */
  383. X        SetCurrentMessage(display, messWindow, 
  384. X            "Auto Tilt Activated", True);
  385. X    
  386. X        balls[i].dx = balls[i].dy = 0;
  387. X    
  388. X        /* Randomise the ball */
  389. X        while (balls[i].dx == 0)
  390. X        {
  391. X                balls[i].dx = (2 - (rand() % 4)) * 2;
  392. X                balls[i].dy = (abs(balls[i].dx)) * 2;
  393. X            balls[i].lastPaddleHitFrame = frame + PADDLE_BALL_FRAME_TILT;
  394. X        }
  395. X    }
  396. X}
  397. X
  398. X#if NeedFunctionPrototypes
  399. Xstatic void TeleportBall(Display *display, Window window, int i)
  400. X#else
  401. Xstatic void TeleportBall(display, window, i)
  402. X    Display *display;
  403. X     Window window;
  404. X    int i;
  405. X#endif
  406. X{
  407. X    /* This function will teleport the ball to some other space not occupied
  408. X     * and start off there.
  409. X     */
  410. X    int r1, c1, s1, r2, c2, s2, r3, c3, s3, r4, c4, s4;
  411. X    int r, c, x, y;
  412. X    struct aBlock *blockP, *bP;
  413. X    int done = False;
  414. X
  415. X    /* Loop until we find a block to move to */
  416. X    while (done == False)
  417. X    {
  418. X        /* Give me a new random block position */
  419. X        r = (rand() % (MAX_ROW - 5)) + 1;
  420. X        c = (rand() % MAX_COL) + 1;
  421. X
  422. X        if (r < 0 || r >= MAX_ROW) continue;
  423. X        if (c < 0 || c >= MAX_COL) continue;
  424. X
  425. X        /* Pointer to the correct block we need - speed things up */
  426. X        blockP = &blocks[r][c];
  427. X
  428. X        /* Check that the block is not occupied and not exploding */
  429. X        if ((blockP->occupied == False) && (blockP->exploding == False))
  430. X        {
  431. X            /* Check that the block is not a closed position */
  432. X
  433. X            r1 = r;     c1 = c - 1;  s1 = 0;
  434. X            if (r1 < 0 || r1 >= MAX_ROW) s1 = 1;
  435. X            if (c1 < 0 || c1 >= MAX_COL) s1 = 1;
  436. X            if (s1 == 0) 
  437. X            {
  438. X                bP = &blocks[r1][c1];
  439. X                if (bP->blockType == BLACK_BLK)
  440. X                s1 = 1;
  441. X            }
  442. X
  443. X            r2 = r - 1; c2 = c;      s2 = 0;
  444. X            if (r2 < 0 || r2 >= MAX_ROW) s2 = 1;
  445. X            if (c2 < 0 || c2 >= MAX_COL) s2 = 1;
  446. X            if (s2 == 0) 
  447. X            {
  448. X                bP = &blocks[r2][c2];
  449. X                if (bP->blockType == BLACK_BLK)
  450. X                    s2 = 1;
  451. X            }
  452. X
  453. X            r3 = r;     c3 = c + 1;  s3 = 0;
  454. X            if (r3 < 0 || r3 >= MAX_ROW) s3 = 1;
  455. X            if (c3 < 0 || c3 >= MAX_COL) s3 = 1;
  456. X            if (s3 == 0) 
  457. X            {
  458. X                bP = &blocks[r3][c3];
  459. X                if (bP->blockType == BLACK_BLK)
  460. X                    s3 = 1;
  461. X            }
  462. X
  463. X            r4 = r + 1; c4 = c;      s4 = 0;
  464. X            if (r4 < 0 || r4 >= MAX_ROW) s4 = 1;
  465. X            if (c4 < 0 || c4 >= MAX_COL) s4 = 1;
  466. X            if (s4 == 0) 
  467. X            {
  468. X                bP = &blocks[r4][c4];
  469. X                if (bP->blockType == BLACK_BLK)
  470. X                    s4 = 1;
  471. X            }
  472. X
  473. X            /* If it isn't ok to go here then keep searching */
  474. X            if ((s1 == 1) && (s2 == 1) && (s3 == 1) && (s4 == 1))
  475. X                continue;
  476. X
  477. X            /* Calculate the new ball coordinates */
  478. X            COL2X(x, c);
  479. X            ROW2Y(y, r);
  480. X
  481. X            balls[i].ballx = x;
  482. X            balls[i].bally = y;
  483. X
  484. X            /* Move the ball to the new position */
  485. X            MoveBall(display, window, x, y, True, i);
  486. X
  487. X            balls[i].lastPaddleHitFrame = frame + PADDLE_BALL_FRAME_TILT;
  488. X
  489. X            /* Ok jump out now thanks. */
  490. X            done = True;
  491. X        }
  492. X    }
  493. X}
  494. X
  495. X#if NeedFunctionPrototypes
  496. Xvoid SplitBallInTwo(Display *display, Window window)
  497. X#else
  498. Xvoid SplitBallInTwo(display, window)
  499. X    Display *display;
  500. X     Window window;
  501. X#endif
  502. X{
  503. X    int j;
  504. X
  505. X    if (livesLeft > 0)
  506. X    {
  507. X        j = AddANewBall(PLAY_WIDTH / 2, -BALL_HC, 3, 3);
  508. X        if (j > 0)
  509. X        {
  510. X            /* Make this new ball move straight away */
  511. X            ChangeBallMode(BALL_ACTIVE, j);
  512. X
  513. X            /* Take the life from player as the new ball is in play */
  514. X            DecExtraLife(display);
  515. X
  516. X            SetCurrentMessage(display, messWindow,
  517. X                "More balls!", True);
  518. X        }
  519. X    }
  520. X    else
  521. X        SetCurrentMessage(display, messWindow,
  522. X            "Cannot add ball!", True);
  523. X}
  524. X
  525. X#if NeedFunctionPrototypes
  526. Xvoid ClearBallNow(Display *display, Window window, int i)
  527. X#else
  528. Xvoid ClearBallNow(display, window, i)
  529. X    Display *display;
  530. X     Window window;
  531. X    int i;
  532. X#endif
  533. X{
  534. X    /* Kill the ball now, boy! */
  535. X    EraseTheBall(display, window, balls[i].ballx, balls[i].bally);
  536. X    ClearBall(i);
  537. X    DeadBall(display, window);
  538. X}
  539. X
  540. X#if NeedFunctionPrototypes
  541. Xvoid KillBallNow(Display *display, Window window, int i)
  542. X#else
  543. Xvoid KillBallNow(display, window, i)
  544. X    Display *display;
  545. X     Window window;
  546. X    int i;
  547. X#endif
  548. X{
  549. X    /* Kill the ball now, boy! */
  550. X    ChangeBallMode(BALL_POP, i);
  551. X}
  552. X
  553. X#if NeedFunctionPrototypes
  554. Xvoid GetBallPosition(int *ballX, int *ballY, int i)
  555. X#else
  556. Xvoid GetBallPosition(ballX, ballY, i)
  557. X    int *ballX;
  558. X    int *ballY;
  559. X    int i;
  560. X#endif
  561. X{
  562. X    /* Return ball i's position */
  563. X    *ballX = balls[i].ballx;
  564. X    *ballY = balls[i].bally;
  565. X}
  566. X
  567. X#if NeedFunctionPrototypes
  568. Xstatic int BallHitPaddle(Display *display, Window window, int *hit, int i,
  569. X    int *x, int *y)
  570. X#else
  571. Xstatic int BallHitPaddle(display, window, hit, i, x, y)
  572. X    Display *display;
  573. X    Window window;
  574. X    int *hit;
  575. X    int i;
  576. X    int *x, *y;
  577. X#endif
  578. X{
  579. X    float x1, x2, y1, y2, alpha, beta, xP1, xP2, xH, yH;
  580. X    int paddleLine;
  581. X
  582. X    /***********************************************************************
  583. X
  584. X                        A1 (x1,y1)
  585. X                        *
  586. X                       .
  587. X                      .
  588. X         P1 =========.=========== P2   <----   paddle (x, y pos is known )
  589. X        (xP1,yP1)   . H (xH, yH)    (xP2,yP2)
  590. X                   .
  591. X                  .
  592. X                 .
  593. X                .
  594. X               .
  595. X              *
  596. X             A2 (x2,y2)
  597. X
  598. X           Given the line A1A2, is the intersecting point H (xH, yH) in the paddle 
  599. X        segment ? (i.e xH in [xP1,xP2])
  600. X
  601. X           A1A2 is :  y = alpha * x + beta
  602. X
  603. X           A1 and A2 are in A1A2 than beta = [(y1 + y2) - alpha*(x1+x2)] / 2
  604. X
  605. X           yH = yP1 = yP2
  606. X
  607. X           so xH = (yP1 - beta) / alpha
  608. X
  609. X    **********************************************************************/
  610. X
  611. X    paddleLine = (PLAY_HEIGHT - DIST_BASE - 2);
  612. X
  613. X    if (balls[i].bally + BALL_HC > paddleLine)
  614. X       {
  615. X           xP1 = (float)(paddlePos - (GetPaddleSize() / 2) - BALL_WC/2);
  616. X           xP2 = (float)(paddlePos + (GetPaddleSize() / 2) + BALL_WC/2);
  617. X
  618. X           if (balls[i].dx == 0)
  619. X          {
  620. X            /* process the vertical moving balls */
  621. X              if (((float)balls[i].ballx > xP1) && ((float)balls[i].ballx < xP2))
  622. X             {
  623. X                 /* the ball hit the paddle */
  624. X                 *hit = balls[i].ballx - paddlePos;
  625. X                 *x      = balls[i].ballx;
  626. X                 *y      = paddleLine - BALL_HC;
  627. X
  628. X                 return True;
  629. X             }
  630. X              else
  631. X                return False;
  632. X          }
  633. X           else
  634. X          {
  635. X             /* compute the line coefficients of the ball */
  636. X
  637. X            alpha     = (float) balls[i].dy;
  638. X            x1         = (float) (balls[i].ballx - balls[i].dx);
  639. X            y1         = (float) (balls[i].bally - balls[i].dy);
  640. X            x2         = (float) (balls[i].ballx);
  641. X            y2         = (float) (balls[i].bally);
  642. X            beta     = ((y1 + y2) - alpha * (x1 + x2)) / 2.0;
  643. X
  644. X            yH = (float) paddleLine;
  645. X            xH = (yH - beta) / alpha;
  646. X
  647. X            if ((xH > xP1) && (xH < xP2))
  648. X            {
  649. X                /* the ball hit the paddle */
  650. X                *hit     = (int) (xH + 0.5) - paddlePos;
  651. X                *x         = (int) (xH + 0.5);
  652. X                *y         = paddleLine - BALL_HC;
  653. X
  654. X                return True;
  655. X            }
  656. X            else
  657. X                return False;
  658. X        }
  659. X    }
  660. X
  661. X       /* We didn't hit the paddle */
  662. X       return False;
  663. X}
  664. X
  665. X#if NeedFunctionPrototypes
  666. Xstatic int HandleTheBlocks(Display *display, Window window, int row, int col,
  667. X    int i)
  668. X#else
  669. Xstatic int HandleTheBlocks(display, window, row, col, i)
  670. X    int row;
  671. X    int col;
  672. X    int i;
  673. X#endif
  674. X{
  675. X    struct aBlock *blockP;
  676. X
  677. X    /* Pointer to the block the ball is in */
  678. X    blockP = &blocks[row][col];
  679. X
  680. X    /* There has been a collision so handle it */
  681. X    if (blockP->exploding == False)
  682. X    {
  683. X        if (blockP->blockType == COUNTER_BLK)
  684. X        {
  685. X            balls[i].lastPaddleHitFrame = frame + PADDLE_BALL_FRAME_TILT;
  686. X
  687. X            /* If in killer mode then don't bounce off block */
  688. X            if (Killer == True)
  689. X            {
  690. X                DrawBlock(display, window, row, col, KILL_BLK);
  691. X                return True;
  692. X            }
  693. X
  694. X            /* Special case for counter - reduce count on block */
  695. X            if (blockP->counterSlide == 0)
  696. X                DrawBlock(display, window, row, col, KILL_BLK);
  697. X            else
  698. X            {
  699. X                /* Draw the counter block minus one number */
  700. X                blockP->counterSlide--;
  701. X                DrawBlock(display, window, row, col, COUNTER_BLK);
  702. X            }
  703. X        }
  704. X        else
  705. X        {
  706. X            if (blockP->blockType == MGUN_BLK)
  707. X            {
  708. X                /* Turn the machine gun on */
  709. X                ToggleFastGun(display, True);
  710. X                DrawSpecials(display);
  711. X                SetCurrentMessage(display, messWindow,
  712. X                    "Machine Gun", True);
  713. X
  714. X                /* Not a wall so explode the block */
  715. X                DrawBlock(display, window, row, col, KILL_BLK);
  716. X                balls[i].lastPaddleHitFrame = frame + PADDLE_BALL_FRAME_TILT;
  717. X
  718. X                /* If in killer mode then don't bounce off block */
  719. X                if (Killer == True)
  720. X                    return True;
  721. X
  722. X            } else if (blockP->blockType == DEATH_BLK)
  723. X            {
  724. X                /* Ha ha - hit death block so die */
  725. X
  726. X                /* Kill the ball now */
  727. X                ClearBallNow(display, window, i);
  728. X
  729. X                /* Not a wall so explode the block */
  730. X                DrawBlock(display, window, row, col, KILL_BLK);
  731. X                balls[i].lastPaddleHitFrame = frame + PADDLE_BALL_FRAME_TILT;
  732. X
  733. X                /* If in killer mode then don't bounce off block */
  734. X                if (Killer == True)
  735. X                    return True;
  736. X
  737. X            } else if (blockP->blockType == HYPERSPACE_BLK)
  738. X            {
  739. X                /* Teleport to somewhere else */
  740. X                TeleportBall(display, window, i);
  741. X
  742. X                /* Redraw it just in case */
  743. X                DrawBlock(display, window, row, col, HYPERSPACE_BLK);
  744. X                balls[i].lastPaddleHitFrame = frame + PADDLE_BALL_FRAME_TILT;
  745. X
  746. X                PlaySoundForBlock(HYPERSPACE_BLK);
  747. X
  748. X                return True;
  749. X
  750. X            } else if (blockP->blockType == WALLOFF_BLK)
  751. X            {
  752. X                /* Walls are now turned off */
  753. X                ToggleWallsOn(display, True);
  754. X                DrawSpecials(display);
  755. X                SetCurrentMessage(display, messWindow,
  756. X                    "Walls off", True);
  757. X
  758. X                /* Not a wall so explode the block */
  759. X                DrawBlock(display, window, row, col, KILL_BLK);
  760. X                balls[i].lastPaddleHitFrame = frame + PADDLE_BALL_FRAME_TILT;
  761. X
  762. X                /* If in killer mode then don't bounce off block */
  763. X                if (Killer == True)
  764. X                    return True;
  765. X
  766. X            } else if (blockP->blockType == REVERSE_BLK)
  767. X            {
  768. X                /* Paddle control now reverse */
  769. X                ToggleReverse(display);
  770. X                SetCurrentMessage(display, messWindow,
  771. X                    "Reverse Control", True);
  772. X                DrawSpecials(display);
  773. X
  774. X                /* Move the paddle to reflect reversed paddle */
  775. X                handlePaddleMoving(display);
  776. X
  777. X                /* Not a wall so explode the block */
  778. X                DrawBlock(display, window, row, col, KILL_BLK);
  779. X                balls[i].lastPaddleHitFrame = frame + PADDLE_BALL_FRAME_TILT;
  780. X
  781. X                /* If in killer mode then don't bounce off block */
  782. X                if (Killer == True)
  783. X                    return True;
  784. X
  785. X            } else if (blockP->blockType == PAD_SHRINK_BLK)
  786. X            {
  787. X                /* Paddle shrinking block */
  788. X                ChangePaddleSize(display, window, PAD_SHRINK_BLK);
  789. X                SetCurrentMessage(display, messWindow,
  790. X                    "Shrink Paddle", True);
  791. X
  792. X                /* Not a wall so explode the block */
  793. X                DrawBlock(display, window, row, col, KILL_BLK);
  794. X                balls[i].lastPaddleHitFrame = frame + PADDLE_BALL_FRAME_TILT;
  795. X
  796. X                /* If in killer mode then don't bounce off block */
  797. X                if (Killer == True)
  798. X                    return True;
  799. X
  800. X            } else if (blockP->blockType == PAD_EXPAND_BLK)
  801. X            {
  802. X                /* Paddle expanding block */
  803. X                ChangePaddleSize(display, window, PAD_EXPAND_BLK);
  804. X                SetCurrentMessage(display, messWindow,
  805. X                    "Expand Paddle", True);
  806. X
  807. X                /* Not a wall so explode the block */
  808. X                DrawBlock(display, window, row, col, KILL_BLK);
  809. X                balls[i].lastPaddleHitFrame = frame + PADDLE_BALL_FRAME_TILT;
  810. X
  811. X                /* If in killer mode then don't bounce off block */
  812. X                if (Killer == True)
  813. X                    return True;
  814. X
  815. X            } else if (blockP->blockType == EXTRABALL_BLK)
  816. X            {
  817. X                /* Extra ball */
  818. X                AddExtraLife(display);
  819. X                SetCurrentMessage(display, messWindow,
  820. X                    "Extra ball", True);
  821. X
  822. X                /* Not a wall so explode the block */
  823. X                DrawBlock(display, window, row, col, KILL_BLK);
  824. X                balls[i].lastPaddleHitFrame = frame + PADDLE_BALL_FRAME_TILT;
  825. X
  826. X                /* If in killer mode then don't bounce off block */
  827. X                if (Killer == True)
  828. X                    return True;
  829. X
  830. X            } else if (blockP->blockType == STICKY_BLK)
  831. X            {
  832. X                ToggleStickyBat(display, True);
  833. X                DrawSpecials(display);
  834. X                SetCurrentMessage(display, messWindow,
  835. X                    "Sticky Bat", True);
  836. X
  837. X                /* Not a wall so explode the block */
  838. X                DrawBlock(display, window, row, col, KILL_BLK);
  839. X                balls[i].lastPaddleHitFrame = frame + PADDLE_BALL_FRAME_TILT;
  840. X
  841. X                /* If in killer mode then don't bounce off block */
  842. X                if (Killer == True)
  843. X                    return True;
  844. X
  845. X            } else if (blockP->blockType == MULTIBALL_BLK)
  846. X            {
  847. X                ToggleMultiBall(display, True);
  848. X                DrawSpecials(display);
  849. X                SplitBallInTwo(display, window);
  850. X
  851. X                /* Not a wall so explode the block */
  852. X                DrawBlock(display, window, row, col, KILL_BLK);
  853. X                balls[i].lastPaddleHitFrame = frame + PADDLE_BALL_FRAME_TILT;
  854. X
  855. X                /* If in killer mode then don't bounce off block */
  856. X                if (Killer == True)
  857. X                    return True;
  858. X
  859. X            } else if (blockP->blockType != BLACK_BLK)
  860. X            {
  861. X                /* Not a wall so explode the block */
  862. X                DrawBlock(display, window, row, col, KILL_BLK);
  863. X                balls[i].lastPaddleHitFrame = frame + PADDLE_BALL_FRAME_TILT;
  864. X
  865. X                /* If in killer mode then don't bounce off block */
  866. X                if (Killer == True) return True;
  867. X            }
  868. X            else if (blockP->blockType == BLACK_BLK)
  869. X            {
  870. X                /* Redraw the solid wall block to make sure */
  871. X                DrawBlock(display, window, row, col, BLACK_BLK);
  872. X            }
  873. X        }
  874. X    }
  875. X
  876. X    /* Don't return after returning */
  877. X    return False;
  878. X}
  879. X
  880. X#if NeedFunctionPrototypes
  881. Xstatic void UpdateABall(Display *display, Window window, int i)
  882. X#else
  883. Xstatic void UpdateABall(display, window, i)
  884. X    Display *display;
  885. X    Window window;
  886. X    int i;
  887. X#endif
  888. X{
  889. X    int row, col, hitPos, ret;
  890. X    int cx, cy, step, j, r, ddx, ddy, Hx, Hy;
  891. X    float incx, incy, x, y;
  892. X    float Vs, Vx, Vy, alpha, beta, gamma, padSize;
  893. X
  894. X    /* Update ball position using dx and dy values */    
  895. X    balls[i].ballx = balls[i].oldx + balls[i].dx;
  896. X    balls[i].bally = balls[i].oldy + balls[i].dy;
  897. X
  898. X    /* Mark the ball to die as it is past the paddle */
  899. X    if (balls[i].bally > (PLAY_HEIGHT - DIST_BASE))
  900. X        ChangeBallMode(BALL_DIE, i);
  901. X
  902. X    /* Check if ball has hit left wall and bounce off */        
  903. X    if (balls[i].ballx < BALL_WC && noWalls == False)
  904. X    {
  905. X        balls[i].dx = abs(balls[i].dx);
  906. X        if (noSound == False) playSoundFile("boing", 20);
  907. X
  908. X    } else if (noWalls == True && balls[i].ballx < BALL_WC)
  909. X    {
  910. X        /* If the no walls mode is on then wrap around onto right wall */
  911. X        balls[i].ballx = (PLAY_WIDTH - BALL_WC);
  912. X
  913. X        /* Move the ball to the new position */
  914. X        MoveBall(display, window, balls[i].ballx, balls[i].bally, True, i);
  915. X
  916. X        return;
  917. X    }
  918. X
  919. X    /* Check if ball has hit right wall and bounce off */        
  920. X    if (balls[i].ballx > (PLAY_WIDTH - BALL_WC) && noWalls == False)
  921. X    {
  922. X        balls[i].dx = -(abs(balls[i].dx));
  923. X        if (noSound == False) playSoundFile("boing", 20);
  924. X
  925. X    } else if (noWalls == True && balls[i].ballx > (PLAY_WIDTH - BALL_WC))
  926. X    {
  927. X        /* If the no walls mode is on then wrap around onto left wall */
  928. X        balls[i].ballx = BALL_WC;
  929. X
  930. X        /* Move the ball to the new position */
  931. X        MoveBall(display, window, balls[i].ballx, balls[i].bally, True, i);
  932. X
  933. X        return;
  934. X    }
  935. X
  936. X    /* Check if ball has hit top wall and bounce off */        
  937. X    if (balls[i].bally < BALL_HC) 
  938. X    {
  939. X        balls[i].dy = abs(balls[i].dy);
  940. X        if (noSound == False) playSoundFile("boing", 20);
  941. X    }
  942. X
  943. X    if (balls[i].ballState != BALL_DIE)
  944. X    {
  945. X        /* Check if the ball has hit the paddle */
  946. X        if (BallHitPaddle(display, window, &hitPos, i, &Hx, &Hy) == True)
  947. X        {
  948. X            /* Keep track of how long it was since the last paddle hit */
  949. X            balls[i].lastPaddleHitFrame = frame + PADDLE_BALL_FRAME_TILT;
  950. X            if (noSound == False) playSoundFile("boing", 20);
  951. X
  952. X            /* Add a paddle hit bonus score, I'm nice ;-) */
  953. X            AddToScore((u_long) PADDLE_HIT_SCORE);
  954. X            DisplayScore(display, scoreWindow, score);
  955. X
  956. X            /* speed vector of the ball */
  957. X               Vx = (float) balls[i].dx;    
  958. X               Vy = (float) balls[i].dy;
  959. X
  960. X            /* speed intensity of the ball */
  961. X               Vs = sqrt( Vx*Vx + Vy*Vy );
  962. X
  963. X               alpha = atan(Vx/-Vy);
  964. X
  965. X               padSize = (float)(GetPaddleSize() + BALL_WC);
  966. X               Vx = (float) hitPos;
  967. X               Vy = (float) padSize/1.0;
  968. X
  969. X               beta = atan(Vx/Vy);
  970. X               gamma = 2.0*beta - alpha;
  971. X
  972. X               Vx = Vs * sin(gamma);
  973. X               Vy = -Vs * cos(gamma);
  974. X
  975. X            /* take in account the horizontal speed of the paddle: 
  976. X             * vectorial summ 
  977. X             */
  978. X               Vx += (float) (paddleDx / 10.0);
  979. X
  980. X               if (Vx > 0.0)
  981. X                balls[i].dx = (int) (Vx + 0.5);
  982. X               else
  983. X                 balls[i].dx = (int) (Vx - 0.5);
  984. X
  985. X               if (Vy < 0.0)
  986. X                 balls[i].dy = (int) (Vy - 0.5);
  987. X               else
  988. X                 balls[i].dy = -MIN_DY_BALL;
  989. X
  990. X               if (balls[i].dy > -MIN_DY_BALL) 
  991. X                balls[i].dy = -MIN_DY_BALL;
  992. X
  993. X               balls[i].ballx = Hx;
  994. X               balls[i].bally = Hy;
  995. X
  996. X            /* handle the sticky paddle special by changing the ball mode
  997. X             * to BALL_READY so it will need user to press space to start
  998. X             * the ball moving again.
  999. X             */
  1000. X            if (stickyBat == True)    
  1001. X            {
  1002. X                ChangeBallMode(BALL_READY, i);
  1003. X
  1004. X                /* Move the ball to the new position */
  1005. X                MoveBall(display, window, 
  1006. X                    balls[i].ballx, balls[i].bally, True, i);
  1007. X
  1008. X                /* So that it will auto shoot off if you wait too long */
  1009. X                balls[i].nextFrame = frame + BALL_AUTO_ACTIVE_DELAY;
  1010. X
  1011. X                return;
  1012. X            }
  1013. X        }
  1014. X        else
  1015. X        {
  1016. X            /* Ball didn't hit the paddle so check if it time to autotilt the
  1017. X             * board as it is in an infinite loop most likely.
  1018. X             */
  1019. X            if (balls[i].lastPaddleHitFrame == frame)
  1020. X                DoBoardTilt(display, i);
  1021. X        }
  1022. X
  1023. X           Vx = (float) balls[i].dx;
  1024. X           Vy = (float) balls[i].dy;
  1025. X           Vs = sqrt(Vx * Vx + Vy * Vy);
  1026. X
  1027. X           alpha = sqrt((float)MAX_X_VEL*(float)MAX_X_VEL + (float)MAX_Y_VEL*
  1028. X            (float)MAX_Y_VEL );
  1029. X           alpha /= 9.0; /* number of speed level */
  1030. X           alpha *= (float) speedLevel;
  1031. X           beta = alpha / Vs;
  1032. X           Vx *= beta;
  1033. X           Vy *= beta;
  1034. X
  1035. X           if (Vx > 0.0)
  1036. X             balls[i].dx = (int) (Vx + 0.5);
  1037. X           else
  1038. X             balls[i].dx = (int) (Vx - 0.5);
  1039. X
  1040. X           if (Vy > 0.0)
  1041. X             balls[i].dy = (int) (Vy + 0.5);
  1042. X           else
  1043. X             balls[i].dy = (int) (Vy - 0.5);
  1044. X
  1045. X           if (balls[i].dy == 0) 
  1046. X            balls[i].dy = MIN_DY_BALL;
  1047. X
  1048. X           if (balls[i].dx == 0) 
  1049. X            balls[i].dx = MIN_DX_BALL;
  1050. X    }
  1051. X
  1052. X    /* Has the player lost the ball of the bottom of the screen */
  1053. X    if (balls[i].bally > (PLAY_HEIGHT + BALL_HEIGHT))
  1054. X    {
  1055. X        /* Make ball start to die */
  1056. X        ClearBallNow(display, window, i);
  1057. X        return;
  1058. X    }
  1059. X
  1060. X    /* Convert the new ball positions to rows and cols for collision */
  1061. X    X2COL(col, balls[i].ballx);
  1062. X    Y2ROW(row, balls[i].bally);
  1063. X
  1064. X    x = balls[i].oldx;
  1065. X    y = balls[i].oldy;
  1066. X
  1067. X    cx = balls[i].dx > 0 ? 1 : -1;
  1068. X    cy = balls[i].dy > 0 ? 1 : -1;
  1069. X
  1070. X    if (abs(balls[i].dx) == abs(balls[i].dy))
  1071. X    {
  1072. X        incx = (float) cx;
  1073. X        incy = (float) cy;
  1074. X        step = abs(balls[i].dx);
  1075. X    } else if (abs(balls[i].dx) > abs(balls[i].dy))
  1076. X    {
  1077. X        incx = (float) cx;
  1078. X        incy = ((float) abs(balls[i].dy) / (float) abs(balls[i].dx)) * cy;
  1079. X        step = abs(balls[i].dx);
  1080. X    } 
  1081. X    else 
  1082. X    {
  1083. X        incy = (float) cy;
  1084. X        incx = ((float) abs(balls[i].dx) / (float) abs(balls[i].dy)) * cx;
  1085. X        step = abs(balls[i].dy);
  1086. X    }
  1087. X
  1088. X    for (j = 0; j < step; j++)
  1089. X    {
  1090. X        /* Check if the ball has hit a brick or something */
  1091. X        if ((ret = CheckForCollision(display, window, 
  1092. X            (int) x, (int) y, &row, &col, i)) != REGION_NONE)
  1093. X        {
  1094. X            if (HandleTheBlocks(display, window, row, col, i) == True)
  1095. X                return;
  1096. X
  1097. X            ddx = ddy = 0;
  1098. X            r = (rand() >> 16) % 4;
  1099. X
  1100. X            /* Find out which side the ball hit the brick */
  1101. X            switch (ret)
  1102. X            {
  1103. X                case REGION_LEFT:
  1104. X                    ddx = -r/4;
  1105. X                    balls[i].dx = -(abs(balls[i].dx));
  1106. X                    break;
  1107. X
  1108. X                case REGION_RIGHT:
  1109. X                    ddx = r/4;
  1110. X                    balls[i].dx = abs(balls[i].dx);
  1111. X                    break;
  1112. X
  1113. X                case REGION_TOP:
  1114. X                    ddy = -r/4;
  1115. X                    balls[i].dy = -(abs(balls[i].dy));
  1116. X                    break;
  1117. X
  1118. X                case REGION_BOTTOM:
  1119. X                    ddy = r/4;
  1120. X                    balls[i].dy = abs(balls[i].dy);
  1121. X                    break;
  1122. X
  1123. X                case (REGION_BOTTOM | REGION_RIGHT):
  1124. X                    ddy = r;
  1125. X                    ddx = r;
  1126. X                    balls[i].dy = abs(balls[i].dy);
  1127. X                    balls[i].dx = abs(balls[i].dx);
  1128. X                    break;
  1129. X
  1130. X                case (REGION_TOP | REGION_RIGHT):
  1131. X                    ddy = -r;
  1132. X                    ddx = r;
  1133. X                    balls[i].dy = -(abs(balls[i].dy));
  1134. X                    balls[i].dx = abs(balls[i].dx);
  1135. X                    break;
  1136. X
  1137. X                case (REGION_BOTTOM | REGION_LEFT):
  1138. X                    ddy = r;
  1139. X                    ddx = -r;
  1140. X                    balls[i].dx = -(abs(balls[i].dx));
  1141. X                    balls[i].dy = abs(balls[i].dy);
  1142. X                    break;
  1143. X
  1144. X                case (REGION_TOP | REGION_LEFT):
  1145. X                    ddy = -r;
  1146. X                    ddx = -r;
  1147. X                    balls[i].dx = -(abs(balls[i].dx));
  1148. X                    balls[i].dy = -(abs(balls[i].dy));
  1149. X                    break;
  1150. X            }
  1151. X
  1152. X            /* Update ball position using dx and dy values */    
  1153. X            balls[i].ballx = (int) x + balls[i].dx + ddx;
  1154. X            balls[i].bally = (int) y + balls[i].dy + ddy;
  1155. X
  1156. X            break;
  1157. X        }
  1158. X
  1159. X        x += incx;
  1160. X        y += incy;
  1161. X
  1162. X    }    /* for */
  1163. X
  1164. X    /* Move the ball to the new position */
  1165. X    MoveBall(display, window, balls[i].ballx, balls[i].bally, True, i);
  1166. X}
  1167. X
  1168. X#if NeedFunctionPrototypes
  1169. Xstatic int CheckRegions(Display *display, Window window, int row, int col,
  1170. X    int x, int y, int i)
  1171. X#else
  1172. Xstatic int CheckRegions(display, window, row, col, x, y, i)
  1173. X    Display *display;
  1174. X    Window window;
  1175. X    int row;
  1176. X    int col;
  1177. X    int x, y;
  1178. X    int i;
  1179. X#endif
  1180. X{
  1181. X    struct aBlock *blockP;
  1182. X    int region = REGION_NONE;
  1183. X
  1184. X    if (row < 0 || row >= MAX_ROW) return REGION_NONE;
  1185. X    if (col < 0 || col >= MAX_COL) return REGION_NONE;
  1186. X
  1187. X    blockP = &blocks[row][col];
  1188. X
  1189. X    /* If blocks is occupied then check for collision */
  1190. X    if (blockP->occupied == 1 && blockP->exploding == False)
  1191. X    {
  1192. X        /* Suss out if ball is moving more vertically than horizontally */
  1193. X        if (abs(balls[i].dx) > abs(balls[i].dy))
  1194. X        {
  1195. X            /* Check left and right first as ball is moving more horizontal */
  1196. X
  1197. X            /* See if the ball intersects with the block's left region */
  1198. X            if (XRectInRegion(blockP->regionLeft, x - BALL_WC, y - BALL_HC,
  1199. X                BALL_WIDTH, BALL_HEIGHT) != RectangleOut)
  1200. X                region |= REGION_LEFT;
  1201. X
  1202. X            /* See if the ball intersects with the block's right region */
  1203. X            if (XRectInRegion(blockP->regionRight, x - BALL_WC, y - BALL_HC,
  1204. X                BALL_WIDTH, BALL_HEIGHT) != RectangleOut)
  1205. X                region |= REGION_RIGHT;
  1206. X
  1207. X            /* See if the ball intersects with the block's bottom region */
  1208. X            if (XRectInRegion(blockP->regionBottom, x - BALL_WC, y - BALL_HC,
  1209. X                BALL_WIDTH, BALL_HEIGHT) != RectangleOut)
  1210. X                region |= REGION_BOTTOM;
  1211. X
  1212. X            /* See if the ball intersects with the block's top region */
  1213. X            if (XRectInRegion(blockP->regionTop, x - BALL_WC, y - BALL_HC,
  1214. X                BALL_WIDTH, BALL_HEIGHT) != RectangleOut)
  1215. X                region |= REGION_TOP;
  1216. X        }
  1217. X        else
  1218. X        {
  1219. X            /* Check top and bottom first as ball is moving more vertical */
  1220. X
  1221. X            /* See if the ball intersects with the block's bottom region */
  1222. X            if (XRectInRegion(blockP->regionBottom, x - BALL_WC, y - BALL_HC,
  1223. X                BALL_WIDTH, BALL_HEIGHT) != RectangleOut)
  1224. X                region |= REGION_BOTTOM;
  1225. X
  1226. X            /* See if the ball intersects with the block's top region */
  1227. X            if (XRectInRegion(blockP->regionTop, x - BALL_WC, y - BALL_HC,
  1228. X                BALL_WIDTH, BALL_HEIGHT) != RectangleOut)
  1229. X                region |= REGION_TOP;
  1230. X
  1231. X            /* See if the ball intersects with the block's left region */
  1232. X            if (XRectInRegion(blockP->regionLeft, x - BALL_WC, y - BALL_HC,
  1233. X                BALL_WIDTH, BALL_HEIGHT) != RectangleOut)
  1234. X                region |= REGION_LEFT;
  1235. X
  1236. X            /* See if the ball intersects with the block's right region */
  1237. X            if (XRectInRegion(blockP->regionRight, x - BALL_WC, y - BALL_HC,
  1238. X                BALL_WIDTH, BALL_HEIGHT) != RectangleOut)
  1239. X                region |= REGION_RIGHT;
  1240. X        }
  1241. X    }
  1242. X
  1243. X    /* Return the region combination */
  1244. X    return region;
  1245. X}
  1246. X
  1247. X#if NeedFunctionPrototypes
  1248. Xstatic int CheckForCollision(Display *display, Window window, int x, int y, 
  1249. X    int *r, int *c, int i)
  1250. X#else
  1251. Xstatic int CheckForCollision(display, window, x, y, r, c, i)
  1252. X    Display *display;
  1253. X    Window window;
  1254. X    int x, y;
  1255. X    int *r, *c;
  1256. X    int i;
  1257. X#endif
  1258. X{
  1259. X    /* Check for ball to block collision */
  1260. X    int ret, row, col;
  1261. X
  1262. X    row = *r;
  1263. X    col = *c;
  1264. X
  1265. X    if ((ret = CheckRegions(display, window, row, col, x, y, i)) 
  1266. X        != REGION_NONE)    /*nothin*/;
  1267. X    else if ((ret = CheckRegions(display, window, row+1, col, x, y, i)) 
  1268. X        != REGION_NONE)    row++;
  1269. X    else if ((ret = CheckRegions(display, window, row-1, col, x, y, i)) 
  1270. X        != REGION_NONE)    row--;
  1271. X    else if ((ret = CheckRegions(display, window, row, col+1, x, y, i)) 
  1272. X        != REGION_NONE)    col++;
  1273. X    else if ((ret = CheckRegions(display, window, row, col-1, x, y, i)) 
  1274. X        != REGION_NONE)    col--;
  1275. X    else if ((ret = CheckRegions(display, window, row+1, col+1, x, y, i)) 
  1276. X        != REGION_NONE)    { row++; col++; }
  1277. X    else if ((ret = CheckRegions(display, window, row-1, col-1, x, y, i)) 
  1278. X        != REGION_NONE)    { row--; col--; }
  1279. X    else if ((ret = CheckRegions(display, window, row+1, col-1, x, y, i)) 
  1280. X        != REGION_NONE) { row++; col--; }
  1281. X    else if ((ret = CheckRegions(display, window, row-1, col+1, x, y, i)) 
  1282. X        != REGION_NONE)    
  1283. X    {
  1284. X        *r = row-1;
  1285. X        *c = col+1;
  1286. X        return REGION_NONE;
  1287. X    }
  1288. X
  1289. X    /* Return the row and column where the ball hit */
  1290. X    *r = row;
  1291. X    *c = col;
  1292. X
  1293. X    return ret;
  1294. X}
  1295. X
  1296. X#if NeedFunctionPrototypes
  1297. Xstatic void updateBallVariables(int i)
  1298. X#else
  1299. Xstatic void updateBallVariables(i)
  1300. X    int i;
  1301. X#endif
  1302. X{
  1303. X    balls[i].ballx     = paddlePos;
  1304. X    balls[i].bally     = PLAY_HEIGHT - DIST_BALL_OF_PADDLE;
  1305. X    balls[i].oldx     = balls[i].ballx;
  1306. X    balls[i].oldy     = balls[i].bally;
  1307. X}
  1308. X
  1309. X#if NeedFunctionPrototypes
  1310. Xint StartAnotherBall(Display *display, Window window)
  1311. X#else
  1312. Xint StartAnotherBall(display, window)
  1313. X    Display *display;
  1314. X    Window window;
  1315. X#endif
  1316. X{
  1317. X    int i;
  1318. X
  1319. X    i = AddANewBall(0, 0, 3, -3);
  1320. X    if (i >= 0)
  1321. X    {
  1322. X        /* Make sure that all variables are updated */
  1323. X        updateBallVariables(i);
  1324. X
  1325. X        /* Set up animation for ball creation */
  1326. X        SetBallWait(BALL_ACTIVE, frame + 1, i);
  1327. X        
  1328. X        return i;
  1329. X    }
  1330. X
  1331. X    return -1;
  1332. X}
  1333. X
  1334. X#if NeedFunctionPrototypes
  1335. Xint GetNumberOfActiveBalls(void)
  1336. X#else
  1337. Xint GetNumberOfActiveBalls()
  1338. X#endif
  1339. X{
  1340. X    int i;
  1341. X    int t;
  1342. X
  1343. X    /* Zap through the list of balls */
  1344. X    for (i = 0, t = 0; i < MAX_BALLS; i++)
  1345. X    {
  1346. X        /* Found an active abll - add to total */
  1347. X        if (balls[i].ballState == BALL_ACTIVE)
  1348. X            t++;
  1349. X    }
  1350. X
  1351. X    /* Return the number of active balls */
  1352. X    return t;
  1353. X}
  1354. X
  1355. X#if NeedFunctionPrototypes
  1356. Xint GetAnActiveBall(void)
  1357. X#else
  1358. Xint GetAnActiveBall()
  1359. X#endif
  1360. X{
  1361. X    int i;
  1362. X
  1363. X    /* Zap through the list of balls */
  1364. X    for (i = 0; i < MAX_BALLS; i++)
  1365. X    {
  1366. X        /* Return this ball */
  1367. X        if (balls[i].ballState == BALL_ACTIVE)
  1368. X            return i;
  1369. X    }
  1370. X
  1371. X    return -1;
  1372. X}
  1373. X
  1374. X#if NeedFunctionPrototypes
  1375. Xint IsBallWaiting(void)
  1376. X#else
  1377. Xint IsBallWaiting()
  1378. X#endif
  1379. X{
  1380. X    int i;
  1381. X
  1382. X    /* Zap through the list of balls */
  1383. X    for (i = 0; i < MAX_BALLS; i++)
  1384. X    {
  1385. X        /* Ok it must be on the paddle so shoot it off */
  1386. X        if (balls[i].ballState == BALL_READY)
  1387. X            return True;
  1388. X    }
  1389. X
  1390. X    return False;
  1391. X}
  1392. X
  1393. X#if NeedFunctionPrototypes
  1394. Xint ActivateWaitingBall(void)
  1395. X#else
  1396. Xint ActivateWaitingBall()
  1397. X#endif
  1398. X{
  1399. X    int i;
  1400. X
  1401. X    /* Zap through the list of balls */
  1402. X    for (i = 0; i < MAX_BALLS; i++)
  1403. X    {
  1404. X        /* Ok it must be on the paddle so shoot it off */
  1405. X        if (balls[i].ballState == BALL_READY)
  1406. X        {
  1407. X            /* Change the balls mode so that it shoots off */
  1408. X            ChangeBallMode(BALL_ACTIVE, i);
  1409. X            return True;
  1410. X        }
  1411. X    }
  1412. X
  1413. X    return False;
  1414. X}
  1415. X
  1416. X#if NeedFunctionPrototypes
  1417. Xvoid ResetBallStart(Display *display, Window window)
  1418. X#else
  1419. Xvoid ResetBallStart(display, window)
  1420. X    Display *display;
  1421. X    Window window;
  1422. X#endif
  1423. X{
  1424. X    int i;
  1425. X
  1426. X    i = AddANewBall(0, 0, 3, -3);
  1427. X    if (i >= 0)
  1428. X    {
  1429. X        /* Make sure that all variables are updated */
  1430. X        updateBallVariables(i);
  1431. X
  1432. X        /* Add 2 bullets every ball death or creation as it happens */
  1433. X        AddABullet(display);
  1434. X        AddABullet(display);
  1435. X
  1436. X        /* Set up animation for ball creation */
  1437. X        SetBallWait(BALL_CREATE, frame + 1, i);
  1438. X    }
  1439. X}
  1440. X
  1441. X#if NeedFunctionPrototypes
  1442. Xstatic void AnimateBallPop(Display *display, Window window, int i)
  1443. X#else
  1444. Xstatic void AnimateBallPop(display, window, i)
  1445. X    Display *display;
  1446. X    Window window;
  1447. X    int i;
  1448. X#endif
  1449. X{
  1450. X    static int slide = BIRTH_SLIDES + 1;
  1451. X
  1452. X    if (frame == balls[i].nextFrame)
  1453. X    {
  1454. X        /* We are imploding so go backwards through slides */
  1455. X        slide--;
  1456. X
  1457. X        /* Wait for the next frame */
  1458. X        balls[i].nextFrame += BIRTH_FRAME_RATE;
  1459. X
  1460. X        /* First frame is to clear the ball away */
  1461. X        if (slide == BIRTH_SLIDES)
  1462. X        {
  1463. X            /* Clear the ball area */
  1464. X            EraseTheBall(display, window, balls[i].oldx, balls[i].oldy);
  1465. X            slide--;
  1466. X        }
  1467. X
  1468. X        if (slide < 0)
  1469. X        {
  1470. X            /* Erase the ball birth image */
  1471. X            MoveBallBirth(display, window, 
  1472. X                balls[i].oldx, balls[i].oldy, -1, True, i);
  1473. X
  1474. X            slide = BIRTH_SLIDES + 1;
  1475. X
  1476. X            /* Stop the ball by killing it! */
  1477. X            ClearBall(i);
  1478. X            ResetBallStart(display, window);
  1479. X            DeadBall(display, window);
  1480. X        }
  1481. X        else
  1482. X            /* Draw ball birth - handles ball moving as well */
  1483. X            MoveBallBirth(display, window, 
  1484. X                balls[i].oldx, balls[i].oldy, slide, True, i);
  1485. X    }
  1486. X}
  1487. X
  1488. X#if NeedFunctionPrototypes
  1489. Xstatic void AnimateBallCreate(Display *display, Window window, int i)
  1490. X#else
  1491. Xstatic void AnimateBallCreate(display, window, i)
  1492. X    Display *display;
  1493. X    Window window;
  1494. X    int i;
  1495. X#endif
  1496. X{
  1497. X    static int slide = 0;
  1498. X
  1499. X    /* Draw the ball birth at the new position */
  1500. X    MoveBallBirth(display, window, paddlePos, 
  1501. X        PLAY_HEIGHT - DIST_BALL_OF_PADDLE, slide, True, i);
  1502. X
  1503. X    if (frame == balls[i].nextFrame)
  1504. X    {
  1505. X        /* Next slide thanks */
  1506. X        slide++;
  1507. X
  1508. X        /* Frame that will trigger the new slide */
  1509. X        balls[i].nextFrame += BIRTH_FRAME_RATE;
  1510. X
  1511. X        if (slide == BIRTH_SLIDES)
  1512. X        {
  1513. X            /* Erase the ball birth image */
  1514. X            MoveBallBirth(display, window, 
  1515. X                paddlePos, PLAY_HEIGHT - DIST_BALL_OF_PADDLE, -1, 
  1516. X                True, i);
  1517. X
  1518. X            slide = 0;
  1519. X
  1520. X            updateBallVariables(i);
  1521. X
  1522. X            MoveBall(display, window, paddlePos, 
  1523. X                PLAY_HEIGHT - DIST_BALL_OF_PADDLE, True, i);
  1524. X
  1525. X            ChangeBallMode(BALL_READY, i);
  1526. X
  1527. X            /* This frame will trigger the auto shoot off the ball if you
  1528. X             * don't press space within a specified time 
  1529. X             */
  1530. X            balls[i].nextFrame = frame + BALL_AUTO_ACTIVE_DELAY;
  1531. X        }
  1532. X        else
  1533. X            MoveBallBirth(display, window, 
  1534. X                paddlePos, PLAY_HEIGHT - DIST_BALL_OF_PADDLE, 
  1535. X                slide, True, i);
  1536. X
  1537. X        if (paddleIsMoving())
  1538. X            updateBallVariables(i);
  1539. X    }
  1540. X}
  1541. X
  1542. X#if NeedFunctionPrototypes
  1543. Xint GetBallMode(int i)
  1544. X#else
  1545. Xint GetBallMode(i)
  1546. X    int i;
  1547. X#endif
  1548. X{
  1549. X    /* Return the current state of the ball */
  1550. X    return balls[i].ballState;
  1551. X}
  1552. X
  1553. X#if NeedFunctionPrototypes
  1554. Xvoid ChangeBallMode(int newMode, int i)
  1555. X#else
  1556. Xvoid ChangeBallMode(newMode, i)
  1557. X    int newMode;
  1558. X    int i;
  1559. X#endif
  1560. X{
  1561. X    /* Change the ball mode */
  1562. X    balls[i].ballState = newMode;
  1563. X}
  1564. X
  1565. X#if NeedFunctionPrototypes
  1566. Xstatic void SetBallWait(int newMode, int waitFrame, int i)
  1567. X#else
  1568. Xstatic void SetBallWait(newMode, waitFrame, i)
  1569. X    int newMode;
  1570. X    int waitFrame;
  1571. X    int i;
  1572. X#endif
  1573. X{
  1574. X    /* Set up the ball waiting loop */
  1575. X    balls[i].waitingFrame    = waitFrame;
  1576. X    balls[i].waitMode         = newMode;
  1577. X    balls[i].ballState         = BALL_WAIT;
  1578. X}
  1579. X
  1580. X#if NeedFunctionPrototypes
  1581. Xstatic void DoBallWait(int i)
  1582. X#else
  1583. Xstatic void DoBallWait(i)
  1584. X    int i;
  1585. X#endif
  1586. X{
  1587. X    /* Once the waiting frame is reached then activate new state */
  1588. X    if (frame == balls[i].waitingFrame)
  1589. X    {
  1590. X        balls[i].nextFrame = frame + 10;
  1591. X        balls[i].ballState = balls[i].waitMode;
  1592. X    }
  1593. X}
  1594. X
  1595. X#if NeedFunctionPrototypes
  1596. Xint AddANewBall(int x, int y, int dx, int dy)
  1597. X#else
  1598. Xint AddANewBall(x, y, dx, dy)
  1599. X    int x;
  1600. X    int y;
  1601. X    int dx;
  1602. X    int dy;
  1603. X#endif
  1604. X{
  1605. X    int i;
  1606. X
  1607. X    /* Add a new ball to the balls array */
  1608. X    for (i = 0; i < MAX_BALLS; i++)
  1609. X    {
  1610. X        /* Is the ball free for us to use? */
  1611. X        if (balls[i].active == False)
  1612. X        {
  1613. X            /* Make sure that it is clear */
  1614. X            ClearBall(i);
  1615. X
  1616. X            /* We have found a new ball spot so setup the ball */
  1617. X            balls[i].active = True;
  1618. X            balls[i].ballx     = x;
  1619. X            balls[i].bally     = y;
  1620. X            balls[i].oldx     = balls[i].ballx;
  1621. X            balls[i].oldy     = balls[i].bally;
  1622. X            balls[i].dx     = dx;
  1623. X            balls[i].dy     = dy;
  1624. X            balls[i].ballState = BALL_CREATE;
  1625. X            balls[i].slide     = 0;
  1626. X            balls[i].nextFrame = frame + BIRTH_FRAME_RATE;
  1627. X
  1628. X            return i;
  1629. X        }
  1630. X    }
  1631. X
  1632. X    /* No more free balls available */
  1633. X    WarningMessage("Cannot create a new ball - all active.");
  1634. X
  1635. X    return -1;
  1636. X}
  1637. X
  1638. X#if NeedFunctionPrototypes
  1639. Xvoid ClearBall(int i)
  1640. X#else
  1641. Xvoid ClearBall(i)
  1642. X    int i;
  1643. X#endif
  1644. X{
  1645. X    /* Clear out the ball structure */
  1646. X    balls[i].waitMode             = BALL_NONE;
  1647. X    balls[i].waitingFrame         = 0;
  1648. X    balls[i].lastPaddleHitFrame = 0;
  1649. X    balls[i].nextFrame             = 0;
  1650. X    balls[i].newMode             = BALL_NONE;
  1651. X    balls[i].active             = False;
  1652. X    balls[i].oldx                 = 0;
  1653. X    balls[i].oldy                 = 0;
  1654. X    balls[i].ballx                 = 0;
  1655. X    balls[i].bally                 = 0;
  1656. X    balls[i].dx                 = 0;
  1657. X    balls[i].dy                 = 0;
  1658. X    balls[i].slide                 = 0;
  1659. X    balls[i].ballState             = BALL_CREATE;
  1660. X}
  1661. X
  1662. X#if NeedFunctionPrototypes
  1663. Xvoid ClearAllBalls(void)
  1664. X#else
  1665. Xvoid ClearAllBalls()
  1666. X#endif
  1667. X{
  1668. X    int i;
  1669. X
  1670. X    /* Clear all the balls in the balls array */
  1671. X    for (i = 0; i < MAX_BALLS; i++)
  1672. X    {
  1673. X        /* "Clear the ball" - in an American accent */
  1674. X        ClearBall(i);
  1675. X    }
  1676. X}
  1677. X
  1678. X#if NeedFunctionPrototypes
  1679. Xvoid HandleBallMode(Display *display, Window window)
  1680. X#else
  1681. Xvoid HandleBallMode(display, window)
  1682. X    Display *display;
  1683. X    Window window;
  1684. X#endif
  1685. X{
  1686. X    int i;
  1687. X
  1688. X    /* Loop through all the balls */
  1689. X    for (i = 0; i < MAX_BALLS; i++)
  1690. X    {
  1691. X        /* Only handle active balls - sounds disgusting! :-) */
  1692. X        if (balls[i].active == True)
  1693. X        {
  1694. X            /* Switch on the state of the ball */
  1695. X            switch (balls[i].ballState)
  1696. X            {
  1697. X                case BALL_POP:        /* Ball pop animation */
  1698. X                    AnimateBallPop(display, window, i);
  1699. X                    break;
  1700. X
  1701. X                case BALL_ACTIVE:    /* Animate the ball normally */
  1702. X                    if ((frame % BALL_FRAME_RATE) == 0)
  1703. X                        UpdateABall(display, window, i);
  1704. X                    break;
  1705. X
  1706. X                case BALL_READY:    /* ball created and waiting to move */
  1707. X                    if (paddleIsMoving())
  1708. X                    {
  1709. X                        balls[i].ballx = paddlePos;
  1710. X                        balls[i].bally = PLAY_HEIGHT - DIST_BALL_OF_PADDLE;
  1711. X
  1712. X                        MoveBall(display, window, balls[i].ballx, 
  1713. X                            balls[i].bally, True, i);
  1714. X                    }
  1715. X
  1716. X                    /* After a certain number of seconds fire off anyway */
  1717. X                    if (frame == balls[i].nextFrame)
  1718. X                        ChangeBallMode(BALL_ACTIVE, i);
  1719. X                    break;
  1720. X
  1721. X                case BALL_STOP:        /* Ball dead and stopped */
  1722. X                    break;
  1723. X
  1724. X                case BALL_CREATE:    /* Create ball animation */
  1725. X                    AnimateBallCreate(display, window, i);
  1726. X                    break;
  1727. X
  1728. X                case BALL_WAIT:        /* In wait mode waiting to change state */
  1729. X                    DoBallWait(i);
  1730. X                    break;
  1731. X
  1732. X                case BALL_DIE:        /* Ball is going to die */
  1733. X                    if ((frame % BALL_FRAME_RATE) == 0)
  1734. X                        UpdateABall(display, window, i);
  1735. X                    break;
  1736. X
  1737. X                case BALL_NONE:        /* Really cool mode ;-) */
  1738. X                default:
  1739. X                    break;
  1740. X
  1741. X            }    /* Ball modes */
  1742. X        }    /* If active */    
  1743. X    }    /* For loop */
  1744. X}
  1745. END_OF_FILE
  1746. if test 43559 -ne `wc -c <'ball.c'`; then
  1747.     echo shar: \"'ball.c'\" unpacked with wrong size!
  1748. fi
  1749. # end of 'ball.c'
  1750. fi
  1751. if test -f 'bitmaps/exblueblock1.xpm.uu' -a "${1}" != "-c" ; then 
  1752.   echo shar: Will not clobber existing file \"'bitmaps/exblueblock1.xpm.uu'\"
  1753. else
  1754. echo shar: Extracting \"'bitmaps/exblueblock1.xpm.uu'\" \(1419 characters\)
  1755. sed "s/^X//" >'bitmaps/exblueblock1.xpm.uu' <<'END_OF_FILE'
  1756. Xbegin 644 exblueblock1.xpm
  1757. XM+RH@6%!-("HO"G-T871I8R!C:&%R("H@97AB;'5E8FQO8VLQ7WAP;5M=(#T@
  1758. XM>PHB-#`@,C`@-"`Q(BP*(B`)8R!.;VYE(BP*(BX)8R`C-#DT.3DX.3A&1D9&
  1759. XM(BP*(E@)8R!B;'5E(BP*(F\)8R!M961I=6T@8FQU92(L"B(@("`@+BXN+BXN
  1760. XM("`N+BXN("`N+BXN("`N+BX@("XN+BX@("XN+B`@(BP*(B`@+BXN+BX@("`N
  1761. XM+BXN("`N+BXN("`N+BX@("XN+BX@("XN+B`@+B`B+`HB+BXN6%@@(%A86%@@
  1762. XM("!86%A8("!86%@@(%A86%@@(%A86"`@6"YO("(L"B(N+B`@(%A86%@@(%A8
  1763. XM6%@@("!86%@@(%A86%@@(%A86"`@6%A8("!O(BP*(B`@6%A86%@@(%A86%@@
  1764. XM(%A86%@@(%A86%@@(%A86"`@6%A8("!8;V\B+`HB+BY86"`@(%A86%@@(%A8
  1765. XM6%@@(%A86%@@(%A86"`@6%A8("!86%@@("(L"B(N+B`@6%A86%@@(%A86%@@
  1766. XM(%A86%@@(%A86"`@6%A8("!86%@@(&]O(BP*(B`@6%A86"`@(%A86"`@(%A8
  1767. XM6%@@(%A86"`@6%A8("!86%@@(%A8;V\B+`HB+BY86"`@6%A86"`@6%A86"`@
  1768. XM(%A86"`@6%A8("!86%@@(%A86%@@("(L"B(N+B`@6%A86"`@6%A86"`@6%A8
  1769. XM6"`@6%A8("!86%@@(%A86%@@(&]O(BP*(B`@6%A86"`@6%A86"`@6%A86"`@
  1770. XM6%A8("!86%@@(%A86%@@(%A8;V\B+`HB+BY86"`@6%A86"`@6%A86"`@6%A8
  1771. XM("!86%@@(%A86%@@(%A86%@@("(L"B(N+B`@6%A86"`@6%A86"`@6%A8("!8
  1772. XM6%@@(%A86%@@(%A86%@@(&]O(BP*(B`@6%A86"`@6%A86"`@6%A8("!86%@@
  1773. XM(%A86%@@(%A86%@@(%A8;V\B+`HB+BY86"`@6%A86"`@6%A8("!86%@@(%A8
  1774. XM6%@@(%A86%@@(%A86%@@("(L"B(N+B`@6%A86"`@6%A8("!86%@@(%A86%@@
  1775. XM(%A86"`@(%A86%@@(&]O(BP*(B`@6%A86"`@6%A8("!86%@@(%A86%@@(%A8
  1776. XM6"`@6%A86%@@(%A8;V\B+`HB+BYO6"`@6%A8("!86%@@(%A86%@@(%A86"`@
  1777. XM6%A86"`@(%A86&\@("(L"B(@;R`@;V]O("!O;V\@(&]O;V\@(&]O;R`@;V]O
  1778. XM;R`@;V]O;R`@(&\@(BP*(B`@;V]O;R!O;V\@(&]O;V\@(&]O;R`@;V]O;R`@
  1779. X/;V]O;R`@;V]O("`B?3L*
  1780. X`
  1781. Xend
  1782. END_OF_FILE
  1783. if test 1419 -ne `wc -c <'bitmaps/exblueblock1.xpm.uu'`; then
  1784.     echo shar: \"'bitmaps/exblueblock1.xpm.uu'\" unpacked with wrong size!
  1785. fi
  1786. # end of 'bitmaps/exblueblock1.xpm.uu'
  1787. fi
  1788. if test -f 'sounds/whoosh.au.uu' -a "${1}" != "-c" ; then 
  1789.   echo shar: Will not clobber existing file \"'sounds/whoosh.au.uu'\"
  1790. else
  1791. echo shar: Extracting \"'sounds/whoosh.au.uu'\" \(10674 characters\)
  1792. sed "s/^X//" >'sounds/whoosh.au.uu' <<'END_OF_FILE'
  1793. Xbegin 644 whoosh.au
  1794. XM+G-N9````"```!X/`````0``'T`````!``````````!G7U5555==9W?GX]O7
  1795. XMU=/1S]'/T=/=W^/O__]W=___=W=O9V=?7UU?7V-G;W=W=W=W=W=O;V]W_^??
  1796. XMU]73T]7=X_=W9UU;5U5555=75U=755-134Q+3$Q/45-;75]?7V-C8V=G;W?O
  1797. XMY^/7U=/3V]_G_V]C7U]?7V-C8V=W__?OW]W7U]75U]_G_V]C75M;75]C9V]O
  1798. XM;W=W]^?CW=O;V]W=W]_CX^/CY^____?W]_]W9U]=5U555UUO=^/=U\_/S]/7
  1799. XMY_]C75U?9_?GW]O;W^/GY^?=V]77V^/W8UU75UMG__?CX]_=W>/G_W=?75M;
  1800. XM5UU;6U]=6U=776/_[^/7T]/7W>__9V-?7U]?75M755-355M=9V______]^_O
  1801. XMX^/?W=O7U]73T]75U]O;W=W=W=_C[_=O9V=O]^_CU=/1T=7C]V-=6U=;;_??
  1802. XMT<S*R\W?]UM33$M*2TQ/45-76UM=75]?7UU=55-/45%145534U-56U]O__?=
  1803. XMV]'1U=_W5U%,1T9&25%;9^/=U=/3U=?C[W=;4TI&14-$2D]OY]O+R<;&RM?O
  1804. XM54Q&0$!&2U?=S<"]O;_#S]MO755/3T]355]G[]W3RL?'R<O;[U5+13X^0493
  1805. XM7W?;T\S*R\W3[V]=34I'24M;=]7/S,_3[V=134M+35UOY]?3U=OG75-+2TM/
  1806. XM6^?7R\G*T]];3TQ,3U__X\W*P\'#RLW=X_]O9UM74U==;__CW]O5U=?;W^]W
  1807. XM7UM75U=;5U5555M?_^/=T<W*RLK,S]OC=U-*0#X]/T5CW\"[M[2UN\#-548[
  1808. XM.3D\/TI16_??U=/3U=OW;U5/2T='2TU5_^/+Q\7&RM/;XW=C5U-14U5C=^?C
  1809. XMW^/G9U]734I)2DU;9^/?U]73U=OG[_?W[_?____WW]O5T=/7W>-O74U+2DU3
  1810. XM=^/1S<S/UV=32C\_1$M5Y]7*R<K3XUU/24E*35%;7V]W;UU544Q/6V?WT\W%
  1811. XMP<#$R>]=1D`]/#U'47?$N[&PL+>]XU=&.3<X.TI=W\&\N+BZOL'/U^=?54U,
  1812. XM3U=?;__GW]_CY^_OY^/?U]?7W^-O75-+2DM+3$Q-55=?7V-C9^_=T\W/[V=7
  1813. XM14`\/3Y)4]7&O;>WO,'G6TH_/T!%2F_=P;RZNKS&S]];34`].SU`56_3S,G$
  1814. XMQ,S7]TM#/3U`3%7_Y]W3U=W?W]W7Q\"[O+[=5SDR+RTO/4_GO+:SM<#38SXZ
  1815. XM.#H]36/3S,O1V_]W=_?GU<_,T==O5TI)25OOQ+^\O;_1[UM%0#T^05W?O[NY
  1816. XMO,1G1S0P+R\S/TWWP;RXN;W3;S\[.3Q$[\^]O+N]OLG;8STV+S`V3]^ZM*^M
  1817. XMK;"VOU$]+2LM,3KGQK.OK:ZSR?]*-"\N,#=/Y[ZYM+2VOL=O448]/4E;W[ZY
  1818. XMM+6WO\;G8U-)1TQ3]]W5S,S+RL?%Q<;)S-OC7U=34UOCT\K`O\3)XV]=45%C
  1819. XM]]O*R=/O6T`\.#<X/45?Y\W,T>=G24,_/S]%2U%C8U-+1#T]2U_CR\K5YT]$
  1820. XM/3<W.3Q`6_?-S='=W^?O=UM334Q)24E-4V_GT\"]N;S!=TLW,S(Z1-/`NK:Y
  1821. XMS/\_.SH^1]O&O;>VO<K=4TM+45_3R</$R=OG7U-)2U?1Q+>TL[>\WUM)/S]*
  1822. XM6^>_N:^MK[.\=TL\/#]CU;FTLK>\S^==0SY$5=VYM+.VRN=3/#<W.CU;V[FQ
  1823. XMK[2^2SLT,SA,_[ZZN<;723\[-C=!4^._O<#&S?]703T\/#Y,7\S$P<SG13T[
  1824. XM/$!;[]7,S_=C540^.CP_4V/W]W=C5TQ)2DQ1;^_7U=7?;TM&1TM*1D9*35OC
  1825. XMT\2_O\SG1D%&8^?5T]7G8T5!16_;RLK,RL2]OLW?_U]51T5&7^/,S,_?W]?3
  1826. XMV]W;S\S3XV]?9_?_;UU=[]W;8T]`/T1=Y\?%RLW3YW=323\R,#0[2[ROIZ>K
  1827. XMP?\W,2XT.E'WQ;^_Q<K'O[R\O]UG4T4^.SY+R\"^Q-WW=]O-S]OO5U%,3U_)
  1828. XMO[BZOV]*0TQCS\S-S='7W^/5P;_`U5\^/43?S,G/WUM58_?/S]-?1S8W/>_1
  1829. XMRM/W3$I7_]?#P,?58T`_5?_/T=UC4TM-6\_$O;_+5TI$1DI355M755533$_?
  1830. XMS\K3[T4].T!+U\O%R]=-1417=]_C]_?CU]7/T=U+0#T_1M?'Q<S=W]7-T]WO
  1831. XM]U%%/T55R\#!RMU14^?7U=W?9U%)1$S;S<S1W5]7=]W5W>]/1#PT-4S7O;&S
  1832. XMRE]`-SQ7[]'1W4H]-SD_[\2QL+?W2CY#3-W*OL'-0S@Q--VWJJ.GQE=`15^\
  1833. XMMK7'72XI)S5;JJ.CJKI%/$WGR[^_YTDW+2Y$W[ZMK;?#WTI&35W*P\5=138T
  1834. XM.5?;O[Z_TU\^/T?+O+F^7TI!04O;S,O;[V?_X]/1T]77W]W)R=%C445'X\:Z
  1835. XMM[]'.3,V/=_$O,#-2STY5\FOL+I).30W/413U<S)Q\GO5T5%3-W+Q\O52CPV
  1836. XM.$EGU;^_W5,_-SS_R\//8SDS,CQ1O;>VS%$[/F_1Q<GG03T]3_^\M;.]RD`V
  1837. XM,T!;O;B_T7='2^/+O[[)=V-C=^?1U=OO_]?/TU]/3$U-8\^\O=MO8]W-Q]'G
  1838. XM341`3]VYM[K!VSXW/$K&O+K35SP[/7?%KZ^U]T4Z0_>ZOU$].CU&W\JXL[+-
  1839. XM1"LL,>^\K[?&/S4M,#S&MZRN;S,G*C:_KZJTT3`K*C[7K["Z7T4U-4S;OK2W
  1840. XMXTH^3/_!O;N_RLO%P\KG0#U`_\JUL[O+;TE-Y\_#MK*SO><T,4S'LJZ\.C`Q
  1841. XM7[ZJJKWC3#P\2EWCO[W30RXG+&.ZJZ:K8S,E)BI7OZZRO$LZ-CQ%_]_C[]O)
  1842. XMRUT_-#[?KZ_W/"\P0;:MKLQ/-#E+MZ^WQ.]$/SY#8\^\L;E&-"TQ/KROK<=!
  1843. XM*2LTX[RNL;I?/3$T2_?*O<'W3#]%6UM)0TI3]^=O6_]O7V/=YTU+X\K`Q_\^
  1844. XM.30\5[V\NN]!/$==Y^]?=[BMK<%G+BTVO:^MM]TX-#I$;\#`P+NZXU-*8[RW
  1845. XMN?=*.SH\6^?!NKG+UU]+04!)RL#?5TQ==V=52S]*O;2RP6,Q+2LW5;FXO-M/
  1846. XM,RX[4]&MI['10"\S/CLS,3?1L*BT72XU2KBMK+D^.46_OSTN*3;5GY^F/2T_
  1847. XMQ:ZIL3HM0\RWON<]/#_,NK?#=V/'MK[O,2[GM*N_/R0HW[>NL\HT-#W=S4T]
  1848. XM/6/1MK?#-S%/P*RQQS$O9\S+_U?=P[R\O^]53$I%9\J^O\_=S^=OW[S#23P[
  1849. XM=\O!YSTH++NIIL8^*"Q`KJK3.2DP4[2W1#`M5[RLMF\F)#[!K:ZW6T?OQ+FY
  1850. XMS38V0+RROV<\+CJLH9^MT2\P/+^V_SPU1=&NLC\O+=.LH:O&*RA)S+W;1"TO
  1851. XMW[:LL<TO+SN\L;?%_TM155OCO,$Z-#S`MKK1/4E?9W??W\W%9RTO3:BL2S$L
  1852. XM-E.WO]M=54E,2U=?/"XM0[^KM3HK*LVKHZS-)B-%OZRPOU55R]'_S+:NN<Q#
  1853. XM/\>VN3<L.$S5KZNSP#@L+;FGK<9+.C_1QM\W-TM3]]MW5V^\O,/-VSDS-]O$
  1854. XM7SDN1L;#_TH^/__#M[7#/T!*0#Q&X]-72KRRQD4O-TG-XTQ+6]&WK<1%,4:O
  1855. XMK;D\-^/75T!%R\=G-CVZKZ]?/%>]J*W,+3/!ON,V1J^MQR4GO*NL8SI'S;W!
  1856. XMS-W%MLE'.%NUM]<F)[:FJ4<VQ[2]+2S%K:WG+2]/T=/C/#^PKL$I)ZZ?GRT?
  1857. XM+<:GLDHO3;.WR2XEYZZM/"DQRJS-+R0SQJN_+2T]L*Y`)2(_LI^K)B`INK-7
  1858. XM-S2_L>-&/].XM]TJ)S"KH]\S*DO`P6]&T;:IKLHY/KJKIV<J+5NLLV\V0;BQ
  1859. XMO#@TOJVJVT_-LZJS=RLTN;3#047G]U=&0T%,W;J\Q,G*S\I*/T6UKLU,X[R_
  1860. XM03DV/$R^O$H\/#Y?KKM!*T>?H;DM-[FR[T0]1TI$4<W'2D^XKCDI3*Z@QR\E
  1861. XM-ZNLQ2DK2]6_]T=`_[R_53$[8\#5-RLJT[7).B(E.:2H+2(EQ:NGO3PG,+6K
  1862. XMKD$O-U_,33QWM[/,1C$]MZNM0S5)V\3,WT1`254\U:ZFK;])2;RNL3@MOZ6A
  1863. XM020WOZ:O6RU$L*6].E^NN5])=T='S*FV)28]H9\X'Q^NGZXU*D6_NMU;6SPY
  1864. XM4^-!.[^VYU,V)S2OL<E#/SI=LKY=,S>_LKL]XZ^]13=!2TM,15WG04"]J,DZ
  1865. XM/\JMK-<U2LJ_6SI1]]_59SHM,5^@H4PS/:RGO$H\44]1RL1/1;W$9R$?2Z>?
  1866. XM6R$FO9^N+B%'K-<L0[BWUTTN-\Q*,TF_O%$T;[31,B0RR<!+SZRDN4\N1+FZ
  1867. XM0R<TO*6V+S+5QW=`]\3+T;*LK<TYW:_&/"H]S]<^.LFPU4I`7;ZGM$-)Q:W7
  1868. XM/=_3.S-'U<4X,,.HQ3,G6[.GK\7=S+7*/4?G/S0S6\'`W4-#Q,MG47?CQKNM
  1869. XMN5W#I[%**2I&M+??+BY5UUW!N2LDOZ*A-2+GHY\K'[&?J"T]L[]CV\U;031-
  1870. XMN:_7*R]3M,LM,%6ONB\\O**P-3^HK,HX9[9?,#+?L,P[3\#!,"7WO.=&0$S,
  1871. XML<4^1D8\T<TS(3-W/3EGKDDL=[A3+C;5L[I3/<NW73O=P&<R'S"VJE\I4:]-
  1872. XM-3ZONCCGHZ;`/N===\N]/1]3HE$FX[M3)T:JNN=&0[.N-"S_J<PK/U=+M[L]
  1873. XM-*BK'Q\[J?\\T?=O[T0WO::B/D"YO<M'W;"V]S<_NKY)-TNZP3,L,TMCM+&Q
  1874. XMK;(Y,4VDJBTL]Y^L)"5`GZHG*;VIJ"\DQJJCS3DS=[:Z.RE*MO\D*Z[=(B6?
  1875. XMH%<^3%$VN;',U;A?/STV34`[1%'-YRU;I)]G3+NZQN_71=6NNG=&+BZUP#,S
  1876. XMN:>J)BJRNLQWT[EW-K2A/"`II:TM+#6IL1\GHJA!)>^^74?*OS,[P+/_*$^P
  1877. XM1$7,Q+T]/,WC-3_7J[7&M+I5S]<[0Z7W+=W+/TRDKRPV9T4ES*JM7=M'6\17
  1878. XM-\2IIRDCK[1+(D6GQ"@ZVRHOK<,K15\L+3V[J,1)1;RO0"WON<<ZS+\V'V.P
  1879. XM.RT^J;4?'_^?JBI1L[G=+#Z?L#FXGR0?'Z>K*2O*H+P?*;RG5R5!K[!O/$2Z
  1880. XMO$^^KRXO-[2@6R,FGY\B(KV?P"9)JN<N+CJCI.<WP-LT+*>?+A\EGY\?'[V?
  1881. XMPR]1L+T_*-V?JCK-O"PJ3Z2E-S!7YSTK0:W3+*^E24M7,L6?ORK;LCHR0[[)
  1882. XM+C3_USHVR4PH+J&^*<:G/"ROQA_CGS(A5:DW)\:DLUTJ.3`QQM$YNJRV1"Y`
  1883. XM,A^TG\!*_[YW/$.\RDHO+LJ_7RT]JJW*0U'$0",VKI_'*K>K.5W`1CM1/;>]
  1884. XM/24\K*U;,SJJMS8G2:3/O*2^(-&K3$J\S,G,Q3`LQ*_#3-=#S:=W*K.TQ;-=
  1885. XM+=6NOK^\][R^2C?WKETJK*H?++#7*::G/<"Z-.>I4RNMLR0UPS$IH:TFQJ$P
  1886. XM,4UG8[.O,\RG(B*?M!_-GR<?.:-O*M^D*A_7I2,JOS\_N5$Z+C.WQT7ON2LJ
  1887. XM1,0X-MVBLRLK8U4X;_<PI*I'-/_C06.WL\IWYV]/3+:J_SFHJ"O;K\$]4:^?
  1888. XM/"GG]]U?0*6?M4M?1<6HW2^UW2XYVV>^YW=&G\8?(N?#)4R?MR@WND/#K;7&
  1889. XMMB,@.;Q?M+3O,32\S!^VGQ\?GZ`_YZMGO\$[J#H?-+QGT;_%.&\W-JU,.I^C
  1890. XM'T>D+2.]/3&S0SW`R4?+*C2EQC&DJSFOL<JZ4RHEO4\XRZDV):W?']^NS#HB
  1891. XMIJ$?9Z,O)ZTQN*`])K&IVTNEMB?GLR@DIJ<F*3HX+4W*NE?'5S=7KRX]GY\C
  1892. XMP%,?)I__)W>D0R&S3"]GQ3H[J4`EQ=%'1T2I13VHOS-7K<,V5;]W5[=;.6//
  1893. XMP,6\,RRZ/B2VK6<SQJNGS[!+,UW&Q?^TGRTFI*TLJY\H1*4K'Z*G*"JKS".H
  1894. XMG]TTGTTJXZ*Y4:R\2BJIL3J?GR,FM#A3.2V^VTH^3[JJS,>I-S3?03:\+V=&
  1895. XM++:M/#-/+V,J'T5O.B9/IRHSG[\ZS+\?(I^_)$:I+#&O)T]-'RNW2_=3ST$L
  1896. XM1%?!M7>]J"0PM[!-/Z&G+;LM.:LA*Y\T*[?-KSTMJ*W*GR@\JU$_T==WN3F[
  1897. XML^]#M#-+I#<G-;V\1BK;KK6D_R=+N,#7132T*A^?Y^>G/&.VPSHK9ZU;.RS'
  1898. XMK-O=*T6M8ZLI.;/?*9]7R;2^Q^.NIU5#GUU*43*K=\3/0_^SJB(?M3TLI[0O
  1899. XMQ\]`1D2CL?^TO;#_.+"VOZ['2V?'Q$=!9S,HXR_%M*XM)Y^_'[JK+;TA.K#$
  1900. XMQ]5O1U\T57=*O3E?_\PS0+4L)I]O'^_3,V>V16>LRL-1Y\-W,\7!R]6W+)^Q
  1901. XM/K;W-,0Z'Q^_XT2WNRFP+/^J-L0ZM[6XJW=)+^^WP#@],\0OP20HS3`JL*^J
  1902. XM*S6[W:`C=[`MISHHK42KNB^X.:RF,+2Q,\J],JRK*:VC,)^G*[2]-[DQJJHW
  1903. XMJR-CP#O**4;W,2ZL-E6OOMNJ*"3!-C!`(#RQ/:$O'Z(YI[9+73P^M#\M3[0?
  1904. XMHZDZH=LZI:E?SSR?HRJI+2*BL+E,NC/_[[[%)=VB.;@Q2JT@UZFG/#Q1P#]5
  1905. XM1[DOO<1/2ZPJL.\LQ3"]0:TI'Y\S,I^N_\RYS%5G[[Q!,:RA+%?#44?_KJXA
  1906. XMGQ\ORQ\S.A^?3Q^?M+B?42^D(#2LJV^\OS^IPZSO+;FS+:HL/Y\F,$L?/<<M
  1907. XMGTDEMJ$?KLO3/*<?GSE7/Q^KO+4NO4==KR!1."KO+K@]2;?#-MTMG[DZ]T&_
  1908. XMO;IGO#JCJ"FD'U-)'V?/MR1)P3&?'[>?'[RJ0S<VST\NY[0TU:0NJL/)GQ\W
  1909. XMH2FL'R*R1KE#N\0M,;G&-,R?(O='+UW32Z:?+)^A'SBW.$\O)]U,,=_WVSHH
  1910. XMO\.HG_];1,4UK"/5NJ\US*PSXU<SLSA?LZ8@HY\HNZ\K1Y^H-KI;K[V](<=/
  1911. XM54VJ4:^Y/2VZ/#R?RA^A6]?;Y[8GGT,?M"^]I3FNQZ^L+Z-7O"RB.2YG/M_7
  1912. XM[[8?I-6Q]S>C.+-7([VD5U-GJJ0K3;<G,V<[RC!#/#>A11^?=Y]='Y_?KJY5
  1913. XM8ZM;RS_WJ3.VNA_,5Q^HL3&LM"K`OCBO1=<N.J8S3:;1RRHT6Q_$-B_)'TFJ
  1914. XM(\O#.:N?'S^GQJ[_H2BSRZX?J,#,33BBRBB?;U'`))]!O.<UM<0J(J\I7V^U
  1915. XM2B[+N?\NM&=-*CT[HBX\(2NVWZ=,VRVXGR3&);>P4Y_/WR^Y-\DH/S3_*LGW
  1916. XMHSJQ/*Q#S]V]+3FH(">N'[PC3+O/S4R?,+5-1"2],[$W-"?+-JJN/#.C3Q^A
  1917. XM.K#)-[TGL[GOO4^?NF>V+4^V+D2K+9\LI\>L6TG_L"0PS:\W.JTCJ=^^.N<E
  1918. XMIA^I'RXH+:93LJ=?I:V^4:=*I#S5I4FOLT<M3#]OOZ0PGT^J=S&G/)\ZK:;/
  1919. XMLR>?'Y\J1Q\M/;\YM,S#H25)*:<BITM%+<I%G]VM'ZT[K!_`*">H/[#!-$/G
  1920. XM7\VP.;4ZP]&X*R-/+T:KW<2S,SPZ)[0?-RNUGRJ?,JJ_MO_$MBBI'Z$?S1]?
  1921. XM(2<H;[6\GQ_*IB6?'[J@MZ0UJF^\+J$F/&,X-3E5K+1)MB!);SDXGZ@MK[Y1
  1922. XMIN-!HS&?'Y^M-,:O-3:G+;G_'Y_$L\6X*+DV2LO#.>/%+-&MJK=3GU6@7_^M
  1923. XM[[35IB\N1B1/W\?ON"RJ._]3O[8TJ[8LM[:?)==/IV,RRL5CQ#\L(ZVU,RFC
  1924. XM]Z@?HZF_I"ZHL%=*+\H[K[%+NJNV.3<_T2;3+S`NIK*WN+:IU3>T+\^L)+TS
  1925. XM[RE,T5?5T;XC7S"Q*[`A3S`PMDV?49\LVRJ_12M=++P?J3B?+TPO(*OWV^_?
  1926. XMHK\JMR:?,BDAQCA)JS5-Q]M*K\G**B<V.[Q7P!_?1+?/=S"?4ZTR+\=,)BNB
  1927. XMO:NI*\8R(T35,[@CH2NR)JDZ+K<XUQ^S,:\WN#"TP<U&*<9CIJNSK[\^'T\A
  1928. XM41^PJ$"^KRY?)ZTK'Y\QI""?T;=!-DT]JZS!1\0K1[8?GS6[+2NV'[U7OK$U
  1929. XMJ^-ON;2D0:X?H3.LJ]&L*B=G*D77JBR?/3XQ+:9?N$^@,R\YI3PU*3Q&43BE
  1930. XMO2VI=[;5()_;MB_&+D5$,2!;19_GP:EO-MVX+SDSGT/1(6_'RZO-5SHL,Y^S
  1931. XMII]GK4Q5+3/3KJD]2C8?PS\]2\:I-;HC,#XAI\>N[Z(ZK3NL*I\?H3F?QZ4M
  1932. XML2&?,9\OGR7-;Y^E6[_$9SD^NC`W+D0X0#,AN\6MNO?-U2JHJD6H=[(BMCJ?
  1933. XM1"*LP,V[.M]/U1_/0[G$)[(DH3VK/>>],#9O(39*)+^VP;^ZMB/$;T^?)Z8P
  1934. XML1^PO*?%'T`?L4O![[2\V],L+"Q?,U&H3Y\L+"51,5-=.<=C*$`PK5NL+ZLM
  1935. XMJT:JO$4VR3TZ3"VD2K`LX\$?1ZU=I<<Y3='1+#0?J*^D-JH?OSJ?,,4EKS`T
  1936. XM5R[ONE\SN;.]=Y_+P*=7'[4GLJT\I$`J9UTV0UNBUS'?N":Q,;&]/=\@KZ>@
  1937. XM.J#*GS>C+T\@W4NF(3$R+K9+0+1,NQ\Q,#E=7;,IIS0?KJN?K".M-Y\DGQ^V
  1938. XM(*)&.TE)J%&G]T>_14^F+R<OJ3J?*J$C+LRTI+PX1[^^9ZXERC2D*5&BL[<S
  1939. XMWSU*.K0?MBI=*G=OJ$>F1L8Z+\`O=TPTW7=*25TJ1"?$*9\KP2=$--6G*</)
  1940. XM+KH?JRV\M+9!52G?3TK/*[/+L##O-*0T-RFLU[`V-/\NJ<>LP3TC6]?!OC*?
  1941. XM.6\QQ3O_1C9)TT2Y)CK5GRXT0<VV8TJLPT.M'ZLSJ;$Z4:U'NR31-T4[*ZAO
  1942. XM-ZRV,+/=*ZJUT1]`GRR?N"C)N*LD-JW+JT6YMN<PWR<WYV]5U2\_J3DIMRTT
  1943. XM*,LYLD;'P;^K']W'*KLJP%,H6ZM#M+I'.$FOH<HJ*RBK0RZ\1K8Z33HMKZ>M
  1944. XM)*NOJK,W/"=CT<TRJE^?I"M7+[8@31^^,\,S2JS`MC@J1C&TI=??JK0U3">C
  1945. XM34TH*36EYRK**UO)QB!;7;N_Q]]CQSJB)"TOOK8VMC^]HTF?RCPZN3K'(;K7
  1946. XM/)_3M2M5,TE/8^?CNM>[/"=CQ%NO,V.NRV<S+#*X.TMG+^-;3*8?GU_+.L=7
  1947. XM.E.S*L3`.=&VXU]+U48OT<1%,R[7-#_+N+ICO<$_4;PY.F.WJS;)_\VO,EW-
  1948. XM*\K,O[I?+$$WL,`Y-[RL*%]-N<RQN+V_.#ZH7['W7:S?N2KCRE=,O4#&O["W
  1949. XM*F?![R=`(;?3+4]CR\_#W=U)]S.N-DS'1*DZ-C'CW4`_K2[+QF/*0S:K-S;O
  1950. XM)]U#.4F^_^=-8]%,Q,EG/3L\.=/11N/)S&=,7SG?S4T^3$UC7\/GW<#_;U7)
  1951. XM/W=?6U.\X]VV2^]?;TO&5>=&RDG=/TOGQ5V]RE5=3$]=;^?376/3XT_?8TTZ
  1952. XMV]&_U4O/W4S?__=59^_325?;SV/5S=-56U]C;W?W]^_O[^_O[^_O[^_O[^_O
  1953. XM[^_O[^_O[^_O[^_O[^_O[^_O[^_O[^_O[^_O[^_O[^_O]_?W]^_W]_?W]_?W
  1954. XM]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W
  1955. XM]_?W]_?W]_?W]_?W__?_]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W
  1956. XM]_?W]_?W]_?W]_?_]__W]_?W]_?_]_?_]_?W____]_?_________________
  1957. XM______?_]__W__?W]_?_]_?W]__W__?W]_?____W___W________]______W
  1958. XM______________________________________?_]______W____________
  1959. XM______________?_]___________________________________________
  1960. XM___________W]_?W______?___?___________________________?_____
  1961. XM____________________________________________________________
  1962. XM___________________________________________________________W
  1963. XM_______W______?W______?___?_________________________________
  1964. XM____________________________________________________________
  1965. X@____________________________________________
  1966. X`
  1967. Xend
  1968. END_OF_FILE
  1969. if test 10674 -ne `wc -c <'sounds/whoosh.au.uu'`; then
  1970.     echo shar: \"'sounds/whoosh.au.uu'\" unpacked with wrong size!
  1971. fi
  1972. # end of 'sounds/whoosh.au.uu'
  1973. fi
  1974. echo shar: End of archive 9 \(of 30\).
  1975. cp /dev/null ark9isdone
  1976. MISSING=""
  1977. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 ; do
  1978.     if test ! -f ark${I}isdone ; then
  1979.     MISSING="${MISSING} ${I}"
  1980.     fi
  1981. done
  1982. if test "${MISSING}" = "" ; then
  1983.     echo You have unpacked all 30 archives.
  1984.     echo "Now execute sdecode.sh to build files."
  1985.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1986. else
  1987.     echo You still need to unpack the following archives:
  1988.     echo "        " ${MISSING}
  1989. fi
  1990. ##  End of shell archive.
  1991. exit 0
  1992.