home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume20 / xboing / part08 < prev    next >
Encoding:
Text File  |  1993-09-03  |  55.1 KB  |  2,149 lines

  1. Newsgroups: comp.sources.x
  2. From: jck@kimba.catt.citri.edu.au (Justin Kibell)
  3. Subject: v20i115:  xboing - a simple blockout type game, Part08/26
  4. Message-ID: <1993Sep3.123220.7219@sparky.sterling.com>
  5. X-Md4-Signature: fbd880999bdd8e9cb49eb1114b3529d4
  6. Sender: chris@sparky.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Fri, 3 Sep 1993 12:32:20 GMT
  9. Approved: chris@sterling.com
  10.  
  11. Submitted-by: jck@kimba.catt.citri.edu.au (Justin Kibell)
  12. Posting-number: Volume 20, Issue 115
  13. Archive-name: xboing/part08
  14. Environment: X11, xpm, color
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then feed it
  18. # into a shell via "sh file" or similar.  To overwrite existing files,
  19. # type "sh file -c".
  20. # Contents:  blocks.c2 highscore.c score.h
  21. # Wrapped by chris@sparky on Fri Sep  3 07:14:44 1993
  22. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  23. echo If this archive is complete, you will see the following message:
  24. echo '          "shar: End of archive 8 (of 26)."'
  25. if test -f 'blocks.c2' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'blocks.c2'\"
  27. else
  28.   echo shar: Extracting \"'blocks.c2'\" \(24327 characters\)
  29.   sed "s/^X//" >'blocks.c2' <<'END_OF_FILE'
  30. X                                    frame + EXPLODE_DELAY);
  31. X                                SetBlockUpForExplosion(r, c+1, 
  32. X                                    frame + EXPLODE_DELAY);
  33. X                                SetBlockUpForExplosion(r-1, c, 
  34. X                                    frame + EXPLODE_DELAY);
  35. X                                SetBlockUpForExplosion(r, c-1, 
  36. X                                    frame + EXPLODE_DELAY);
  37. X                                SetBlockUpForExplosion(r-1, c-1, 
  38. X                                    frame + EXPLODE_DELAY);
  39. X                                SetBlockUpForExplosion(r-1, c+1, 
  40. X                                    frame + EXPLODE_DELAY);
  41. X                                SetBlockUpForExplosion(r+1, c-1, 
  42. X                                    frame + EXPLODE_DELAY);
  43. X                                SetBlockUpForExplosion(r+1, c+1, 
  44. X                                    frame + EXPLODE_DELAY);
  45. X
  46. X                                /* Special effect where screen shakes 
  47. X                                 * during explosion 
  48. X                                 */
  49. X                                SetSfxEndFrame(frame + 70);
  50. X                                changeSfxMode(SFX_SHAKE);
  51. X                                break;
  52. X
  53. X                            case BULLET_BLK:
  54. X                                SetCurrentMessage(display, messWindow, 
  55. X                                    "More ammunition, cool!", True);
  56. X                                AddABullet(display);
  57. X                                AddABullet(display);
  58. X                                AddABullet(display);
  59. X                                AddABullet(display);
  60. X                                break;
  61. X
  62. X                            case BONUS_BLK:
  63. X                                IncNumberBonus();
  64. X
  65. X                                if (GetNumberBonus() <= MAX_BONUS)
  66. X                                    sprintf(str, 
  67. X                                        "- Bonus #%d -", GetNumberBonus());
  68. X                                else
  69. X                                    sprintf(str, "- Super Bonus -");
  70. X
  71. X                                SetCurrentMessage(display, messWindow, str, 
  72. X                                    True);
  73. X                                bonusBlock = False;
  74. X
  75. X                                /* Turn on killer mode after 10 bonuses */
  76. X                                if (GetNumberBonus() == 10)
  77. X                                {
  78. X                                    /* Turn on killer mode */
  79. X                                    ToggleKiller(display, True);
  80. X                                    DrawSpecials(display);
  81. X
  82. X                                    SetCurrentMessage(display, messWindow, 
  83. X                                        "- Killer Mode -", True);
  84. X                                }
  85. X                                break;
  86. X
  87. X                            case BONUSX2_BLK:
  88. X                                Togglex2Bonus(display, True);
  89. X                                Togglex4Bonus(display, False);
  90. X                                DrawSpecials(display);
  91. X
  92. X                                bonusBlock = False;
  93. X                                SetCurrentMessage(display, messWindow, 
  94. X                                    "- x2 Bonus -", True);
  95. X                                break;
  96. X
  97. X                            case BONUSX4_BLK:
  98. X                                Togglex2Bonus(display, False);
  99. X                                Togglex4Bonus(display, True);
  100. X                                DrawSpecials(display);
  101. X
  102. X                                bonusBlock = False;
  103. X                                SetCurrentMessage(display, messWindow, 
  104. X                                    "- x4 Bonus -", True);
  105. X                                break;
  106. X
  107. X                            default :
  108. X                                break;
  109. X                        }
  110. X
  111. X                        /* Reset to a non exploding block */
  112. X                        ClearBlock(r, c);
  113. X                    }
  114. X                }
  115. X            }
  116. X        }
  117. X    }
  118. X}
  119. X
  120. X#if NeedFunctionPrototypes
  121. Xvoid DrawTheBlock(Display *display, Window window, int x, int y, 
  122. X    int blockType, int slide)
  123. X#else
  124. Xvoid DrawTheBlock(display, window, x, y, blockType, slide)
  125. X    Display *display;
  126. X    Window window;
  127. X    int x;
  128. X    int y; 
  129. X    int blockType;
  130. X    int slide;
  131. X#endif
  132. X{
  133. X    switch(blockType)
  134. X    {
  135. X        case PAD_SHRINK_BLK:    /* Paddle shrink block */
  136. X            RenderShape(display, window, paddleshrink,
  137. X                paddleshrinkM, x, y, 40, 15, True);
  138. X            break;
  139. X
  140. X        case PAD_EXPAND_BLK:    /* Paddle expand block */
  141. X            RenderShape(display, window, paddleexpand,
  142. X                paddleexpandM, x, y, 40, 15, True);
  143. X            break;
  144. X
  145. X        case BULLET_BLK:    /* Draw a bullet shape */
  146. X            RenderShape(display, window, yellowblock, yellowblockM, 
  147. X                x, y, 40, 20, True);
  148. X            DrawTheBullet(display, window, x+6, y+10);
  149. X            DrawTheBullet(display, window, x+15, y+10);
  150. X            DrawTheBullet(display, window, x+24, y+10);
  151. X            DrawTheBullet(display, window, x+33, y+10);
  152. X            break;
  153. X
  154. X        case MULTIBALL_BLK:    /* Draw multiple ball block */
  155. X            RenderShape(display, window, multiball, multiballM, 
  156. X                x, y, 40, 20, True);
  157. X            break;
  158. X
  159. X        case STICKY_BLK:    /* Draw sticky block */
  160. X            RenderShape(display, window, sticky, stickyM, 
  161. X                x, y, 32, 32, True);
  162. X            break;
  163. X
  164. X        case RED_BLK:    /* Draw a red block shape */
  165. X            RenderShape(display, window, redblock, redblockM, 
  166. X                x, y, 40, 20, True);
  167. X            break;
  168. X
  169. X        case BLACK_BLK:        /* Draw a solid wall block */    
  170. X            RenderShape(display, window, blackblock, blackblockM, 
  171. X                x, y, 50, 30, True);
  172. X            break;
  173. X
  174. X        case GREEN_BLK:        /* Draw a green block */
  175. X            RenderShape(display, window, greenblock, greenblockM, 
  176. X                x, y, 40, 20, True);
  177. X            break;
  178. X
  179. X        case BLUE_BLK:        /* Draw a blue block */
  180. X            RenderShape(display, window, blueblock, blueblockM, 
  181. X                x, y, 40, 20, True);
  182. X            break;
  183. X
  184. X        case YELLOW_BLK:    /* Draw a yellow block */
  185. X            RenderShape(display, window, yellowblock, yellowblockM, 
  186. X                x, y, 40, 20, True);
  187. X            break;
  188. X
  189. X        case TAN_BLK:        /* Draw a tan block */
  190. X            RenderShape(display, window, tanblock, tanblockM, 
  191. X                x, y, 40, 20, True);
  192. X            break;
  193. X
  194. X        case PURPLE_BLK:    /* Draw a purple block */
  195. X            RenderShape(display, window, purpleblock, purpleblockM, 
  196. X                x, y, 40, 20, True);
  197. X            break;
  198. X
  199. X        case COUNTER_BLK:    /* Draw a frame of counter block */
  200. X            RenderShape(display, window, counterblock[slide], 
  201. X                counterblockM[slide], x, y, 40, 20, True);
  202. X            break;
  203. X
  204. X        case BONUSX2_BLK:    /* Draw a bonus x2 coin block */
  205. X            RenderShape(display, window, x2bonus[slide], 
  206. X                x2bonusM[slide], x, y, 27, 27, True);
  207. X            break;
  208. X
  209. X        case BONUSX4_BLK:    /* Draw a bonus x4 coin block */
  210. X            RenderShape(display, window, x4bonus[slide], 
  211. X                x4bonusM[slide], x, y, 27, 27, True);
  212. X            break;
  213. X
  214. X        case BONUS_BLK:    /* Draw a bonus coin block */
  215. X            RenderShape(display, window, Bonus[slide], 
  216. X                BonusM[slide], x, y, 27, 27, True);
  217. X            break;
  218. X
  219. X        case BOMB_BLK:        /* Draw a bomb block */
  220. X            RenderShape(display, window, bombblock, bombblockM, 
  221. X                x, y, 30, 30, True);
  222. X            break;
  223. X
  224. X        case DEATH_BLK:        /* Draw the pirate death block */
  225. X            RenderShape(display, window, death[slide], deathM[slide], 
  226. X                x, y, 30, 30, True);
  227. X            break;
  228. X
  229. X        case REVERSE_BLK:    /* Draw the reverse block */
  230. X            RenderShape(display, window, revblock, revblockM, 
  231. X                x, y, 33, 16, True);
  232. X            break;
  233. X
  234. X        case EXTRABALL_BLK:    /* Draw the extra ball block */
  235. X            RenderShape(display, window, extraball[slide], extraballM[slide], 
  236. X                x, y, 30, 19, True);
  237. X            break;
  238. X
  239. X        case HYPERSPACE_BLK:    /* Draw the hyperspace block */
  240. X            RenderShape(display, window, hyperblock, hyperblockM, 
  241. X                x, y, 31, 31, True);
  242. X            break;
  243. X
  244. X        case MGUN_BLK:    /* Draw the machine gun block */
  245. X            RenderShape(display, window, mgunblock, mgunblockM, 
  246. X                x, y, 35, 15, True);
  247. X            break;
  248. X
  249. X        case WALLOFF_BLK:    /* Draw the wall off block */
  250. X            RenderShape(display, window, walloffblock, walloffblockM, 
  251. X                x, y, 27, 23, True);
  252. X            break;
  253. X    }
  254. X}
  255. X
  256. X#if NeedFunctionPrototypes
  257. Xstatic void SetBlockUpForExplosion(int row, int col, int frame)
  258. X#else
  259. Xstatic void SetBlockUpForExplosion(row, col, frame)
  260. X    int row;
  261. X    int col;
  262. X    int frame;
  263. X#endif
  264. X{
  265. X    struct aBlock *blockP;
  266. X
  267. X    if (row < 0 || row >= MAX_ROW) return;
  268. X    if (col < 0 || col >= MAX_COL) return;
  269. X
  270. X    /* Obtain a pointer to the affected block */
  271. X    blockP = &blocks[row][col];
  272. X
  273. X    /* Do not have any effect on a specials block */
  274. X    if (blockP->blockType == HYPERSPACE_BLK) return;
  275. X
  276. X    /* If it isn't occupied then why blow it up */
  277. X    if (blockP->occupied == 1 && blockP->exploding == False)
  278. X    {
  279. X        /* Keep track of how many blocks are exploding */
  280. X        blocksExploding++;
  281. X
  282. X        /* Some special variables used for timing */
  283. X        blockP->explodeStartFrame     = frame;
  284. X        blockP->explodeNextFrame     = frame;
  285. X        blockP->explodeSlide         = 1;
  286. X        blockP->exploding             = True;
  287. X    }
  288. X}
  289. X
  290. X
  291. X#if NeedFunctionPrototypes
  292. Xvoid DrawBlock(Display *display, Window window, int row, int col, int blockType)
  293. X#else
  294. Xvoid DrawBlock(display, window, row, col, blockType)
  295. X    Display *display;
  296. X    Window window;
  297. X    int row;
  298. X    int col;
  299. X    int blockType;
  300. X#endif
  301. X{
  302. X    struct aBlock *blockP;
  303. X
  304. X    if (row < 0 || row > MAX_ROW) 
  305. X    {
  306. X        ErrorMessage("Block out of bounds row.");
  307. X        return;
  308. X    }
  309. X
  310. X    if (col < 0 || col > MAX_COL) 
  311. X    {
  312. X        ErrorMessage("Block out of bounds column.");
  313. X        return;
  314. X    }
  315. X
  316. X    /* Pointer to the block in question */
  317. X    blockP = &blocks[row][col];
  318. X
  319. X    switch(blockType)
  320. X    {
  321. X        case KILL_BLK:        /* Special block - blow it up */
  322. X            PlaySoundForBlock(blockP->blockType);
  323. X
  324. X            if (blockP->blockType != BLACK_BLK)
  325. X                SetBlockUpForExplosion(row, col, frame);
  326. X            break;
  327. X
  328. X        default:            /* Your average block - draw it */
  329. X            DrawTheBlock(display, window, blockP->x, blockP->y, 
  330. X                blockType, blockP->counterSlide);
  331. X    }
  332. X}
  333. X
  334. X#if NeedFunctionPrototypes
  335. Xvoid FreeBlockPixmaps(Display *display)
  336. X#else
  337. Xvoid FreeBlockPixmaps(display)
  338. X    Display *display;
  339. X#endif
  340. X{
  341. X    int i;
  342. X
  343. X    /* Free the memory associated with the block pixmaps */
  344. X    if (redblock)        XFreePixmap(display, redblock);            
  345. X    if (redblockM)        XFreePixmap(display, redblockM);
  346. X    if (blueblock)        XFreePixmap(display, blueblock);        
  347. X    if (blueblockM)        XFreePixmap(display, blueblockM);
  348. X    if (greenblock)        XFreePixmap(display, greenblock);        
  349. X    if (greenblockM)    XFreePixmap(display, greenblockM);
  350. X    if (tanblock)        XFreePixmap(display, tanblock);            
  351. X    if (tanblockM)        XFreePixmap(display, tanblockM);
  352. X    if (yellowblock)    XFreePixmap(display, yellowblock);        
  353. X    if (yellowblockM)    XFreePixmap(display, yellowblockM);
  354. X    if (purpleblock)    XFreePixmap(display, purpleblock);        
  355. X    if (purpleblockM)    XFreePixmap(display, purpleblockM);
  356. X    if (blackblock)        XFreePixmap(display, blackblock);        
  357. X    if (blackblockM)    XFreePixmap(display, blackblockM);
  358. X    if (bombblock)        XFreePixmap(display, bombblock);        
  359. X    if (bombblockM)        XFreePixmap(display, bombblockM);
  360. X    if (revblock)        XFreePixmap(display, revblock);        
  361. X    if (revblockM)        XFreePixmap(display, revblockM);
  362. X    if (hyperblock)        XFreePixmap(display, hyperblock);        
  363. X    if (hyperblockM)    XFreePixmap(display, hyperblockM);
  364. X    if (mgunblock)        XFreePixmap(display, mgunblock);        
  365. X    if (mgunblockM)        XFreePixmap(display, mgunblockM);
  366. X    if (walloffblock)    XFreePixmap(display, walloffblock);        
  367. X    if (walloffblockM)    XFreePixmap(display, walloffblockM);
  368. X    if (multiball)        XFreePixmap(display, multiball);        
  369. X    if (multiballM)        XFreePixmap(display, multiballM);
  370. X    if (sticky)            XFreePixmap(display, sticky);        
  371. X    if (stickyM)        XFreePixmap(display, stickyM);
  372. X    if (paddleexpand)    XFreePixmap(display, paddleexpand);        
  373. X    if (paddleexpandM)    XFreePixmap(display, paddleexpandM);
  374. X    if (paddleshrink)    XFreePixmap(display, paddleshrink);        
  375. X    if (paddleshrinkM)    XFreePixmap(display, paddleshrinkM);
  376. X
  377. X    for (i = 0; i < 5; i++)
  378. X    {
  379. X        /* Free the frames for the death block */
  380. X        if (death[i])    XFreePixmap(display, death[i]);     
  381. X        if (deathM[i])    XFreePixmap(display, deathM[i]);
  382. X    }
  383. X
  384. X    for (i = 0; i < 6; i++)
  385. X    {
  386. X        if (counterblock[i])    XFreePixmap(display, counterblock[i]);     
  387. X        if (counterblockM[i])    XFreePixmap(display, counterblockM[i]);
  388. X    }
  389. X
  390. X    for (i = 0; i < 4; i++)
  391. X    {
  392. X        if (x2bonus[i])            XFreePixmap(display, x2bonus[i]);     
  393. X        if (x2bonusM[i])        XFreePixmap(display, x2bonusM[i]);
  394. X
  395. X        if (x4bonus[i])            XFreePixmap(display, x4bonus[i]);     
  396. X        if (x4bonusM[i])        XFreePixmap(display, x4bonusM[i]);
  397. X
  398. X        if (Bonus[i])            XFreePixmap(display, Bonus[i]);     
  399. X        if (BonusM[i])            XFreePixmap(display, BonusM[i]);
  400. X    }
  401. X
  402. X    for (i = 0; i < 2; i++)
  403. X    {
  404. X        if (extraball[i])        XFreePixmap(display, extraball[i]);     
  405. X        if (extraballM[i])        XFreePixmap(display, extraballM[i]);
  406. X    }
  407. X
  408. X    for (i = 0; i < 3; i++)
  409. X    {
  410. X        if (exgreenblock[i])       XFreePixmap(display, exgreenblock[i]);     
  411. X        if (exgreenblockM[i])   XFreePixmap(display, exgreenblockM[i]);
  412. X
  413. X        if (exyellowblock[i])   XFreePixmap(display, exyellowblock[i]);
  414. X        if (exyellowblockM[i])  XFreePixmap(display, exyellowblockM[i]);
  415. X
  416. X        if (exredblock[i])         XFreePixmap(display, exredblock[i]);
  417. X        if (exredblockM[i])     XFreePixmap(display, exredblockM[i]);
  418. X
  419. X        if (exblueblock[i])     XFreePixmap(display, exblueblock[i]);
  420. X        if (exblueblockM[i])    XFreePixmap(display, exblueblockM[i]);
  421. X
  422. X        if (extanblock[i])         XFreePixmap(display, extanblock[i]);
  423. X        if (extanblockM[i])     XFreePixmap(display, extanblockM[i]);
  424. X
  425. X        if (excounterblock[i])  XFreePixmap(display, excounterblock[i]);
  426. X        if (excounterblockM[i]) XFreePixmap(display, excounterblockM[i]);
  427. X
  428. X        if (exbombblock[i])     XFreePixmap(display, exbombblock[i]);
  429. X        if (exbombblockM[i])    XFreePixmap(display, exbombblockM[i]);
  430. X        
  431. X        if (expurpleblock[i])   XFreePixmap(display, expurpleblock[i]);
  432. X        if (expurpleblockM[i])  XFreePixmap(display, expurpleblockM[i]);
  433. X        
  434. X        if (exx2bonus[i])         XFreePixmap(display, exx2bonus[i]);
  435. X        if (exx2bonusM[i])         XFreePixmap(display, exx2bonusM[i]);
  436. X
  437. X        if (exdeath[i])            XFreePixmap(display, exdeath[i]);     
  438. X        if (exdeathM[i])        XFreePixmap(display, exdeathM[i]);
  439. X    }
  440. X}
  441. X
  442. X#if NeedFunctionPrototypes
  443. Xstatic void CalculateBlockGeometry(int row, int col)
  444. X#else
  445. Xstatic void CalculateBlockGeometry(row, col)
  446. X    int row, col;
  447. X#endif
  448. X{
  449. X    struct aBlock *blockP;
  450. X    XPoint points[4];
  451. X    int halfWidth, halfHeight;
  452. X
  453. X    /* Pointer to the correct block we need - speed things up */
  454. X    blockP = &blocks[row][col];
  455. X
  456. X    switch (blockP->blockType)
  457. X    {
  458. X        case COUNTER_BLK:
  459. X            blockP->width             = BLOCK_WIDTH;
  460. X            blockP->height            = BLOCK_HEIGHT;
  461. X            blockP->blockOffsetX    = (colWidth - BLOCK_WIDTH) / 2;
  462. X            blockP->blockOffsetY     = (rowHeight - BLOCK_HEIGHT) / 2;
  463. X            break;
  464. X
  465. X        case MGUN_BLK:
  466. X            blockP->width             = 35;
  467. X            blockP->height            = 15;
  468. X            blockP->blockOffsetX    = (colWidth - 35) / 2;
  469. X            blockP->blockOffsetY     = (rowHeight - 15) / 2;
  470. X            break;
  471. X
  472. X        case WALLOFF_BLK:
  473. X            blockP->width             = 27;
  474. X            blockP->height            = 23;
  475. X            blockP->blockOffsetX    = (colWidth - 27) / 2;
  476. X            blockP->blockOffsetY     = (rowHeight - 23) / 2;
  477. X            break;
  478. X
  479. X        case REVERSE_BLK:
  480. X            blockP->width             = 33;
  481. X            blockP->height            = 16;
  482. X            blockP->blockOffsetX    = (colWidth - 33) / 2;
  483. X            blockP->blockOffsetY     = (rowHeight - 16) / 2;
  484. X            break;
  485. X
  486. X        case EXTRABALL_BLK:
  487. X            blockP->width             = 30;
  488. X            blockP->height            = 19;
  489. X            blockP->blockOffsetX    = (colWidth - 30) / 2;
  490. X            blockP->blockOffsetY     = (rowHeight - 19) / 2;
  491. X            break;
  492. X
  493. X        case HYPERSPACE_BLK:
  494. X            blockP->width             = 31;
  495. X            blockP->height            = 31;
  496. X            blockP->blockOffsetX    = (colWidth - 31) / 2;
  497. X            blockP->blockOffsetY     = (rowHeight - 31) / 2;
  498. X            break;
  499. X
  500. X        case BOMB_BLK:
  501. X        case DEATH_BLK:
  502. X            blockP->width             = 30;
  503. X            blockP->height            = 30;
  504. X            blockP->blockOffsetX    = (colWidth - 30) / 2;
  505. X            blockP->blockOffsetY     = (rowHeight - 30) / 2;
  506. X            break;
  507. X
  508. X        case STICKY_BLK:
  509. X            blockP->width             = 32;
  510. X            blockP->height            = 32;
  511. X            blockP->blockOffsetX    = (colWidth - 32) / 2;
  512. X            blockP->blockOffsetY     = (rowHeight - 32) / 2;
  513. X            break;
  514. X
  515. X        case BLACK_BLK:
  516. X            blockP->width             = 50;
  517. X            blockP->height            = 30;
  518. X            blockP->blockOffsetX    = (colWidth - 50) / 2;
  519. X            blockP->blockOffsetY     = (rowHeight - 30) / 2;
  520. X            break;
  521. X
  522. X        case PAD_SHRINK_BLK:
  523. X        case PAD_EXPAND_BLK:
  524. X            blockP->width             = 40;
  525. X            blockP->height            = 15;
  526. X            blockP->blockOffsetX    = (colWidth - 40) / 2;
  527. X            blockP->blockOffsetY     = (rowHeight - 15) / 2;
  528. X            break;
  529. X
  530. X        case BONUS_BLK:
  531. X        case BONUSX4_BLK:
  532. X        case BONUSX2_BLK:
  533. X            blockP->width             = 27;
  534. X            blockP->height            = 27;
  535. X            blockP->blockOffsetX    = (colWidth - 27) / 2;
  536. X            blockP->blockOffsetY     = (rowHeight - 27) / 2;
  537. X            break;
  538. X
  539. X        default:        /* All other blocks */
  540. X            blockP->width             = BLOCK_WIDTH;
  541. X            blockP->height            = BLOCK_HEIGHT;
  542. X            blockP->blockOffsetX    = (colWidth - BLOCK_WIDTH) / 2;
  543. X            blockP->blockOffsetY     = (rowHeight - BLOCK_HEIGHT) / 2;
  544. X            break;
  545. X
  546. X    }    
  547. X
  548. X    /* Calculate the offset within the block grid */
  549. X    blockP->x = (col * colWidth) + blockP->blockOffsetX;
  550. X    blockP->y = (row * rowHeight) + blockP->blockOffsetY;
  551. X
  552. X    /* Used below */
  553. X    halfWidth = blockP->x + (blockP->width / 2);
  554. X    halfHeight = blockP->y + (blockP->height / 2);
  555. X
  556. X    /* Create the XPoint array for the top region */
  557. X    points[0].x = blockP->x;
  558. X    points[0].y = blockP->y;
  559. X    points[1].x = halfWidth;
  560. X    points[1].y = halfHeight;
  561. X    points[2].x = blockP->x + blockP->width;
  562. X    points[2].y = blockP->y;
  563. X    points[3].x = points[0].x;
  564. X    points[3].y = points[0].y;
  565. X
  566. X    /* Create the top region for the block */
  567. X    blockP->regionTop = XPolygonRegion(points, 4, EvenOddRule);
  568. X
  569. X    /* Create the XPoint array for the bottom region */
  570. X    points[0].x = blockP->x;
  571. X    points[0].y = blockP->y + blockP->height;
  572. X    points[1].x = halfWidth;
  573. X    points[1].y = halfHeight;
  574. X    points[2].x = blockP->x + blockP->width;
  575. X    points[2].y = points[0].y;
  576. X    points[3].x = points[0].x;
  577. X    points[3].y = points[0].y;
  578. X
  579. X    /* Create the bottom region for the block */
  580. X    blockP->regionBottom = XPolygonRegion(points, 4, EvenOddRule);
  581. X
  582. X    /* Create the XPoint array for the left region */
  583. X    points[0].x = blockP->x;
  584. X    points[0].y = blockP->y;
  585. X    points[1].x = halfWidth;
  586. X    points[1].y = halfHeight;
  587. X    points[2].x = blockP->x;
  588. X    points[2].y = blockP->y + blockP->height;
  589. X    points[3].x = points[0].x;
  590. X    points[3].y = points[0].y;
  591. X
  592. X    /* Create the left region for the block */
  593. X    blockP->regionLeft = XPolygonRegion(points, 4, EvenOddRule);
  594. X
  595. X    /* Create the XPoint array for the right region */
  596. X    points[0].x = blockP->x + blockP->width;
  597. X    points[0].y = blockP->y;
  598. X    points[1].x = halfWidth;
  599. X    points[1].y = halfHeight;
  600. X    points[2].x = points[0].x;
  601. X    points[2].y = blockP->y + blockP->height;
  602. X    points[3].x = points[0].x;
  603. X    points[3].y = points[0].y;
  604. X
  605. X    /* Create the right region for the block */
  606. X    blockP->regionRight = XPolygonRegion(points, 4, EvenOddRule);
  607. X}
  608. X
  609. X#if NeedFunctionPrototypes
  610. Xvoid AddNewBlock(Display *display, Window window, int row, int col,
  611. X    int blockType, int counterSlide)
  612. X#else
  613. Xvoid AddNewBlock(display, window, row, col, blockType, counterSlide)
  614. X    Display *display;
  615. X    Window window;
  616. X    int row;
  617. X    int col;
  618. X    int blockType;
  619. X    int counterSlide;
  620. X#endif
  621. X{
  622. X    struct aBlock *blockP;
  623. X
  624. X    if (row > MAX_ROW || row < 0) return;
  625. X    if (col > MAX_COL || col < 0) return;
  626. X
  627. X    /* Pointer to the block we want */
  628. X    blockP = &blocks[row][col];
  629. X
  630. X    /* Now set the block structure with new values */
  631. X    blockP->blockType         = blockType;
  632. X    blockP->occupied         = 1;
  633. X    blockP->counterSlide     = counterSlide;
  634. X
  635. X    /* Handle the special case for a random block */
  636. X    if (blockType == RANDOM_BLK)
  637. X    {
  638. X        /* Setup the random block so it has a next frame and new type */
  639. X        blockP->random       = True;
  640. X        blockP->blockType = RED_BLK;
  641. X        blockP->nextFrame = frame + 1;
  642. X    }
  643. X
  644. X    /* Work out all the block geometry stuff */
  645. X    CalculateBlockGeometry(row, col);
  646. X    
  647. X    /* Add the number of points that will be awarded for each block */
  648. X    switch(blockType)
  649. X    {
  650. X        case BULLET_BLK:
  651. X            blockP->hitPoints = 50;
  652. X            break;
  653. X
  654. X        case RED_BLK:
  655. X            blockP->hitPoints = 100;
  656. X            break;
  657. X
  658. X        case GREEN_BLK:
  659. X            blockP->hitPoints = 120;
  660. X            break;
  661. X
  662. X        case BLUE_BLK:
  663. X            blockP->hitPoints = 110;
  664. X            break;
  665. X
  666. X        case TAN_BLK:
  667. X            blockP->hitPoints = 130;
  668. X            break;
  669. X
  670. X        case YELLOW_BLK:
  671. X            blockP->hitPoints = 140;
  672. X            break;
  673. X
  674. X        case PURPLE_BLK:
  675. X            blockP->hitPoints = 150;
  676. X            break;
  677. X
  678. X        case BOMB_BLK:
  679. X            blockP->hitPoints = 50;
  680. X            break;
  681. X
  682. X        case COUNTER_BLK:
  683. X            blockP->hitPoints = 200;
  684. X            break;
  685. X
  686. X        case EXTRABALL_BLK:
  687. X            blockP->nextFrame = frame + EXTRABALL_DELAY;
  688. X            blockP->hitPoints = 100;
  689. X            break;
  690. X
  691. X        case HYPERSPACE_BLK:
  692. X        case MGUN_BLK:
  693. X        case WALLOFF_BLK:
  694. X        case REVERSE_BLK:
  695. X        case MULTIBALL_BLK:
  696. X        case STICKY_BLK:
  697. X        case PAD_SHRINK_BLK:
  698. X        case PAD_EXPAND_BLK:
  699. X            blockP->hitPoints = 100;
  700. X            break;
  701. X
  702. X        case DEATH_BLK:
  703. X            blockP->hitPoints = -1000;
  704. X            blockP->nextFrame = frame + DEATH_DELAY2;
  705. X            break;
  706. X
  707. X        default:
  708. X            break;
  709. X    }
  710. X
  711. X    /* Draw the blocks please */
  712. X    DrawBlock(display, window, row, col, blockType);
  713. X}
  714. X
  715. X#if NeedFunctionPrototypes
  716. Xvoid SkipToNextLevel(Display *display, Window window)
  717. X#else
  718. Xvoid SkipToNextLevel(display, window)
  719. X    Display *display;
  720. X    Window window;
  721. X#endif
  722. X{
  723. X    struct aBlock *blockP;
  724. X    int r, c;
  725. X
  726. X    /* This will kill all blocks that need to go before next level can
  727. X     * be reached. Used in debug mode and maybe in special bonus mode.
  728. X     */
  729. X
  730. X    for (r = 0; r < MAX_ROW; r++)
  731. X        for (c = 0; c < MAX_COL; c++)
  732. X        {
  733. X            /* Pointer to the block we want */
  734. X            blockP = &blocks[r][c];
  735. X
  736. X            if (blockP->occupied == True) 
  737. X            {
  738. X                switch (blockP->blockType)
  739. X                {
  740. X                    case BONUSX2_BLK:
  741. X                    case BONUSX4_BLK:
  742. X                    case BONUS_BLK:
  743. X                    case BLACK_BLK:
  744. X                    case BULLET_BLK:
  745. X                    case BOMB_BLK:
  746. X                    case DEATH_BLK:
  747. X                    case REVERSE_BLK:
  748. X                    case HYPERSPACE_BLK:
  749. X                    case EXTRABALL_BLK:
  750. X                    case MGUN_BLK:
  751. X                    case WALLOFF_BLK:
  752. X                    case MULTIBALL_BLK:
  753. X                    case STICKY_BLK:
  754. X                    case PAD_SHRINK_BLK:
  755. X                    case PAD_EXPAND_BLK:
  756. X                        break;
  757. X
  758. X                    default:
  759. X                        DrawBlock(display, window, r, c, KILL_BLK);
  760. X                        break;
  761. X                }
  762. X            }
  763. X        }
  764. X}
  765. X
  766. X#if NeedFunctionPrototypes
  767. Xvoid RedrawAllBlocks(Display *display, Window window)
  768. X#else
  769. Xvoid RedrawAllBlocks(display, window)
  770. X    Display *display;
  771. X    Window window;
  772. X#endif
  773. X{
  774. X    struct aBlock *blockP;
  775. X    int r, c;
  776. X
  777. X    for (r = 0; r < MAX_ROW; r++)
  778. X        for (c = 0; c < MAX_COL; c++)
  779. X        {
  780. X            /* Pointer to the block we want */
  781. X            blockP = &blocks[r][c];
  782. X
  783. X            if (blockP->occupied == True)
  784. X                DrawBlock(display, window, r, c, blockP->blockType);
  785. X        }
  786. X}
  787. X
  788. X#if NeedFunctionPrototypes
  789. Xint StillActiveBlocks(void)
  790. X#else
  791. Xint StillActiveBlocks()
  792. X#endif
  793. X{
  794. X    struct aBlock *blockP;
  795. X    int r, c;
  796. X
  797. X    /* Check all blocks to see if they still are active */
  798. X    for (r = 0; r < MAX_ROW; r++)
  799. X        for (c = 0; c < MAX_COL; c++)
  800. X        {
  801. X            /* Pointer to the block we want */
  802. X            blockP = &blocks[r][c];
  803. X
  804. X            if (blockP->occupied == True) 
  805. X            {
  806. X                switch (blockP->blockType)
  807. X                {
  808. X                    /* These blocks don't count */
  809. X                    case BONUSX2_BLK:
  810. X                    case BONUSX4_BLK:
  811. X                    case BONUS_BLK:
  812. X                    case BLACK_BLK:
  813. X                    case BULLET_BLK:
  814. X                    case BOMB_BLK:
  815. X                    case DEATH_BLK:
  816. X                    case REVERSE_BLK:
  817. X                    case HYPERSPACE_BLK:
  818. X                    case EXTRABALL_BLK:
  819. X                    case MGUN_BLK:
  820. X                    case WALLOFF_BLK:
  821. X                    case MULTIBALL_BLK:
  822. X                    case STICKY_BLK:
  823. X                    case PAD_SHRINK_BLK:
  824. X                    case PAD_EXPAND_BLK:
  825. X                        break;
  826. X
  827. X                    default:
  828. X                        return True;
  829. X                }
  830. X            }
  831. X        }
  832. X    
  833. X    /* Only all done when explosions are finished */
  834. X    if (blocksExploding > 0)
  835. X        return True;
  836. X    else
  837. X        return False;
  838. X}
  839. X
  840. X#if NeedFunctionPrototypes
  841. Xstatic void ClearBlock(int row, int col)
  842. X#else
  843. Xstatic void ClearBlock(row, col)
  844. X    int row;
  845. X    int col;
  846. X#endif
  847. X{
  848. X    struct aBlock *blockP;
  849. X
  850. X    /* Pointer to the block we want */
  851. X    blockP = &blocks[row][col];
  852. X
  853. X    /* Initialise everything in block */
  854. X    blockP->occupied             = False;
  855. X    blockP->exploding             = False;
  856. X    blockP->x                     = 0;
  857. X    blockP->y                     = 0;
  858. X    blockP->width                 = 0;
  859. X    blockP->height                 = 0;
  860. X    blockP->hitPoints             = 0;
  861. X    blockP->blockType             = NONE_BLK;
  862. X    blockP->explodeStartFrame     = 0;
  863. X    blockP->explodeNextFrame     = 0;
  864. X    blockP->explodeSlide         = 0;
  865. X    blockP->counterSlide         = 0;
  866. X    blockP->bonusSlide             = 0;
  867. X    blockP->blockOffsetY         = 0;
  868. X    blockP->blockOffsetX         = 0;
  869. X    blockP->lastFrame             = 0;
  870. X    blockP->nextFrame             = 0;
  871. X    blockP->currentFrame         = 0;
  872. X    blockP->random                 = False;
  873. X    blockP->ballHitIndex         = 0;
  874. X    blockP->balldx                 = 0;
  875. X    blockP->balldy                 = 0;
  876. X
  877. X    /* Destroy the top region of the block */
  878. X    if (blockP->regionTop != (Region) NULL)
  879. X    {
  880. X        XDestroyRegion(blockP->regionTop);
  881. X        blockP->regionTop = (Region) NULL;
  882. X    }
  883. X
  884. X    /* Destroy the bottom region of the block */
  885. X    if (blockP->regionBottom != (Region) NULL)
  886. X    {
  887. X        XDestroyRegion(blockP->regionBottom);
  888. X        blockP->regionBottom = (Region) NULL;
  889. X    }
  890. X
  891. X    /* Destroy the left region of the block */
  892. X    if (blockP->regionLeft != (Region) NULL)
  893. X    {
  894. X        XDestroyRegion(blockP->regionLeft);
  895. X        blockP->regionLeft = (Region) NULL;
  896. X    }
  897. X
  898. X    /* Destroy the right region of the block */
  899. X    if (blockP->regionRight != (Region) NULL)
  900. X    {
  901. X        XDestroyRegion(blockP->regionRight);
  902. X        blockP->regionRight = (Region) NULL;
  903. X    }
  904. X}
  905. X
  906. X
  907. X#if NeedFunctionPrototypes
  908. Xvoid ClearBlockArray(void)
  909. X#else
  910. Xvoid ClearBlockArray()
  911. X#endif
  912. X{
  913. X    int r, c;
  914. X
  915. X    /* Scan through all block entries and erase their contents */
  916. X    for (r = 0; r < MAX_ROW; r++)
  917. X    {
  918. X        for (c = 0; c < MAX_COL; c++)
  919. X        {
  920. X            /* Clear the block thanks */
  921. X            ClearBlock(r, c);
  922. X        }
  923. X    }
  924. X}
  925. X
  926. X#if NeedFunctionPrototypes
  927. Xvoid SetupStage(Display *display, Window window)
  928. X#else
  929. Xvoid SetupStage(display, window)
  930. X    Display *display;
  931. X    Window window;
  932. X#endif
  933. X{
  934. X    char levelPath[1024];
  935. X    char *str;
  936. X    char str2[1024];
  937. X    static int bgrnd = 1;
  938. X    u_long newLevel;
  939. X
  940. X    bgrnd++;
  941. X    if (bgrnd == 12) bgrnd = 2;
  942. X    DrawStageBackground(display, window, bgrnd);
  943. X
  944. X    ClearAllBalls();
  945. X    currentPaddleSize   = PADDLE_HUGE;
  946. X    ResetPaddleStart(display, window);
  947. X    ResetBallStart(display, playWindow);
  948. X
  949. X    ClearBullets();
  950. X    SetNumberBullets(NUMBER_OF_BULLETS_NEW_LEVEL);
  951. X    ResetNumberBonus();
  952. X
  953. X    TurnSpecialsOff(display);        
  954. X    SetReverseOff();
  955. X    DisplayScore(display, scoreWindow, score);
  956. X    DisplayLevelInfo(display, levelWindow, level);
  957. X    DrawSpecials(display);
  958. X
  959. X    /* map the level number for the filename so that after the maximum
  960. X     * level is reached it will wrap around to 1 again but will not
  961. X       * affect the level number
  962. X        */
  963. X       newLevel = level % (MAX_NUM_LEVELS + 1);
  964. X      if (newLevel == 0) newLevel = 1;
  965. X
  966. X    /* Construct the level filename */
  967. X    if ((str = getenv("XBOING_LEVELS_DIR")) != NULL)
  968. X        sprintf(levelPath, "%s/level%ld.data", str, newLevel);
  969. X    else
  970. X        sprintf(levelPath, "%s/level%ld.data", LEVEL_INSTALL_DIR, newLevel);
  971. X
  972. X    if (ReadNextLevel(display, window, levelPath) == False)
  973. X        ShutDown(display, 1, "Sorry, email: jck@citri.edu.au with bug.");
  974. X    
  975. X    /* Display level name for all to see */
  976. X    sprintf(str2, "- %s -", GetLevelName());
  977. X    SetCurrentMessage(display, messWindow, str2, True);
  978. X
  979. X    XFlush(display);
  980. X}
  981. END_OF_FILE
  982.   if test 24327 -ne `wc -c <'blocks.c2'`; then
  983.     echo shar: \"'blocks.c2'\" unpacked with wrong size!
  984.   fi
  985.   # end of 'blocks.c2'
  986. fi
  987. if test -f 'highscore.c' -a "${1}" != "-c" ; then 
  988.   echo shar: Will not clobber existing file \"'highscore.c'\"
  989. else
  990.   echo shar: Extracting \"'highscore.c'\" \(26283 characters\)
  991.   sed "s/^X//" >'highscore.c' <<'END_OF_FILE'
  992. X#include "copyright.h"
  993. X
  994. X/*
  995. X *  Include file dependencies:
  996. X */
  997. X
  998. X#include <stdio.h>
  999. X#include <stdlib.h>
  1000. X#include <stddef.h>
  1001. X#include <ctype.h>
  1002. X#include <unistd.h>
  1003. X#include <sys/time.h>
  1004. X#include <sys/param.h>
  1005. X#include <sys/types.h>
  1006. X#include <netinet/in.h>
  1007. X#include <pwd.h>
  1008. X#include <X11/Xlib.h>
  1009. X#include <X11/Xutil.h>
  1010. X#include <X11/Xos.h>
  1011. X#include <xpm.h>
  1012. X
  1013. X#include "error.h"
  1014. X#include "misc.h"
  1015. X#include "main.h"
  1016. X#include "audio.h"
  1017. X#include "special.h"
  1018. X#include "init.h"
  1019. X#include "inst.h"
  1020. X#include "stage.h"
  1021. X#include "blocks.h"
  1022. X#include "ball.h"
  1023. X#include "score.h"
  1024. X#include "paddle.h"
  1025. X#include "level.h"
  1026. X#include "mess.h"
  1027. X#include "intro.h"
  1028. X
  1029. X#include "bitmaps/highscores.xpm"
  1030. X
  1031. X#include "highscore.h"
  1032. X
  1033. X/*
  1034. X *  Internal macro definitions:
  1035. X */
  1036. X
  1037. X#define GAP                13
  1038. X#define NUM_HIGHSCORES    10
  1039. X
  1040. X#ifndef MAXPATHLEN
  1041. X#define MAXPATHLEN 1024
  1042. X#endif
  1043. X
  1044. X/*
  1045. X *  Internal type declarations:
  1046. X */
  1047. X
  1048. X#if NeedFunctionPrototypes
  1049. Xstatic void SetHighScoreWait(int newMode, int waitFrame);
  1050. Xstatic void InitialiseHighScores(void);
  1051. Xstatic void SortHighScores(void);
  1052. Xstatic char *GetHomeDir(void);
  1053. Xstatic void DeleteScore(int index);
  1054. Xstatic int LockUnlock(int cmd);
  1055. X#else
  1056. Xstatic int LockUnlock();
  1057. Xstatic void DeleteScore();
  1058. Xstatic char *GetHomeDir();
  1059. Xstatic void SetHighScoreWait();
  1060. Xstatic void InitialiseHighScores();
  1061. Xstatic void SortHighScores();
  1062. X#endif
  1063. X
  1064. X/*
  1065. X *  Internal variable declarations:
  1066. X */
  1067. X
  1068. Xstatic int nextFrame = 0;
  1069. Xstatic int endFrame = 0;
  1070. Xenum HighScoreStates HighScoreState;
  1071. Xstatic Pixmap titlePixmap, titlePixmapM;
  1072. Xstatic int waitingFrame, waitMode;
  1073. Xstatic int sparkley = 0;
  1074. Xstatic int sindex = 0;
  1075. Xstatic int si = 0;
  1076. Xstatic int scoreType = GLOBAL;
  1077. X
  1078. XhighScoreEntry highScores[NUM_HIGHSCORES];
  1079. X
  1080. X#if NeedFunctionPrototypes
  1081. Xvoid SetUpHighScore(Display *display, Window window, Colormap colormap)
  1082. X#else
  1083. Xvoid SetUpHighScore(display, window, colormap)
  1084. X    Display *display;
  1085. X    Window window;
  1086. X    Colormap colormap;
  1087. X#endif
  1088. X{
  1089. X    XpmAttributes   attributes;
  1090. X    int             XpmErrorStatus;
  1091. X
  1092. X    attributes.valuemask = XpmColormap;
  1093. X    attributes.colormap = colormap;
  1094. X
  1095. X    /* Load the highscore title pixmap */
  1096. X    XpmErrorStatus = XpmCreatePixmapFromData(display, window, highscores_xpm,
  1097. X        &titlePixmap, &titlePixmapM, &attributes);
  1098. X    HandleXPMError(display, XpmErrorStatus, "InitialiseHighScore()");
  1099. X
  1100. X    /* Free the xpm pixmap attributes */
  1101. X    XpmFreeAttributes(&attributes);
  1102. X
  1103. X    /* Setup the high score table */
  1104. X    InitialiseHighScores();
  1105. X    ResetHighScore(GLOBAL);
  1106. X}
  1107. X
  1108. X#if NeedFunctionPrototypes
  1109. Xstatic void DoTitle(Display *display, Window window)
  1110. X#else
  1111. Xstatic void DoTitle(display, window)
  1112. X    Display *display;
  1113. X    Window window;
  1114. X#endif
  1115. X{
  1116. X    char string[80];
  1117. X
  1118. X    /* Clear */
  1119. X    DrawStageBackground(display, window, BACKGROUND_0);
  1120. X
  1121. X    /* Draw the highscore title */
  1122. X    RenderShape(display, window, titlePixmap, titlePixmapM,
  1123. X        59, 20, 377, 37, False);
  1124. X
  1125. X    /* Let the dudes know how to start the game */
  1126. X    strcpy(string, "Press <Space> to start the game");
  1127. X    DrawShadowCentredText(display, window, textFont,
  1128. X        string, PLAY_HEIGHT - 40, tann, PLAY_WIDTH);
  1129. X
  1130. X    /* Set the message window to have the other display toggle key */
  1131. X    if (scoreType == GLOBAL)
  1132. X        SetCurrentMessage(display, messWindow, 
  1133. X            "<H> - Personal Best", False);
  1134. X    else
  1135. X        SetCurrentMessage(display, messWindow, 
  1136. X            "<h> - Roll of Honour", False);
  1137. X
  1138. X    SetHighScoreWait(HIGHSCORE_SHOW, frame + 10);
  1139. X}
  1140. X
  1141. X#if NeedFunctionPrototypes
  1142. Xstatic void DoHighScores(Display *display, Window window)
  1143. X#else
  1144. Xstatic void DoHighScores(display, window)
  1145. X    Display *display;
  1146. X    Window window;
  1147. X#endif
  1148. X{
  1149. X    int i, len, plen;
  1150. X    int xr = 30;
  1151. X    int ym = 75;
  1152. X    int xs = xr + 30;
  1153. X    int xl = xs + 80;
  1154. X    int xt = xl + 35;
  1155. X    int xg = xt + 55;
  1156. X    int xn = xg + 90;
  1157. X    int y = 180;
  1158. X    char string[80];
  1159. X    char string2[80];
  1160. X    char *p;
  1161. X
  1162. X    /* Read the high score table */
  1163. X    if (ReadHighScoreTable(GLOBAL) == False)
  1164. X        InitialiseHighScores();
  1165. X
  1166. X    /* Draw the boing master at top of the list */
  1167. X    strcpy(string, "Boing Master");
  1168. X    DrawShadowCentredText(display, window, textFont, 
  1169. X        string, ym, red, PLAY_WIDTH);
  1170. X    ym += textFont->ascent + GAP;
  1171. X
  1172. X    /* Render the boing master's name */
  1173. X    strcpy(string, highScores[0].name);
  1174. X    DrawShadowCentredText(display, window, titleFont, 
  1175. X        string, ym, yellow, PLAY_WIDTH);
  1176. X    ym += textFont->ascent + GAP * 2;
  1177. X
  1178. X    /* Read the high score table */
  1179. X    if (ReadHighScoreTable(scoreType) == False)
  1180. X        InitialiseHighScores();
  1181. X
  1182. X    /* Explain that this is the roll of honour */
  1183. X    if (scoreType == GLOBAL)
  1184. X        strcpy(string, "- The Roll of Honour -");
  1185. X    else
  1186. X        strcpy(string, "- Personal Best -");
  1187. X    DrawShadowCentredText(display, window, textFont, 
  1188. X        string, ym, green, PLAY_WIDTH);
  1189. X    ym += textFont->ascent + GAP;
  1190. X
  1191. X    /* Draw the titles for the highscore table */
  1192. X    strcpy(string, "#");
  1193. X    len = strlen(string);
  1194. X    DrawText(display, window, xr+2, y+2, textFont, black, string, len);
  1195. X    DrawText(display, window, xr, y, textFont, yellow, string, len);
  1196. X
  1197. X    strcpy(string, "Score");
  1198. X    len = strlen(string);
  1199. X    DrawText(display, window, xs+2, y+2, textFont, black, string, len);
  1200. X    DrawText(display, window, xs, y, textFont, yellow, string, len);
  1201. X
  1202. X    strcpy(string, "L");
  1203. X    len = strlen(string);
  1204. X    DrawText(display, window, xl+2, y+2, textFont, black, string, len);
  1205. X    DrawText(display, window, xl, y, textFont, yellow, string, len);
  1206. X
  1207. X    strcpy(string, "Time");
  1208. X    len = strlen(string);
  1209. X    DrawText(display, window, xt+2, y+2, textFont, black, string, len);
  1210. X    DrawText(display, window, xt, y, textFont, yellow, string, len);
  1211. X
  1212. X    strcpy(string, "Date");
  1213. X    len = strlen(string);
  1214. X    DrawText(display, window, xg+2, y+2, textFont, black, string, len);
  1215. X    DrawText(display, window, xg, y, textFont, yellow, string, len);
  1216. X
  1217. X    strcpy(string, "Player");
  1218. X    len = strlen(string);
  1219. X    DrawText(display, window, xn+2, y+2, textFont, black, string, len);
  1220. X    DrawText(display, window, xn, y, textFont, yellow, string, len);
  1221. X
  1222. X    y += textFont->ascent + GAP / 2;
  1223. X
  1224. X    /* Draw the line above the table */
  1225. X    DrawLine(display, window, 22, y+2, PLAY_WIDTH - 18, y+2, black, 3);
  1226. X    DrawLine(display, window, 20, y, PLAY_WIDTH - 20, y, white, 3);
  1227. X
  1228. X    y += textFont->ascent;
  1229. X
  1230. X    /* Draw the scores into the table */
  1231. X    for (i = 0; i < NUM_HIGHSCORES; i++)
  1232. X    {
  1233. X        if (ntohl(highScores[i].score) > (u_long) 0)
  1234. X        {
  1235. X            /* Draw the rank */
  1236. X            sprintf(string, "%d", i+1);
  1237. X            if (ntohl(highScores[i].score) != score)
  1238. X                DrawShadowText(display, window, textFont, string, xr, y, tann);
  1239. X            else
  1240. X                DrawShadowText(display, window, textFont, string, xr, y, green);
  1241. X
  1242. X            /* Draw the score */
  1243. X            sprintf(string, "%ld", ntohl(highScores[i].score));
  1244. X            if (highScores[i].score != score)
  1245. X                DrawShadowText(display, window, textFont, string, xs, y, red);
  1246. X            else
  1247. X                DrawShadowText(display, window, textFont, string, xs, y, green);
  1248. X
  1249. X            /* Write out the level reached */
  1250. X            sprintf(string, "%ld", ntohl(highScores[i].level));
  1251. X            DrawShadowText(display, window, textFont, string, xl, y, green);
  1252. X
  1253. X            /* Game duration in minutes and seconds */
  1254. X            sprintf(string, "%d'%d\"",
  1255. X                highScores[i].gameTime / 60, highScores[i].gameTime % 60);
  1256. X            if (ntohl(highScores[i].score) != score)
  1257. X                DrawShadowText(display, window, textFont, string, xt, y, tann);
  1258. X            else
  1259. X                DrawShadowText(display, window, textFont, string, xt, y, green);
  1260. X
  1261. X            /* Construct the date for the highscore entry */
  1262. X            strftime(string, 10, "%d %b %y", localtime(&highScores[i].time));
  1263. X            string[9] = '\0';    /* Just to be sure */
  1264. X            if (ntohl(highScores[i].score) != score)
  1265. X                DrawShadowText(display, window, textFont, string, xg, y, white);
  1266. X            else    
  1267. X                DrawShadowText(display, window, textFont, string, xg, y, green);
  1268. X
  1269. X            /* Name of the boing master */
  1270. X            strcpy(string, highScores[i].name);
  1271. X            plen = XTextWidth(textFont, string, len);
  1272. X
  1273. X            /* Only use the first name if too big for screen */
  1274. X            if ((plen + xn) > PLAY_WIDTH)
  1275. X            {
  1276. X                /* Find the first space and null terminate there */
  1277. X                p = strchr(string, ' ');
  1278. X                *p = '\0';
  1279. X                strcpy(string2, string);
  1280. X
  1281. X                /* Draw a much smaller version of your name */
  1282. X                if (ntohl(highScores[i].score) != score)
  1283. X                    DrawShadowText(display, window, textFont, string2, xn, y, 
  1284. X                        yellow);
  1285. X                else
  1286. X                    DrawShadowText(display, window, textFont, string2, xn, y, 
  1287. X                        green);
  1288. X            }
  1289. X            else
  1290. X            {
  1291. X                /* Write out users name */
  1292. X                if (ntohl(highScores[i].score) != score)
  1293. X                    DrawShadowText(display, window, textFont, string, xn, y, 
  1294. X                        yellow);
  1295. X                else
  1296. X                    DrawShadowText(display, window, textFont, string, xn, y, 
  1297. X                        green);
  1298. X            }
  1299. X
  1300. X        }
  1301. X        else
  1302. X        {
  1303. X            /* This bit is for when the table entry is blank */
  1304. X            sprintf(string, "%d", i+1);
  1305. X            DrawShadowText(display, window, textFont, string, xr, y, tann);
  1306. X
  1307. X            /* Draw dashes for blank entries */
  1308. X            strcpy(string, "--");
  1309. X            DrawShadowText(display, window, textFont, string, xs, y, red);
  1310. X            DrawShadowText(display, window, textFont, string, xl, y, green);
  1311. X            DrawShadowText(display, window, textFont, string, xt, y, tann);
  1312. X            DrawShadowText(display, window, textFont, string, xg, y, white);
  1313. X            DrawShadowText(display, window, textFont, string, xn, y, yellow);
  1314. X        }
  1315. X
  1316. X        y += textFont->ascent + GAP;
  1317. X    }
  1318. X
  1319. X    /* Draw the line above the table */
  1320. X    DrawLine(display, window, 22, y+2, PLAY_WIDTH - 18, y+2, black, 3);
  1321. X    DrawLine(display, window, 20, y, PLAY_WIDTH - 20, y, white, 3);
  1322. X
  1323. X    SetHighScoreWait(HIGHSCORE_SPARKLE, frame + 2);
  1324. X}
  1325. X
  1326. X#if NeedFunctionPrototypes
  1327. Xstatic void DoSparkle(Display *display, Window window)
  1328. X#else
  1329. Xstatic void DoSparkle(display, window)
  1330. X    Display *display;
  1331. X    Window window;
  1332. X#endif
  1333. X{
  1334. X    static Pixmap store;    /* backing store for the sparkle */
  1335. X    static int x = 6;        /* X position of the sparkle */
  1336. X
  1337. X    if (!store)
  1338. X    {
  1339. X        /* Create some backing store for the sparkle star */
  1340. X        store = XCreatePixmap(display, window, 20, 20,
  1341. X            DefaultDepth(display, XDefaultScreen(display)));
  1342. X    }
  1343. X
  1344. X    if (frame == endFrame)
  1345. X    {
  1346. X        /* Bug out of the sparkle and goto next sequence */
  1347. X        si = 0;
  1348. X        sindex = 0;
  1349. X        sparkley = 180 + textFont->ascent + 20;
  1350. X
  1351. X        /* End the sparkle and now set up for finish */
  1352. X        SetHighScoreWait(HIGHSCORE_FINISH, frame + 1000);
  1353. X        return;
  1354. X    }
  1355. X
  1356. X    if (sindex == 0)
  1357. X        XCopyArea(display, window, store, gc, x, sparkley, 20, 20, 0, 0);
  1358. X
  1359. X    if (frame == nextFrame)
  1360. X    {
  1361. X        /* Draw the sparkle frame */
  1362. X        RenderShape(display, window, stars[sindex], starsM[sindex],
  1363. X            x, sparkley, 20, 20, False);
  1364. X
  1365. X        sindex++;
  1366. X        nextFrame = frame + 15;
  1367. X
  1368. X        /* Last frame of sparkle so reset */
  1369. X        if (sindex == 11)
  1370. X        {
  1371. X            XCopyArea(display, store, window, gc, 0, 0, 20, 20, x, sparkley);
  1372. X
  1373. X            sindex = 0;
  1374. X            nextFrame = frame + 100;
  1375. X            sparkley += textFont->ascent + GAP;
  1376. X
  1377. X            si++;
  1378. X
  1379. X            if ((ntohl(highScores[si].score) <= (u_long) 0) || (si == 10))
  1380. X            {
  1381. X                si = 0;
  1382. X                sindex = 0;
  1383. X                sparkley = 180 + textFont->ascent + 20;
  1384. X            }
  1385. X        }
  1386. X    }
  1387. X}
  1388. X
  1389. X
  1390. X
  1391. X#if NeedFunctionPrototypes
  1392. Xstatic void SetHighScoreWait(int newMode, int waitFrame)
  1393. X#else
  1394. Xstatic void SetHighScoreWait(newMode, waitFrame)
  1395. X    int newMode;
  1396. X    int waitFrame;
  1397. X#endif
  1398. X{
  1399. X    waitingFrame = waitFrame;
  1400. X    waitMode = newMode;
  1401. X    HighScoreState = HIGHSCORE_WAIT;
  1402. X}
  1403. X
  1404. X#if NeedFunctionPrototypes
  1405. Xvoid DoHighScoreWait(void)
  1406. X#else
  1407. Xvoid DoHighScoreWait()
  1408. X#endif
  1409. X{
  1410. X    /* Wait for the end frame then change mode */
  1411. X    if (frame == waitingFrame)
  1412. X        HighScoreState = waitMode;
  1413. X}
  1414. X
  1415. X#if NeedFunctionPrototypes
  1416. Xstatic void DoFinish(Display *display, Window window)
  1417. X#else
  1418. Xstatic void DoFinish(display, window)
  1419. X    Display *display;
  1420. X    Window window;
  1421. X#endif
  1422. X{
  1423. X    mode = MODE_INTRO;
  1424. X    HighScoreState = HIGHSCORE_TITLE;
  1425. X    ResetIntroduction();
  1426. X
  1427. X    if (noSound == False)
  1428. X        playSoundFile("weeek", 100);
  1429. X
  1430. X    SetGameSpeed(FAST_SPEED);
  1431. X}
  1432. X
  1433. X#if NeedFunctionPrototypes
  1434. Xvoid HighScore(Display *display, Window window)
  1435. X#else
  1436. Xvoid HighScore(display, window)
  1437. X    Display *display;
  1438. X    Window window;
  1439. X#endif
  1440. X{
  1441. X    /* Switch on the highscore table state */
  1442. X    switch (HighScoreState)
  1443. X    {
  1444. X        case HIGHSCORE_TITLE:
  1445. X            DoTitle(display, window);
  1446. X            break;
  1447. X
  1448. X        case HIGHSCORE_SHOW:
  1449. X            DoHighScores(display, window);
  1450. X            break;
  1451. X
  1452. X        case HIGHSCORE_SPARKLE:
  1453. X            DoSparkle(display, window);
  1454. X            if ((frame % FLASH) == 0)
  1455. X                RandomDrawSpecials(display);
  1456. X            break;
  1457. X
  1458. X        case HIGHSCORE_FINISH:
  1459. X            DoFinish(display, window);
  1460. X            break;
  1461. X
  1462. X        case HIGHSCORE_WAIT:
  1463. X            DoHighScoreWait();
  1464. X            break;
  1465. X
  1466. X        default:
  1467. X            break;
  1468. X    }
  1469. X}
  1470. X
  1471. X#if NeedFunctionPrototypes
  1472. Xvoid CommandlineHighscorePrint(void)
  1473. X#else
  1474. Xvoid CommandlineHighscorePrint()
  1475. X#endif
  1476. X{
  1477. X    char string[11];
  1478. X    int i;
  1479. X
  1480. X    InitialiseHighScores();
  1481. X
  1482. X    /* Must have table initialised with scores */
  1483. X    if (ReadHighScoreTable(GLOBAL) == False)
  1484. X        InitialiseHighScores();
  1485. X
  1486. X    /* Print out a pretty title message for scores */
  1487. X    fprintf(stdout, "XBoing Roll of Honour\n\n");
  1488. X    fprintf(stdout, "Rank\tScore\t  Level\tTime\tDate       Name\n");
  1489. X    fprintf(stdout, 
  1490. X        "----------------------------------------------------------------\n");
  1491. X
  1492. X    /* Zoom through the highscore table from the top */
  1493. X    for (i = 0; i < NUM_HIGHSCORES; i++)
  1494. X    {
  1495. X        strftime(string, 10, "%d %b %y", localtime(&highScores[i].time));
  1496. X
  1497. X        if (ntohl(highScores[i].score) > 0)
  1498. X        {
  1499. X            /* Print out the actual record */
  1500. X            fprintf(stdout, "%d\t%ld\t  %ld\t%d'%d\"\t%s  %s\n", 
  1501. X                i + 1, ntohl(highScores[i].score), 
  1502. X                ntohl(highScores[i].level),
  1503. X                highScores[i].gameTime / 60, highScores[i].gameTime % 60, 
  1504. X                string, highScores[i].name);
  1505. X        }
  1506. X    }
  1507. X
  1508. X    /* Print a trailing line to make the table look good */
  1509. X    fprintf(stdout, 
  1510. X        "----------------------------------------------------------------\n");
  1511. X    fflush(stdout);
  1512. X
  1513. X    /* Now display the personal highscore table */
  1514. X
  1515. X    InitialiseHighScores();
  1516. X
  1517. X    /* Must have table initialised with scores */
  1518. X    if (ReadHighScoreTable(PERSONAL) == False)
  1519. X        InitialiseHighScores();
  1520. X
  1521. X    /* Print out a pretty title message for scores */
  1522. X    fprintf(stdout, "\nPersonal Best\n\n");
  1523. X    fprintf(stdout, "Rank\tScore\t  Level\tTime\tDate       Name\n");
  1524. X    fprintf(stdout, 
  1525. X        "----------------------------------------------------------------\n");
  1526. X
  1527. X    /* Zoom through the highscore table from the top */
  1528. X    for (i = 0; i < NUM_HIGHSCORES; i++)
  1529. X    {
  1530. X        strftime(string, 10, "%d %b %y", localtime(&highScores[i].time));
  1531. X
  1532. X        if (ntohl(highScores[i].score) > 0)
  1533. X        {
  1534. X            /* Print out the actual record */
  1535. X            fprintf(stdout, "%d\t%ld\t  %ld\t%d'%d\"\t%s  %s\n", 
  1536. X                i + 1, ntohl(highScores[i].score), 
  1537. X                ntohl(highScores[i].level),
  1538. X                highScores[i].gameTime / 60, highScores[i].gameTime % 60, 
  1539. X                string, highScores[i].name);
  1540. X        }
  1541. X    }
  1542. X
  1543. X    /* Print a trailing line to make the table look good */
  1544. X    fprintf(stdout, 
  1545. X        "----------------------------------------------------------------\n");
  1546. X    fflush(stdout);
  1547. X}
  1548. X
  1549. X#if NeedFunctionPrototypes
  1550. Xint GetHighScoreRanking(u_long score)
  1551. X#else
  1552. Xint GetHighScoreRanking(score)
  1553. X    u_long score;
  1554. X#endif
  1555. X{
  1556. X    int i;
  1557. X
  1558. X    /* Must have table initialised with scores */
  1559. X    if (ReadHighScoreTable(GLOBAL) == False)
  1560. X        InitialiseHighScores();
  1561. X
  1562. X    /* Zoom through the highscore table from the top */
  1563. X    for (i = 0; i < NUM_HIGHSCORES; i++)
  1564. X    {
  1565. X        /* Is my score better than theirs */
  1566. X        if (score >= ntohl(highScores[i].score))
  1567. X            return (i + 1);
  1568. X    }
  1569. X
  1570. X    /* Not even in highscore table yet! */
  1571. X    return -1;
  1572. X}
  1573. X
  1574. X#if NeedFunctionPrototypes
  1575. Xstatic void ShiftScoresDown(int index, u_long score, u_long level, 
  1576. X    time_t gameTime, char *name)
  1577. X#else
  1578. Xstatic void ShiftScoresDown(index, score, level, gameTime, name)
  1579. X    int index;
  1580. X    u_long score;
  1581. X    u_long level;
  1582. X    time_t gameTime;
  1583. X    char *name;
  1584. X#endif
  1585. X{
  1586. X    /* This function will shift all score below the index down
  1587. X     * towards the end and kill off the last dude. Sorry mate.
  1588. X     */
  1589. X    int i;
  1590. X
  1591. X    /* Move all the scores down one notch */
  1592. X    for (i = NUM_HIGHSCORES-1; i > index; i--)
  1593. X    {
  1594. X        /* Shift the scores down one notch */
  1595. X        highScores[i].score     = highScores[i-1].score;
  1596. X        highScores[i].level     = highScores[i-1].level;
  1597. X        highScores[i].time         = highScores[i-1].time;
  1598. X        highScores[i].gameTime     = highScores[i-1].gameTime;
  1599. X        strcpy(highScores[i].name, highScores[i-1].name);
  1600. X    }
  1601. X
  1602. X    /* Add our new high score to the high score table */
  1603. X    highScores[index].score     = htonl(score);
  1604. X    highScores[index].level     = htonl(level);
  1605. X    highScores[index].gameTime     = gameTime;
  1606. X    highScores[index].time         = time(NULL);
  1607. X    strcpy(highScores[index].name, name);
  1608. X}
  1609. X
  1610. X#if NeedFunctionPrototypes
  1611. Xchar *getUsersFullName(void)
  1612. X#else
  1613. Xchar *getUsersFullName()
  1614. X#endif
  1615. X{
  1616. X    struct passwd   *pass;
  1617. X    char *comma;
  1618. X    char *cp1, *cp2;
  1619. X    static char fullname[80];
  1620. X
  1621. X    /* Get user information from password file */
  1622. X    if (!(pass = getpwuid(getuid())))
  1623. X        return("Anonymous?");        /* Unknown user oops. */
  1624. X
  1625. X    /* find a comma indicating further info after name */
  1626. X    comma = index(pass->pw_gecos, ',');
  1627. X
  1628. X    /* NULL out the comma */
  1629. X    if (comma) *comma = '\0';
  1630. X
  1631. X    cp1 = pass->pw_gecos;
  1632. X    cp2 = fullname;
  1633. X
  1634. X    /* Search through the gecos field looking for an '&' which on very
  1635. X     * old UNIX systems is supposed to be the users user name with the
  1636. X     * first letter uppercased.
  1637. X     */
  1638. X    while(*cp1)
  1639. X    {
  1640. X        /* Look for the '&' symbol */
  1641. X        if(*cp1 != '&')
  1642. X            *cp2++ = *cp1++;
  1643. X        else
  1644. X        {
  1645. X            /* A ha. Now copy the users name to be in place of '&' */
  1646. X            strcpy(cp2, pass->pw_name);
  1647. X            
  1648. X            /* Convert the first letter to uppercase. */
  1649. X            if(islower(*cp2)) 
  1650. X                *cp2 = toupper(*cp2);
  1651. X
  1652. X            /* Continue with the remaining string */
  1653. X            while(*cp2) cp2++;
  1654. X                cp1++;
  1655. X        }
  1656. X    }
  1657. X
  1658. X    /* Return their name without any trailing stuff */
  1659. X    return(fullname);
  1660. X}
  1661. X
  1662. X#if NeedFunctionPrototypes
  1663. Xstatic void DeleteScore(int index)
  1664. X#else
  1665. Xstatic void DeleteScore(index)
  1666. X    int index;
  1667. X#endif
  1668. X{
  1669. X    /* Delete the given score and shift all others up to fill in the hole */
  1670. X    int i;
  1671. X
  1672. X    /* Move all the scores down one notch */
  1673. X    for (i = index; i < NUM_HIGHSCORES-1; i++)
  1674. X    {
  1675. X        /* Shift the scores up one notch */
  1676. X        highScores[i].score     = highScores[i+1].score;
  1677. X        highScores[i].level     = highScores[i+1].level;
  1678. X        highScores[i].time         = highScores[i+1].time;
  1679. X        highScores[i].gameTime     = highScores[i+1].gameTime;
  1680. X        strcpy(highScores[i].name, highScores[i+1].name);
  1681. X    }
  1682. X
  1683. X    highScores[i].score     = htonl((u_long)0);
  1684. X    highScores[i].level     = htonl((u_long)1);
  1685. X    highScores[i].gameTime     = 0;
  1686. X    highScores[i].time         = time(NULL);
  1687. X    strcpy(highScores[i].name, "To be announced!");
  1688. X}
  1689. X
  1690. X#if NeedFunctionPrototypes
  1691. Xint CheckAndAddScoreToHighScore(u_long score, u_long level, time_t gameTime,
  1692. X    int type)
  1693. X#else
  1694. Xint CheckAndAddScoreToHighScore(score, level, gameTime, type)
  1695. X    u_long score;
  1696. X    u_long level;
  1697. X    time_t gameTime;
  1698. X    int type;
  1699. X#endif
  1700. X{
  1701. X    int i;
  1702. X    int id = -1;
  1703. X    char name[80];
  1704. X
  1705. X    /* Lock the file for me only */
  1706. X    if (type == GLOBAL)
  1707. X        id = LockUnlock(F_LOCK);
  1708. X
  1709. X    /* Read in the lastest scores */
  1710. X    if (ReadHighScoreTable(type) == False)
  1711. X        InitialiseHighScores();
  1712. X
  1713. X    /* Speed up by obtaining users name */
  1714. X    strcpy(name, getUsersFullName());
  1715. X
  1716. X    if (type == GLOBAL)
  1717. X    {
  1718. X        /* Go through the highscore table */
  1719. X        for (i = 0; i < NUM_HIGHSCORES; i++)
  1720. X        {
  1721. X            if (strcmp(highScores[i].name, name) == 0)
  1722. X            {
  1723. X                /* Can the last score be added to the highscores */
  1724. X                if (score > ntohl(highScores[i].score))
  1725. X                {
  1726. X                    /* Delete and move up all old scores */
  1727. X                    DeleteScore(i);
  1728. X
  1729. X                    break;
  1730. X                }
  1731. X                else
  1732. X                {
  1733. X                    /* Don't add as score is smaller */
  1734. X                    return False;
  1735. X                }
  1736. X            }
  1737. X        }    /* for */
  1738. X
  1739. X        /* Now add the new score into the table */
  1740. X        for (i = 0; i < NUM_HIGHSCORES; i++)
  1741. X        {
  1742. X            /* Can the last game be added to the highscores */
  1743. X            if (score > ntohl(highScores[i].score))
  1744. X            {
  1745. X                ShiftScoresDown(i, score, level, gameTime, name);
  1746. X
  1747. X                /* Add to the highscore by writing it out */
  1748. X                (void) WriteHighScoreTable(type);
  1749. X
  1750. X                /* Unlock the file now thanks */
  1751. X                if (id != -1) LockUnlock(F_ULOCK);
  1752. X
  1753. X                /* Yes - it was placed in the highscore */
  1754. X                return True;
  1755. X            }
  1756. X        }
  1757. X
  1758. X        /* Unlock the file now thanks */
  1759. X        if (id != -1) LockUnlock(F_ULOCK);
  1760. X
  1761. X        /* Not even a highscore - loser! */
  1762. X        return False;
  1763. X    }
  1764. X    else    /* Type == PERSONAL */
  1765. X    {
  1766. X        /* Go through the highscore table */
  1767. X        for (i = 0; i < NUM_HIGHSCORES; i++)
  1768. X        {
  1769. X            /* Can the last game be added to the highscores */
  1770. X            if (score > ntohl(highScores[i].score))
  1771. X            {
  1772. X                ShiftScoresDown(i, score, level, gameTime, name);
  1773. X
  1774. X                /* Add to the highscore by writing it out */
  1775. X                (void) WriteHighScoreTable(type);
  1776. X
  1777. X                /* Yes - it was placed in the highscore */
  1778. X                return True;
  1779. X            }
  1780. X        }
  1781. X
  1782. X        /* Not even a highscore - loser! */
  1783. X        return False;
  1784. X    }
  1785. X}
  1786. X
  1787. X#if NeedFunctionPrototypes
  1788. Xstatic void SortHighScores(void)
  1789. X#else
  1790. Xstatic void SortHighScores()
  1791. X#endif
  1792. X{
  1793. X    int i, j;
  1794. X    highScoreEntry tempHighScore;
  1795. X
  1796. X    /* The old bubble sort strikes again :-) */
  1797. X    for (i = 0; i < NUM_HIGHSCORES - 1; ++i)
  1798. X    {
  1799. X        for (j = NUM_HIGHSCORES - 1; j > i; --j)
  1800. X        {
  1801. X            /* Who has the higher score */
  1802. X            if (highScores[j-1].score < highScores[j].score)
  1803. X            {
  1804. X                /* Swap the entries around - use memcpy in future */
  1805. X                tempHighScore.score         = highScores[j-1].score;
  1806. X                tempHighScore.level         = highScores[j-1].level;
  1807. X                tempHighScore.gameTime         = highScores[j-1].gameTime;
  1808. X                strcpy(tempHighScore.name, highScores[j-1].name);
  1809. X
  1810. X                highScores[j-1].score         = highScores[j].score;
  1811. X                highScores[j-1].level         = highScores[j].level;
  1812. X                highScores[j-1].gameTime     = highScores[j].gameTime;
  1813. X                strcpy(highScores[j-1].name, highScores[j].name);
  1814. X
  1815. X                highScores[j].score         = tempHighScore.score;
  1816. X                highScores[j].level         = tempHighScore.level;
  1817. X                highScores[j].gameTime         = tempHighScore.gameTime;
  1818. X                strcpy(highScores[j].name, tempHighScore.name);
  1819. X            }
  1820. X        }
  1821. X    }
  1822. X}
  1823. X
  1824. X#if NeedFunctionPrototypes
  1825. Xstatic void InitialiseHighScores(void)
  1826. X#else
  1827. Xstatic void InitialiseHighScores()
  1828. X#endif
  1829. X{
  1830. X    int i;
  1831. X
  1832. X    /* Loop down table clearing everything out */
  1833. X    for (i = 0; i < NUM_HIGHSCORES; i++)
  1834. X    {
  1835. X        /* Null out all entries */
  1836. X        highScores[i].score = htonl((u_long) 0);
  1837. X        highScores[i].level = htonl((u_long) 1);
  1838. X        highScores[i].gameTime = 0;
  1839. X        highScores[i].time = time(NULL);
  1840. X        strcpy(highScores[i].name, "To be announced!");
  1841. X    }
  1842. X}
  1843. X
  1844. X#if NeedFunctionPrototypes
  1845. Xstatic char *GetHomeDir(void)
  1846. X#else
  1847. Xstatic char *GetHomeDir()
  1848. X#endif
  1849. X{
  1850. X    int uid;
  1851. X    struct passwd *pw;
  1852. X    register char *ptr;
  1853. X    static char dest[MAXPATHLEN];
  1854. X
  1855. X    /* This function will return the home directory of the user
  1856. X     * by either using the HOME environment variable or constructing
  1857. X     * it through the USER environment variable.
  1858. X     */
  1859. X
  1860. X    if ((ptr = getenv("HOME")) != NULL)
  1861. X        (void) strcpy(dest, ptr);
  1862. X    else
  1863. X    {
  1864. X        /* HOME variable is not present so get USER var */
  1865. X        if ((ptr = getenv("USER")) != NULL)
  1866. X            pw = getpwnam(ptr);
  1867. X        else
  1868. X        {
  1869. X            /* Obtain user id etc. */
  1870. X            uid = getuid();
  1871. X            pw = getpwuid(uid);
  1872. X        }
  1873. X
  1874. X        if (pw)
  1875. X            (void) strcpy(dest, pw->pw_dir);
  1876. X        else
  1877. X            *dest = '\0';
  1878. X    }
  1879. X
  1880. X    /* This will be NULL on error or the actual path */
  1881. X    return dest;
  1882. X}
  1883. X
  1884. X#if NeedFunctionPrototypes
  1885. Xint ReadHighScoreTable(int type)
  1886. X#else
  1887. Xint ReadHighScoreTable(type)
  1888. X    int type;
  1889. X#endif
  1890. X{
  1891. X    /* Read the high score table into memory structure */
  1892. X    FILE *hsfp;
  1893. X    int i;
  1894. X    char filename[MAXPATHLEN];
  1895. X    char *str;
  1896. X
  1897. X    /* Are we going to use the global or personal highscore file */
  1898. X    if (type == GLOBAL)
  1899. X    {
  1900. X        /* Use the environment variable if it exists */
  1901. X        if ((str = getenv("XBOING_SCORE_FILE")) != NULL)
  1902. X            strcpy(filename, str);
  1903. X        else
  1904. X            strcpy(filename, HIGH_SCORE_FILE);
  1905. X    }
  1906. X    else
  1907. X        sprintf(filename, "%s/.xboing-scores", GetHomeDir());
  1908. X
  1909. X    /* Open the high score file */
  1910. X    if ((hsfp = fopen(filename, "r")) == NULL)
  1911. X    {
  1912. X        /* Cannot open the high score file */
  1913. X        ErrorMessage("Warning: Cannot open high score file for reading.");
  1914. X        return False;
  1915. X    }
  1916. X
  1917. X    /* Read all high score entries */
  1918. X    for (i = 0; i < NUM_HIGHSCORES; i++)
  1919. X    {
  1920. X        /* Read the highscore entry */
  1921. X        if (fread(&highScores[i], sizeof(highScoreEntry), 1, hsfp) != 1)
  1922. X        {
  1923. X            if (fclose(hsfp) < 0)
  1924. X                ErrorMessage("Warning: Cannot close high score file.");
  1925. X            return False;
  1926. X        }
  1927. X    }
  1928. X
  1929. X    /* Close the high score file */
  1930. X    if (fclose(hsfp) < 0)
  1931. X        ErrorMessage("Warning: Cannot close high score file.");
  1932. X
  1933. X    return True;
  1934. X}
  1935. X
  1936. X
  1937. X#if NeedFunctionPrototypes
  1938. Xint WriteHighScoreTable(int type)
  1939. X#else
  1940. Xint WriteHighScoreTable(type)
  1941. X    int type;
  1942. X#endif
  1943. X{
  1944. X    /* write the high score table to the high score file */
  1945. X    FILE *hsfp;
  1946. X    int i;
  1947. X    char filename[MAXPATHLEN];
  1948. X    char *str;
  1949. X
  1950. X    /* Make sure the table is sorted */
  1951. X    SortHighScores();
  1952. X
  1953. X    /* Are we going to use the global or personal highscore file */
  1954. X    if (type == GLOBAL)
  1955. X    {
  1956. X        /* Use the environment variable if it exists */
  1957. X        if ((str = getenv("XBOING_SCORE_FILE")) != NULL)
  1958. X            strcpy(filename, str);
  1959. X        else
  1960. X            strcpy(filename, HIGH_SCORE_FILE);
  1961. X    }    
  1962. X    else
  1963. X        sprintf(filename, "%s/.xboing-scores", GetHomeDir());
  1964. X
  1965. X    /* Open the high score file */
  1966. X    if ((hsfp = fopen(filename, "w+")) == NULL)
  1967. X    {
  1968. X        /* Cannot open the high score file */
  1969. X        ErrorMessage("Warning: Cannot open high score file for writing.");
  1970. X        return False;
  1971. X    }
  1972. X
  1973. X    /* Write out all high score entries */
  1974. X    for (i = 0; i < NUM_HIGHSCORES; i++)
  1975. X    {
  1976. X        /* Write the highscore entry */
  1977. X        if (fwrite(&highScores[i], sizeof(highScoreEntry), 1, hsfp) != 1)
  1978. X        {
  1979. X            if (fclose(hsfp) < 0)
  1980. X                ErrorMessage("Warning: Cannot close high score file.");
  1981. X            return False;
  1982. X        }
  1983. X    }
  1984. X    
  1985. X    /* Make sure that the permissions on the file are rw for everyone */
  1986. X    fchmod(fileno(hsfp), 0666);
  1987. X    
  1988. X    /* Close the high score file */
  1989. X    if (fclose(hsfp) < 0)
  1990. X        ErrorMessage("Warning: Cannot close high score file.");
  1991. X
  1992. X    return True;
  1993. X}
  1994. X
  1995. X#if NeedFunctionPrototypes
  1996. Xvoid RedrawHighScore(Display *display, Window window)
  1997. X#else
  1998. Xvoid RedrawHighScore(display, window)
  1999. X    Display *display;
  2000. X    Window window;
  2001. X#endif
  2002. X{
  2003. X    /* Draw the title screen for highscore table */
  2004. X    DoTitle(display, window);
  2005. X}
  2006. X
  2007. X#if NeedFunctionPrototypes
  2008. Xvoid FreeHighScore(Display *display)
  2009. X#else
  2010. Xvoid FreeHighScore(display)
  2011. X    Display *display;
  2012. X#endif
  2013. X{
  2014. X    /* Free up those memory leaks thanks */
  2015. X    if (titlePixmap)     XFreePixmap(display, titlePixmap);
  2016. X    if (titlePixmapM)     XFreePixmap(display, titlePixmapM);
  2017. X}
  2018. X
  2019. X#if NeedFunctionPrototypes
  2020. Xvoid ResetHighScore(int type)
  2021. X#else
  2022. Xvoid ResetHighScore(type)
  2023. X    int type;
  2024. X#endif
  2025. X{
  2026. X    HighScoreState = HIGHSCORE_TITLE;
  2027. X    nextFrame = frame + 100;
  2028. X    endFrame = frame + 4000;
  2029. X
  2030. X    /* Reset the sparkles for the names */
  2031. X    sparkley = 180 + textFont->ascent + 20;
  2032. X    sindex = 0;
  2033. X    si = 0;
  2034. X    scoreType = type;
  2035. X}
  2036. X
  2037. X#if NeedFunctionPrototypes
  2038. Xstatic int LockUnlock(int cmd)
  2039. X#else
  2040. Xstatic int LockUnlock(cmd)
  2041. X    int cmd;
  2042. X#endif
  2043. X{
  2044. X    int inter;
  2045. X    char filename[1024];
  2046. X    char *str;
  2047. X
  2048. X    /* Use the environment variable if it exists */
  2049. X    if ((str = getenv("XBOING_SCORE_FILE")) != NULL)
  2050. X        strcpy(filename, str);
  2051. X    else
  2052. X        strcpy(filename, HIGH_SCORE_FILE);
  2053. X
  2054. X    /* Open the highscore file for both read & write */
  2055. X    inter = open(filename, O_RDWR);
  2056. X
  2057. X    /* Ok - if successful then lock or unlock the file */
  2058. X    if (inter != -1) lockf(inter, cmd, sizeof(highScores));
  2059. X
  2060. X    /* Return success */
  2061. X    return inter;
  2062. X}
  2063. END_OF_FILE
  2064.   if test 26283 -ne `wc -c <'highscore.c'`; then
  2065.     echo shar: \"'highscore.c'\" unpacked with wrong size!
  2066.   fi
  2067.   # end of 'highscore.c'
  2068. fi
  2069. if test -f 'score.h' -a "${1}" != "-c" ; then 
  2070.   echo shar: Will not clobber existing file \"'score.h'\"
  2071. else
  2072.   echo shar: Extracting \"'score.h'\" \(713 characters\)
  2073.   sed "s/^X//" >'score.h' <<'END_OF_FILE'
  2074. X#ifndef _SCORE_H_
  2075. X#define _SCORE_H_
  2076. X
  2077. X#include "copyright.h"
  2078. X
  2079. X/*
  2080. X *  Dependencies on other include files:
  2081. X */
  2082. X
  2083. X#include <X11/Xlib.h>
  2084. X
  2085. X/*
  2086. X *  Constants and macros:
  2087. X */
  2088. X
  2089. X/*
  2090. X *  Type declarations:
  2091. X */
  2092. X
  2093. X/*
  2094. X *  Function prototypes:
  2095. X */
  2096. X
  2097. X#if NeedFunctionPrototypes
  2098. Xvoid InitialiseScoreDigits(Display *display, Window window, Colormap colormap);
  2099. Xvoid FreeScoreDigits(Display *display);
  2100. Xvoid DisplayScore(Display *display, Window window, u_long score);
  2101. Xvoid DrawOutNumber(Display *display, Window window, u_long score, int x, int y);
  2102. Xvoid AddToScore(u_long inc);
  2103. X#else
  2104. Xvoid AddToScore();
  2105. Xvoid InitialiseScoreDigits();
  2106. Xvoid FreeScoreDigits();
  2107. Xvoid DisplayScore();
  2108. Xvoid DrawOutNumber();
  2109. X#endif
  2110. X
  2111. Xextern u_long score;
  2112. X
  2113. X#endif
  2114. END_OF_FILE
  2115.   if test 713 -ne `wc -c <'score.h'`; then
  2116.     echo shar: \"'score.h'\" unpacked with wrong size!
  2117.   fi
  2118.   # end of 'score.h'
  2119. fi
  2120. echo shar: End of archive 8 \(of 26\).
  2121. cp /dev/null ark8isdone
  2122. MISSING=""
  2123. 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 ; do
  2124.     if test ! -f ark${I}isdone ; then
  2125.     MISSING="${MISSING} ${I}"
  2126.     fi
  2127. done
  2128. if test "${MISSING}" = "" ; then
  2129.     echo You have unpacked all 26 archives.
  2130.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2131.     echo "merging split files..."
  2132.     cat blocks.c[12] > blocks.c
  2133.     rm blocks.c[12]
  2134.     echo "blocks.c done"
  2135.     cat bitmaps/earth.xpm.Z.u.[ab] > bitmaps/earth.xpm.Z.uue
  2136.     rm bitmaps/earth.xpm.Z.u.[ab]
  2137.     echo "bitmaps/earth.xpm.Z.uue done"
  2138. else
  2139.     echo You still must unpack the following archives:
  2140.     echo "        " ${MISSING}
  2141. fi
  2142. exit 0
  2143. exit 0 # Just in case...
  2144. -- 
  2145.   // chris@Sterling.COM           | Send comp.sources.x submissions to:
  2146. \X/  Amiga - The only way to fly! |    sources-x@sterling.com
  2147.  "It's intuitively obvious to the |
  2148.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  2149.